Skip to content

Commit a9e4270

Browse files
committed
refactor _build_tv_query to improve handling of TV episode releases #507
1 parent 48c64b4 commit a9e4270

File tree

2 files changed

+35
-25
lines changed

2 files changed

+35
-25
lines changed

src/events/models.py

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.utils import timezone
66

77
from app import media_type_config
8-
from app.models import Item, Media, MediaTypes, Season
8+
from app.models import TV, Item, Media, MediaTypes, Season
99

1010
# Statuses that represent inactive tracking
1111
# will be ignored when creating events
@@ -68,38 +68,48 @@ def get_user_events(self, user, first_day, last_day):
6868
return self.sort_with_sentinel_last(queryset)
6969

7070
def _build_tv_query(self, user, enabled_types):
71-
"""Build query for TV shows based on latest season status."""
71+
"""Build query for TV shows based on TV status and season statuses."""
7272
if not (
7373
MediaTypes.TV.value in enabled_types
7474
or MediaTypes.SEASON.value in enabled_types
7575
):
7676
return Q()
7777

78-
user_seasons = Season.objects.filter(user=user).select_related("item")
79-
latest_seasons = {}
80-
81-
for season in user_seasons:
82-
tv_id = season.item.media_id
83-
season_number = season.item.season_number
78+
active_tv_shows = (
79+
TV.objects.filter(
80+
user=user,
81+
item__media_type=MediaTypes.TV.value,
82+
)
83+
.exclude(
84+
status__in=INACTIVE_TRACKING_STATUSES,
85+
)
86+
.values_list("item__media_id", flat=True)
87+
)
8488

85-
if (
86-
tv_id not in latest_seasons
87-
or season_number > latest_seasons[tv_id].item.season_number
88-
):
89-
latest_seasons[tv_id] = season
89+
if not active_tv_shows:
90+
return Q()
9091

91-
tv_shows_with_active_latest_season = {
92-
tv_id
93-
for tv_id, season in latest_seasons.items()
94-
if season.status not in INACTIVE_TRACKING_STATUSES
95-
}
92+
inactive_seasons = Season.objects.filter(
93+
user=user,
94+
status__in=INACTIVE_TRACKING_STATUSES,
95+
item__media_id__in=active_tv_shows,
96+
).select_related("item")
9697

97-
if not tv_shows_with_active_latest_season:
98-
return Q()
98+
# Build a query that excludes specific inactive seasons
99+
exclude_query = Q()
100+
for season in inactive_seasons:
101+
exclude_query |= Q(
102+
item__media_type=MediaTypes.SEASON.value,
103+
item__media_id=season.item.media_id,
104+
item__season_number=season.item.season_number,
105+
)
99106

100-
return Q(
101-
item__media_type=MediaTypes.SEASON.value,
102-
item__media_id__in=tv_shows_with_active_latest_season,
107+
return (
108+
Q(
109+
item__media_type=MediaTypes.SEASON.value,
110+
item__media_id__in=active_tv_shows,
111+
)
112+
& ~exclude_query
103113
)
104114

105115
def sort_with_sentinel_last(self, queryset):

src/events/tests/test_models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,8 @@ def test_get_user_events(self):
298298
# Get events for the other user
299299
other_events = Event.objects.get_user_events(self.other_user, today, next_week)
300300

301-
# Should have no events, as other user has no active seasons or non-TV media
302-
self.assertEqual(other_events.count(), 0)
301+
# Other user has TV as active, so get season events
302+
self.assertEqual(other_events.count(), 1)
303303

304304
# Test with a different date range
305305
tomorrow = today + datetime.timedelta(days=1) # April 16

0 commit comments

Comments
 (0)