fix: set movie progress to 1 when status is Completed in imports

This commit is contained in:
FuzzyGrim
2026-02-01 17:42:55 +01:00
parent 3bff235eec
commit f35a5e3959
6 changed files with 49 additions and 15 deletions

View File

@@ -0,0 +1,23 @@
# Generated by Django 5.2.8 on 2026-02-01
from django.db import migrations
def fix_movie_progress(apps, _):
"""Set progress=1 for movies with status=Completed and progress=0."""
Movie = apps.get_model("app", "Movie")
Movie.objects.filter(status="Completed", progress=0).update(progress=1)
class Migration(migrations.Migration):
"""Migration to fix movie progress."""
dependencies = [
("app", "0053_add_boardgame"),
]
operations = [
migrations.RunPython(
fix_movie_progress, reverse_code=migrations.RunPython.noop
),
]

View File

@@ -384,6 +384,7 @@ class SimklImporter:
user=self.user,
status=movie_status,
score=movie["user_rating"],
progress=1 if movie_status == Status.COMPLETED.value else 0,
start_date=self._get_date(movie.get("last_watched_at")),
end_date=self._get_date(movie.get("last_watched_at")),
notes=movie["memo"]["text"] if movie["memo"] != {} else "",

View File

@@ -397,6 +397,7 @@ class TraktImporter:
user=self.user,
end_date=watched_at,
status=Status.COMPLETED.value,
progress=1,
)
movie_obj._history_date = parse_datetime(watched_at)
@@ -605,7 +606,7 @@ class TraktImporter:
msg = f"Error processing comment entry: {entry}"
raise MediaImportUnexpectedError(msg) from e
def _process_generic_entry(self, entry, entry_type, attribute_updates=None):
def _process_generic_entry(self, entry, entry_type, attribute_updates):
"""Process a generic entry (watchlist, rating, or comment)."""
if entry["type"] == "movie":
logger.info(
@@ -613,12 +614,18 @@ class TraktImporter:
entry["movie"]["title"],
entry_type,
)
# Movies with Completed status (from ratings and comments)
# should have progress=1
status = attribute_updates.get("status", Status.COMPLETED.value)
if status == Status.COMPLETED.value:
attribute_updates["progress"] = 1
self._process_media_item(
entry,
entry["movie"],
MediaTypes.MOVIE.value,
app.models.Movie,
attribute_updates or {},
attribute_updates,
)
elif entry["type"] == "show":
logger.info(
@@ -631,7 +638,7 @@ class TraktImporter:
entry["show"],
MediaTypes.TV.value,
app.models.TV,
attribute_updates or {},
attribute_updates,
)
elif entry["type"] == "season":
logger.info(
@@ -645,7 +652,7 @@ class TraktImporter:
entry["show"],
MediaTypes.SEASON.value,
app.models.Season,
attribute_updates or {},
attribute_updates,
entry["season"]["number"],
)
@@ -655,7 +662,7 @@ class TraktImporter:
media_data,
media_type,
model_class,
defaults=None,
defaults,
season_number=None,
):
"""Process media items for watchlist, ratings, and comments."""

View File

@@ -105,6 +105,7 @@ class ImportSimkl(TestCase):
movie_obj = Movie.objects.get(item=movie_item)
self.assertEqual(movie_obj.status, Status.COMPLETED.value)
self.assertEqual(movie_obj.score, 9)
self.assertEqual(movie_obj.progress, 1)
anime_item = Item.objects.get(media_type=MediaTypes.ANIME.value)
self.assertEqual(anime_item.title, "Cowboy Bebop")

View File

@@ -48,6 +48,10 @@ class ImportTrakt(TestCase):
self.assertEqual(len(trakt_importer.bulk_media[MediaTypes.MOVIE.value]), 1)
self.assertEqual(len(trakt_importer.media_instances[MediaTypes.MOVIE.value]), 1)
# Verify progress is set to 1 for completed movies
movie_obj = trakt_importer.bulk_media[MediaTypes.MOVIE.value][0]
self.assertEqual(movie_obj.progress, 1)
# Process the same movie again to test repeat handling
trakt_importer.process_watched_movie(movie_entry)
self.assertEqual(len(trakt_importer.bulk_media[MediaTypes.MOVIE.value]), 2)

View File

@@ -105,16 +105,14 @@
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95">
{% for value, label in sort_choices %}
{% if media_type != MediaTypes.MOVIE.value or value != 'progress' %}
<button hx-get="{% url 'medialist' media_type %}"
{% if media_list %} hx-target="{{ layout_class }}" {% else %} hx-target="#empty_list" {% endif %}
hx-include="#filter-form"
hx-indicator="#loading-indicator"
class="block w-full px-4 py-2 text-left text-sm transition-colors cursor-pointer"
:class="sort === '{{ value }}' ? 'bg-indigo-600 text-white font-medium' : 'text-gray-300 hover:bg-[#454d5a] hover:text-white'"
@click="sort = '{{ value }}'; open = false"
type="button">{{ label }}</button>
{% endif %}
<button hx-get="{% url 'medialist' media_type %}"
{% if media_list %} hx-target="{{ layout_class }}" {% else %} hx-target="#empty_list" {% endif %}
hx-include="#filter-form"
hx-indicator="#loading-indicator"
class="block w-full px-4 py-2 text-left text-sm transition-colors cursor-pointer"
:class="sort === '{{ value }}' ? 'bg-indigo-600 text-white font-medium' : 'text-gray-300 hover:bg-[#454d5a] hover:text-white'"
@click="sort = '{{ value }}'; open = false"
type="button">{{ label }}</button>
{% endfor %}
</div>
</div>