Upgrades
[audio.git] / src / archive / views.py
index 3da6bb4..6ae2927 100644 (file)
@@ -5,11 +5,14 @@ from urllib.parse import quote
 
 from archive import settings
 from django.contrib.auth.decorators import permission_required
+from django.contrib.postgres.search import SearchVector
 from django.urls import reverse
 from django.db.models import Q, Max
 from django.http import Http404, HttpResponse
 from django.shortcuts import render, redirect, get_object_or_404
+from django.utils.translation import gettext as _
 from django.views.decorators.http import require_POST
+from django.views.generic import ListView
 
 import mutagen
 
@@ -21,8 +24,6 @@ from archive.utils import all_files
 
 
 def list_new(request):
-    division = 'new'
-
     path = settings.NEW_PATH
     objects = sorted(all_files(path))
     return render(request, "archive/list_new.html", locals())
@@ -30,8 +31,6 @@ def list_new(request):
 
 @permission_required('archive.change_audiobook')
 def file_new(request, filename):
-    division = 'new'
-
     filepath = filename
     root_filepath = os.path.join(settings.NEW_PATH, filename)
     if request.POST:
@@ -71,9 +70,8 @@ def file_new(request, filename):
 def move_to_archive(request, filename):
     """ move a new file to the unmanaged files dir """
 
-    filename_str = filename.encode('utf-8')
-    old_path = os.path.join(settings.NEW_PATH, filename_str)
-    new_path = os.path.join(settings.UNMANAGED_PATH, filename_str)
+    old_path = os.path.join(settings.NEW_PATH, filename)
+    new_path = os.path.join(settings.UNMANAGED_PATH, filename)
     new_dir = os.path.split(new_path)[0]
     if not os.path.isdir(new_dir):
         os.makedirs(new_dir)
@@ -132,9 +130,8 @@ def remove_to_archive(request, aid):
 def move_to_new(request, filename):
     """ move a unmanaged file to new files dir """
 
-    filename_str = filename.encode('utf-8')
-    old_path = os.path.join(settings.UNMANAGED_PATH, filename_str)
-    new_path = os.path.join(settings.NEW_PATH, filename_str)
+    old_path = os.path.join(settings.UNMANAGED_PATH, filename)
+    new_path = os.path.join(settings.NEW_PATH, filename)
     new_dir = os.path.split(new_path)[0]
     if not os.path.isdir(new_dir):
         os.makedirs(new_dir)
@@ -158,20 +155,7 @@ def move_to_new(request, filename):
 def publish(request, aid, publish=True):
     """ mark file for publishing """
     audiobook = get_object_or_404(models.Audiobook, id=aid)
-    tags = {
-        'name': audiobook.title,
-        'url': audiobook.url,
-        'tags': audiobook.new_publish_tags(),
-        }
-    audiobook.set_mp3_tags(tags)
-    audiobook.set_ogg_tags(tags)
-    audiobook.mp3_status = audiobook.ogg_status = status.WAITING
-    audiobook.save()
-    # isn't there a race here?
-    audiobook.mp3_task = tasks.Mp3Task.delay(request.user.id, aid, publish).task_id
-    audiobook.ogg_task = tasks.OggTask.delay(request.user.id, aid, publish).task_id
-    audiobook.save()
-
+    audiobook.publish(request.user, publish=publish)
     return redirect(file_managed, aid)
 
 
@@ -184,6 +168,7 @@ def cancel_publishing(request, aid):
     audiobook.mp3_status = None
     audiobook.ogg_status = None
     audiobook.youtube_status = None
+    audiobook.youtube_queued = None
     audiobook.save()
     return redirect(file_managed, aid)
 
@@ -209,35 +194,32 @@ def download(request, aid, which="source"):
     return response
 
 
-def list_unpublished(request):
-    division = 'unpublished'
-
-    objects = models.Audiobook.objects.filter(Q(mp3_published=None) | Q(ogg_published=None))
-    return render(request, "archive/list_unpublished.html", locals())
-
-
 def list_publishing(request):
-    division = 'publishing'
-
-    objects = models.Audiobook.objects.exclude(mp3_status=None, ogg_status=None)
+    objects = models.Audiobook.objects.exclude(
+        mp3_status=None, ogg_status=None, youtube_status=None
+    ).order_by("youtube_queued", "title")
     objects_by_status = {}
     for o in objects:
+        statuses = set()
         if o.mp3_status:
-            k = o.mp3_status, o.get_mp3_status_display()
-            objects_by_status.setdefault(k, []).append(o)
-        if o.ogg_status and o.ogg_status != o.mp3_status:
-            k = o.ogg_status, o.get_ogg_status_display()
-            objects_by_status.setdefault(k, []).append(o)
+            statuses.add((o.mp3_status, o.get_mp3_status_display()))
+        if o.ogg_status:
+            statuses.add((o.ogg_status, o.get_ogg_status_display()))
+        if o.youtube_status:
+            statuses.add((o.youtube_status, o.get_youtube_status_display()))
+        for status in statuses:
+            objects_by_status.setdefault(status, []).append(o)
     status_objects = sorted(objects_by_status.items(), reverse=True)
 
     return render(request, "archive/list_publishing.html", locals())
 
 
-def list_published(request):
-    division = 'published'
-
-    objects = models.Audiobook.objects.exclude(Q(mp3_published=None) | Q(ogg_published=None))
-    return render(request, "archive/list_published.html", locals())
+class AudiobookList(ListView):
+    def get_queryset(self):
+        qs = models.Audiobook.objects.all()
+        if 's' in self.request.GET:
+            qs = qs.annotate(s=SearchVector('title', 'slug')).filter(s=self.request.GET['s'])
+        return qs
 
 
 @permission_required('archive.change_audiobook')
@@ -252,35 +234,89 @@ def file_managed(request, id):
             except IOError:
                 raise Http404
 
-    division = 'published' if audiobook.published() else 'unpublished'
-    path = audiobook.source_file.path[len(settings.FILES_PATH):].lstrip('/')
+    tags = {}
+    if audiobook.source_file:
+        path = audiobook.source_file.path[len(settings.FILES_PATH):].lstrip('/')
 
-    # for tags update
-    tags = mutagen.File(audiobook.source_file.path.encode('utf-8'))
-    if not tags:
-        tags = {}
+        # for tags update
+        tags = mutagen.File(audiobook.source_file.path.encode('utf-8'))
+        if not tags:
+            tags = {}
     form = AudiobookForm(instance=audiobook)
 
     user_can_publish = (
         request.user.is_authenticated and
         request.user.oauthconnection_set.filter(access=True).exists())
 
+    alerts = []
+    parts_count = audiobook.parts_count
+    if parts_count > 1:
+        series = models.Audiobook.objects.filter(slug=audiobook.slug)
+        if not audiobook.index:
+            alerts.append(_('There is more than one part, but index is not set.'))
+        if set(series.values_list('index', flat=True)) != set(range(1, parts_count + 1)):
+            alerts.append(_('Part indexes are not 1..%(parts_count)d.') % {"parts_count": parts_count})
+
+    from youtube.models import YouTube
+    youtube = YouTube.objects.first()
+    youtube_title = youtube.get_title(audiobook)
+    youtube_description = youtube.get_description(audiobook)
+
+            
     return render(request, "archive/file_managed.html", locals())
 
 
 def list_unmanaged(request):
-    division = 'unmanaged'
-
     objects = sorted(all_files(settings.UNMANAGED_PATH))
     return render(request, "archive/list_unmanaged.html", locals())
 
 
 def file_unmanaged(request, filename):
-    division = 'unmanaged'
-
-    tags = mutagen.File(os.path.join(settings.UNMANAGED_PATH, filename.encode('utf-8')))
+    tags = mutagen.File(os.path.join(settings.UNMANAGED_PATH, filename))
     if not tags:
         tags = {}
     
     err_exists = request.GET.get('exists')
     return render(request, "archive/file_unmanaged.html", locals())
+
+
+class BookView(ListView):
+    template_name = 'archive/book.html'
+
+    def get_queryset(self):
+        qs = models.Audiobook.objects.filter(slug=self.kwargs["slug"]).order_by(
+            "index"
+        )
+        last_vol = None
+        last_vol_sub = None
+        for b in qs:
+            if last_vol is None or last_vol.youtube_volume_index != b.youtube_volume_index:
+                last_vol = b
+                b.total = 0
+                if last_vol_sub is None or b.youtube_volume:
+                    last_vol_sub = last_vol
+                    last_vol_sub.total_for_sub = 0
+            last_vol.total += b.duration
+            last_vol_sub.total_for_sub += b.duration
+            b.subtotal = last_vol_sub.total_for_sub
+        return list(qs)
+
+
+@permission_required('archive.change_audiobook')
+def book_youtube_volume(request, aid):
+    audiobook = get_object_or_404(models.Audiobook, id=aid)
+    slug = audiobook.slug
+    cur_vol = audiobook.youtube_volume
+    new_vol = request.POST.get('volume', '')
+
+    audiobook.youtube_volume = new_vol
+    audiobook.save()
+    
+    for a in models.Audiobook.objects.filter(slug=slug, youtube_volume=cur_vol, index__gt=audiobook.index).order_by('index'):
+        if a.youtube_volume != cur_vol:
+            break
+        a.youtube_volume = new_vol
+        a.save()
+    
+    return redirect('book', audiobook.slug)
+