merge
59
README
|
@ -1,14 +1,16 @@
|
|||
pan.do/ra - open media archive
|
||||
|
||||
== DEVELOPMENT ==
|
||||
To setup a development instance of pan.do/ra,
|
||||
you need python, bazaar, pip and virtualenv and several other python modules:
|
||||
== SETUP ==
|
||||
To setup pan.do/ra, you need
|
||||
python, bazaar, pip and virtualenv and several other python modules:
|
||||
|
||||
* Packages
|
||||
apt-get install bzr git subversion mercurial \
|
||||
python-setuptools python-pip python-virtualenv ipython \
|
||||
python-dev python-imaging python-numpy python-psycopg2
|
||||
|
||||
* Pan.do/ra
|
||||
Get code from bazzar
|
||||
bzr branch http://code.0x2620.org/pandora pandora
|
||||
cd pandora
|
||||
virtualenv .
|
||||
|
@ -17,6 +19,18 @@ you need python, bazaar, pip and virtualenv and several other python modules:
|
|||
cd static
|
||||
bzr branch http://code.0x2620.org/oxjs
|
||||
|
||||
create settings_local.py and create site.jsonc
|
||||
(use settings.py / 0xdb.jsonc / padma.jsonc as example)
|
||||
create db
|
||||
|
||||
./manage.py syncdb
|
||||
|
||||
create / update static files
|
||||
|
||||
./manage.py update_static
|
||||
./manage.py compile_pyc
|
||||
|
||||
|
||||
* Additional pandora tools:
|
||||
You need current versions of oxframe, oxtimeline installed.
|
||||
For Ubuntu we provide these packages in a ppa:
|
||||
|
@ -30,11 +44,12 @@ you need python, bazaar, pip and virtualenv and several other python modules:
|
|||
(make sure you have the python bindings installed).
|
||||
|
||||
create a postgresql database and adjust settings in local_settings.py
|
||||
and run ./manage.py syncdb to populate the database
|
||||
you might want to load example configurations from fixutes.
|
||||
and run ./manage.py syncdb to populate the database.
|
||||
|
||||
createdb -T template0 --locale=C --encoding=UTF8 -O pandora pandora
|
||||
|
||||
(setting locale to C is required to fix a bug in sort if set to UTF8)
|
||||
|
||||
* RabbitMQ
|
||||
For background tasks we use RabbitMQ, to install rabbitmq:
|
||||
sudo apt-get install rabbitmq-server
|
||||
|
@ -48,7 +63,7 @@ you need python, bazaar, pip and virtualenv and several other python modules:
|
|||
* H264
|
||||
to support h264 videos, install ffmpeg with x264 enabled,
|
||||
install qt-faststart from (ffmpeg/tools)
|
||||
set VIDEO_H264 = True in local_settings.py
|
||||
to enable add "mp4" to video.formats in your config.jsonc
|
||||
|
||||
Running developer environment:
|
||||
in one terminal:
|
||||
|
@ -56,24 +71,36 @@ Running developer environment:
|
|||
and in another one:
|
||||
./manage.py celeryd -Q default,encoding -B
|
||||
|
||||
Updating database:
|
||||
right now database updates are not managed, each time you update to current bzr
|
||||
you might have to update db tables too.
|
||||
Use
|
||||
./manage.py sqldiff appname
|
||||
to check if changes exist and
|
||||
./manage.py sqldiff appname | ./manage.py dbshell
|
||||
=== Updating ===
|
||||
To update a pandora installation get the latest version from bzr by running
|
||||
./update.sh
|
||||
this will pull pandora/oxjs/python-ox and list possible upgrades to the db
|
||||
|
||||
to update your database tables, use
|
||||
./manage.py sqldiff -a
|
||||
to check if there are changes and
|
||||
./manage.py sqldiff -a | ./manage.py dbshell
|
||||
to apply them.
|
||||
This has to be done for all installed apps
|
||||
|
||||
== DEPLOYMENT ==
|
||||
* Install upstart scripts
|
||||
check etc/init for upstart scripts, adjust path and user and put into /etc/init
|
||||
|
||||
To run pan.do/ra in production, we use nginx, using apache2 is also possible.
|
||||
|
||||
* nginx setup
|
||||
sudo apt-get install nginx
|
||||
|
||||
add this to local_settings.py:
|
||||
XACCELREDIRECT = True
|
||||
|
||||
setup nginx according to etc/nginx/vhost.in
|
||||
|
||||
* apache2 setup
|
||||
sudo apt-get install apache2-mpm-prefork
|
||||
sudo apt-get install libapache2-mod-xsendfile
|
||||
apt-get install apache2-mpm-prefork libapache2-mod-xsendfile
|
||||
|
||||
add this to local_settings.py:
|
||||
XSENDFILE = True
|
||||
|
||||
setup apache according to etc/apache2/vhost.in
|
||||
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
[
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "backend.reviewwhitelist",
|
||||
"fields": {
|
||||
"url": "://filmcritic.com",
|
||||
"name": "Filmcritic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "backend.reviewwhitelist",
|
||||
"fields": {
|
||||
"url": "villagevoice.com",
|
||||
"name": "Village Voice"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "backend.reviewwhitelist",
|
||||
"fields": {
|
||||
"url": "salon.com",
|
||||
"name": "Salon.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "backend.reviewwhitelist",
|
||||
"fields": {
|
||||
"url": "rottentomatoes.com",
|
||||
"name": "Rotten Tomatoes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "backend.reviewwhitelist",
|
||||
"fields": {
|
||||
"url": "nytimes.com",
|
||||
"name": "New York Times"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "backend.reviewwhitelist",
|
||||
"fields": {
|
||||
"url": "metacritic.com",
|
||||
"name": "Metacritic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 7,
|
||||
"model": "backend.reviewwhitelist",
|
||||
"fields": {
|
||||
"url": "sensesofcinema.com",
|
||||
"name": "Senses of Cinema"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -10,7 +10,7 @@ import ox
|
|||
from archive import extract
|
||||
from clip.models import Clip
|
||||
|
||||
|
||||
from item.utils import sort_string
|
||||
import managers
|
||||
import utils
|
||||
from tasks import update_matching_events, update_matching_places
|
||||
|
@ -34,6 +34,7 @@ class Annotation(models.Model):
|
|||
|
||||
layer = models.CharField(max_length=255, db_index=True)
|
||||
value = models.TextField()
|
||||
sortvalue = models.CharField(max_length=1000, null=True, blank=True, db_index=True)
|
||||
|
||||
def editable(self, user):
|
||||
if user.is_authenticated():
|
||||
|
@ -57,6 +58,15 @@ class Annotation(models.Model):
|
|||
|
||||
def save(self, *args, **kwargs):
|
||||
set_public_id = not self.id or not self.public_id
|
||||
if self.value:
|
||||
sortvalue = ox.stripTags(self.value).strip()
|
||||
sortvalue = sort_string(sortvalue)
|
||||
if sortvalue:
|
||||
self.sortvalue = sortvalue[:1000]
|
||||
else:
|
||||
self.sortvalue = None
|
||||
else:
|
||||
self.sortvalue = None
|
||||
|
||||
#no clip or update clip
|
||||
def get_layer(id):
|
||||
|
|
|
@ -51,6 +51,10 @@ class MetaClip:
|
|||
for key in j.keys():
|
||||
if key not in keys:
|
||||
del j[key]
|
||||
#needed here to make item find with clips work
|
||||
if 'annotations' in keys:
|
||||
j['annotations'] = [a.json(keys=['value', 'id', 'layer'])
|
||||
for a in self.annotations.filter(layer__in=self.layers)]
|
||||
for key in keys:
|
||||
if key not in clip_keys and key not in j:
|
||||
value = self.item.get(key)
|
||||
|
|
|
@ -35,14 +35,14 @@ def order_query(qs, sort):
|
|||
if operator != '-':
|
||||
operator = ''
|
||||
clip_keys = ('public_id', 'start', 'end', 'hue', 'saturation', 'lightness', 'volume',
|
||||
'annotations__value', 'videoRatio',
|
||||
'annotations__sortvalue', 'videoRatio',
|
||||
'director', 'title')
|
||||
key = {
|
||||
'id': 'public_id',
|
||||
'in': 'start',
|
||||
'out': 'end',
|
||||
'position': 'start',
|
||||
'text': 'annotations__value',
|
||||
'text': 'annotations__sortvalue',
|
||||
'videoRatio': 'aspect_ratio',
|
||||
}.get(e['key'], e['key'])
|
||||
if key.startswith('clip:'):
|
||||
|
|
|
@ -21,7 +21,8 @@ def plural_key(term):
|
|||
|
||||
|
||||
def sort_string(string):
|
||||
string = string.replace(u'Þ', 'Th')
|
||||
string = string.replace(u'Æ', 'AE').replace(u'Ø', 'O').replace(u'Þ', 'Th')
|
||||
|
||||
#pad numbered titles
|
||||
string = re.sub('(\d+)', lambda x: '%010d' % int(x.group(0)), string)
|
||||
return unicodedata.normalize('NFKD', string)
|
||||
|
|
|
@ -48,7 +48,6 @@ class Person(models.Model):
|
|||
if not self.sortname:
|
||||
self.sortname = ox.get_sort_name(self.name)
|
||||
self.sortname = unicodedata.normalize('NFKD', self.sortname)
|
||||
self.sortname = self.sortname.replace(u'Æ', 'AE').replace(u'Ø', 'O').replace(u'Þ', 'P')
|
||||
self.sortsortname = utils.sort_string(self.sortname)
|
||||
self.numberofnames = len(self.name.split(' '))
|
||||
super(Person, self).save(*args, **kwargs)
|
||||
|
|
|
@ -42,7 +42,6 @@ APPEND_SLASH = False
|
|||
# Example: "/home/media/media.lawrence.com/"
|
||||
MEDIA_ROOT = normpath(join(PROJECT_ROOT, '..', 'data'))
|
||||
STATIC_ROOT = normpath(join(PROJECT_ROOT, '..', 'static'))
|
||||
TESTS_ROOT = join(PROJECT_ROOT, 'tests')
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash if there is a path component (optional in other cases).
|
||||
|
@ -183,11 +182,12 @@ VIDEO_PREFIX=''
|
|||
#VIDEO_PREFIX='videoPART.example.com'
|
||||
#SESSION_COOKIE_DOMAIN=*.example.com"
|
||||
|
||||
SCRIPT_ROOT = normpath(join(PROJECT_ROOT, '..', 'scripts'))
|
||||
#copy scripts and adjust to customize
|
||||
ITEM_POSTER = join('scripts', 'oxdb_poster')
|
||||
#ITEM_POSTER = join('scripts', 'padma_poster')
|
||||
ITEM_ICON = join('scripts', 'item_icon')
|
||||
LIST_ICON = join('scripts', 'list_icon')
|
||||
ITEM_POSTER = join(SCRIPT_ROOT, 'oxdb_poster')
|
||||
#ITEM_POSTER = join(SCRIPT_ROOT, 'padma_poster')
|
||||
ITEM_ICON = join(SCRIPT_ROOT, 'item_icon')
|
||||
LIST_ICON = join(SCRIPT_ROOT, 'list_icon')
|
||||
|
||||
|
||||
#you can ignore things below this line
|
||||
|
|
|
@ -30,14 +30,13 @@ urlpatterns = patterns('',
|
|||
(r'^robots.txt$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'robots.txt'), 'content_type': 'text/plain'}),
|
||||
(r'^favicon.ico$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'png/icon.16.png'), 'content_type': 'image/x-icon'}),
|
||||
)
|
||||
if settings.DEBUG:
|
||||
#if settings.DEBUG:
|
||||
#sould this not be enabled by default? nginx should handle those
|
||||
urlpatterns += patterns('',
|
||||
(r'^data/(?P<path>.*)$', 'django.views.static.serve',
|
||||
{'document_root': settings.MEDIA_ROOT}),
|
||||
(r'^static/(?P<path>.*)$', 'django.views.static.serve',
|
||||
{'document_root': settings.STATIC_ROOT}),
|
||||
(r'^tests/(?P<path>.*)$', 'django.views.static.serve',
|
||||
{'document_root': settings.TESTS_ROOT}),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('',
|
||||
|
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
@ -4,7 +4,7 @@
|
|||
from __future__ import division
|
||||
import os
|
||||
|
||||
root_dir = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
|
||||
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')
|
|
@ -4,7 +4,7 @@
|
|||
from __future__ import division
|
||||
import os
|
||||
|
||||
root_dir = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
|
||||
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')
|
|
@ -4,7 +4,7 @@
|
|||
from __future__ import division
|
||||
import os
|
||||
|
||||
root_dir = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
|
||||
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')
|
|
@ -4,7 +4,7 @@
|
|||
from __future__ import division
|
||||
import os
|
||||
|
||||
root_dir = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
|
||||
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')
|