From e634d6be86ff68af294ff726dc3fffbeb3711aaa Mon Sep 17 00:00:00 2001
From: olivier <>
Date: Tue, 1 May 2007 14:45:31 +0000
Subject: [PATCH] * Created new administration interface. BEWARE: update your
site urls (in urls.py), telemeta now provides an internal "admin/" url, that
may conflict with django's admin. * Implemented edition of generic
"dictionaries" (or "enumerations"). These are the linked tables that
contained various predefined values, used in collections, items and/or parts
* added "physical format" dictionary (collection field and linked table),
see EthnomusDatabase * misc cleanup
---
telemeta/models.py | 11 +-
telemeta/templates/admin.html | 37 ++++++
telemeta/templates/base.html | 20 ++-
telemeta/templates/dictionary_edit.html | 48 +++++++
telemeta/templates/dictionary_edit_value.html | 22 +++
telemeta/templates/dictionary_list.html | 14 ++
telemeta/urls.py | 29 +++-
telemeta/views/web.py | 125 +++++++++++++++---
8 files changed, 276 insertions(+), 30 deletions(-)
create mode 100644 telemeta/templates/admin.html
create mode 100644 telemeta/templates/dictionary_edit.html
create mode 100644 telemeta/templates/dictionary_edit_value.html
create mode 100644 telemeta/templates/dictionary_list.html
diff --git a/telemeta/models.py b/telemeta/models.py
index 0a3b893d..7c6d8995 100644
--- a/telemeta/models.py
+++ b/telemeta/models.py
@@ -19,6 +19,14 @@ class MediaCore:
fields_dict[field.name] = getattr(self, field.name)
return fields_dict
+class PhysicalFormat(models.Model):
+ value = models.CharField(maxlength=250)
+ is_dictionary = True
+ def __str__(self):
+ return self.value
+ class Meta:
+ ordering = ['value']
+
class MediaCollectionManager(models.Manager):
def quick_search(self, pattern):
return super(MediaCollectionManager, self).get_query_set().filter(
@@ -26,6 +34,7 @@ class MediaCollectionManager(models.Manager):
Q(description__icontains=pattern)
)
+
class MediaCollection(models.Model, MediaCore):
"Group related media items"
@@ -42,6 +51,7 @@ class MediaCollection(models.Model, MediaCore):
rights = models.CharField(maxlength=250, blank=True)
source = models.CharField(maxlength=250, blank=True)
subject = models.CharField(maxlength=250, blank=True)
+ physical_format = models.ForeignKey(PhysicalFormat, null=True, blank=True)
objects = MediaCollectionManager()
@@ -131,4 +141,3 @@ class MediaPart(models.Model, MediaCore):
class Admin:
pass
-
diff --git a/telemeta/templates/admin.html b/telemeta/templates/admin.html
new file mode 100644
index 00000000..e335b3cf
--- /dev/null
+++ b/telemeta/templates/admin.html
@@ -0,0 +1,37 @@
+{% extends "base.html" %}
+
+{% block extra_style %}
+
+{% endblock %}
+
+{% block content %}
+
Administration
+
+
+- Users
+
+{% if dictionaries %}
+ - Dictionaries
+
+ {% for d in dictionaries %}
+ {%ifequal d.id dictionary_id %}
+ - {{ d.name|capfirst }}
+ {%else%}
+ - {{ d.name|capfirst }}
+ {%endifequal%}
+ {% endfor %}
+
+
+{% endif %}
+
+
+
+ {% block tabcontents %}
+
+
+
+
+
+ {% endblock %}
+
+{% endblock %}
diff --git a/telemeta/templates/base.html b/telemeta/templates/base.html
index 0c4f6335..9fb41880 100644
--- a/telemeta/templates/base.html
+++ b/telemeta/templates/base.html
@@ -1,9 +1,19 @@
-
-
+
+
+
+Telemeta
+
+{% block extra_style %}{% endblock %}
+
+{% load i18n %}
-
+
+
{% block content %}{% endblock %}
+
diff --git a/telemeta/templates/dictionary_edit.html b/telemeta/templates/dictionary_edit.html
new file mode 100644
index 00000000..e5a7b3a4
--- /dev/null
+++ b/telemeta/templates/dictionary_edit.html
@@ -0,0 +1,48 @@
+{% extends "admin.html" %}
+
+{% block tabcontents %}
+ Manage {{ dictionary_name_plural|capfirst }}
+
+
+
+
+ {% if dictionary_values %}
+
+ {% else %}
+ This dictionary is empty.
+ {% endif %}
+
+
+
+{% endblock %}
diff --git a/telemeta/templates/dictionary_edit_value.html b/telemeta/templates/dictionary_edit_value.html
new file mode 100644
index 00000000..0f205c69
--- /dev/null
+++ b/telemeta/templates/dictionary_edit_value.html
@@ -0,0 +1,22 @@
+{% extends "admin.html" %}
+
+{% block tabcontents %}
+ Manage {{ dictionary_name_plural|capfirst }}
+
+
+
+
+{% endblock %}
diff --git a/telemeta/templates/dictionary_list.html b/telemeta/templates/dictionary_list.html
new file mode 100644
index 00000000..bc780f8c
--- /dev/null
+++ b/telemeta/templates/dictionary_list.html
@@ -0,0 +1,14 @@
+{% extends "base.html" %}
+
+{% block content %}
+Dictionaries
+{% if dictionaries %}
+
+{% else %}
+ No dictionary.
+{% endif %}
+{% endblock %}
diff --git a/telemeta/urls.py b/telemeta/urls.py
index 09b36cbc..f08699cb 100644
--- a/telemeta/urls.py
+++ b/telemeta/urls.py
@@ -1,5 +1,10 @@
from django.conf.urls.defaults import *
from telemeta.models import MediaItem, MediaCollection
+from telemeta.core import ComponentManager
+from telemeta.views.web import WebView
+
+comp_mgr = ComponentManager()
+web_view = WebView(comp_mgr)
all_items = {
'queryset': MediaItem.objects.all(),
@@ -10,12 +15,12 @@ all_collections = {
}
urlpatterns = patterns('',
- (r'^$', 'telemeta.views.web.index'),
+ (r'^$', web_view.index),
(r'^items/$', 'django.views.generic.list_detail.object_list',
dict(all_items, paginate_by=10, template_name="mediaitem_list.html")),
- (r'^items/(?P[0-9]+)/$', 'telemeta.views.web.item_detail'),
+ (r'^items/(?P[0-9]+)/$', web_view.item_detail),
(r'^items/(?P[0-9]+)/download/(?P[0-9A-Z]+)/$',
- 'telemeta.views.web.item_export'),
+ web_view.item_export),
#(r'^media_item/(?P[0-9]+)/$', 'telemeta.views.web.media_item_edit'),
(r'^media_item/(?P[0-9]+)/update/$', 'telemeta.views.web.media_item_update'),
@@ -24,13 +29,23 @@ urlpatterns = patterns('',
(r'^collections/(?P[0-9]+)/$',
'django.views.generic.list_detail.object_detail',
dict(all_collections, template_name="collection_detail.html")),
+ #(r'^dictionaries/$', web_view.dictionary_list),
+ (r'^admin/$', web_view.admin_index),
+ (r'^admin/dictionaries/(?P[0-9a-z]+)/$', web_view.edit_dictionary),
+ (r'^admin/dictionaries/(?P[0-9a-z]+)/add/$', web_view.add_to_dictionary),
+ (r'^admin/dictionaries/(?P[0-9a-z]+)/update/$', web_view.update_dictionary),
+ (r'^admin/dictionaries/(?P[0-9a-z]+)/(?P[0-9]+)/$',
+ web_view.edit_dictionary_value),
+
+ (r'^admin/dictionaries/(?P[0-9a-z]+)/(?P[0-9]+)/update/$',
+ web_view.update_dictionary_value),
- (r'^search/$',
- 'telemeta.views.web.quick_search'),
+ (r'^search/$', web_view.quick_search),
- # CSS (FIXME: for developement only)
- (r'^css/(?P.*)$', 'django.views.static.serve', {'document_root': './telemeta/css'}),
+ # CSS+Images (FIXME: for developement only)
+ (r'^css/(?P.*)$', 'django.views.static.serve', {'document_root': './telemeta/htdocs/css'}),
+ (r'^images/(?P.*)$', 'django.views.static.serve', {'document_root': './telemeta/htdocs/images'}),
)
diff --git a/telemeta/views/web.py b/telemeta/views/web.py
index 7b733db0..a23cedc7 100644
--- a/telemeta/views/web.py
+++ b/telemeta/views/web.py
@@ -8,26 +8,24 @@ from telemeta.models import MediaCollection
from django.shortcuts import render_to_response
import re
from telemeta.core import *
-from telemeta.core import ComponentManager
from telemeta.export import *
from django.conf import settings
import os
-def index(request):
- "Render the homepage"
-
- media_items = MediaItem.objects.all()
- template = loader.get_template('index.html')
- context = Context({
- 'media_items' : media_items,
- })
- return HttpResponse(template.render(context))
-
class WebView(Component):
+ """Provide web UI methods"""
exporters = ExtensionPoint(IExporter)
+ def index(self, request):
+ """Render the homepage"""
+
+ template = loader.get_template('index.html')
+ context = Context({})
+ return HttpResponse(template.render(context))
+
def item_detail(self, request, item_id):
+ """Show the details of a given item"""
item = MediaItem.objects.get(pk=item_id)
formats = []
for exporter in self.exporters:
@@ -35,7 +33,12 @@ class WebView(Component):
return render_to_response('mediaitem_detail.html',
{'item': item, 'export_formats': formats})
- def file_stream(self, filepath):
+ def __file_stream(self, filepath):
+ """Generator for streaming a file from the disk.
+
+ This method shouldn't be needed anymore when bug #8 get fixed
+ """
+
buffer_size = 0xFFFF
f = open(filepath, 'rb')
chunk = f.read(buffer_size)
@@ -46,6 +49,7 @@ class WebView(Component):
f.close()
def item_export(self, request, item_id, format):
+ """Export a given media item in the specified format (OGG, FLAC, ...)"""
for exporter in self.exporters:
if exporter.get_format() == format:
break
@@ -68,12 +72,13 @@ class WebView(Component):
outfile = exporter.process(item.id, infile, metadata, [])
- response = HttpResponse(self.file_stream(outfile), mimetype = mime_type)
+ response = HttpResponse(self.__file_stream(outfile), mimetype = mime_type)
response['Content-Disposition'] = 'attachment; filename="download.' + \
exporter.get_file_extension() + '"'
return response
def quick_search(self, request):
+ """Perform a simple search through collections and items core metadata"""
pattern = request.REQUEST["pattern"]
collections = MediaCollection.objects.quick_search(pattern)
items = MediaItem.objects.quick_search(pattern)
@@ -81,14 +86,98 @@ class WebView(Component):
{'pattern': pattern, 'collections': collections,
'items': items})
+ def __get_dictionary_list(self):
+ from django.db.models import get_models
+ models = get_models(telemeta.models)
+
+ dictionaries = []
+ for model in models:
+ if getattr(model, "is_dictionary", False):
+ dictionaries.append({"name": model._meta.verbose_name_plural,
+ "id": model._meta.module_name})
+ return dictionaries
+
+ def __get_admin_context_vars(self):
+ return {"dictionaries": self.__get_dictionary_list()}
+
+ def admin_index(self, request):
+ return render_to_response('admin.html', self. __get_admin_context_vars())
+
+ def __get_dictionary(self, id):
+ from django.db.models import get_models
+ models = get_models(telemeta.models)
+ for model in models:
+ if model._meta.module_name == id:
+ break
+
+ if model._meta.module_name != id:
+ return None
+
+ return model
-comp_mgr = ComponentManager()
-view = WebView(comp_mgr)
-item_detail = view.item_detail
-item_export = view.item_export
-quick_search = view.quick_search
+ def edit_dictionary(self, request, dictionary_id):
+
+ dictionary = self.__get_dictionary(dictionary_id)
+ if dictionary == None:
+ raise Http404
+
+ vars = self.__get_admin_context_vars()
+ vars["dictionary_id"] = dictionary._meta.module_name
+ vars["dictionary_name"] = dictionary._meta.verbose_name
+ vars["dictionary_name_plural"] = dictionary._meta.verbose_name_plural
+ vars["dictionary_values"] = dictionary.objects.all()
+ return render_to_response('dictionary_edit.html', vars)
+ def add_to_dictionary(self, request, dictionary_id):
+
+ dictionary = self.__get_dictionary(dictionary_id)
+ if dictionary == None:
+ raise Http404
+
+ dictionary_value = dictionary(value=request.POST['value'])
+ dictionary_value.save()
+
+ return self.edit_dictionary(request, dictionary_id)
+
+ def update_dictionary(self, request, dictionary_id):
+
+ dictionary = self.__get_dictionary(dictionary_id)
+ if dictionary == None:
+ raise Http404
+
+ if request.POST.has_key("remove"):
+ dictionary.objects.filter(id__in=request.POST['sel']).delete()
+
+ return self.edit_dictionary(request, dictionary_id)
+
+ def edit_dictionary_value(self, request, dictionary_id, value_id):
+
+ dictionary = self.__get_dictionary(dictionary_id)
+ if dictionary == None:
+ raise Http404
+
+ vars = self.__get_admin_context_vars()
+ vars["dictionary_id"] = dictionary._meta.module_name
+ vars["dictionary_name"] = dictionary._meta.verbose_name
+ vars["dictionary_name_plural"] = dictionary._meta.verbose_name_plural
+ vars["dictionary_record"] = dictionary.objects.get(id__exact=value_id)
+ return render_to_response('dictionary_edit_value.html', vars)
+
+ def update_dictionary_value(self, request, dictionary_id, value_id):
+
+ if request.POST.has_key("save"):
+ dictionary = self.__get_dictionary(dictionary_id)
+ if dictionary == None:
+ raise Http404
+
+ record = dictionary.objects.get(id__exact=value_id)
+ record.value = request.POST["value"]
+ record.save()
+
+ return self.edit_dictionary(request, dictionary_id)
+
+
def media_item_edit(request, media_item_id):
"Provide MediaItem object edition"
--
2.39.5