From: Radek Czajka Date: Wed, 24 Aug 2011 09:13:40 +0000 (+0200) Subject: use directories and allow filetypes other than FLAC X-Git-Url: https://git.mdrn.pl/audio.git/commitdiff_plain/339f6babf1e1d7b24e5b22662d04f99af909bd40 use directories and allow filetypes other than FLAC --- diff --git a/apps/archive/forms.py b/apps/archive/forms.py index c551cf8..cdc416e 100755 --- a/apps/archive/forms.py +++ b/apps/archive/forms.py @@ -7,7 +7,7 @@ from django.utils.translation import ugettext_lazy as _ import mutagen from archive.models import Audiobook -from archive.settings import FILES_PATH +from archive.settings import FILES_PATH, NEW_PATH from archive.utils import ExistingFile, sha1_file class AudiobookForm(forms.ModelForm): @@ -15,6 +15,10 @@ class AudiobookForm(forms.ModelForm): model = Audiobook def save(self, commit=True, path=None): + """ Performs normal save, with given file as an source audiobook. + + `path' is relative to NEW_PATH. + """ m = super(AudiobookForm, self).save(commit=False) m.modified = datetime.now() @@ -24,9 +28,10 @@ class AudiobookForm(forms.ModelForm): os.makedirs(FILES_PATH) # save the file in model + abs_path = os.path.join(NEW_PATH, path) m.source_file.save( - os.path.basename(path), - ExistingFile(path)) + path, + ExistingFile(abs_path)) f = open(m.source_file.path) m.source_sha1 = sha1_file(f) diff --git a/apps/archive/models.py b/apps/archive/models.py index afa90b5..4d3f838 100644 --- a/apps/archive/models.py +++ b/apps/archive/models.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- +import os.path from django.db import models from jsonfield.fields import JSONField from django.utils.translation import ugettext_lazy as _ from archive.constants import status -from archive.settings import FILES_PATH, ADVERT, LICENSE, ORGANIZATION, PROJECT +from archive.settings import FILES_SAVE_PATH, ADVERT, LICENSE, ORGANIZATION, PROJECT from archive.utils import OverwriteStorage # Create your models here. @@ -25,8 +26,12 @@ class Project(models.Model): return self.name +def source_upload_to(intance, filename): + return os.path.join(FILES_SAVE_PATH, filename) # FIXME: what about really long file names? + + class Audiobook(models.Model): - source_file = models.FileField(upload_to='archive/files', max_length=255, + source_file = models.FileField(upload_to=source_upload_to, max_length=255, verbose_name=_('source file'), editable=False) source_sha1 = models.CharField(max_length=40, editable=False) diff --git a/apps/archive/settings.py b/apps/archive/settings.py index 3c85f84..476f6c7 100755 --- a/apps/archive/settings.py +++ b/apps/archive/settings.py @@ -17,6 +17,9 @@ except AttributeError: FILES_PATH = os.path.abspath(os.path.join(settings.MEDIA_ROOT, "archive/files")) +if FILES_PATH.startswith(settings.MEDIA_ROOT): + FILES_SAVE_PATH = FILES_PATH[len(settings.MEDIA_ROOT):].lstrip('/') + # here the app keeps the unmanaged (archive) files try: diff --git a/apps/archive/tasks.py b/apps/archive/tasks.py index e8ce4fb..941bbc6 100755 --- a/apps/archive/tasks.py +++ b/apps/archive/tasks.py @@ -162,6 +162,7 @@ class Mp3Task(AudioFormatTask): '-ab', '64k', '-ac', '1', '-y', + '-acodec', 'libmp3lame', out_path ]) @@ -188,11 +189,12 @@ class OggTask(AudioFormatTask): @staticmethod def encode(in_path, out_path): # 44.1kHz 64kbps mono Ogg Vorbis - subprocess.check_call(['oggenc', - in_path, - '--discard-comments', - '--resample', '44100', - '--downmix', - '-b', '64', - '-o', out_path + subprocess.check_call(['ffmpeg', + '-i', in_path, + '-ar', '44100', + '-ab', '64k', + '-ac', '1', + '-y', + '-acodec', 'libvorbis', + out_path ]) diff --git a/apps/archive/templates/archive/file_managed.html b/apps/archive/templates/archive/file_managed.html index c67edea..92ee639 100755 --- a/apps/archive/templates/archive/file_managed.html +++ b/apps/archive/templates/archive/file_managed.html @@ -4,6 +4,10 @@ {% block content %} +

Plik źródłowy: {{ path }} +(sha1: {{ audiobook.source_sha1 }}). +

+

{% trans "Publishing" %}

{% if audiobook.mp3_status or audiobook.ogg_status %} diff --git a/apps/archive/urls.py b/apps/archive/urls.py index 40730ba..29552a2 100644 --- a/apps/archive/urls.py +++ b/apps/archive/urls.py @@ -4,8 +4,8 @@ urlpatterns = patterns('', url(r'^$', 'django.views.generic.simple.redirect_to', {'url': 'new/'}), url(r'^new/$', 'archive.views.list_new', name="list_new"), - url(r'^new/([^/]+)/$', 'archive.views.file_new', name="file_new"), - url(r'^move_to_archive/([^/]+)/$', 'archive.views.move_to_archive', name="move_to_archive"), + url(r'^new/(.+)/$', 'archive.views.file_new', name="file_new"), + url(r'^move_to_archive/(.+)/$', 'archive.views.move_to_archive', name="move_to_archive"), url(r'^unpublished/$', 'archive.views.list_unpublished', name="list_unpublished"), url(r'^publishing/$', 'archive.views.list_publishing', name="list_publishing"), @@ -15,6 +15,6 @@ urlpatterns = patterns('', url(r'^cancel/(\d+)/$', 'archive.views.cancel_publishing', name="cancel_publishing"), url(r'^unmanaged/$', 'archive.views.list_unmanaged', name="list_unmanaged"), - url(r'^unmanaged/([^/]+)/$', 'archive.views.file_unmanaged', name="file_unmanaged"), - url(r'^move_to_new/([^/]+)/$', 'archive.views.move_to_new', name="move_to_new"), + url(r'^unmanaged/(.+)/$', 'archive.views.file_unmanaged', name="file_unmanaged"), + url(r'^move_to_new/(.+)/$', 'archive.views.move_to_new', name="move_to_new"), ) diff --git a/apps/archive/utils.py b/apps/archive/utils.py index c69fe1c..3e89a8b 100755 --- a/apps/archive/utils.py +++ b/apps/archive/utils.py @@ -1,4 +1,6 @@ from hashlib import sha1 +import os +import os.path from django.core.files.storage import FileSystemStorage from django.core.files.uploadedfile import UploadedFile @@ -32,3 +34,11 @@ def sha1_file(f): for piece in iter(lambda: f.read(1024*1024), ''): sha.update(piece) return sha.hexdigest() + + +def all_files(root_path): + root_len = len(root_path) + for path, dirs, files in os.walk(root_path): + for fname in files: + yield os.path.join(path, fname)[root_len:].lstrip('/') + diff --git a/apps/archive/views.py b/apps/archive/views.py index 8841dbb..cfed4a6 100644 --- a/apps/archive/views.py +++ b/apps/archive/views.py @@ -19,6 +19,7 @@ from archive.constants import status from archive import models from archive.forms import AudiobookForm from archive import tasks +from archive.utils import all_files @login_required @@ -26,7 +27,7 @@ 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()) @@ -34,7 +35,8 @@ def list_new(request): 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(): @@ -45,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) @@ -73,9 +76,10 @@ def move_to_archive(request, filename): 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 @@ -98,9 +102,10 @@ def move_to_new(request, filename): 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 @@ -197,9 +202,12 @@ def file_managed(request, id): 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()) @@ -209,7 +217,7 @@ def file_managed(request, id): 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()) @@ -218,6 +226,9 @@ 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())