Sfoglia il codice sorgente

Fix completion for video games

Colin Powell 2 anni fa
parent
commit
df62865eea

+ 2 - 16
vrobbler/apps/scrobbles/admin.py

@@ -57,14 +57,7 @@ class ChartRecordAdmin(admin.ModelAdmin):
     ordering = ("-created",)
 
     def media_name(self, obj):
-        if obj.video:
-            return obj.video
-        if obj.track:
-            return obj.track
-        if obj.podcast_episode:
-            return obj.podcast_episode
-        if obj.sport_event:
-            return obj.sport_event
+        return obj.media_obj
 
 
 @admin.register(Scrobble)
@@ -86,6 +79,7 @@ class ScrobbleAdmin(admin.ModelAdmin):
         "track",
         "sport_event",
         "book",
+        "video_game",
     )
     list_filter = ("is_paused", "in_progress", "source", "track__artist")
     ordering = ("-timestamp",)
@@ -95,14 +89,6 @@ class ScrobbleAdmin(admin.ModelAdmin):
 
     def media_type(self, obj):
         return obj.media_obj.__class__.__name__
-        if obj.video:
-            return "Video"
-        if obj.track:
-            return "Track"
-        if obj.podcast_episode:
-            return "Podcast"
-        if obj.sport_event:
-            return "Sport Event"
 
     def playback_percent(self, obj):
         return obj.percent_played

+ 12 - 6
vrobbler/apps/scrobbles/models.py

@@ -417,7 +417,6 @@ class Scrobble(TimeStampedModel):
 
     # Fields for keeping track long content like books and games
     book_pages_read = models.IntegerField(**BNULL)
-    videogame_minutes_played = models.IntegerField(**BNULL)
     long_play_complete = models.BooleanField(**BNULL)
 
     def save(self, *args, **kwargs):
@@ -490,6 +489,8 @@ class Scrobble(TimeStampedModel):
             media_obj = self.sport_event
         if self.book:
             media_obj = self.book
+        if self.video_game:
+            media_obj = self.video_game
         return media_obj
 
     def __str__(self):
@@ -501,21 +502,26 @@ class Scrobble(TimeStampedModel):
         cls, media, user_id: int, scrobble_data: dict
     ) -> "Scrobble":
 
-        if media.__class__.__name__ == "Track":
+        media_class = media.__class__.__name__
+
+        if media_class == "Track":
             media_query = models.Q(track=media)
             scrobble_data["track_id"] = media.id
-        if media.__class__.__name__ == "Video":
+        if media_class == "Video":
             media_query = models.Q(video=media)
             scrobble_data["video_id"] = media.id
-        if media.__class__.__name__ == "Episode":
+        if media_class == "Episode":
             media_query = models.Q(podcast_episode=media)
             scrobble_data["podcast_episode_id"] = media.id
-        if media.__class__.__name__ == "SportEvent":
+        if media_class == "SportEvent":
             media_query = models.Q(sport_event=media)
             scrobble_data["sport_event_id"] = media.id
-        if media.__class__.__name__ == "Book":
+        if media_class == "Book":
             media_query = models.Q(book=media)
             scrobble_data["book_id"] = media.id
+        if media_class == "VideoGame":
+            media_query = models.Q(video_game=media)
+            scrobble_data["video_game_id"] = media.id
 
         scrobble = (
             cls.objects.filter(

+ 9 - 1
vrobbler/apps/scrobbles/utils.py

@@ -112,6 +112,14 @@ def check_scrobble_for_finish(
 def get_scrobbles_for_media(media_obj, user: User) -> models.QuerySet:
     Scrobble = apps.get_model(app_label="scrobbles", model_name="Scrobble")
 
-    if media_obj.__class__.__name__ == "Book":
+    media_query = None
+    media_class = media_obj.__class__.__name__
+    if media_class == "Book":
         media_query = models.Q(book=media_obj)
+    if media_class == "VideoGame":
+        media_query = models.Q(video_game=media_obj)
+
+    if not media_query:
+        logger.warn("Do not know about media {media_class} 🙍")
+        return []
     return Scrobble.objects.filter(media_query, user=user)

+ 4 - 0
vrobbler/apps/videogames/howlongtobeat.py

@@ -6,6 +6,10 @@ from howlongtobeatpy import HowLongToBeat
 logger = logging.getLogger(__name__)
 
 
+def hrs_to_secs(hrs: float) -> int:
+    return int(hrs * 60 * 60)
+
+
 def lookup_game_from_hltb(name_or_id: str) -> Optional[dict]:
     """Lookup game on HowLongToBeat.com via HLtB ID or a name string and return
     the data in a dictonary mapped to our internal game fields

+ 26 - 1
vrobbler/apps/videogames/models.py

@@ -1,16 +1,18 @@
 import logging
-from typing import Optional
 from uuid import uuid4
 
 from django.conf import settings
+from django.contrib.auth import get_user_model
 from django.db import models
 from django.urls import reverse
 from django_extensions.db.models import TimeStampedModel
 from scrobbles.mixins import ScrobblableMixin
 
+from vrobbler.apps.scrobbles.utils import get_scrobbles_for_media
 
 logger = logging.getLogger(__name__)
 BNULL = {"blank": True, "null": True}
+User = get_user_model()
 
 
 class VideoGamePlatform(TimeStampedModel):
@@ -93,6 +95,24 @@ class VideoGame(ScrobblableMixin):
     def hltb_link(self):
         return f"https://howlongtobeat.com/game/{self.hltb_id}"
 
+    @property
+    def seconds_for_completion(self) -> int:
+        completion_time = self.run_time_ticks
+        if not completion_time:
+            # Default to 10 hours, why not
+            completion_time = 10 * 60 * 60
+        return int(completion_time * (self.COMPLETION_PERCENT / 100))
+
+    def progress_for_user(self, user_id: int) -> int:
+        """Used to keep track of whether the game is complete or not"""
+        user = User.objects.get(id=user_id)
+        last_scrobble = get_scrobbles_for_media(self, user).last()
+        if not last_scrobble or not last_scrobble.playback_position:
+            logger.warn("No total minutes in last scrobble, no progress")
+            return 0
+        sec_played = last_scrobble.playback_position * 60
+        return int(sec_played / self.run_time) * 100
+
     def fix_metadata(
         self,
         force_update: bool = False,
@@ -107,3 +127,8 @@ class VideoGame(ScrobblableMixin):
 
         if self.igdb_id:
             load_game_data_from_igdb(self.id)
+
+        if (not self.run_time_ticks or force_update) and self.main_story_time:
+            self.run_time_ticks = self.main_story_time * 1000  # miliseconds
+            self.run_time = self.main_story_time
+            self.save(update_fields=["run_time_ticks", "run_time"])

+ 0 - 4
vrobbler/apps/videogames/utils.py

@@ -11,10 +11,6 @@ from videogames.igdb import lookup_game_from_igdb
 logger = logging.getLogger(__name__)
 
 
-def hrs_to_secs(hrs: float) -> int:
-    return int(hrs * 60 * 60)
-
-
 def get_or_create_videogame(
     name_or_id: str, force_update=False
 ) -> Optional[VideoGame]: