Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

starting work on new video system

  • Loading branch information...
commit 7e80792b397611312a39287a75e854dc45393219 1 parent 379357e
@evildmp authored
View
2  cmsplugin_filer_video/__init__.py
@@ -1,2 +0,0 @@
-__version__ = "0.0.1a"
-__authors__ = ["Daniele Procida <daniele@cf.ac.uk>", ]
View
162 cmsplugin_filer_video/cms_plugins.py
@@ -1,162 +0,0 @@
-import os, models, bisect
-
-from threading import Thread
-
-from django.utils.translation import ugettext_lazy as _
-
-from cms.plugin_pool import plugin_pool
-from cms.plugin_base import CMSPluginBase
-
-from arkestra_utilities.output_libraries.plugin_widths import *
-
-from filer.models.videomodels import CODECS, VERSIONS, SIZES, PLAYERS
-
-class FilerVideoPluginPublisher(CMSPluginBase):
- model = models.FilerVideoEditor
- name = _("Video")
- render_template = "cmsplugin_filer_video/video.html"
- text_enabled = True
- admin_preview = False
- raw_id_fields = ('video',)
-
- def render(self, context, instance, placeholder):
- """
- Arkestra can calculate the exact pixel width of any column in any placeholder; however, this isn't available to all applications that might use the filer.
-
- So, we should make the calculations here optional, and for non-Arkestra implementations do something different
- """
- instance.has_borders = False
-
- # calculate the width of the placeholder
- placeholder_width = get_placeholder_width(context, instance)
-
- # widths a fraction of nominal container width (deprecated)
- if instance.width <= 10:
- width = placeholder_width/instance.width
-
- # widths relative to placeholder width
- else:
- # widths a percentage of placeholder width
- if instance.width <= 100:
- width = placeholder_width/100.0 * instance.width
- auto = False
-
- # automatic width
- elif instance.width == 1000:
- width = placeholder_width
- auto = True
-
- # calculate the width of the block the image will be in
- width = calculate_container_width(context, instance, width, auto)
-
- # shave off 5 point if the image is floated, to make room for a margin
- # see arkestra.css, span.image.left and span.image.right
- if instance.float:
- print "-5 for float"
- width = width - 5
-
- if instance.use_description_as_caption:
- instance.caption = instance.caption or instance.image.description
-
- # given the width we want to show the video at, we have to find the most suitable (i.e. closest larger) video file version we have created
- index = bisect.bisect_left(SIZES,width)
- print "sizes", SIZES, width, index
- if index < len(SIZES): # not larger than the largest preset size?
- size = SIZES[index] # get the exact or closest larger size
- else:
- # choose the widest, if we don't have one wider
- size = SIZES[-1]
-
- # create the lists of missing and available items
- instance.missing_versions = []
- instance.available_versions =[]
-
- # get the video's status dictionary
- version_status = instance.video.get_status()
- print
- print ">>> checking status of the video"
-
- for codec, codec_dictionary in CODECS.items():
- print " checking...", codec, size
- # get the version's codec_and_size identifier
- codec_and_size = instance.video.codec_and_size(codec,size)
- # get the file path for the version
- videofilepath = instance.video.outputpath(codec, size)
- print " Status:", instance.video.check_status(codec,size)
- print " Filepath:", videofilepath
-
- # does the file exist?
- if os.path.exists(videofilepath):
- print " the file exists"
- # if it does, check that the status dictionary agrees
-
- if instance.video.check_status(codec,size) == "OK":
- print " the file is there and marked as present"
- # and add the version to available_versions
- instance.available_versions.append(codec)
- else:
- # what if the status dictionary doesn't say that the file is ready?
- instance.missing_versions.append(codec)
- # if status check says it's encoding, leave it alone
- if instance.video.check_status(codec,size) == "encoding":
- print " but it must be still encoding"
- else:
- # if it's not "OK" and not "encoding", it must be "missing" or "failed"- so let's try to encode it
- print " but it's marked as missing or failed, so we'd better re-create it"
- print " instance.video.create_version:", instance.video.create_version
- print " videofilepath:", videofilepath
- print " codec:", codec
-
- thread = Thread(target=instance.video.create_version, name=videofilepath, args=(codec, size))
- print " launching thread"
- thread.start()
-
- # if the file doesn't exist
- else:
- print " the file doesn't exist, so we need to create the missing version"
- print " instance.video.create_version:", instance.video.create_version
- print " videofilepath:", videofilepath
- print " codec:", codec
- # add the version of missing versions
- instance.missing_versions.append(codec)
- thread = Thread(target=instance.video.create_version, name=videofilepath, args=(codec, size))
- print " launching thread"
- thread.start()
-
- # now we need to list the versions available to the different players (HTML5 and Flash so far, but we could have others if we wanted). The same version (H.264) is currently used for both HTML5 and Flash
- instance.html5_formats = []
- instance.flash_formats = []
- # all_formats is a list of versions without any duplications
- instance.all_formats = []
- instance.available_versions = set(instance.available_versions)
-
- # let's assemble the list of versions available for HTML5
- instance.formats = {}
- print "available versions", instance.available_versions
- for player, player_codecs in PLAYERS.items():
- print "player", player, "player_codecs", player_codecs
- instance.formats[player] = []
- for codec in player_codecs:
- print "codec is", codec
- if codec in instance.available_versions:
- print "adding", codec
- # add all the information we'll need about this version to a dictionary
- description = {"url": instance.video.url(codec, size), "type": VERSIONS[codec][size]["type"], "description": CODECS[codec]["description"], "implications": CODECS[codec]["implications"],}
- instance.formats[player].append(description)
- if description not in instance.all_formats:
- instance.all_formats.append(description)
-
- instance.width = int(width)
- instance.height = int(width/1.5)
- context.update({
- 'object':instance,
- #'link':instance.link,
- #'image_url':instance.scaled_image_url,
- 'width': int(width),
- 'caption_width': int(width),
- 'placeholder':placeholder,
- })
- print "returning from video plugin render"
- return context
-
-plugin_pool.register_plugin(FilerVideoPluginPublisher)
View
131 cmsplugin_filer_video/migrations/0001_initial.py
@@ -1,131 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
- def forwards(self, orm):
-
- # Adding model 'FilerVideoEditor'
- db.create_table('cmsplugin_filervideoeditor', (
- ('cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)),
- ('video', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['filer.File'])),
- ('width', self.gf('django.db.models.fields.FloatField')(default=1000.0, null=True, blank=True)),
- ('use_description_as_caption', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
- ('caption', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
- ('float', self.gf('django.db.models.fields.CharField')(max_length=10, null=True, blank=True)),
- ))
- db.send_create_signal('cmsplugin_filer_video', ['FilerVideoEditor'])
-
-
- def backwards(self, orm):
-
- # Deleting model 'FilerVideoEditor'
- db.delete_table('cmsplugin_filervideoeditor')
-
-
- models = {
- 'auth.group': {
- 'Meta': {'object_name': 'Group'},
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- 'auth.permission': {
- 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- 'auth.user': {
- 'Meta': {'object_name': 'User'},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- 'cms.cmsplugin': {
- 'Meta': {'object_name': 'CMSPlugin'},
- 'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'language': ('django.db.models.fields.CharField', [], {'max_length': '5', 'db_index': 'True'}),
- 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
- 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.CMSPlugin']", 'null': 'True', 'blank': 'True'}),
- 'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}),
- 'plugin_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
- 'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'publisher_is_draft': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'publisher_public': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'publisher_draft'", 'unique': 'True', 'null': 'True', 'to': "orm['cms.CMSPlugin']"}),
- 'publisher_state': ('django.db.models.fields.SmallIntegerField', [], {'default': '0', 'db_index': 'True'}),
- 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
- 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
- },
- 'cms.placeholder': {
- 'Meta': {'object_name': 'Placeholder'},
- 'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
- },
- 'cmsplugin_filer_video.filervideoeditor': {
- 'Meta': {'object_name': 'FilerVideoEditor', 'db_table': "'cmsplugin_filervideoeditor'", '_ormbases': ['cms.CMSPlugin']},
- 'caption': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
- 'float': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
- 'use_description_as_caption': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
- 'video': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['filer.File']"}),
- 'width': ('django.db.models.fields.FloatField', [], {'default': '1000.0', 'null': 'True', 'blank': 'True'})
- },
- 'contenttypes.contenttype': {
- 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- 'filer.file': {
- 'Meta': {'object_name': 'File'},
- '_file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- '_file_type_plugin_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'folder': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'all_files'", 'null': 'True', 'to': "orm['filer.Folder']"}),
- 'has_all_mandatory_data': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
- 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'original_filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'owned_files'", 'null': 'True', 'to': "orm['auth.User']"}),
- 'sha1': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '40', 'blank': 'True'}),
- 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
- },
- 'filer.folder': {
- 'Meta': {'unique_together': "(('parent', 'name'),)", 'object_name': 'Folder'},
- 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
- 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
- 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'filer_owned_folders'", 'null': 'True', 'to': "orm['auth.User']"}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['filer.Folder']"}),
- 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
- 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
- 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
- }
- }
-
- complete_apps = ['cmsplugin_filer_video']
View
0  cmsplugin_filer_video/migrations/__init__.py
No changes.
View
45 cmsplugin_filer_video/models.py
@@ -1,45 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-from django.db import models
-from cms.models import CMSPlugin, Page
-from django.utils.translation import ugettext_lazy as _
-from posixpath import join, basename, splitext, exists
-from filer.fields.image import FilerImageField
-from filer.fields.video import FilerVideoField
-from cms import settings as cms_settings
-from django.conf import settings
-
-class FilerVideoEditor(CMSPlugin):
- LEFT = "left"
- RIGHT = "right"
- FLOAT_CHOICES = ((LEFT, _("left")),
- (RIGHT, _("right")),
- )
- video = FilerVideoField()
- # added for cardiff template calculations
- VIDEO_WIDTHS = (
- (1000.0, u"Automatic"),
- (u'Widths relative to the containing column', (
- (100.0, u"100%"),
- (75.0, u"75%"),
- (66.7, u"66%"),
- (50.0, u"50%"),
- (33.3, u"33%"),
- (25.0, u"25%"),
- )
- ),
- ('', u"Video's native width - on your head be it"),
- )
- width = models.FloatField(null=True, blank=True, choices = VIDEO_WIDTHS, default = 1000.0)
- wait = models.BooleanField(default=False) # not implemented yet - will make the plugin wait until all the video files are OK and present before rendering anything
-
-# end of cardiff amendments
- use_description_as_caption = models.BooleanField(verbose_name = "Use description", default=False, help_text = "Use image's description field as caption")
- caption = models.TextField(_("Caption"), blank=True, null=True)
- float = models.CharField(_("float"), max_length=10, blank=True, null=True, choices=FLOAT_CHOICES)
-
- def __unicode__(self):
- if self.video:
- return self.video.label
- else:
- return u"Video %s" % self.caption
- return ''
View
4 cmsplugin_filer_video/templates/cmsplugin_filer_video/image.html
@@ -1,4 +0,0 @@
-{% load thumbnail %}
-{% if link %}<a href="{{ link }}">{% endif %}
-<img {% if object.float %}class="{{ object.float }}" {% endif %}alt="{% if object.alt %}{{ object.alt }}{% endif %}" src="{% thumbnail object.image image_size crop,upscale %}" />
-{% if link %}</a>{% endif %}
View
40 cmsplugin_filer_video/templates/cmsplugin_filer_video/video.html
@@ -1,40 +0,0 @@
-{% load i18n filermedia %}
-{% if object.formats.HTML5 %}<video width="{{ object.width }}" height="{{ object.height }}" controls>
- {% for codec in object.formats.HTML5 %}
- {% autoescape off %}<source src="{{codec.url}}" />{% endautoescape %}
- {% endfor %}
- {% if object.formats.FLASH %}<object width="{{object.width}}" height="{{object.height}}" type="application/x-shockwave-flash" data="{% filer_staticmedia_prefix %}flash/player.swf">
- <param name="movie" value="{% filer_staticmedia_prefix %}flash/player.swf" />
- {% for codec in object.formats.FLASH %}
- <param name="flashvars" value="controlbar=over&amp;file={{codec.url}}" />
- {% endfor %}{% endif %}
- </object>{% endif %}
-
-{% if object.formats.HTML5 %}</video>{% endif %}
-{% if object.missing_versions %}
- {% if not object.available_versions %}
- <div style="border: 1px solid black; width: {{object.width}}px; height:{{object.height}}px;">
- <div style="text-align: center; padding: 15%">
- <p>The files for this video are being encoded and are not yet ready.</p>
- <p><strong>Please wait a few moments, then reload this page.</strong></p>
- </div>
- </div>
- {% else %}
- <p><strong>Having problems playing this video?</strong></p>
- <p>Some of the files are still being encoded.</p>
- <p>Please <strong>wait a few moments and reload this page</strong>
- {% if object.all_formats %}
- , or try one of the following files:
- {% else%}
- .</p>
- {% endif %}
- {% endif %}
-{% endif %}
- <p>Video available as:</p>
-{% if object.all_formats %}
- <ul>
- {% for codec in object.all_formats %}
- <li><a href="{{codec.url}}">{{ codec.description }}</a></li>
- {% endfor %}
- </ul>
-{% endif %}
View
1,033 example/filer.json
@@ -1,1033 +0,0 @@
-[
- {
- "pk": 2,
- "model": "filer.folder",
- "fields": {
- "rght": 2,
- "uploaded_at": "2011-07-06 17:42:24",
- "name": "Institute staff",
- "parent": null,
- "level": 0,
- "created_at": "2011-07-06 17:42:24",
- "modified_at": "2011-07-06 17:42:24",
- "lft": 1,
- "tree_id": 2,
- "owner": 1
- }
- },
- {
- "pk": 3,
- "model": "filer.folder",
- "fields": {
- "rght": 2,
- "uploaded_at": "2011-07-14 23:08:23",
- "name": "Other institutions",
- "parent": null,
- "level": 0,
- "created_at": "2011-07-14 23:08:23",
- "modified_at": "2011-07-14 23:08:23",
- "lft": 1,
- "tree_id": 3,
- "owner": 1
- }
- },
- {
- "pk": 1,
- "model": "filer.folder",
- "fields": {
- "rght": 2,
- "uploaded_at": "2011-06-30 21:24:23",
- "name": "Site images",
- "parent": null,
- "level": 0,
- "created_at": "2011-06-30 21:24:23",
- "modified_at": "2011-06-30 21:24:23",
- "lft": 1,
- "tree_id": 1,
- "owner": 1
- }
- },
- {
- "pk": 4,
- "model": "filer.folder",
- "fields": {
- "rght": 2,
- "uploaded_at": "2011-09-20 14:30:05",
- "name": "Video",
- "parent": null,
- "level": 0,
- "created_at": "2011-09-20 14:30:05",
- "modified_at": "2011-09-20 14:30:05",
- "lft": 1,
- "tree_id": 4,
- "owner": 1
- }
- },
- {
- "pk": 1,
- "model": "filer.file",
- "fields": {
- "sha1": "28e5b40dbd9e3d01d4cef5bcd4850a721af27611",
- "original_filename": "0020n040.jpg",
- "name": "Cutaway body",
- "description": "Latest research at the Institute has revealed the body's secrets",
- "modified_at": "2011-06-30 21:28:00",
- "_file_size": 47641,
- "uploaded_at": "2011-06-30 21:24:02",
- "file": "2011/06/30/0020n040.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 1,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 2,
- "model": "filer.file",
- "fields": {
- "sha1": "a47d7ef24edeb3a4e510294824fff4125c206e07",
- "original_filename": "07.jpg",
- "name": "Ernie Brooks",
- "description": "",
- "modified_at": "2011-07-06 17:43:04",
- "_file_size": 188780,
- "uploaded_at": "2011-07-06 17:42:41",
- "file": "2011/07/06/07.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 2,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 3,
- "model": "filer.file",
- "fields": {
- "sha1": "6d776c4712df08efa6aff9a3dd138ff1091afeb8",
- "original_filename": "335.jpg",
- "name": "Sterling Morrison",
- "description": "",
- "modified_at": "2011-07-06 17:43:19",
- "_file_size": 165741,
- "uploaded_at": "2011-07-06 17:42:44",
- "file": "2011/07/06/335.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 2,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 4,
- "model": "filer.file",
- "fields": {
- "sha1": "01f77e67705a14f27d365ce70799d1332415ce6f",
- "original_filename": "JohnCale.jpg",
- "name": "John Cale",
- "description": "",
- "modified_at": "2011-07-06 17:43:29",
- "_file_size": 82031,
- "uploaded_at": "2011-07-06 17:42:45",
- "file": "2011/07/06/johncale.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 2,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 5,
- "model": "filer.file",
- "fields": {
- "sha1": "f8b848f89ec5bcc6801002950d079e50d40ba59e",
- "original_filename": "jonathan-richman-101.jpg",
- "name": "Jonathan Richman",
- "description": "",
- "modified_at": "2011-07-06 17:43:44",
- "_file_size": 37264,
- "uploaded_at": "2011-07-06 17:42:46",
- "file": "2011/07/06/jonathan-richman-101.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 2,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 6,
- "model": "filer.file",
- "fields": {
- "sha1": "c6d77989d15419c20723ca1a94c13175fd28c9ce",
- "original_filename": "84_evil-eye.gif",
- "name": "Evil eye",
- "description": "",
- "modified_at": "2011-07-06 19:43:32",
- "_file_size": 24297,
- "uploaded_at": "2011-07-06 19:43:13",
- "file": "2011/07/06/84_evil-eye.gif",
- "owner": 1,
- "is_public": true,
- "folder": 1,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 7,
- "model": "filer.file",
- "fields": {
- "sha1": "70675d59be8930fbf0e9d26c884f21980686518a",
- "original_filename": "tooth.jpg",
- "name": "Tooth pulling",
- "description": "",
- "modified_at": "2011-07-06 21:42:30",
- "_file_size": 199037,
- "uploaded_at": "2011-07-06 21:42:13",
- "file": "2011/07/06/tooth.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 1,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 8,
- "model": "filer.file",
- "fields": {
- "sha1": "5902ae1c382964b4485a698f921fd9be35cb590a",
- "original_filename": "Haddock.JPG",
- "name": "Captain Haddock",
- "description": "",
- "modified_at": "2011-07-14 23:08:53",
- "_file_size": 16411,
- "uploaded_at": "2011-07-14 23:08:41",
- "file": "2011/07/14/haddock.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 3,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 9,
- "model": "filer.file",
- "fields": {
- "sha1": "e6fdf2332db6cc8c6496b3c35ec7f25aa3077217",
- "original_filename": "110.jpg",
- "name": "Shane MacGowan",
- "description": "",
- "modified_at": "2011-07-28 15:38:24",
- "_file_size": 352020,
- "uploaded_at": "2011-07-28 13:46:36",
- "file": "2011/07/28/15644525.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 1,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 10,
- "model": "filer.file",
- "fields": {
- "sha1": "a852f38f985ee098f9aba2dae274e623e90317dd",
- "original_filename": "arrow-down.png",
- "name": "Arrow down",
- "description": "",
- "modified_at": "2011-07-28 23:54:57",
- "_file_size": 1038,
- "uploaded_at": "2011-07-28 23:39:31",
- "file": "2011/07/28/arrow-down_1.png",
- "owner": 1,
- "is_public": true,
- "folder": 1,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 11,
- "model": "filer.file",
- "fields": {
- "sha1": "d4b530a3cfb9f223d934ad79f54f77834cd85863",
- "original_filename": "arrow-left.png",
- "name": "Arrow left",
- "description": "",
- "modified_at": "2011-07-28 23:55:37",
- "_file_size": 1259,
- "uploaded_at": "2011-07-28 23:39:32",
- "file": "2011/07/28/arrow-left_1.png",
- "owner": 1,
- "is_public": true,
- "folder": 1,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 12,
- "model": "filer.file",
- "fields": {
- "sha1": "817fc1fe1ff40ce4119912c30a31462f979e9ec6",
- "original_filename": "arrow-right.png",
- "name": "Arrow right",
- "description": "",
- "modified_at": "2011-07-28 23:55:48",
- "_file_size": 1195,
- "uploaded_at": "2011-07-28 23:39:33",
- "file": "2011/07/28/arrow-right_1.png",
- "owner": 1,
- "is_public": true,
- "folder": 1,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 13,
- "model": "filer.file",
- "fields": {
- "sha1": "875f211695c0a988a27de9589420f90c17de6d86",
- "original_filename": "arrow-up.png",
- "name": "Arrow up",
- "description": "",
- "modified_at": "2011-07-28 23:55:58",
- "_file_size": 1019,
- "uploaded_at": "2011-07-28 23:39:33",
- "file": "2011/07/28/arrow-up_1.png",
- "owner": 1,
- "is_public": true,
- "folder": 1,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 14,
- "model": "filer.file",
- "fields": {
- "sha1": "e6b801b13e94fd559524d0b42f5f78f460c45ac2",
- "original_filename": "normal_Carl_Perkins.jpg",
- "name": "Carl Perkins",
- "description": "",
- "modified_at": "2011-07-29 00:10:11",
- "_file_size": 59630,
- "uploaded_at": "2011-07-29 00:10:00",
- "file": "2011/07/29/normal_carl_perkins.jpg",
- "owner": 1,
- "is_public": true,
- "folder": 3,
- "has_all_mandatory_data": true,
- "polymorphic_ctype": 37
- }
- },
- {
- "pk": 19,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:03:14",
- "file": "2011/09/20/video.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 20,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:11:15",
- "file": "2011/09/20/video_1.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 21,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:11:35",
- "file": "2011/09/20/video_2.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 22,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:13:13",
- "file": "2011/09/20/video_3.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 23,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:14:00",
- "file": "2011/09/20/video_4.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 24,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:14:24",
- "file": "2011/09/20/video_5.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 25,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:14:48",
- "file": "2011/09/20/video_6.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 26,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:15:56",
- "file": "2011/09/20/video_7.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 27,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:16:17",
- "file": "2011/09/20/video_8.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 28,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:17:19",
- "file": "2011/09/20/video_9.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 29,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:17:36",
- "file": "2011/09/20/video_10.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 30,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:18",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:25:10",
- "file": "2011/09/20/video_11.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 31,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:25:28",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:25:25",
- "file": "2011/09/20/video_12.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 32,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:26:00",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:25:58",
- "file": "2011/09/20/video_13.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 33,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 16:28:32",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:27:20",
- "file": "2011/09/20/video_14.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 34,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "video.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 17:02:02",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 16:29:25",
- "file": "2011/09/20/video_15.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 35,
- "model": "filer.file",
- "fields": {
- "sha1": "0cf34ce49b3795117b98d8aded90ce8cd4534029",
- "original_filename": "newvideo.dv",
- "name": null,
- "description": null,
- "modified_at": "2011-09-20 17:06:04",
- "_file_size": 20576,
- "uploaded_at": "2011-09-20 17:06:01",
- "file": "2011/09/20/newvideo.dv",
- "owner": 1,
- "is_public": true,
- "folder": 4,
- "has_all_mandatory_data": false,
- "polymorphic_ctype": 69
- }
- },
- {
- "pk": 1,
- "model": "filer.clipboard",
- "fields": {
- "user": 1
- }
- },
- {
- "pk": 1,
- "model": "filer.clipboarditem",
- "fields": {
- "clipboard": 1,
- "file": 35
- }
- },
- {
- "pk": 1,
- "model": "filer.image",
- "fields": {
- "subject_location": "178,292",
- "must_always_publish_copyright": false,
- "date_taken": "2011-06-30 21:24:02",
- "author": "",
- "_height": 500,
- "_width": 382,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 2,
- "model": "filer.image",
- "fields": {
- "subject_location": "257,117",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-06 17:42:41",
- "author": "",
- "_height": 385,
- "_width": 685,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 3,
- "model": "filer.image",
- "fields": {
- "subject_location": "249,172",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-06 17:42:44",
- "author": "",
- "_height": 709,
- "_width": 476,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 4,
- "model": "filer.image",
- "fields": {
- "subject_location": "233,86",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-06 17:42:45",
- "author": "",
- "_height": 257,
- "_width": 480,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 5,
- "model": "filer.image",
- "fields": {
- "subject_location": "189,101",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-06 17:42:46",
- "author": "",
- "_height": 585,
- "_width": 410,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 6,
- "model": "filer.image",
- "fields": {
- "subject_location": "215,161",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-06 19:43:13",
- "author": "",
- "_height": 300,
- "_width": 440,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 7,
- "model": "filer.image",
- "fields": {
- "subject_location": "",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-06 21:42:13",
- "author": "",
- "_height": 282,
- "_width": 425,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 8,
- "model": "filer.image",
- "fields": {
- "subject_location": "161,98",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-14 23:08:41",
- "author": "",
- "_height": 424,
- "_width": 324,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 9,
- "model": "filer.image",
- "fields": {
- "subject_location": "457,409",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-28 13:46:36",
- "author": "",
- "_height": 858,
- "_width": 1000,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 10,
- "model": "filer.image",
- "fields": {
- "subject_location": "",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-28 23:39:31",
- "author": "",
- "_height": 43,
- "_width": 95,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 11,
- "model": "filer.image",
- "fields": {
- "subject_location": "",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-28 23:39:32",
- "author": "",
- "_height": 95,
- "_width": 43,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 12,
- "model": "filer.image",
- "fields": {
- "subject_location": "",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-28 23:39:33",
- "author": "",
- "_height": 95,
- "_width": 43,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 13,
- "model": "filer.image",
- "fields": {
- "subject_location": "",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-28 23:39:33",
- "author": "",
- "_height": 43,
- "_width": 95,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 14,
- "model": "filer.image",
- "fields": {
- "subject_location": "",
- "must_always_publish_copyright": false,
- "date_taken": "2011-07-29 00:10:00",
- "author": "",
- "_height": 450,
- "_width": 800,
- "must_always_publish_author_credit": false,
- "default_alt_text": "",
- "default_caption": ""
- }
- },
- {
- "pk": 19,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 20,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 21,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 22,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 23,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 24,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 25,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 26,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 27,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 28,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 29,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 30,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 31,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 32,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 33,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 34,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- },
- {
- "pk": 35,
- "model": "filer.video",
- "fields": {
- "encode_on_save": false,
- "delete_encoded_videos_on_save": false,
- "status": "(d."
- }
- }
-]
View
3  example/settings.py
@@ -222,8 +222,7 @@
'arkestra_utilities',
'arkestra_utilities.widgets.combobox', # so that static-files picks it up
'arkestra_image_plugin',
- # 'video',
- 'cmsplugin_filer_video',
+ 'video',
# other applications
View
2  video/__init__.py
@@ -0,0 +1,2 @@
+__version__ = "0.0.1a"
+__authors__ = ["Daniele Procida <daniele@cf.ac.uk>", ]
View
166 video/cms_plugins.py
@@ -1,24 +1,162 @@
-print "in VideoPluginPlublisher"
-from cms.plugin_base import CMSPluginBase
-from cms.plugin_pool import plugin_pool
+import os, models, bisect
+
+from threading import Thread
+
from django.utils.translation import ugettext_lazy as _
-import models
-class VideoPluginPublisher(CMSPluginBase):
- model = models.VideoPluginEditor
- name = _("Video new")
+from cms.plugin_pool import plugin_pool
+from cms.plugin_base import CMSPluginBase
+
+from arkestra_utilities.output_libraries.plugin_widths import *
+
+from filer.models.videomodels import CODECS, VERSIONS, SIZES, PLAYERS
+
+class FilerVideoPluginPublisher(CMSPluginBase):
+ model = models.FilerVideoEditor
+ name = _("Video")
render_template = "video/video.html"
- text_enabled = False
- raw_id_fields = ('image',)
+ text_enabled = True
+ admin_preview = False
+ raw_id_fields = ('video',)
def render(self, context, instance, placeholder):
+ """
+ Arkestra can calculate the exact pixel width of any column in any placeholder; however, this isn't available to all applications that might use the filer.
+
+ So, we should make the calculations here optional, and for non-Arkestra implementations do something different
+ """
+ instance.has_borders = False
+
+ # calculate the width of the placeholder
+ placeholder_width = get_placeholder_width(context, instance)
+
+ # widths a fraction of nominal container width (deprecated)
+ if instance.width <= 10:
+ width = placeholder_width/instance.width
+
+ # widths relative to placeholder width
+ else:
+ # widths a percentage of placeholder width
+ if instance.width <= 100:
+ width = placeholder_width/100.0 * instance.width
+ auto = False
+
+ # automatic width
+ elif instance.width == 1000:
+ width = placeholder_width
+ auto = True
+
+ # calculate the width of the block the image will be in
+ width = calculate_container_width(context, instance, width, auto)
+
+ # shave off 5 point if the image is floated, to make room for a margin
+ # see arkestra.css, span.image.left and span.image.right
+ if instance.float:
+ print "-5 for float"
+ width = width - 5
+
+ if instance.use_description_as_caption:
+ instance.caption = instance.caption or instance.image.description
+
+ # given the width we want to show the video at, we have to find the most suitable (i.e. closest larger) video file version we have created
+ index = bisect.bisect_left(SIZES,width)
+ print "sizes", SIZES, width, index
+ if index < len(SIZES): # not larger than the largest preset size?
+ size = SIZES[index] # get the exact or closest larger size
+ else:
+ # choose the widest, if we don't have one wider
+ size = SIZES[-1]
+
+ # create the lists of missing and available items
+ instance.missing_versions = []
+ instance.available_versions =[]
+
+ # get the video's status dictionary
+ version_status = instance.video.get_status()
+ print
+ print ">>> checking status of the video"
+
+ for codec, codec_dictionary in CODECS.items():
+ print " checking...", codec, size
+ # get the version's codec_and_size identifier
+ codec_and_size = instance.video.codec_and_size(codec,size)
+ # get the file path for the version
+ videofilepath = instance.video.outputpath(codec, size)
+ print " Status:", instance.video.check_status(codec,size)
+ print " Filepath:", videofilepath
+
+ # does the file exist?
+ if os.path.exists(videofilepath):
+ print " the file exists"
+ # if it does, check that the status dictionary agrees
+
+ if instance.video.check_status(codec,size) == "OK":
+ print " the file is there and marked as present"
+ # and add the version to available_versions
+ instance.available_versions.append(codec)
+ else:
+ # what if the status dictionary doesn't say that the file is ready?
+ instance.missing_versions.append(codec)
+ # if status check says it's encoding, leave it alone
+ if instance.video.check_status(codec,size) == "encoding":
+ print " but it must be still encoding"
+ else:
+ # if it's not "OK" and not "encoding", it must be "missing" or "failed"- so let's try to encode it
+ print " but it's marked as missing or failed, so we'd better re-create it"
+ print " instance.video.create_version:", instance.video.create_version
+ print " videofilepath:", videofilepath
+ print " codec:", codec
+
+ thread = Thread(target=instance.video.create_version, name=videofilepath, args=(codec, size))
+ print " launching thread"
+ thread.start()
+
+ # if the file doesn't exist
+ else:
+ print " the file doesn't exist, so we need to create the missing version"
+ print " instance.video.create_version:", instance.video.create_version
+ print " videofilepath:", videofilepath
+ print " codec:", codec
+ # add the version of missing versions
+ instance.missing_versions.append(codec)
+ thread = Thread(target=instance.video.create_version, name=videofilepath, args=(codec, size))
+ print " launching thread"
+ thread.start()
+
+ # now we need to list the versions available to the different players (HTML5 and Flash so far, but we could have others if we wanted). The same version (H.264) is currently used for both HTML5 and Flash
+ instance.html5_formats = []
+ instance.flash_formats = []
+ # all_formats is a list of versions without any duplications
+ instance.all_formats = []
+ instance.available_versions = set(instance.available_versions)
+
+ # let's assemble the list of versions available for HTML5
+ instance.formats = {}
+ print "available versions", instance.available_versions
+ for player, player_codecs in PLAYERS.items():
+ print "player", player, "player_codecs", player_codecs
+ instance.formats[player] = []
+ for codec in player_codecs:
+ print "codec is", codec
+ if codec in instance.available_versions:
+ print "adding", codec
+ # add all the information we'll need about this version to a dictionary
+ description = {"url": instance.video.url(codec, size), "type": VERSIONS[codec][size]["type"], "description": CODECS[codec]["description"], "implications": CODECS[codec]["implications"],}
+ instance.formats[player].append(description)
+ if description not in instance.all_formats:
+ instance.all_formats.append(description)
+
+ instance.width = int(width)
+ instance.height = int(width/1.5)
context.update({
'object':instance,
+ #'link':instance.link,
+ #'image_url':instance.scaled_image_url,
+ 'width': int(width),
+ 'caption_width': int(width),
'placeholder':placeholder,
- })
+ })
+ print "returning from video plugin render"
return context
- def icon_src(self, instance):
- return "instance.image.thumbnails['admin_tiny_icon']"
-
-plugin_pool.register_plugin(VideoPluginPublisher)
+plugin_pool.register_plugin(FilerVideoPluginPublisher)
View
0  cmsplugin_filer_video/forms.py → video/forms.py
File renamed without changes
View
93 video/migrations/0001_initial.py
@@ -8,21 +8,54 @@ class Migration(SchemaMigration):
def forwards(self, orm):
- # Adding model 'VideoPluginEditor'
- db.create_table('cmsplugin_videoplugineditor', (
+ # Adding model 'FilerVideoEditor'
+ db.create_table('cmsplugin_filervideoeditor', (
('cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)),
+ ('video', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['filer.File'])),
+ ('width', self.gf('django.db.models.fields.FloatField')(default=1000.0, null=True, blank=True)),
+ ('use_description_as_caption', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
('caption', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+ ('float', self.gf('django.db.models.fields.CharField')(max_length=10, null=True, blank=True)),
))
- db.send_create_signal('video', ['VideoPluginEditor'])
+ db.send_create_signal('cmsplugin_filer_video', ['FilerVideoEditor'])
def backwards(self, orm):
- # Deleting model 'VideoPluginEditor'
- db.delete_table('cmsplugin_videoplugineditor')
+ # Deleting model 'FilerVideoEditor'
+ db.delete_table('cmsplugin_filervideoeditor')
models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
'cms.cmsplugin': {
'Meta': {'object_name': 'CMSPlugin'},
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
@@ -46,11 +79,53 @@ def backwards(self, orm):
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
},
- 'video.videoplugineditor': {
- 'Meta': {'object_name': 'VideoPluginEditor', 'db_table': "'cmsplugin_videoplugineditor'", '_ormbases': ['cms.CMSPlugin']},
+ 'cmsplugin_filer_video.filervideoeditor': {
+ 'Meta': {'object_name': 'FilerVideoEditor', 'db_table': "'cmsplugin_filervideoeditor'", '_ormbases': ['cms.CMSPlugin']},
'caption': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'})
+ 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
+ 'float': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'use_description_as_caption': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'video': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['filer.File']"}),
+ 'width': ('django.db.models.fields.FloatField', [], {'default': '1000.0', 'null': 'True', 'blank': 'True'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'filer.file': {
+ 'Meta': {'object_name': 'File'},
+ '_file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ '_file_type_plugin_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'folder': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'all_files'", 'null': 'True', 'to': "orm['filer.Folder']"}),
+ 'has_all_mandatory_data': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'original_filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'owned_files'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'sha1': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '40', 'blank': 'True'}),
+ 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
+ },
+ 'filer.folder': {
+ 'Meta': {'unique_together': "(('parent', 'name'),)", 'object_name': 'Folder'},
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+ 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+ 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'filer_owned_folders'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['filer.Folder']"}),
+ 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+ 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+ 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
}
}
- complete_apps = ['video']
+ complete_apps = ['cmsplugin_filer_video']
View
0  ...auto__chg_field_filervideoeditor_video.py → ...auto__chg_field_filervideoeditor_video.py
File renamed without changes
View
0  ..._auto__add_field_filervideoeditor_wait.py → ..._auto__add_field_filervideoeditor_wait.py
File renamed without changes
View
46 video/models.py
@@ -1,9 +1,49 @@
from django.utils.translation import ugettext_lazy as _
from django.db import models
-from cms.models import CMSPlugin
+from cms.models import CMSPlugin, Page
+from django.utils.translation import ugettext_lazy as _
+from posixpath import join, basename, splitext, exists
+from filer.fields.image import FilerImageField
+from filer.fields.video import FilerVideoField
+from cms import settings as cms_settings
+from django.conf import settings
+
+class FilerVideoEditor(CMSPlugin):
+ LEFT = "left"
+ RIGHT = "right"
+ FLOAT_CHOICES = ((LEFT, _("left")),
+ (RIGHT, _("right")),
+ )
+ video = FilerVideoField()
+ # added for cardiff template calculations
+ VIDEO_WIDTHS = (
+ (1000.0, u"Automatic"),
+ (u'Widths relative to the containing column', (
+ (100.0, u"100%"),
+ (75.0, u"75%"),
+ (66.7, u"66%"),
+ (50.0, u"50%"),
+ (33.3, u"33%"),
+ (25.0, u"25%"),
+ )
+ ),
+ ('', u"Video's native width - on your head be it"),
+ )
+ width = models.FloatField(null=True, blank=True, choices = VIDEO_WIDTHS, default = 1000.0)
+ wait = models.BooleanField(default=False) # not implemented yet - will make the plugin wait until all the video files are OK and present before rendering anything
-class VideoPluginEditor(CMSPlugin):
+# end of cardiff amendments
+ use_description_as_caption = models.BooleanField(verbose_name = "Use description", default=False, help_text = "Use image's description field as caption")
caption = models.TextField(_("Caption"), blank=True, null=True)
+ float = models.CharField(_("float"), max_length=10, blank=True, null=True, choices=FLOAT_CHOICES)
def __unicode__(self):
- return 'Video'
+ if self.video:
+ return self.video.label
+ else:
+ return u"Video %s" % self.caption
+ return ''
+
+class VideoVersion(models.Model):
+ source = FilerVideoField()
+ status = models.CharField(max_length=10, blank=True, null=True,)
View
0  cmsplugin_filer_video/settings.py → video/settings.py
File renamed without changes
View
BIN  video/templates/.DS_Store
Binary file not shown
View
61 video/templates/video/video.html
@@ -1,21 +1,40 @@
-<!-- first try HTML5 playback: if serving as XML, expand `controls` to `controls="controls"` and autoplay likewise -->
-<!-- warning: playback does not work on iPad/iPhone if you include the poster attribute! fixed in iOS4.0 -->
-<video width="640" height="360" controls>
- <!-- MP4 must be first for iPad! -->
- <source src="__VIDEO__.MP4" type="video/mp4" /><!-- WebKit video -->
- <source src="__VIDEO__.OGV" type="video/ogg" /><!-- Firefox / Opera -->
- <!-- fallback to Flash: -->
- <object width="640" height="360" type="application/x-shockwave-flash" data="__FLASH__.SWF">
- <!-- Firefox uses the `data` attribute above, IE/Safari uses the param below -->
- <param name="movie" value="__FLASH__.SWF" />
- <param name="flashvars" value="controlbar=over&amp;image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
- <!-- fallback image. note the title field below, put the title of the video there -->
- <img src="__VIDEO__.JPG" width="640" height="360" alt="__TITLE__"
- title="No video playback capabilities, please download the video below" />
- </object>
-</video>
-<!-- you *must* offer a download link as they may be able to play the file locally. customise this bit all you want -->
-<p> <strong>Download Video:</strong>
- Closed Format: <a href="__VIDEO__.MP4">"MP4"</a>
- Open Format: <a href="__VIDEO__.OGV">"Ogg"</a>
-</p>
+{% load i18n filermedia %}
+{% if object.formats.HTML5 %}<video width="{{ object.width }}" controls>
+ {% for codec in object.formats.HTML5 %}
+ {% autoescape off %}<source src="{{codec.url}}" />{% endautoescape %}
+ {% endfor %}
+ {% if object.formats.FLASH %}<object width="{{object.width}}" height="{{object.height}}" type="application/x-shockwave-flash" data="{% filer_staticmedia_prefix %}flash/player.swf">
+ <param name="movie" value="{% filer_staticmedia_prefix %}flash/player.swf" />
+ {% for codec in object.formats.FLASH %}
+ <param name="flashvars" value="controlbar=over&amp;file={{codec.url}}" />
+ {% endfor %}{% endif %}
+ </object>{% endif %}
+
+{% if object.formats.HTML5 %}</video>{% endif %}
+{% if object.missing_versions %}
+ {% if not object.available_versions %}
+ <div style="border: 1px solid black; width: {{object.width}}px; height:{{object.height}}px;">
+ <div style="text-align: center; padding: 15%">
+ <p>The files for this video are being encoded and are not yet ready.</p>
+ <p><strong>Please wait a few moments, then reload this page.</strong></p>
+ </div>
+ </div>
+ {% else %}
+ <p><strong>Having problems playing this video?</strong></p>
+ <p>Some of the files are still being encoded.</p>
+ <p>Please <strong>wait a few moments and reload this page</strong>
+ {% if object.all_formats %}
+ , or try one of the following files:
+ {% else%}
+ .</p>
+ {% endif %}
+ {% endif %}
+{% endif %}
+ <p>Video available as:</p>
+{% if object.all_formats %}
+ <ul>
+ {% for codec in object.all_formats %}
+ <li><a href="{{codec.url}}">{{ codec.description }}</a></li>
+ {% endfor %}
+ </ul>
+{% endif %}
Please sign in to comment.
Something went wrong with that request. Please try again.