forked from 0x2620/pandora
drop python2 support, upgrade to django 3
This commit is contained in:
parent
80390a1f9b
commit
844382b1e8
124 changed files with 413 additions and 563 deletions
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
|
@ -158,7 +158,7 @@ class AnnotationManager(Manager):
|
||||||
#anonymous can only see public items
|
#anonymous can only see public items
|
||||||
public_layers = self.model.public_layers()
|
public_layers = self.model.public_layers()
|
||||||
|
|
||||||
if user.is_anonymous():
|
if user.is_anonymous:
|
||||||
qs = qs.filter(layer__in=public_layers)
|
qs = qs.filter(layer__in=public_layers)
|
||||||
#users can see public and own
|
#users can see public and own
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
@ -83,16 +81,15 @@ def get_matches(obj, model, layer_type, qs=None):
|
||||||
matches = [-1]
|
matches = [-1]
|
||||||
return Annotation.objects.filter(id__in=matches)
|
return Annotation.objects.filter(id__in=matches)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Annotation(models.Model):
|
class Annotation(models.Model):
|
||||||
objects = managers.AnnotationManager()
|
objects = managers.AnnotationManager()
|
||||||
|
|
||||||
#FIXME: here having a item,start index would be good
|
#FIXME: here having a item,start index would be good
|
||||||
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)
|
||||||
user = models.ForeignKey(User, related_name='annotations')
|
user = models.ForeignKey(User, related_name='annotations', on_delete=models.CASCADE)
|
||||||
item = models.ForeignKey('item.Item', related_name='annotations')
|
item = models.ForeignKey('item.Item', related_name='annotations', on_delete=models.CASCADE)
|
||||||
clip = models.ForeignKey('clip.Clip', null=True, related_name='annotations')
|
clip = models.ForeignKey('clip.Clip', null=True, related_name='annotations', on_delete=models.CASCADE)
|
||||||
|
|
||||||
public_id = models.CharField(max_length=128, unique=True)
|
public_id = models.CharField(max_length=128, unique=True)
|
||||||
#seconds
|
#seconds
|
||||||
|
@ -107,7 +104,7 @@ class Annotation(models.Model):
|
||||||
languages = models.CharField(max_length=255, null=True, blank=True)
|
languages = models.CharField(max_length=255, null=True, blank=True)
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
if user.is_authenticated():
|
if user.is_authenticated:
|
||||||
if user.profile.capability('canEditAnnotations') or \
|
if user.profile.capability('canEditAnnotations') or \
|
||||||
self.user == user or \
|
self.user == user or \
|
||||||
user.groups.filter(id__in=self.item.groups.all()).count() > 0:
|
user.groups.filter(id__in=self.item.groups.all()).count() > 0:
|
||||||
|
@ -400,7 +397,7 @@ class Annotation(models.Model):
|
||||||
return j
|
return j
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s %s-%s" % (self.public_id, self.start, self.end)
|
return "%s %s-%s" % (self.public_id, self.start, self.end)
|
||||||
|
|
||||||
def cleanup_related(sender, **kwargs):
|
def cleanup_related(sender, **kwargs):
|
||||||
kwargs['instance'].cleanup_undefined_relations()
|
kwargs['instance'].cleanup_undefined_relations()
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Count, Sum, F, Value
|
from django.db.models import Count, Sum, F, Value
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
import os
|
import os
|
||||||
|
@ -38,7 +37,7 @@ def get_version():
|
||||||
version = settings.VERSION_EPOCH + version
|
version = settings.VERSION_EPOCH + version
|
||||||
return version
|
return version
|
||||||
else:
|
else:
|
||||||
return u'unknown'
|
return 'unknown'
|
||||||
|
|
||||||
def load_config(init=False):
|
def load_config(init=False):
|
||||||
with open(settings.SITE_CONFIG) as f:
|
with open(settings.SITE_CONFIG) as f:
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import ox.jsonc
|
import ox.jsonc
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from ... import documentation
|
from ... import documentation
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
|
|
||||||
from . import monkey_patch
|
from . import monkey_patch
|
||||||
from . import tasks
|
from . import tasks
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Page(models.Model):
|
class Page(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)
|
||||||
|
@ -20,7 +17,6 @@ class Page(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Settings(models.Model):
|
class Settings(models.Model):
|
||||||
|
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from os.path import exists
|
from os.path import exists
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -12,7 +11,6 @@ from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.signals import pre_delete
|
from django.db.models.signals import pre_delete
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from oxdjango.fields import JSONField
|
from oxdjango.fields import JSONField
|
||||||
|
|
||||||
from oxdjango import fields
|
from oxdjango import fields
|
||||||
|
@ -36,7 +34,6 @@ if not PY2:
|
||||||
def data_path(f, x):
|
def data_path(f, x):
|
||||||
return f.get_path('data.bin')
|
return f.get_path('data.bin')
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class File(models.Model):
|
class File(models.Model):
|
||||||
AV_INFO = (
|
AV_INFO = (
|
||||||
'duration', 'video', 'audio', 'oshash', 'size',
|
'duration', 'video', 'audio', 'oshash', 'size',
|
||||||
|
@ -55,7 +52,7 @@ class File(models.Model):
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
oshash = models.CharField(max_length=16, unique=True)
|
oshash = models.CharField(max_length=16, unique=True)
|
||||||
item = models.ForeignKey("item.Item", related_name='files', null=True)
|
item = models.ForeignKey("item.Item", related_name='files', null=True, on_delete=models.CASCADE)
|
||||||
|
|
||||||
path = models.CharField(max_length=2048, default="") # canoncial path/file
|
path = models.CharField(max_length=2048, default="") # canoncial path/file
|
||||||
sort_path = models.CharField(max_length=2048, default="") # sort name
|
sort_path = models.CharField(max_length=2048, default="") # sort name
|
||||||
|
@ -483,7 +480,7 @@ class File(models.Model):
|
||||||
if k not in keys:
|
if k not in keys:
|
||||||
del data[k]
|
del data[k]
|
||||||
can_see_media = False
|
can_see_media = False
|
||||||
if user and not user.is_anonymous():
|
if user and not user.is_anonymous:
|
||||||
can_see_media = user.profile.capability('canSeeMedia') or \
|
can_see_media = user.profile.capability('canSeeMedia') or \
|
||||||
user.is_staff or \
|
user.is_staff or \
|
||||||
self.item.user == user or \
|
self.item.user == user or \
|
||||||
|
@ -598,15 +595,15 @@ class File(models.Model):
|
||||||
status = {}
|
status = {}
|
||||||
if self.encoding:
|
if self.encoding:
|
||||||
for s in self.streams.all():
|
for s in self.streams.all():
|
||||||
status[s.name()] = u'done' if s.available else u'encoding'
|
status[s.name()] = 'done' if s.available else 'encoding'
|
||||||
config = settings.CONFIG['video']
|
config = settings.CONFIG['video']
|
||||||
max_resolution = self.streams.get(source=None).resolution
|
max_resolution = self.streams.get(source=None).resolution
|
||||||
for resolution in sorted(config['resolutions'], reverse=True):
|
for resolution in sorted(config['resolutions'], reverse=True):
|
||||||
if resolution <= max_resolution:
|
if resolution <= max_resolution:
|
||||||
for f in config['formats']:
|
for f in config['formats']:
|
||||||
name = u'%sp.%s' % (resolution, f)
|
name = '%sp.%s' % (resolution, f)
|
||||||
if name not in status:
|
if name not in status:
|
||||||
status[name] = u'queued'
|
status[name] = 'queued'
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def delete_frames(self):
|
def delete_frames(self):
|
||||||
|
@ -627,7 +624,6 @@ def delete_file(sender, **kwargs):
|
||||||
f.delete_files()
|
f.delete_files()
|
||||||
pre_delete.connect(delete_file, sender=File)
|
pre_delete.connect(delete_file, sender=File)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Volume(models.Model):
|
class Volume(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -636,11 +632,11 @@ class Volume(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)
|
||||||
|
|
||||||
user = models.ForeignKey(User, related_name='volumes')
|
user = models.ForeignKey(User, related_name='volumes', on_delete=models.CASCADE)
|
||||||
name = models.CharField(max_length=1024)
|
name = models.CharField(max_length=1024)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s's %s" % (self.user, self.name)
|
return "%s's %s" % (self.user, self.name)
|
||||||
|
|
||||||
def json(self):
|
def json(self):
|
||||||
return {
|
return {
|
||||||
|
@ -652,7 +648,6 @@ class Volume(models.Model):
|
||||||
def inttime():
|
def inttime():
|
||||||
return int(time.time())
|
return int(time.time())
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Instance(models.Model):
|
class Instance(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -668,11 +663,11 @@ class Instance(models.Model):
|
||||||
path = models.CharField(max_length=2048)
|
path = models.CharField(max_length=2048)
|
||||||
ignore = models.BooleanField(default=False)
|
ignore = models.BooleanField(default=False)
|
||||||
|
|
||||||
file = models.ForeignKey(File, related_name='instances')
|
file = models.ForeignKey(File, related_name='instances', on_delete=models.CASCADE)
|
||||||
volume = models.ForeignKey(Volume, related_name='files')
|
volume = models.ForeignKey(Volume, related_name='files', on_delete=models.CASCADE)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s's %s <%s>" % (self.volume.user, self.path, self.file.oshash)
|
return "%s's %s <%s>" % (self.volume.user, self.path, self.file.oshash)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def public_id(self):
|
def public_id(self):
|
||||||
|
@ -691,14 +686,13 @@ def frame_path(frame, name):
|
||||||
name = "%s%s" % (frame.position, ext)
|
name = "%s%s" % (frame.position, ext)
|
||||||
return frame.file.get_path(name)
|
return frame.file.get_path(name)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Frame(models.Model):
|
class Frame(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("file", "position")
|
unique_together = ("file", "position")
|
||||||
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)
|
||||||
file = models.ForeignKey(File, related_name="frames")
|
file = models.ForeignKey(File, related_name="frames", on_delete=models.CASCADE)
|
||||||
position = models.FloatField()
|
position = models.FloatField()
|
||||||
frame = models.ImageField(default=None, null=True, upload_to=frame_path)
|
frame = models.ImageField(default=None, null=True, upload_to=frame_path)
|
||||||
width = models.IntegerField(default=0)
|
width = models.IntegerField(default=0)
|
||||||
|
@ -711,7 +705,7 @@ class Frame(models.Model):
|
||||||
super(Frame, self).save(*args, **kwargs)
|
super(Frame, self).save(*args, **kwargs)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s/%s' % (self.file, self.position)
|
return '%s/%s' % (self.file, self.position)
|
||||||
|
|
||||||
def delete_frame(sender, **kwargs):
|
def delete_frame(sender, **kwargs):
|
||||||
f = kwargs['instance']
|
f = kwargs['instance']
|
||||||
|
@ -722,18 +716,17 @@ pre_delete.connect(delete_frame, sender=Frame)
|
||||||
def stream_path(f, x):
|
def stream_path(f, x):
|
||||||
return f.path(x)
|
return f.path(x)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Stream(models.Model):
|
class Stream(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("file", "resolution", "format")
|
unique_together = ("file", "resolution", "format")
|
||||||
|
|
||||||
file = models.ForeignKey(File, related_name='streams')
|
file = models.ForeignKey(File, related_name='streams', on_delete=models.CASCADE)
|
||||||
resolution = models.IntegerField(default=96)
|
resolution = models.IntegerField(default=96)
|
||||||
format = models.CharField(max_length=255, default='webm')
|
format = models.CharField(max_length=255, default='webm')
|
||||||
|
|
||||||
media = models.FileField(default=None, blank=True, upload_to=stream_path)
|
media = models.FileField(default=None, blank=True, upload_to=stream_path)
|
||||||
source = models.ForeignKey('Stream', related_name='derivatives', default=None, null=True)
|
source = models.ForeignKey('Stream', related_name='derivatives', default=None, null=True, on_delete=models.CASCADE)
|
||||||
available = models.BooleanField(default=False)
|
available = models.BooleanField(default=False)
|
||||||
oshash = models.CharField(max_length=16, null=True, db_index=True)
|
oshash = models.CharField(max_length=16, null=True, db_index=True)
|
||||||
info = JSONField(default=dict, editable=False)
|
info = JSONField(default=dict, editable=False)
|
||||||
|
@ -753,10 +746,10 @@ class Stream(models.Model):
|
||||||
return os.path.join(settings.MEDIA_ROOT, self.path(), 'timeline')
|
return os.path.join(settings.MEDIA_ROOT, self.path(), 'timeline')
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return u"%sp.%s" % (self.resolution, self.format)
|
return "%sp.%s" % (self.resolution, self.format)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s/%s" % (self.file, self.name())
|
return "%s/%s" % (self.file, self.name())
|
||||||
|
|
||||||
def get(self, resolution, format):
|
def get(self, resolution, format):
|
||||||
streams = []
|
streams = []
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from time import time
|
from time import time
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from oxdjango.fields import JSONField
|
from oxdjango.fields import JSONField
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
@ -19,14 +17,13 @@ User = get_user_model()
|
||||||
'''
|
'''
|
||||||
FIXME: remove this table more migrate to new ChangeLog
|
FIXME: remove this table more migrate to new ChangeLog
|
||||||
'''
|
'''
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Changelog(models.Model):
|
class Changelog(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
type = models.CharField(max_length=255, db_index=True)
|
type = models.CharField(max_length=255, db_index=True)
|
||||||
value = JSONField(default=dict, editable=False)
|
value = JSONField(default=dict, editable=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s %s' % (self.type, self.created)
|
return '%s %s' % (self.type, self.created)
|
||||||
|
|
||||||
def json(self):
|
def json(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
@ -50,19 +47,18 @@ def add_changelog(request, data, id=None):
|
||||||
'user': c.user.username,
|
'user': c.user.username,
|
||||||
})
|
})
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Log(models.Model):
|
class Log(models.Model):
|
||||||
|
|
||||||
action = models.CharField(max_length=255, db_index=True)
|
action = models.CharField(max_length=255, db_index=True)
|
||||||
data = JSONField(default=dict, editable=False)
|
data = JSONField(default=dict, editable=False)
|
||||||
created = models.DateTimeField(db_index=True)
|
created = models.DateTimeField(db_index=True)
|
||||||
user = models.ForeignKey(User, null=True, related_name='changelog')
|
user = models.ForeignKey(User, null=True, related_name='changelog', on_delete=models.CASCADE)
|
||||||
changeid = models.TextField()
|
changeid = models.TextField()
|
||||||
|
|
||||||
objects = managers.LogManager()
|
objects = managers.LogManager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s %s %s' % (self.created, self.action, self.changeid)
|
return '%s %s %s' % (self.created, self.action, self.changeid)
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return ox.toAZ(self.id)
|
return ox.toAZ(self.id)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import models
|
import models
|
||||||
import item.models
|
import item.models
|
||||||
|
@ -18,33 +17,33 @@ def recover_item(id):
|
||||||
created = old.value['created']
|
created = old.value['created']
|
||||||
i.user = user.models.User.objects.get(username=i.data['user'])
|
i.user = user.models.User.objects.get(username=i.data['user'])
|
||||||
for key in [
|
for key in [
|
||||||
u'rendered',
|
'rendered',
|
||||||
u'random',
|
'random',
|
||||||
u'cuts',
|
'cuts',
|
||||||
u'duration',
|
'duration',
|
||||||
u'id',
|
'id',
|
||||||
u'size',
|
'size',
|
||||||
u'posterFrame',
|
'posterFrame',
|
||||||
u'parts',
|
'parts',
|
||||||
u'cutsperminute',
|
'cutsperminute',
|
||||||
u'hue',
|
'hue',
|
||||||
u'numberofcuts',
|
'numberofcuts',
|
||||||
u'durations',
|
'durations',
|
||||||
u'volume',
|
'volume',
|
||||||
u'user',
|
'user',
|
||||||
u'words',
|
'words',
|
||||||
u'videoRatio',
|
'videoRatio',
|
||||||
u'aspectratio',
|
'aspectratio',
|
||||||
u'bitrate',
|
'bitrate',
|
||||||
u'pixels',
|
'pixels',
|
||||||
u'created',
|
'created',
|
||||||
u'numberoffiles',
|
'numberoffiles',
|
||||||
u'modified',
|
'modified',
|
||||||
u'timesaccessed',
|
'timesaccessed',
|
||||||
u'accessed',
|
'accessed',
|
||||||
u'resolution',
|
'resolution',
|
||||||
u'wordsperminute',
|
'wordsperminute',
|
||||||
u'posterRatio'
|
'posterRatio'
|
||||||
]:
|
]:
|
||||||
if key in i.data:
|
if key in i.data:
|
||||||
del i.data[key]
|
del i.data[key]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,7 @@ class ClipManager(Manager):
|
||||||
for l in list(filter(lambda k: k in layer_ids, data['keys'])):
|
for l in list(filter(lambda k: k in layer_ids, data['keys'])):
|
||||||
qs = qs.filter(**{l: True})
|
qs = qs.filter(**{l: True})
|
||||||
#anonymous can only see public clips
|
#anonymous can only see public clips
|
||||||
if not user or user.is_anonymous():
|
if not user or user.is_anonymous:
|
||||||
allowed_level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
allowed_level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
||||||
qs = qs.filter(sort__rightslevel__lte=allowed_level)
|
qs = qs.filter(sort__rightslevel__lte=allowed_level)
|
||||||
#users can see public clips, there own clips and clips of there groups
|
#users can see public clips, there own clips and clips of there groups
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
|
||||||
|
@ -15,7 +13,7 @@ from . import managers
|
||||||
def get_layers(item, interval=None, user=None):
|
def get_layers(item, interval=None, user=None):
|
||||||
from annotation.models import Annotation
|
from annotation.models import Annotation
|
||||||
|
|
||||||
if user and user.is_anonymous():
|
if user and user.is_anonymous:
|
||||||
user = None
|
user = None
|
||||||
|
|
||||||
layers = {}
|
layers = {}
|
||||||
|
@ -45,7 +43,6 @@ def get_layers(item, interval=None, user=None):
|
||||||
return layers
|
return layers
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class MetaClip(object):
|
class MetaClip(object):
|
||||||
def update_calculated_values(self):
|
def update_calculated_values(self):
|
||||||
start = self.start
|
start = self.start
|
||||||
|
@ -184,7 +181,7 @@ class MetaClip(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def public_id(self):
|
def public_id(self):
|
||||||
return u"%s/%0.03f-%0.03f" % (self.item.public_id, float(self.start), float(self.end))
|
return "%s/%0.03f-%0.03f" % (self.item.public_id, float(self.start), float(self.end))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.public_id
|
return self.public_id
|
||||||
|
@ -200,8 +197,8 @@ attrs = {
|
||||||
'modified': models.DateTimeField(auto_now=True),
|
'modified': models.DateTimeField(auto_now=True),
|
||||||
'aspect_ratio': models.FloatField(default=0),
|
'aspect_ratio': models.FloatField(default=0),
|
||||||
|
|
||||||
'item': models.ForeignKey('item.Item', related_name='clips'),
|
'item': models.ForeignKey('item.Item', related_name='clips', on_delete=models.CASCADE),
|
||||||
'sort': models.ForeignKey('item.ItemSort', related_name='matching_clips'),
|
'sort': models.ForeignKey('item.ItemSort', related_name='matching_clips', on_delete=models.CASCADE),
|
||||||
'user': models.IntegerField(db_index=True, null=True),
|
'user': models.IntegerField(db_index=True, null=True),
|
||||||
|
|
||||||
#seconds
|
#seconds
|
||||||
|
@ -226,4 +223,4 @@ Clip = type('Clip', (MetaClip, models.Model), attrs)
|
||||||
|
|
||||||
class ClipRandom(models.Model):
|
class ClipRandom(models.Model):
|
||||||
id = models.BigIntegerField(primary_key=True)
|
id = models.BigIntegerField(primary_key=True)
|
||||||
clip = models.OneToOneField(Clip)
|
clip = models.OneToOneField(Clip, on_delete=models.CASCADE)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import ox
|
import ox
|
||||||
|
@ -154,7 +153,7 @@ def findClips(request, data):
|
||||||
add_annotations(layer, aqs)
|
add_annotations(layer, aqs)
|
||||||
elif 'position' in query:
|
elif 'position' in query:
|
||||||
qs = order_query(qs, query['sort'])
|
qs = order_query(qs, query['sort'])
|
||||||
ids = [u'%s/%0.03f-%0.03f' % (c['item__public_id'], c['start'], c['end'])
|
ids = ['%s/%0.03f-%0.03f' % (c['item__public_id'], c['start'], c['end'])
|
||||||
for c in qs.values('item__public_id', 'start', 'end')]
|
for c in qs.values('item__public_id', 'start', 'end')]
|
||||||
data['conditions'] = data['conditions'] + {
|
data['conditions'] = data['conditions'] + {
|
||||||
'value': data['position'],
|
'value': data['position'],
|
||||||
|
@ -167,7 +166,7 @@ def findClips(request, data):
|
||||||
response['data']['position'] = utils.get_positions(ids, [qs[0].public_id])[0]
|
response['data']['position'] = utils.get_positions(ids, [qs[0].public_id])[0]
|
||||||
elif 'positions' in data:
|
elif 'positions' in data:
|
||||||
qs = order_query(qs, query['sort'])
|
qs = order_query(qs, query['sort'])
|
||||||
ids = [u'%s/%0.03f-%0.03f' % (c['item__public_id'], c['start'], c['end'])
|
ids = ['%s/%0.03f-%0.03f' % (c['item__public_id'], c['start'], c['end'])
|
||||||
for c in qs.values('item__public_id', 'start', 'end')]
|
for c in qs.values('item__public_id', 'start', 'end')]
|
||||||
response['data']['positions'] = utils.get_positions(ids, data['positions'])
|
response['data']['positions'] = utils.get_positions(ids, data['positions'])
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
|
|
|
@ -283,7 +283,7 @@ class DocumentManager(Manager):
|
||||||
qs = qs.distinct()
|
qs = qs.distinct()
|
||||||
|
|
||||||
#anonymous can only see public items
|
#anonymous can only see public items
|
||||||
if not user or user.is_anonymous():
|
if not user or user.is_anonymous:
|
||||||
level = 'guest'
|
level = 'guest'
|
||||||
allowed_level = settings.CONFIG['capabilities']['canSeeDocument'][level]
|
allowed_level = settings.CONFIG['capabilities']['canSeeDocument'][level]
|
||||||
qs = qs.filter(rightslevel__lte=allowed_level)
|
qs = qs.filter(rightslevel__lte=allowed_level)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -13,7 +12,6 @@ from django.db.models import Q, Sum, Max
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.db.models.signals import pre_delete
|
from django.db.models.signals import pre_delete
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from oxdjango.fields import JSONField
|
from oxdjango.fields import JSONField
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
@ -42,13 +40,12 @@ if not PY2:
|
||||||
def get_path(f, x):
|
def get_path(f, x):
|
||||||
return f.path(x)
|
return f.path(x)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Document(models.Model, FulltextMixin):
|
class Document(models.Model, FulltextMixin):
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
user = models.ForeignKey(User, related_name='documents')
|
user = models.ForeignKey(User, related_name='documents', on_delete=models.CASCADE)
|
||||||
groups = models.ManyToManyField(Group, blank=True, related_name='documents')
|
groups = models.ManyToManyField(Group, blank=True, related_name='documents')
|
||||||
|
|
||||||
extension = models.CharField(max_length=255)
|
extension = models.CharField(max_length=255)
|
||||||
|
@ -74,7 +71,7 @@ class Document(models.Model, FulltextMixin):
|
||||||
data = JSONField(default=dict, editable=False)
|
data = JSONField(default=dict, editable=False)
|
||||||
|
|
||||||
def update_access(self, user):
|
def update_access(self, user):
|
||||||
if not user.is_authenticated():
|
if not user.is_authenticated:
|
||||||
user = None
|
user = None
|
||||||
access, created = Access.objects.get_or_create(document=self, user=user)
|
access, created = Access.objects.get_or_create(document=self, user=user)
|
||||||
if not created:
|
if not created:
|
||||||
|
@ -161,7 +158,7 @@ class Document(models.Model, FulltextMixin):
|
||||||
elif i not in ('*', 'dimensions') and i not in self.facet_keys:
|
elif i not in ('*', 'dimensions') and i not in self.facet_keys:
|
||||||
value = data.get(i)
|
value = data.get(i)
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
value = u'\n'.join(value)
|
value = '\n'.join(value)
|
||||||
save(i, value)
|
save(i, value)
|
||||||
|
|
||||||
base_keys = ('id', 'size', 'dimensions', 'extension', 'matches')
|
base_keys = ('id', 'size', 'dimensions', 'extension', 'matches')
|
||||||
|
@ -192,11 +189,11 @@ class Document(models.Model, FulltextMixin):
|
||||||
s.dimensions = ox.sort_string('%d' % prefix) + ox.sort_string('%d' % value)
|
s.dimensions = ox.sort_string('%d' % prefix) + ox.sort_string('%d' % value)
|
||||||
|
|
||||||
def sortNames(values):
|
def sortNames(values):
|
||||||
sort_value = u''
|
sort_value = ''
|
||||||
if values:
|
if values:
|
||||||
sort_value = u'; '.join([get_name_sort(name) for name in values])
|
sort_value = '; '.join([get_name_sort(name) for name in values])
|
||||||
if not sort_value:
|
if not sort_value:
|
||||||
sort_value = u''
|
sort_value = ''
|
||||||
return sort_value.lower()
|
return sort_value.lower()
|
||||||
|
|
||||||
def set_value(s, name, value):
|
def set_value(s, name, value):
|
||||||
|
@ -229,7 +226,7 @@ class Document(models.Model, FulltextMixin):
|
||||||
if isinstance(sort_type, list):
|
if isinstance(sort_type, list):
|
||||||
sort_type = sort_type[0]
|
sort_type = sort_type[0]
|
||||||
if sort_type == 'title':
|
if sort_type == 'title':
|
||||||
value = self.get_value(source, u'Untitled')
|
value = self.get_value(source, 'Untitled')
|
||||||
value = utils.sort_title(value)[:955]
|
value = utils.sort_title(value)[:955]
|
||||||
set_value(s, name, value)
|
set_value(s, name, value)
|
||||||
elif sort_type == 'person':
|
elif sort_type == 'person':
|
||||||
|
@ -237,9 +234,9 @@ class Document(models.Model, FulltextMixin):
|
||||||
value = utils.sort_string(value)[:955]
|
value = utils.sort_string(value)[:955]
|
||||||
set_value(s, name, value)
|
set_value(s, name, value)
|
||||||
elif sort_type == 'string':
|
elif sort_type == 'string':
|
||||||
value = self.get_value(source, u'')
|
value = self.get_value(source, '')
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
value = u','.join(value)
|
value = ','.join(value)
|
||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
value = str(value)
|
value = str(value)
|
||||||
value = utils.sort_string(value)[:955]
|
value = utils.sort_string(value)[:955]
|
||||||
|
@ -319,7 +316,7 @@ class Document(models.Model, FulltextMixin):
|
||||||
return ox.toAZ(self.id)
|
return ox.toAZ(self.id)
|
||||||
|
|
||||||
def access(self, user):
|
def access(self, user):
|
||||||
if user.is_anonymous():
|
if user.is_anonymous:
|
||||||
level = 'guest'
|
level = 'guest'
|
||||||
else:
|
else:
|
||||||
level = user.profile.get_level()
|
level = user.profile.get_level()
|
||||||
|
@ -332,7 +329,7 @@ class Document(models.Model, FulltextMixin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def editable(self, user, item=None):
|
def editable(self, user, item=None):
|
||||||
if not user or user.is_anonymous():
|
if not user or user.is_anonymous:
|
||||||
return False
|
return False
|
||||||
if self.user == user or \
|
if self.user == user or \
|
||||||
self.groups.filter(id__in=user.groups.all()).count() > 0 or \
|
self.groups.filter(id__in=user.groups.all()).count() > 0 or \
|
||||||
|
@ -693,8 +690,8 @@ class ItemProperties(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)
|
||||||
|
|
||||||
item = models.ForeignKey(Item)
|
item = models.ForeignKey(Item, on_delete=models.CASCADE)
|
||||||
document = models.ForeignKey(Document, related_name='descriptions')
|
document = models.ForeignKey(Document, related_name='descriptions', on_delete=models.CASCADE)
|
||||||
description = models.TextField(default="")
|
description = models.TextField(default="")
|
||||||
index = models.IntegerField(default=0)
|
index = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
@ -709,14 +706,13 @@ class ItemProperties(models.Model):
|
||||||
super(ItemProperties, self).save(*args, **kwargs)
|
super(ItemProperties, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Access(models.Model):
|
class Access(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("document", "user")
|
unique_together = ("document", "user")
|
||||||
|
|
||||||
access = models.DateTimeField(auto_now=True)
|
access = models.DateTimeField(auto_now=True)
|
||||||
document = models.ForeignKey(Document, related_name='accessed')
|
document = models.ForeignKey(Document, related_name='accessed', on_delete=models.CASCADE)
|
||||||
user = models.ForeignKey(User, null=True, related_name='accessed_documents')
|
user = models.ForeignKey(User, null=True, related_name='accessed_documents', on_delete=models.CASCADE)
|
||||||
accessed = models.IntegerField(default=0)
|
accessed = models.IntegerField(default=0)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
@ -729,10 +725,9 @@ class Access(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.user:
|
if self.user:
|
||||||
return u"%s/%s/%s" % (self.user, self.document, self.access)
|
return "%s/%s/%s" % (self.user, self.document, self.access)
|
||||||
return u"%s/%s" % (self.item, self.access)
|
return "%s/%s" % (self.item, self.access)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Facet(models.Model):
|
class Facet(models.Model):
|
||||||
'''
|
'''
|
||||||
used for keys that can have multiple values like people, languages etc.
|
used for keys that can have multiple values like people, languages etc.
|
||||||
|
@ -743,13 +738,13 @@ class Facet(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("document", "key", "value")
|
unique_together = ("document", "key", "value")
|
||||||
|
|
||||||
document = models.ForeignKey('Document', related_name='facets')
|
document = models.ForeignKey('Document', related_name='facets', on_delete=models.CASCADE)
|
||||||
key = models.CharField(max_length=200, db_index=True)
|
key = models.CharField(max_length=200, db_index=True)
|
||||||
value = models.CharField(max_length=1000, db_index=True)
|
value = models.CharField(max_length=1000, db_index=True)
|
||||||
sortvalue = models.CharField(max_length=1000, db_index=True)
|
sortvalue = models.CharField(max_length=1000, db_index=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s=%s" % (self.key, self.value)
|
return "%s=%s" % (self.key, self.value)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.sortvalue:
|
if not self.sortvalue:
|
||||||
|
@ -768,18 +763,17 @@ for key in settings.CONFIG['itemKeys']:
|
||||||
if key.get('sortType') == 'person':
|
if key.get('sortType') == 'person':
|
||||||
Document.person_keys.append(key['id'])
|
Document.person_keys.append(key['id'])
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Find(models.Model):
|
class Find(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('document', 'key')
|
unique_together = ('document', 'key')
|
||||||
|
|
||||||
document = models.ForeignKey('Document', related_name='find', db_index=True)
|
document = models.ForeignKey('Document', related_name='find', db_index=True, on_delete=models.CASCADE)
|
||||||
key = models.CharField(max_length=200, db_index=True)
|
key = models.CharField(max_length=200, db_index=True)
|
||||||
value = models.TextField(blank=True, db_index=settings.DB_GIN_TRGM)
|
value = models.TextField(blank=True, db_index=settings.DB_GIN_TRGM)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s=%s' % (self.key, self.value)
|
return '%s=%s' % (self.key, self.value)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Sort
|
Sort
|
||||||
|
@ -787,7 +781,7 @@ table constructed based on info in settings.CONFIG['documentKeys']
|
||||||
'''
|
'''
|
||||||
attrs = {
|
attrs = {
|
||||||
'__module__': 'document.models',
|
'__module__': 'document.models',
|
||||||
'document': models.OneToOneField('Document', related_name='sort', primary_key=True),
|
'document': models.OneToOneField('Document', related_name='sort', primary_key=True, on_delete=models.CASCADE),
|
||||||
'created': models.DateTimeField(null=True, blank=True, db_index=True),
|
'created': models.DateTimeField(null=True, blank=True, db_index=True),
|
||||||
}
|
}
|
||||||
for key in list(filter(lambda k: k.get('sort', False) or k['type'] in ('integer', 'time', 'float', 'date', 'enum'), settings.CONFIG['documentKeys'])):
|
for key in list(filter(lambda k: k.get('sort', False) or k['type'] in ('integer', 'time', 'float', 'date', 'enum'), settings.CONFIG['documentKeys'])):
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
|
@ -124,7 +124,7 @@ class CollectionManager(Manager):
|
||||||
if conditions:
|
if conditions:
|
||||||
qs = qs.filter(conditions)
|
qs = qs.filter(conditions)
|
||||||
|
|
||||||
if user.is_anonymous():
|
if user.is_anonymous:
|
||||||
qs = qs.filter(Q(status='public') | Q(status='featured'))
|
qs = qs.filter(Q(status='public') | Q(status='featured'))
|
||||||
else:
|
else:
|
||||||
qs = qs.filter(Q(status='public') | Q(status='featured') | Q(user=user))
|
qs = qs.filter(Q(status='public') | Q(status='featured') | Q(user=user))
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -10,7 +9,6 @@ from django.db import models
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from oxdjango.fields import JSONField
|
from oxdjango.fields import JSONField
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
@ -36,7 +34,6 @@ def get_collectionview():
|
||||||
def get_collectionsort():
|
def get_collectionsort():
|
||||||
return tuple(settings.CONFIG['user']['ui']['collectionSort'])
|
return tuple(settings.CONFIG['user']['ui']['collectionSort'])
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Collection(models.Model):
|
class Collection(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -44,7 +41,7 @@ class Collection(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)
|
||||||
user = models.ForeignKey(User, related_name='collections')
|
user = models.ForeignKey(User, related_name='collections', on_delete=models.CASCADE)
|
||||||
groups = models.ManyToManyField(Group, blank=True, related_name='collections')
|
groups = models.ManyToManyField(Group, blank=True, related_name='collections')
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
status = models.CharField(max_length=20, default='private')
|
status = models.CharField(max_length=20, default='private')
|
||||||
|
@ -58,7 +55,7 @@ class Collection(models.Model):
|
||||||
view = models.TextField(default=get_collectionview)
|
view = models.TextField(default=get_collectionview)
|
||||||
sort = JSONField(default=get_collectionsort, editable=False)
|
sort = JSONField(default=get_collectionsort, editable=False)
|
||||||
|
|
||||||
poster_frames = JSONField(default=[], editable=False)
|
poster_frames = JSONField(default=list, editable=False)
|
||||||
|
|
||||||
#is through table still required?
|
#is through table still required?
|
||||||
documents = models.ManyToManyField('document.Document', related_name='collections',
|
documents = models.ManyToManyField('document.Document', related_name='collections',
|
||||||
|
@ -117,13 +114,13 @@ class Collection(models.Model):
|
||||||
return self.get_id()
|
return self.get_id()
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return u'%s:%s' % (self.user.username, self.name)
|
return '%s:%s' % (self.user.username, self.name)
|
||||||
|
|
||||||
def accessible(self, user):
|
def accessible(self, user):
|
||||||
return self.user == user or self.status in ('public', 'featured')
|
return self.user == user or self.status in ('public', 'featured')
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
if not user or user.is_anonymous():
|
if not user or user.is_anonymous:
|
||||||
return False
|
return False
|
||||||
if self.user == user or \
|
if self.user == user or \
|
||||||
self.groups.filter(id__in=user.groups.all()).count() > 0 or \
|
self.groups.filter(id__in=user.groups.all()).count() > 0 or \
|
||||||
|
@ -251,7 +248,7 @@ class Collection(models.Model):
|
||||||
elif key == 'subscribers':
|
elif key == 'subscribers':
|
||||||
response[key] = self.subscribed_users.all().count()
|
response[key] = self.subscribed_users.all().count()
|
||||||
elif key == 'subscribed':
|
elif key == 'subscribed':
|
||||||
if user and not user.is_anonymous():
|
if user and not user.is_anonymous:
|
||||||
response[key] = self.subscribed_users.filter(id=user.id).exists()
|
response[key] = self.subscribed_users.filter(id=user.id).exists()
|
||||||
else:
|
else:
|
||||||
response[key] = getattr(self, {
|
response[key] = getattr(self, {
|
||||||
|
@ -318,28 +315,26 @@ class Collection(models.Model):
|
||||||
path = source
|
path = source
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class CollectionDocument(models.Model):
|
class CollectionDocument(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)
|
||||||
collection = models.ForeignKey(Collection)
|
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
|
||||||
index = models.IntegerField(default=0)
|
index = models.IntegerField(default=0)
|
||||||
document = models.ForeignKey('document.Document')
|
document = models.ForeignKey('document.Document', on_delete=models.CASCADE)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s in %s' % (self.document, self.collection)
|
return '%s in %s' % (self.document, self.collection)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Position(models.Model):
|
class Position(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("user", "collection", "section")
|
unique_together = ("user", "collection", "section")
|
||||||
|
|
||||||
collection = models.ForeignKey(Collection, related_name='position')
|
collection = models.ForeignKey(Collection, related_name='position', on_delete=models.CASCADE)
|
||||||
user = models.ForeignKey(User, related_name='collection_positions')
|
user = models.ForeignKey(User, related_name='collection_positions', on_delete=models.CASCADE)
|
||||||
section = models.CharField(max_length=255)
|
section = models.CharField(max_length=255)
|
||||||
position = models.IntegerField(default=0)
|
position = models.IntegerField(default=0)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s/%s/%s' % (self.section, self.position, self.collection)
|
return '%s/%s/%s' % (self.section, self.position, self.collection)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -75,7 +74,7 @@ def findCollections(request, data):
|
||||||
query = parse_query(data, request.user)
|
query = parse_query(data, request.user)
|
||||||
|
|
||||||
#order
|
#order
|
||||||
is_section_request = query['sort'] == [{u'operator': u'+', u'key': u'position'}]
|
is_section_request = query['sort'] == [{'operator': '+', 'key': 'position'}]
|
||||||
|
|
||||||
def is_featured_condition(x):
|
def is_featured_condition(x):
|
||||||
return x['key'] == 'status' and \
|
return x['key'] == 'status' and \
|
||||||
|
@ -89,7 +88,7 @@ def findCollections(request, data):
|
||||||
|
|
||||||
if is_section_request:
|
if is_section_request:
|
||||||
qs = query['qs']
|
qs = query['qs']
|
||||||
if not is_featured and not request.user.is_anonymous():
|
if not is_featured and not request.user.is_anonymous:
|
||||||
qs = qs.filter(position__in=models.Position.objects.filter(user=request.user))
|
qs = qs.filter(position__in=models.Position.objects.filter(user=request.user))
|
||||||
qs = qs.order_by('position__position')
|
qs = qs.order_by('position__position')
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -124,7 +124,7 @@ class EditManager(Manager):
|
||||||
if conditions:
|
if conditions:
|
||||||
qs = qs.filter(conditions)
|
qs = qs.filter(conditions)
|
||||||
|
|
||||||
if user.is_anonymous():
|
if user.is_anonymous:
|
||||||
qs = qs.filter(Q(status='public') | Q(status='featured'))
|
qs = qs.filter(Q(status='public') | Q(status='featured'))
|
||||||
else:
|
else:
|
||||||
qs = qs.filter(Q(status='public') | Q(status='featured') | Q(user=user))
|
qs = qs.filter(Q(status='public') | Q(status='featured') | Q(user=user))
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
@ -15,7 +14,6 @@ from django.db import models, transaction
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from oxdjango.fields import JSONField
|
from oxdjango.fields import JSONField
|
||||||
|
|
||||||
from annotation.models import Annotation
|
from annotation.models import Annotation
|
||||||
|
@ -35,7 +33,6 @@ User = get_user_model()
|
||||||
def get_path(f, x): return f.path(x)
|
def get_path(f, x): return f.path(x)
|
||||||
def get_icon_path(f, x): return get_path(f, 'icon.jpg')
|
def get_icon_path(f, x): return get_path(f, 'icon.jpg')
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Edit(models.Model):
|
class Edit(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -45,7 +42,7 @@ class Edit(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)
|
||||||
user = models.ForeignKey(User, related_name='edits')
|
user = models.ForeignKey(User, related_name='edits', on_delete=models.CASCADE)
|
||||||
groups = models.ManyToManyField(Group, blank=True, related_name='edits')
|
groups = models.ManyToManyField(Group, blank=True, related_name='edits')
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
@ -59,11 +56,11 @@ class Edit(models.Model):
|
||||||
|
|
||||||
icon = models.ImageField(default=None, blank=True, null=True, upload_to=get_icon_path)
|
icon = models.ImageField(default=None, blank=True, null=True, upload_to=get_icon_path)
|
||||||
|
|
||||||
poster_frames = JSONField(default=[], editable=False)
|
poster_frames = JSONField(default=list, editable=False)
|
||||||
subscribed_users = models.ManyToManyField(User, related_name='subscribed_edits')
|
subscribed_users = models.ManyToManyField(User, related_name='subscribed_edits')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s (%s)' % (self.name, self.user)
|
return '%s (%s)' % (self.name, self.user)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls, id):
|
def get(cls, id):
|
||||||
|
@ -73,7 +70,7 @@ class Edit(models.Model):
|
||||||
return cls.objects.get(user__username=username, name=name)
|
return cls.objects.get(user__username=username, name=name)
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return u'%s:%s' % (self.user.username, self.name)
|
return '%s:%s' % (self.user.username, self.name)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return ('/edits/%s' % quote(self.get_id())).replace('%3A', ':')
|
return ('/edits/%s' % quote(self.get_id())).replace('%3A', ':')
|
||||||
|
@ -137,7 +134,7 @@ class Edit(models.Model):
|
||||||
return self.user == user or self.status in ('public', 'featured')
|
return self.user == user or self.status in ('public', 'featured')
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
if not user or user.is_anonymous():
|
if not user or user.is_anonymous:
|
||||||
return False
|
return False
|
||||||
if self.user == user or \
|
if self.user == user or \
|
||||||
self.groups.filter(id__in=user.groups.all()).count() > 0 or \
|
self.groups.filter(id__in=user.groups.all()).count() > 0 or \
|
||||||
|
@ -403,7 +400,7 @@ class Edit(models.Model):
|
||||||
elif key == 'subscribers':
|
elif key == 'subscribers':
|
||||||
response[key] = self.subscribed_users.all().count()
|
response[key] = self.subscribed_users.all().count()
|
||||||
elif key == 'subscribed':
|
elif key == 'subscribed':
|
||||||
if user and not user.is_anonymous():
|
if user and not user.is_anonymous:
|
||||||
response[key] = self.subscribed_users.filter(id=user.id).exists()
|
response[key] = self.subscribed_users.filter(id=user.id).exists()
|
||||||
elif hasattr(self, _map.get(key, key)):
|
elif hasattr(self, _map.get(key, key)):
|
||||||
response[key] = getattr(self, _map.get(key, key))
|
response[key] = getattr(self, _map.get(key, key))
|
||||||
|
@ -430,15 +427,14 @@ class Edit(models.Model):
|
||||||
#p.wait()
|
#p.wait()
|
||||||
shutil.rmtree(tmp)
|
shutil.rmtree(tmp)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Clip(models.Model):
|
class Clip(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)
|
||||||
|
|
||||||
edit = models.ForeignKey(Edit, related_name='clips')
|
edit = models.ForeignKey(Edit, related_name='clips', on_delete=models.CASCADE)
|
||||||
index = models.IntegerField(default=0)
|
index = models.IntegerField(default=0)
|
||||||
item = models.ForeignKey(Item, null=True, default=None, related_name='editclip')
|
item = models.ForeignKey(Item, null=True, default=None, related_name='editclip', on_delete=models.CASCADE)
|
||||||
annotation = models.ForeignKey(Annotation, null=True, default=None, related_name='editclip')
|
annotation = models.ForeignKey(Annotation, null=True, default=None, related_name='editclip', on_delete=models.CASCADE)
|
||||||
start = models.FloatField(default=0)
|
start = models.FloatField(default=0)
|
||||||
end = models.FloatField(default=0)
|
end = models.FloatField(default=0)
|
||||||
duration = models.FloatField(default=0)
|
duration = models.FloatField(default=0)
|
||||||
|
@ -454,8 +450,8 @@ class Clip(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.annotation:
|
if self.annotation:
|
||||||
return u'%s' % self.annotation.public_id
|
return '%s' % self.annotation.public_id
|
||||||
return u'%s/%0.3f-%0.3f' % (self.item.public_id, self.start, self.end)
|
return '%s/%0.3f-%0.3f' % (self.item.public_id, self.start, self.end)
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return ox.toAZ(self.id)
|
return ox.toAZ(self.id)
|
||||||
|
@ -541,17 +537,16 @@ class Clip(models.Model):
|
||||||
|
|
||||||
return clip.models.get_layers(item=item, interval=(start, end), user=user)
|
return clip.models.get_layers(item=item, interval=(start, end), user=user)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Position(models.Model):
|
class Position(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("user", "edit", "section")
|
unique_together = ("user", "edit", "section")
|
||||||
|
|
||||||
edit = models.ForeignKey(Edit, related_name='position')
|
edit = models.ForeignKey(Edit, related_name='position', on_delete=models.CASCADE)
|
||||||
user = models.ForeignKey(User, related_name='edit_position')
|
user = models.ForeignKey(User, related_name='edit_position', on_delete=models.CASCADE)
|
||||||
section = models.CharField(max_length=255)
|
section = models.CharField(max_length=255)
|
||||||
position = models.IntegerField(default=0)
|
position = models.IntegerField(default=0)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s/%s/%s' % (self.section, self.position, self.edit)
|
return '%s/%s/%s' % (self.section, self.position, self.edit)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -404,7 +403,8 @@ def findEdits(request, data):
|
||||||
query = parse_query(data, request.user)
|
query = parse_query(data, request.user)
|
||||||
|
|
||||||
#order
|
#order
|
||||||
is_section_request = query['sort'] == [{u'operator': u'+', u'key': u'position'}]
|
is_section_request = query['sort'] == [{'operator': '+', 'key': 'position'}]
|
||||||
|
|
||||||
def is_featured_condition(x):
|
def is_featured_condition(x):
|
||||||
return x['key'] == 'status' and \
|
return x['key'] == 'status' and \
|
||||||
x['value'] == 'featured' and \
|
x['value'] == 'featured' and \
|
||||||
|
@ -414,7 +414,7 @@ def findEdits(request, data):
|
||||||
|
|
||||||
if is_section_request:
|
if is_section_request:
|
||||||
qs = query['qs']
|
qs = query['qs']
|
||||||
if not is_featured and not request.user.is_anonymous():
|
if not is_featured and not request.user.is_anonymous:
|
||||||
qs = qs.filter(position__in=models.Position.objects.filter(user=request.user))
|
qs = qs.filter(position__in=models.Position.objects.filter(user=request.user))
|
||||||
qs = qs.order_by('position__position')
|
qs = qs.order_by('position__position')
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -14,7 +13,6 @@ from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from django.db.models.signals import pre_delete, post_init
|
from django.db.models.signals import pre_delete, post_init
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from oxdjango.fields import JSONField
|
from oxdjango.fields import JSONField
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
@ -28,7 +26,6 @@ from . import managers
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Entity(models.Model):
|
class Entity(models.Model):
|
||||||
class ValueError(ValueError):
|
class ValueError(ValueError):
|
||||||
'''Raised if a field name or value is invalid (based on the "entities"
|
'''Raised if a field name or value is invalid (based on the "entities"
|
||||||
|
@ -38,7 +35,7 @@ class Entity(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("type", "name")
|
unique_together = ("type", "name")
|
||||||
|
|
||||||
user = models.ForeignKey(User, related_name='entities', null=True, default=None)
|
user = models.ForeignKey(User, related_name='entities', null=True, default=None, on_delete=models.CASCADE)
|
||||||
|
|
||||||
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)
|
||||||
|
@ -64,7 +61,7 @@ class Entity(models.Model):
|
||||||
self.name = self.name.decode('utf-8')
|
self.name = self.name.decode('utf-8')
|
||||||
self.name_sort = get_name_sort(self.name)[:255].lower()
|
self.name_sort = get_name_sort(self.name)[:255].lower()
|
||||||
else:
|
else:
|
||||||
self.name_sort = ox.sort_string(self.name or u'')[:255].lower() or None
|
self.name_sort = ox.sort_string(self.name or '')[:255].lower() or None
|
||||||
self.name_find = '||' + '||'.join((self.name,) + self.alternativeNames) + '||'
|
self.name_find = '||' + '||'.join((self.name,) + self.alternativeNames) + '||'
|
||||||
self.name_find = self.name_find.lower()
|
self.name_find = self.name_find.lower()
|
||||||
super(Entity, self).save(*args, **kwargs)
|
super(Entity, self).save(*args, **kwargs)
|
||||||
|
@ -88,11 +85,11 @@ class Entity(models.Model):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by_name(cls, name, type):
|
def get_by_name(cls, name, type):
|
||||||
return cls.objects.get(name_find__contains=u'|%s|' % name.lower(), type=type)
|
return cls.objects.get(name_find__contains='|%s|' % name.lower(), type=type)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_or_create(model, name):
|
def get_or_create(model, name):
|
||||||
qs = model.objects.filter(name_find__contains=u'|%s|' % name.lower())
|
qs = model.objects.filter(name_find__contains='|%s|' % name.lower())
|
||||||
if qs.count() == 0:
|
if qs.count() == 0:
|
||||||
instance = model(name=name)
|
instance = model(name=name)
|
||||||
instance.save()
|
instance.save()
|
||||||
|
@ -117,7 +114,7 @@ class Entity(models.Model):
|
||||||
DocumentProperties.objects.filter(document=document, entity=self).delete()
|
DocumentProperties.objects.filter(document=document, entity=self).delete()
|
||||||
|
|
||||||
def editable(self, user, item=None):
|
def editable(self, user, item=None):
|
||||||
if not user or user.is_anonymous():
|
if not user or user.is_anonymous:
|
||||||
return False
|
return False
|
||||||
if user.is_staff or \
|
if user.is_staff or \
|
||||||
user.profile.capability('canEditEntities') == True or \
|
user.profile.capability('canEditEntities') == True or \
|
||||||
|
@ -140,7 +137,7 @@ class Entity(models.Model):
|
||||||
data['name'] = "Unnamed"
|
data['name'] = "Unnamed"
|
||||||
name = data['name']
|
name = data['name']
|
||||||
n = 1
|
n = 1
|
||||||
while Entity.objects.filter(name_find__contains=u'|%s|' % name.lower()).exclude(id=self.id).count() > 0:
|
while Entity.objects.filter(name_find__contains='|%s|' % name.lower()).exclude(id=self.id).count() > 0:
|
||||||
n += 1
|
n += 1
|
||||||
name = data['name'] + ' [%d]' % n
|
name = data['name'] + ' [%d]' % n
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -155,7 +152,7 @@ class Entity(models.Model):
|
||||||
name_ = name
|
name_ = name
|
||||||
n = 1
|
n = 1
|
||||||
while name in used_names or \
|
while name in used_names or \
|
||||||
Entity.objects.filter(name_find__contains=u'|%s|' % name.lower()).exclude(id=self.id).count() > 0:
|
Entity.objects.filter(name_find__contains='|%s|' % name.lower()).exclude(id=self.id).count() > 0:
|
||||||
n += 1
|
n += 1
|
||||||
name = name_ + ' [%d]' % n
|
name = name_ + ' [%d]' % n
|
||||||
names.append(name)
|
names.append(name)
|
||||||
|
@ -268,7 +265,7 @@ class Entity(models.Model):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def annotation_value(self):
|
def annotation_value(self):
|
||||||
#return u'<a href="/entities/%s">%s</a>' % (self.get_id(), ox.escape_html(self.name))
|
#return '<a href="/entities/%s">%s</a>' % (self.get_id(), ox.escape_html(self.name))
|
||||||
return ox.escape_html(self.name)
|
return ox.escape_html(self.name)
|
||||||
|
|
||||||
def update_find(self):
|
def update_find(self):
|
||||||
|
@ -292,10 +289,10 @@ class Entity(models.Model):
|
||||||
for key in entity['keys']:
|
for key in entity['keys']:
|
||||||
value = self.data.get(key['id'])
|
value = self.data.get(key['id'])
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
value = u'\n'.join(value)
|
value = '\n'.join(value)
|
||||||
save(key['id'], value)
|
save(key['id'], value)
|
||||||
ids.append(key['id'])
|
ids.append(key['id'])
|
||||||
save('name', u'\n'.join([self.name] + list(self.alternativeNames)))
|
save('name', '\n'.join([self.name] + list(self.alternativeNames)))
|
||||||
self.find.exclude(key__in=ids).delete()
|
self.find.exclude(key__in=ids).delete()
|
||||||
|
|
||||||
def update_matches(self):
|
def update_matches(self):
|
||||||
|
@ -344,7 +341,6 @@ post_init.connect(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class DocumentProperties(models.Model):
|
class DocumentProperties(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -353,42 +349,40 @@ class DocumentProperties(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)
|
||||||
|
|
||||||
document = models.ForeignKey(Document, related_name='documentproperties')
|
document = models.ForeignKey(Document, related_name='documentproperties', on_delete=models.CASCADE)
|
||||||
entity = models.ForeignKey(Entity, related_name='documentproperties')
|
entity = models.ForeignKey(Entity, related_name='documentproperties', on_delete=models.CASCADE)
|
||||||
index = models.IntegerField(default=0)
|
index = models.IntegerField(default=0)
|
||||||
data = JSONField(default=dict, editable=False)
|
data = JSONField(default=dict, editable=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%r-%r" % (self.document, self.entity)
|
return "%r-%r" % (self.document, self.entity)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
|
||||||
super(DocumentProperties, self).save(*args, **kwargs)
|
super(DocumentProperties, self).save(*args, **kwargs)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Find(models.Model):
|
class Find(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("entity", "key")
|
unique_together = ("entity", "key")
|
||||||
|
|
||||||
entity = models.ForeignKey('Entity', related_name='find', db_index=True)
|
entity = models.ForeignKey('Entity', related_name='find', db_index=True, on_delete=models.CASCADE)
|
||||||
key = models.CharField(max_length=200, db_index=True)
|
key = models.CharField(max_length=200, db_index=True)
|
||||||
value = models.TextField(blank=True, db_index=settings.DB_GIN_TRGM)
|
value = models.TextField(blank=True, db_index=settings.DB_GIN_TRGM)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s=%s" % (self.key, self.value)
|
return "%s=%s" % (self.key, self.value)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Link(models.Model):
|
class Link(models.Model):
|
||||||
'''Models entity fields of type "entity".'''
|
'''Models entity fields of type "entity".'''
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("source", "key", "target")
|
unique_together = ("source", "key", "target")
|
||||||
|
|
||||||
source = models.ForeignKey(Entity, related_name='links')
|
source = models.ForeignKey(Entity, related_name='links', on_delete=models.CASCADE)
|
||||||
key = models.CharField(max_length=200)
|
key = models.CharField(max_length=200)
|
||||||
target = models.ForeignKey(Entity, related_name='backlinks')
|
target = models.ForeignKey(Entity, related_name='backlinks', on_delete=models.CASCADE)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s-[%s]->%s" % (self.source, self.key, self.target)
|
return "%s-[%s]->%s" % (self.source, self.key, self.target)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
import ox
|
import ox
|
||||||
|
@ -60,7 +59,7 @@ def addEntity(request, data):
|
||||||
for name in names:
|
for name in names:
|
||||||
name = ox.decode_html(name)
|
name = ox.decode_html(name)
|
||||||
if models.Entity.objects.filter(type=data['type'],
|
if models.Entity.objects.filter(type=data['type'],
|
||||||
name_find__icontains=u'|%s|'%name).count() != 0:
|
name_find__icontains='|%s|'%name).count() != 0:
|
||||||
exists = True
|
exists = True
|
||||||
existing_names.append(name)
|
existing_names.append(name)
|
||||||
if not exists:
|
if not exists:
|
||||||
|
@ -87,7 +86,7 @@ def addEntity(request, data):
|
||||||
type = data['type']
|
type = data['type']
|
||||||
name = 'Unnamed'
|
name = 'Unnamed'
|
||||||
num = 1
|
num = 1
|
||||||
while models.Entity.objects.filter(name_find__icontains=u'|%s|'%name).count() > 0:
|
while models.Entity.objects.filter(name_find__icontains='|%s|'%name).count() > 0:
|
||||||
num += 1
|
num += 1
|
||||||
name = 'Unnamed [%d]' % num
|
name = 'Unnamed [%d]' % num
|
||||||
entity = models.Entity(name=name, type=type)
|
entity = models.Entity(name=name, type=type)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
from oxdjango import fields
|
from oxdjango import fields
|
||||||
|
@ -19,7 +17,6 @@ from . import managers
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Event(models.Model):
|
class Event(models.Model):
|
||||||
'''
|
'''
|
||||||
Events are events in time that can be once or recurring,
|
Events are events in time that can be once or recurring,
|
||||||
|
@ -33,7 +30,7 @@ class Event(models.Model):
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
defined = models.BooleanField(default=False)
|
defined = models.BooleanField(default=False)
|
||||||
|
|
||||||
user = models.ForeignKey(User, null=True, related_name='events')
|
user = models.ForeignKey(User, null=True, related_name='events', on_delete=models.CASCADE)
|
||||||
|
|
||||||
name = models.CharField(null=True, max_length=255, unique=True)
|
name = models.CharField(null=True, max_length=255, unique=True)
|
||||||
name_sort = models.CharField(null=True, max_length=255, db_index=True)
|
name_sort = models.CharField(null=True, max_length=255, db_index=True)
|
||||||
|
@ -66,7 +63,7 @@ class Event(models.Model):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_or_create(model, name):
|
def get_or_create(model, name):
|
||||||
qs = model.objects.filter(name_find__contains=u'|%s|' % name.lower())
|
qs = model.objects.filter(name_find__contains='|%s|' % name.lower())
|
||||||
if qs.count() == 0:
|
if qs.count() == 0:
|
||||||
instance = model(name=name)
|
instance = model(name=name)
|
||||||
instance.save()
|
instance.save()
|
||||||
|
@ -75,7 +72,7 @@ class Event(models.Model):
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
if user and not user.is_anonymous() \
|
if user and not user.is_anonymous \
|
||||||
and (not self.user or \
|
and (not self.user or \
|
||||||
self.user == user or \
|
self.user == user or \
|
||||||
user.profile.capability('canEditEvents')):
|
user.profile.capability('canEditEvents')):
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from celery.task import task
|
from celery.task import task
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -37,7 +36,7 @@ def addEvent(request, data):
|
||||||
for name in names:
|
for name in names:
|
||||||
name = ox.decode_html(name)
|
name = ox.decode_html(name)
|
||||||
if models.Event.objects.filter(defined=True,
|
if models.Event.objects.filter(defined=True,
|
||||||
name_find__icontains=u'|%s|'%name).count() != 0:
|
name_find__icontains='|%s|'%name).count() != 0:
|
||||||
exists = True
|
exists = True
|
||||||
existing_names.append(name)
|
existing_names.append(name)
|
||||||
if not exists:
|
if not exists:
|
||||||
|
@ -93,7 +92,7 @@ def editEvent(request, data):
|
||||||
names = [data.get('name', event.name)] + data.get('alternativeNames', [])
|
names = [data.get('name', event.name)] + data.get('alternativeNames', [])
|
||||||
for name in names:
|
for name in names:
|
||||||
if models.Event.objects.filter(defined=True,
|
if models.Event.objects.filter(defined=True,
|
||||||
name_find__icontains=u'|%s|'%name).exclude(id=event.id).count() != 0:
|
name_find__icontains='|%s|'%name).exclude(id=event.id).count() != 0:
|
||||||
conflict = True
|
conflict = True
|
||||||
conflict_names.append(name)
|
conflict_names.append(name)
|
||||||
if not conflict:
|
if not conflict:
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
from six.moves.urllib.parse import quote
|
from six.moves.urllib.parse import quote
|
||||||
|
@ -7,7 +6,6 @@ from six.moves.urllib.parse import quote
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
from django.db.models.signals import pre_delete
|
from django.db.models.signals import pre_delete
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from oxdjango.fields import JSONField
|
from oxdjango.fields import JSONField
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
@ -17,7 +15,6 @@ from edit.models import Edit
|
||||||
from documentcollection.models import Collection
|
from documentcollection.models import Collection
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Item(models.Model):
|
class Item(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)
|
||||||
|
@ -27,7 +24,7 @@ class Item(models.Model):
|
||||||
data = JSONField(default=dict, editable=False)
|
data = JSONField(default=dict, editable=False)
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
return user.is_authenticated() and user.profile.capability("canManageHome")
|
return user.is_authenticated and user.profile.capability("canManageHome")
|
||||||
|
|
||||||
def edit(self, data):
|
def edit(self, data):
|
||||||
changed = False
|
changed = False
|
||||||
|
@ -153,7 +150,7 @@ class Item(models.Model):
|
||||||
return j
|
return j
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s" % (self.get_id())
|
return "%s" % (self.get_id())
|
||||||
|
|
||||||
def delete_item(type, contentid):
|
def delete_item(type, contentid):
|
||||||
for home in Item.objects.all():
|
for home in Item.objects.all():
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
@ -44,7 +43,13 @@ class Command(BaseCommand):
|
||||||
(document.models.Find._meta.db_table, 'value'), # Document Find
|
(document.models.Find._meta.db_table, 'value'), # Document Find
|
||||||
):
|
):
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
indexes = connection.introspection.get_indexes(cursor, table)
|
contraints = connection.introspection.get_constraints(cursor, table)
|
||||||
|
indexes = {
|
||||||
|
','.join(c['columns']): {'primary_key': c['primary_key'], 'unique': c['unique']}
|
||||||
|
for k, c in contraints.items()
|
||||||
|
if c['index'] or c['primary_key'] or c['unique']
|
||||||
|
}
|
||||||
|
#indexes = connection.introspection.get_indexes(cursor, table)
|
||||||
drop = []
|
drop = []
|
||||||
if column in indexes:
|
if column in indexes:
|
||||||
for sql in (
|
for sql in (
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -38,10 +37,10 @@ class Command(BaseCommand):
|
||||||
versions = os.path.join(prefix, os.path.dirname(path), 'Versions')
|
versions = os.path.join(prefix, os.path.dirname(path), 'Versions')
|
||||||
s = f.streams.filter(source=None)[0]
|
s = f.streams.filter(source=None)[0]
|
||||||
basename = os.path.basename(path).rsplit('.', 1)[0]
|
basename = os.path.basename(path).rsplit('.', 1)[0]
|
||||||
target = os.path.join(versions, u'%s.%s' % (basename, s.format))
|
target = os.path.join(versions, '%s.%s' % (basename, s.format))
|
||||||
link(s.media.path, target)
|
link(s.media.path, target)
|
||||||
else:
|
else:
|
||||||
s = f.streams.filter(source=None)[0]
|
s = f.streams.filter(source=None)[0]
|
||||||
basename = path.rsplit('.', 1)[0]
|
basename = path.rsplit('.', 1)[0]
|
||||||
target = os.path.join(prefix, u'%s.%s' % (basename, s.format))
|
target = os.path.join(prefix, '%s.%s' % (basename, s.format))
|
||||||
link(s.media.path, target)
|
link(s.media.path, target)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
@ -81,7 +80,7 @@ def parseCondition(condition, user, owner=None):
|
||||||
|
|
||||||
if (not exclude and op == '=' or op in ('$', '^')) and v == '':
|
if (not exclude and op == '=' or op in ('$', '^')) and v == '':
|
||||||
return Q()
|
return Q()
|
||||||
elif k == 'filename' and (user.is_anonymous() or not user.profile.capability('canSeeMedia')):
|
elif k == 'filename' and (user.is_anonymous or not user.profile.capability('canSeeMedia')):
|
||||||
return Q(id=0)
|
return Q(id=0)
|
||||||
elif k == 'oshash':
|
elif k == 'oshash':
|
||||||
return Q(files__oshash=v)
|
return Q(files__oshash=v)
|
||||||
|
@ -100,7 +99,7 @@ def parseCondition(condition, user, owner=None):
|
||||||
q = ~q
|
q = ~q
|
||||||
return q
|
return q
|
||||||
elif k in ('canplayvideo', 'canplayclips'):
|
elif k in ('canplayvideo', 'canplayclips'):
|
||||||
level = user.is_anonymous() and 'guest' or user.profile.get_level()
|
level = user.is_anonymous and 'guest' or user.profile.get_level()
|
||||||
allowed_level = settings.CONFIG['capabilities'][{
|
allowed_level = settings.CONFIG['capabilities'][{
|
||||||
'canplayvideo': 'canPlayVideo',
|
'canplayvideo': 'canPlayVideo',
|
||||||
'canplayclips': 'canPlayClips'
|
'canplayclips': 'canPlayClips'
|
||||||
|
@ -249,7 +248,7 @@ class ItemManager(Manager):
|
||||||
if l != "*":
|
if l != "*":
|
||||||
l = l.split(":")
|
l = l.split(":")
|
||||||
only_public = True
|
only_public = True
|
||||||
if not user.is_anonymous():
|
if not user.is_anonymous:
|
||||||
if len(l) == 1:
|
if len(l) == 1:
|
||||||
l = [user.username] + l
|
l = [user.username] + l
|
||||||
if user.username == l[0]:
|
if user.username == l[0]:
|
||||||
|
@ -305,7 +304,7 @@ class ItemManager(Manager):
|
||||||
qs = qs.distinct()
|
qs = qs.distinct()
|
||||||
|
|
||||||
#anonymous can only see public items
|
#anonymous can only see public items
|
||||||
if not user or user.is_anonymous():
|
if not user or user.is_anonymous:
|
||||||
level = 'guest'
|
level = 'guest'
|
||||||
allowed_level = settings.CONFIG['capabilities']['canSeeItem'][level]
|
allowed_level = settings.CONFIG['capabilities']['canSeeItem'][level]
|
||||||
qs = qs.filter(level__lte=allowed_level)
|
qs = qs.filter(level__lte=allowed_level)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
@ -21,7 +20,6 @@ from django.core.files.temp import NamedTemporaryFile
|
||||||
from django.db import models, transaction, connection
|
from django.db import models, transaction, connection
|
||||||
from django.db.models import Q, Sum, Max
|
from django.db.models import Q, Sum, Max
|
||||||
from django.db.models.signals import pre_delete
|
from django.db.models.signals import pre_delete
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from django.utils import datetime_safe
|
from django.utils import datetime_safe
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
@ -164,12 +162,11 @@ def get_poster_path(f, x):
|
||||||
def get_torrent_path(f, x):
|
def get_torrent_path(f, x):
|
||||||
return get_path(f, 'torrent.torrent')
|
return get_path(f, 'torrent.torrent')
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Item(models.Model):
|
class Item(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)
|
||||||
|
|
||||||
user = models.ForeignKey(User, null=True, related_name='items')
|
user = models.ForeignKey(User, null=True, related_name='items', on_delete=models.CASCADE)
|
||||||
groups = models.ManyToManyField(Group, blank=True, related_name='items')
|
groups = models.ManyToManyField(Group, blank=True, related_name='items')
|
||||||
|
|
||||||
# while metadata is updated, files are set to rendered=False
|
# while metadata is updated, files are set to rendered=False
|
||||||
|
@ -221,7 +218,7 @@ class Item(models.Model):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def access(self, user):
|
def access(self, user):
|
||||||
if user.is_anonymous():
|
if user.is_anonymous:
|
||||||
level = 'guest'
|
level = 'guest'
|
||||||
else:
|
else:
|
||||||
level = user.profile.get_level()
|
level = user.profile.get_level()
|
||||||
|
@ -236,7 +233,7 @@ class Item(models.Model):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
if user.is_anonymous():
|
if user.is_anonymous:
|
||||||
return False
|
return False
|
||||||
if user.profile.capability('canEditMetadata') or \
|
if user.profile.capability('canEditMetadata') or \
|
||||||
user.is_staff or \
|
user.is_staff or \
|
||||||
|
@ -350,10 +347,10 @@ class Item(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
year = self.get('year')
|
year = self.get('year')
|
||||||
if year:
|
if year:
|
||||||
string = u'%s (%s)' % (ox.decode_html(self.get('title', 'Untitled')), self.get('year'))
|
string = '%s (%s)' % (ox.decode_html(self.get('title', 'Untitled')), self.get('year'))
|
||||||
else:
|
else:
|
||||||
string = self.get('title', u'Untitled')
|
string = self.get('title', 'Untitled')
|
||||||
return u'[%s] %s' % (self.public_id, string)
|
return '[%s] %s' % (self.public_id, string)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/%s' % self.public_id
|
return '/%s' % self.public_id
|
||||||
|
@ -400,7 +397,7 @@ class Item(models.Model):
|
||||||
title = self.get(key, 'Untitled')
|
title = self.get(key, 'Untitled')
|
||||||
while q.count() != 0:
|
while q.count() != 0:
|
||||||
n += 1
|
n += 1
|
||||||
self.data[key] = u'%s [%d]' % (title, n)
|
self.data[key] = '%s [%d]' % (title, n)
|
||||||
oxdbId = self.oxdb_id()
|
oxdbId = self.oxdb_id()
|
||||||
q = Item.objects.filter(oxdbId=oxdbId).exclude(id=self.id)
|
q = Item.objects.filter(oxdbId=oxdbId).exclude(id=self.id)
|
||||||
self.oxdbId = oxdbId
|
self.oxdbId = oxdbId
|
||||||
|
@ -821,7 +818,7 @@ class Item(models.Model):
|
||||||
for key in settings.CONFIG['itemKeys']:
|
for key in settings.CONFIG['itemKeys']:
|
||||||
i = key['id']
|
i = key['id']
|
||||||
if i == 'title':
|
if i == 'title':
|
||||||
save(i, u'\n'.join(get_titles()))
|
save(i, '\n'.join(get_titles()))
|
||||||
elif i == 'rightslevel':
|
elif i == 'rightslevel':
|
||||||
save(i, self.level)
|
save(i, self.level)
|
||||||
elif i == 'filename':
|
elif i == 'filename':
|
||||||
|
@ -830,17 +827,17 @@ class Item(models.Model):
|
||||||
qs = Annotation.objects.filter(item=self)
|
qs = Annotation.objects.filter(item=self)
|
||||||
qs = qs.filter(layer__in=Annotation.public_layers()).exclude(findvalue=None)
|
qs = qs.filter(layer__in=Annotation.public_layers()).exclude(findvalue=None)
|
||||||
qs = qs.order_by('start')
|
qs = qs.order_by('start')
|
||||||
save(i, u'\n'.join([l.findvalue for l in qs]))
|
save(i, '\n'.join([l.findvalue for l in qs]))
|
||||||
elif key['type'] == 'layer':
|
elif key['type'] == 'layer':
|
||||||
qs = Annotation.objects.filter(item=self).exclude(findvalue=None)
|
qs = Annotation.objects.filter(item=self).exclude(findvalue=None)
|
||||||
qs = qs.filter(layer=i)
|
qs = qs.filter(layer=i)
|
||||||
qs = qs.order_by('start')
|
qs = qs.order_by('start')
|
||||||
save(i, u'\n'.join(list(filter(None, [l.findvalue for l in qs]))))
|
save(i, '\n'.join(list(filter(None, [l.findvalue for l in qs]))))
|
||||||
layer_keys.append(i)
|
layer_keys.append(i)
|
||||||
elif i != '*' and i not in self.facet_keys:
|
elif i != '*' and i not in self.facet_keys:
|
||||||
value = self.get(i)
|
value = self.get(i)
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
value = u'\n'.join(value)
|
value = '\n'.join(value)
|
||||||
save(i, value)
|
save(i, value)
|
||||||
|
|
||||||
for key in self.facet_keys:
|
for key in self.facet_keys:
|
||||||
|
@ -911,11 +908,11 @@ class Item(models.Model):
|
||||||
s = ItemSort(item=self)
|
s = ItemSort(item=self)
|
||||||
|
|
||||||
def sortNames(values):
|
def sortNames(values):
|
||||||
sort_value = u''
|
sort_value = ''
|
||||||
if values:
|
if values:
|
||||||
sort_value = u'; '.join([get_name_sort(name) for name in values])
|
sort_value = '; '.join([get_name_sort(name) for name in values])
|
||||||
if not sort_value:
|
if not sort_value:
|
||||||
sort_value = u''
|
sort_value = ''
|
||||||
return sort_value.lower()
|
return sort_value.lower()
|
||||||
|
|
||||||
def set_value(s, name, value):
|
def set_value(s, name, value):
|
||||||
|
@ -1019,7 +1016,7 @@ class Item(models.Model):
|
||||||
sort_type = sort_type[0]
|
sort_type = sort_type[0]
|
||||||
if name not in self.base_keys:
|
if name not in self.base_keys:
|
||||||
if sort_type == 'title':
|
if sort_type == 'title':
|
||||||
value = get_title_sort(self.get(source, u'Untitled'))
|
value = get_title_sort(self.get(source, 'Untitled'))
|
||||||
value = utils.sort_title(value)[:955]
|
value = utils.sort_title(value)[:955]
|
||||||
set_value(s, name, value)
|
set_value(s, name, value)
|
||||||
elif sort_type == 'person':
|
elif sort_type == 'person':
|
||||||
|
@ -1027,9 +1024,9 @@ class Item(models.Model):
|
||||||
value = utils.sort_string(value)[:955]
|
value = utils.sort_string(value)[:955]
|
||||||
set_value(s, name, value)
|
set_value(s, name, value)
|
||||||
elif sort_type == 'string':
|
elif sort_type == 'string':
|
||||||
value = self.get(source, u'')
|
value = self.get(source, '')
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
value = u','.join(value)
|
value = ','.join(value)
|
||||||
value = utils.sort_string(value)[:955]
|
value = utils.sort_string(value)[:955]
|
||||||
set_value(s, name, value)
|
set_value(s, name, value)
|
||||||
elif sort_type == 'words':
|
elif sort_type == 'words':
|
||||||
|
@ -1784,7 +1781,6 @@ for key in settings.CONFIG['itemKeys']:
|
||||||
if key.get('sortType') == 'person':
|
if key.get('sortType') == 'person':
|
||||||
Item.person_keys.append(key['id'])
|
Item.person_keys.append(key['id'])
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class ItemFind(models.Model):
|
class ItemFind(models.Model):
|
||||||
"""
|
"""
|
||||||
used to find items,
|
used to find items,
|
||||||
|
@ -1795,19 +1791,19 @@ class ItemFind(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("item", "key")
|
unique_together = ("item", "key")
|
||||||
|
|
||||||
item = models.ForeignKey('Item', related_name='find', db_index=True)
|
item = models.ForeignKey('Item', related_name='find', db_index=True, on_delete=models.CASCADE)
|
||||||
key = models.CharField(max_length=200, db_index=True)
|
key = models.CharField(max_length=200, db_index=True)
|
||||||
value = models.TextField(blank=True, db_index=settings.DB_GIN_TRGM)
|
value = models.TextField(blank=True, db_index=settings.DB_GIN_TRGM)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s=%s" % (self.key, self.value)
|
return "%s=%s" % (self.key, self.value)
|
||||||
'''
|
'''
|
||||||
ItemSort
|
ItemSort
|
||||||
table constructed based on info in settings.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, on_delete=models.CASCADE),
|
||||||
'duration': models.FloatField(null=True, blank=True, db_index=True),
|
'duration': models.FloatField(null=True, blank=True, db_index=True),
|
||||||
'width': models.BigIntegerField(null=True, blank=True, db_index=True),
|
'width': models.BigIntegerField(null=True, blank=True, db_index=True),
|
||||||
'height': models.BigIntegerField(null=True, blank=True, db_index=True),
|
'height': models.BigIntegerField(null=True, blank=True, db_index=True),
|
||||||
|
@ -1826,14 +1822,13 @@ for key in list(filter(lambda k: k.get('sort', False) or k['type'] in ('integer'
|
||||||
ItemSort = type('ItemSort', (models.Model,), attrs)
|
ItemSort = type('ItemSort', (models.Model,), attrs)
|
||||||
ItemSort.fields = [f.name for f in ItemSort._meta.fields]
|
ItemSort.fields = [f.name for f in ItemSort._meta.fields]
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Access(models.Model):
|
class Access(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("item", "user")
|
unique_together = ("item", "user")
|
||||||
|
|
||||||
access = models.DateTimeField(auto_now=True)
|
access = models.DateTimeField(auto_now=True)
|
||||||
item = models.ForeignKey(Item, related_name='accessed')
|
item = models.ForeignKey(Item, related_name='accessed', on_delete=models.CASCADE)
|
||||||
user = models.ForeignKey(User, null=True, related_name='accessed_items')
|
user = models.ForeignKey(User, null=True, related_name='accessed_items', on_delete=models.CASCADE)
|
||||||
accessed = models.IntegerField(default=0)
|
accessed = models.IntegerField(default=0)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
@ -1846,10 +1841,9 @@ class Access(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.user:
|
if self.user:
|
||||||
return u"%s/%s/%s" % (self.user, self.item, self.access)
|
return "%s/%s/%s" % (self.user, self.item, self.access)
|
||||||
return u"%s/%s" % (self.item, self.access)
|
return "%s/%s" % (self.item, self.access)
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Facet(models.Model):
|
class Facet(models.Model):
|
||||||
'''
|
'''
|
||||||
used for keys that can have multiple values like people, languages etc.
|
used for keys that can have multiple values like people, languages etc.
|
||||||
|
@ -1860,13 +1854,13 @@ class Facet(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("item", "key", "value")
|
unique_together = ("item", "key", "value")
|
||||||
|
|
||||||
item = models.ForeignKey('Item', related_name='facets')
|
item = models.ForeignKey('Item', related_name='facets', on_delete=models.CASCADE)
|
||||||
key = models.CharField(max_length=200, db_index=True)
|
key = models.CharField(max_length=200, db_index=True)
|
||||||
value = models.CharField(max_length=1000, db_index=True)
|
value = models.CharField(max_length=1000, db_index=True)
|
||||||
sortvalue = models.CharField(max_length=1000, db_index=True)
|
sortvalue = models.CharField(max_length=1000, db_index=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s=%s" % (self.key, self.value)
|
return "%s=%s" % (self.key, self.value)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.sortvalue:
|
if not self.sortvalue:
|
||||||
|
@ -1886,7 +1880,7 @@ class Description(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class AnnotationSequence(models.Model):
|
class AnnotationSequence(models.Model):
|
||||||
item = models.OneToOneField('Item', related_name='_annotation_sequence')
|
item = models.OneToOneField('Item', related_name='_annotation_sequence', on_delete=models.CASCADE)
|
||||||
value = models.BigIntegerField(default=1)
|
value = models.BigIntegerField(default=1)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
51
pandora/item/site.py
Normal file
51
pandora/item/site.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from django.urls import path, re_path
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
[
|
||||||
|
#frames
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/(?P<size>\d+)p(?P<position>[\d\.]*)\.jpg$', views.frame),
|
||||||
|
|
||||||
|
#timelines
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/timeline(?P<mode>[a-z]*)(?P<size>\d+)p(?P<position>\d+)\.(?P<format>png|jpg)$', views.timeline),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/timeline(?P<mode>[a-z]*)(?P<size>\d+)p\.(?P<format>png|jpg)$', views.timeline),
|
||||||
|
|
||||||
|
#download
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/download$', views.download),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/download/$', views.download),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/download/source/(?P<part>\d+)?$', views.download_source),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/download/(?P<resolution>\d+)p(?P<part>\d+)\.(?P<format>webm|ogv|mp4)$', views.download),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/download/(?P<resolution>\d+)p\.(?P<format>webm|ogv|mp4)$', views.download),
|
||||||
|
|
||||||
|
#video
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/(?P<resolution>\d+)p(?P<index>\d*)\.(?P<format>webm|ogv|mp4)$', views.video),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/(?P<resolution>\d+)p(?P<index>\d*)\.(?P<track>.+)\.(?P<format>webm|ogv|mp4)$', views.video),
|
||||||
|
|
||||||
|
#torrent
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/torrent$', views.torrent),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/torrent/(?P<filename>.*?)$', views.torrent),
|
||||||
|
|
||||||
|
#export
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/json$', views.item_json),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/xml$', views.item_xml),
|
||||||
|
|
||||||
|
#srt export
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/(?P<layer>.+)\.(?:(?P<language>.{2})\.)?(?P<ext>srt|vtt)$', views.srt),
|
||||||
|
|
||||||
|
#icon
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/icon(?P<size>\d*)\.jpg$', views.icon),
|
||||||
|
|
||||||
|
#poster
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/posterframe(?P<position>\d+).jpg$', views.poster_frame),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/poster(?P<size>\d+)\.jpg$', views.poster),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/siteposter(?P<size>\d*)\.jpg$', views.siteposter),
|
||||||
|
re_path(r'^(?P<id>[A-Z0-9].*)/poster\.jpg$', views.siteposter),
|
||||||
|
|
||||||
|
re_path(r'^random$', views.random_annotation),
|
||||||
|
],
|
||||||
|
'item',
|
||||||
|
'item',
|
||||||
|
]
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, with_statement, print_function
|
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from django.conf.urls import url
|
|
||||||
|
|
||||||
from . import views
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
#frames
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/(?P<size>\d+)p(?P<position>[\d\.]*)\.jpg$', views.frame),
|
|
||||||
|
|
||||||
#timelines
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/timeline(?P<mode>[a-z]*)(?P<size>\d+)p(?P<position>\d+)\.(?P<format>png|jpg)$', views.timeline),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/timeline(?P<mode>[a-z]*)(?P<size>\d+)p\.(?P<format>png|jpg)$', views.timeline),
|
|
||||||
|
|
||||||
#download
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/download$', views.download),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/download/$', views.download),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/download/source/(?P<part>\d+)?$', views.download_source),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/download/(?P<resolution>\d+)p(?P<part>\d+)\.(?P<format>webm|ogv|mp4)$', views.download),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/download/(?P<resolution>\d+)p\.(?P<format>webm|ogv|mp4)$', views.download),
|
|
||||||
|
|
||||||
#video
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/(?P<resolution>\d+)p(?P<index>\d*)\.(?P<format>webm|ogv|mp4)$', views.video),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/(?P<resolution>\d+)p(?P<index>\d*)\.(?P<track>.+)\.(?P<format>webm|ogv|mp4)$', views.video),
|
|
||||||
|
|
||||||
#torrent
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/torrent$', views.torrent),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/torrent/(?P<filename>.*?)$', views.torrent),
|
|
||||||
|
|
||||||
#export
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/json$', views.item_json),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/xml$', views.item_xml),
|
|
||||||
|
|
||||||
#srt export
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/(?P<layer>.+)\.(?:(?P<language>.{2})\.)?(?P<ext>srt|vtt)$', views.srt),
|
|
||||||
|
|
||||||
#icon
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/icon(?P<size>\d*)\.jpg$', views.icon),
|
|
||||||
|
|
||||||
#poster
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/posterframe(?P<position>\d+).jpg$', views.poster_frame),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/poster(?P<size>\d+)\.jpg$', views.poster),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/siteposter(?P<size>\d*)\.jpg$', views.siteposter),
|
|
||||||
url(r'^(?P<id>[A-Z0-9].*)/poster\.jpg$', views.siteposter),
|
|
||||||
|
|
||||||
url(r'^random$', views.random_annotation),
|
|
||||||
]
|
|
|
@ -55,14 +55,14 @@ def plural_key(term):
|
||||||
|
|
||||||
def sort_title(title):
|
def sort_title(title):
|
||||||
|
|
||||||
title = title.replace(u'Æ', 'Ae')
|
title = title.replace('Æ', 'Ae')
|
||||||
if isinstance(title, bytes):
|
if isinstance(title, bytes):
|
||||||
title = title.decode('utf-8')
|
title = title.decode('utf-8')
|
||||||
title = ox.decode_html(title)
|
title = ox.decode_html(title)
|
||||||
title = sort_string(title)
|
title = sort_string(title)
|
||||||
|
|
||||||
#title
|
#title
|
||||||
title = re.sub(u'[\'!¿¡,\.;\-"\:\*\[\]]', '', title)
|
title = re.sub('[\'!¿¡,\.;\-"\:\*\[\]]', '', title)
|
||||||
return title.strip()
|
return title.strip()
|
||||||
|
|
||||||
def get_positions(ids, pos, decode_id=False):
|
def get_positions(ids, pos, decode_id=False):
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import mimetypes
|
import mimetypes
|
||||||
|
@ -144,7 +143,7 @@ def get_positions(request, query):
|
||||||
return utils.get_positions(ids, query['positions'])
|
return utils.get_positions(ids, query['positions'])
|
||||||
|
|
||||||
def is_editable(request, item):
|
def is_editable(request, item):
|
||||||
if request.user.is_anonymous():
|
if request.user.is_anonymous:
|
||||||
return False
|
return False
|
||||||
if not hasattr(request, 'user_group_names'):
|
if not hasattr(request, 'user_group_names'):
|
||||||
request.user_group_names = {g.name for g in request.user.groups.all()}
|
request.user_group_names = {g.name for g in request.user.groups.all()}
|
||||||
|
@ -1097,7 +1096,7 @@ def video(request, id, resolution, format, index=None, track=None):
|
||||||
ext = '.%s' % format
|
ext = '.%s' % format
|
||||||
duration = stream.info['duration']
|
duration = stream.info['duration']
|
||||||
|
|
||||||
filename = u"Clip of %s - %s-%s - %s %s%s" % (
|
filename = "Clip of %s - %s-%s - %s %s%s" % (
|
||||||
item.get('title'),
|
item.get('title'),
|
||||||
ox.format_duration(t[0] * 1000).replace(':', '.')[:-4],
|
ox.format_duration(t[0] * 1000).replace(':', '.')[:-4],
|
||||||
ox.format_duration(t[1] * 1000).replace(':', '.')[:-4],
|
ox.format_duration(t[1] * 1000).replace(':', '.')[:-4],
|
||||||
|
@ -1166,9 +1165,9 @@ def srt(request, id, layer, language=None, index=None, ext='srt'):
|
||||||
content_type, encoder = _subtitle_formats[ext]
|
content_type, encoder = _subtitle_formats[ext]
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
if language:
|
if language:
|
||||||
filename = u"%s.%s.%s" % (item.get('title'), language, ext)
|
filename = "%s.%s.%s" % (item.get('title'), language, ext)
|
||||||
else:
|
else:
|
||||||
filename = u"%s.%s" % (item.get('title'), ext)
|
filename = "%s.%s" % (item.get('title'), ext)
|
||||||
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % quote(filename.encode('utf-8'))
|
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % quote(filename.encode('utf-8'))
|
||||||
response['Content-Type'] = content_type
|
response['Content-Type'] = content_type
|
||||||
response.write(item.srt(layer, language, encoder=encoder))
|
response.write(item.srt(layer, language, encoder=encoder))
|
||||||
|
@ -1206,7 +1205,7 @@ def atom_xml(request):
|
||||||
el.text = atom_link
|
el.text = atom_link
|
||||||
|
|
||||||
level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
||||||
if not request.user.is_anonymous():
|
if not request.user.is_anonymous:
|
||||||
level = request.user.profile.level
|
level = request.user.profile.level
|
||||||
for item in models.Item.objects.filter(level__lte=level, rendered=True).order_by('-created')[:7]:
|
for item in models.Item.objects.filter(level__lte=level, rendered=True).order_by('-created')[:7]:
|
||||||
if add_updated:
|
if add_updated:
|
||||||
|
@ -1232,7 +1231,7 @@ def atom_xml(request):
|
||||||
if item.get('director'):
|
if item.get('director'):
|
||||||
el = ET.SubElement(entry, "author")
|
el = ET.SubElement(entry, "author")
|
||||||
name = ET.SubElement(el, "name")
|
name = ET.SubElement(el, "name")
|
||||||
name.text = ox.decode_html(u', '.join(item.get('director')))
|
name.text = ox.decode_html(', '.join(item.get('director')))
|
||||||
elif item.user:
|
elif item.user:
|
||||||
el = ET.SubElement(entry, "author")
|
el = ET.SubElement(entry, "author")
|
||||||
name = ET.SubElement(el, "name")
|
name = ET.SubElement(el, "name")
|
||||||
|
@ -1283,7 +1282,7 @@ def atom_xml(request):
|
||||||
el = ET.SubElement(format, key)
|
el = ET.SubElement(format, key)
|
||||||
el.text = unicode(value)
|
el.text = unicode(value)
|
||||||
el = ET.SubElement(format, 'pixel_aspect_ratio')
|
el = ET.SubElement(format, 'pixel_aspect_ratio')
|
||||||
el.text = u"1:1"
|
el.text = "1:1"
|
||||||
|
|
||||||
if has_capability(request.user, 'canDownloadVideo'):
|
if has_capability(request.user, 'canDownloadVideo'):
|
||||||
if item.torrent:
|
if item.torrent:
|
||||||
|
@ -1386,7 +1385,7 @@ def sitemap_part_xml(request, part):
|
||||||
|
|
||||||
def item_json(request, id):
|
def item_json(request, id):
|
||||||
level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
||||||
if not request.user.is_anonymous():
|
if not request.user.is_anonymous:
|
||||||
level = request.user.profile.level
|
level = request.user.profile.level
|
||||||
qs = models.Item.objects.filter(public_id=id, level__lte=level)
|
qs = models.Item.objects.filter(public_id=id, level__lte=level)
|
||||||
if qs.count() == 0:
|
if qs.count() == 0:
|
||||||
|
@ -1399,7 +1398,7 @@ def item_json(request, id):
|
||||||
|
|
||||||
def item_xml(request, id):
|
def item_xml(request, id):
|
||||||
level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
||||||
if not request.user.is_anonymous():
|
if not request.user.is_anonymous:
|
||||||
level = request.user.profile.level
|
level = request.user.profile.level
|
||||||
qs = models.Item.objects.filter(public_id=id, level__lte=level)
|
qs = models.Item.objects.filter(public_id=id, level__lte=level)
|
||||||
if qs.count() == 0:
|
if qs.count() == 0:
|
||||||
|
@ -1439,7 +1438,7 @@ def item(request, id):
|
||||||
view = None
|
view = None
|
||||||
template = 'index.html'
|
template = 'index.html'
|
||||||
level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
level = settings.CONFIG['capabilities']['canSeeItem']['guest']
|
||||||
if not request.user.is_anonymous():
|
if not request.user.is_anonymous:
|
||||||
level = request.user.profile.level
|
level = request.user.profile.level
|
||||||
qs = models.Item.objects.filter(public_id=id, level__lte=level)
|
qs = models.Item.objects.filter(public_id=id, level__lte=level)
|
||||||
if qs.count() == 0:
|
if qs.count() == 0:
|
||||||
|
@ -1484,7 +1483,7 @@ def item(request, id):
|
||||||
else:
|
else:
|
||||||
title = key['title'] if key else k.capitalize()
|
title = key['title'] if key else k.capitalize()
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
value = value = u', '.join([unicode(v) for v in value])
|
value = value = ', '.join([unicode(v) for v in value])
|
||||||
elif key and key.get('type') == 'float':
|
elif key and key.get('type') == 'float':
|
||||||
value = '%0.3f' % value
|
value = '%0.3f' % value
|
||||||
elif key and key.get('type') == 'time':
|
elif key and key.get('type') == 'time':
|
||||||
|
@ -1493,7 +1492,7 @@ def item(request, id):
|
||||||
clips = []
|
clips = []
|
||||||
clip = {'in': 0, 'annotations': []}
|
clip = {'in': 0, 'annotations': []}
|
||||||
# logged in users should have javascript. not adding annotations makes load faster
|
# logged in users should have javascript. not adding annotations makes load faster
|
||||||
if not settings.USE_IMDB and request.user.is_anonymous():
|
if not settings.USE_IMDB and request.user.is_anonymous:
|
||||||
for a in item.annotations.exclude(
|
for a in item.annotations.exclude(
|
||||||
layer='subtitles'
|
layer='subtitles'
|
||||||
).exclude(
|
).exclude(
|
||||||
|
@ -1513,13 +1512,13 @@ def item(request, id):
|
||||||
head_title = item.get('title', '')
|
head_title = item.get('title', '')
|
||||||
title = item.get('title', '')
|
title = item.get('title', '')
|
||||||
if item.get('director'):
|
if item.get('director'):
|
||||||
head_title += u' (%s)' % u', '.join(item.get('director', []))
|
head_title += ' (%s)' % ', '.join(item.get('director', []))
|
||||||
if item.get('year'):
|
if item.get('year'):
|
||||||
head_title += u' %s' % item.get('year')
|
head_title += ' %s' % item.get('year')
|
||||||
title += u' (%s)' % item.get('year')
|
title += ' (%s)' % item.get('year')
|
||||||
if view:
|
if view:
|
||||||
head_title += u' – %s' % view
|
head_title += ' – %s' % view
|
||||||
head_title += u' – %s' % settings.SITENAME
|
head_title += ' – %s' % settings.SITENAME
|
||||||
head_title = ox.decode_html(head_title)
|
head_title = ox.decode_html(head_title)
|
||||||
title = ox.decode_html(title)
|
title = ox.decode_html(title)
|
||||||
ctx = {
|
ctx = {
|
||||||
|
|
|
@ -124,7 +124,7 @@ class ListManager(Manager):
|
||||||
if conditions:
|
if conditions:
|
||||||
qs = qs.filter(conditions)
|
qs = qs.filter(conditions)
|
||||||
|
|
||||||
if user.is_anonymous():
|
if user.is_anonymous:
|
||||||
qs = qs.filter(Q(status='public') | Q(status='featured'))
|
qs = qs.filter(Q(status='public') | Q(status='featured'))
|
||||||
else:
|
else:
|
||||||
qs = qs.filter(Q(status='public') | Q(status='featured') | Q(user=user))
|
qs = qs.filter(Q(status='public') | Q(status='featured') | Q(user=user))
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -10,7 +9,6 @@ from django.db import models
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from oxdjango.fields import JSONField
|
from oxdjango.fields import JSONField
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
@ -28,7 +26,6 @@ def get_icon_path(f, x): return get_path(f, 'icon.jpg')
|
||||||
def get_listview(): return settings.CONFIG['user']['ui']['listView']
|
def get_listview(): return settings.CONFIG['user']['ui']['listView']
|
||||||
def get_listsort(): return tuple(settings.CONFIG['user']['ui']['listSort'])
|
def get_listsort(): return tuple(settings.CONFIG['user']['ui']['listSort'])
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class List(models.Model):
|
class List(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -36,7 +33,7 @@ class List(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)
|
||||||
user = models.ForeignKey(User, related_name='lists')
|
user = models.ForeignKey(User, related_name='lists', on_delete=models.CASCADE)
|
||||||
groups = models.ManyToManyField(Group, blank=True, related_name='lists')
|
groups = models.ManyToManyField(Group, blank=True, related_name='lists')
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
status = models.CharField(max_length=20, default='private')
|
status = models.CharField(max_length=20, default='private')
|
||||||
|
@ -50,7 +47,7 @@ class List(models.Model):
|
||||||
view = models.TextField(default=get_listview)
|
view = models.TextField(default=get_listview)
|
||||||
sort = JSONField(default=get_listsort, editable=False)
|
sort = JSONField(default=get_listsort, editable=False)
|
||||||
|
|
||||||
poster_frames = JSONField(default=[], editable=False)
|
poster_frames = JSONField(default=list, editable=False)
|
||||||
|
|
||||||
#is through table still required?
|
#is through table still required?
|
||||||
items = models.ManyToManyField('item.Item', related_name='lists',
|
items = models.ManyToManyField('item.Item', related_name='lists',
|
||||||
|
@ -110,13 +107,13 @@ class List(models.Model):
|
||||||
return self.get_id()
|
return self.get_id()
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return u'%s:%s' % (self.user.username, self.name)
|
return '%s:%s' % (self.user.username, self.name)
|
||||||
|
|
||||||
def accessible(self, user):
|
def accessible(self, user):
|
||||||
return self.user == user or self.status in ('public', 'featured')
|
return self.user == user or self.status in ('public', 'featured')
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
if not user or user.is_anonymous():
|
if not user or user.is_anonymous:
|
||||||
return False
|
return False
|
||||||
if self.user == user or \
|
if self.user == user or \
|
||||||
self.groups.filter(id__in=user.groups.all()).count() > 0 or \
|
self.groups.filter(id__in=user.groups.all()).count() > 0 or \
|
||||||
|
@ -244,7 +241,7 @@ class List(models.Model):
|
||||||
elif key == 'subscribers':
|
elif key == 'subscribers':
|
||||||
response[key] = self.subscribed_users.all().count()
|
response[key] = self.subscribed_users.all().count()
|
||||||
elif key == 'subscribed':
|
elif key == 'subscribed':
|
||||||
if user and not user.is_anonymous():
|
if user and not user.is_anonymous:
|
||||||
response[key] = self.subscribed_users.filter(id=user.id).exists()
|
response[key] = self.subscribed_users.filter(id=user.id).exists()
|
||||||
else:
|
else:
|
||||||
response[key] = getattr(self, {
|
response[key] = getattr(self, {
|
||||||
|
@ -314,29 +311,27 @@ class List(models.Model):
|
||||||
path = source
|
path = source
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class ListItem(models.Model):
|
class ListItem(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)
|
||||||
list = models.ForeignKey(List)
|
list = models.ForeignKey(List, on_delete=models.CASCADE)
|
||||||
index = models.IntegerField(default=0)
|
index = models.IntegerField(default=0)
|
||||||
item = models.ForeignKey('item.Item')
|
item = models.ForeignKey('item.Item', on_delete=models.CASCADE)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s in %s' % (self.item, self.list)
|
return '%s in %s' % (self.item, self.list)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Position(models.Model):
|
class Position(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("user", "list", "section")
|
unique_together = ("user", "list", "section")
|
||||||
|
|
||||||
list = models.ForeignKey(List, related_name='position')
|
list = models.ForeignKey(List, related_name='position', on_delete=models.CASCADE)
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
section = models.CharField(max_length=255)
|
section = models.CharField(max_length=255)
|
||||||
position = models.IntegerField(default=0)
|
position = models.IntegerField(default=0)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s/%s/%s' % (self.section, self.position, self.list)
|
return '%s/%s/%s' % (self.section, self.position, self.list)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -75,7 +74,7 @@ def findLists(request, data):
|
||||||
query = parse_query(data, request.user)
|
query = parse_query(data, request.user)
|
||||||
|
|
||||||
#order
|
#order
|
||||||
is_section_request = query['sort'] == [{u'operator': u'+', u'key': u'position'}]
|
is_section_request = query['sort'] == [{'operator': '+', 'key': 'position'}]
|
||||||
def is_featured_condition(x):
|
def is_featured_condition(x):
|
||||||
return x['key'] == 'status' and \
|
return x['key'] == 'status' and \
|
||||||
x['value'] == 'featured' and \
|
x['value'] == 'featured' and \
|
||||||
|
@ -87,7 +86,7 @@ def findLists(request, data):
|
||||||
|
|
||||||
if is_section_request:
|
if is_section_request:
|
||||||
qs = query['qs']
|
qs = query['qs']
|
||||||
if not is_featured and not request.user.is_anonymous():
|
if not is_featured and not request.user.is_anonymous:
|
||||||
qs = qs.filter(position__in=models.Position.objects.filter(user=request.user))
|
qs = qs.filter(position__in=models.Position.objects.filter(user=request.user))
|
||||||
qs = qs.order_by('position__position')
|
qs = qs.order_by('position__position')
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
|
||||||
|
@ -12,11 +10,10 @@ from . import managers
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Log(models.Model):
|
class Log(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True, db_index=True)
|
created = models.DateTimeField(auto_now_add=True, db_index=True)
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
user = models.ForeignKey(User, default=None, blank=True, null=True)
|
user = models.ForeignKey(User, default=None, blank=True, null=True, on_delete=models.CASCADE)
|
||||||
url = models.CharField(max_length=1000, default='')
|
url = models.CharField(max_length=1000, default='')
|
||||||
line = models.IntegerField(default=0)
|
line = models.IntegerField(default=0)
|
||||||
text = models.TextField(blank=True)
|
text = models.TextField(blank=True)
|
||||||
|
@ -24,7 +21,7 @@ class Log(models.Model):
|
||||||
objects = managers.LogManager()
|
objects = managers.LogManager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s" % self.id
|
return "%s" % self.id
|
||||||
|
|
||||||
def json(self, keys=None):
|
def json(self, keys=None):
|
||||||
j = {
|
j = {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
@ -34,7 +33,7 @@ class ErrorHandler(logging.Handler):
|
||||||
request = record.request
|
request = record.request
|
||||||
|
|
||||||
request_repr = repr(request)
|
request_repr = repr(request)
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated:
|
||||||
user = request.user
|
user = request.user
|
||||||
url = request.META.get('PATH_INFO', '')
|
url = request.META.get('PATH_INFO', '')
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
from ox.utils import json
|
from ox.utils import json
|
||||||
|
@ -25,7 +24,7 @@ def logError(request, data):
|
||||||
returns {}
|
returns {}
|
||||||
see: findErrorLogs, removeErrorLogs
|
see: findErrorLogs, removeErrorLogs
|
||||||
'''
|
'''
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated:
|
||||||
user = request.user
|
user = request.user
|
||||||
else:
|
else:
|
||||||
user = None
|
user = None
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
import ox
|
import ox
|
||||||
|
|
||||||
from . import managers
|
from . import managers
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class News(models.Model):
|
class News(models.Model):
|
||||||
objects = managers.NewsManager()
|
objects = managers.NewsManager()
|
||||||
|
|
||||||
|
@ -20,7 +17,7 @@ class News(models.Model):
|
||||||
text = models.TextField()
|
text = models.TextField()
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
return user.is_authenticated() and user.profile.capability("canEditSitePages")
|
return user.is_authenticated and user.profile.capability("canEditSitePages")
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
super(News, self).save(*args, **kwargs)
|
super(News, self).save(*args, **kwargs)
|
||||||
|
@ -42,5 +39,5 @@ class News(models.Model):
|
||||||
return j
|
return j
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u"%s/%s" % (self.date, self.title)
|
return "%s/%s" % (self.date, self.title)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
from ox.utils import json
|
from ox.utils import json
|
||||||
|
|
|
@ -111,10 +111,10 @@ class ApiActions(dict):
|
||||||
f = fc[len(fc)-1].cell_contents
|
f = fc[len(fc)-1].cell_contents
|
||||||
if PY2:
|
if PY2:
|
||||||
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 = '%s:%s' % (info, f.func_code.co_firstlineno)
|
||||||
else:
|
else:
|
||||||
info = f.__code__.co_filename[len(settings.PROJECT_ROOT)+1:]
|
info = f.__code__.co_filename[len(settings.PROJECT_ROOT)+1:]
|
||||||
info = u'%s:%s' % (info, f.__code__.co_firstlineno)
|
info = '%s:%s' % (info, f.__code__.co_firstlineno)
|
||||||
return info, trim(inspect.getsource(f))
|
return info, trim(inspect.getsource(f))
|
||||||
|
|
||||||
def register(self, method, action=None, cache=True, version=None):
|
def register(self, method, action=None, cache=True, version=None):
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.urls import path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
from . import actions
|
from . import actions
|
||||||
actions.autodiscover()
|
actions.autodiscover()
|
||||||
|
|
||||||
urlpatterns = [
|
urls = [
|
||||||
url(r'^$', views.api),
|
[
|
||||||
|
path(r'', views.api),
|
||||||
|
],
|
||||||
|
'api',
|
||||||
|
'api'
|
||||||
]
|
]
|
|
@ -3,7 +3,7 @@ from __future__ import division, absolute_import
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from ..shortcuts import render_to_json_response, json_response, HttpErrorJson
|
from ..shortcuts import render_to_json_response, json_response, HttpErrorJson
|
||||||
|
@ -31,7 +31,7 @@ def api(request):
|
||||||
'settings': settings,
|
'settings': settings,
|
||||||
'sitename': settings.SITENAME
|
'sitename': settings.SITENAME
|
||||||
}
|
}
|
||||||
response = render_to_response('api.html', context)
|
response = render(request, 'api.html', context)
|
||||||
response['Access-Control-Allow-Origin'] = '*'
|
response['Access-Control-Allow-Origin'] = '*'
|
||||||
return response
|
return response
|
||||||
if request.META.get('CONTENT_TYPE') == 'application/json':
|
if request.META.get('CONTENT_TYPE') == 'application/json':
|
||||||
|
|
|
@ -12,7 +12,7 @@ def login_required_json(function=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _wrapped_view(request, *args, **kwargs):
|
def _wrapped_view(request, *args, **kwargs):
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated:
|
||||||
return function(request, *args, **kwargs)
|
return function(request, *args, **kwargs)
|
||||||
return render_to_json_response({'status': {'code': 401, 'text': 'login required'}})
|
return render_to_json_response({'status': {'code': 401, 'text': 'login required'}})
|
||||||
return wraps(function)(_wrapped_view)
|
return wraps(function)(_wrapped_view)
|
||||||
|
@ -24,7 +24,7 @@ def admin_required_json(function=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _wrapped_view(request, *args, **kwargs):
|
def _wrapped_view(request, *args, **kwargs):
|
||||||
if request.user.is_authenticated() and request.user.profile.get_level() == 'admin':
|
if request.user.is_authenticated and request.user.profile.get_level() == 'admin':
|
||||||
return function(request, *args, **kwargs)
|
return function(request, *args, **kwargs)
|
||||||
return render_to_json_response({'status': {'code': 403, 'text': 'permission denied'}})
|
return render_to_json_response({'status': {'code': 403, 'text': 'permission denied'}})
|
||||||
return wraps(function)(_wrapped_view)
|
return wraps(function)(_wrapped_view)
|
||||||
|
|
|
@ -64,7 +64,7 @@ class DictField(models.TextField):
|
||||||
def dumps(cls, obj):
|
def dumps(cls, obj):
|
||||||
return json.dumps(obj, default=to_json, ensure_ascii=False)
|
return json.dumps(obj, default=to_json, ensure_ascii=False)
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection, context=None):
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
if isinstance(value, self._type):
|
if isinstance(value, self._type):
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.utils.deprecation import MiddlewareMixin
|
||||||
|
|
||||||
from .shortcuts import HttpErrorJson, render_to_json_response
|
from .shortcuts import HttpErrorJson, render_to_json_response
|
||||||
|
|
||||||
class ExceptionMiddleware(object):
|
class ExceptionMiddleware(MiddlewareMixin):
|
||||||
|
|
||||||
def process_exception(self, request, exception):
|
def process_exception(self, request, exception):
|
||||||
if isinstance(exception, HttpErrorJson):
|
if isinstance(exception, HttpErrorJson):
|
||||||
return render_to_json_response(exception.response)
|
return render_to_json_response(exception.response)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class ChromeFrameMiddleware(object):
|
class ChromeFrameMiddleware(MiddlewareMixin):
|
||||||
|
|
||||||
def process_response(self, request, response):
|
def process_response(self, request, response):
|
||||||
response['X-UA-Compatible'] = 'chrome=1'
|
response['X-UA-Compatible'] = 'chrome=1'
|
||||||
return response
|
return response
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function
|
|
||||||
import datetime
|
import datetime
|
||||||
from django.utils import datetime_safe
|
from django.utils import datetime_safe
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
|
@ -23,7 +22,7 @@ def _to_json(python_object):
|
||||||
return python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
|
return python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
if isinstance(python_object, datetime_safe.datetime):
|
if isinstance(python_object, datetime_safe.datetime):
|
||||||
return python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
|
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)))
|
raise TypeError('%s %s is not JSON serializable' % (repr(python_object), type(python_object)))
|
||||||
|
|
||||||
def json_dump(data, fp, indent=4):
|
def json_dump(data, fp, indent=4):
|
||||||
return json.dump(data, fp, indent=indent, default=_to_json, ensure_ascii=False)
|
return json.dump(data, fp, indent=indent, default=_to_json, ensure_ascii=False)
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
|
|
||||||
from oxdjango import fields
|
from oxdjango import fields
|
||||||
import ox
|
import ox
|
||||||
|
@ -24,10 +22,9 @@ def get_name_sort(name, sortname=None):
|
||||||
person.save()
|
person.save()
|
||||||
sortname = unicodedata.normalize('NFKD', person.sortname)
|
sortname = unicodedata.normalize('NFKD', person.sortname)
|
||||||
else:
|
else:
|
||||||
sortname = u''
|
sortname = ''
|
||||||
return sortname
|
return sortname
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Person(models.Model):
|
class Person(models.Model):
|
||||||
name = models.CharField(max_length=200, unique=True)
|
name = models.CharField(max_length=200, unique=True)
|
||||||
sortname = models.CharField(max_length=200)
|
sortname = models.CharField(max_length=200)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from celery.task import task
|
from celery.task import task
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
from ox.utils import json
|
from ox.utils import json
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
import ox
|
import ox
|
||||||
from oxdjango import fields
|
from oxdjango import fields
|
||||||
|
|
||||||
|
@ -15,7 +13,6 @@ from . import managers
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Place(models.Model):
|
class Place(models.Model):
|
||||||
'''
|
'''
|
||||||
Places are named locations, they should have geographical information attached to them.
|
Places are named locations, they should have geographical information attached to them.
|
||||||
|
@ -24,7 +21,7 @@ class Place(models.Model):
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
defined = models.BooleanField(default=True)
|
defined = models.BooleanField(default=True)
|
||||||
|
|
||||||
user = models.ForeignKey(User, null=True, related_name='places')
|
user = models.ForeignKey(User, null=True, related_name='places', on_delete=models.CASCADE)
|
||||||
|
|
||||||
name = models.CharField(max_length=1024)
|
name = models.CharField(max_length=1024)
|
||||||
alternativeNames = fields.TupleField(default=())
|
alternativeNames = fields.TupleField(default=())
|
||||||
|
@ -60,7 +57,7 @@ class Place(models.Model):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_or_create(model, name):
|
def get_or_create(model, name):
|
||||||
qs = model.objects.filter(name_find__contains=u'|%s|' % name.lower())
|
qs = model.objects.filter(name_find__contains='|%s|' % name.lower())
|
||||||
if qs.count() == 0:
|
if qs.count() == 0:
|
||||||
instance = model(name=name)
|
instance = model(name=name)
|
||||||
instance.save()
|
instance.save()
|
||||||
|
@ -69,7 +66,7 @@ class Place(models.Model):
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
if user and not user.is_anonymous() \
|
if user and not user.is_anonymous \
|
||||||
and (not self.user or \
|
and (not self.user or \
|
||||||
self.user == user or \
|
self.user == user or \
|
||||||
user.profile.capability('canEditPlaces')):
|
user.profile.capability('canEditPlaces')):
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from celery.task import task
|
from celery.task import task
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db.models import Max, Min, Count
|
from django.db.models import Max, Min, Count
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -50,7 +49,7 @@ def addPlace(request, data):
|
||||||
n = 0
|
n = 0
|
||||||
while _exists:
|
while _exists:
|
||||||
_exists = models.Place.objects.filter(defined=True,
|
_exists = models.Place.objects.filter(defined=True,
|
||||||
name_find__contains=u'|%s|' % name.lower()).count() > 0
|
name_find__contains='|%s|' % name.lower()).count() > 0
|
||||||
if _exists:
|
if _exists:
|
||||||
name = 'Untitled [%s]' %n
|
name = 'Untitled [%s]' %n
|
||||||
n += 1
|
n += 1
|
||||||
|
@ -61,7 +60,7 @@ def addPlace(request, data):
|
||||||
for n in names:
|
for n in names:
|
||||||
n = ox.decode_html(name)
|
n = ox.decode_html(name)
|
||||||
if models.Place.objects.filter(defined=True,
|
if models.Place.objects.filter(defined=True,
|
||||||
name_find__contains=u'|%s|' % n.lower()).count() != 0:
|
name_find__contains='|%s|' % n.lower()).count() != 0:
|
||||||
exists = True
|
exists = True
|
||||||
existing_names.append(n)
|
existing_names.append(n)
|
||||||
'''
|
'''
|
||||||
|
@ -130,7 +129,7 @@ def editPlace(request, data):
|
||||||
for name in names + alternative_names:
|
for name in names + alternative_names:
|
||||||
name = ox.decode_html(name)
|
name = ox.decode_html(name)
|
||||||
if models.Place.objects.filter(defined=True,
|
if models.Place.objects.filter(defined=True,
|
||||||
name_find__contains=u'|%s|' % name.lower()).exclude(id=place.id).count() != 0:
|
name_find__contains='|%s|' % name.lower()).exclude(id=place.id).count() != 0:
|
||||||
conflict = True
|
conflict = True
|
||||||
conflict_names.append(name)
|
conflict_names.append(name)
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db.models import Q, Manager
|
from django.db.models import Q, Manager
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
|
|
||||||
from item.models import ItemSort
|
from item.models import ItemSort
|
||||||
|
|
||||||
|
@ -15,7 +13,6 @@ def parse_hash(value):
|
||||||
def format_hash(value):
|
def format_hash(value):
|
||||||
return hex(value + 9223372036854775808)[2:-1].upper()
|
return hex(value + 9223372036854775808)[2:-1].upper()
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Sequence(models.Model):
|
class Sequence(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("sort", "start", "end", "mode")
|
unique_together = ("sort", "start", "end", "mode")
|
||||||
|
@ -25,7 +22,7 @@ class Sequence(models.Model):
|
||||||
'color': 1
|
'color': 1
|
||||||
}
|
}
|
||||||
mode = models.IntegerField(choices=sorted(zip(MODE.values(), list(MODE)), key=lambda k: k[0]), default=0)
|
mode = models.IntegerField(choices=sorted(zip(MODE.values(), list(MODE)), key=lambda k: k[0]), default=0)
|
||||||
sort = models.ForeignKey(ItemSort, null=True, related_name='sequences')
|
sort = models.ForeignKey(ItemSort, null=True, related_name='sequences', on_delete=models.CASCADE)
|
||||||
|
|
||||||
hash = models.BigIntegerField(db_index=True, default=-9223372036854775808)
|
hash = models.BigIntegerField(db_index=True, default=-9223372036854775808)
|
||||||
start = models.FloatField(default=-1)
|
start = models.FloatField(default=-1)
|
||||||
|
@ -40,7 +37,7 @@ class Sequence(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def public_id(self):
|
def public_id(self):
|
||||||
return u"%s/%0.03f-%0.03f" % (self.sort.item.public_id, float(self.start), float(self.end))
|
return "%s/%0.03f-%0.03f" % (self.sort.item.public_id, float(self.start), float(self.end))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.public_id
|
return self.public_id
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import division, print_function, absolute_import
|
|
||||||
|
|
||||||
from ox.utils import json
|
from ox.utils import json
|
||||||
from oxdjango.shortcuts import render_to_json_response, json_response
|
from oxdjango.shortcuts import render_to_json_response, json_response
|
||||||
|
|
|
@ -96,7 +96,7 @@ TEMPLATES = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
MIDDLEWARE = (
|
||||||
'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',
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue