[videos] Add youtube scrobbling
This commit is contained in:
@ -1186,7 +1186,7 @@ class Scrobble(TimeStampedModel):
|
||||
profile = UserProfile.objects.filter(
|
||||
user_id=scrobble_data["user_id"]
|
||||
).first()
|
||||
if profile.ntfy_enabled and profile.ntfy_url:
|
||||
if profile and profile.ntfy_enabled and profile.ntfy_url:
|
||||
# TODO allow prority and tags to be configured in the profile
|
||||
notify_str = f"{scrobble.media_obj}"
|
||||
if scrobble.log and scrobble.log.get("description"):
|
||||
|
||||
@ -2,6 +2,7 @@ import logging
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from datetime import datetime
|
||||
import pendulum
|
||||
import pytz
|
||||
from beers.models import Beer
|
||||
@ -133,6 +134,49 @@ def jellyfin_scrobble_media(
|
||||
)
|
||||
|
||||
|
||||
def web_scrobbler_scrobble_media(
|
||||
post_data: dict, user_id: int
|
||||
) -> Optional[Scrobble]:
|
||||
media_type = Scrobble.MediaType.VIDEO
|
||||
|
||||
event_name = post_data.get("eventName")
|
||||
parsed = post_data.get("data").get("song").get("parsed")
|
||||
processed = post_data.get("data").get("song").get("processed")
|
||||
video, created = Video.objects.get_or_create(
|
||||
video_type=Video.VideoType.YOUTUBE,
|
||||
youtube_url=parsed.get("originUrl"),
|
||||
)
|
||||
timestamp = datetime.utcfromtimestamp(
|
||||
post_data.get("time", 0)/1000
|
||||
).replace(tzinfo=pytz.utc)
|
||||
|
||||
if created or event_name == "nowplaying":
|
||||
video.run_time_seconds = 1800
|
||||
processed = post_data.get("data").get("song").get("processed")
|
||||
# TODO maybe artist could be the series?
|
||||
video.title = " - ".join([processed.get("artist"), processed.get("track")])
|
||||
video.save()
|
||||
return video.scrobble_for_user(
|
||||
user_id,
|
||||
source="YouTube",
|
||||
playback_position_seconds=0,
|
||||
status=event_name,
|
||||
)
|
||||
|
||||
scrobble = Scrobble.objects.filter(user_id=user_id, video=video, in_progress=True).first()
|
||||
if not scrobble:
|
||||
return video.scrobble_for_user(
|
||||
user_id,
|
||||
source="YouTube",
|
||||
playback_position_seconds=0,
|
||||
status=event_name,
|
||||
)
|
||||
if event_name == "paused":
|
||||
scrobble.pause()
|
||||
if event_name == "resumedplaying":
|
||||
scrobble.resume()
|
||||
return scrobble
|
||||
|
||||
def manual_scrobble_video(imdb_id: str, user_id: int):
|
||||
if "tt" not in imdb_id:
|
||||
imdb_id = "tt" + imdb_id
|
||||
|
||||
@ -31,6 +31,11 @@ urlpatterns = [
|
||||
views.lastfm_import,
|
||||
name="lastfm-import",
|
||||
),
|
||||
path(
|
||||
"webhook/web-scrobbler/",
|
||||
views.web_scrobbler_webhook,
|
||||
name="web-scrobbler-webhook",
|
||||
),
|
||||
path(
|
||||
"webhook/gps/",
|
||||
views.gps_webhook,
|
||||
|
||||
@ -314,6 +314,29 @@ def lastfm_import(request):
|
||||
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
|
||||
|
||||
@csrf_exempt
|
||||
@permission_classes([IsAuthenticated])
|
||||
@api_view(["POST"])
|
||||
def web_scrobbler_webhook(request):
|
||||
post_data = request.data
|
||||
logger.info(
|
||||
"[web_scrobbler_webhook] called",
|
||||
extra={
|
||||
"post_data": post_data,
|
||||
"user_id": request.user.id,
|
||||
},
|
||||
)
|
||||
|
||||
scrobble = web_scrobbler_scrobble_media(post_data, request.user.id)
|
||||
|
||||
if not scrobble:
|
||||
return Response({}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
logger.info(
|
||||
"[jellyfin_webhook] finished",
|
||||
extra={"scrobble_id": scrobble.id},
|
||||
)
|
||||
return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
|
||||
|
||||
@csrf_exempt
|
||||
@permission_classes([IsAuthenticated])
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
# Generated by Django 4.2.16 on 2024-11-06 03:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("videos", "0017_alter_video_video_type"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="video",
|
||||
name="youtube_url",
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="video",
|
||||
name="video_type",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("U", "Unknown"),
|
||||
("E", "TV Episode"),
|
||||
("M", "Movie"),
|
||||
("S", "Skate Video"),
|
||||
("Y", "YouTube Video"),
|
||||
],
|
||||
default="U",
|
||||
max_length=1,
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -128,6 +128,7 @@ class Video(ScrobblableMixin):
|
||||
TV_EPISODE = "E", _("TV Episode")
|
||||
MOVIE = "M", _("Movie")
|
||||
SKATE_VIDEO = "S", _("Skate Video")
|
||||
YOUTUBE = "Y", _("YouTube Video")
|
||||
|
||||
video_type = models.CharField(
|
||||
max_length=1,
|
||||
@ -161,6 +162,7 @@ class Video(ScrobblableMixin):
|
||||
tvrage_id = models.CharField(max_length=20, **BNULL)
|
||||
tvdb_id = models.CharField(max_length=20, **BNULL)
|
||||
tmdb_id = models.CharField(max_length=20, **BNULL)
|
||||
youtube_url = models.CharField(max_length=255, **BNULL)
|
||||
plot = models.TextField(**BNULL)
|
||||
year = models.IntegerField(**BNULL)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user