mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Channels: fix statistics inflated by tagged videos
The tag_file join in Channel.get_statistics() produced one row per tag, so a Video with N Tags was counted N times in video_count, size, and length. Count tagged Videos in a subquery instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
8044fd1240
commit
64b1ca8029
2 changed files with 43 additions and 7 deletions
|
|
@ -110,6 +110,40 @@ async def test_channel_download_relationships(test_session, download_channel):
|
|||
assert test_session.query(Download).count() == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_channel_statistics_with_tagged_videos(async_client, test_session, channel_factory, video_factory,
|
||||
tag_factory):
|
||||
"""Tagging a Video must not inflate its Channel's statistics.
|
||||
|
||||
A Video with multiple Tags was counted once per Tag because of the tag_file join."""
|
||||
channel = channel_factory()
|
||||
video1 = video_factory(channel_id=channel.id)
|
||||
video2 = video_factory(channel_id=channel.id)
|
||||
video3 = video_factory(channel_id=channel.id)
|
||||
test_session.commit()
|
||||
|
||||
expected_size = video1.file_group.size + video2.file_group.size + video3.file_group.size
|
||||
|
||||
# Statistics are correct before any Videos are tagged.
|
||||
statistics = channel.get_statistics()
|
||||
assert statistics['video_count'] == 3
|
||||
assert statistics['size'] == expected_size
|
||||
assert statistics['video_tags'] == 0
|
||||
|
||||
# video1 has two Tags, video2 has one Tag, video3 has none.
|
||||
tag1, tag2 = await tag_factory(), await tag_factory()
|
||||
video1.add_tag(test_session, tag1.name)
|
||||
video1.add_tag(test_session, tag2.name)
|
||||
video2.add_tag(test_session, tag1.name)
|
||||
test_session.commit()
|
||||
|
||||
# Tagging Videos must not change the number of Videos in the Channel.
|
||||
statistics = channel.get_statistics()
|
||||
assert statistics['video_count'] == 3
|
||||
assert statistics['size'] == expected_size
|
||||
assert statistics['video_tags'] == 2
|
||||
|
||||
|
||||
def test_channel_info_json(test_session, test_directory):
|
||||
from wrolpi.collections import Collection
|
||||
|
||||
|
|
|
|||
|
|
@ -953,15 +953,17 @@ class Channel(ModelHelper, Base):
|
|||
"""Get statistics about this channel."""
|
||||
with get_db_curs() as curs:
|
||||
stmt = '''
|
||||
SELECT SUM(size) AS "size",
|
||||
MAX(size) AS "largest_video",
|
||||
COUNT(video.id) AS "video_count",
|
||||
SUM(fg.length) AS "length",
|
||||
-- Videos may use multiple tags.
|
||||
COUNT(video.id) FILTER ( WHERE tf.file_group_id IS NOT NULL ) AS "video_tags"
|
||||
SELECT SUM(size) AS "size",
|
||||
MAX(size) AS "largest_video",
|
||||
COUNT(video.id) AS "video_count",
|
||||
SUM(fg.length) AS "length",
|
||||
-- Count Videos with at least one Tag; a Video may use multiple Tags.
|
||||
(SELECT COUNT(DISTINCT tf.file_group_id)
|
||||
FROM tag_file tf
|
||||
INNER JOIN video v ON v.file_group_id = tf.file_group_id
|
||||
WHERE v.channel_id = %(id)s) AS "video_tags"
|
||||
FROM video
|
||||
LEFT JOIN file_group fg on fg.id = video.file_group_id
|
||||
LEFT JOIN public.tag_file tf on fg.id = tf.file_group_id
|
||||
WHERE channel_id = %(id)s \
|
||||
'''
|
||||
curs.execute(stmt, dict(id=self.id))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue