The scheduled RSS poll and recent backfill covered every channel row, but rows also come from search results, playlist sync and dropped subscriptions, and nothing deletes them. On prod 582 of 979 polled channels had no follower, three of them dead feeds answering 404 on every poll. Both jobs now take subscribed or explored channels only, and the scheduler card counts the same set. As a deliberate trade-off, the shared Library no longer receives new uploads from channels nobody follows.
64 lines
2.5 KiB
Python
64 lines
2.5 KiB
Python
"""The scheduled RSS poll and recent backfill cover FOLLOWED channels only (owner decision, 2026-09-17).
|
|
|
|
A channel row also comes from a search result, a playlist item or a subscription somebody dropped,
|
|
and nothing deletes those rows. Polling all of them was 582 of 979 channels on prod with no follower,
|
|
three of them dead feeds answering 404 every 20 minutes. Followed = subscribed by someone, or explored
|
|
by someone. The admin card counting "channels to sync" must use the same selection, or it counts
|
|
channels the backfill will never touch. DB lane.
|
|
"""
|
|
|
|
from app.models import Channel, ExploredChannel, Subscription
|
|
from app.sync import runner
|
|
|
|
|
|
def _channels(db, make_user):
|
|
user = make_user()
|
|
for cid in ("UC_sub", "UC_explored", "UC_search", "UC_playlist"):
|
|
db.add(Channel(id=cid, title=cid, from_search=cid == "UC_search"))
|
|
db.flush()
|
|
db.add(Subscription(user_id=user.id, channel_id="UC_sub"))
|
|
db.add(ExploredChannel(user_id=user.id, channel_id="UC_explored"))
|
|
db.commit()
|
|
return user
|
|
|
|
|
|
def test_the_rss_poll_skips_channels_nobody_follows(db, make_user, monkeypatch):
|
|
_channels(db, make_user)
|
|
polled: list[str] = []
|
|
monkeypatch.setattr(runner, "fetch_channel_feed", lambda cid: polled.append(cid) or [])
|
|
monkeypatch.setattr(runner, "apply_rss_feed", lambda db, ch, entries: 0)
|
|
assert runner.run_rss_poll(db) == {"new": 0, "failed": 0}
|
|
assert sorted(polled) == ["UC_explored", "UC_sub"]
|
|
|
|
|
|
def test_the_recent_backfill_skips_channels_nobody_follows(db, make_user, monkeypatch):
|
|
user = _channels(db, make_user)
|
|
done: list[str] = []
|
|
|
|
class _Client:
|
|
def __init__(self, *a):
|
|
pass
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *a):
|
|
return False
|
|
|
|
monkeypatch.setattr(runner, "get_service_user", lambda db: user)
|
|
monkeypatch.setattr(runner, "YouTubeClient", _Client)
|
|
monkeypatch.setattr(runner.quota, "backfill_reserve_reached", lambda: False)
|
|
monkeypatch.setattr(
|
|
runner, "backfill_channel_recent", lambda db, yt, ch: done.append(ch.id) or 0
|
|
)
|
|
monkeypatch.setattr(runner, "reconcile_full_history", lambda db: 0)
|
|
runner.run_recent_backfill(db)
|
|
assert sorted(done) == ["UC_explored", "UC_sub"]
|
|
|
|
|
|
def test_the_dashboard_counts_the_channels_the_backfill_will_process(db, make_user, as_user):
|
|
_channels(db, make_user)
|
|
admin = make_user(role="admin")
|
|
queue = as_user(admin).get("/api/admin/scheduler").json()["queue"]
|
|
assert queue["channels_recent_pending"] == 2
|