X-Git-Url: https://git.mdrn.pl/audio.git/blobdiff_plain/b8a3e0d3dd1e8bcc94bd26e156e7900667e0e43e..a3bff3a1ab98b4d4334901b906d602a5d1f0417a:/apps/archive/views.py diff --git a/apps/archive/views.py b/apps/archive/views.py index 3ee87cb..d40f633 100644 --- a/apps/archive/views.py +++ b/apps/archive/views.py @@ -3,31 +3,40 @@ from datetime import datetime import os import os.path +from urllib import quote from archive import settings +from django.contrib.auth import logout +from django.contrib.auth.decorators import permission_required from django.core.urlresolvers import reverse -from django.http import Http404 +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.views.decorators.http import require_POST import mutagen +from archive.constants import status from archive import models from archive.forms import AudiobookForm +from archive import tasks +from archive.utils import all_files def list_new(request): division = 'new' path = settings.NEW_PATH - objects = sorted(os.listdir(path)) + objects = sorted(all_files(path)) return render(request, "archive/list_new.html", locals()) +@permission_required('archive.change_audiobook') def file_new(request, filename): division = 'new' - filepath = os.path.join(settings.NEW_PATH, filename.encode('utf-8')) + filepath = filename.encode('utf-8') + root_filepath = os.path.join(settings.NEW_PATH, filename.encode('utf-8')) if request.POST: form = AudiobookForm(request.POST) if form.is_valid(): @@ -38,21 +47,22 @@ def file_new(request, filename): return redirect(list_new) try: - tags = mutagen.File(filepath) + tags = mutagen.File(root_filepath) except IOError: raise Http404 d = {} - for tag in tags: - value = tags[tag] - if isinstance(value, list): - d[tag] = value[0] - else: - d[tag] = value - if tag == 'project': - try: - d[tag] = models.Project.objects.get(name=d[tag]).pk - except models.Project.DoesNotExist: - d[tag] = None + if tags: + for tag in tags: + value = tags[tag] + if isinstance(value, list): + d[tag] = value[0] + else: + d[tag] = value + if tag == 'project': + try: + d[tag] = models.Project.objects.get(name=d[tag]).pk + except models.Project.DoesNotExist: + d[tag] = None if not request.POST: form = AudiobookForm(d) @@ -60,14 +70,16 @@ def file_new(request, filename): @require_POST +@permission_required('archive.change_audiobook') 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) - if not os.path.isdir(settings.UNMANAGED_PATH): - os.makedirs(settings.UNMANAGED_PATH) new_path = os.path.join(settings.UNMANAGED_PATH, filename_str) + new_dir = os.path.split(new_path)[0] + if not os.path.isdir(new_dir): + os.makedirs(new_dir) if not os.path.isfile(old_path): raise Http404 @@ -84,14 +96,44 @@ def move_to_archive(request, filename): @require_POST +@permission_required('archive.change_audiobook') +def remove_to_archive(request, aid): + """ move a managed file to the unmanaged files dir """ + + audiobook = get_object_or_404(models.Audiobook, id=aid) + old_path = audiobook.source_file.path + new_path = os.path.join(settings.UNMANAGED_PATH, + str(audiobook.source_file)[len(settings.FILES_SAVE_PATH):].lstrip('/')) + new_dir = os.path.split(new_path)[0] + if not os.path.isdir(new_dir): + os.makedirs(new_dir) + + if not os.path.isfile(old_path): + raise Http404 + + try: + os.link(old_path, new_path) + except OSError: + # destination file exists, don't overwrite it + # TODO: this should probably be more informative + return redirect(file_new, filename) + else: + os.unlink(old_path) + audiobook.delete() + + return redirect(list_unmanaged) + +@require_POST +@permission_required('archive.change_audiobook') 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) - if not os.path.isdir(settings.NEW_PATH): - os.makedirs(settings.NEW_PATH) new_path = os.path.join(settings.NEW_PATH, filename_str) + new_dir = os.path.split(new_path)[0] + if not os.path.isdir(new_dir): + os.makedirs(new_dir) if not os.path.isfile(old_path): raise Http404 @@ -106,59 +148,116 @@ def move_to_new(request, filename): return redirect(list_unmanaged) + @require_POST -def publish(request, id): +@permission_required('archive.change_audiobook') +def publish(request, aid, publish=True): """ mark file for publishing """ - audiobook = get_object_or_404(models.Audiobook, id=id) - audiobook.publish_wait = datetime.now() - audiobook.publishing_tags = audiobook.new_publish_tags() + audiobook = get_object_or_404(models.Audiobook, id=aid) + tags = { + 'name': audiobook.title, + 'url': audiobook.url, + 'tags': audiobook.new_publish_tags(), + } + audiobook.mp3_tags = tags + audiobook.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(aid, publish).task_id + audiobook.ogg_task = tasks.OggTask.delay(aid, publish).task_id audiobook.save() - return redirect(file_managed, id) + + return redirect(file_managed, aid) + @require_POST -def cancel_publishing(request, id): +@permission_required('archive.change_audiobook') +def cancel_publishing(request, aid): """ cancel scheduled publishing """ - audiobook = get_object_or_404(models.Audiobook, id=id) - if not audiobook.publishing: - audiobook.publish_wait = None - audiobook.publishing_tags = None - audiobook.save() - return redirect(file_managed, id) + audiobook = get_object_or_404(models.Audiobook, id=aid) + # TODO: cancel tasks + audiobook.mp3_status = None + audiobook.ogg_status = None + audiobook.save() + return redirect(file_managed, aid) + + +def download(request, aid, which="source"): + if which not in ("source", "mp3", "ogg"): + raise Http404 + audiobook = get_object_or_404(models.Audiobook, id=aid) + file_ = getattr(audiobook, "%s_file" % which) + if not file_: + raise Http404 + ext = file_.path.rsplit('.', 1)[-1] + response = HttpResponse(mimetype='application/force-download') + + response['Content-Disposition'] = "attachment; filename*=UTF-8''%s.%s" % ( + quote(audiobook.title.encode('utf-8'), safe=''), ext) + response['X-Sendfile'] = file_.path.encode('utf-8') + return response def list_unpublished(request): division = 'unpublished' - objects = models.Audiobook.objects.filter(published=None) + 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' -def file_managed(request, id): - audiobook = get_object_or_404(models.Audiobook, id=id) - division = 'published' if audiobook.published else 'unpublished' - - # for tags update - tags = mutagen.File(audiobook.source_file.path) - form = AudiobookForm(instance=audiobook) - - return render(request, "archive/file_managed.html", locals()) + objects = models.Audiobook.objects.exclude(mp3_status=None, ogg_status=None) + objects_by_status = {} + for o in objects: + 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) + 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(published=None) + objects = models.Audiobook.objects.exclude(Q(mp3_published=None) | Q(ogg_published=None)) return render(request, "archive/list_published.html", locals()) +@permission_required('archive.change_audiobook') +def file_managed(request, id): + audiobook = get_object_or_404(models.Audiobook, id=id) + + if request.POST: + form = AudiobookForm(request.POST, instance=audiobook) + if form.is_valid(): + try: + form.save() + except IOError: + raise Http404 + + division = 'published' if audiobook.published() else 'unpublished' + path = audiobook.source_file.path[len(settings.FILES_PATH):].lstrip('/') + + # for tags update + tags = mutagen.File(audiobook.source_file.path) + if not tags: + tags = {} + form = AudiobookForm(instance=audiobook) + + return render(request, "archive/file_managed.html", locals()) def list_unmanaged(request): division = 'unmanaged' - objects = sorted(os.listdir(settings.UNMANAGED_PATH)) + objects = sorted(all_files(settings.UNMANAGED_PATH)) return render(request, "archive/list_unmanaged.html", locals()) @@ -166,6 +265,8 @@ def file_unmanaged(request, filename): division = 'unmanaged' tags = mutagen.File(os.path.join(settings.UNMANAGED_PATH, filename.encode('utf-8'))) + if not tags: + tags = {} + err_exists = request.GET.get('exists') return render(request, "archive/file_unmanaged.html", locals()) -