From f38625eb8451c9e81e99c1077134305b91ff0337 Mon Sep 17 00:00:00 2001 From: yomguy Date: Thu, 3 Nov 2011 18:04:29 +0100 Subject: [PATCH] add MediaItemRelatedFile model and forms to handle media item attachements --- telemeta/admin.py | 5 ++ telemeta/models/media.py | 55 +++++++++++++++++-- .../telemeta/mediaitem_related_edit.html | 1 + .../telemeta_default/mediaitem_detail.html | 37 +++++++++++++ .../mediaitem_related_edit.html | 49 +++++++++++++++++ telemeta/templatetags/telemeta_utils.py | 5 ++ telemeta/urls.py | 3 +- telemeta/web/base.py | 32 ++++++++++- 8 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 telemeta/templates/telemeta/mediaitem_related_edit.html create mode 100644 telemeta/templates/telemeta_default/mediaitem_related_edit.html diff --git a/telemeta/admin.py b/telemeta/admin.py index bda90d9a..23669690 100644 --- a/telemeta/admin.py +++ b/telemeta/admin.py @@ -13,6 +13,10 @@ class MediaItemAdmin(admin.ModelAdmin): ordering = ['code'] exclude = ('copied_from_item', ) +class MediaItemRelatedFileAdmin(admin.ModelAdmin): + search_fields = ['title', 'code'] + ordering = ['code'] + class MediaPartAdmin(admin.ModelAdmin): search_fields = ['title', 'item__code'] ordering = ['title'] @@ -48,6 +52,7 @@ class LocationRelationAdmin(admin.ModelAdmin): admin.site.register(MediaCollection, MediaCollectionAdmin) admin.site.register(MediaItem, MediaItemAdmin) admin.site.register(MediaPart, MediaPartAdmin) +admin.site.register(MediaItemRelatedFile, MediaItemRelatedFileAdmin) admin.site.register(Instrument, InstrumentAdmin) admin.site.register(InstrumentAlias, InstrumentAliasAdmin) diff --git a/telemeta/models/media.py b/telemeta/models/media.py index b20d7caa..ba12483d 100644 --- a/telemeta/models/media.py +++ b/telemeta/models/media.py @@ -42,6 +42,7 @@ from telemeta.models.core import * from telemeta.models.enum import ContextKeyword from telemeta.util.unaccent import unaccent_icmp import re +import mimetypes from telemeta.models.location import LocationRelation, Location from telemeta.models.system import Revision from telemeta.models.query import * @@ -319,18 +320,62 @@ class MediaItem(MediaResource): title = self.title else: title = unicode(self.collection) - if self.track: title += ' ' + self.track - return title - class MediaItemForm(ModelForm): class Meta: model = MediaItem def clean_code(self): return self.cleaned_data['code'] or None + + +class MediaItemRelatedFile(MediaResource): + "Item related attached file" + + element_type = 'media' + + item = ForeignKey('MediaItem', related_name="related", verbose_name=_('item')) + code = CharField(_('code'), unique=True, blank=True) + title = CharField(_('title')) + date = DateTimeField(_('date'), auto_now=True) + description = TextField(_('description')) + author = ForeignKey(User, related_name="related", verbose_name=_('author')) + mime_type = CharField(_('mime_type'), blank=True) + file = FileField(_('file'), upload_to='items/%Y/%m/%d', db_column="filename") + + @property + def public_id(self): + if self.code: + return self.code + return self.id + + def is_image(self): + return 'image' in self.mime_type + + def save(self, force_insert=False, force_update=False): + super(MediaItemRelatedFile, self).save(force_insert, force_update) + + def set_mime_type(self): + if self.file: + self.mime_type = mimetypes.guess_type(self.file.path)[0] + + def __unicode__(self): + if self.title and not re.match('^ *N *$', self.title): + title = self.title + else: + title = unicode(self.item) + return title + + class Meta(MetaCore): + db_table = 'media_item_related_file' + +class MediaItemRelatedFileForm(ModelForm): + class Meta: + model = MediaItemRelatedFile + def clean_code(self): + return self.cleaned_data['code'] or None class MediaItemKeyword(ModelCore): "Item keyword" @@ -464,8 +509,8 @@ class MediaItemTranscodingFlag(ModelCore): class Meta(MetaCore): db_table = 'media_transcoding' - - + + class Search(ModelCore): "Keywork search" diff --git a/telemeta/templates/telemeta/mediaitem_related_edit.html b/telemeta/templates/telemeta/mediaitem_related_edit.html new file mode 100644 index 00000000..6b318a9e --- /dev/null +++ b/telemeta/templates/telemeta/mediaitem_related_edit.html @@ -0,0 +1 @@ +{% extends "telemeta_default/mediaitem_related_edit.html" %} diff --git a/telemeta/templates/telemeta_default/mediaitem_detail.html b/telemeta/templates/telemeta_default/mediaitem_detail.html index 02117338..e5b6c10d 100644 --- a/telemeta/templates/telemeta_default/mediaitem_detail.html +++ b/telemeta/templates/telemeta_default/mediaitem_detail.html @@ -272,6 +272,43 @@ {% endblock infos %} +
+ {% block related_files %} +
+

{% trans "Related files" %}

+ {% if related_files %} +
+ + + + + + + + + + + + {% for file in related_files %} + + + + + + + + {% endfor %} + +
{% field_label "MediaItemRelatedFile" "file" %}{% field_label "MediaItemRelatedFile" "title" %}{% field_label "MediaItemRelatedFile" "mime type" %}{% field_label "MediaItemRelatedFile" "author" %}{% field_label "MediaItemRelatedFile" "preview" %}
{% if file.file %}{{ file.file|get_filename }}{% endif %}{{ file.title }}{{ file.mime_type }}{{ file.author }}{% if file.is_image %}{% else %}link{% endif %}
+ {% if user.is_authenticated and perms.telemeta.change_mediaitem %} + {% trans "Edit"%} {% trans "related"%} + {% endif %} +
+ {% endif %} +
+ {% endblock related_files %} +
+ {% endblock %} {% block delete %} diff --git a/telemeta/templates/telemeta_default/mediaitem_related_edit.html b/telemeta/templates/telemeta_default/mediaitem_related_edit.html new file mode 100644 index 00000000..8a08f801 --- /dev/null +++ b/telemeta/templates/telemeta_default/mediaitem_related_edit.html @@ -0,0 +1,49 @@ +{% extends "telemeta/mediaitem_detail.html" %} +{% load i18n %} +{% load telemeta_utils %} + +{% block extra_javascript %}{% endblock %} + +{% block title %} + Item : {{ item }} +{% endblock %} + +{% block title_buttons %} + {% trans "Cancel" %} +{% endblock %} + +{% block content %} + {% block infos %} +
+
{% csrf_token %} + + {{ formset.management_form }} + {% for form in formset.forms %} + + + {% for field in form %} + + {% if not "media_item" in field.html_name %} + {% if "id" in field.html_name or "item" in field.html_name %} + + {% else %} + + {% endif %} + {% else %} + + {% endif %} + + {% endfor %} +
{% trans "File" %} :
{{ field.label_tag.as_hidden }}{{ field.as_hidden }}{{ field.label_tag }}: {{ field }}{{ field.label_tag.as_hidden }}{{ field.as_hidden }}
+
+ {% endfor %} +
+ {% trans "Cancel" %} + {% trans "Save" %} +
+
+
+ {% endblock infos %} +{% endblock content %} diff --git a/telemeta/templatetags/telemeta_utils.py b/telemeta/templatetags/telemeta_utils.py index 3c678261..30ffe65f 100644 --- a/telemeta/templatetags/telemeta_utils.py +++ b/telemeta/templatetags/telemeta_utils.py @@ -12,6 +12,7 @@ from django.utils.encoding import smart_str, force_unicode from django.utils.safestring import mark_safe from django import db import re +import os import datetime from django.conf import settings @@ -319,3 +320,7 @@ def to_string(list): return list[0].encode('utf-8') else: return '' + +@register.filter +def get_filename(file): + return file.path.split(os.sep)[-1] diff --git a/telemeta/urls.py b/telemeta/urls.py index 5272a3b0..b67508cf 100644 --- a/telemeta/urls.py +++ b/telemeta/urls.py @@ -113,7 +113,8 @@ urlpatterns = patterns('', url(r'^items/(?P[A-Za-z0-9._-]+)/keywords/$', item_view.item_keywords_edit, dict(template='telemeta/mediaitem_keywords_edit.html'), name="telemeta-item-keywords_edit"), url(r'^items/(?P[A-Za-z0-9._-]+)/delete/$', item_view.item_delete, name="telemeta-item-delete"), - + url(r'^items/(?P[A-Za-z0-9._-]+)/related/(?P[A-Za-z0-9._-]+)$', item_view.related_file_stream, name="telemeta-item-related-file"), + url(r'^items/(?P[A-Za-z0-9._-]+)/related_edit/$', item_view.related_file_edit, dict(template='telemeta/mediaitem_related_edit.html'), name="telemeta-item-related_edit"), # Markers url(r'^markers/(?P[A-Za-z0-9]+)/$', item_view.item_detail, name="telemeta-item-detail-marker"), diff --git a/telemeta/web/base.py b/telemeta/web/base.py index c85464e5..4caca191 100644 --- a/telemeta/web/base.py +++ b/telemeta/web/base.py @@ -505,13 +505,20 @@ class ItemView(object): playlists = get_playlists(request) public_access = get_public_access(item.public_access, str(item.recorded_from_date).split('-')[0], str(item.recorded_to_date).split('-')[0]) - + + related_files = MediaItemRelatedFile.objects.filter(item=item) + for file in related_files: + if not file.mime_type: + file.set_mime_type() + file.save() + return render(request, template, {'item': item, 'export_formats': formats, 'visualizers': graphers, 'visualizer_id': grapher_id, 'audio_export_enabled': getattr(settings, 'TELEMETA_DOWNLOAD_ENABLED', True), 'previous' : previous, 'next' : next, 'marker': marker_id, 'playlists' : playlists, 'public_access': public_access, 'width': width, 'height': height, + 'related_files': related_files, }) @method_decorator(permission_required('telemeta.change_mediaitem')) @@ -561,6 +568,27 @@ class ItemView(object): 'audio_export_enabled': getattr(settings, 'TELEMETA_DOWNLOAD_ENABLED', True), "form": form, 'previous' : previous, 'next' : next, }) + + def related_file_stream(self, request, item_public_id, file_id): + item = MediaItem.objects.get(public_id=item_public_id) + file = MediaItemRelatedFile.objects.get(item=item, id=file_id) + response = HttpResponse(stream_from_file(file.file.path), mimetype=file.mime_type) +# response['Content-Disposition'] = 'attachment' + return response + + @method_decorator(permission_required('telemeta.change_mediaitem')) + def related_file_edit(self, request, public_id, template): + item = MediaItem.objects.get(public_id=public_id) + MediaItemRelatedFileFormSet = inlineformset_factory(MediaItem, MediaItemRelatedFile, form=MediaItemRelatedFileForm) + if request.method == 'POST': + formset = MediaItemRelatedFileFormSet(data=request.POST, files=request.FILES, instance=item) + if formset.is_valid(): + formset.save() + return HttpResponseRedirect('/items/'+public_id) + else: + formset = MediaItemRelatedFileFormSet(instance=item) + + return render(request, template, {'item': item, 'formset': formset,}) @method_decorator(permission_required('telemeta.add_mediaitem')) def item_add(self, request, public_id=None, template='telemeta/mediaitem_add.html'): @@ -710,7 +738,7 @@ class ItemView(object): response = HttpResponse(self.cache_data.read_stream_bin(image_file), mimetype=mime_type) return response - + def list_export_extensions(self): "Return the recognized item export file extensions, as a list" list = [] -- 2.39.5