Commits

Anonymous committed 12d0fc2

Next big changes with upload processing. Added filter framework.
First filter is exif parser to add photo meta-tags.

  • Participants
  • Parent commits f7a28ec

Comments (0)

Files changed (8)

 \.pyc$
+\.DS_Store$
 from django.contrib import admin
 
-from models import Stream, Category, Item, Filter, Variant, Queue
+from models import Stream, Item, Filter, Variant, Queue, Meta
 
-class CategoryAdmin(admin.ModelAdmin):
-    prepopulated_fields = {"slug": ("name",)}
 
 class StreamAdmin(admin.ModelAdmin):
     prepopulated_fields = {"slug": ("name",)}
 
+class MetaAdmin(admin.ModelAdmin):
+    list_display = ('__unicode__', 'item')
+
 class ItemAdmin(admin.ModelAdmin):
-    list_display = ('name', 'mime', 'category', 'upload_date')
+    list_display = ('__unicode__', 'mime', 'upload_date')
     prepopulated_fields = {"slug": ("name",)}
     date_hierarchy = 'upload_date'
     filter_horizontal = ('stream',)
-    radio_fields = {'category': admin.VERTICAL}
-    list_filter = ('category', 'upload_date', 'mime')
+    #radio_fields = {'category': admin.VERTICAL}
+    list_filter = ('upload_date', 'mime')
     search_fields = ['name']
 
-admin.site.register(Category, CategoryAdmin)
+admin.site.register(Item, ItemAdmin)
+admin.site.register(Meta, MetaAdmin)
 admin.site.register(Stream, StreamAdmin)
-admin.site.register(Item, ItemAdmin)
+

File filters/__init__.py

+from django.conf import settings
+
+def active():
+    filters = []
+    for filt in settings.ENABLED_FILTERS:
+        try:
+            mod = __import__(filt, '', '', [''])
+        except ImportError, e:
+            continue
+        if mod.enabled():
+            filters.append(filt)
+    return filters
+
+def run(instance, **kwargs):
+    """
+    Run filters on specific Item.
+    """
+    for filt in settings.ENABLED_FILTERS:
+        try:
+            mod = __import__('mediatr.filters', '', '', [filt])
+            mod = getattr(mod, filt)
+        except ImportError, e:
+            print "Can't import module %s: %s" % (filt, e)
+            continue
+        if mod.enabled():
+            mod.filter_obj(instance)

File filters/exif.py

+"""
+Filter for jpg images only. Export some EXIF fields as meta fields for file item.
+"""
+import EXIF
+
+def enabled():
+    """
+    Various cheks goes here (settings, imports, etc)
+    """
+    return True
+
+def filter_obj(object, params=None):
+    """
+    Main filter body. Object is instance of mediatr.models.Item, params is a filter specific tunings.
+    """
+    tags = EXIF.process_file(object.file)
+    if not tags:
+        return
+    fnum = str(tags.get('EXIF FNumber')).split('/')
+    # calculate aperture
+    if len(fnum) == 2:
+        aperture = "f/%.1f" % (float(fnum[0])/float(fnum[1]))
+    elif fnum[0] != 'None':
+        aperture = "f/%s" % (fnum[0])
+    else:
+        aperture = None
+    exposure = str(tags.get('EXIF ExposureTime'))
+    focal = tags.get('EXIF FocalLength')
+    if focal: # prettify focal length value
+        focal = "%smm" % (str(focal))
+    # trying to update exiting aperture value
+    try:
+        ma = object.meta_set.get(field='Aperture')
+        if not aperture:
+            ma.delete()
+        else:
+            ma.value=aperture
+            ma.save()
+    # add aperture value if empty
+    except object.meta_set.model.DoesNotExist:
+        if aperture:
+            object.meta_set.create(field='Aperture', value=aperture)
+    # trying to update exposure value
+    try:
+        me = object.meta_set.get(field='Exposure')
+        if not exposure:
+            me.delete()
+        else:
+            me.value=exposure
+            me.save()
+    # add exposure value if empty
+    except object.meta_set.model.DoesNotExist:
+        if exposure:
+            object.meta_set.create(field='Exposure', value=exposure)
+    # trying to update focal length value
+    try:
+        mf = object.meta_set.get(field='Focal Length')
+        if not focal:
+            mf.delete()
+        else:
+            mf.value=focal
+            mf.save()
+    # add focal length value if empty
+    except object.meta_set.model.DoesNotExist:
+        if focal:
+            object.meta_set.create(field='Focal Length', value=focal)

File filters/sample.py

+"""
+Sample skeleton for new filter.
+"""
+
+def enabled():
+    """
+    Various cheks goes here (settings, imports, etc)
+    """
+    return False
+
+def filter_obj(object, params=None):
+    """
+    Main filter body. Object is instance of mediatr.models.Item, params is a filter specific tunings.
+    """
+import uuid
+import base64
+import random
+
+
+def make_hash(lenght=7):
+    """
+    Creates random hash (youtube-like) with specified lenght
+    """
+    bstr = base64.b64encode("%s" % uuid.uuid4())
+    start_p = random.randrange(1, len(bstr) - lenght)
+    return bstr[start_p:start_p+lenght]
 from django.template.defaultfilters import slugify
 from django.db.models import permalink
 
-from signals import add_mime_type
+from signals import add_mime_type, make_slug
+import filters
 
 
 class Stream(models.Model):
     def __unicode__(self):
         return self.name
 
-class Category(models.Model):
+class Gallery(models.Model):
     """
-    Global one-level file classification by media type,
-    e.g. image, video, text, etc.
+    Media gallery for internal resource categorization.
     """
     name = models.CharField(max_length=200)
     slug = models.SlugField()
+    description = models.TextField(blank=True)
 
     def __unicode__(self):
         return self.name
 
+class Batch(models.Model):
+    """
+    Batch upload tracking. For mass upload/edit capabilities.
+    """
+    ident = models.CharField(max_length=200)
+    uploaded = models.DateTimeField(auto_now_add=True)
+
+    def __unicode__(self):
+        return self.ident
+
+
 class Item(models.Model):
     """
     Main file
     """
     user = models.ForeignKey(User)
-    name = models.CharField(max_length=200)
-    slug = models.SlugField()
+    name = models.CharField(max_length=200, blank=True)
+    slug = models.SlugField(blank=True)
     text = models.TextField(blank=True)
     file = models.FileField(upload_to='files', blank=True)
     mime = models.ForeignKey(MimeType, blank=True, null=True)
-    category = models.ForeignKey(Category)
+    batch = models.ForeignKey(Batch, blank=True, null=True)
+    gallery = models.ForeignKey(Gallery, blank=True, null=True)
     stream = models.ManyToManyField(Stream, blank=True, related_name='items')
     upload_date = models.DateTimeField(auto_now_add=True)
     publish_date = models.DateTimeField(auto_now_add=True)
 
     def __unicode__(self):
-        return self.name
+        if self.name:
+            return self.name
+        else:
+            return "Item: %s" % (self.slug)
     
     def set_mime(self, mime):
         obj, created = MimeType.objects.get_or_create(name=mime, slug=slugify(mime))
     """
     File filter for creating variants, such as thumbnails, flv, etc
     """
-    for_type = models.ForeignKey(Category)
     name = models.CharField(max_length=200)
     cmd = models.CharField(max_length=100)
     params = models.TextField(blank=True)
     template = models.TextField(default="<a href={{ object.get_absolute_url }}>{{ object.name }}</a>")
-    auto = models.BooleanField(default=False)
     default = models.BooleanField(default=False)
 
     class Admin:
     file = models.FileField(upload_to='variants')
     mime = models.ForeignKey(MimeType)
     filter = models.ForeignKey(Filter)
+    default = models.BooleanField(default=False)
     
     class Meta:
         unique_together = (("filter", "file"),)
     def __unicode__(self):
         return self.name
 
+# class MetaField(models.Model):
+#     """
+#     MetaField aka meta type
+#     """
+#     name = models.CharField(max_length=150)
+# 
+#     def __unicode__(self):
+#         return self.name
+
+class Meta(models.Model):
+    """
+    File meta info, like exif data for jpg or id3 tags for mp3
+    """
+    item = models.ForeignKey(Item)
+    field = models.CharField(max_length=250)
+    value = models.CharField(max_length=250)
+
+    class Meta:
+        unique_together = (("item", "field", "value"),)
+
+    def __unicode__(self):
+        return u"%s: %s" % (self.field, self.value)
+
 class Queue(models.Model):
     """
     Queue for creating variants from file via filter
         return self.file
 
 models.signals.pre_save.connect(add_mime_type, sender=Item)
+models.signals.pre_save.connect(make_slug, sender=Item)
+models.signals.post_save.connect(filters.run, sender=Item)
 import mimetypes
 import os.path
+from django.template.defaultfilters import slugify
+
+from helpers import make_hash
 
 
 # init mime types dict
         extension = os.path.splitext(instance.file.path)[1].lower()
         instance.set_mime(mimetypes.types_map[extension])
         #instance.save()
+
+def make_slug(instance, **kwargs):
+    """
+    Set random hash as slug for unnamed items.
+    """
+    if not hasattr(instance, 'slug'):
+        raise WrongObjectException("Object %s does not have slug attribute! Can't set random slug!" % instance)
+    if not instance.slug:
+        if hasattr(instance, 'name') and instance.name:
+            instance.slug = slugify(instance.name)
+        else:
+            instance.slug = make_hash()