diff --git a/scrobbles/urls.py b/scrobbles/urls.py index 69d84cf..8cff0fc 100644 --- a/scrobbles/urls.py +++ b/scrobbles/urls.py @@ -4,5 +4,6 @@ from scrobbles import views app_name = 'scrobbles' urlpatterns = [ - path('', views.scrobble_list, name='scrobble-list'), + path('', views.scrobble_endpoint, name='scrobble-list'), + path('jellyfin/', views.jellyfin_websocket, name='jellyfin-websocket'), ] diff --git a/scrobbles/views.py b/scrobbles/views.py index f8738f6..7b64e45 100644 --- a/scrobbles/views.py +++ b/scrobbles/views.py @@ -38,101 +38,101 @@ class RecentScrobbleList(ListView): @csrf_exempt -@api_view(['GET', 'POST']) -def scrobble_list(request): +@api_view(['GET']) +def scrobble_endpoint(request): """List all Scrobbles, or create a new Scrobble""" - if request.method == 'GET': - scrobble = Scrobble.objects.all() - serializer = ScrobbleSerializer(scrobble, many=True) - return Response(serializer.data) + scrobble = Scrobble.objects.all() + serializer = ScrobbleSerializer(scrobble, many=True) + return Response(serializer.data) - elif request.method == 'POST': - data_dict = request.data - media_type = data_dict["ItemType"] - # Check if it's a TV Episode - video_dict = { - "title": data_dict["Name"], - "imdb_id": data_dict["Provider_imdb"], - "video_type": Video.VideoType.MOVIE, - "year": data_dict["Year"], - } - if media_type == 'Episode': - series_name = data_dict["SeriesName"] - series, series_created = Series.objects.get_or_create( - name=series_name - ) - video_dict['video_type'] = Video.VideoType.TV_EPISODE - video_dict["tv_series_id"] = series.id - video_dict["episode_number"] = data_dict["EpisodeNumber"] - video_dict["season_number"] = data_dict["SeasonNumber"] - video_dict["tvdb_id"] = data_dict.get("Provider_tvdb", None) - video_dict["tvrage_id"] = data_dict.get("Provider_tvrage", None) +@csrf_exempt +@api_view(['POST']) +def jellyfin_websocket(request): + data_dict = request.data + media_type = data_dict["ItemType"] + # Check if it's a TV Episode + video_dict = { + "title": data_dict["Name"], + "imdb_id": data_dict["Provider_imdb"], + "video_type": Video.VideoType.MOVIE, + "year": data_dict["Year"], + } + if media_type == 'Episode': + series_name = data_dict["SeriesName"] + series, series_created = Series.objects.get_or_create(name=series_name) - video, video_created = Video.objects.get_or_create(**video_dict) + video_dict['video_type'] = Video.VideoType.TV_EPISODE + video_dict["tv_series_id"] = series.id + video_dict["episode_number"] = data_dict["EpisodeNumber"] + video_dict["season_number"] = data_dict["SeasonNumber"] + video_dict["tvdb_id"] = data_dict.get("Provider_tvdb", None) + video_dict["tvrage_id"] = data_dict.get("Provider_tvrage", None) - if video_created: - video.overview = data_dict["Overview"] - video.tagline = data_dict["Tagline"] - video.run_time_ticks = data_dict["RunTimeTicks"] - video.run_time = data_dict["RunTime"] - video.save() + video, video_created = Video.objects.get_or_create(**video_dict) - # Now we run off a scrobble - timestamp = parse(data_dict["UtcTimestamp"]) - scrobble_dict = { - 'video_id': video.id, - 'user_id': request.user.id, - 'in_progress': True, - } + if video_created: + video.overview = data_dict["Overview"] + video.tagline = data_dict["Tagline"] + video.run_time_ticks = data_dict["RunTimeTicks"] + video.run_time = data_dict["RunTime"] + video.save() - existing_finished_scrobble = ( - Scrobble.objects.filter( - video=video, user_id=request.user.id, in_progress=False - ) - .order_by('-modified') - .first() + # Now we run off a scrobble + timestamp = parse(data_dict["UtcTimestamp"]) + scrobble_dict = { + 'video_id': video.id, + 'user_id': request.user.id, + 'in_progress': True, + } + + existing_finished_scrobble = ( + Scrobble.objects.filter( + video=video, user_id=request.user.id, in_progress=False ) + .order_by('-modified') + .first() + ) - minutes_from_now = timezone.now() + timedelta(minutes=15) + minutes_from_now = timezone.now() + timedelta(minutes=15) - if ( - existing_finished_scrobble - and existing_finished_scrobble.modified < minutes_from_now - ): - logger.info( - 'Found a scrobble for this video less than 15 minutes ago, holding off scrobbling again' - ) - return Response(video_dict, status=status.HTTP_204_NO_CONTENT) - - scrobble, scrobble_created = Scrobble.objects.get_or_create( - **scrobble_dict + if ( + existing_finished_scrobble + and existing_finished_scrobble.modified < minutes_from_now + ): + logger.info( + 'Found a scrobble for this video less than 15 minutes ago, holding off scrobbling again' ) + return Response(video_dict, status=status.HTTP_204_NO_CONTENT) - if scrobble_created: - # If we newly created this, capture the client we're watching from - scrobble.source = data_dict['ClientName'] - scrobble.source_id = data_dict['MediaSourceId'] - else: - last_tick = scrobble.playback_position_ticks + scrobble, scrobble_created = Scrobble.objects.get_or_create( + **scrobble_dict + ) - # Update a found scrobble with new position and timestamp - scrobble.playback_position_ticks = data_dict["PlaybackPositionTicks"] - scrobble.playback_position = data_dict["PlaybackPosition"] - scrobble.timestamp = parse(data_dict["UtcTimestamp"]) - scrobble.is_paused = data_dict["IsPaused"] in TRUTHY_VALUES + if scrobble_created: + # If we newly created this, capture the client we're watching from + scrobble.source = data_dict['ClientName'] + scrobble.source_id = data_dict['MediaSourceId'] + else: + last_tick = scrobble.playback_position_ticks + + # Update a found scrobble with new position and timestamp + scrobble.playback_position_ticks = data_dict["PlaybackPositionTicks"] + scrobble.playback_position = data_dict["PlaybackPosition"] + scrobble.timestamp = parse(data_dict["UtcTimestamp"]) + scrobble.is_paused = data_dict["IsPaused"] in TRUTHY_VALUES + scrobble.save() + + # If we hit our completion threshold, save it and get ready + # to scrobble again if we re-watch this. + if scrobble.percent_played >= getattr( + settings, "PERCENT_FOR_COMPLETION", 95 + ): + scrobble.in_progress = False + scrobble.playback_position_ticks = video.run_time_ticks scrobble.save() - # If we hit our completion threshold, save it and get ready - # to scrobble again if we re-watch this. - if scrobble.percent_played >= getattr( - settings, "PERCENT_FOR_COMPLETION", 95 - ): - scrobble.in_progress = False - scrobble.playback_position_ticks = video.run_time_ticks - scrobble.save() + if scrobble.percent_played % 5 == 0: + logger.info(f"You are {scrobble.percent_played}% through {video}") - if scrobble.percent_played % 5 == 0: - logger.info(f"You are {scrobble.percent_played}% through {video}") - - return Response(video_dict, status=status.HTTP_201_CREATED) + return Response(video_dict, status=status.HTTP_201_CREATED) diff --git a/vrobbler/urls.py b/vrobbler/urls.py index 94571d5..99f546f 100644 --- a/vrobbler/urls.py +++ b/vrobbler/urls.py @@ -21,10 +21,9 @@ urlpatterns = [ path("admin/", admin.site.urls), path("accounts/", include("allauth.urls")), # path("api-auth/", include("rest_framework.urls")), - # path("api/v1/", include(router.urls)), # path("movies/", include(movies, namespace="movies")), # path("shows/", include(shows, namespace="shows")), - path("scrobbles/", include(scrobble_urls, namespace="scrobbles")), + path("api/v1/scrobbles/", include(scrobble_urls, namespace="scrobbles")), path("", RecentScrobbleList.as_view(), name="home"), ]