Skip to content

Commit 168bc57

Browse files
committed
feat(media): Add formatted progress properties for media models and update templates
1 parent 84f21ed commit 168bc57

File tree

3 files changed

+62
-17
lines changed

3 files changed

+62
-17
lines changed

src/app/models.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from simple_history.models import HistoricalRecords
2828
from simple_history.utils import bulk_create_with_history, bulk_update_with_history
2929

30+
import app
3031
import events
3132
import users
3233
from app import providers
@@ -624,6 +625,11 @@ def process_status(self):
624625
):
625626
events.tasks.reload_calendar.delay(items_to_process=[self.item])
626627

628+
@property
629+
def formatted_progress(self):
630+
"""Return the progress of the media in a formatted string."""
631+
return str(self.progress)
632+
627633
def increase_progress(self):
628634
"""Increase the progress of the media by one."""
629635
self.progress += 1
@@ -667,6 +673,33 @@ def progress(self):
667673
"""Return the total episodes watched for the TV show."""
668674
return sum(season.progress for season in self.seasons.all())
669675

676+
@property
677+
def formatted_progress(self):
678+
"""Return the latest watched episode in SxxExx format."""
679+
if not hasattr(self, "seasons"):
680+
return ""
681+
682+
watched_episodes = [
683+
{
684+
"season": season.item.season_number,
685+
"episode": episode.item.episode_number,
686+
}
687+
for season in self.seasons.all()
688+
if hasattr(season, "episodes")
689+
for episode in season.episodes.all()
690+
]
691+
692+
if not watched_episodes:
693+
return ""
694+
695+
# Find the episode with highest season and episode numbers
696+
latest_episode = max(
697+
watched_episodes,
698+
key=lambda x: (x["season"], x["episode"]),
699+
)
700+
701+
return f"S{latest_episode['season']:02d}E{latest_episode['episode']:02d}"
702+
670703
@property
671704
def repeats(self):
672705
"""Return the number of max repeated episodes in the TV show."""
@@ -1163,6 +1196,11 @@ class Game(Media):
11631196

11641197
tracker = FieldTracker()
11651198

1199+
@property
1200+
def formatted_progress(self):
1201+
"""Return progress in hours:minutes format."""
1202+
return app.helpers.minutes_to_hhmm(self.progress)
1203+
11661204
def increase_progress(self):
11671205
"""Increase the progress of the media by 30 minutes."""
11681206
self.progress += 30

src/templates/app/components/media_table_items.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,24 @@
7979
</div>
8080
</td>
8181
{% endif %}
82-
<td class="p-2 text-center">{{ media.progress }}</td>
82+
83+
{% if media_type == MediaTypes.TV.value %}
84+
<td class="p-2 text-center">{{ media.progress }}</td>
85+
<td class="p-2 text-center">{{ media.formatted_progress }}</td>
86+
{% else %}
87+
<td class="p-2 text-center">{{ media.formatted_progress }}</td>
88+
{% endif %}
89+
8390
<td class="p-2 text-center">{{ media.status|media_status_readable }}</td>
91+
8492
{% if media.start_date %}
8593
<td class="p-2 text-center">{{ media.start_date|date:"Y-m-d" }}</td>
8694
{% else %}
8795
<td class="p-2 text-center">
8896
<span class="text-gray-500">-</span>
8997
</td>
9098
{% endif %}
99+
91100
{% if media.end_date %}
92101
<td class="p-2 text-center">{{ media.end_date|date:"Y-m-d" }}</td>
93102
{% else %}

src/templates/app/media_list.html

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,19 @@
99
{% block content %}
1010
<h1 class="text-3xl font-bold mb-6">{{ media_type|media_type_readable_plural }}</h1>
1111

12-
<div x-data="{
13-
sort: '{{ current_sort }}',
14-
status: '{{ current_status }}',
15-
layout: '{{ current_layout }}',
16-
search: '{{ request.GET.search|default:'' }}',
17-
statusLabels: {
18-
{% for value, label in status_choices %}
19-
'{{ value }}': '{{ label }}'{% if not forloop.last %},{% endif %}
20-
{% endfor %}
21-
},
22-
sortLabels: {
23-
{% for value, label in sort_choices %}
24-
'{{ value }}': '{{ label }}'{% if not forloop.last %},{% endif %}
25-
{% endfor %}
26-
}
27-
}">
12+
<div x-data="{ sort: '{{ current_sort }}', status: '{{ current_status }}', layout: '{{ current_layout }}', search: '{{ request.GET.search|default:'' }}', statusLabels: {
13+
{% for value, label in status_choices %}
14+
'{{ value }}': '{{ label }}'
15+
{% if not forloop.last %},{% endif %}
16+
17+
{% endfor %}
18+
}, sortLabels: {
19+
{% for value, label in sort_choices %}
20+
'{{ value }}': '{{ label }}'
21+
{% if not forloop.last %},{% endif %}
22+
23+
{% endfor %}
24+
} }">
2825

2926
<!-- Form to manage state -->
3027
<form id="filter-form" class="hidden">
@@ -265,6 +262,7 @@ <h3 class="text-xl font-semibold mb-2">No {{ media_type|media_type_readable_plur
265262
<th class="p-2 w-2/5">Title</th>
266263
<th class="p-2 text-center">Score</th>
267264
<th class="p-2 text-center">Progress</th>
265+
{% if media_type == MediaTypes.TV.value %}<th class="p-2 text-center">Last Watched</th>{% endif %}
268266
<th class="p-2 text-center">Status</th>
269267
<th class="p-2 text-center">Start Date</th>
270268
<th class="p-2 text-center">End Date</th>

0 commit comments

Comments
 (0)