--- /dev/null
+from telemeta.util.logger import Logger
+
+logger = Logger()
--- /dev/null
+body {
+ font-family: Verdana;
+}
+
+#header {
+ font-size: 16px;
+ border-bottom: solid 1px black;
+ font-weight: bold;
+}
+
+label {
+ width: 20ex;
+ display: block;
+ float: left;
+}
+
+input {
+ margin-bottom: 4px;
+}
--- /dev/null
+import telemeta
+from django.db import models
+from django.core import validators
+
+class Collection(models.Model):
+ "Group related media items"
+
+ name = models.CharField(maxlength=250)
+
+ def __str__(self):
+ return self.name
+
+ class Admin:
+ pass
+
+class MediaItem(models.Model):
+ "Describe an audio/video item with metadata"
+
+ collection = models.ForeignKey(Collection)
+ title = models.CharField(maxlength=250)
+ author = models.CharField(maxlength=250)
+
+
+
+ def get_dynamic_properties(self):
+ "Retrieve dynamic properties associated with a given media item"
+
+ definitions = MediaItemPropertyDefinition.objects.all()
+ assigned = MediaItemProperty.objects.filter(media_item=self)
+ assigned_dict = {}
+ for p in assigned:
+ assigned_dict[p.definition.id] = p
+
+ properties = []
+ for d in definitions:
+ enumeration = MediaItemPropertyEnumerationItem.objects.filter(definition=d)
+
+ if d.id in assigned_dict:
+ if d.type == "text":
+ value = assigned_dict[d.id].value
+ else:
+ value = assigned_dict[d.id].enum_item
+
+ properties.append({
+ "id": d.id, "name": d.name, "value": value,
+ "type" : d.type, "enumeration" : enumeration})
+ else:
+ properties.append({"id": d.id, "name": d.name, "value": "",
+ "type" : d.type, "enumeration" : enumeration})
+
+ return properties
+
+ def __str__(self):
+ return self.author + " - " + self.title
+
+ class Meta:
+ pass
+
+ class Admin:
+ pass
+
+class MediaItemPropertyDefinition(models.Model):
+ "Define a media item dynamic property"
+
+ TYPE_CHOICES = (
+ ('text', 'Text'),
+ ('enumeration', 'Enumeration'),
+ )
+
+ name = models.CharField(maxlength=64)
+ type = models.CharField(maxlength=64, choices = TYPE_CHOICES)
+
+ def __str__(self):
+ return self.name
+
+ class Admin:
+ pass
+
+class MediaItemPropertyEnumerationItem(models.Model):
+ "Define a possible value for media item dynamic enumeration properties"
+
+ definition = models.ForeignKey(MediaItemPropertyDefinition, core=True)
+ name = models.CharField(maxlength=250)
+
+ def __str__(self):
+ return self.definition.name + " / " + self.name
+
+ class Admin:
+ pass
+
+class MediaItemProperty(models.Model):
+ "Associate a value to a media item dynamic property"
+
+ definition = models.ForeignKey(MediaItemPropertyDefinition, core=True)
+ media_item = models.ForeignKey(MediaItem)
+ value = models.CharField(maxlength=250)
+ enum_item = models.ForeignKey(MediaItemPropertyEnumerationItem, null=True)
+
+ def __str__(self):
+ return str(self.media_item) + " / " + str(self.definition)
+
+ class Meta:
+ unique_together = (("media_item", "definition"),)
+
+ class Admin:
+ pass
+
+
+class Part:
+ media_item = models.ForeignKey(MediaItem)
+ parent = models.ForeignKey('self', null=True, related_name='children')
+ name = models.CharField(maxlength=250)
--- /dev/null
+<html>
+<link rel="stylesheet" href="/telemeta/css/style.css" />
+<body>
+<div id="header">
+Telemeta Web Interface
+</div>
+{% block content %}{% endblock %}
+</body>
+</html>
--- /dev/null
+<pre>{% debug %}</pre>
+
+<h3>Pieces</h3>
+{% if pieces %}
+ <ul>
+ {% for p in pieces %}
+ <li><b>{{ p.author }}</b> - {{ p.title }}</li>
+ {% endfor %}
+ </ul>
+{% else %}
+ <p>No pieces are available.</p>
+{% endif %}
--- /dev/null
+{% extends "base.html" %}
+
+{% block content %}
+<h3>Media Item</h3>
+
+<form action="/telemeta/media_item/{{ media_item.id }}/update/" method="post">
+<label>Author : </label><input name="author" value="{{ media_item.author }}"><br/>
+<label>Title : </label><input name="title" value="{{ media_item.title }}"><br/>
+{% if dynprops %}
+ {% for prop in dynprops %}
+ <label>{{ prop.name }} : </label>
+ {% ifequal prop.type "text" %}
+ <input name="dynprop_{{ prop.id }}" value="{{ prop.value }}"><br/>
+ {% else %}
+ <select name="dynprop_{{ prop.id }}">
+ <option value="0"></option>
+ {% for item in prop.enumeration %}
+ <option value="{{ item.id }}"
+ {% ifequal prop.value.id item.id %} selected {% endifequal %} >
+ {{ item.name }}</option>
+ {% endfor %}
+ </select>
+ {% endifequal %}
+ {% endfor %}
+{% endif %}
+<p>
+<input type="submit">
+</form>
+{% endblock %}
--- /dev/null
+{% extends "base.html" %}
+
+{% block content %}
+<h3>Media items</h3>
+{% if object_list %}
+ <ul>
+ {% for p in object_list %}
+ <li><b>{{ p.author }}</b> - {{ p.title }}
+ <a href="{{ p.id }}">View</a>
+ <a href="#">Edit</a>
+ </li>
+ {% endfor %}
+ </ul>
+{% else %}
+ <p>No pieces are available.</p>
+{% endif %}
+{% endblock %}
--- /dev/null
+from django.conf.urls.defaults import *
+from telemeta.models import MediaItem
+
+list_dict = {
+ 'queryset': MediaItem.objects.all(),
+}
+
+urlpatterns = patterns('',
+ (r'^$', 'telemeta.views.web.index'),
+ (r'^media_item/$', 'django.views.generic.list_detail.object_list',
+ dict(list_dict, paginate_by=10, template_name="mediaitem_list.html")),
+ (r'^media_item/(?P<media_item_id>[0-9]+)/$', 'telemeta.views.web.media_item_edit'),
+ (r'^media_item/(?P<media_item_id>[0-9]+)/update/$', 'telemeta.views.web.media_item_update'),
+
+ # CSS (FIXME: for developement only)
+ (r'^css/(?P<path>.*)$', 'django.views.static.serve', {'document_root': './telemeta/css'}),
+)
+
+
--- /dev/null
+
+class Logger:
+ "Provide simple message logging"
+
+ filename="/tmp/telemeta.log"
+
+ def __init__(self):
+ self.file = open(self.filename, "a")
+
+ def debug(self, msg):
+ self.file.write(msg + "\n")
+ self.file.flush()
+
--- /dev/null
+
+import telemeta
+from django.template import Context, loader
+from django.http import HttpResponse
+from telemeta.models import MediaItem
+from telemeta.models import MediaItemPropertyDefinition
+from telemeta.models import MediaItemPropertyEnumerationItem
+from telemeta.models import MediaItemProperty
+from django.shortcuts import render_to_response
+import re
+
+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))
+
+def media_item_edit(request, media_item_id):
+ "Provide MediaItem object edition"
+
+ media_item = MediaItem.objects.get(pk=media_item_id)
+ dynprops = media_item.get_dynamic_properties()
+ return render_to_response('media_item.html', {'media_item': media_item, 'dynprops' : dynprops})
+
+def media_item_update(request, media_item_id):
+ "Handle MediaItem object edition form submission"
+
+ media_item = MediaItem.objects.get(pk=media_item_id)
+ media_item.author = request.POST['author']
+ media_item.title = request.POST['title']
+ media_item.save()
+
+ pattern = re.compile(r'^dynprop_(\d+)$')
+ for name, value in request.POST.items():
+ match = pattern.search(name)
+ if match:
+ prop_id = match.groups()[0]
+ prop = MediaItemPropertyDefinition.objects.get(pk=prop_id)
+ telemeta.logger.debug("prop_id: " + prop_id + " ; " + "media_item_id: " +
+ media_item_id + " ; value: " + value +
+ " ; type:" + prop.type)
+ media_item = MediaItem.objects.get(pk=media_item_id)
+ property, created = MediaItemProperty.objects.get_or_create(
+ media_item=media_item, definition=prop)
+
+ if prop.type == 'text':
+ property.value = value
+ else:
+ value = int(value)
+
+ if value > 0:
+ enum_item = MediaItemPropertyEnumerationItem.objects.get(pk=value)
+ property.enum_item = enum_item
+ else:
+ property.enum_item = 0
+
+ property.save()
+
+ return media_item_edit(request, media_item_id)
+
+
+
+
+