Clean up URLs and templates
This commit is contained in:
@ -4,6 +4,21 @@ from scrobbles import views
|
|||||||
app_name = 'scrobbles'
|
app_name = 'scrobbles'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path(
|
||||||
|
'manual/imdb/',
|
||||||
|
views.ManualScrobbleView.as_view(),
|
||||||
|
name='imdb-manual-scrobble',
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'manual/audioscrobbler/',
|
||||||
|
views.AudioScrobblerImportCreateView.as_view(),
|
||||||
|
name='audioscrobbler-file-upload',
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'manual/koreader/',
|
||||||
|
views.KoReaderImportCreateView.as_view(),
|
||||||
|
name='koreader-file-upload',
|
||||||
|
),
|
||||||
path('finish/<slug:uuid>', views.scrobble_finish, name='finish'),
|
path('finish/<slug:uuid>', views.scrobble_finish, name='finish'),
|
||||||
path('cancel/<slug:uuid>', views.scrobble_cancel, name='cancel'),
|
path('cancel/<slug:uuid>', views.scrobble_cancel, name='cancel'),
|
||||||
path(
|
path(
|
||||||
|
|||||||
@ -4,6 +4,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.db.models.fields import timezone
|
from django.db.models.fields import timezone
|
||||||
from django.http import FileResponse, HttpResponseRedirect, JsonResponse
|
from django.http import FileResponse, HttpResponseRedirect, JsonResponse
|
||||||
@ -28,6 +29,7 @@ from rest_framework.decorators import (
|
|||||||
from rest_framework.parsers import MultiPartParser
|
from rest_framework.parsers import MultiPartParser
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from scrobbles.api import serializers
|
||||||
from scrobbles.constants import (
|
from scrobbles.constants import (
|
||||||
JELLYFIN_AUDIO_ITEM_TYPES,
|
JELLYFIN_AUDIO_ITEM_TYPES,
|
||||||
JELLYFIN_VIDEO_ITEM_TYPES,
|
JELLYFIN_VIDEO_ITEM_TYPES,
|
||||||
@ -49,7 +51,6 @@ from scrobbles.scrobblers import (
|
|||||||
mopidy_scrobble_podcast,
|
mopidy_scrobble_podcast,
|
||||||
mopidy_scrobble_track,
|
mopidy_scrobble_track,
|
||||||
)
|
)
|
||||||
from scrobbles.api import serializers
|
|
||||||
from scrobbles.tasks import (
|
from scrobbles.tasks import (
|
||||||
process_koreader_import,
|
process_koreader_import,
|
||||||
process_lastfm_import,
|
process_lastfm_import,
|
||||||
@ -295,39 +296,48 @@ def import_audioscrobbler_file(request):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
|
||||||
@permission_classes([IsAuthenticated])
|
@permission_classes([IsAuthenticated])
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def scrobble_finish(request, uuid):
|
def scrobble_finish(request, uuid):
|
||||||
user = request.user
|
user = request.user
|
||||||
|
success_url = reverse_lazy('vrobbler-home')
|
||||||
|
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return Response({}, status=status.HTTP_403_FORBIDDEN)
|
return HttpResponseRedirect(success_url)
|
||||||
|
|
||||||
scrobble = Scrobble.objects.filter(user=user, uuid=uuid).first()
|
scrobble = Scrobble.objects.filter(user=user, uuid=uuid).first()
|
||||||
if not scrobble:
|
if scrobble:
|
||||||
return Response({}, status=status.HTTP_404_NOT_FOUND)
|
scrobble.stop(force_finish=True)
|
||||||
scrobble.stop(force_finish=True)
|
messages.add_message(
|
||||||
return Response(
|
request,
|
||||||
{'id': scrobble.id, 'status': scrobble.status},
|
messages.SUCCESS,
|
||||||
status=status.HTTP_200_OK,
|
f"Scrobble of {scrobble.media_obj} finished.",
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
messages.add_message(request, messages.ERROR, "Scrobble not found.")
|
||||||
|
return HttpResponseRedirect(success_url)
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
|
||||||
@permission_classes([IsAuthenticated])
|
@permission_classes([IsAuthenticated])
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def scrobble_cancel(request, uuid):
|
def scrobble_cancel(request, uuid):
|
||||||
user = request.user
|
user = request.user
|
||||||
|
success_url = reverse_lazy('vrobbler-home')
|
||||||
|
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return Response({}, status=status.HTTP_403_FORBIDDEN)
|
return HttpResponseRedirect(success_url)
|
||||||
|
|
||||||
scrobble = Scrobble.objects.filter(user=user, uuid=uuid).first()
|
scrobble = Scrobble.objects.filter(user=user, uuid=uuid).first()
|
||||||
if not scrobble:
|
if scrobble:
|
||||||
return Response({}, status=status.HTTP_404_NOT_FOUND)
|
scrobble.cancel()
|
||||||
scrobble.cancel()
|
messages.add_message(
|
||||||
return Response(
|
request,
|
||||||
{'id': scrobble.id, 'status': 'cancelled'}, status=status.HTTP_200_OK
|
messages.SUCCESS,
|
||||||
)
|
f"Scrobble of {scrobble.media_obj} cancelled.",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
messages.add_message(request, messages.ERROR, "Scrobble not found.")
|
||||||
|
return HttpResponseRedirect(success_url)
|
||||||
|
|
||||||
|
|
||||||
@permission_classes([IsAuthenticated])
|
@permission_classes([IsAuthenticated])
|
||||||
|
|||||||
@ -140,6 +140,8 @@ TEMPLATES = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
MESSAGE_STORAGE = "django.contrib.messages.storage.session.SessionStorage"
|
||||||
|
|
||||||
WSGI_APPLICATION = "vrobbler.wsgi.application"
|
WSGI_APPLICATION = "vrobbler.wsgi.application"
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
|
|||||||
@ -177,7 +177,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<form id="scrobble-form" action="{% url 'imdb-manual-scrobble' %}" method="post">
|
<form id="scrobble-form" action="{% url 'scrobbles:imdb-manual-scrobble' %}" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ imdb_form }}
|
{{ imdb_form }}
|
||||||
</form>
|
</form>
|
||||||
@ -197,6 +197,13 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
||||||
<div class="position-sticky pt-3">
|
<div class="position-sticky pt-3">
|
||||||
|
{% if messages %}
|
||||||
|
<ul style="padding-right:10px;">
|
||||||
|
{% for message in messages %}
|
||||||
|
<li {% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
{% if now_playing_list and user.is_authenticated %}
|
{% if now_playing_list and user.is_authenticated %}
|
||||||
<ul style="padding-right:10px;">
|
<ul style="padding-right:10px;">
|
||||||
<b>Now playing</b>
|
<b>Now playing</b>
|
||||||
@ -219,8 +226,6 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<ul class="nav flex-column">
|
<ul class="nav flex-column">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link active" aria-current="page" href="/">
|
<a class="nav-link active" aria-current="page" href="/">
|
||||||
@ -271,6 +276,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/feather-icons@4.28.0/dist/feather.min.js" integrity="sha384-uO3SXW5IuS1ZpFPKugNNWqTZRRglnUJK6UAZ/gxOX80nxEkN9NcGZTftn6RzhGWE" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js" integrity="sha384-zNy6FEbO50N+Cg5wap8IKA4M/ZnLJgzc6w2NqACZaK0u0FXfOWRRJOnQtpZun8ha" crossorigin="anonymous"></script>
|
<script src="https://cdn.jsdelivr.net/npm/feather-icons@4.28.0/dist/feather.min.js" integrity="sha384-uO3SXW5IuS1ZpFPKugNNWqTZRRglnUJK6UAZ/gxOX80nxEkN9NcGZTftn6RzhGWE" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js" integrity="sha384-zNy6FEbO50N+Cg5wap8IKA4M/ZnLJgzc6w2NqACZaK0u0FXfOWRRJOnQtpZun8ha" crossorigin="anonymous"></script>
|
||||||
<script><!-- comment ------------------------------------------------->
|
<script><!-- comment ------------------------------------------------->
|
||||||
/* globals Chart:false, feather:false */
|
/* globals Chart:false, feather:false */
|
||||||
|
|||||||
@ -316,7 +316,7 @@
|
|||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="{% url 'audioscrobbler-file-upload' %}" method="post" enctype="multipart/form-data">
|
<form action="{% url 'scrobbles:audioscrobbler-file-upload' %}" method="post" enctype="multipart/form-data">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -328,7 +328,7 @@
|
|||||||
<button type="submit" class="btn btn-primary">Import</button>
|
<button type="submit" class="btn btn-primary">Import</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<form action="{% url 'koreader-file-upload' %}" method="post" enctype="multipart/form-data">
|
<form action="{% url 'scrobbles:koreader-file-upload' %}" method="post" enctype="multipart/form-data">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main class="col-md-4 ms-sm-auto col-lg-10 px-md-4">
|
<main class="col-md-4 ms-sm-auto col-lg-10 px-md-4">
|
||||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
<div
|
||||||
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||||
<h1 class="h2">Manual scrobble</h1>
|
<h1 class="h2">Manual scrobble</h1>
|
||||||
<form action="{% url 'audioscrobbler-file-upload' %}" method="post">
|
<form action="{% url 'scrobbles:audioscrobbler-file-upload' %}" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form }}
|
{{ form }}
|
||||||
<input type="submit" value="Submit">
|
<input type="submit" value="Submit">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -43,23 +43,9 @@ urlpatterns = [
|
|||||||
path('api/v1/auth', include("rest_framework.urls")),
|
path('api/v1/auth', include("rest_framework.urls")),
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("accounts/", include("allauth.urls")),
|
path("accounts/", include("allauth.urls")),
|
||||||
path(
|
|
||||||
'manual/imdb/',
|
|
||||||
scrobbles_views.ManualScrobbleView.as_view(),
|
|
||||||
name='imdb-manual-scrobble',
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'manual/audioscrobbler/',
|
|
||||||
scrobbles_views.AudioScrobblerImportCreateView.as_view(),
|
|
||||||
name='audioscrobbler-file-upload',
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'manual/koreader/',
|
|
||||||
scrobbles_views.KoReaderImportCreateView.as_view(),
|
|
||||||
name='koreader-file-upload',
|
|
||||||
),
|
|
||||||
path("", include(music_urls, namespace="music")),
|
path("", include(music_urls, namespace="music")),
|
||||||
path("", include(video_urls, namespace="videos")),
|
path("", include(video_urls, namespace="videos")),
|
||||||
|
path("", include(scrobble_urls, namespace="scrobbles")),
|
||||||
path(
|
path(
|
||||||
"", scrobbles_views.RecentScrobbleList.as_view(), name="vrobbler-home"
|
"", scrobbles_views.RecentScrobbleList.as_view(), name="vrobbler-home"
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user