forked from 0x2620/pandora
more moving around
This commit is contained in:
parent
75f6e3b2dc
commit
bdb0365fb1
36 changed files with 200 additions and 120 deletions
5
pandora/api/models.py
Normal file
5
pandora/api/models.py
Normal 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
10
pandora/api/urls.py
Normal 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
148
pandora/api/views.py
Normal 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
|
|
@ -8,7 +8,7 @@ from oxdjango.shortcuts import json_response, render_to_json_response, get_objec
|
|||
|
||||
import models
|
||||
|
||||
from backend.views import html_snapshot
|
||||
from api.views import html_snapshot
|
||||
|
||||
def intro(request):
|
||||
context = RequestContext(request, {'settings':settings})
|
||||
|
|
|
@ -22,8 +22,8 @@ from ox.normalize import canonicalTitle, canonicalName
|
|||
from firefogg import Firefogg
|
||||
import chardet
|
||||
|
||||
from backend import utils
|
||||
from pandora.backend.models import Item
|
||||
from item import utils
|
||||
from item.models import Item
|
||||
|
||||
import extract
|
||||
|
||||
|
@ -143,7 +143,7 @@ class File(models.Model):
|
|||
|
||||
#upload and data handling
|
||||
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):
|
||||
if self.data != None:
|
||||
|
|
|
@ -29,9 +29,9 @@ import ox
|
|||
|
||||
import models
|
||||
|
||||
from backend.utils import oxid, parse_path
|
||||
import backend.models
|
||||
import backend.tasks
|
||||
from item.utils import oxid, parse_path
|
||||
import item.models
|
||||
import item.tasks
|
||||
|
||||
@login_required_json
|
||||
def api_removeVolume(request):
|
||||
|
@ -114,7 +114,7 @@ def api_update(request):
|
|||
else:
|
||||
if not item:
|
||||
item_info = parse_path(folder)
|
||||
item = backend.models.getItem(item_info)
|
||||
item = item.models.getItem(item_info)
|
||||
file_object = models.File()
|
||||
file_object.oshash = oshash
|
||||
file_object.name = name
|
||||
|
@ -223,7 +223,7 @@ def firefogg_upload(request):
|
|||
elif form.cleaned_data['done']:
|
||||
f.available = True
|
||||
f.save()
|
||||
backend.tasks.updateStreams.delay(f.item.itemId)
|
||||
item.tasks.updateStreams.delay(f.item.itemId)
|
||||
response['result'] = 1
|
||||
response['done'] = 1
|
||||
return render_to_json_response(response)
|
||||
|
|
0
pandora/item/__init__.py
Normal file
0
pandora/item/__init__.py
Normal file
23
pandora/item/tests.py
Normal file
23
pandora/item/tests.py
Normal 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
|
||||
"""}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
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>.*)/(?P<profile>.*.webm)$', '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\.jpg$', 'poster'),
|
||||
(r'^(?P<id>.*)/timelines/(?P<timeline>.+)\.(?P<size>\d+)\.(?P<position>\d+)\.png$', 'timeline'),
|
||||
(r'^api/$', 'api'),
|
||||
)
|
||||
|
|
@ -32,66 +32,10 @@ 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
|
||||
|
||||
|
||||
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__'):
|
||||
order_by = []
|
||||
if len(sort) == 1:
|
||||
|
@ -489,46 +433,6 @@ def api_getImdbId(request):
|
|||
response = json_response(status=404, text='not found')
|
||||
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
|
||||
|
@ -577,14 +481,3 @@ def video(request, id, profile):
|
|||
content_type = path.endswith('.mp4') and 'video/mp4' or 'video/webm'
|
||||
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
|
|
@ -117,7 +117,8 @@ INSTALLED_APPS = (
|
|||
'djcelery',
|
||||
|
||||
'app',
|
||||
'backend',
|
||||
'api',
|
||||
'item',
|
||||
'archive',
|
||||
'user',
|
||||
'torrent',
|
||||
|
|
|
@ -24,7 +24,8 @@ urlpatterns = patterns('',
|
|||
(r'^file/(?P<oshash>.*)$', 'archive.views.lookup_file'),
|
||||
|
||||
(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'
|
||||
# to INSTALLED_APPS to enable admin documentation:
|
||||
|
|
Loading…
Reference in a new issue