Bladeren bron

[scrobbles] Radically simplify stopping ... may need to roll this back

Colin Powell 1 jaar geleden
bovenliggende
commit
e47f4905e8
3 gewijzigde bestanden met toevoegingen van 52 en 67 verwijderingen
  1. 1 1
      vrobbler/apps/music/models.py
  2. 51 18
      vrobbler/apps/scrobbles/models.py
  3. 0 48
      vrobbler/apps/scrobbles/utils.py

+ 1 - 1
vrobbler/apps/music/models.py

@@ -404,7 +404,7 @@ class Album(TimeStampedModel):
 
 
 class Track(ScrobblableMixin):
-    COMPLETION_PERCENT = getattr(settings, "MUSIC_COMPLETION_PERCENT", 95)
+    COMPLETION_PERCENT = getattr(settings, "MUSIC_COMPLETION_PERCENT", 99)
 
     class Opinion(models.IntegerChoices):
         DOWN = -1, "Thumbs down"

+ 51 - 18
vrobbler/apps/scrobbles/models.py

@@ -32,10 +32,7 @@ from profiles.utils import (
 )
 from scrobbles.constants import LONG_PLAY_MEDIA
 from scrobbles.stats import build_charts
-from scrobbles.utils import (
-    check_scrobble_for_finish,
-    media_class_to_foreign_key,
-)
+from scrobbles.utils import media_class_to_foreign_key
 from sports.models import SportEvent
 from videogames import retroarch
 from videogames.models import VideoGame
@@ -961,46 +958,60 @@ class Scrobble(TimeStampedModel):
         return [s.geo_location for s in past_scrobbles]
 
     def update(self, scrobble_data: dict) -> "Scrobble":
+        # Status is a field we get from Mopidy, which refuses to poll us
+        scrobble_status = scrobble_data.pop("mopidy_status", None)
+        if not scrobble_status:
+            scrobble_status = scrobble_data.pop("jellyfin_status", None)
+
         logger.info(
-            "[scrobbling] update",
+            "[scrobbling] update called",
             extra={
                 "scrobble_id": self.id,
                 "scrobble_data": scrobble_data,
                 "media_type": self.media_type,
+                "scrobble_status": scrobble_status,
             },
         )
-        # Status is a field we get from Mopidy, which refuses to poll us
-        scrobble_status = scrobble_data.pop("mopidy_status", None)
-        if not scrobble_status:
-            scrobble_status = scrobble_data.pop("jellyfin_status", None)
 
-        if self.percent_played < 100:
-            # Only worry about ticks if we haven't gotten to the end
-            self.update_ticks(scrobble_data)
+        # This is really expensive on the DB ... do we need to track this?
+        # if self.percent_played < 100:
+        #    # Only worry about ticks if we haven't gotten to the end
+        #    self.update_ticks(scrobble_data)
+
+        if self.beyond_completion_percent:
+            scrobble_status = "stopped"
 
-        # On stop, stop progress and send it to the check for completion
         if scrobble_status == "stopped":
             self.stop()
-        # On pause, set is_paused and stop scrobbling
         if scrobble_status == "paused":
             self.pause()
         if scrobble_status == "resumed":
             self.resume()
 
-        check_scrobble_for_finish(self)
-
         if scrobble_status != "resumed":
             scrobble_data["stop_timestamp"] = (
                 scrobble_data.pop("timestamp", None) or timezone.now()
             )
 
+        # timestamp is should be more-or-less immutable
         scrobble_data.pop("timestamp", None)
+
         update_fields = []
         for key, value in scrobble_data.items():
             setattr(self, key, value)
             update_fields.append(key)
         self.save(update_fields=update_fields)
 
+        logger.info(
+            "[scrobbling] update finished",
+            extra={
+                "scrobble_id": self.id,
+                "scrobble_data": scrobble_data,
+                "scrobble_status": scrobble_status,
+                "media_type": self.media_type,
+            },
+        )
+
         return self
 
     @classmethod
@@ -1016,9 +1027,9 @@ class Scrobble(TimeStampedModel):
 
     def stop(self, force_finish=False) -> None:
         self.stop_timestamp = timezone.now()
-        if force_finish:
-            self.played_to_completion = True
+        self.played_to_completion = True
         self.in_progress = False
+
         if not self.playback_position_seconds:
             self.playback_position_seconds = int(
                 (self.stop_timestamp - self.timestamp).total_seconds()
@@ -1110,3 +1121,25 @@ class Scrobble(TimeStampedModel):
                 "scrobble_id": self.id,
             },
         )
+
+    @property
+    def beyond_completion_percent(self) -> bool:
+        """Returns true if our media is beyond our completion percent, unless
+        our type is geolocation in which case we always return false
+        """
+        beyond_completion = (
+            self.percent_played >= self.media_obj.COMPLETION_PERCENT
+        )
+
+        if self.media_type == "GeoLocation":
+            logger.info(
+                f"[scrobbling] locations are ONLY completed when new one is created",
+                extra={
+                    "scrobble_id": self.id,
+                    "media_type": self.media_type,
+                    "beyond_completion": beyond_completion,
+                },
+            )
+            beyond_completion = False
+
+        return beyond_completion

+ 0 - 48
vrobbler/apps/scrobbles/utils.py

@@ -88,54 +88,6 @@ def parse_mopidy_uri(uri: str) -> dict:
     }
 
 
-def check_scrobble_for_finish(
-    scrobble: "Scrobble", force_to_100=False, force_finish=False
-) -> None:
-    completion_percent = scrobble.media_obj.COMPLETION_PERCENT
-
-    if scrobble.media_type == "GeoLocation" and not force_finish:
-        logger.info(
-            f"[scrobbling] not complete, locations are ONLY completed when new one is created, use force_finish",
-            extra={
-                "scrobble_id": scrobble.id,
-                "media_type": scrobble.media_type,
-            },
-        )
-        return
-
-    is_complete = False
-    if scrobble.percent_played >= completion_percent or force_finish:
-        is_complete = True
-        # A hack to fix overruns on time ... default to media taking as long as needed to finish
-        scrobble.playback_position_seconds = (
-            scrobble.media_obj.run_time_seconds
-        )
-
-        scrobble.in_progress = False
-        scrobble.is_paused = False
-        scrobble.played_to_completion = True
-
-        scrobble.save(
-            update_fields=[
-                "in_progress",
-                "is_paused",
-                "played_to_completion",
-                "playback_position_seconds",
-            ]
-        )
-    logger.info(
-        f"[scrobbling] checked for completion",
-        extra={
-            "scrobble_id": scrobble.id,
-            "media_type": scrobble.media_type,
-            "percent_played": scrobble.percent_played,
-            "completion_percent": completion_percent,
-            "is_complete": is_complete,
-            "force_finish": force_finish,
-        },
-    )
-
-
 def get_scrobbles_for_media(media_obj, user: User) -> models.QuerySet:
     Scrobble = apps.get_model(app_label="scrobbles", model_name="Scrobble")