migrate to django 1.9
This commit is contained in:
parent
f7855147ce
commit
e5dd8aaab7
48 changed files with 659 additions and 848 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -14,3 +14,4 @@ build
|
||||||
*.pyc
|
*.pyc
|
||||||
*~
|
*~
|
||||||
*.swp
|
*.swp
|
||||||
|
local
|
||||||
|
|
|
@ -20,7 +20,8 @@ end script
|
||||||
exec start-stop-daemon \
|
exec start-stop-daemon \
|
||||||
--pidfile /var/run/oxdata/oxdata.pid \
|
--pidfile /var/run/oxdata/oxdata.pid \
|
||||||
--start -c $USER -d $VENV/oxdata \
|
--start -c $USER -d $VENV/oxdata \
|
||||||
--exec $VENV/bin/gunicorn_django -- \
|
--exec $VENV/bin/gunicorn -- \
|
||||||
|
wsgi:application \
|
||||||
--bind 127.0.0.1:8087 \
|
--bind 127.0.0.1:8087 \
|
||||||
--workers 5 \
|
--workers 5 \
|
||||||
--max-requests 1000 \
|
--max-requests 1000 \
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>{{sitename}} API</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
|
||||||
<script type="text/javascript" src="/static/oxjs/build/Ox.js"></script>
|
|
||||||
<script type="text/javascript" src="/static/js/pandora.api.js"></script>
|
|
||||||
</head>
|
|
||||||
<body></body>
|
|
||||||
</html>
|
|
|
@ -1,10 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
|
||||||
|
|
||||||
from django.conf.urls.defaults import *
|
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = patterns("api.views",
|
|
||||||
(r'^$', 'api'),
|
|
||||||
)
|
|
||||||
|
|
|
@ -5,10 +5,7 @@ from __future__ import division
|
||||||
import os.path
|
import os.path
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import models
|
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.core.files.base import ContentFile
|
||||||
|
|
||||||
from lookup.models import MovieId
|
from lookup.models import MovieId
|
||||||
|
@ -43,6 +40,9 @@ def cover_path(url, filename):
|
||||||
name = "%s.%s" % (h, ext)
|
name = "%s.%s" % (h, ext)
|
||||||
return os.path.join('covers', h[:2], h[2:4], h[4:6], name)
|
return os.path.join('covers', h[:2], h[2:4], h[4:6], name)
|
||||||
|
|
||||||
|
def covercache_image_path(i, f):
|
||||||
|
return cover_path(i.url.encode('utf-8'), f)
|
||||||
|
|
||||||
class CoverCache(models.Model):
|
class CoverCache(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("isbn", "url")
|
unique_together = ("isbn", "url")
|
||||||
|
@ -54,7 +54,7 @@ class CoverCache(models.Model):
|
||||||
url = models.CharField(max_length=1024)
|
url = models.CharField(max_length=1024)
|
||||||
site = models.CharField(max_length=255)
|
site = models.CharField(max_length=255)
|
||||||
site_id = models.CharField(max_length=42)
|
site_id = models.CharField(max_length=42)
|
||||||
image = models.ImageField(max_length=255, upload_to=lambda i, f: cover_path(i.url.encode('utf-8'), f))
|
image = models.ImageField(max_length=255, upload_to=covercache_image_path)
|
||||||
status = models.CharField(max_length=1024, default='200')
|
status = models.CharField(max_length=1024, default='200')
|
||||||
failed = models.BooleanField(default=False)
|
failed = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
@ -89,10 +89,13 @@ class CoverCache(models.Model):
|
||||||
self.image.delete()
|
self.image.delete()
|
||||||
return self.image
|
return self.image
|
||||||
|
|
||||||
|
def cover_image_path(i, f):
|
||||||
|
return cover_path('upload/%s' % i.id, f)
|
||||||
|
|
||||||
class Cover(models.Model):
|
class Cover(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
isbn = models.ForeignKey(MovieId, related_name='cover')
|
isbn = models.ForeignKey(MovieId, related_name='cover')
|
||||||
cover = models.ImageField(max_length=255, upload_to=lambda i, f: cover_path('upload/%s' % i.id, f))
|
cover = models.ImageField(max_length=255, upload_to=cover_image_path)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from django.conf.urls.defaults import *
|
from django.conf.urls import url
|
||||||
|
|
||||||
urlpatterns = patterns('oxdata.cover.views',
|
import views
|
||||||
(r'^$', 'cover'),
|
|
||||||
)
|
urlpatterns = [
|
||||||
|
url(r'^$', views.cover),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
import os.path
|
|
||||||
from django.db import models
|
|
||||||
from django.db.models import Q
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
|
|
||||||
from django.template import RequestContext
|
|
||||||
|
|
||||||
from ox.django.shortcuts import render_to_json_response
|
from oxdjango.shortcuts import render_to_json_response
|
||||||
|
|
||||||
import models
|
import models
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
import os
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from ox import find_re
|
|
||||||
import ox.web.criterion
|
import ox.web.criterion
|
||||||
import ox.web.imdb
|
import ox.web.imdb
|
||||||
import ox.web.impawards
|
import ox.web.impawards
|
||||||
|
|
||||||
import models
|
import models
|
||||||
from oxdata.poster.models import PosterCache
|
from poster.models import PosterCache
|
||||||
import modules
|
import modules
|
||||||
|
|
||||||
def addPoster(m, url, site, site_id):
|
def addPoster(m, url, site, site_id):
|
||||||
|
|
|
@ -1,78 +1,38 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.4 on 2016-03-06 10:11
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from south.db import db
|
from django.db import migrations, models
|
||||||
from django.db import models
|
|
||||||
from oxdata.lookup.models import *
|
|
||||||
|
|
||||||
class Migration:
|
|
||||||
|
|
||||||
def forwards(self, orm):
|
|
||||||
|
|
||||||
# Adding model 'MovieId'
|
|
||||||
db.create_table('lookup_movieid', (
|
|
||||||
('id', orm['lookup.MovieId:id']),
|
|
||||||
('created', orm['lookup.MovieId:created']),
|
|
||||||
('modified', orm['lookup.MovieId:modified']),
|
|
||||||
('title', orm['lookup.MovieId:title']),
|
|
||||||
('year', orm['lookup.MovieId:year']),
|
|
||||||
('director', orm['lookup.MovieId:director']),
|
|
||||||
('series_title', orm['lookup.MovieId:series_title']),
|
|
||||||
('episode_title', orm['lookup.MovieId:episode_title']),
|
|
||||||
('season', orm['lookup.MovieId:season']),
|
|
||||||
('episode', orm['lookup.MovieId:episode']),
|
|
||||||
('oxdb_id', orm['lookup.MovieId:oxdb_id']),
|
|
||||||
('imdb_id', orm['lookup.MovieId:imdb_id']),
|
|
||||||
('amg_id', orm['lookup.MovieId:amg_id']),
|
|
||||||
('wikipedia_id', orm['lookup.MovieId:wikipedia_id']),
|
|
||||||
('criterion_id', orm['lookup.MovieId:criterion_id']),
|
|
||||||
('impawards_id', orm['lookup.MovieId:impawards_id']),
|
|
||||||
))
|
|
||||||
db.send_create_signal('lookup', ['MovieId'])
|
|
||||||
|
|
||||||
# Adding model 'Karagarga'
|
|
||||||
db.create_table('lookup_karagarga', (
|
|
||||||
('id', orm['lookup.Karagarga:id']),
|
|
||||||
('movie_id', orm['lookup.Karagarga:movie_id']),
|
|
||||||
('karagarga_id', orm['lookup.Karagarga:karagarga_id']),
|
|
||||||
))
|
|
||||||
db.send_create_signal('lookup', ['Karagarga'])
|
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
def backwards(self, orm):
|
initial = True
|
||||||
|
|
||||||
# Deleting model 'MovieId'
|
dependencies = [
|
||||||
db.delete_table('lookup_movieid')
|
]
|
||||||
|
|
||||||
# Deleting model 'Karagarga'
|
operations = [
|
||||||
db.delete_table('lookup_karagarga')
|
migrations.CreateModel(
|
||||||
|
name='MovieId',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
models = {
|
('created', models.DateTimeField(auto_now_add=True)),
|
||||||
'lookup.karagarga': {
|
('modified', models.DateTimeField(auto_now=True)),
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
('title', models.CharField(blank=True, default=b'', max_length=1000)),
|
||||||
'karagarga_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
|
('year', models.CharField(blank=True, default=b'', max_length=4)),
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'karagarga_ids'", 'to': "orm['lookup.MovieId']"})
|
('director', models.CharField(blank=True, default=b'', max_length=1000)),
|
||||||
},
|
('series_title', models.CharField(blank=True, default=b'', max_length=1000)),
|
||||||
'lookup.movieid': {
|
('episode_title', models.CharField(blank=True, default=b'', max_length=1000)),
|
||||||
'amg_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
('season', models.IntegerField(default=-1)),
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
('episode', models.IntegerField(default=-1)),
|
||||||
'criterion_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
('oxdb_id', models.CharField(blank=True, default=None, max_length=42, null=True, unique=True)),
|
||||||
'director': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
('imdb_id', models.CharField(blank=True, default=None, max_length=7, null=True, unique=True)),
|
||||||
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
('amg_id', models.IntegerField(blank=True, default=None, null=True, unique=True)),
|
||||||
'episode_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
('archiveorg_id', models.CharField(blank=True, default=None, max_length=255, null=True, unique=True)),
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
('wikipedia_id', models.CharField(blank=True, default=None, max_length=255, null=True, unique=True)),
|
||||||
'imdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '7', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
('criterion_id', models.IntegerField(blank=True, default=None, null=True, unique=True)),
|
||||||
'impawards_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
('impawards_id', models.CharField(blank=True, default=None, max_length=255, null=True, unique=True)),
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
],
|
||||||
'oxdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '42', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
),
|
||||||
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
]
|
||||||
'series_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'wikipedia_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'year': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '4', 'blank': 'True'})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_apps = ['lookup']
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
# encoding: utf-8
|
|
||||||
import datetime
|
|
||||||
from south.db import db
|
|
||||||
from south.v2 import SchemaMigration
|
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
class Migration(SchemaMigration):
|
|
||||||
|
|
||||||
def forwards(self, orm):
|
|
||||||
|
|
||||||
# Deleting model 'karagarga'
|
|
||||||
db.delete_table('lookup_karagarga')
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
|
||||||
|
|
||||||
# Adding model 'karagarga'
|
|
||||||
db.create_table('lookup_karagarga', (
|
|
||||||
('movie_id', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='karagarga_ids', to=orm['lookup.MovieId'])),
|
|
||||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
|
||||||
('karagarga_id', self.gf('django.db.models.fields.IntegerField')(unique=True)),
|
|
||||||
))
|
|
||||||
db.send_create_signal('lookup', ['karagarga'])
|
|
||||||
|
|
||||||
|
|
||||||
models = {
|
|
||||||
'lookup.movieid': {
|
|
||||||
'Meta': {'object_name': 'MovieId'},
|
|
||||||
'amg_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'criterion_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'director': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
|
||||||
'episode_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'imdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '7', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'impawards_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'oxdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '42', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
|
||||||
'series_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'wikipedia_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'year': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '4', 'blank': 'True'})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_apps = ['lookup']
|
|
|
@ -1,16 +1,12 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
import os
|
import os
|
||||||
import hashlib
|
|
||||||
from urllib import quote
|
from urllib import quote
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q, Max
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
from ox.normalize import canonical_name, normalize_path, strip_accents
|
from ox.normalize import canonical_name
|
||||||
from ox import strip_tags
|
|
||||||
import ox.web.archive
|
import ox.web.archive
|
||||||
import ox.web.imdb
|
import ox.web.imdb
|
||||||
import ox.web.wikipedia
|
import ox.web.wikipedia
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
from django.conf.urls.defaults import *
|
from django.conf.urls import url
|
||||||
|
|
||||||
urlpatterns = patterns('oxdata.lookup.views',
|
import views
|
||||||
(r'^$', 'ids'),
|
|
||||||
(r'^urls$', 'urls'),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', views.ids),
|
||||||
|
url(r'^urls$', views.urls),
|
||||||
|
]
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
import os.path
|
from oxdjango.shortcuts import render_to_json_response, json_response
|
||||||
from django.db import models
|
from oxdjango.api import actions
|
||||||
from django.db.models import Q
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
|
|
||||||
from ox.django.shortcuts import render_to_json_response, json_response
|
|
||||||
from ox.utils import json
|
|
||||||
from api.actions import actions
|
|
||||||
|
|
||||||
import models
|
import models
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
root_dir = os.path.normpath(os.path.abspath(os.path.dirname(__file__)))
|
root_dir = os.path.normpath(os.path.abspath(os.path.dirname(__file__)))
|
||||||
os.chdir(root_dir)
|
os.chdir(root_dir)
|
||||||
|
@ -8,13 +9,8 @@ os.chdir(root_dir)
|
||||||
activate_this = os.path.join(root_dir, '..', 'bin', 'activate_this.py')
|
activate_this = os.path.join(root_dir, '..', 'bin', 'activate_this.py')
|
||||||
execfile(activate_this, dict(__file__=activate_this))
|
execfile(activate_this, dict(__file__=activate_this))
|
||||||
|
|
||||||
from django.core.management import execute_manager
|
|
||||||
try:
|
|
||||||
import settings # Assumed to be in the same directory.
|
|
||||||
except ImportError:
|
|
||||||
import sys
|
|
||||||
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
execute_manager(settings)
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
execute_from_command_line(sys.argv)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import base64
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import ox
|
import ox
|
||||||
from ox.django.fields import DictField
|
from oxdjango.fields import DictField
|
||||||
|
|
||||||
from lookup.models import get_movie_id
|
from lookup.models import get_movie_id
|
||||||
from poster.models import getPosters
|
from poster.models import getPosters
|
||||||
|
@ -238,10 +238,11 @@ def get_new_ids(timeout=-1):
|
||||||
ids = re.compile('<loc>http://www.imdb.com/title/tt(\d{7})/combined</loc>').findall(s)
|
ids = re.compile('<loc>http://www.imdb.com/title/tt(\d{7})/combined</loc>').findall(s)
|
||||||
added = 0
|
added = 0
|
||||||
for i in frozenset(ids) - known_ids:
|
for i in frozenset(ids) - known_ids:
|
||||||
m = Imdb(imdb=i)
|
m, created = Imdb.objects.get_or_create(imdb=i)
|
||||||
m.update()
|
m.update()
|
||||||
print m
|
print m
|
||||||
added += 1
|
if created:
|
||||||
|
added += 1
|
||||||
if added:
|
if added:
|
||||||
print url, added
|
print url, added
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from ox.django.shortcuts import render_to_json_response, json_response
|
from oxdjango.shortcuts import render_to_json_response, json_response
|
||||||
import ox.web.imdb
|
import ox.web.imdb
|
||||||
|
|
||||||
from api.actions import actions
|
from oxdjango.api import actions
|
||||||
import models
|
import models
|
||||||
|
|
||||||
def getId(request, data):
|
def getId(request, data):
|
||||||
|
|
1
oxdata/oxdjango/api/__init__.py
Normal file
1
oxdata/oxdjango/api/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
from actions import actions
|
|
@ -1,17 +1,16 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
import sys
|
from __future__ import division, with_statement
|
||||||
import inspect
|
import inspect
|
||||||
|
import sys
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from ox.django.shortcuts import render_to_json_response, json_response
|
from ..shortcuts import render_to_json_response, json_response
|
||||||
from ox.utils import json
|
|
||||||
|
|
||||||
|
|
||||||
def autodiscover():
|
def autodiscover():
|
||||||
#register api actions from all installed apps
|
# Register api actions from all installed apps
|
||||||
from django.utils.importlib import import_module
|
from importlib import import_module
|
||||||
from django.utils.module_loading import module_has_submodule
|
from django.utils.module_loading import module_has_submodule
|
||||||
for app in settings.INSTALLED_APPS:
|
for app in settings.INSTALLED_APPS:
|
||||||
if app != 'api':
|
if app != 'api':
|
||||||
|
@ -50,62 +49,75 @@ def trim(docstring):
|
||||||
|
|
||||||
class ApiActions(dict):
|
class ApiActions(dict):
|
||||||
properties = {}
|
properties = {}
|
||||||
|
versions = {}
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
def api(request, data):
|
def api(request, data):
|
||||||
'''
|
'''
|
||||||
returns list of all known api actions
|
Returns a list of all api actions
|
||||||
param data {
|
takes {
|
||||||
docs: bool
|
code: boolean, // if true, return source code (optional)
|
||||||
}
|
docs: boolean // if true, return doc strings (optional)
|
||||||
if docs is true, action properties contain docstrings
|
}
|
||||||
return {
|
returns {
|
||||||
status: {'code': int, 'text': string},
|
actions: {
|
||||||
data: {
|
name: {
|
||||||
actions: {
|
cache: boolean, // if false, don't cache results
|
||||||
'api': {
|
code: string, // source code
|
||||||
cache: true,
|
doc: string // doc strings
|
||||||
doc: 'recursion'
|
},
|
||||||
},
|
... // more actions
|
||||||
'hello': {
|
|
||||||
cache: true,
|
|
||||||
..
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
'''
|
'''
|
||||||
docs = data.get('docs', False)
|
docs = data.get('docs', False)
|
||||||
code = data.get('code', False)
|
code = data.get('code', False)
|
||||||
_actions = self.keys()
|
version = getattr(request, 'version', None)
|
||||||
|
if version:
|
||||||
|
_actions = self.versions.get(version, {}).keys()
|
||||||
|
_actions = list(set(_actions + self.keys()))
|
||||||
|
else:
|
||||||
|
_actions = self.keys()
|
||||||
_actions.sort()
|
_actions.sort()
|
||||||
actions = {}
|
actions = {}
|
||||||
for a in _actions:
|
for a in _actions:
|
||||||
actions[a] = self.properties[a]
|
actions[a] = self.properties[a]
|
||||||
if docs:
|
if docs:
|
||||||
actions[a]['doc'] = self.doc(a)
|
actions[a]['doc'] = self.doc(a, version)
|
||||||
if code:
|
if code:
|
||||||
actions[a]['code'] = self.code(a)
|
actions[a]['code'] = self.code(a, version)
|
||||||
response = json_response({'actions': actions})
|
response = json_response({'actions': actions})
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
self.register(api)
|
self.register(api)
|
||||||
|
|
||||||
def doc(self, f):
|
def doc(self, name, version=None):
|
||||||
return trim(self[f].__doc__)
|
if version:
|
||||||
|
f = self.versions[version].get(name, self.get(name))
|
||||||
|
else:
|
||||||
|
f = self[name]
|
||||||
|
return trim(f.__doc__)
|
||||||
|
|
||||||
def code(self, name):
|
def code(self, name, version=None):
|
||||||
f = self[name]
|
if version:
|
||||||
|
f = self.versions[version].get(name, self.get(name))
|
||||||
|
else:
|
||||||
|
f = self[name]
|
||||||
if name != 'api' and hasattr(f, 'func_closure') and f.func_closure:
|
if name != 'api' and hasattr(f, 'func_closure') and f.func_closure:
|
||||||
f = f.func_closure[0].cell_contents
|
fc = filter(lambda c: hasattr(c.cell_contents, '__call__'), f.func_closure)
|
||||||
|
f = fc[len(fc)-1].cell_contents
|
||||||
info = f.func_code.co_filename[len(settings.PROJECT_ROOT)+1:]
|
info = f.func_code.co_filename[len(settings.PROJECT_ROOT)+1:]
|
||||||
info = u'%s:%s' % (info, f.func_code.co_firstlineno)
|
info = u'%s:%s' % (info, f.func_code.co_firstlineno)
|
||||||
return info, trim(inspect.getsource(f))
|
return info, trim(inspect.getsource(f))
|
||||||
|
|
||||||
def register(self, method, action=None, cache=True):
|
def register(self, method, action=None, cache=True, version=None):
|
||||||
if not action:
|
if not action:
|
||||||
action = method.func_name
|
action = method.func_name
|
||||||
self[action] = method
|
if version:
|
||||||
|
if not version in self.versions:
|
||||||
|
self.versions[version] = {}
|
||||||
|
self.versions[version][action] = method
|
||||||
|
else:
|
||||||
|
self[action] = method
|
||||||
self.properties[action] = {'cache': cache}
|
self.properties[action] = {'cache': cache}
|
||||||
|
|
||||||
def unregister(self, action):
|
def unregister(self, action):
|
||||||
|
@ -114,3 +126,10 @@ class ApiActions(dict):
|
||||||
|
|
||||||
actions = ApiActions()
|
actions = ApiActions()
|
||||||
|
|
||||||
|
def error(request, data):
|
||||||
|
'''
|
||||||
|
This action is used to test API error codes. It should return a 503 error.
|
||||||
|
'''
|
||||||
|
success = error_is_success
|
||||||
|
return render_to_json_response({})
|
||||||
|
actions.register(error)
|
13
oxdata/oxdjango/api/urls.py
Normal file
13
oxdata/oxdjango/api/urls.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
import views
|
||||||
|
|
||||||
|
import actions
|
||||||
|
actions.autodiscover()
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', views.api),
|
||||||
|
]
|
|
@ -2,20 +2,16 @@
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
from __future__ import division, with_statement
|
from __future__ import division, with_statement
|
||||||
|
|
||||||
import os
|
import json
|
||||||
import copy
|
|
||||||
|
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Max, Sum
|
|
||||||
|
|
||||||
from ox.django.shortcuts import render_to_json_response, json_response
|
from ..shortcuts import render_to_json_response, json_response
|
||||||
from ox.utils import json
|
|
||||||
|
|
||||||
from actions import actions
|
from actions import actions
|
||||||
|
|
||||||
|
|
||||||
def api(request):
|
def api(request):
|
||||||
if request.META['REQUEST_METHOD'] == "OPTIONS":
|
if request.META['REQUEST_METHOD'] == "OPTIONS":
|
||||||
response = render_to_json_response({'status': {'code': 200,
|
response = render_to_json_response({'status': {'code': 200,
|
||||||
|
@ -30,8 +26,11 @@ def api(request):
|
||||||
for f in sorted(methods):
|
for f in sorted(methods):
|
||||||
api.append({'name': f,
|
api.append({'name': f,
|
||||||
'doc': actions.doc(f).replace('\n', '<br>\n')})
|
'doc': actions.doc(f).replace('\n', '<br>\n')})
|
||||||
context = RequestContext(request, {'api': api,
|
context = RequestContext(request, {
|
||||||
'sitename': settings.SITENAME})
|
'api': api,
|
||||||
|
'settings': settings,
|
||||||
|
'sitename': settings.SITENAME
|
||||||
|
})
|
||||||
return render_to_response('api.html', context)
|
return render_to_response('api.html', context)
|
||||||
if request.META.get('CONTENT_TYPE') == 'application/json':
|
if request.META.get('CONTENT_TYPE') == 'application/json':
|
||||||
r = json.loads(request.body)
|
r = json.loads(request.body)
|
||||||
|
@ -40,8 +39,11 @@ def api(request):
|
||||||
else:
|
else:
|
||||||
action = request.POST['action']
|
action = request.POST['action']
|
||||||
data = json.loads(request.POST.get('data', '{}'))
|
data = json.loads(request.POST.get('data', '{}'))
|
||||||
|
version = getattr(request, 'version', None)
|
||||||
f = actions.get(action)
|
if version:
|
||||||
|
f = actions.versions.get(version, {}).get(action, actions.get(action))
|
||||||
|
else:
|
||||||
|
f = actions.get(action)
|
||||||
if f:
|
if f:
|
||||||
response = f(request, data)
|
response = f(request, data)
|
||||||
else:
|
else:
|
||||||
|
@ -50,14 +52,3 @@ def api(request):
|
||||||
response['Access-Control-Allow-Origin'] = '*'
|
response['Access-Control-Allow-Origin'] = '*'
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def init(request, data):
|
|
||||||
return render_to_json_response(json_response())
|
|
||||||
actions.register(init)
|
|
||||||
|
|
||||||
def error(request, data):
|
|
||||||
'''
|
|
||||||
this action is used to test api error codes, it should return a 503 error
|
|
||||||
'''
|
|
||||||
success = error_is_success
|
|
||||||
return render_to_json_response({})
|
|
||||||
actions.register(error)
|
|
32
oxdata/oxdjango/decorators.py
Normal file
32
oxdata/oxdjango/decorators.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
|
||||||
|
try:
|
||||||
|
from django.contrib.auth.decorators import wraps
|
||||||
|
except:
|
||||||
|
from django.utils.functional import wraps
|
||||||
|
from shortcuts import render_to_json_response
|
||||||
|
|
||||||
|
def login_required_json(function=None):
|
||||||
|
"""
|
||||||
|
Decorator for views that checks that the user is logged in
|
||||||
|
return json error if not logged in.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _wrapped_view(request, *args, **kwargs):
|
||||||
|
if request.user.is_authenticated():
|
||||||
|
return function(request, *args, **kwargs)
|
||||||
|
return render_to_json_response({'status': {'code': 401, 'text': 'login required'}})
|
||||||
|
return wraps(function)(_wrapped_view)
|
||||||
|
|
||||||
|
def admin_required_json(function=None):
|
||||||
|
"""
|
||||||
|
Decorator for views that checks that the user is logged in
|
||||||
|
return json error if not logged in.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _wrapped_view(request, *args, **kwargs):
|
||||||
|
if request.user.is_authenticated() and request.user.profile.get_level() == 'admin':
|
||||||
|
return function(request, *args, **kwargs)
|
||||||
|
return render_to_json_response({'status': {'code': 403, 'text': 'permission denied'}})
|
||||||
|
return wraps(function)(_wrapped_view)
|
99
oxdata/oxdjango/fields.py
Normal file
99
oxdata/oxdjango/fields.py
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
|
import copy
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.utils import datetime_safe
|
||||||
|
from six import string_types
|
||||||
|
|
||||||
|
from ox.utils import json
|
||||||
|
|
||||||
|
|
||||||
|
def to_json(python_object):
|
||||||
|
if isinstance(python_object, datetime.datetime):
|
||||||
|
if python_object.year < 1900:
|
||||||
|
tt = python_object.timetuple()
|
||||||
|
value = '%d-%02d-%02dT%02d:%02d%02dZ' % tuple(list(tt)[:6])
|
||||||
|
else:
|
||||||
|
value = python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
return {'__class__': 'datetime.datetime',
|
||||||
|
'__value__': value}
|
||||||
|
if isinstance(python_object, datetime_safe.datetime):
|
||||||
|
return {'__class__': 'datetime.datetime',
|
||||||
|
'__value__': python_object.strftime('%Y-%m-%dT%H:%M:%SZ')}
|
||||||
|
if isinstance(python_object, time.struct_time):
|
||||||
|
return {'__class__': 'time.asctime',
|
||||||
|
'__value__': time.asctime(python_object)}
|
||||||
|
try:
|
||||||
|
if isinstance(python_object, bytes):
|
||||||
|
return {'__class__': 'bytes',
|
||||||
|
'__value__': list(python_object)}
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
raise TypeError(repr(python_object) + ' is not JSON serializable')
|
||||||
|
|
||||||
|
def from_json(json_object):
|
||||||
|
if '__class__' in json_object:
|
||||||
|
if json_object['__class__'] == 'bytes':
|
||||||
|
return bytes(json_object['__value__'])
|
||||||
|
if json_object['__class__'] == 'datetime_safe.datetime' \
|
||||||
|
or json_object['__class__'] == 'datetime.datetime':
|
||||||
|
return datetime_safe.datetime.strptime(json_object['__value__'], '%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
if json_object['__class__'] == 'time.asctime':
|
||||||
|
return time.strptime(json_object['__value__'])
|
||||||
|
return json_object
|
||||||
|
|
||||||
|
class DictField(models.TextField):
|
||||||
|
_type = dict
|
||||||
|
|
||||||
|
def loads(self, value):
|
||||||
|
return json.loads(value, object_hook=from_json)
|
||||||
|
|
||||||
|
def dumps(self, obj):
|
||||||
|
return json.dumps(obj, default=to_json, ensure_ascii=False)
|
||||||
|
|
||||||
|
def from_db_value(self, value, expression, connection, context):
|
||||||
|
if value is None:
|
||||||
|
return value
|
||||||
|
if isinstance(value, self._type):
|
||||||
|
return value
|
||||||
|
try:
|
||||||
|
value = self.loads(value)
|
||||||
|
except:
|
||||||
|
raise Exception('failed to parse value: %s' % value)
|
||||||
|
if value is not None:
|
||||||
|
assert isinstance(value, self._type)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_prep_value(self, value):
|
||||||
|
if isinstance(value, self._type):
|
||||||
|
value = self.dumps(value)
|
||||||
|
if value is not None:
|
||||||
|
assert isinstance(value, string_types)
|
||||||
|
value = models.TextField.get_prep_value(self, value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_default(self):
|
||||||
|
if self.has_default():
|
||||||
|
if callable(self.default):
|
||||||
|
return self.default()
|
||||||
|
return copy.deepcopy(self.default)
|
||||||
|
return super(DictField, self).get_default()
|
||||||
|
|
||||||
|
class TupleField(DictField):
|
||||||
|
_type = (tuple, list)
|
||||||
|
|
||||||
|
def loads(self, value):
|
||||||
|
value = DictField.loads(self, value)
|
||||||
|
if isinstance(value, list):
|
||||||
|
value = tuple(value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
try:
|
||||||
|
from south.modelsinspector import add_introspection_rules
|
||||||
|
add_introspection_rules([], ["^oxdjango\.fields\.DictField"])
|
||||||
|
add_introspection_rules([], ["^oxdjango\.fields\.TupleField"])
|
||||||
|
except:
|
||||||
|
pass
|
58
oxdata/oxdjango/http.py
Normal file
58
oxdata/oxdjango/http.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
import os
|
||||||
|
import mimetypes
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from six.moves.urllib.parse import quote
|
||||||
|
|
||||||
|
from django.http import HttpResponse, Http404
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
def HttpFileResponse(path, content_type=None, filename=None):
|
||||||
|
if not os.path.exists(path):
|
||||||
|
raise Http404
|
||||||
|
if not content_type:
|
||||||
|
content_type = mimetypes.guess_type(path)[0]
|
||||||
|
if not content_type:
|
||||||
|
content_type = 'application/octet-stream'
|
||||||
|
|
||||||
|
if getattr(settings, 'XACCELREDIRECT', False):
|
||||||
|
response = HttpResponse()
|
||||||
|
response['Content-Length'] = os.stat(path).st_size
|
||||||
|
|
||||||
|
for PREFIX in ('STATIC', 'MEDIA'):
|
||||||
|
root = getattr(settings, PREFIX+'_ROOT', '')
|
||||||
|
url = getattr(settings, PREFIX+'_URL', '')
|
||||||
|
if root and path.startswith(root):
|
||||||
|
path = url + path[len(root)+1:]
|
||||||
|
if not isinstance(path, bytes):
|
||||||
|
path = path.encode('utf-8')
|
||||||
|
response['X-Accel-Redirect'] = path
|
||||||
|
if content_type:
|
||||||
|
response['Content-Type'] = content_type
|
||||||
|
elif getattr(settings, 'XSENDFILE', False):
|
||||||
|
response = HttpResponse()
|
||||||
|
if not isinstance(path, bytes):
|
||||||
|
path = path.encode('utf-8')
|
||||||
|
response['X-Sendfile'] = path
|
||||||
|
if content_type:
|
||||||
|
response['Content-Type'] = content_type
|
||||||
|
response['Content-Length'] = os.stat(path).st_size
|
||||||
|
else:
|
||||||
|
response = HttpResponse(open(path), content_type=content_type)
|
||||||
|
if filename:
|
||||||
|
if not isinstance(filename, bytes):
|
||||||
|
filename = filename.encode('utf-8')
|
||||||
|
response['Content-Disposition'] = "attachment; filename*=UTF=8''%s" % quote(filename)
|
||||||
|
|
||||||
|
response['Expires'] = datetime.strftime(datetime.utcnow() + timedelta(days=1), "%a, %d-%b-%Y %H:%M:%S GMT")
|
||||||
|
|
||||||
|
def allow_access():
|
||||||
|
for key in ('X-Accel-Redirect', 'X-Sendfile'):
|
||||||
|
if key in response:
|
||||||
|
del response[key]
|
||||||
|
response['Access-Control-Allow-Origin'] = '*'
|
||||||
|
response.allow_access = allow_access
|
||||||
|
return response
|
||||||
|
|
15
oxdata/oxdjango/middleware.py
Normal file
15
oxdata/oxdjango/middleware.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
|
||||||
|
from .shortcuts import HttpErrorJson, render_to_json_response
|
||||||
|
|
||||||
|
class ExceptionMiddleware(object):
|
||||||
|
def process_exception(self, request, exception):
|
||||||
|
if isinstance(exception, HttpErrorJson):
|
||||||
|
return render_to_json_response(exception.response)
|
||||||
|
return None
|
||||||
|
|
||||||
|
class ChromeFrameMiddleware(object):
|
||||||
|
def process_response(self, request, response):
|
||||||
|
response['X-UA-Compatible'] = 'chrome=1'
|
||||||
|
return response
|
58
oxdata/oxdjango/query.py
Normal file
58
oxdata/oxdjango/query.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
|
||||||
|
from django.db.models.sql import Query
|
||||||
|
from django.db.models.sql.compiler import SQLCompiler
|
||||||
|
from django.db import connections
|
||||||
|
import django.db.models.query
|
||||||
|
|
||||||
|
'''
|
||||||
|
models.py:
|
||||||
|
-----------------------------------
|
||||||
|
from oxdjango.query import QuerySet
|
||||||
|
|
||||||
|
class Manager(models.Manager):
|
||||||
|
def get_query_set(self):
|
||||||
|
return QuerySet(self.model)
|
||||||
|
|
||||||
|
class Model(models.Model):
|
||||||
|
...
|
||||||
|
objects = Manager()
|
||||||
|
'''
|
||||||
|
|
||||||
|
class NullLastSQLCompiler(SQLCompiler):
|
||||||
|
|
||||||
|
def get_order_by(self):
|
||||||
|
result = super(NullLastSQLCompiler, self).get_order_by()
|
||||||
|
if self.query.nulls_last and result \
|
||||||
|
and self.connection.vendor == 'postgresql':
|
||||||
|
return [(expr, (sql + ' NULLS LAST', params, is_ref))
|
||||||
|
for (expr, (sql, params, is_ref)) in result]
|
||||||
|
return result
|
||||||
|
|
||||||
|
class NullsLastQuery(Query):
|
||||||
|
nulls_last = False
|
||||||
|
|
||||||
|
def clone(self, *args, **kwargs):
|
||||||
|
obj = super(NullsLastQuery, self).clone(*args, **kwargs)
|
||||||
|
obj.nulls_last = self.nulls_last
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def get_compiler(self, using=None, connection=None):
|
||||||
|
if using is None and connection is None:
|
||||||
|
raise ValueError("Need either using or connection")
|
||||||
|
if using:
|
||||||
|
connection = connections[using]
|
||||||
|
return NullLastSQLCompiler(self, connection, using)
|
||||||
|
|
||||||
|
class QuerySet(django.db.models.query.QuerySet):
|
||||||
|
|
||||||
|
def __init__(self, model=None, query=None, using=None, **kwargs):
|
||||||
|
super(QuerySet, self).__init__(model=model, query=query, using=None, **kwargs)
|
||||||
|
self.query = query or NullsLastQuery(self.model)
|
||||||
|
|
||||||
|
def order_by(self, *args, **kwargs):
|
||||||
|
nulls_last = kwargs.pop('nulls_last', False)
|
||||||
|
obj = super(QuerySet, self).order_by(*args, **kwargs)
|
||||||
|
obj.query.nulls_last = nulls_last
|
||||||
|
return obj
|
49
oxdata/oxdjango/shortcuts.py
Normal file
49
oxdata/oxdjango/shortcuts.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
from __future__ import print_function
|
||||||
|
import datetime
|
||||||
|
from django.utils import datetime_safe
|
||||||
|
from django.http import HttpResponse, Http404
|
||||||
|
import json
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
class HttpErrorJson(Http404):
|
||||||
|
def __init__(self, response):
|
||||||
|
self.response = response
|
||||||
|
|
||||||
|
def json_response(data=None, status=200, text='ok'):
|
||||||
|
if not data:
|
||||||
|
data = {}
|
||||||
|
return {'status': {'code': status, 'text': text}, 'data': data}
|
||||||
|
|
||||||
|
def _to_json(python_object):
|
||||||
|
if isinstance(python_object, datetime.datetime):
|
||||||
|
if python_object.year < 1900:
|
||||||
|
tt = python_object.timetuple()
|
||||||
|
return '%d-%02d-%02dT%02d:%02d%02dZ' % tuple(list(tt)[:6])
|
||||||
|
return python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
if isinstance(python_object, datetime_safe.datetime):
|
||||||
|
return python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
raise TypeError(u'%s %s is not JSON serializable' % (repr(python_object), type(python_object)))
|
||||||
|
|
||||||
|
def render_to_json_response(dictionary, content_type="text/json", status=200):
|
||||||
|
indent=None
|
||||||
|
if settings.DEBUG:
|
||||||
|
content_type = "text/javascript"
|
||||||
|
indent = 2
|
||||||
|
if getattr(settings, 'JSON_DEBUG', False):
|
||||||
|
print(json.dumps(dictionary, indent=2, default=_to_json, ensure_ascii=False).encode('utf-8'))
|
||||||
|
|
||||||
|
return HttpResponse(json.dumps(dictionary, indent=indent, default=_to_json,
|
||||||
|
ensure_ascii=False).encode('utf-8'), content_type=content_type, status=status)
|
||||||
|
|
||||||
|
def get_object_or_404_json(klass, *args, **kwargs):
|
||||||
|
from django.shortcuts import _get_queryset
|
||||||
|
queryset = _get_queryset(klass)
|
||||||
|
try:
|
||||||
|
return queryset.get(*args, **kwargs)
|
||||||
|
except queryset.model.DoesNotExist:
|
||||||
|
response = {'status': {'code': 404,
|
||||||
|
'text': '%s not found' % queryset.model._meta.object_name}}
|
||||||
|
raise HttpErrorJson(response)
|
||||||
|
|
47
oxdata/oxdjango/utils.py
Normal file
47
oxdata/oxdjango/utils.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
from django.http import HttpResponse,Http404
|
||||||
|
from django.core.servers.basehttp import FileWrapper
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
import mimetypes
|
||||||
|
import os
|
||||||
|
|
||||||
|
def basic_sendfile(fname,download_name=None):
|
||||||
|
if not os.path.exists(fname):
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
wrapper = FileWrapper(open(fname,"r"))
|
||||||
|
|
||||||
|
content_type = mimetypes.guess_type(fname)[0]
|
||||||
|
response = HttpResponse(wrapper, content_type=content_type)
|
||||||
|
response['Content-Length'] = os.path.getsize(fname)
|
||||||
|
|
||||||
|
if download_name:
|
||||||
|
response['Content-Disposition'] = "attachment; filename=%s"%download_name
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
def x_sendfile(fname,download_name=None):
|
||||||
|
if not os.path.exists(fname):
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
content_type = mimetypes.guess_type(fname)[0]
|
||||||
|
response = HttpResponse('', content_type=content_type)
|
||||||
|
response['Content-Length'] = os.path.getsize(fname)
|
||||||
|
response['X-Sendfile'] = fname
|
||||||
|
|
||||||
|
if download_name:
|
||||||
|
response['Content-Disposition'] = "attachment; filename=%s"%download_name
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
try:
|
||||||
|
__sendfile = getattr(settings,'SENDFILE',False) == 'x_sendfile'
|
||||||
|
except:
|
||||||
|
__sendfile = False
|
||||||
|
if __sendfile == 'x_sendfile':
|
||||||
|
sendfile = x_sendfile
|
||||||
|
else:
|
||||||
|
sendfile = basic_sendfile
|
||||||
|
|
|
@ -1,90 +1,38 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.4 on 2016-03-06 10:11
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from south.db import db
|
from django.db import migrations, models
|
||||||
from django.db import models
|
import django.db.models.deletion
|
||||||
from oxdata.poster.models import *
|
import poster.models
|
||||||
|
|
||||||
class Migration:
|
|
||||||
|
|
||||||
def forwards(self, orm):
|
|
||||||
|
|
||||||
# Adding model 'PosterCache'
|
|
||||||
db.create_table('poster_postercache', (
|
|
||||||
('id', orm['poster.PosterCache:id']),
|
|
||||||
('created', orm['poster.PosterCache:created']),
|
|
||||||
('modified', orm['poster.PosterCache:modified']),
|
|
||||||
('movie_id', orm['poster.PosterCache:movie_id']),
|
|
||||||
('url', orm['poster.PosterCache:url']),
|
|
||||||
('site', orm['poster.PosterCache:site']),
|
|
||||||
('site_id', orm['poster.PosterCache:site_id']),
|
|
||||||
('image', orm['poster.PosterCache:image']),
|
|
||||||
('failed', orm['poster.PosterCache:failed']),
|
|
||||||
))
|
|
||||||
db.send_create_signal('poster', ['PosterCache'])
|
|
||||||
|
|
||||||
# Adding model 'Poster'
|
|
||||||
db.create_table('poster_poster', (
|
|
||||||
('id', orm['poster.Poster:id']),
|
|
||||||
('created', orm['poster.Poster:created']),
|
|
||||||
('modified', orm['poster.Poster:modified']),
|
|
||||||
('movie_id', orm['poster.Poster:movie_id']),
|
|
||||||
('poster', orm['poster.Poster:poster']),
|
|
||||||
('upload', orm['poster.Poster:upload']),
|
|
||||||
('oxdb', orm['poster.Poster:oxdb']),
|
|
||||||
))
|
|
||||||
db.send_create_signal('poster', ['Poster'])
|
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
def backwards(self, orm):
|
initial = True
|
||||||
|
|
||||||
# Deleting model 'PosterCache'
|
dependencies = [
|
||||||
db.delete_table('poster_postercache')
|
('lookup', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
# Deleting model 'Poster'
|
operations = [
|
||||||
db.delete_table('poster_poster')
|
migrations.CreateModel(
|
||||||
|
name='PosterCache',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
models = {
|
('created', models.DateTimeField(auto_now_add=True)),
|
||||||
'lookup.movieid': {
|
('modified', models.DateTimeField(auto_now=True)),
|
||||||
'amg_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
('url', models.CharField(max_length=1024)),
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
('site', models.CharField(max_length=255)),
|
||||||
'criterion_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
('site_id', models.CharField(max_length=1024)),
|
||||||
'director': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
('image', models.ImageField(max_length=255, upload_to=poster.models.postercache_path)),
|
||||||
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
('status', models.CharField(default=b'200', max_length=1024)),
|
||||||
'episode_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
('failed', models.BooleanField(default=False)),
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
('movie_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='postercache', to='lookup.MovieId')),
|
||||||
'imdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '7', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
],
|
||||||
'impawards_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
),
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
migrations.AlterUniqueTogether(
|
||||||
'oxdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '42', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
name='postercache',
|
||||||
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
unique_together=set([('movie_id', 'url')]),
|
||||||
'series_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
),
|
||||||
'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
]
|
||||||
'wikipedia_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'year': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '4', 'blank': 'True'})
|
|
||||||
},
|
|
||||||
'poster.poster': {
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'poster'", 'to': "orm['lookup.MovieId']"}),
|
|
||||||
'oxdb': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'}),
|
|
||||||
'poster': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['poster.PosterCache']", 'blank': 'True'}),
|
|
||||||
'upload': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'})
|
|
||||||
},
|
|
||||||
'poster.postercache': {
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'postercache'", 'to': "orm['lookup.MovieId']"}),
|
|
||||||
'site': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
|
||||||
'site_id': ('django.db.models.fields.CharField', [], {'max_length': '42'}),
|
|
||||||
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_apps = ['poster']
|
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
# encoding: utf-8
|
|
||||||
import datetime
|
|
||||||
from south.db import db
|
|
||||||
from south.v2 import SchemaMigration
|
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
class Migration(SchemaMigration):
|
|
||||||
|
|
||||||
def forwards(self, orm):
|
|
||||||
|
|
||||||
# Adding field 'PosterCache.status'
|
|
||||||
db.add_column('poster_postercache', 'status', self.gf('django.db.models.fields.CharField')(default='200', max_length=1024), keep_default=False)
|
|
||||||
|
|
||||||
# Deleting field 'poster.upload'
|
|
||||||
db.delete_column('poster_poster', 'upload')
|
|
||||||
|
|
||||||
# Deleting field 'poster.oxdb'
|
|
||||||
db.delete_column('poster_poster', 'oxdb')
|
|
||||||
|
|
||||||
# Renaming column for 'Poster.poster' to match new field type.
|
|
||||||
db.rename_column('poster_poster', 'poster_id', 'poster')
|
|
||||||
# Changing field 'Poster.poster'
|
|
||||||
db.add_column('poster_poster', 'poster', self.gf('django.db.models.fields.files.ImageField')(max_length=255))
|
|
||||||
|
|
||||||
# Removing index on 'poster', fields ['poster']
|
|
||||||
db.delete_index('poster_poster', ['poster_id'])
|
|
||||||
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
|
||||||
|
|
||||||
# Deleting field 'PosterCache.status'
|
|
||||||
db.delete_column('poster_postercache', 'status')
|
|
||||||
|
|
||||||
# Adding field 'poster.upload'
|
|
||||||
db.add_column('poster_poster', 'upload', self.gf('django.db.models.fields.files.ImageField')(default=None, max_length=255), keep_default=False)
|
|
||||||
|
|
||||||
# Adding field 'poster.oxdb'
|
|
||||||
db.add_column('poster_poster', 'oxdb', self.gf('django.db.models.fields.files.ImageField')(default=None, max_length=255), keep_default=False)
|
|
||||||
|
|
||||||
# Renaming column for 'Poster.poster' to match new field type.
|
|
||||||
db.rename_column('poster_poster', 'poster', 'poster_id')
|
|
||||||
# Changing field 'Poster.poster'
|
|
||||||
db.alter_column('poster_poster', 'poster_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['poster.PosterCache'], blank=True))
|
|
||||||
|
|
||||||
# Adding index on 'poster', fields ['poster']
|
|
||||||
db.create_index('poster_poster', ['poster_id'])
|
|
||||||
|
|
||||||
|
|
||||||
models = {
|
|
||||||
'lookup.movieid': {
|
|
||||||
'Meta': {'object_name': 'MovieId'},
|
|
||||||
'amg_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'criterion_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'director': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
|
||||||
'episode_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'imdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '7', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'impawards_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'oxdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '42', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
|
||||||
'series_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'wikipedia_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'year': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '4', 'blank': 'True'})
|
|
||||||
},
|
|
||||||
'poster.poster': {
|
|
||||||
'Meta': {'object_name': 'Poster'},
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'poster'", 'to': "orm['lookup.MovieId']"}),
|
|
||||||
'poster': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'})
|
|
||||||
},
|
|
||||||
'poster.postercache': {
|
|
||||||
'Meta': {'object_name': 'PosterCache'},
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'postercache'", 'to': "orm['lookup.MovieId']"}),
|
|
||||||
'site': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
|
||||||
'site_id': ('django.db.models.fields.CharField', [], {'max_length': '42'}),
|
|
||||||
'status': ('django.db.models.fields.CharField', [], {'default': "'200'", 'max_length': '1024'}),
|
|
||||||
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_apps = ['poster']
|
|
|
@ -1,64 +0,0 @@
|
||||||
# encoding: utf-8
|
|
||||||
import datetime
|
|
||||||
from south.db import db
|
|
||||||
from south.v2 import SchemaMigration
|
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
class Migration(SchemaMigration):
|
|
||||||
|
|
||||||
def forwards(self, orm):
|
|
||||||
|
|
||||||
# Adding unique constraint on 'PosterCache', fields ['url']
|
|
||||||
db.create_unique('poster_postercache', ['url'])
|
|
||||||
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
|
||||||
|
|
||||||
# Removing unique constraint on 'PosterCache', fields ['url']
|
|
||||||
db.delete_unique('poster_postercache', ['url'])
|
|
||||||
|
|
||||||
|
|
||||||
models = {
|
|
||||||
'lookup.movieid': {
|
|
||||||
'Meta': {'object_name': 'MovieId'},
|
|
||||||
'amg_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'criterion_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'director': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
|
||||||
'episode_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'imdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '7', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'impawards_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'oxdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '42', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
|
||||||
'series_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'wikipedia_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'year': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '4', 'blank': 'True'})
|
|
||||||
},
|
|
||||||
'poster.poster': {
|
|
||||||
'Meta': {'object_name': 'Poster'},
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'poster'", 'to': "orm['lookup.MovieId']"}),
|
|
||||||
'poster': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'})
|
|
||||||
},
|
|
||||||
'poster.postercache': {
|
|
||||||
'Meta': {'object_name': 'PosterCache'},
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'postercache'", 'to': "orm['lookup.MovieId']"}),
|
|
||||||
'site': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
|
||||||
'site_id': ('django.db.models.fields.CharField', [], {'max_length': '42'}),
|
|
||||||
'status': ('django.db.models.fields.CharField', [], {'default': "'200'", 'max_length': '1024'}),
|
|
||||||
'url': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_apps = ['poster']
|
|
|
@ -1,70 +0,0 @@
|
||||||
# encoding: utf-8
|
|
||||||
import datetime
|
|
||||||
from south.db import db
|
|
||||||
from south.v2 import SchemaMigration
|
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
class Migration(SchemaMigration):
|
|
||||||
|
|
||||||
def forwards(self, orm):
|
|
||||||
|
|
||||||
# Removing unique constraint on 'PosterCache', fields ['url']
|
|
||||||
db.delete_unique('poster_postercache', ['url'])
|
|
||||||
|
|
||||||
# Adding unique constraint on 'PosterCache', fields ['url', 'movie_id']
|
|
||||||
db.create_unique('poster_postercache', ['url', 'movie_id_id'])
|
|
||||||
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
|
||||||
|
|
||||||
# Adding unique constraint on 'PosterCache', fields ['url']
|
|
||||||
db.create_unique('poster_postercache', ['url'])
|
|
||||||
|
|
||||||
# Removing unique constraint on 'PosterCache', fields ['url', 'movie_id']
|
|
||||||
db.delete_unique('poster_postercache', ['url', 'movie_id_id'])
|
|
||||||
|
|
||||||
|
|
||||||
models = {
|
|
||||||
'lookup.movieid': {
|
|
||||||
'Meta': {'object_name': 'MovieId'},
|
|
||||||
'amg_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'criterion_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'director': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
|
||||||
'episode_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'imdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '7', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'impawards_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'oxdb_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '42', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
|
|
||||||
'series_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
|
|
||||||
'wikipedia_id': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
|
|
||||||
'year': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '4', 'blank': 'True'})
|
|
||||||
},
|
|
||||||
'poster.poster': {
|
|
||||||
'Meta': {'object_name': 'Poster'},
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'poster'", 'to': "orm['lookup.MovieId']"}),
|
|
||||||
'poster': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'})
|
|
||||||
},
|
|
||||||
'poster.postercache': {
|
|
||||||
'Meta': {'unique_together': "(('movie_id', 'url'),)", 'object_name': 'PosterCache'},
|
|
||||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
|
||||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
|
||||||
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255'}),
|
|
||||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
|
||||||
'movie_id': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'postercache'", 'to': "orm['lookup.MovieId']"}),
|
|
||||||
'site': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
|
||||||
'site_id': ('django.db.models.fields.CharField', [], {'max_length': '42'}),
|
|
||||||
'status': ('django.db.models.fields.CharField', [], {'default': "'200'", 'max_length': '1024'}),
|
|
||||||
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_apps = ['poster']
|
|
|
@ -7,11 +7,7 @@ import hashlib
|
||||||
import socket
|
import socket
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import models
|
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
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
import ox.web.criterion
|
import ox.web.criterion
|
||||||
|
@ -21,7 +17,7 @@ import ox.web.impawards
|
||||||
import ox.web.apple
|
import ox.web.apple
|
||||||
import ox.web.piratecinema
|
import ox.web.piratecinema
|
||||||
|
|
||||||
from oxdata.lookup.models import MovieId
|
from lookup.models import MovieId
|
||||||
|
|
||||||
def getPosters(movie_id, url_prefix='', limit=lambda x, y: 0.3 < x/y < 1):
|
def getPosters(movie_id, url_prefix='', limit=lambda x, y: 0.3 < x/y < 1):
|
||||||
if not movie_id:
|
if not movie_id:
|
||||||
|
@ -55,6 +51,9 @@ def poster_path(url, filename):
|
||||||
name = "%s.%s" % (h, ext)
|
name = "%s.%s" % (h, ext)
|
||||||
return os.path.join('posters', h[:2], h[2:4], h[4:6], name)
|
return os.path.join('posters', h[:2], h[2:4], h[4:6], name)
|
||||||
|
|
||||||
|
def postercache_path(i, f):
|
||||||
|
return poster_path(i.url.encode('utf-8'), f)
|
||||||
|
|
||||||
class PosterCache(models.Model):
|
class PosterCache(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("movie_id", "url")
|
unique_together = ("movie_id", "url")
|
||||||
|
@ -66,7 +65,7 @@ class PosterCache(models.Model):
|
||||||
url = models.CharField(max_length=1024)
|
url = models.CharField(max_length=1024)
|
||||||
site = models.CharField(max_length=255)
|
site = models.CharField(max_length=255)
|
||||||
site_id = models.CharField(max_length=1024)
|
site_id = models.CharField(max_length=1024)
|
||||||
image = models.ImageField(max_length=255, upload_to=lambda i, f: poster_path(i.url.encode('utf-8'), f))
|
image = models.ImageField(max_length=255, upload_to=postercache_path)
|
||||||
status = models.CharField(max_length=1024, default='200')
|
status = models.CharField(max_length=1024, default='200')
|
||||||
failed = models.BooleanField(default=False)
|
failed = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from django.conf.urls.defaults import *
|
from django.conf.urls import url
|
||||||
|
|
||||||
urlpatterns = patterns('oxdata.poster.views',
|
import views
|
||||||
(r'^$', 'poster'),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', views.poster),
|
||||||
|
]
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
import os.path
|
from oxdjango.shortcuts import render_to_json_response
|
||||||
from django.db import models
|
|
||||||
from django.db.models import Q
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
|
|
||||||
from django.template import RequestContext
|
|
||||||
|
|
||||||
from ox.django.shortcuts import render_to_json_response
|
from lookup.views import get_movie_id
|
||||||
from oxdata.lookup.models import MovieId
|
|
||||||
|
|
||||||
from oxdata.lookup.views import get_movie_id
|
|
||||||
|
|
||||||
import models
|
import models
|
||||||
|
|
||||||
|
|
||||||
def poster(request):
|
def poster(request):
|
||||||
movie_id = get_movie_id(request)
|
movie_id = get_movie_id(request)
|
||||||
json = models.getPosters(movie_id, request.build_absolute_uri('/'))
|
json = models.getPosters(movie_id, request.build_absolute_uri('/'))
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
# Django settings for oxdata project.
|
# Django settings for oxdata project.
|
||||||
import os
|
import os
|
||||||
from os.path import join
|
from os.path import join, normpath, dirname
|
||||||
|
import djcelery
|
||||||
|
djcelery.setup_loader()
|
||||||
|
|
||||||
SITENAME = 'oxdata'
|
SITENAME = 'oxdata'
|
||||||
|
|
||||||
PROJECT_ROOT = os.path.normpath(os.path.dirname(__file__))
|
BASE_DIR = PROJECT_ROOT = normpath(dirname(__file__))
|
||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
TEMPLATE_DEBUG = DEBUG
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
@ -30,7 +32,7 @@ DATABASES = {
|
||||||
# although not all choices may be available on all operating systems.
|
# although not all choices may be available on all operating systems.
|
||||||
# If running in a Windows environment this must be set to the same as your
|
# If running in a Windows environment this must be set to the same as your
|
||||||
# system time zone.
|
# system time zone.
|
||||||
TIME_ZONE = 'Europe/Berlin'
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
# Language code for this installation. All choices can be found here:
|
# Language code for this installation. All choices can be found here:
|
||||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||||
|
@ -58,6 +60,23 @@ STATIC_ROOT = join(PROJECT_ROOT, 'static')
|
||||||
DATA_ROOT = join(PROJECT_ROOT, 'data')
|
DATA_ROOT = join(PROJECT_ROOT, 'data')
|
||||||
CACHE_ROOT = join(PROJECT_ROOT, 'cache')
|
CACHE_ROOT = join(PROJECT_ROOT, 'cache')
|
||||||
|
|
||||||
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
|
# Additional locations of static files
|
||||||
|
STATICFILES_DIRS = (
|
||||||
|
# Put strings here, like "/home/html/static" or "C:/www/django/static".
|
||||||
|
# Always use forward slashes, even on Windows.
|
||||||
|
# Don't forget to use absolute paths, not relative paths.
|
||||||
|
)
|
||||||
|
|
||||||
|
# List of finder classes that know how to find static files in
|
||||||
|
# various locations.
|
||||||
|
STATICFILES_FINDERS = (
|
||||||
|
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||||
|
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||||
|
#'django.contrib.staticfiles.finders.DefaultStorageFinder',
|
||||||
|
)
|
||||||
|
|
||||||
os.environ['oxCACHE'] = 'fs:' + CACHE_ROOT
|
os.environ['oxCACHE'] = 'fs:' + CACHE_ROOT
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,38 +90,45 @@ MEDIA_URL = '/media/'
|
||||||
# Examples: "http://foo.com/media/", "/media/".
|
# Examples: "http://foo.com/media/", "/media/".
|
||||||
ADMIN_MEDIA_PREFIX = '/admin/media/'
|
ADMIN_MEDIA_PREFIX = '/admin/media/'
|
||||||
|
|
||||||
# List of callables that know how to import templates from various sources.
|
TEMPLATES = [
|
||||||
TEMPLATE_LOADERS = (
|
{
|
||||||
'django.template.loaders.filesystem.Loader',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'django.template.loaders.app_directories.Loader',
|
'DIRS': [
|
||||||
'django.template.loaders.eggs.Loader',
|
join(PROJECT_ROOT, 'templates'),
|
||||||
)
|
],
|
||||||
|
'APP_DIRS': True,
|
||||||
|
'OPTIONS': {
|
||||||
|
'context_processors': [
|
||||||
|
'django.template.context_processors.debug',
|
||||||
|
'django.template.context_processors.request',
|
||||||
|
'django.contrib.auth.context_processors.auth',
|
||||||
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
MIDDLEWARE_CLASSES = (
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
)
|
)
|
||||||
|
|
||||||
ROOT_URLCONF = 'oxdata.urls'
|
ROOT_URLCONF = 'urls'
|
||||||
|
|
||||||
TEMPLATE_DIRS = (
|
|
||||||
join(PROJECT_ROOT, 'templates'),
|
|
||||||
)
|
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS = (
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.sites',
|
'django.contrib.sites',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.humanize',
|
'django.contrib.humanize',
|
||||||
'south',
|
|
||||||
'django_extensions',
|
'django_extensions',
|
||||||
'djcelery',
|
'djcelery',
|
||||||
|
|
||||||
'api',
|
|
||||||
'lookup',
|
'lookup',
|
||||||
'movie',
|
'movie',
|
||||||
'poster',
|
'poster',
|
||||||
|
@ -112,12 +138,12 @@ INSTALLED_APPS = (
|
||||||
LOGIN_REDIRECT_URL='/'
|
LOGIN_REDIRECT_URL='/'
|
||||||
|
|
||||||
|
|
||||||
CELERY_RESULT_BACKEND = "database"
|
CELERY_RESULT_BACKEND = 'database'
|
||||||
BROKER_HOST = "127.0.0.1"
|
CELERY_TASK_SERIALIZER = 'json'
|
||||||
BROKER_PORT = 5672
|
CELERY_RESULT_SERIALIZER = 'json'
|
||||||
BROKER_USER = "oxdata"
|
CELERY_ACCEPT_CONTENT = ['json']
|
||||||
BROKER_PASSWORD = "ox"
|
|
||||||
BROKER_VHOST = "/oxdata"
|
BROKER_URL = 'amqp://oxdata:ox@localhost:5672//odata'
|
||||||
|
|
||||||
#Movie related settings
|
#Movie related settings
|
||||||
REVIEW_WHITELIST = {
|
REVIEW_WHITELIST = {
|
||||||
|
|
19
oxdata/static/js/jquery.js
vendored
19
oxdata/static/js/jquery.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,157 +0,0 @@
|
||||||
/***
|
|
||||||
Pandora API
|
|
||||||
***/
|
|
||||||
Ox.load('UI', {
|
|
||||||
hideScreen: false,
|
|
||||||
showScreen: true,
|
|
||||||
theme: 'classic'
|
|
||||||
}, function() {
|
|
||||||
|
|
||||||
var app = new Ox.App({
|
|
||||||
apiURL: '/api/',
|
|
||||||
}).bindEvent('load', function(data) {
|
|
||||||
app.default_info = '<div class="OxSelectable"><h2>Pan.do/ra API Overview</h2>use this api in the browser with <a href="/static/oxjs/demos/doc2/index.html#Ox.App">Ox.app</a> or use <a href="http://code.0x2620.org/pandora_client">pandora_client</a> it in python. Further description of the api can be found <a href="https://wiki.0x2620.org/wiki/pandora/API">on the wiki</a></div>';
|
|
||||||
app.$body = $('body');
|
|
||||||
app.$document = $(document);
|
|
||||||
app.$window = $(window);
|
|
||||||
//app.$body.html('');
|
|
||||||
Ox.UI.hideLoadingScreen();
|
|
||||||
|
|
||||||
app.$ui = {};
|
|
||||||
app.$ui.actionList = constructList();
|
|
||||||
app.$ui.actionInfo = Ox.Container().css({padding: '16px'}).html(app.default_info);
|
|
||||||
|
|
||||||
app.api.api({docs: true, code: true}, function(results) {
|
|
||||||
app.actions = results.data.actions;
|
|
||||||
|
|
||||||
if(document.location.hash) {
|
|
||||||
app.$ui.actionList.triggerEvent('select', {ids: document.location.hash.substring(1).split(',')});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var $left = new Ox.SplitPanel({
|
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
element: new Ox.Element().append(new Ox.Element()
|
|
||||||
.html('API').css({
|
|
||||||
'padding': '4px',
|
|
||||||
})).css({
|
|
||||||
'background-color': '#ddd',
|
|
||||||
'font-weight': 'bold',
|
|
||||||
}),
|
|
||||||
size: 24
|
|
||||||
},
|
|
||||||
{
|
|
||||||
element: app.$ui.actionList
|
|
||||||
}
|
|
||||||
],
|
|
||||||
orientation: 'vertical'
|
|
||||||
});
|
|
||||||
var $main = new Ox.SplitPanel({
|
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
element: $left,
|
|
||||||
size: 160
|
|
||||||
},
|
|
||||||
{
|
|
||||||
element: app.$ui.actionInfo,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
orientation: 'horizontal'
|
|
||||||
});
|
|
||||||
|
|
||||||
$main.appendTo(app.$body);
|
|
||||||
});
|
|
||||||
|
|
||||||
function constructList() {
|
|
||||||
return new Ox.TextList({
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "name",
|
|
||||||
operator: "+",
|
|
||||||
title: "Name",
|
|
||||||
unique: true,
|
|
||||||
visible: true,
|
|
||||||
width: 140
|
|
||||||
},
|
|
||||||
],
|
|
||||||
columnsMovable: false,
|
|
||||||
columnsRemovable: false,
|
|
||||||
id: 'actionList',
|
|
||||||
items: function(data, callback) {
|
|
||||||
function _sort(a, b) {
|
|
||||||
if(a.name > b.name)
|
|
||||||
return 1;
|
|
||||||
else if(a.name == b.name)
|
|
||||||
return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!data.keys) {
|
|
||||||
app.api.api(function(results) {
|
|
||||||
var items = [];
|
|
||||||
Ox.forEach(results.data.actions, function(v, k) {
|
|
||||||
items.push({'name': k})
|
|
||||||
});
|
|
||||||
items.sort(_sort);
|
|
||||||
var result = {'data': {'items': items.length}};
|
|
||||||
callback(result);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
app.api.api(function(results) {
|
|
||||||
var items = [];
|
|
||||||
Ox.forEach(results.data.actions, function(v, k) {
|
|
||||||
items.push({'name': k})
|
|
||||||
});
|
|
||||||
items.sort(_sort);
|
|
||||||
var result = {'data': {'items': items}};
|
|
||||||
callback(result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scrollbarVisible: true,
|
|
||||||
sort: [
|
|
||||||
{
|
|
||||||
key: "name",
|
|
||||||
operator: "+"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}).bindEvent({
|
|
||||||
select: function(data) {
|
|
||||||
var info = $('<div>').addClass('OxSelectable'),
|
|
||||||
hash = '#';
|
|
||||||
if(data.ids.length)
|
|
||||||
data.ids.forEach(function(id) {
|
|
||||||
info.append($("<h2>").html(id));
|
|
||||||
var $doc =$('<pre>')
|
|
||||||
.html(app.actions[id].doc.replace('/\n/<br>\n/g'))
|
|
||||||
.appendTo(info);
|
|
||||||
var $code = $('<code class="python">')
|
|
||||||
.html(app.actions[id].code[1].replace('/\n/<br>\n/g'))
|
|
||||||
.hide();
|
|
||||||
var $button = new Ox.Button({
|
|
||||||
title: [
|
|
||||||
{id: "one", title: "right"},
|
|
||||||
{id: "two", title: "down"},
|
|
||||||
],
|
|
||||||
type: "image"
|
|
||||||
})
|
|
||||||
.addClass("margin")
|
|
||||||
.click(function() { $code.toggle()})
|
|
||||||
.appendTo(info)
|
|
||||||
var f = app.actions[id].code[0];
|
|
||||||
$('<span>').html(' View Source ('+f+')').appendTo(info)
|
|
||||||
$('<pre>').append($code).appendTo(info)
|
|
||||||
|
|
||||||
hash += id + ','
|
|
||||||
});
|
|
||||||
else
|
|
||||||
info.html(app.default_info);
|
|
||||||
|
|
||||||
document.location.hash = hash.substring(0, hash.length-1);
|
|
||||||
app.$ui.actionInfo.html(info);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
1
oxdata/templates/404.html
Normal file
1
oxdata/templates/404.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
404 not found
|
1
oxdata/templates/api.html
Normal file
1
oxdata/templates/api.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
api
|
|
@ -2,49 +2,50 @@
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from django.conf.urls.defaults import *
|
from django.conf.urls import url, include
|
||||||
from ox.django.http import HttpFileResponse
|
from oxdjango.http import HttpFileResponse
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
import django.views.static
|
||||||
|
|
||||||
# Uncomment the next two lines to enable the admin:
|
# Uncomment the next two lines to enable the admin:
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
admin.autodiscover()
|
admin.autodiscover()
|
||||||
|
|
||||||
from api import actions
|
import oxdjango.api.urls
|
||||||
actions.autodiscover()
|
|
||||||
|
|
||||||
|
import views
|
||||||
|
import poster.urls
|
||||||
|
import lookup.urls
|
||||||
|
|
||||||
def serve_static_file(path, location, content_type):
|
def serve_static_file(path, location, content_type):
|
||||||
return HttpFileResponse(location, content_type=content_type)
|
return HttpFileResponse(location, content_type=content_type)
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
|
||||||
(r'^$', 'oxdata.views.index'),
|
|
||||||
(r'^api/$', include('api.urls')),
|
|
||||||
(r'^poster/', include('oxdata.poster.urls')),
|
|
||||||
(r'^still/$', 'oxdata.poster.views.still'),
|
|
||||||
(r'^id/', include('oxdata.lookup.urls')),
|
|
||||||
(r'^get/', include('oxdata.lookup.urls')),
|
|
||||||
|
|
||||||
(r'^robots.txt$', serve_static_file, {
|
urlpatterns = [
|
||||||
|
url(r'^$', views.index),
|
||||||
|
url(r'^api/?', include(oxdjango.api.urls)),
|
||||||
|
url(r'^poster/', include(poster.urls)),
|
||||||
|
url(r'^still/$', poster.views.still),
|
||||||
|
url(r'^id/', include(lookup.urls)),
|
||||||
|
url(r'^get/', include(lookup.urls)),
|
||||||
|
|
||||||
|
url(r'^robots.txt$', serve_static_file, {
|
||||||
'location': os.path.join(settings.STATIC_ROOT, 'robots.txt'),
|
'location': os.path.join(settings.STATIC_ROOT, 'robots.txt'),
|
||||||
'content_type': 'text/plain'
|
'content_type': 'text/plain'
|
||||||
}),
|
}),
|
||||||
(r'^favicon.ico$', serve_static_file, {
|
url(r'^favicon.ico$', serve_static_file, {
|
||||||
'location': os.path.join(settings.STATIC_ROOT, 'favicon.ico'),
|
'location': os.path.join(settings.STATIC_ROOT, 'favicon.ico'),
|
||||||
'content_type': 'image/x-icon'}),
|
'content_type': 'image/x-icon'}),
|
||||||
# Uncomment the next line to enable the admin:
|
url(r'^admin/', include(admin.site.urls)),
|
||||||
(r'^admin/', include(admin.site.urls)),
|
]
|
||||||
)
|
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
urlpatterns += patterns('',
|
urlpatterns += [
|
||||||
(r'^media/(?P<path>.*)$', 'django.views.static.serve',
|
url(r'^media/(?P<path>.*)$', django.views.static.serve,
|
||||||
{'document_root': settings.MEDIA_ROOT}),
|
{'document_root': settings.MEDIA_ROOT}),
|
||||||
(r'^static/(?P<path>.*)$', 'django.views.static.serve',
|
url(r'^static/(?P<path>.*)$', django.views.static.serve,
|
||||||
{'document_root': settings.STATIC_ROOT}),
|
{'document_root': settings.STATIC_ROOT}),
|
||||||
)
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#load local urls if present
|
#load local urls if present
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# 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
|
||||||
from django.template import RequestContext
|
|
||||||
|
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
context = RequestContext(request, {})
|
return render(request, 'index.html', {})
|
||||||
return render_to_response('index.html', context)
|
|
||||||
|
|
||||||
|
|
16
oxdata/wsgi.py
Normal file
16
oxdata/wsgi.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
"""
|
||||||
|
WSGI config for fixme project.
|
||||||
|
|
||||||
|
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
|
@ -1,7 +1,6 @@
|
||||||
Django>=1.3.0,<1.4
|
Django==1.9.4
|
||||||
South
|
celery==3.1.20
|
||||||
-e bzr+http://code.0x2620.org/python-ox/#egg=python-ox
|
django-celery==3.1.17
|
||||||
chardet
|
django-extensions==1.6.1
|
||||||
django-celery
|
gunicorn==19.4.5
|
||||||
gunicorn
|
-e git+http://git.0x2620.org/python-ox.git#egg=python-ox
|
||||||
-e git://github.com/bit/django-extensions.git#egg=django_extensions
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
# django.wsgi
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import site
|
|
||||||
|
|
||||||
project_module = 'oxdata'
|
|
||||||
|
|
||||||
root_dir = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
||||||
|
|
||||||
#using virtualenv's activate_this.py to reorder sys.path
|
|
||||||
activate_this = os.path.join(root_dir, 'bin', 'activate_this.py')
|
|
||||||
execfile(activate_this, dict(__file__=activate_this))
|
|
||||||
|
|
||||||
sys.path.append(root_dir)
|
|
||||||
sys.path.append(os.path.join(root_dir, project_module))
|
|
||||||
|
|
||||||
#reload if this django.wsgi gets touched
|
|
||||||
from oxdjango import monitor
|
|
||||||
monitor.start(interval=1.0)
|
|
||||||
|
|
||||||
monitor.track(os.path.abspath(os.path.dirname(__file__)))
|
|
||||||
|
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = project_module + '.settings'
|
|
||||||
|
|
||||||
import django.core.handlers.wsgi
|
|
||||||
|
|
||||||
application = django.core.handlers.wsgi.WSGIHandler()
|
|
||||||
|
|
Loading…
Reference in a new issue