more moving around

This commit is contained in:
j 2010-11-08 17:34:25 +01:00
parent 75f6e3b2dc
commit bdb0365fb1
36 changed files with 200 additions and 120 deletions

5
pandora/api/models.py Normal file
View file

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from item.models import *

10
pandora/api/urls.py Normal file
View file

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from django.conf.urls.defaults import *
urlpatterns = patterns("api.views",
(r'^$', 'api'),
)

148
pandora/api/views.py Normal file
View file

@ -0,0 +1,148 @@
# -*- 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
try:
import simplejson as json
except ImportError:
from django.utils import simplejson as json
from oxdjango.decorators import login_required_json
from oxdjango.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from oxdjango.http import HttpFileResponse
import ox
import models
import utils
import tasks
from user.models import getUserJSON
from user.views import api_login, api_logout, api_register, api_contact, api_recover, api_preferences, api_findUser
from archive.views import api_update, api_upload, api_editFile
from archive.models import File
from archive import extract
from item.views import *
def api(request):
if request.META['REQUEST_METHOD'] == "OPTIONS":
response = HttpResponse('')
response = render_to_json_response({'status': {'code': 200, 'text': 'use POST'}})
response['Access-Control-Allow-Origin'] = '*'
return response
if not 'action' in request.POST:
return apidoc(request)
function = request.POST['action']
#FIXME: possible to do this in f
#data = json.loads(request.POST['data'])
f = globals().get('api_'+function, None)
if f:
response = f(request)
else:
response = render_to_json_response(json_response(status=400,
text='Unknown function %s' % function))
response['Access-Control-Allow-Origin'] = '*'
return response
def api_api(request):
'''
returns list of all known api action
return {'status': {'code': int, 'text': string},
'data': {actions: ['api', 'hello', ...]}}
'''
actions = globals().keys()
actions = map(lambda a: a[4:], filter(lambda a: a.startswith('api_'), actions))
actions.sort()
return render_to_json_response(json_response({'actions': actions}))
def api_hello(request):
'''
return {'status': {'code': int, 'text': string},
'data': {user: object}}
'''
#data = json.loads(request.POST['data'])
response = json_response({})
if request.user.is_authenticated():
response['data']['user'] = getUserJSON(request.user)
else:
response['data']['user'] = {'name': 'Guest', 'group': 'guest', 'preferences': {}}
return render_to_json_response(response)
def api_error(request):
'''
trows 503 error
'''
success = error_is_success
return render_to_json_response({})
def apidoc(request):
'''
this is used for online documentation at http://127.0.0.1:8000/api/
'''
import sys
def trim(docstring):
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
indent = sys.maxint
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxint:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return '\n'.join(trimmed)
functions = filter(lambda x: x.startswith('api_'), globals().keys())
api = []
for f in sorted(functions):
api.append({
'name': f[4:],
'doc': trim(globals()[f].__doc__).replace('\n', '<br>\n')
})
context = RequestContext(request, {'api': api,
'sitename': settings.SITENAME,})
return render_to_response('api.html', context)
'''
ajax html snapshots
http://code.google.com/web/ajaxcrawling/docs/html-snapshot.html
'''
def html_snapshot(request):
fragment = unquote(request.GET['_escaped_fragment_'])
url = request.build_absolute_uri('/ra')
url = 'http://'+settings.URL
response = HttpResponse('sorry, server side rendering for %s!#%s not yet implemented'%(url, fragment))
return response

View file

@ -8,7 +8,7 @@ from oxdjango.shortcuts import json_response, render_to_json_response, get_objec
import models import models
from backend.views import html_snapshot from api.views import html_snapshot
def intro(request): def intro(request):
context = RequestContext(request, {'settings':settings}) context = RequestContext(request, {'settings':settings})

View file

@ -22,8 +22,8 @@ from ox.normalize import canonicalTitle, canonicalName
from firefogg import Firefogg from firefogg import Firefogg
import chardet import chardet
from backend import utils from item import utils
from pandora.backend.models import Item from item.models import Item
import extract import extract
@ -143,7 +143,7 @@ class File(models.Model):
#upload and data handling #upload and data handling
video = models.FileField(null=True, blank=True, upload_to=lambda f, x: file_path(f, '%s.webm'%settings.VIDEO_PROFILE)) video = models.FileField(null=True, blank=True, upload_to=lambda f, x: file_path(f, '%s.webm'%settings.VIDEO_PROFILE))
data = models.FileField(null=True, blank=True, upload_to=lambda f, x: file_path(f, 'data.raw')) data = models.FileField(null=True, blank=True, upload_to=lambda f, x: file_path(f, 'data.bin'))
def contents(self): def contents(self):
if self.data != None: if self.data != None:

View file

@ -29,9 +29,9 @@ import ox
import models import models
from backend.utils import oxid, parse_path from item.utils import oxid, parse_path
import backend.models import item.models
import backend.tasks import item.tasks
@login_required_json @login_required_json
def api_removeVolume(request): def api_removeVolume(request):
@ -114,7 +114,7 @@ def api_update(request):
else: else:
if not item: if not item:
item_info = parse_path(folder) item_info = parse_path(folder)
item = backend.models.getItem(item_info) item = item.models.getItem(item_info)
file_object = models.File() file_object = models.File()
file_object.oshash = oshash file_object.oshash = oshash
file_object.name = name file_object.name = name
@ -223,7 +223,7 @@ def firefogg_upload(request):
elif form.cleaned_data['done']: elif form.cleaned_data['done']:
f.available = True f.available = True
f.save() f.save()
backend.tasks.updateStreams.delay(f.item.itemId) item.tasks.updateStreams.delay(f.item.itemId)
response['result'] = 1 response['result'] = 1
response['done'] = 1 response['done'] = 1
return render_to_json_response(response) return render_to_json_response(response)

0
pandora/item/__init__.py Normal file
View file

23
pandora/item/tests.py Normal file
View file

@ -0,0 +1,23 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
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.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

View file

@ -4,7 +4,7 @@
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
urlpatterns = patterns("backend.views", urlpatterns = patterns("item.views",
(r'^(?P<id>.*)/frame/(?P<size>\d+)/(?P<position>[0-9\.,]+).jpg$', 'frame'), (r'^(?P<id>.*)/frame/(?P<size>\d+)/(?P<position>[0-9\.,]+).jpg$', 'frame'),
(r'^(?P<id>.*)/(?P<profile>.*.webm)$', 'video'), (r'^(?P<id>.*)/(?P<profile>.*.webm)$', 'video'),
(r'^(?P<id>.*)/(?P<profile>.*.mp4)$', 'video'), (r'^(?P<id>.*)/(?P<profile>.*.mp4)$', 'video'),
@ -12,6 +12,5 @@ urlpatterns = patterns("backend.views",
(r'^(?P<id>.*)/poster\.(?P<size>large)\.jpg$', 'poster'), (r'^(?P<id>.*)/poster\.(?P<size>large)\.jpg$', 'poster'),
(r'^(?P<id>.*)/poster\.jpg$', 'poster'), (r'^(?P<id>.*)/poster\.jpg$', 'poster'),
(r'^(?P<id>.*)/timelines/(?P<timeline>.+)\.(?P<size>\d+)\.(?P<position>\d+)\.png$', 'timeline'), (r'^(?P<id>.*)/timelines/(?P<timeline>.+)\.(?P<size>\d+)\.(?P<position>\d+)\.png$', 'timeline'),
(r'^api/$', 'api'),
) )

View file

@ -32,66 +32,10 @@ import utils
import tasks import tasks
from user.models import getUserJSON from user.models import getUserJSON
from user.views import api_login, api_logout, api_register, api_contact, api_recover, api_preferences, api_findUser
from archive.views import api_update, api_upload, api_editFile
from archive.models import File from archive.models import File
from archive import extract from archive import extract
def api(request):
if request.META['REQUEST_METHOD'] == "OPTIONS":
response = HttpResponse('')
response = render_to_json_response({'status': {'code': 200, 'text': 'use POST'}})
response['Access-Control-Allow-Origin'] = '*'
return response
if not 'action' in request.POST:
return apidoc(request)
function = request.POST['action']
#FIXME: possible to do this in f
#data = json.loads(request.POST['data'])
f = globals().get('api_'+function, None)
if f:
response = f(request)
else:
response = render_to_json_response(json_response(status=400,
text='Unknown function %s' % function))
response['Access-Control-Allow-Origin'] = '*'
return response
def api_api(request):
'''
returns list of all known api action
return {'status': {'code': int, 'text': string},
'data': {actions: ['api', 'hello', ...]}}
'''
actions = globals().keys()
actions = map(lambda a: a[4:], filter(lambda a: a.startswith('api_'), actions))
actions.sort()
return render_to_json_response(json_response({'actions': actions}))
def api_hello(request):
'''
return {'status': {'code': int, 'text': string},
'data': {user: object}}
'''
#data = json.loads(request.POST['data'])
response = json_response({})
if request.user.is_authenticated():
response['data']['user'] = getUserJSON(request.user)
else:
response['data']['user'] = {'name': 'Guest', 'group': 'guest', 'preferences': {}}
return render_to_json_response(response)
def api_error(request):
'''
trows 503 error
'''
success = error_is_success
return render_to_json_response({})
def _order_query(qs, sort, prefix='sort__'): def _order_query(qs, sort, prefix='sort__'):
order_by = [] order_by = []
if len(sort) == 1: if len(sort) == 1:
@ -489,46 +433,6 @@ def api_getImdbId(request):
response = json_response(status=404, text='not found') response = json_response(status=404, text='not found')
return render_to_json_response(response) return render_to_json_response(response)
def apidoc(request):
'''
this is used for online documentation at http://127.0.0.1:8000/api/
'''
import sys
def trim(docstring):
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
indent = sys.maxint
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxint:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return '\n'.join(trimmed)
functions = filter(lambda x: x.startswith('api_'), globals().keys())
api = []
for f in sorted(functions):
api.append({
'name': f[4:],
'doc': trim(globals()[f].__doc__).replace('\n', '<br>\n')
})
context = RequestContext(request, {'api': api,
'sitename': settings.SITENAME,})
return render_to_response('api.html', context)
''' '''
media delivery media delivery
@ -577,14 +481,3 @@ def video(request, id, profile):
content_type = path.endswith('.mp4') and 'video/mp4' or 'video/webm' content_type = path.endswith('.mp4') and 'video/mp4' or 'video/webm'
return HttpFileResponse(path, content_type=content_type) return HttpFileResponse(path, content_type=content_type)
'''
ajax html snapshots
http://code.google.com/web/ajaxcrawling/docs/html-snapshot.html
'''
def html_snapshot(request):
fragment = unquote(request.GET['_escaped_fragment_'])
url = request.build_absolute_uri('/ra')
url = 'http://'+settings.URL
response = HttpResponse('sorry, server side rendering for %s!#%s not yet implemented'%(url, fragment))
return response

View file

@ -117,7 +117,8 @@ INSTALLED_APPS = (
'djcelery', 'djcelery',
'app', 'app',
'backend', 'api',
'item',
'archive', 'archive',
'user', 'user',
'torrent', 'torrent',

View file

@ -24,7 +24,8 @@ urlpatterns = patterns('',
(r'^file/(?P<oshash>.*)$', 'archive.views.lookup_file'), (r'^file/(?P<oshash>.*)$', 'archive.views.lookup_file'),
(r'^r/(?P<key>.*)$', 'user.views.recover'), (r'^r/(?P<key>.*)$', 'user.views.recover'),
(r'', include('backend.urls')), (r'^api/$', include('api.urls')),
(r'', include('item.urls')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs' # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation: # to INSTALLED_APPS to enable admin documentation: