Allow starting next in series
This commit is contained in:
@ -229,7 +229,7 @@ class ManualScrobbleView(FormView):
|
||||
if key == "-i":
|
||||
manual_scrobble_video(item_id, self.request.user.id)
|
||||
|
||||
return HttpResponseRedirect(reverse("vrobbler-home"))
|
||||
return HttpResponseRedirect(self.request.META.get("HTTP_REFERER"))
|
||||
|
||||
|
||||
class JsonableResponseMixin:
|
||||
@ -272,7 +272,7 @@ class AudioScrobblerImportCreateView(
|
||||
self.object.user = self.request.user
|
||||
self.object.save()
|
||||
process_tsv_import.delay(self.object.id)
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
return HttpResponseRedirect(self.request.META.get("HTTP_REFERER"))
|
||||
|
||||
|
||||
class KoReaderImportCreateView(
|
||||
@ -288,7 +288,7 @@ class KoReaderImportCreateView(
|
||||
self.object.user = self.request.user
|
||||
self.object.save()
|
||||
process_koreader_import.delay(self.object.id)
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
return HttpResponseRedirect(self.request.META.get("HTTP_REFERER"))
|
||||
|
||||
|
||||
@permission_classes([IsAuthenticated])
|
||||
@ -300,8 +300,7 @@ def lastfm_import(request):
|
||||
|
||||
process_lastfm_import.delay(lfm_import.id)
|
||||
|
||||
success_url = reverse_lazy("vrobbler-home")
|
||||
return HttpResponseRedirect(success_url)
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@ -394,6 +393,7 @@ def scrobble_start(request, uuid):
|
||||
success_url = request.META.get("HTTP_REFERER")
|
||||
|
||||
if not user.is_authenticated:
|
||||
|
||||
return HttpResponseRedirect(success_url)
|
||||
|
||||
media_obj = None
|
||||
@ -506,7 +506,7 @@ def scrobble_cancel(request, uuid):
|
||||
)
|
||||
else:
|
||||
messages.add_message(request, messages.ERROR, "Scrobble not found.")
|
||||
return HttpResponseRedirect(success_url)
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
|
||||
|
||||
|
||||
@permission_classes([IsAuthenticated])
|
||||
|
||||
21
vrobbler/apps/videos/migrations/0013_video_next_imdb_id.py
Normal file
21
vrobbler/apps/videos/migrations/0013_video_next_imdb_id.py
Normal file
@ -0,0 +1,21 @@
|
||||
# Generated by Django 4.1.5 on 2023-03-15 17:52
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
(
|
||||
"videos",
|
||||
"0012_remove_series_tags_remove_video_tags_series_genre_and_more",
|
||||
),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="video",
|
||||
name="next_imdb_id",
|
||||
field=models.CharField(blank=True, max_length=20, null=True),
|
||||
),
|
||||
]
|
||||
@ -1,5 +1,5 @@
|
||||
import logging
|
||||
from typing import Dict
|
||||
from typing import Dict, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
import requests
|
||||
@ -40,13 +40,33 @@ class Series(TimeStampedModel):
|
||||
def imdb_link(self):
|
||||
return f"https://www.imdb.com/title/tt{self.imdb_id}"
|
||||
|
||||
def scrobbles_for_user(self, user_id: int):
|
||||
def scrobbles_for_user(self, user_id: int, include_playing=False):
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
played_query = models.Q(played_to_completion=True)
|
||||
if include_playing:
|
||||
played_query = models.Q()
|
||||
return Scrobble.objects.filter(
|
||||
video__tv_series=self, user=user_id, played_to_completion=True
|
||||
played_query,
|
||||
video__tv_series=self,
|
||||
user=user_id,
|
||||
).order_by("-timestamp")
|
||||
|
||||
def last_scrobbled_episode(self, user_id: int) -> Optional["Video"]:
|
||||
episode = None
|
||||
last_scrobble = self.scrobbles_for_user(
|
||||
user_id, include_playing=True
|
||||
).first()
|
||||
if last_scrobble:
|
||||
episode = last_scrobble.media_obj
|
||||
return episode
|
||||
|
||||
def is_episode_playing(self, user_id: int) -> bool:
|
||||
last_scrobble = self.scrobbles_for_user(
|
||||
user_id, include_playing=True
|
||||
).first()
|
||||
return not last_scrobble.played_to_completion
|
||||
|
||||
def fix_metadata(self, force_update=False):
|
||||
name_or_id = self.name
|
||||
if self.imdb_id:
|
||||
@ -95,6 +115,7 @@ class Video(ScrobblableMixin):
|
||||
tv_series = models.ForeignKey(Series, on_delete=models.DO_NOTHING, **BNULL)
|
||||
season_number = models.IntegerField(**BNULL)
|
||||
episode_number = models.IntegerField(**BNULL)
|
||||
next_imdb_id = models.CharField(max_length=20, **BNULL)
|
||||
imdb_id = models.CharField(max_length=20, **BNULL)
|
||||
imdb_rating = models.FloatField(**BNULL)
|
||||
cover_image = models.ImageField(upload_to="videos/video/", **BNULL)
|
||||
|
||||
@ -37,6 +37,7 @@ def get_or_create_video(name_or_id: str, force_update=False):
|
||||
"run_time_seconds": run_time_seconds,
|
||||
"episode_number": imdb_dict.get("episode", None),
|
||||
"season_number": imdb_dict.get("season", None),
|
||||
"next_imdb_id": imdb_dict.get("next episode", None),
|
||||
"tv_series_id": series.id if series else None,
|
||||
}
|
||||
Video.objects.filter(pk=video.id).update(**video_dict)
|
||||
|
||||
@ -21,11 +21,16 @@ class SeriesDetailView(generic.DetailView):
|
||||
slug_field = "uuid"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
user_id = self.request.user.id
|
||||
context_data = super().get_context_data(**kwargs)
|
||||
|
||||
context_data["scrobbles"] = self.object.scrobbles_for_user(
|
||||
self.request.user.id
|
||||
)
|
||||
context_data["scrobbles"] = self.object.scrobbles_for_user(user_id)
|
||||
next_episode_id = self.object.last_scrobbled_episode(
|
||||
user_id
|
||||
).next_imdb_id
|
||||
if self.object.is_episode_playing(user_id):
|
||||
next_episode_id = None
|
||||
context_data["next_episode_id"] = next_episode_id
|
||||
return context_data
|
||||
|
||||
|
||||
|
||||
@ -28,6 +28,13 @@
|
||||
<div class="cover image-wrapper">
|
||||
{% if object.imdb_rating %}<div class="caption">{{object.imdb_rating}}</div>{% endif %}
|
||||
<img src="{% if object.cover_image %}{{object.cover_image.url}}{% else %}{% static 'images/no-video-cover.jpg' %}{% endif %}" width="400px" />
|
||||
{% if next_episode_id %}
|
||||
<form id="scrobble-form" action="{% url 'scrobbles:lookup-manual-scrobble' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="item_id" id="id_item_id" value="-i {{next_episode_id}}">
|
||||
<button type="submit" class="btn btn-primary">Start next episode</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="summary">
|
||||
{% if object.plot%}<p>{{object.plot|safe|linebreaks|truncatewords:160}}</p>{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user