Prechádzať zdrojové kódy

Allow scrobbling video games

Colin Powell 2 rokov pred
rodič
commit
a4537879f9

+ 22 - 0
vrobbler/apps/scrobbles/scrobblers.py

@@ -15,6 +15,7 @@ from scrobbles.models import Scrobble
 from scrobbles.utils import convert_to_seconds, parse_mopidy_uri
 from sports.models import SportEvent
 from videos.models import Video
+from videogames.models import VideoGame
 
 logger = logging.getLogger(__name__)
 
@@ -200,3 +201,24 @@ def manual_scrobble_event(data_dict: dict, user_id: Optional[int]):
     scrobble_dict = build_scrobble_dict(data_dict, user_id)
 
     return Scrobble.create_or_update(event, user_id, scrobble_dict)
+
+
+def manual_scrobble_video_game(data_dict: dict, user_id: Optional[int]):
+    game = VideoGame.find_or_create(data_dict)
+
+    last_scrobble = Scrobble.objects.filter(
+        video_game=game, user_id=user_id, played_to_completion=True
+    ).last()
+
+    playback_position = 0
+    if last_scrobble and not last_scrobble.playback_position:
+        playback_position = last_scrobble.playback_position + (30 * 60)
+    scrobble_dict = {
+        "user_id": user_id,
+        "timestamp": timezone.now(),
+        "playback_position_ticks": playback_position * 1000,
+        "playback_position": playback_position,
+        "source": "Vrobbler",
+    }
+
+    return Scrobble.create_or_update(game, user_id, scrobble_dict)

+ 10 - 6
vrobbler/apps/scrobbles/views.py

@@ -46,6 +46,7 @@ from scrobbles.scrobblers import (
     jellyfin_scrobble_video,
     manual_scrobble_event,
     manual_scrobble_video,
+    manual_scrobble_video_game,
     mopidy_scrobble_podcast,
     mopidy_scrobble_track,
 )
@@ -56,6 +57,7 @@ from scrobbles.tasks import (
 )
 from sports.thesportsdb import lookup_event_from_thesportsdb
 from videos.imdb import lookup_video_from_imdb
+from videogames.howlongtobeat import lookup_game_from_hltb
 
 logger = logging.getLogger(__name__)
 
@@ -180,20 +182,22 @@ class ManualScrobbleView(FormView):
         item_id = form.cleaned_data.get("item_id")
         data_dict = None
         if "tt" in item_id:
-            data_dict = lookup_video_from_imdb(
-                form.cleaned_data.get("item_id")
-            )
+            data_dict = lookup_video_from_imdb(item_id)
             if data_dict:
                 manual_scrobble_video(data_dict, self.request.user.id)
 
         if not data_dict:
             logger.debug(f"Looking for sport event with ID {item_id}")
-            data_dict = lookup_event_from_thesportsdb(
-                form.cleaned_data.get("item_id")
-            )
+            data_dict = lookup_event_from_thesportsdb(item_id)
             if data_dict:
                 manual_scrobble_event(data_dict, self.request.user.id)
 
+        if not data_dict:
+            logger.debug(f"Looking for video game with ID {item_id}")
+            data_dict = lookup_game_from_hltb(item_id)
+            if data_dict:
+                manual_scrobble_video_game(data_dict, self.request.user.id)
+
         return HttpResponseRedirect(reverse("vrobbler-home"))
 
 

+ 5 - 1
vrobbler/apps/sports/thesportsdb.py

@@ -14,7 +14,11 @@ client = TheSportsDbClient(api_key=API_KEY)
 
 def lookup_event_from_thesportsdb(event_id: str) -> dict:
 
-    event = client.lookup_event(event_id)["events"][0]
+    try:
+        event = client.lookup_event(event_id)["events"][0]
+    except TypeError:
+        return {}
+
     if not event or type(event) != dict:
         return {}
     league = {}  # client.lookup_league(league_id=event.get('idLeague'))

+ 7 - 2
vrobbler/apps/videogames/models.py

@@ -7,8 +7,7 @@ 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
+from scrobbles.utils import get_scrobbles_for_media
 
 logger = logging.getLogger(__name__)
 BNULL = {"blank": True, "null": True}
@@ -132,3 +131,9 @@ class VideoGame(ScrobblableMixin):
             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"])
+
+    @classmethod
+    def find_or_create(cls, data_dict: dict) -> "Game":
+        from videogames.utils import get_or_create_videogame
+
+        return get_or_create_videogame(data_dict.get("hltb_id"))

+ 14 - 0
vrobbler/apps/videogames/urls.py

@@ -0,0 +1,14 @@
+from django.urls import path
+from videogames import views
+
+app_name = "videogames"
+
+
+urlpatterns = [
+    path("game/", views.VideoGameListView.as_view(), name="videogame_list"),
+    path(
+        "game/<slug:slug>/",
+        views.VideoGameDetailView.as_view(),
+        name="videogame_detail",
+    ),
+]

+ 12 - 0
vrobbler/apps/videogames/views.py

@@ -0,0 +1,12 @@
+from django.views import generic
+from videogames.models import VideoGame
+
+
+class VideoGameListView(generic.ListView):
+    model = VideoGame
+    paginate_by = 20
+
+
+class VideoGameDetailView(generic.DetailView):
+    model = VideoGame
+    slug_field = "uuid"

+ 2 - 0
vrobbler/urls.py

@@ -6,6 +6,7 @@ import vrobbler.apps.scrobbles.views as scrobbles_views
 from vrobbler.apps.books.api.views import AuthorViewSet, BookViewSet
 from vrobbler.apps.music import urls as music_urls
 from vrobbler.apps.sports import urls as sports_urls
+from vrobbler.apps.videogames import urls as videogame_urls
 from vrobbler.apps.music.api.views import (
     AlbumViewSet,
     ArtistViewSet,
@@ -58,6 +59,7 @@ urlpatterns = [
     path("accounts/", include("allauth.urls")),
     path("", include(music_urls, namespace="music")),
     path("", include(video_urls, namespace="videos")),
+    path("", include(videogame_urls, namespace="videogames")),
     path("", include(sports_urls, namespace="sports")),
     path("", include(scrobble_urls, namespace="scrobbles")),
     path(