forked from 0x2620/pandora
cleanup imports and syntax warnings
This commit is contained in:
parent
7fdae917cf
commit
2d5f924891
46 changed files with 452 additions and 517 deletions
|
@ -2,31 +2,14 @@
|
|||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from __future__ import division, with_statement
|
||||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
import math
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
import unicodedata
|
||||
from glob import glob
|
||||
|
||||
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.conf import settings
|
||||
|
||||
from ox.django import fields
|
||||
import ox
|
||||
from ox.utils import json
|
||||
from ox import stripTags
|
||||
from ox.normalize import canonicalTitle, canonicalName
|
||||
|
||||
import utils
|
||||
|
||||
|
||||
class Layer(models.Model):
|
||||
|
||||
class Meta:
|
||||
ordering = ('position', )
|
||||
|
||||
|
@ -61,7 +44,9 @@ class Layer(models.Model):
|
|||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class Annotation(models.Model):
|
||||
|
||||
#FIXME: here having a item,start index would be good
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
@ -77,9 +62,9 @@ class Annotation(models.Model):
|
|||
|
||||
def editable(self, user):
|
||||
if user.is_authenticated():
|
||||
if obj.user == user.id or user.has_perm('0x.admin'):
|
||||
if self.user == user or user.has_perm('0x.admin'):
|
||||
return True
|
||||
if user.groups.filter(id__in=obj.groups.all()).count() > 0:
|
||||
if user.groups.filter(id__in=self.groups.all()).count() > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -102,4 +87,3 @@ class Annotation(models.Model):
|
|||
|
||||
def __unicode__(self):
|
||||
return "%s/%s-%s" %(self.item, self.start, self.stop)
|
||||
|
||||
|
|
|
@ -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
|
||||
"""}
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# ci:si:et:sw=4:sts=4:ts=4
|
||||
import re
|
||||
import ox
|
||||
|
||||
|
||||
def html_parser(text, nofollow=True):
|
||||
text = text.replace('<i>', '__i__').replace('</i>', '__/i__')
|
||||
text = text.replace('<b>', '__b__').replace('</b>', '__/b__')
|
||||
#truns links into wiki links, make sure to only take http links
|
||||
text = re.sub('<a .*?href="(http.*?)".*?>(.*?)</a>', '[\\1 \\2]', text)
|
||||
text = escape(text)
|
||||
text = ox.escape(text)
|
||||
text = text.replace('__i__', '<i>').replace('__/i__', '</i>')
|
||||
text = text.replace('__b__', '<b>').replace('__/b__', '</b>')
|
||||
if nofollow:
|
||||
|
@ -25,7 +28,7 @@ def html_parser(text, nofollow=True):
|
|||
ll = '<a href="%s"%s>%s</a>' % (link, nofollow_rel, link)
|
||||
text = text.replace(t, ll)
|
||||
|
||||
text = urlize(text, nofollow=nofollow)
|
||||
text = ox.urlize(text, nofollow=nofollow)
|
||||
|
||||
#inpage links
|
||||
text = re.sub('\[(/.+?) (.+?)\]', '<a href="\\1">\\2</a>', text)
|
||||
|
@ -33,4 +36,3 @@ def html_parser(text, nofollow=True):
|
|||
text = text.replace('__LINK__', 'http').replace('__DOT__', '.')
|
||||
text = text.replace("\n", '<br />')
|
||||
return text
|
||||
|
||||
|
|
|
@ -1,27 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# 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.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
|
||||
import ox
|
||||
|
||||
import models
|
||||
from api.actions import actions
|
||||
|
@ -48,6 +31,7 @@ def findAnnotation(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(findAnnotation)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def addAnnotation(request):
|
||||
'''
|
||||
|
@ -67,7 +51,8 @@ def addAnnotation(request):
|
|||
data = json.loads(request.POST['data'])
|
||||
for key in ('item', 'layer', 'start', 'end', 'value'):
|
||||
if key not in data:
|
||||
return render_to_json_response(json_response(status=400, text='invalid data'))
|
||||
return render_to_json_response(json_response(status=400,
|
||||
text='invalid data'))
|
||||
|
||||
item = get_object_or_404_json(models.Item, itemId=data['item'])
|
||||
layer = get_object_or_404_json(models.Layer, layerId=data['layer'])
|
||||
|
@ -77,8 +62,7 @@ def addAnnotation(request):
|
|||
layer=layer,
|
||||
user=request.user,
|
||||
start=float(data['start']), end=float(data['end']),
|
||||
value=data['value']
|
||||
)
|
||||
value=data['value'])
|
||||
annotation.save()
|
||||
response = json_response()
|
||||
response['data']['annotation'] = annotation.json()
|
||||
|
@ -88,6 +72,7 @@ def addAnnotation(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(addAnnotation)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def removeAnnotation(request):
|
||||
'''
|
||||
|
@ -103,6 +88,7 @@ def removeAnnotation(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(removeAnnotation)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def editAnnotation(request):
|
||||
'''
|
||||
|
@ -129,4 +115,3 @@ def editAnnotation(request):
|
|||
response = json_response(status=501, text='not implemented')
|
||||
return render_to_json_response(response)
|
||||
actions.register(editAnnotation)
|
||||
|
||||
|
|
|
@ -46,8 +46,11 @@ def trim(docstring):
|
|||
# Return a single string:
|
||||
return '\n'.join(trimmed)
|
||||
|
||||
|
||||
class ApiActions(dict):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
def api(request):
|
||||
'''
|
||||
returns list of all known api action
|
||||
|
@ -56,7 +59,8 @@ class ApiActions(dict):
|
|||
'''
|
||||
actions = self.keys()
|
||||
actions.sort()
|
||||
return render_to_json_response(json_response({'actions': actions}))
|
||||
response = json_response({'actions': actions})
|
||||
return render_to_json_response(response)
|
||||
self['api'] = api
|
||||
|
||||
def apidoc(request):
|
||||
|
|
|
@ -1,54 +1,32 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# 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.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
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
|
||||
import ox
|
||||
|
||||
import models
|
||||
from ox.django.shortcuts import render_to_json_response, json_response
|
||||
|
||||
from pandora.user.models import get_user_json
|
||||
|
||||
from pandora.archive.models import File
|
||||
from pandora.archive import extract
|
||||
|
||||
|
||||
from actions import actions
|
||||
|
||||
|
||||
def api(request):
|
||||
if request.META['REQUEST_METHOD'] == "OPTIONS":
|
||||
response = HttpResponse('')
|
||||
response = render_to_json_response({'status': {'code': 200, 'text': 'use POST'}})
|
||||
response = render_to_json_response({'status': {'code': 200,
|
||||
'text': 'use POST'}})
|
||||
response['Access-Control-Allow-Origin'] = '*'
|
||||
return response
|
||||
if not 'action' in request.POST:
|
||||
methods = actions.keys()
|
||||
api = []
|
||||
for f in sorted(methods):
|
||||
api.append({
|
||||
'name': f,
|
||||
'doc': actions.doc(f).replace('\n', '<br>\n')
|
||||
})
|
||||
api.append({'name': f,
|
||||
'doc': actions.doc(f).replace('\n', '<br>\n')})
|
||||
context = RequestContext(request, {'api': api,
|
||||
'sitename': settings.SITENAME,})
|
||||
'sitename': settings.SITENAME})
|
||||
return render_to_response('api.html', context)
|
||||
function = request.POST['action']
|
||||
#FIXME: possible to do this in f
|
||||
|
@ -63,6 +41,7 @@ def api(request):
|
|||
response['Access-Control-Allow-Origin'] = '*'
|
||||
return response
|
||||
|
||||
|
||||
def hello(request):
|
||||
'''
|
||||
return {'status': {'code': int, 'text': string},
|
||||
|
@ -73,10 +52,13 @@ def hello(request):
|
|||
if request.user.is_authenticated():
|
||||
response['data']['user'] = get_user_json(request.user)
|
||||
else:
|
||||
response['data']['user'] = {'name': 'Guest', 'group': 'guest', 'preferences': {}}
|
||||
response['data']['user'] = {'name': 'Guest',
|
||||
'group': 'guest',
|
||||
'preferences': {}}
|
||||
return render_to_json_response(response)
|
||||
actions.register(hello)
|
||||
|
||||
|
||||
def error(request):
|
||||
'''
|
||||
this action is used to test api error codes, it should return a 503 error
|
||||
|
@ -84,4 +66,3 @@ def error(request):
|
|||
success = error_is_success
|
||||
return render_to_json_response({})
|
||||
actions.register(error)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.contrib import admin
|
|||
|
||||
import models
|
||||
|
||||
|
||||
class PageAdmin(admin.ModelAdmin):
|
||||
search_fields = ['name', 'body']
|
||||
|
||||
|
@ -15,4 +16,3 @@ class SiteSettingsAdmin(admin.ModelAdmin):
|
|||
search_fields = ['key', 'value']
|
||||
|
||||
admin.site.register(models.SiteSettings, SiteSettingsAdmin)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Page(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
@ -11,10 +12,10 @@ class Page(models.Model):
|
|||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class SiteSettings(models.Model):
|
||||
key = models.CharField(max_length=1024, unique=True)
|
||||
value = models.TextField(blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.key
|
||||
|
||||
|
|
|
@ -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
|
||||
"""}
|
||||
|
||||
|
|
|
@ -1,31 +1,32 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.conf import settings
|
||||
|
||||
from ox.django.shortcuts import json_response, render_to_json_response, get_object_or_404_json
|
||||
from ox.utils import json
|
||||
|
||||
import models
|
||||
|
||||
from item.models import siteJson
|
||||
|
||||
from api.actions import actions
|
||||
|
||||
|
||||
def intro(request):
|
||||
context = RequestContext(request, {'settings':settings})
|
||||
context = RequestContext(request, {'settings': settings})
|
||||
return render_to_response('intro.html', context)
|
||||
|
||||
|
||||
def index(request):
|
||||
context = RequestContext(request, {'settings':settings})
|
||||
if request.GET.get('_escaped_fragment_', None):
|
||||
return html_snapshot(request)
|
||||
context = RequestContext(request, {'settings': settings})
|
||||
return render_to_response('index.html', context)
|
||||
|
||||
|
||||
def timeline(request):
|
||||
context = RequestContext(request, {'settings':settings})
|
||||
context = RequestContext(request, {'settings': settings})
|
||||
return render_to_response('timeline.html', context)
|
||||
|
||||
|
||||
def getPage(request):
|
||||
data = json.loads(request.POST['data'])
|
||||
name = data['page']
|
||||
|
@ -34,6 +35,7 @@ def getPage(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(getPage)
|
||||
|
||||
|
||||
def site_json(request):
|
||||
'''
|
||||
return render_to_json_response(siteJson())
|
||||
|
@ -41,6 +43,7 @@ def site_json(request):
|
|||
siteSettings = {}
|
||||
for s in models.SiteSettings.objects.all():
|
||||
siteSettings[s.key] = s.value
|
||||
context = RequestContext(request, {'settings':settings, 'siteSettings': siteSettings})
|
||||
return render_to_response('site.json', context, mimetype="application/javascript")
|
||||
|
||||
context = RequestContext(request, {'settings': settings,
|
||||
'siteSettings': siteSettings})
|
||||
return render_to_response('site.json', context,
|
||||
mimetype="application/javascript")
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -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,7 +199,7 @@ 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)
|
||||
|
@ -213,6 +212,7 @@ def stream(video, target, profile, info):
|
|||
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')
|
||||
|
@ -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,6 +340,7 @@ 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']
|
||||
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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",
|
||||
(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,14 +155,14 @@ 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 :
|
||||
if bomDetection:
|
||||
return bomDetection
|
||||
|
||||
encoding = 'latin-1'
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
"""}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -9,4 +9,3 @@ import models
|
|||
class DateAdmin(admin.ModelAdmin):
|
||||
search_fields = ['name']
|
||||
admin.site.register(models.Date, DateAdmin)
|
||||
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
import re
|
||||
|
||||
from ox.utils import json
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Q, Manager
|
||||
|
||||
import models
|
||||
|
||||
class DateManager(Manager):
|
||||
|
||||
def get_query_set(self):
|
||||
return super(DateManager, self).get_query_set()
|
||||
|
||||
|
|
|
@ -3,13 +3,12 @@
|
|||
from __future__ import division, with_statement
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.conf import settings
|
||||
|
||||
from ox.django import fields
|
||||
|
||||
import managers
|
||||
|
||||
|
||||
class Date(models.Model):
|
||||
'''
|
||||
Dates are dates in time that can be once or recurring,
|
||||
|
@ -41,4 +40,3 @@ class Date(models.Model):
|
|||
self.name_sort = self.name
|
||||
self.name_find = self.name + '||'.join(self.aliases)
|
||||
super(Date, self).save(*args, **kwargs)
|
||||
|
||||
|
|
|
@ -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
|
||||
"""}
|
||||
|
||||
|
|
|
@ -1,32 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# 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.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
|
||||
import ox
|
||||
|
||||
import models
|
||||
from api.actions import actions
|
||||
|
||||
|
||||
@login_required_json
|
||||
def addDate(request):
|
||||
data = json.loads(request.POST['data'])
|
||||
|
@ -39,6 +22,7 @@ def addDate(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(addDate)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def editDate(request):
|
||||
'''
|
||||
|
@ -69,12 +53,14 @@ def editDate(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(editDate)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def removeDate(request):
|
||||
response = json_response(status=501, text='not implemented')
|
||||
return render_to_json_response(response)
|
||||
actions.register(removeDate)
|
||||
|
||||
|
||||
def findDate(request):
|
||||
'''
|
||||
param data
|
||||
|
@ -111,8 +97,7 @@ Positions
|
|||
response = json_response(status=200, text='ok')
|
||||
response['data']['places'] = []
|
||||
#FIXME: add coordinates to limit search
|
||||
for p in Dates.objects.find(data['query']):
|
||||
for p in models.Date.objects.find(data['query']):
|
||||
response['data']['dates'].append(p.json())
|
||||
return render_to_json_response(response)
|
||||
actions.register(findDate)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.contrib import admin
|
|||
|
||||
import models
|
||||
|
||||
|
||||
class ItemAdmin(admin.ModelAdmin):
|
||||
search_fields = ['itemId', 'data', 'external_data']
|
||||
list_display = ['available', 'itemId', '__unicode__']
|
||||
|
@ -12,8 +13,7 @@ class ItemAdmin(admin.ModelAdmin):
|
|||
|
||||
admin.site.register(models.Item, ItemAdmin)
|
||||
|
||||
|
||||
class PropertyAdmin(admin.ModelAdmin):
|
||||
search_fields = ['name', 'title']
|
||||
admin.site.register(models.Property, PropertyAdmin)
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
from ajax_filtered_fields.forms import AjaxManyToManyField, ForeignKeyByLetter
|
||||
from django.conf import settings
|
||||
from django import forms
|
||||
|
||||
import models
|
||||
|
||||
ajax_filtered_js = (
|
||||
settings.ADMIN_MEDIA_PREFIX + "js/SelectBox.js",
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
import re
|
||||
from datetime import datetime
|
||||
from urllib2 import unquote
|
||||
from ox.utils import json
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Q, Manager
|
||||
|
||||
import models
|
||||
|
@ -21,6 +16,7 @@ def keyType(key):
|
|||
return "float"
|
||||
return "string"
|
||||
|
||||
|
||||
def parseCondition(condition):
|
||||
'''
|
||||
condition: {
|
||||
|
@ -36,10 +32,12 @@ def parseCondition(condition):
|
|||
'''
|
||||
k = condition.get('key', 'all')
|
||||
k = {'id': 'itemId'}.get(k, k)
|
||||
if not k: k = 'all'
|
||||
if not k:
|
||||
k = 'all'
|
||||
v = condition['value']
|
||||
op = condition.get('operator', None)
|
||||
if not op: op = '~'
|
||||
if not op:
|
||||
op = '~'
|
||||
if op.startswith('!'):
|
||||
op = op[1:]
|
||||
exclude = True
|
||||
|
@ -66,16 +64,17 @@ def parseCondition(condition):
|
|||
k = str(k)
|
||||
if exclude:
|
||||
if in_find and not k.startswith('itemId'):
|
||||
q = ~Q(**{'find__key':k, value_key:v})
|
||||
q = ~Q(**{'find__key': k, value_key: v})
|
||||
else:
|
||||
q = ~Q(**{k:v})
|
||||
q = ~Q(**{k: v})
|
||||
else:
|
||||
if in_find and not k.startswith('itemId'):
|
||||
q = Q(**{'find__key':k, value_key:v})
|
||||
q = Q(**{'find__key': k, value_key: v})
|
||||
else:
|
||||
q = Q(**{k:v})
|
||||
q = Q(**{k: v})
|
||||
return q
|
||||
else: #number or date
|
||||
|
||||
def parseDate(d):
|
||||
while len(d) < 3:
|
||||
d.append(1)
|
||||
|
@ -90,11 +89,11 @@ def parseCondition(condition):
|
|||
if exclude: #!1960-1970
|
||||
k1 = 'value__lt'
|
||||
k2 = 'value__gte'
|
||||
return Q(**{'find__key': k, k1:v1})|Q(**{'find__key': k, k2:v2})
|
||||
return Q(**{'find__key': k, k1: v1})|Q(**{'find__key': k, k2: v2})
|
||||
else: #1960-1970
|
||||
k1 = 'value__gte'
|
||||
k2 = 'value__lt'
|
||||
return Q(**{'find__key': k, k1:v1})&Q(**{'find__key': k, k2:v2})
|
||||
return Q(**{'find__key': k, k1: v1})&Q(**{'find__key': k, k2: v2})
|
||||
else:
|
||||
if keyType(k) == "date":
|
||||
v = parseDate(v.split('.'))
|
||||
|
@ -113,9 +112,10 @@ def parseCondition(condition):
|
|||
vk = str(vk)
|
||||
|
||||
if exclude: #!1960
|
||||
return ~Q(**{'find__key': k, vk:v})
|
||||
return ~Q(**{'find__key': k, vk: v})
|
||||
else: #1960
|
||||
return Q(**{'find__key': k, vk:v})
|
||||
return Q(**{'find__key': k, vk: v})
|
||||
|
||||
|
||||
def parseConditions(conditions, operator):
|
||||
'''
|
||||
|
@ -141,10 +141,12 @@ def parseConditions(conditions, operator):
|
|||
if 'conditions' in condition:
|
||||
q = parseConditions(condition['conditions'],
|
||||
condition.get('operator', '&'))
|
||||
if q: conn.append(q)
|
||||
if q:
|
||||
conn.append(q)
|
||||
pass
|
||||
else:
|
||||
if condition.get('value', '') != '' or condition.get('operator', '') == '=':
|
||||
if condition.get('value', '') != '' or \
|
||||
condition.get('operator', '') == '=':
|
||||
conn.append(parseCondition(condition))
|
||||
if conn:
|
||||
q = conn[0]
|
||||
|
@ -156,7 +158,9 @@ def parseConditions(conditions, operator):
|
|||
return q
|
||||
return None
|
||||
|
||||
|
||||
class ItemManager(Manager):
|
||||
|
||||
def get_query_set(self):
|
||||
return super(ItemManager, self).get_query_set()
|
||||
|
||||
|
@ -165,13 +169,14 @@ class ItemManager(Manager):
|
|||
l = l.split(":")
|
||||
only_public = True
|
||||
if not user.is_anonymous():
|
||||
if len(l) == 1: l = [request.user.username] + l
|
||||
if request.user.username == l[0]:
|
||||
if len(l) == 1:
|
||||
l = [user.username] + l
|
||||
if user.username == l[0]:
|
||||
only_public = False
|
||||
if len(l) == 2:
|
||||
lqs = models.List.objects.filter(name=l[1], user__username=l[0])
|
||||
if only_public:
|
||||
lqs = qls.filter(public=True)
|
||||
lqs = lqs.filter(public=True)
|
||||
if lqs.count() == 1:
|
||||
qs = qs.filter(listitem__list__id=lqs[0].id)
|
||||
return qs
|
||||
|
@ -212,4 +217,3 @@ class ItemManager(Manager):
|
|||
l = data.get('list', 'all')
|
||||
qs = self.filter_list(qs, l, user)
|
||||
return qs
|
||||
|
||||
|
|
|
@ -4,26 +4,18 @@ from __future__ import division, with_statement
|
|||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
import math
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
import unicodedata
|
||||
from glob import glob
|
||||
|
||||
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.django import fields
|
||||
from ox.normalize import canonicalTitle
|
||||
import ox.web.imdb
|
||||
from ox.normalize import canonicalTitle, canonicalName
|
||||
from firefogg import Firefogg
|
||||
|
||||
import managers
|
||||
import utils
|
||||
|
@ -31,7 +23,7 @@ import tasks
|
|||
from archive import extract
|
||||
|
||||
from annotaion.models import Annotation, Layer
|
||||
from person.models import get_name_sort, Person
|
||||
from person.models import get_name_sort
|
||||
|
||||
|
||||
def siteJson():
|
||||
|
@ -129,6 +121,7 @@ def siteJson():
|
|||
}
|
||||
return r
|
||||
|
||||
|
||||
def get_item(info):
|
||||
'''
|
||||
info dict with:
|
||||
|
@ -176,7 +169,9 @@ def get_item(info):
|
|||
item.save()
|
||||
return item
|
||||
|
||||
|
||||
class Property(models.Model):
|
||||
|
||||
class Meta:
|
||||
ordering = ('position', )
|
||||
verbose_name_plural = "Properties"
|
||||
|
@ -220,6 +215,7 @@ class Property(models.Model):
|
|||
self.title = self.name.capitalize()
|
||||
super(Property, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class Item(models.Model):
|
||||
person_keys = ('director', 'writer', 'producer', 'editor', 'cinematographer', 'actor', 'character')
|
||||
facet_keys = person_keys + ('country', 'language', 'genre', 'keyword')
|
||||
|
@ -468,7 +464,9 @@ class Item(models.Model):
|
|||
'''
|
||||
Search related functions
|
||||
'''
|
||||
|
||||
def update_find(self):
|
||||
|
||||
def save(key, value):
|
||||
f, created = ItemFind.objects.get_or_create(item=self, key=key)
|
||||
if value not in ('', '||'):
|
||||
|
@ -585,8 +583,8 @@ class Item(models.Model):
|
|||
if not getattr(s, key):
|
||||
setattr(s, key, u'zzzzzzzzzzzzzzzzzzzzzzzzz')
|
||||
if not s.year:
|
||||
s.year_desc = '';
|
||||
s.year = '9999';
|
||||
s.year_desc = ''
|
||||
s.year = '9999'
|
||||
#FIXME: also deal with number based rows like genre, keywords etc
|
||||
s.save()
|
||||
|
||||
|
@ -624,6 +622,7 @@ class Item(models.Model):
|
|||
'''
|
||||
Video related functions
|
||||
'''
|
||||
|
||||
def frame(self, position, width=128):
|
||||
stream = self.streams.filter(profile=settings.VIDEO_PROFILE+'.webm')[0]
|
||||
path = os.path.join(settings.MEDIA_ROOT, self.path(), 'frames', "%d"%width, "%s.jpg"%position)
|
||||
|
@ -693,6 +692,7 @@ class Item(models.Model):
|
|||
'''
|
||||
Poster related functions
|
||||
'''
|
||||
|
||||
def update_poster_urls(self):
|
||||
_current = {}
|
||||
for s in settings.POSTER_SERVICES:
|
||||
|
@ -781,12 +781,14 @@ class Item(models.Model):
|
|||
p.wait()
|
||||
return posters.keys()
|
||||
|
||||
|
||||
class ItemFind(models.Model):
|
||||
"""
|
||||
used to find items,
|
||||
item.update_find populates this table
|
||||
its used in manager.ItemManager
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
unique_together = ("item", "key")
|
||||
|
||||
|
@ -794,8 +796,9 @@ class ItemFind(models.Model):
|
|||
key = models.CharField(max_length=200, db_index=True)
|
||||
value = models.TextField(blank=True)
|
||||
|
||||
#FIXME: make sort based on site.json
|
||||
|
||||
class ItemSort(models.Model):
|
||||
#FIXME: make sort based on site.json
|
||||
"""
|
||||
used to sort items, all sort values are in here
|
||||
"""
|
||||
|
@ -872,6 +875,7 @@ class ItemSort(models.Model):
|
|||
return tuple(fields)
|
||||
fields = classmethod(fields)
|
||||
|
||||
|
||||
class Facet(models.Model):
|
||||
item = models.ForeignKey('Item', related_name='facets')
|
||||
key = models.CharField(max_length=200, db_index=True)
|
||||
|
@ -883,7 +887,9 @@ class Facet(models.Model):
|
|||
self.value_sort = self.value
|
||||
super(Facet, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class Stream(models.Model):
|
||||
|
||||
class Meta:
|
||||
unique_together = ("item", "profile")
|
||||
|
||||
|
@ -945,7 +951,9 @@ class Stream(models.Model):
|
|||
self.info = ox.avinfo(self.video.path)
|
||||
super(Stream, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class PosterUrl(models.Model):
|
||||
|
||||
class Meta:
|
||||
unique_together = ("item", "service", "url")
|
||||
ordering = ('-height', )
|
||||
|
@ -958,4 +966,3 @@ class PosterUrl(models.Model):
|
|||
|
||||
def __unicode__(self):
|
||||
return u'%s %s %dx%d' % (unicode(self.item), self.service, self.width, self.height)
|
||||
|
||||
|
|
|
@ -11,16 +11,19 @@ import models
|
|||
def cronjob(**kwargs):
|
||||
print "do some cleanup stuff once a day"
|
||||
|
||||
|
||||
@task(ignore_resulsts=True, queue='default')
|
||||
def update_poster(itemId):
|
||||
item = models.Item.objects.get(itemId=itemId)
|
||||
item.make_poster(True)
|
||||
|
||||
|
||||
@task(ignore_resulsts=True, queue='default')
|
||||
def update_imdb(itemId):
|
||||
item = models.Item.objects.get(itemId=itemId)
|
||||
item.update_imdb()
|
||||
|
||||
|
||||
@task(queue="encoding")
|
||||
def update_streams(itemId):
|
||||
'''
|
||||
|
|
|
@ -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
|
||||
"""}
|
||||
|
||||
|
|
|
@ -13,4 +13,3 @@ urlpatterns = patterns("item.views",
|
|||
(r'^(?P<id>[A-Z0-9].*)/poster\.jpg$', 'poster'),
|
||||
(r'^(?P<id>[A-Z0-9].*)/timelines/(?P<timeline>.+)\.(?P<size>\d+)\.(?P<position>\d+)\.png$', 'timeline'),
|
||||
)
|
||||
|
||||
|
|
|
@ -2,17 +2,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
#
|
||||
import errno
|
||||
from decimal import Decimal
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import hashlib
|
||||
import unicodedata
|
||||
|
||||
import ox
|
||||
import ox.iso
|
||||
from ox.normalize import normalizeName, normalizeTitle, canonicalTitle
|
||||
from ox.normalize import normalizeName, normalizeTitle
|
||||
|
||||
|
||||
def parse_decimal(string):
|
||||
|
@ -22,11 +20,13 @@ def parse_decimal(string):
|
|||
d = string.split('/')
|
||||
return Decimal(d[0]) / Decimal(d[1])
|
||||
|
||||
|
||||
def plural_key(term):
|
||||
return {
|
||||
'country': 'countries',
|
||||
}.get(term, term + 's')
|
||||
|
||||
|
||||
def oxid(title, directors, year='', seriesTitle='', episodeTitle='', season=0, episode=0):
|
||||
director = ', '.join(directors)
|
||||
oxid_value = u"\n".join([title, director, year])
|
||||
|
@ -38,6 +38,7 @@ def oxid(title, directors, year='', seriesTitle='', episodeTitle='', season=0, e
|
|||
oxid += hashlib.sha1(oxid_value.encode('utf-8')).hexdigest()[:20]
|
||||
return u"0x" + oxid
|
||||
|
||||
|
||||
def oxdb_id(title, directors=[], year='', season='', episode='', episode_title='', episode_directors=[], episode_year=''):
|
||||
# new id function, will replace oxid()
|
||||
def get_hash(string):
|
||||
|
@ -51,11 +52,13 @@ def oxdb_id(title, directors=[], year='', season='', episode='', episode_title='
|
|||
get_hash('\n'.join([str(episode), episode_director, episode_title, str(episode_year)]))[:8]
|
||||
return u'0x' + oxdb_id
|
||||
|
||||
|
||||
def oxdb_directors(director):
|
||||
director = os.path.basename(os.path.dirname(director))
|
||||
if director.endswith('_'):
|
||||
director = "%s." % director[:-1]
|
||||
directors = [normalizeName(d) for d in director.split('; ')]
|
||||
|
||||
def cleanup(director):
|
||||
director = director.strip()
|
||||
director = director.replace('Series', '')
|
||||
|
@ -65,6 +68,7 @@ def oxdb_directors(director):
|
|||
directors = filter(None, [cleanup(d) for d in directors])
|
||||
return directors
|
||||
|
||||
|
||||
def oxdb_title(_title, searchTitle = False):
|
||||
'''
|
||||
normalize filename to get item title
|
||||
|
@ -98,9 +102,11 @@ def oxdb_title(_title, searchTitle = False):
|
|||
title = normalizeTitle(title)
|
||||
return title
|
||||
|
||||
|
||||
def oxdb_year(data):
|
||||
return ox.findRe(data, '\.(\d{4})\.')
|
||||
|
||||
|
||||
def oxdb_series_title(path):
|
||||
seriesTitle = u''
|
||||
if path.startswith('Series'):
|
||||
|
@ -111,6 +117,7 @@ def oxdb_series_title(path):
|
|||
seriesTitle = t.split(" (S")[0]
|
||||
return seriesTitle
|
||||
|
||||
|
||||
def oxdb_episode_title(path):
|
||||
episodeTitle = u''
|
||||
ep = re.compile('.Episode \d+?\.(.*?)\.[a-zA-Z]').findall(path)
|
||||
|
@ -118,6 +125,7 @@ def oxdb_episode_title(path):
|
|||
episodeTitle = ep[0]
|
||||
return episodeTitle
|
||||
|
||||
|
||||
def oxdb_season_episode(path):
|
||||
season = 0
|
||||
episode = 0
|
||||
|
@ -137,6 +145,7 @@ def oxdb_season_episode(path):
|
|||
episode = int(se[0][1])
|
||||
return (season, episode)
|
||||
|
||||
|
||||
def oxdb_part(path):
|
||||
part = 1
|
||||
path = path.lower()
|
||||
|
@ -149,6 +158,7 @@ def oxdb_part(path):
|
|||
part = p[0]
|
||||
return part
|
||||
|
||||
|
||||
def parse_path(path):
|
||||
'''
|
||||
expects path in the form
|
||||
|
@ -178,6 +188,7 @@ def parse_path(path):
|
|||
episode_year='')
|
||||
return r
|
||||
|
||||
|
||||
def sort_title(title):
|
||||
#title
|
||||
title = re.sub(u'[\'!¿¡,\.;\-"\:\*\[\]]', '', title)
|
||||
|
@ -185,9 +196,8 @@ def sort_title(title):
|
|||
#title = title.replace(u'Æ', 'Ae')
|
||||
if isinstance(title, str):
|
||||
title = unicode(title)
|
||||
title = unicodedata.normalize('NFKD',title)
|
||||
title = unicodedata.normalize('NFKD', title)
|
||||
|
||||
#pad numbered titles
|
||||
title = re.sub('(\d+)', lambda x: '%010d' % int(x.group(0)), title)
|
||||
return title.strip()
|
||||
|
||||
|
|
|
@ -2,19 +2,10 @@
|
|||
# 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.db.models import 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
|
||||
|
@ -28,13 +19,13 @@ import models
|
|||
import utils
|
||||
import tasks
|
||||
|
||||
from user.models import get_user_json
|
||||
|
||||
from archive.models import File
|
||||
from archive import extract
|
||||
|
||||
from api.actions import actions
|
||||
|
||||
|
||||
def _order_query(qs, sort, prefix='sort__'):
|
||||
order_by = []
|
||||
if len(sort) == 1:
|
||||
|
@ -44,7 +35,8 @@ def _order_query(qs, sort, prefix='sort__'):
|
|||
sort.append({'operator': '+', 'key': 'director'})
|
||||
for e in sort:
|
||||
operator = e['operator']
|
||||
if operator != '-': operator = ''
|
||||
if operator != '-':
|
||||
operator = ''
|
||||
key = {'id': 'itemId'}.get(e['key'], e['key'])
|
||||
#FIXME: this should be a property of models.ItemSort!!!
|
||||
if operator=='-' and key in ('title', 'director', 'writer', 'producer', 'editor', 'cinematographer', 'language', 'country', 'year'):
|
||||
|
@ -371,7 +363,8 @@ def getImdbId(request):
|
|||
}
|
||||
}
|
||||
'''
|
||||
imdbId = ox.web.imdb.guess(search_title, r['director'], timeout=-1)
|
||||
data = json.loads(request.POST['data'])
|
||||
imdbId = ox.web.imdb.getImdbId(data['title'], data['director'], timeout=-1)
|
||||
if imdbId:
|
||||
response = json_response({'imdbId': imdbId})
|
||||
else:
|
||||
|
@ -406,7 +399,8 @@ def poster(request, id, size=None):
|
|||
else:
|
||||
poster_path = item.poster.path
|
||||
else:
|
||||
if not size: size='large'
|
||||
if not size:
|
||||
size='large'
|
||||
return redirect('http://0xdb.org/%s/poster.%s.jpg' % (item.itemId, size))
|
||||
poster_path = os.path.join(settings.STATIC_ROOT, 'png/posterDark.48.png')
|
||||
return HttpFileResponse(poster_path, content_type='image/jpeg')
|
||||
|
|
|
@ -2,29 +2,12 @@
|
|||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from __future__ import division, with_statement
|
||||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
import math
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
import unicodedata
|
||||
from glob import glob
|
||||
|
||||
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
|
||||
|
||||
|
||||
class List(models.Model):
|
||||
|
||||
class Meta:
|
||||
unique_together = ("user", "name")
|
||||
|
||||
|
@ -33,7 +16,8 @@ class List(models.Model):
|
|||
user = models.ForeignKey(User)
|
||||
name = models.CharField(max_length=255)
|
||||
public = models.BooleanField(default=False)
|
||||
items = models.ManyToManyField('item.Item', related_name='lists', through='ListItem')
|
||||
items = models.ManyToManyField('item.Item', related_name='lists',
|
||||
through='ListItem')
|
||||
|
||||
def add(self, item):
|
||||
q = self.items.filter(id=item.id)
|
||||
|
@ -55,6 +39,7 @@ class List(models.Model):
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
class ListItem(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
@ -63,4 +48,3 @@ class ListItem(models.Model):
|
|||
|
||||
def __unicode__(self):
|
||||
return u'%s in %s' % (self.item, self.list)
|
||||
|
||||
|
|
|
@ -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
|
||||
"""}
|
||||
|
||||
|
|
|
@ -1,28 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# 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.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
|
||||
import ox
|
||||
|
||||
import models
|
||||
from api.actions import actions
|
||||
|
||||
|
||||
|
@ -54,6 +38,7 @@ def addListItem(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(addListItem)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def removeListItem(request):
|
||||
'''
|
||||
|
@ -82,6 +67,7 @@ def removeListItem(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(removeListItem)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def addList(request):
|
||||
'''
|
||||
|
@ -97,12 +83,11 @@ def addList(request):
|
|||
response = json_response(status=200, text='created')
|
||||
else:
|
||||
response = json_response(status=200, text='list already exists')
|
||||
response['data']['errors'] = {
|
||||
'name': 'List already exists'
|
||||
}
|
||||
response['data']['errors'] = {'name': 'List already exists'}
|
||||
return render_to_json_response(response)
|
||||
actions.register(addList)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def editList(request):
|
||||
'''
|
||||
|
@ -124,6 +109,8 @@ def editList(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(editList)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def removeList(request):
|
||||
'''
|
||||
param data
|
||||
|
@ -139,4 +126,3 @@ def removeList(request):
|
|||
response = json_response(status=403, text='not allowed')
|
||||
return render_to_json_response(response)
|
||||
actions.register(removeList)
|
||||
|
||||
|
|
|
@ -2,26 +2,12 @@
|
|||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from __future__ import division, with_statement
|
||||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
import math
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
import unicodedata
|
||||
from glob import glob
|
||||
|
||||
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
|
||||
|
||||
|
||||
def get_name_sort(name):
|
||||
|
@ -29,6 +15,7 @@ def get_name_sort(name):
|
|||
name_sort = unicodedata.normalize('NFKD', person.name_sort)
|
||||
return name_sort
|
||||
|
||||
|
||||
class Person(models.Model):
|
||||
name = models.CharField(max_length=200)
|
||||
name_sort = models.CharField(max_length=200)
|
||||
|
@ -67,4 +54,3 @@ class Person(models.Model):
|
|||
|
||||
def json(self):
|
||||
return self.name
|
||||
|
||||
|
|
|
@ -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
|
||||
"""}
|
||||
|
||||
|
|
|
@ -9,5 +9,3 @@ import models
|
|||
class PlaceAdmin(admin.ModelAdmin):
|
||||
search_fields = ['name']
|
||||
admin.site.register(models.Place, PlaceAdmin)
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
import re
|
||||
|
||||
from ox.utils import json
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Q, Manager
|
||||
|
||||
import models
|
||||
|
||||
class PlaceManager(Manager):
|
||||
|
||||
def get_query_set(self):
|
||||
return super(PlaceManager, self).get_query_set()
|
||||
|
||||
|
@ -22,7 +17,7 @@ class PlaceManager(Manager):
|
|||
Q(Q(ne_lat__gt=sw_lat)|Q(ne_lat__lt=ne_lat)|Q(ne_lng__gt=sw_lng)|Q(ne_lng__lt=ne_lng))
|
||||
))
|
||||
if q:
|
||||
qs = qs.filter(name_find__icontains, q)
|
||||
qs = qs.filter(name_find__icontains=q)
|
||||
return qs
|
||||
'''
|
||||
#only return locations that have layers of videos visible to current user
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
from __future__ import division, with_statement
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.conf import settings
|
||||
|
||||
import ox
|
||||
from ox.django import fields
|
||||
|
||||
import managers
|
||||
|
||||
|
||||
class Place(models.Model):
|
||||
'''
|
||||
Places are named locations, they should have geographical information attached to them.
|
||||
|
@ -60,7 +60,6 @@ class Place(models.Model):
|
|||
self.lng_center = ox.location.center(self.lng_sw, self.lng_ne)
|
||||
|
||||
#update area
|
||||
self.area = location.area(self.lat_sw, self.lng_sw, self.lat_ne, self.lng_ne)
|
||||
self.area = ox.location.area(self.lat_sw, self.lng_sw, self.lat_ne, self.lng_ne)
|
||||
|
||||
super(Place, self).save(*args, **kwargs)
|
||||
|
||||
|
|
|
@ -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
|
||||
"""}
|
||||
|
||||
|
|
|
@ -1,37 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# 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.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
|
||||
import ox
|
||||
|
||||
import models
|
||||
from api.actions import actions
|
||||
|
||||
'''
|
||||
fixme, require admin
|
||||
'''
|
||||
|
||||
@login_required_json
|
||||
def addPlace(request):
|
||||
#FIXME: require admin
|
||||
'''
|
||||
param data
|
||||
{
|
||||
|
@ -56,6 +38,7 @@ def addPlace(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(addPlace)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def editPlace(request):
|
||||
'''
|
||||
|
@ -86,12 +69,14 @@ def editPlace(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(editPlace)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def removePlace(request):
|
||||
response = json_response(status=501, text='not implemented')
|
||||
return render_to_json_response(response)
|
||||
actions.register(removePlace)
|
||||
|
||||
|
||||
def findPlace(request):
|
||||
'''
|
||||
param data
|
||||
|
@ -129,8 +114,7 @@ Positions
|
|||
response = json_response(status=200, text='ok')
|
||||
response['data']['places'] = []
|
||||
#FIXME: add coordinates to limit search
|
||||
for p in Places.objects.find(data['query']):
|
||||
for p in models.Place.objects.find(data['query']):
|
||||
response['data']['places'].append(p.json())
|
||||
return render_to_json_response(response)
|
||||
actions.register(findPlace)
|
||||
|
||||
|
|
|
@ -5,11 +5,6 @@ from datetime import datetime
|
|||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.conf import settings
|
||||
|
||||
import ox
|
||||
from ox.django import fields
|
||||
from ox.utils import json
|
||||
|
||||
|
||||
class News(models.Model):
|
||||
|
@ -29,6 +24,7 @@ class News(models.Model):
|
|||
def get_absolute_url(self):
|
||||
return '/text/%s' % self.slug
|
||||
|
||||
|
||||
class Text(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
@ -46,6 +42,7 @@ class Text(models.Model):
|
|||
def get_absolute_url(self):
|
||||
return '/text/%s' % self.slug
|
||||
|
||||
|
||||
class Image(models.Model):
|
||||
image = models.ImageField(upload_to='text/image')
|
||||
caption = models.CharField(max_length=255, default="")
|
||||
|
@ -53,10 +50,10 @@ class Image(models.Model):
|
|||
def get_absolute_url(self):
|
||||
return self.image.url
|
||||
|
||||
|
||||
class Attachment(models.Model):
|
||||
file = models.FileField(upload_to='text/attachment')
|
||||
caption = models.CharField(max_length=255, default="")
|
||||
|
||||
def get_absolute_url(self):
|
||||
return self.file.url
|
||||
|
||||
|
|
|
@ -2,23 +2,15 @@
|
|||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from __future__ import division
|
||||
|
||||
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.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
|
||||
import ox
|
||||
|
||||
import models
|
||||
from api.actions import actions
|
||||
|
||||
|
||||
def getNews(request):
|
||||
'''
|
||||
param data
|
||||
|
@ -33,6 +25,23 @@ def getNews(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(getNews)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def editNews(request):
|
||||
'''
|
||||
param data
|
||||
string id
|
||||
|
||||
return page
|
||||
'''
|
||||
response = json_response({})
|
||||
itemId = json.loads(request.POST['data'])
|
||||
item = get_object_or_404_json(models.Text, pk=itemId)
|
||||
response['data']['page'] = item.html()
|
||||
return render_to_json_response(response)
|
||||
actions.register(editNews)
|
||||
|
||||
|
||||
def findNews(request):
|
||||
'''
|
||||
'''
|
||||
|
@ -40,6 +49,7 @@ def findNews(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(findNews)
|
||||
|
||||
|
||||
def getText(request):
|
||||
'''
|
||||
param data
|
||||
|
@ -54,10 +64,26 @@ def getText(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(getText)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def editText(request):
|
||||
'''
|
||||
param data
|
||||
string id
|
||||
|
||||
return page
|
||||
'''
|
||||
response = json_response({})
|
||||
itemId = json.loads(request.POST['data'])
|
||||
item = get_object_or_404_json(models.Text, pk=itemId)
|
||||
response['data']['page'] = item.html()
|
||||
return render_to_json_response(response)
|
||||
actions.register(editText)
|
||||
|
||||
|
||||
def findText(request):
|
||||
'''
|
||||
'''
|
||||
response = json_response({})
|
||||
return render_to_json_response(response)
|
||||
actions.register(findText)
|
||||
|
||||
|
|
|
@ -10,12 +10,14 @@ from django.conf import settings
|
|||
import ox.torrent
|
||||
import transmissionrpc
|
||||
|
||||
|
||||
def connect():
|
||||
return transmissionrpc.Client(settings.TRANSMISSON_HOST,
|
||||
port=settings.TRANSMISSON_PORT,
|
||||
user=settings.TRANSMISSON_USER,
|
||||
password=settings.TRANSMISSON_PASSWORD)
|
||||
|
||||
|
||||
def remove(info_hash):
|
||||
if settings.DEBUG:
|
||||
print 'remove', info_hash
|
||||
|
@ -24,10 +26,11 @@ def remove(info_hash):
|
|||
tc = connect()
|
||||
tc.remove(info_hash.lower())
|
||||
except:
|
||||
if DEBUG:
|
||||
if settings.DEBUG:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
def add(torrent_file):
|
||||
download_dir = os.path.dirname(torrent_file)
|
||||
with open(torrent_file) as f:
|
||||
|
@ -42,6 +45,7 @@ def add(torrent_file):
|
|||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
def is_seeding(info_hash):
|
||||
info_hash = info_hash.lower()
|
||||
try:
|
||||
|
@ -56,6 +60,7 @@ def is_seeding(info_hash):
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def start_daemon():
|
||||
try:
|
||||
tc = connect()
|
||||
|
@ -71,4 +76,3 @@ def start_daemon():
|
|||
'-w', settings.MEDIA_ROOT,
|
||||
])
|
||||
time.sleep(1)
|
||||
|
||||
|
|
|
@ -5,12 +5,11 @@ from datetime import datetime
|
|||
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
from django.dispatch import dispatcher
|
||||
from django.conf import settings
|
||||
|
||||
from ox.utils import json
|
||||
|
||||
|
||||
class UserProfile(models.Model):
|
||||
reset_token = models.TextField(blank=True, null=True, unique=True)
|
||||
user = models.ForeignKey(User, unique=True)
|
||||
|
@ -18,11 +17,13 @@ class UserProfile(models.Model):
|
|||
files_updated = models.DateTimeField(default=datetime.now)
|
||||
newsletter = models.BooleanField(default=True)
|
||||
|
||||
|
||||
def user_post_save(sender, instance, **kwargs):
|
||||
profile, new = UserProfile.objects.get_or_create(user=instance)
|
||||
|
||||
models.signals.post_save.connect(user_post_save, sender=User)
|
||||
|
||||
|
||||
class Preference(models.Model):
|
||||
user = models.ForeignKey(User, related_name='preferences')
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
@ -33,18 +34,20 @@ class Preference(models.Model):
|
|||
def __unicode__(self):
|
||||
return u"%s/%s=%s" % (self.user, self.key, self.value)
|
||||
|
||||
|
||||
def get_user_json(user):
|
||||
json = {}
|
||||
result = {}
|
||||
for key in ('username', ):
|
||||
json[key] = getattr(user, key)
|
||||
json['group'] = 'user'
|
||||
result[key] = getattr(user, key)
|
||||
result['group'] = 'user'
|
||||
if user.is_staff:
|
||||
json['group'] = 'admin'
|
||||
result['group'] = 'admin'
|
||||
elif user.has_perm('0x.vip'): #FIXME: permissions
|
||||
json['group'] = 'vip'
|
||||
json['preferences'] = get_preferences(user)
|
||||
json['ui'] = get_ui(user)
|
||||
return json
|
||||
result['group'] = 'vip'
|
||||
result['preferences'] = get_preferences(user)
|
||||
result['ui'] = get_ui(user)
|
||||
return result
|
||||
|
||||
|
||||
def get_ui(user):
|
||||
with open(os.path.join(settings.PROJECT_ROOT, 'templates', 'site.json')) as f:
|
||||
|
@ -70,6 +73,7 @@ def get_ui(user):
|
|||
}
|
||||
'''
|
||||
|
||||
|
||||
def get_preferences(user):
|
||||
prefs = {}
|
||||
for p in Preference.objects.filter(user=user):
|
||||
|
@ -77,6 +81,7 @@ def get_preferences(user):
|
|||
prefs['email'] = user.email
|
||||
return prefs
|
||||
|
||||
|
||||
def get_preference(user, key, value=None):
|
||||
if key in ('email', ):
|
||||
value = getattr(user, key)
|
||||
|
@ -86,6 +91,7 @@ def get_preference(user, key, value=None):
|
|||
value = json.loads(q[0].value)
|
||||
return value
|
||||
|
||||
|
||||
def set_preference(user, key, value):
|
||||
if key in ('email', ):
|
||||
setattr(user, key, value)
|
||||
|
|
|
@ -7,8 +7,7 @@ random.seed()
|
|||
from django import forms
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect
|
||||
from django.template import RequestContext, loader, Context
|
||||
from django.template import RequestContext, loader
|
||||
from django.utils import simplejson as json
|
||||
from django.conf import settings
|
||||
from django.core.mail import send_mail, BadHeaderError
|
||||
|
@ -26,6 +25,7 @@ class LoginForm(forms.Form):
|
|||
username = forms.TextInput()
|
||||
password = forms.TextInput()
|
||||
|
||||
|
||||
def api_login(request):
|
||||
'''
|
||||
param data {
|
||||
|
@ -81,6 +81,7 @@ def api_login(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(api_login, 'login')
|
||||
|
||||
|
||||
def api_logout(request):
|
||||
'''
|
||||
param data {
|
||||
|
@ -105,11 +106,13 @@ def api_logout(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(api_logout, 'logout')
|
||||
|
||||
|
||||
class RegisterForm(forms.Form):
|
||||
username = forms.TextInput()
|
||||
password = forms.TextInput()
|
||||
email = forms.TextInput()
|
||||
|
||||
|
||||
def register(request):
|
||||
'''
|
||||
param data {
|
||||
|
@ -172,6 +175,7 @@ def register(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(register)
|
||||
|
||||
|
||||
def resetPassword(request):
|
||||
'''
|
||||
param data {
|
||||
|
@ -226,6 +230,7 @@ def resetPassword(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(resetPassword)
|
||||
|
||||
|
||||
def requestToken(request):
|
||||
'''
|
||||
param data {
|
||||
|
@ -291,6 +296,7 @@ def requestToken(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(requestToken)
|
||||
|
||||
|
||||
def findUser(request):
|
||||
'''
|
||||
param data {
|
||||
|
@ -315,11 +321,13 @@ def findUser(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(findUser)
|
||||
|
||||
|
||||
class ContactForm(forms.Form):
|
||||
email = forms.EmailField()
|
||||
subject = forms.TextInput()
|
||||
message = forms.TextInput()
|
||||
|
||||
|
||||
def contact(request):
|
||||
'''
|
||||
param data {
|
||||
|
@ -353,6 +361,7 @@ def contact(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(contact)
|
||||
|
||||
|
||||
@login_required_json
|
||||
def preferences(request):
|
||||
'''
|
||||
|
@ -391,4 +400,3 @@ def preferences(request):
|
|||
models.set_preference(request.user, key, data[key])
|
||||
return render_to_json_response(response)
|
||||
actions.register(preferences)
|
||||
|
||||
|
|
Loading…
Reference in a new issue