site config, user level, item level

This commit is contained in:
j 2011-09-06 08:06:59 -04:00
parent aafb513492
commit cbd04a10c8
12 changed files with 71 additions and 73 deletions

View file

@ -2,13 +2,14 @@
# 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
from django.conf import settings
import ox import ox
from ox.utils import json from ox.utils import json
from ox.django.decorators import login_required_json from ox.django.decorators import login_required_json
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from app.models import site_config
from item.models import Item from item.models import Item
from api.actions import actions from api.actions import actions
@ -101,7 +102,7 @@ def addAnnotation(request):
text='invalid data')) text='invalid data'))
#FIXME: this should be only called starting up server #FIXME: this should be only called starting up server
models.load_layers(site_config()['layers']) models.load_layers(settings.CONFIG['layers'])
item = get_object_or_404_json(Item, itemId=data['item']) item = get_object_or_404_json(Item, itemId=data['item'])
layer = get_object_or_404_json(models.Layer, name=data['layer']) layer = get_object_or_404_json(models.Layer, name=data['layer'])

View file

@ -14,7 +14,6 @@ from ox.utils import json
from user.models import get_user_json from user.models import get_user_json
from item.models import ItemSort from item.models import ItemSort
from app.models import site_config
from actions import actions from actions import actions
@ -55,7 +54,7 @@ def init(request):
''' '''
#data = json.loads(request.POST['data']) #data = json.loads(request.POST['data'])
response = json_response({}) response = json_response({})
config = site_config() config = settings.CONFIG.copy()
del config['keys'] #is this needed? del config['keys'] #is this needed?
#populate max values for percent requests #populate max values for percent requests

View file

@ -11,8 +11,3 @@ class PageAdmin(admin.ModelAdmin):
admin.site.register(models.Page, PageAdmin) admin.site.register(models.Page, PageAdmin)
class SiteSettingsAdmin(admin.ModelAdmin):
search_fields = ['key', 'value']
admin.site.register(models.SiteSettings, SiteSettingsAdmin)

View file

@ -2,11 +2,15 @@
# 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 os
import sys
import time
import thread
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from ox.utils import json from ox.utils import json
_win = (sys.platform == "win32")
class Page(models.Model): class Page(models.Model):
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
@ -17,24 +21,31 @@ class Page(models.Model):
def __unicode__(self): def __unicode__(self):
return self.name return self.name
RUN_RELOADER = True
class SiteSettings(models.Model): def reloader_thread():
key = models.CharField(max_length=1024, unique=True) _config_mtime = 0
value = models.TextField(blank=True) while RUN_RELOADER:
stat = os.stat(settings.SITE_CONFIG)
def __unicode__(self): mtime = stat.st_mtime
return self.key if _win:
mtime -= stat.st_ctime
def site_config(): if mtime > _config_mtime:
with open(settings.SITE_CONFIG) as f: with open(settings.SITE_CONFIG) as f:
site_config = json.load(f) config = json.load(f)
site_config['site']['id'] = settings.SITEID config['site']['id'] = settings.SITEID
site_config['site']['name'] = settings.SITENAME config['site']['name'] = settings.SITENAME
site_config['site']['sectionName'] = settings.SITENAME config['site']['sectionName'] = settings.SITENAME
site_config['site']['url'] = settings.URL config['site']['url'] = settings.URL
config['keys'] = {}
for key in config['itemKeys']:
config['keys'][key['id']] = key
settings.CONFIG = config
_config_mtime = mtime
time.sleep(1)
thread.start_new_thread(reloader_thread, ())
site_config['keys'] = {}
for key in site_config['itemKeys']:
site_config['keys'][key['id']] = key
return site_config

View file

@ -17,7 +17,6 @@ import ox
from ox.normalize import canonicalTitle from ox.normalize import canonicalTitle
import chardet import chardet
from app.models import site_config
from item import utils from item import utils
from person.models import get_name_sort from person.models import get_name_sort
@ -237,12 +236,11 @@ class File(models.Model):
return srt return srt
def editable(self, user): def editable(self, user):
#FIXME: check that user has instance of this file return self.instances.filter(volume__user=user).count() > 0
return True
def save_chunk(self, chunk, chunk_id=-1, done=False): def save_chunk(self, chunk, chunk_id=-1, done=False):
if not self.available: if not self.available:
config = site_config()['video'] config = settings.CONFIG['video']
stream, created = Stream.objects.get_or_create( stream, created = Stream.objects.get_or_create(
file=self, file=self,
resolution=config['resolutions'][0], resolution=config['resolutions'][0],
@ -485,7 +483,7 @@ class Stream(models.Model):
return self.file.path(name) return self.file.path(name)
def extract_derivatives(self): def extract_derivatives(self):
config = site_config()['video'] config = settings.CONFIG['video']
for resolution in config['resolutions']: for resolution in config['resolutions']:
for f in config['formats']: for f in config['formats']:
derivative, created = Stream.objects.get_or_create(file=self.file, derivative, created = Stream.objects.get_or_create(file=self.file,

View file

@ -14,7 +14,6 @@ from ox.django.decorators import login_required_json
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from ox.django.views import task_status from ox.django.views import task_status
from app.models import site_config
from item import utils from item import utils
from item.models import get_item, Item from item.models import get_item, Item
from item.views import parse_query from item.views import parse_query
@ -114,7 +113,7 @@ actions.register(update, cache=False)
@login_required_json @login_required_json
def encodingProfile(request): def encodingProfile(request):
config = site_config()['video'] config = settings.CONFIG['video']
profile = "%sp.%s" % (config['resolutions'][0], config['formats'][0]) profile = "%sp.%s" % (config['resolutions'][0], config['formats'][0])
response = json_response({'profile': profile}) response = json_response({'profile': profile})
return render_to_json_response(response) return render_to_json_response(response)
@ -172,7 +171,7 @@ class VideoChunkForm(forms.Form):
def firefogg_upload(request): def firefogg_upload(request):
profile = request.GET['profile'] profile = request.GET['profile']
oshash = request.GET['id'] oshash = request.GET['id']
config = site_config()['video'] config = settings.CONFIG['video']
video_profile = "%sp.%s" % (config['resolutions'][0], config['formats'][0]) video_profile = "%sp.%s" % (config['resolutions'][0], config['formats'][0])
#handle video upload #handle video upload

View file

@ -3,9 +3,11 @@
from datetime import datetime from datetime import datetime
from django.db.models import Q, Manager from django.db.models import Q, Manager
from django.conf import settings
from itemlist.models import List from itemlist.models import List
import models import models
from ox.django.query import QuerySet from ox.django.query import QuerySet
def parseCondition(condition): def parseCondition(condition):
@ -43,7 +45,7 @@ def parseCondition(condition):
else: else:
return q return q
key_type = models.site_config()['keys'].get(k, {'type':'string'}).get('type') key_type = settings.config['keys'].get(k, {'type':'string'}).get('type')
if isinstance(key_type, list): if isinstance(key_type, list):
key_type = key_type[0] key_type = key_type[0]
key_type = { key_type = {
@ -245,9 +247,11 @@ class ItemManager(Manager):
#anonymous can only see public items #anonymous can only see public items
if user.is_anonymous(): if user.is_anonymous():
qs = qs.filter(public=True) allowed_level = settings.config['capabilities']['canSeeItem']['guest']
qs = qs.filter(level__lte=allowed_level)
#users can see public items, there own items and items of there groups #users can see public items, there own items and items of there groups
elif not user.is_staff: else:
qs = qs.filter(Q(public=True)|Q(user=user)|Q(groups__in=user.groups.all())) allowed_level = settings.config['capabilities']['canSeeItem'][user.get_profile().get_level()]
qs = qs.filter(Q(level__lte=allowed_level)|Q(user=user)|Q(groups__in=user.groups.all()))
#admins can see all available items #admins can see all available items
return qs return qs

View file

@ -37,7 +37,6 @@ from annotation.models import Annotation, Layer
import archive.models import archive.models
from person.models import get_name_sort from person.models import get_name_sort
from app.models import site_config
def get_item(info, user=None, async=False): def get_item(info, user=None, async=False):
@ -129,7 +128,7 @@ class Item(models.Model):
#while metadata is updated, files are set to rendered=False #while metadata is updated, files are set to rendered=False
rendered = models.BooleanField(default=False, db_index=True) rendered = models.BooleanField(default=False, db_index=True)
public = models.BooleanField(default=False, db_index=True) level = models.IntegerField(default=False, db_index=True)
itemId = models.CharField(max_length=128, unique=True, blank=True) itemId = models.CharField(max_length=128, unique=True, blank=True)
oxdbId = models.CharField(max_length=42, unique=True, blank=True, null=True) oxdbId = models.CharField(max_length=42, unique=True, blank=True, null=True)
@ -163,11 +162,11 @@ class Item(models.Model):
return default return default
def access(self, user): def access(self, user):
#check rights level allowed_level = settings.CONFIG['capabilities']['canSeeItem'][user.get_profile().get_level()]
if self.public: if self.level < allowed_level:
return True return True
elif user.is_authenticated() and \ elif user.is_authenticated() and \
(user.is_staff or self.user == user or \ (self.user == user or \
self.groups.filter(id__in=user.groups.all()).count() > 0): self.groups.filter(id__in=user.groups.all()).count() > 0):
return True return True
return False return False
@ -414,7 +413,7 @@ class Item(models.Model):
} }
i.update(self.external_data) i.update(self.external_data)
i.update(self.data) i.update(self.data)
for k in site_config()['itemKeys']: for k in settings.CONFIG['itemKeys']:
key = k['id'] key = k['id']
if not keys or key in keys: if not keys or key in keys:
if key not in i: if key not in i:
@ -483,7 +482,7 @@ class Item(models.Model):
else: else:
f.delete() f.delete()
for key in site_config()['itemKeys']: for key in settings.CONFIG['itemKeys']:
if key.get('find'): if key.get('find'):
i = key['id'] i = key['id']
if i == 'title': if i == 'title':
@ -514,7 +513,7 @@ class Item(models.Model):
values = [] values = []
for k in map(lambda x: x['id'], for k in map(lambda x: x['id'],
filter(lambda x: x.get('sort') == 'person', filter(lambda x: x.get('sort') == 'person',
config['itemKeys'])): settings.CONFIG['itemKeys'])):
values += self.get(k, []) values += self.get(k, [])
else: else:
values = self.get(key, '') values = self.get(key, '')
@ -566,7 +565,7 @@ class Item(models.Model):
'popularity', 'popularity',
) )
for key in filter(lambda k: 'columnWidth' in k, config['itemKeys']): for key in filter(lambda k: 'columnWidth' in k, settings.CONFIG['itemKeys']):
name = key['id'] name = key['id']
source = name source = name
sort_type = key.get('sort', key['type']) sort_type = key.get('sort', key['type'])
@ -619,10 +618,9 @@ class Item(models.Model):
s.published = self.published s.published = self.published
# sort values based on data from videos # sort values based on data from videos
s.words = 0 #FIXME: get words from all layers or something s.words = sum([len(a.value.split()) for a in self.annotations.all()])
s.wordsperminute = 0
s.clips = 0 #FIXME: get clips from all layers or something s.clips = 0 #FIXME: get clips from all layers or something
s.popularity = 0 #FIXME: get popularity from somewhere
videos = self.files.filter(active=True, is_video=True) videos = self.files.filter(active=True, is_video=True)
if videos.count() > 0: if videos.count() > 0:
s.duration = sum([v.duration for v in videos]) s.duration = sum([v.duration for v in videos])
@ -656,8 +654,10 @@ class Item(models.Model):
s.cuts = len(self.data.get('cuts', [])) s.cuts = len(self.data.get('cuts', []))
if s.duration: if s.duration:
s.cutsperminute = s.cuts / (s.duration/60) s.cutsperminute = s.cuts / (s.duration/60)
s.wordsperminute = s.words / (s.duration / 60)
else: else:
s.cutsperminute = None s.cutsperminute = None
s.wordsperminute = None
s.popularity = self.accessed.aggregate(Sum('accessed'))['accessed__sum'] s.popularity = self.accessed.aggregate(Sum('accessed'))['accessed__sum']
s.save() s.save()
@ -679,7 +679,7 @@ class Item(models.Model):
current_values = [] current_values = []
for k in map(lambda x: x['id'], for k in map(lambda x: x['id'],
filter(lambda x: x.get('sort') == 'person', filter(lambda x: x.get('sort') == 'person',
config['itemKeys'])): settings.CONFIG['itemKeys'])):
current_values += self.get(k, []) current_values += self.get(k, [])
if not isinstance(current_values, list): if not isinstance(current_values, list):
current_values = [unicode(current_values)] current_values = [unicode(current_values)]
@ -852,7 +852,6 @@ class Item(models.Model):
file__item=self, file__is_video=True, file__active=True).order_by('file__part') file__item=self, file__is_video=True, file__active=True).order_by('file__part')
def update_timeline(self, force=False): def update_timeline(self, force=False):
config = site_config()
streams = self.streams() streams = self.streams()
self.make_timeline() self.make_timeline()
self.data['cuts'] = extract.cuts(self.timeline_prefix) self.data['cuts'] = extract.cuts(self.timeline_prefix)
@ -862,7 +861,7 @@ class Item(models.Model):
self.make_local_poster() self.make_local_poster()
self.make_poster() self.make_poster()
self.make_icon() self.make_icon()
if config['video']['download']: if settings.CONFIG['video']['download']:
self.make_torrent() self.make_torrent()
self.load_subtitles() self.load_subtitles()
self.rendered = streams != [] self.rendered = streams != []
@ -999,7 +998,7 @@ class Item(models.Model):
if frames and len(frames) > int(self.poster_frame): if frames and len(frames) > int(self.poster_frame):
return frames[int(self.poster_frame)]['path'] return frames[int(self.poster_frame)]['path']
else: else:
size = site_config()['video']['resolutions'][0] size = settings.CONFIG['video']['resolutions'][0]
return self.frame(self.poster_frame, size) return self.frame(self.poster_frame, size)
if frames: if frames:
@ -1068,15 +1067,13 @@ def delete_item(sender, **kwargs):
i.delete_files() i.delete_files()
pre_delete.connect(delete_item, sender=Item) pre_delete.connect(delete_item, sender=Item)
config = site_config()
Item.facet_keys = [] Item.facet_keys = []
for key in config['itemKeys']: for key in settings.CONFIG['itemKeys']:
if 'autocomplete' in key and not 'autocompleteSortKey' in key: if 'autocomplete' in key and not 'autocompleteSortKey' in key:
Item.facet_keys.append(key['id']) Item.facet_keys.append(key['id'])
Item.person_keys = [] Item.person_keys = []
for key in config['itemKeys']: for key in settings.CONFIG['itemKeys']:
if 'sort' in key and key['sort'] == 'person': if 'sort' in key and key['sort'] == 'person':
Item.person_keys.append(key['id']) Item.person_keys.append(key['id'])
@ -1098,14 +1095,14 @@ class ItemFind(models.Model):
return u"%s=%s" % (self.key, self.value) return u"%s=%s" % (self.key, self.value)
''' '''
ItemSort ItemSort
table constructed based on info in site_config['itemKeys'] table constructed based on info in settings.CONFIG['itemKeys']
''' '''
attrs = { attrs = {
'__module__': 'item.models', '__module__': 'item.models',
'item': models.OneToOneField('Item', related_name='sort', primary_key=True), 'item': models.OneToOneField('Item', related_name='sort', primary_key=True),
'duration': models.FloatField(null=True, blank=True, db_index=True), 'duration': models.FloatField(null=True, blank=True, db_index=True),
} }
for key in filter(lambda k: 'columnWidth' in k, config['itemKeys']): for key in filter(lambda k: 'columnWidth' in k, settings.CONFIG['itemKeys']):
name = key['id'] name = key['id']
name = {'id': 'itemId'}.get(name, name) name = {'id': 'itemId'}.get(name, name)
sort_type = key.get('sort', key['type']) sort_type = key.get('sort', key['type'])

View file

@ -288,8 +288,7 @@ def autocomplete(request):
data['range'] = [0, 10] data['range'] = [0, 10]
op = data.get('operator', '') op = data.get('operator', '')
site_config = models.site_config() key = settings.CONFIG['keys'][data['key']]
key = site_config['keys'][data['key']]
order_by = key.get('autocompleteSortKey', False) order_by = key.get('autocompleteSortKey', False)
if order_by: if order_by:
order_by = '-sort__%s' % order_by order_by = '-sort__%s' % order_by
@ -452,7 +451,6 @@ def setPosterFrame(request): #parse path and return info
data = json.loads(request.POST['data']) data = json.loads(request.POST['data'])
item = get_object_or_404_json(models.Item, itemId=data['id']) item = get_object_or_404_json(models.Item, itemId=data['id'])
if item.editable(request.user): if item.editable(request.user):
#FIXME: some things need to be updated after changing this
item.poster_frame = data['position'] item.poster_frame = data['position']
item.save() item.save()
tasks.update_poster(item.itemId) tasks.update_poster(item.itemId)

View file

@ -25,7 +25,7 @@ class List(models.Model):
status = models.CharField(max_length=20, default='private') status = models.CharField(max_length=20, default='private')
_status = ['private', 'public', 'featured'] _status = ['private', 'public', 'featured']
query = DictField(default={"static": True}) query = DictField(default={"static": True})
type= models.CharField(max_length=255, default='static') type = models.CharField(max_length=255, default='static')
description = models.TextField(default='') description = models.TextField(default='')
icon = models.ImageField(default=None, blank=True, icon = models.ImageField(default=None, blank=True,

View file

@ -5,17 +5,18 @@ from datetime import datetime
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models from django.db import models
from django.db.models import Max from django.db.models import Max
from django.conf import settings
from ox.django.fields import DictField from ox.django.fields import DictField
from app.models import site_config
from itemlist.models import List, Position from itemlist.models import List, Position
class UserProfile(models.Model): class UserProfile(models.Model):
reset_token = models.TextField(blank=True, null=True, unique=True) reset_token = models.TextField(blank=True, null=True, unique=True)
user = models.ForeignKey(User, unique=True) user = models.ForeignKey(User, unique=True, related_name='profile')
level = models.IntegerField(default=1)
files_updated = models.DateTimeField(default=datetime.now) files_updated = models.DateTimeField(default=datetime.now)
newsletter = models.BooleanField(default=True) newsletter = models.BooleanField(default=True)
ui = DictField(default={}) ui = DictField(default={})
@ -28,7 +29,7 @@ class UserProfile(models.Model):
def get_ui(self): def get_ui(self):
ui = {} ui = {}
config = site_config() config = settings.CONFIG.copy()
ui.update(config['user']['ui']) ui.update(config['user']['ui'])
def updateUI(ui, new): def updateUI(ui, new):
''' '''
@ -82,11 +83,7 @@ class UserProfile(models.Model):
return ui return ui
def get_level(self): def get_level(self):
if self.user.is_superuser: return ['guest', 'member', 'staff', 'admin'][self.level]
return 'admin'
elif self.user.is_staff:
return 'staff'
return 'member'
def user_post_save(sender, instance, **kwargs): def user_post_save(sender, instance, **kwargs):
profile, new = UserProfile.objects.get_or_create(user=instance) profile, new = UserProfile.objects.get_or_create(user=instance)

View file

@ -18,7 +18,6 @@ import ox
import models import models
from api.actions import actions from api.actions import actions
from app.models import site_config
from item.models import Access, Item from item.models import Access, Item
class SigninForm(forms.Form): class SigninForm(forms.Form):
@ -101,7 +100,7 @@ def signout(request):
response = json_response(text='logged out') response = json_response(text='logged out')
logout(request) logout(request)
response['data']['user'] = site_config()['user'] response['data']['user'] = settings.CONFIG['user']
return render_to_json_response(response) return render_to_json_response(response)
actions.register(signout, cache=False) actions.register(signout, cache=False)