fix(playlists): "+N without length" counts every video the sum left out
The label said "without length" but the count held only live videos, so a video not fetched yet, or gone before it was, was left out of the sum and named nowhere. The server's `Video.without_length` and the client's `isWithoutLength` are now one rule (no length, whatever the live status), and the field, the key and the helpers are named for what they count. The comments that still quoted "+N live" say the current copy.
This commit is contained in:
@@ -17,7 +17,6 @@ from sqlalchemy import (
|
||||
String,
|
||||
Text,
|
||||
UniqueConstraint,
|
||||
and_,
|
||||
case,
|
||||
func,
|
||||
literal_column,
|
||||
@@ -125,7 +124,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 (a playlist's counts it as `live_without_length`), and the duration filter, sort and Home budget never
|
||||
# it out (a playlist's counts it as `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
|
||||
@@ -239,15 +238,16 @@ class Video(Base, TimestampMixin):
|
||||
)
|
||||
|
||||
@hybrid_property
|
||||
def live_without_length(self) -> bool:
|
||||
"""A live video (on air, upcoming, a premiere or an archive) whose length is unknown: what a
|
||||
total leaves out and names as "+N live"."""
|
||||
return self.live_status != "none" and self.length_seconds is None
|
||||
def without_length(self) -> bool:
|
||||
"""A video whose length is unknown — live, an archive past a day, or not fetched yet: what a
|
||||
sum of lengths leaves out and names as "+N without length". Every such video, so the count
|
||||
and the sum never disagree about what was left out."""
|
||||
return self.length_seconds is None
|
||||
|
||||
@live_without_length.inplace.expression
|
||||
@without_length.inplace.expression
|
||||
@classmethod
|
||||
def _live_without_length_expression(cls) -> ColumnElement[bool]:
|
||||
return and_(cls.live_status != "none", cls.length_seconds.is_(None))
|
||||
def _without_length_expression(cls) -> ColumnElement[bool]:
|
||||
return cls.length_seconds.is_(None)
|
||||
|
||||
# Weighted full-text search document (DB-generated, never written by the app): title (A) >
|
||||
# creator keywords + search queries (B) > truncated description (C). ts_rank honours the
|
||||
|
||||
Reference in New Issue
Block a user