diff --git a/pandora/backend/__init__.py b/pandora/api/__init__.py
similarity index 100%
rename from pandora/backend/__init__.py
rename to pandora/api/__init__.py
diff --git a/pandora/backend/admin.py b/pandora/api/admin.py
similarity index 100%
rename from pandora/backend/admin.py
rename to pandora/api/admin.py
diff --git a/pandora/backend/forms.py b/pandora/api/forms.py
similarity index 100%
rename from pandora/backend/forms.py
rename to pandora/api/forms.py
diff --git a/pandora/backend/management/__init__.py b/pandora/api/management/__init__.py
similarity index 100%
rename from pandora/backend/management/__init__.py
rename to pandora/api/management/__init__.py
diff --git a/pandora/backend/management/commands/__init__.py b/pandora/api/management/commands/__init__.py
similarity index 100%
rename from pandora/backend/management/commands/__init__.py
rename to pandora/api/management/commands/__init__.py
diff --git a/pandora/backend/migrations/0001_initial.py b/pandora/api/migrations/0001_initial.py
similarity index 100%
rename from pandora/backend/migrations/0001_initial.py
rename to pandora/api/migrations/0001_initial.py
diff --git a/pandora/backend/migrations/0002_poster.py b/pandora/api/migrations/0002_poster.py
similarity index 100%
rename from pandora/backend/migrations/0002_poster.py
rename to pandora/api/migrations/0002_poster.py
diff --git a/pandora/backend/migrations/0003_archive.py b/pandora/api/migrations/0003_archive.py
similarity index 100%
rename from pandora/backend/migrations/0003_archive.py
rename to pandora/api/migrations/0003_archive.py
diff --git a/pandora/backend/migrations/0004_add_dialog.py b/pandora/api/migrations/0004_add_dialog.py
similarity index 100%
rename from pandora/backend/migrations/0004_add_dialog.py
rename to pandora/api/migrations/0004_add_dialog.py
diff --git a/pandora/backend/migrations/0005_dialog_sort.py b/pandora/api/migrations/0005_dialog_sort.py
similarity index 100%
rename from pandora/backend/migrations/0005_dialog_sort.py
rename to pandora/api/migrations/0005_dialog_sort.py
diff --git a/pandora/backend/migrations/0006_poster.py b/pandora/api/migrations/0006_poster.py
similarity index 100%
rename from pandora/backend/migrations/0006_poster.py
rename to pandora/api/migrations/0006_poster.py
diff --git a/pandora/backend/migrations/0007_poster_url.py b/pandora/api/migrations/0007_poster_url.py
similarity index 100%
rename from pandora/backend/migrations/0007_poster_url.py
rename to pandora/api/migrations/0007_poster_url.py
diff --git a/pandora/backend/migrations/0008_stream.py b/pandora/api/migrations/0008_stream.py
similarity index 100%
rename from pandora/backend/migrations/0008_stream.py
rename to pandora/api/migrations/0008_stream.py
diff --git a/pandora/backend/migrations/0009_stream_info.py b/pandora/api/migrations/0009_stream_info.py
similarity index 100%
rename from pandora/backend/migrations/0009_stream_info.py
rename to pandora/api/migrations/0009_stream_info.py
diff --git a/pandora/backend/migrations/0010_add_posterurl.py b/pandora/api/migrations/0010_add_posterurl.py
similarity index 100%
rename from pandora/backend/migrations/0010_add_posterurl.py
rename to pandora/api/migrations/0010_add_posterurl.py
diff --git a/pandora/backend/migrations/0011_rename_movie.py b/pandora/api/migrations/0011_rename_movie.py
similarity index 100%
rename from pandora/backend/migrations/0011_rename_movie.py
rename to pandora/api/migrations/0011_rename_movie.py
diff --git a/pandora/backend/migrations/0012_auto__del_field_itemfind_all__del_field_itemfind_trivia__del_field_ite.py b/pandora/api/migrations/0012_auto__del_field_itemfind_all__del_field_itemfind_trivia__del_field_ite.py
similarity index 100%
rename from pandora/backend/migrations/0012_auto__del_field_itemfind_all__del_field_itemfind_trivia__del_field_ite.py
rename to pandora/api/migrations/0012_auto__del_field_itemfind_all__del_field_itemfind_trivia__del_field_ite.py
diff --git a/pandora/backend/migrations/0013_auto.py b/pandora/api/migrations/0013_auto.py
similarity index 100%
rename from pandora/backend/migrations/0013_auto.py
rename to pandora/api/migrations/0013_auto.py
diff --git a/pandora/backend/migrations/__init__.py b/pandora/api/migrations/__init__.py
similarity index 100%
rename from pandora/backend/migrations/__init__.py
rename to pandora/api/migrations/__init__.py
diff --git a/pandora/api/models.py b/pandora/api/models.py
new file mode 100644
index 0000000..dc3eab4
--- /dev/null
+++ b/pandora/api/models.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# vi:si:et:sw=4:sts=4:ts=4
+
+from item.models import *
+
diff --git a/pandora/api/urls.py b/pandora/api/urls.py
new file mode 100644
index 0000000..fb0b40c
--- /dev/null
+++ b/pandora/api/urls.py
@@ -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'),
+)
+
diff --git a/pandora/api/views.py b/pandora/api/views.py
new file mode 100644
index 0000000..e4f1d53
--- /dev/null
+++ b/pandora/api/views.py
@@ -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', '
\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
diff --git a/pandora/app/views.py b/pandora/app/views.py
index 5cd2e0b..f527340 100644
--- a/pandora/app/views.py
+++ b/pandora/app/views.py
@@ -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})
diff --git a/pandora/archive/models.py b/pandora/archive/models.py
index 6386b06..3bb8de3 100644
--- a/pandora/archive/models.py
+++ b/pandora/archive/models.py
@@ -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:
diff --git a/pandora/archive/views.py b/pandora/archive/views.py
index 8bb2374..28a0398 100644
--- a/pandora/archive/views.py
+++ b/pandora/archive/views.py
@@ -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)
diff --git a/pandora/item/__init__.py b/pandora/item/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pandora/backend/load.py b/pandora/item/load.py
similarity index 100%
rename from pandora/backend/load.py
rename to pandora/item/load.py
diff --git a/pandora/backend/managers.py b/pandora/item/managers.py
similarity index 100%
rename from pandora/backend/managers.py
rename to pandora/item/managers.py
diff --git a/pandora/backend/models.py b/pandora/item/models.py
similarity index 100%
rename from pandora/backend/models.py
rename to pandora/item/models.py
diff --git a/pandora/backend/tasks.py b/pandora/item/tasks.py
similarity index 100%
rename from pandora/backend/tasks.py
rename to pandora/item/tasks.py
diff --git a/pandora/item/tests.py b/pandora/item/tests.py
new file mode 100644
index 0000000..2247054
--- /dev/null
+++ b/pandora/item/tests.py
@@ -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
+"""}
+
diff --git a/pandora/backend/urls.py b/pandora/item/urls.py
similarity index 89%
rename from pandora/backend/urls.py
rename to pandora/item/urls.py
index c4c188d..78dc1b7 100644
--- a/pandora/backend/urls.py
+++ b/pandora/item/urls.py
@@ -4,7 +4,7 @@
from django.conf.urls.defaults import *
-urlpatterns = patterns("backend.views",
+urlpatterns = patterns("item.views",
(r'^(?P.*)/frame/(?P\d+)/(?P[0-9\.,]+).jpg$', 'frame'),
(r'^(?P.*)/(?P.*.webm)$', 'video'),
(r'^(?P.*)/(?P.*.mp4)$', 'video'),
@@ -12,6 +12,5 @@ urlpatterns = patterns("backend.views",
(r'^(?P.*)/poster\.(?Plarge)\.jpg$', 'poster'),
(r'^(?P.*)/poster\.jpg$', 'poster'),
(r'^(?P.*)/timelines/(?P.+)\.(?P\d+)\.(?P\d+)\.png$', 'timeline'),
- (r'^api/$', 'api'),
)
diff --git a/pandora/backend/utils.py b/pandora/item/utils.py
similarity index 100%
rename from pandora/backend/utils.py
rename to pandora/item/utils.py
diff --git a/pandora/backend/views.py b/pandora/item/views.py
similarity index 81%
rename from pandora/backend/views.py
rename to pandora/item/views.py
index 43c14ed..6dc469c 100644
--- a/pandora/backend/views.py
+++ b/pandora/item/views.py
@@ -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', '
\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
diff --git a/pandora/settings.py b/pandora/settings.py
index 7a3feb6..5a08561 100644
--- a/pandora/settings.py
+++ b/pandora/settings.py
@@ -117,7 +117,8 @@ INSTALLED_APPS = (
'djcelery',
'app',
- 'backend',
+ 'api',
+ 'item',
'archive',
'user',
'torrent',
diff --git a/pandora/urls.py b/pandora/urls.py
index 2065b75..b2a3975 100644
--- a/pandora/urls.py
+++ b/pandora/urls.py
@@ -24,7 +24,8 @@ urlpatterns = patterns('',
(r'^file/(?P.*)$', 'archive.views.lookup_file'),
(r'^r/(?P.*)$', '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: