cleanup imports and syntax warnings

This commit is contained in:
j 2011-01-01 17:14:42 +05:30
commit 2d5f924891
46 changed files with 452 additions and 517 deletions

View file

@ -6,6 +6,7 @@ from django.contrib import admin
from forms import FileAdminForm, InstanceAdminForm
import models
class FileAdmin(admin.ModelAdmin):
search_fields = ['name', 'video_codec']
list_display = ['available', 'is_main', '__unicode__', 'itemId']
@ -18,9 +19,9 @@ class FileAdmin(admin.ModelAdmin):
admin.site.register(models.File, FileAdmin)
class InstanceAdmin(admin.ModelAdmin):
search_fields = ['name', 'folder', 'volume__name']
form = InstanceAdminForm
admin.site.register(models.Instance, InstanceAdmin)

View file

@ -3,33 +3,31 @@
from __future__ import division, with_statement
import os
from os.path import abspath, join, dirname, exists
from os.path import exists
import fractions
import subprocess
import sys
import shutil
import tempfile
import time
import re
import math
from glob import glob
import numpy as np
import Image
import ox
from ox.utils import json
img_extension='jpg'
FFMPEG2THEORA = 'ffmpeg2theora'
class AspectRatio(fractions.Fraction):
def __new__(cls, numerator, denominator=None):
if not denominator:
ratio = map(int, numerator.split(':'))
if len(ratio) == 1: ratio.append(1)
if len(ratio) == 1:
ratio.append(1)
numerator = ratio[0]
denominator = ratio[1]
#if its close enough to the common aspect ratios rather use that
@ -45,6 +43,7 @@ class AspectRatio(fractions.Fraction):
def ratio(self):
return "%d:%d" % (self.numerator, self.denominator)
def stream(video, target, profile, info):
if not os.path.exists(target):
fdir = os.path.dirname(target)
@ -118,8 +117,8 @@ def stream(video, target, profile, info):
bpp = 0.17
fps = AspectRatio(info['video'][0]['framerate'])
width = int(dar * height)
width += width % 2
width = int(dar * height)
width += width % 2
bitrate = height*width*fps*bpp/1000
aspect = dar.ratio
@ -184,7 +183,7 @@ def stream(video, target, profile, info):
'-me_range', '16',
'-g', '250', #FIXME: should this be related to fps?
'-keyint_min', '25', #FIXME: should this be related to fps?
'-sc_threshold','40',
'-sc_threshold', '40',
'-i_qfactor', '0.71',
'-qmin', '10', '-qmax', '51',
'-qdiff', '4'
@ -200,19 +199,20 @@ def stream(video, target, profile, info):
if format == 'mp4':
cmd += ["%s.mp4"%target]
else:
cmd += ['-f','webm', target]
cmd += ['-f', 'webm', target]
print cmd
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT)
p.communicate()
if format == 'mp4':
cmd = ['qt-faststart', "%s.mp4"%target, target]
cmd = ['qt-faststart', "%s.mp4"%target, target]
print cmd
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT)
p.communicate()
os.unlink("%s.mp4"%target)
return True
def run_command(cmd, timeout=10):
#print cmd
p = subprocess.Popen(cmd, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT)
@ -226,6 +226,7 @@ def run_command(cmd, timeout=10):
killedpid, stat = os.waitpid(p.pid, os.WNOHANG)
return p.returncode
def frame(videoFile, frame, position, width=128, redo=False):
'''
params:
@ -243,6 +244,7 @@ def frame(videoFile, frame, position, width=128, redo=False):
cmd = ['oxframe', '-i', videoFile, '-o', frame, '-p', str(position), '-x', str(width)]
run_command(cmd)
def resize_image(image_source, image_output, width=None, size=None):
if exists(image_source):
source = Image.open(image_source).convert('RGB')
@ -257,7 +259,7 @@ def resize_image(image_source, image_output, width=None, size=None):
height = size
width = int(height * (float(source_width) / source_height))
width = width - width % 2
else:
height = int(width / (float(source_width) / source_height))
height = height - height % 2
@ -269,12 +271,13 @@ def resize_image(image_source, image_output, width=None, size=None):
output = source.resize((width, height), resize_method)
output.save(image_output)
def timeline(video, prefix):
cmd = ['oxtimeline', '-i', video, '-o', prefix]
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()
#stats based on timeline images
def average_color(prefix):
height = 64
width = 1500
@ -294,10 +297,12 @@ def average_color(prefix):
color += p
return list(map(float, color))
def get_distance(rgb0, rgb1):
dst = math.sqrt(pow(rgb0[0] - rgb1[0], 2) + pow(rgb0[0] - rgb1[0], 2) + pow(rgb0[0] - rgb1[0], 2))
return dst / math.sqrt(3 * pow(255, 2))
def cuts(prefix):
cuts = []
fps = 25
@ -324,6 +329,7 @@ def cuts(prefix):
cuts.append(frame / fps)
return cuts
def divide(num, by):
# >>> divide(100, 3)
# [33, 33, 34]
@ -334,9 +340,10 @@ def divide(num, by):
arr.append(div + (i > by - 1 - mod))
return arr
def timeline_strip(item, cuts, info, prefix):
_debug = False
duration = info['duration']
duration = info['duration']
video_height = info['video'][0]['height']
video_width = info['video'][0]['width']
video_ratio = video_width / video_height
@ -392,6 +399,7 @@ def timeline_strip(item, cuts, info, prefix):
print 'writing', timeline_file
timeline_image.save(timeline_file)
def chop(video, start, end):
t = end - start
tmp = tempfile.mkdtemp()
@ -401,7 +409,7 @@ def chop(video, start, end):
'-y',
'-i', video,
'-ss', '%.3f'%start,
'-t','%.3f'%t,
'-t', '%.3f'%t,
'-vcodec', 'copy',
'-acodec', 'copy',
'-f', 'webm',

View file

@ -1,4 +1,4 @@
from ajax_filtered_fields.forms import AjaxManyToManyField, ForeignKeyByLetter
from ajax_filtered_fields.forms import ForeignKeyByLetter
from django.conf import settings
from django import forms
@ -10,6 +10,8 @@ ajax_filtered_js = (
settings.STATIC_URL + 'js/jquery/jquery.js',
settings.STATIC_URL + 'js/ajax_filtered_fields.js',
)
class FileAdminForm(forms.ModelForm):
item = ForeignKeyByLetter(models.Item, field_name='itemId')
@ -28,4 +30,3 @@ class InstanceAdminForm(forms.ModelForm):
class Media:
js = ajax_filtered_js

View file

@ -1,31 +1,23 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division
from datetime import datetime
import os.path
import random
import re
import time
from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User
from django.core.files.base import ContentFile
from django.utils import simplejson as json
from django.conf import settings
from ox.django import fields
import ox
from ox import stripTags
from ox.normalize import canonicalTitle, canonicalName
from firefogg import Firefogg
from ox.normalize import canonicalTitle
import chardet
from item import utils
from item.models import Item
import extract
class File(models.Model):
created = models.DateTimeField(auto_now_add=True)
@ -37,7 +29,7 @@ class File(models.Model):
item = models.ForeignKey(Item, related_name='files')
name = models.CharField(max_length=2048, default="") # canoncial path/file
sort_name = models.CharField(max_length=2048, default="") # sort path/file name
sort_name = models.CharField(max_length=2048, default="") # sort name
part = models.CharField(default="", max_length=255)
version = models.CharField(default="", max_length=255) # sort path/file name
@ -146,13 +138,14 @@ class File(models.Model):
return None
def srt(self):
def _detectEncoding(fp):
bomDict={ # bytepattern : name
(0x00, 0x00, 0xFE, 0xFF) : "utf_32_be",
(0xFF, 0xFE, 0x00, 0x00) : "utf_32_le",
(0xFE, 0xFF, None, None) : "utf_16_be",
(0xFF, 0xFE, None, None) : "utf_16_le",
(0xEF, 0xBB, 0xBF, None) : "utf_8",
bomDict={ # bytepattern : name
(0x00, 0x00, 0xFE, 0xFF): "utf_32_be",
(0xFF, 0xFE, 0x00, 0x00): "utf_32_le",
(0xFE, 0xFF, None, None): "utf_16_be",
(0xFF, 0xFE, None, None): "utf_16_le",
(0xEF, 0xBB, 0xBF, None): "utf_8",
}
# go to beginning of file and get the first 4 bytes
@ -162,15 +155,15 @@ class File(models.Model):
# try bom detection using 4 bytes, 3 bytes, or 2 bytes
bomDetection = bomDict.get((byte1, byte2, byte3, byte4))
if not bomDetection :
if not bomDetection:
bomDetection = bomDict.get((byte1, byte2, byte3, None))
if not bomDetection :
if not bomDetection:
bomDetection = bomDict.get((byte1, byte2, None, None))
## if BOM detected, we're done :-)
fp.seek(oldFP)
if bomDetection :
return bomDetection
if bomDetection:
return bomDetection
encoding = 'latin-1'
#more character detecting magick using http://chardet.feedparser.org/
@ -221,7 +214,9 @@ class File(models.Model):
return True
return False
class Volume(models.Model):
class Meta:
unique_together = ("user", "name")
@ -234,7 +229,9 @@ class Volume(models.Model):
def __unicode__(self):
return u"%s's %s"% (self.user, self.name)
class Instance(models.Model):
class Meta:
unique_together = ("name", "folder", "volume")
@ -258,12 +255,15 @@ class Instance(models.Model):
def itemId(self):
return File.objects.get(oshash=self.oshash).itemId
def frame_path(frame, name):
ext = os.path.splitext(name)[-1]
name = "%s%s" % (frame.position, ext)
return frame.file.path(name)
class Frame(models.Model):
class Meta:
unique_together = ("file", "position")
created = models.DateTimeField(auto_now_add=True)
@ -282,5 +282,3 @@ class Frame(models.Model):
def __unicode__(self):
return u'%s at %s' % (self.file, self.position)

View file

@ -1,17 +1,15 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from datetime import timedelta
import os
import re
from celery.decorators import task, periodic_task
from celery.decorators import task
from item.utils import oxid, parse_path
from item.utils import parse_path
from item.models import get_item
import item.tasks
import models
@task(ignore_resulsts=True, queue='default')
def update_files(user, volume, files):
user = models.User.objects.get(username=user)
@ -33,9 +31,9 @@ def update_files(user, volume, files):
same_folder = models.Instance.objects.filter(folder=folder, volume=volume)
if same_folder.count() > 0:
item = same_folder[0].file.item
i = same_folder[0].file.item
else:
item = None
i = None
path = os.path.join(folder, name)
@ -48,7 +46,7 @@ def update_files(user, volume, files):
setattr(instance, key, f[key])
updated=True
if updated:
instance.save()
instance.save()
else:
#look if oshash is known
file_objects = models.File.objects.filter(oshash=oshash)
@ -56,13 +54,13 @@ def update_files(user, volume, files):
file_object = file_objects[0]
#new oshash, add to database
else:
if not item:
if not i:
item_info = parse_path(folder)
item = get_item(item_info)
i = get_item(item_info)
file_object = models.File()
file_object.oshash = oshash
file_object.name = name
file_object.item = item
file_object.item = i
file_object.save()
instance = models.Instance()
instance.volume = volume
@ -74,4 +72,3 @@ def update_files(user, volume, files):
#remove deleted files
#FIXME: can this have any bad consequences? i.e. on the selction of used item files.
models.Instance.objects.filter(volume=volume).exclude(file__oshash__in=all_files).delete()

View file

@ -7,7 +7,9 @@ Replace these with more appropriate tests for your application.
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
@ -20,4 +22,3 @@ Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

View file

@ -2,29 +2,18 @@
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division
import os.path
import re
from datetime import datetime
from urllib2 import unquote
import mimetypes
from django import forms
from django.core.paginator import Paginator
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.db.models import Q, Avg, Count, Sum
from django.http import HttpResponse, Http404
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect
from django.template import RequestContext
from django.shortcuts import get_object_or_404, redirect
from django.conf import settings
from ox.utils import json
from ox.django.decorators import login_required_json
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from ox.django.http import HttpFileResponse
from ox.django.views import task_status
import ox
from item.utils import oxid, parse_path
from item.utils import parse_path
from item.models import get_item
import item.tasks
from api.actions import actions
@ -47,6 +36,7 @@ def removeVolume(request):
return render_to_json_response(response)
actions.register(removeVolume)
@login_required_json
def update(request):
'''
@ -111,12 +101,14 @@ def update(request):
return render_to_json_response(response)
actions.register(update)
@login_required_json
def encodingProfile(request):
response = json_response({'profile': settings.VIDEO_PROFILE})
return render_to_json_response(response)
actions.register(encodingProfile)
@login_required_json
def upload(request):
'''
@ -157,11 +149,13 @@ def upload(request):
return render_to_json_response(response)
actions.register(upload)
class VideoChunkForm(forms.Form):
chunk = forms.FileField()
chunkId = forms.IntegerField(required=False)
done = forms.IntegerField(required=False)
@login_required_json
def firefogg_upload(request):
profile = request.GET['profile']
@ -189,7 +183,7 @@ def firefogg_upload(request):
#FIXME: this fails badly if rabbitmq goes down
try:
t = item.tasks.update_streams.delay((f.item.itemId))
data['resultUrl'] = t.task_id
response['resultUrl'] = t.task_id
except:
pass
response['result'] = 1
@ -213,6 +207,7 @@ def firefogg_upload(request):
response = json_response(status=400, text='this request requires POST')
return render_to_json_response(response)
@login_required_json
def taskStatus(request):
#FIXME: should check if user has permissions to get status
@ -223,6 +218,7 @@ def taskStatus(request):
return render_to_json_response(response)
actions.register(taskStatus)
@login_required_json
def editFile(request):
'''
@ -257,6 +253,7 @@ def editFile(request):
return render_to_json_response(response)
actions.register(editFile)
def lookup_file(request, oshash):
f = get_object_or_404(models.File, oshash=oshash)
return redirect(f.item.get_absolute_url())
@ -270,34 +267,34 @@ def fileInfo(request):
'data': {imdbId:string }}
'''
if 'data' in request.POST:
oshash = json.loads(request.POST['data'])
elif 'oshash' in request.GET:
oshash = request.GET['oshash']
oshash = json.loads(request.POST['data'])
elif 'oshash' in request.GET:
oshash = request.GET['oshash']
f = models.ItemFile.objects.get(oshash=oshash)
response = {'data': f.json()}
return render_to_json_response(response)
actions.register(fileInfo)
def subtitles(request):
'''
param data
oshash string
language string
subtitle string
return
if no language is provided:
{data: {languages: array}}
if language is set:
{data: {subtitle: string}}
if subtitle is set:
saves subtitle for given language
'''
'''
param data
oshash string
language string
subtitle string
return
if no language is provided:
{data: {languages: array}}
if language is set:
{data: {subtitle: string}}
if subtitle is set:
saves subtitle for given language
'''
if 'data' in request.POST:
data = json.loads(request.POST['data'])
oshash = data['oshash']
language = data.get('language', None)
srt = data.get('subtitle', None)
if srt:
data = json.loads(request.POST['data'])
oshash = data['oshash']
language = data.get('language', None)
srt = data.get('subtitle', None)
if srt:
user = request.user
sub = models.Subtitles.objects.get_or_create(user, oshash, language)
sub.srt = srt
@ -307,8 +304,8 @@ def subtitles(request):
if language:
q = models.Subtitles.objects.filter(item_file__oshash=oshash, language=language)
if q.count() > 0:
response['data']['subtitle'] = q[0].srt
return render_to_json_response(response)
response['data']['subtitle'] = q[0].srt
return render_to_json_response(response)
l = models.Subtitles.objects.filter(item_file__oshash=oshash).values('language')
response['data']['languages'] = [f['language'] for f in l]
return render_to_json_response(response)