fix(channels): the Length column shows the sum alone
The "+N without length" line did not fit the 4.5 rem column (88 px of text in a 56 px cell) and spilled into Tags. The owner wants no such line there: the cell shows the summed hours, and the channel list no longer sends a count nothing reads. A playlist's total keeps it.
This commit is contained in:
@@ -125,7 +125,7 @@ LIVE_OR_UPCOMING = ("live", "upcoming")
|
||||
# the stream has run (measured on prod, 2026-11-06: 122,962,914 s), and one such video made a Watch
|
||||
# later total read 44,073 hours. YouTube caps an upload at 12 hours, so nothing real is lost. Such a
|
||||
# length is unknown wherever a length is used: the API sends none (`Video.length_seconds`), sums leave
|
||||
# it out and count it as `live_without_length`, and the duration filter, sort and Home budget never
|
||||
# it out (a playlist's counts it as `live_without_length`), and the duration filter, sort and Home budget never
|
||||
# match it. The raw `duration_seconds` stays for what it does prove — that the video is not a Short —
|
||||
# and for the jobs that ask whether YouTube has answered yet (test_video_length holds who reads it).
|
||||
LENGTH_MAX_S = 24 * 3600
|
||||
|
||||
@@ -44,8 +44,8 @@ def channel_titles(db: Session, ids: set[str]) -> dict[str, str]:
|
||||
|
||||
|
||||
def channel_aggregates(channel_ids: list[str]) -> Select:
|
||||
"""Per-channel stored count, last upload, total duration and the live videos the total cannot
|
||||
hold (`Video.live_without_length`), in one grouped pass. Every column it
|
||||
"""Per-channel stored count, last upload and total duration (the lengths it knows: a video with
|
||||
none is left out, `Video.length_seconds`), in one grouped pass. Every column it
|
||||
reads is in `ix_videos_channel_pub_cover` (migration 0095), so Postgres answers it from the index
|
||||
alone; a test holds that (test_channel_list_index_only)."""
|
||||
return (
|
||||
@@ -54,18 +54,14 @@ def channel_aggregates(channel_ids: list[str]) -> Select:
|
||||
func.count(Video.id),
|
||||
func.max(Video.published_at),
|
||||
func.coalesce(func.sum(Video.length_seconds), 0),
|
||||
func.count().filter(Video.live_without_length),
|
||||
)
|
||||
.where(Video.channel_id.in_(channel_ids))
|
||||
.group_by(Video.channel_id)
|
||||
)
|
||||
|
||||
|
||||
def aggregates(
|
||||
db: Session, channel_ids: list[str]
|
||||
) -> list[tuple[str, int, datetime | None, int, int]]:
|
||||
"""`channel_aggregates`, run: (channel id, stored videos, last upload, total seconds, live
|
||||
videos without a length)."""
|
||||
def aggregates(db: Session, channel_ids: list[str]) -> list[tuple[str, int, datetime | None, int]]:
|
||||
"""`channel_aggregates`, run: (channel id, stored videos, last upload, total seconds)."""
|
||||
if not channel_ids:
|
||||
return []
|
||||
return list(db.execute(channel_aggregates(channel_ids)).tuples())
|
||||
|
||||
@@ -46,12 +46,11 @@ def list_channels(user: User = Depends(current_user), db: Session = Depends(get_
|
||||
# computed here — the manager table dropped its N/S/L column.)
|
||||
channel_ids = [c.id for _, c in rows]
|
||||
agg: dict[str, dict] = {}
|
||||
for cid, n, last_up, total_dur, live in queries.aggregates(db, channel_ids):
|
||||
for cid, n, last_up, total_dur in queries.aggregates(db, channel_ids):
|
||||
agg[cid] = {
|
||||
"stored": n,
|
||||
"last_video_at": iso(last_up),
|
||||
"total_duration_seconds": int(total_dur or 0),
|
||||
"live_without_length": live,
|
||||
}
|
||||
|
||||
# Channels already in the *global* deep-backfill queue — i.e. at least one user (any
|
||||
@@ -69,7 +68,6 @@ def list_channels(user: User = Depends(current_user), db: Session = Depends(get_
|
||||
"stored_videos": (agg.get(ch.id) or {}).get("stored", 0),
|
||||
"last_video_at": (agg.get(ch.id) or {}).get("last_video_at"),
|
||||
"total_duration_seconds": (agg.get(ch.id) or {}).get("total_duration_seconds", 0),
|
||||
"live_without_length": (agg.get(ch.id) or {}).get("live_without_length", 0),
|
||||
"priority": sub.priority,
|
||||
"hidden": sub.hidden,
|
||||
"deep_requested": sub.deep_requested,
|
||||
|
||||
@@ -141,7 +141,8 @@ def test_the_totals_leave_it_out_and_count_the_live_ones(db, make_user, as_user)
|
||||
assert channels.status_code == 200
|
||||
(ch,) = channels.json()
|
||||
assert ch["total_duration_seconds"] == KNOWN_SUM
|
||||
assert ch["live_without_length"] == 2
|
||||
# The channel table shows the sum alone (the count did not fit its column), so it is not sent.
|
||||
assert "live_without_length" not in ch
|
||||
|
||||
|
||||
def test_the_duration_filter_and_sort_pass_it_over(db, make_user, as_user):
|
||||
|
||||
Reference in New Issue
Block a user