switch download audiobooks views
[wolnelektury.git] / src / catalogue / views.py
index e754e05..8bb86c2 100644 (file)
@@ -5,11 +5,13 @@ from collections import OrderedDict
 import random
 import re
 from urllib.parse import quote_plus
+from slugify import slugify
+from zipstream import ZipStream
 
 from django.conf import settings
 from django.template.loader import render_to_string
 from django.shortcuts import get_object_or_404, render, redirect
-from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect
+from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect, StreamingHttpResponse
 from django.urls import reverse
 from django.db.models import Q, QuerySet
 from django.contrib.auth.decorators import login_required, user_passes_test
@@ -518,6 +520,42 @@ def download_zip(request, file_format=None, media_format=None, slug=None):
     return HttpResponseRedirect(quote_plus(settings.MEDIA_URL + url, safe='/?='))
 
 
+def stream_zip(request, media_format=None, slug=None):
+    book = get_object_or_404(Book, slug=slug)
+    def iterate_audiobooks(book, names):
+        for bm in book.media.filter(type=media_format).order_by('index'):
+            yield (
+                bm.file.path,
+                bm.get_extra_info_json().get('license'),
+                names + (slugify(bm.part_name),) if bm.part_name else names
+            )
+        for child in book.get_children():
+            yield from iterate_audiobooks(child, names + (slugify(child.title),))
+
+    zs = ZipStream()
+
+    licenses = set()
+    for i, (file_path, lic, names) in enumerate(iterate_audiobooks(book, ())):
+        index = i + 1
+        part_name = '_'.join(names)
+        ext = file_path.rsplit('.', 1)[-1]
+        zip_name = f'{book.slug}_{index:03d}_{part_name}'[:240] + '.' + ext
+        zs.add_path(file_path, zip_name)
+
+        lic_name = constants.LICENSES.get(lic, {}).get('locative')
+        if lic_name:
+            licenses.add(lic_name)
+
+    readme = render_to_string('catalogue/audiobook_zip_readme.txt', {
+        'licenses': licenses,
+    })
+    zs.add(readme, 'informacje.txt')
+
+    response = StreamingHttpResponse(zs, content_type='application/zip')
+    response['Content-Disposition'] = f'attachment; filename={slug}_{media_format}.zip'
+    return response
+
+
 class CustomPDFFormView(AjaxableFormView):
     form_class = forms.CustomPDFForm
     title = gettext_lazy('Stwórz własny PDF')