Compare commits

...

4 commits

Author SHA1 Message Date
j
0d0770802c get_json -> json 2018-07-09 15:22:12 +02:00
j
910d95f9b2 refactor update_cache 2018-07-09 15:22:12 +02:00
j
bd0732b8d5 rename item.json -> item.cache 2018-07-09 15:22:12 +02:00
j
1bac062a50 use postgres json field 2018-07-09 15:22:12 +02:00
30 changed files with 349 additions and 86 deletions

View file

@ -368,7 +368,7 @@ class Annotation(models.Model):
if key in self._clip_keys: if key in self._clip_keys:
j[key] = getattr(self.clip, key) j[key] = getattr(self.clip, key)
elif key not in self.annotation_keys: elif key not in self.annotation_keys:
value = self.item.get(key) or self.item.json.get(key) value = self.item.get(key) or self.item.cache.get(key)
if not value and hasattr(self.item.sort, key): if not value and hasattr(self.item.sort, key):
value = getattr(self.item.sort, key) value = getattr(self.item.sort, key)
if value != None: if value != None:

View file

@ -4,7 +4,6 @@ from django.db.models import Q, Manager
from oxdjango.managers import get_operator from oxdjango.managers import get_operator
from oxdjango.query import QuerySet from oxdjango.query import QuerySet
from oxdjango.fields import DictField
keymap = { keymap = {
@ -36,8 +35,7 @@ def parseCondition(condition, user):
if isinstance(v, bool): if isinstance(v, bool):
key = k key = k
elif k == 'url': elif k == 'url':
key = 'info' + get_operator('=', 'istr') key = 'info__url' + get_operator('=', 'istr')
v = DictField.dumps({'url': v})[1:-1]
elif k == 'list': elif k == 'list':
q = Q(id=0) q = Q(id=0)
l = v.split(":") l = v.split(":")

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('archive', '0003_auto_20161104_1726'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "archive_file" ALTER COLUMN "info" TYPE jsonb USING "info"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "archive_stream" ALTER COLUMN "info" TYPE jsonb USING "info"::text::jsonb'
),
]

View file

@ -13,6 +13,7 @@ from django.contrib.auth.models import User
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 django.utils.encoding import python_2_unicode_compatible
from oxdjango.fields import JSONField
from oxdjango import fields from oxdjango import fields
import ox import ox
@ -69,7 +70,7 @@ class File(models.Model):
size = models.BigIntegerField(default=0) size = models.BigIntegerField(default=0)
duration = models.FloatField(null=True) duration = models.FloatField(null=True)
info = fields.DictField(default={}) info = JSONField(default=dict, editable=False)
video_codec = models.CharField(max_length=255) video_codec = models.CharField(max_length=255)
pixel_format = models.CharField(max_length=255) pixel_format = models.CharField(max_length=255)
@ -687,7 +688,7 @@ class Stream(models.Model):
source = models.ForeignKey('Stream', related_name='derivatives', default=None, null=True) source = models.ForeignKey('Stream', related_name='derivatives', default=None, null=True)
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 = fields.DictField(default={}) info = JSONField(default=dict, editable=False)
duration = models.FloatField(default=0) duration = models.FloatField(default=0)
aspect_ratio = models.FloatField(default=0) aspect_ratio = models.FloatField(default=0)

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('changelog', '0001_initial'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "changelog_changelog" ALTER COLUMN "value" TYPE jsonb USING "value"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "changelog_log" ALTER COLUMN "data" TYPE jsonb USING "data"::text::jsonb'
),
]

View file

@ -6,8 +6,8 @@ from datetime import datetime
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models from django.db import models
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from oxdjango.fields import JSONField
from oxdjango import fields
import ox import ox
import websocket import websocket
@ -21,7 +21,7 @@ FIXME: remove this table more migrate to new ChangeLog
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 = fields.DictField(default={}) value = JSONField(default=dict, editable=False)
def __str__(self): def __str__(self):
return u'%s %s' % (self.type, self.created) return u'%s %s' % (self.type, self.created)
@ -52,7 +52,7 @@ def add_changelog(request, data, id=None):
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 = fields.DictField(default={}) 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')
changeid = models.TextField() changeid = models.TextField()

View file

@ -131,7 +131,7 @@ class MetaClip(object):
if key == 'streams': if key == 'streams':
value = [s.file.oshash for s in self.item.streams()] value = [s.file.oshash for s in self.item.streams()]
else: else:
value = self.item.get(key) or self.item.json.get(key) value = self.item.get(key) or self.item.cache.get(key)
if not value and hasattr(self.item.sort, key): if not value and hasattr(self.item.sort, key):
value = getattr(self.item.sort, key) value = getattr(self.item.sort, key)
if value is not None: if value is not None:
@ -148,10 +148,10 @@ class MetaClip(object):
qs = self.annotations.all() qs = self.annotations.all()
if qs.count(): if qs.count():
data['annotation'] = qs[0].public_id data['annotation'] = qs[0].public_id
data['parts'] = self.item.json['parts'] data['parts'] = self.item.cache['parts']
data['durations'] = self.item.json['durations'] data['durations'] = self.item.cache['durations']
for key in ('title', 'director', 'year', 'videoRatio'): for key in ('title', 'director', 'year', 'videoRatio'):
value = self.item.json.get(key) value = self.item.cache.get(key)
if value: if value:
data[key] = value data[key] = value
data['duration'] = data['out'] - data['in'] data['duration'] = data['out'] - data['in']

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('document', '0010_auto_20170126_1528'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "document_document" ALTER COLUMN "data" TYPE jsonb USING "data"::text::jsonb'
),
]

View file

@ -14,12 +14,12 @@ from django.contrib.auth.models import User, Group
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 django.utils.encoding import python_2_unicode_compatible
from oxdjango.fields import JSONField
from PIL import Image from PIL import Image
import ox import ox
from oxdjango import fields
from oxdjango.sortmodel import get_sort_field from oxdjango.sortmodel import get_sort_field
from person.models import get_name_sort from person.models import get_name_sort
from item.models import Item from item.models import Item
@ -65,7 +65,7 @@ class Document(models.Model):
linked_documents = models.ManyToManyField('Document', related_name='linking_documents') linked_documents = models.ManyToManyField('Document', related_name='linking_documents')
rightslevel = models.IntegerField(db_index=True, default=0) rightslevel = models.IntegerField(db_index=True, default=0)
data = fields.DictField(default={}) 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():
@ -584,7 +584,7 @@ class Document(models.Model):
def referenced(self): def referenced(self):
result = {} result = {}
result['items'] = [ result['items'] = [
i.get_json(keys=['id', 'title']) i.json(keys=['id', 'title'])
for i in self.items.all().order_by('sort__title') for i in self.items.all().order_by('sort__title')
] ]
result['annotations'] = [ result['annotations'] = [

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('documentcollection', '0002_collection_groups'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "documentcollection_collection" ALTER COLUMN "query" TYPE jsonb USING "query"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "documentcollection_collection" ALTER COLUMN "sort" TYPE jsonb USING "sort"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "documentcollection_collection" ALTER COLUMN "poster_frames" TYPE jsonb USING "poster_frames"::text::jsonb'
),
]

View file

@ -11,11 +11,10 @@ from django.db.models import Max
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.conf import settings from django.conf import settings
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from oxdjango.fields import JSONField
import ox import ox
from oxdjango.fields import DictField, TupleField
from archive import extract from archive import extract
from user.utils import update_groups from user.utils import update_groups
@ -47,16 +46,16 @@ class Collection(models.Model):
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')
_status = ['private', 'public', 'featured'] _status = ['private', 'public', 'featured']
query = DictField(default={"static": True}) query = JSONField(default=lambda: {"static": True}, editable=False)
type = models.CharField(max_length=255, default='static') type = models.CharField(max_length=255, default='static')
description = models.TextField(default='') description = models.TextField(default='')
icon = models.ImageField(default=None, blank=True, upload_to=get_icon_path) icon = models.ImageField(default=None, blank=True, upload_to=get_icon_path)
view = models.TextField(default=get_collectionview) view = models.TextField(default=get_collectionview)
sort = TupleField(default=get_collectionsort, editable=False) sort = JSONField(default=get_collectionsort, editable=False)
poster_frames = TupleField(default=[], editable=False) poster_frames = JSONField(default=[], 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',

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('edit', '0004_edit_groups'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "edit_edit" ALTER COLUMN "query" TYPE jsonb USING "query"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "edit_edit" ALTER COLUMN "poster_frames" TYPE jsonb USING "poster_frames"::text::jsonb'
),
]

View file

@ -10,12 +10,12 @@ import tempfile
from six.moves.urllib.parse import quote from six.moves.urllib.parse import quote
import ox import ox
from oxdjango.fields import DictField, TupleField
from django.conf import settings from django.conf import settings
from django.db import models, transaction from django.db import models, transaction
from django.db.models import Max from django.db.models import Max
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from oxdjango.fields import JSONField
from annotation.models import Annotation from annotation.models import Annotation
from item.models import Item from item.models import Item
@ -49,12 +49,12 @@ class Edit(models.Model):
description = models.TextField(default='') description = models.TextField(default='')
rightslevel = models.IntegerField(db_index=True, default=0) rightslevel = models.IntegerField(db_index=True, default=0)
query = DictField(default={"static": True}) query = JSONField(default=lambda: {"static": True}, editable=False)
type = models.CharField(max_length=255, default='static') type = models.CharField(max_length=255, default='static')
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 = TupleField(default=[], editable=False) poster_frames = JSONField(default=[], 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):
@ -493,16 +493,16 @@ class Clip(models.Model):
data['item'] = self.item.public_id data['item'] = self.item.public_id
data['in'] = self.annotation.start data['in'] = self.annotation.start
data['out'] = self.annotation.end data['out'] = self.annotation.end
data['parts'] = self.annotation.item.json['parts'] data['parts'] = self.annotation.item.cache['parts']
data['durations'] = self.annotation.item.json['durations'] data['durations'] = self.annotation.item.cache['durations']
else: else:
data['item'] = self.item.public_id data['item'] = self.item.public_id
data['in'] = self.start data['in'] = self.start
data['out'] = self.end data['out'] = self.end
data['parts'] = self.item.json['parts'] data['parts'] = self.item.cache['parts']
data['durations'] = self.item.json['durations'] data['durations'] = self.item.cache['durations']
for key in ('title', 'director', 'year', 'videoRatio'): for key in ('title', 'director', 'year', 'videoRatio'):
value = self.item.json.get(key) value = self.item.cache.get(key)
if value: if value:
data[key] = value data[key] = value
data['duration'] = data['out'] - data['in'] data['duration'] = data['out'] - data['in']

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entity', '0004_related_name_Document_documentproperties'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "entity_entity" ALTER COLUMN "data" TYPE jsonb USING "data"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "entity_documentproperties" ALTER COLUMN "data" TYPE jsonb USING "data"::text::jsonb'
),
]

View file

@ -14,6 +14,7 @@ from django.contrib.auth.models import User
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 django.utils.encoding import python_2_unicode_compatible
from oxdjango.fields import JSONField
import ox import ox
from oxdjango import fields from oxdjango import fields
@ -40,7 +41,7 @@ class Entity(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
alternativeNames = fields.TupleField(default=()) alternativeNames = fields.TupleField(default=())
data = fields.DictField(default={}, editable=False) data = JSONField(default=dict, editable=False)
matches = models.IntegerField(default=0) matches = models.IntegerField(default=0)
objects = managers.EntityManager() objects = managers.EntityManager()
@ -271,7 +272,7 @@ class DocumentProperties(models.Model):
document = models.ForeignKey(Document, related_name='documentproperties') document = models.ForeignKey(Document, related_name='documentproperties')
entity = models.ForeignKey(Entity, related_name='documentproperties') entity = models.ForeignKey(Entity, related_name='documentproperties')
index = models.IntegerField(default=0) index = models.IntegerField(default=0)
data = fields.DictField(default={}) data = JSONField(default=dict, editable=False)
def __str__(self): def __str__(self):
return u"%r-%r" % (self.document, self.entity) return u"%r-%r" % (self.document, self.entity)

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('home', '0001_initial'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "home_item" ALTER COLUMN "data" TYPE jsonb USING "data"::text::jsonb'
),
]

View file

@ -8,10 +8,10 @@ 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 django.utils.encoding import python_2_unicode_compatible
from oxdjango.fields import JSONField
import ox import ox
from oxdjango import fields
from itemlist.models import List from itemlist.models import List
from edit.models import Edit from edit.models import Edit
from documentcollection.models import Collection from documentcollection.models import Collection
@ -24,7 +24,7 @@ class Item(models.Model):
active = models.BooleanField(default=True) active = models.BooleanField(default=True)
index = models.IntegerField(default=-1) index = models.IntegerField(default=-1)
data = fields.DictField(default={}, 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")

View file

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('item', '0002_auto_20160219_1734'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "item_item" ALTER COLUMN "data" TYPE jsonb USING "data"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "item_item" ALTER COLUMN "external_data" TYPE jsonb USING "external_data"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "item_item" ALTER COLUMN "json" TYPE jsonb USING "json"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "item_item" ALTER COLUMN "stream_info" TYPE jsonb USING "stream_info"::text::jsonb'
),
]

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-19 20:24
from __future__ import unicode_literals
import django.core.serializers.json
from django.db import migrations, models
import oxdjango.fields
class Migration(migrations.Migration):
dependencies = [
('item', '0003_jsonfield'),
]
operations = [
migrations.RenameField(
model_name='item',
old_name='json',
new_name='cache',
),
]

View file

@ -23,7 +23,7 @@ from django.utils import datetime_safe
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
import ox import ox
from oxdjango import fields from oxdjango.fields import JSONField, to_json
from oxdjango.sortmodel import get_sort_field from oxdjango.sortmodel import get_sort_field
import ox.web.imdb import ox.web.imdb
import ox.image import ox.image
@ -175,9 +175,9 @@ class Item(models.Model):
public_id = models.CharField(max_length=128, unique=True, blank=True) public_id = models.CharField(max_length=128, unique=True, blank=True)
oxdbId = models.CharField(max_length=42, unique=True, blank=True, null=True) oxdbId = models.CharField(max_length=42, unique=True, blank=True, null=True)
external_data = fields.DictField(default={}, editable=False) external_data = JSONField(default=dict, editable=False)
data = fields.DictField(default={}, editable=False) data = JSONField(default=dict, editable=False)
json = fields.DictField(default={}, editable=False) cache = JSONField(default=dict, editable=False)
poster = models.ImageField(default=None, blank=True, upload_to=get_poster_path) poster = models.ImageField(default=None, blank=True, upload_to=get_poster_path)
poster_source = models.TextField(blank=True) poster_source = models.TextField(blank=True)
poster_height = models.IntegerField(default=0) poster_height = models.IntegerField(default=0)
@ -187,7 +187,7 @@ class Item(models.Model):
icon = models.ImageField(default=None, blank=True, upload_to=get_icon_path) icon = models.ImageField(default=None, blank=True, upload_to=get_icon_path)
torrent = models.FileField(default=None, blank=True, max_length=1000, upload_to=get_torrent_path) torrent = models.FileField(default=None, blank=True, max_length=1000, upload_to=get_torrent_path)
stream_info = fields.DictField(default={}, editable=False) stream_info = JSONField(default=dict, editable=False)
# stream related fields # stream related fields
stream_aspect = models.FloatField(default=4/3) stream_aspect = models.FloatField(default=4/3)
@ -425,8 +425,8 @@ class Item(models.Model):
self.poster_width = 80 self.poster_width = 80
self.update_sort() self.update_sort()
self.update_languages() self.update_languages()
self.json = self.get_json() self.cache = self.json()
self.json['modified'] = datetime.now() self.cache['modified'] = datetime.now()
super(Item, self).save(*args, **kwargs) super(Item, self).save(*args, **kwargs)
self.update_find() self.update_find()
self.update_sort() self.update_sort()
@ -582,7 +582,7 @@ class Item(models.Model):
documents = [d.json(item=self) for d in qs] documents = [d.json(item=self) for d in qs]
return sorted(documents, key=lambda d: d['index']) return sorted(documents, key=lambda d: d['index'])
def get_json(self, keys=None): def json(self, keys=None):
i = { i = {
'id': self.public_id, 'id': self.public_id,
'rendered': self.rendered, 'rendered': self.rendered,
@ -700,7 +700,7 @@ class Item(models.Model):
def get_item_description_html(self): def get_item_description_html(self):
description = '' description = ''
data = self.get_json() data = self.json()
info = [] info = []
for key in [ for key in [
'director', 'writer', 'producer', 'director', 'writer', 'producer',
@ -1360,7 +1360,7 @@ class Item(models.Model):
if offset: if offset:
self.data['volume'] /= offset self.data['volume'] /= offset
# extract.timeline_strip(self, self.data['cuts'], stream.info, self.timeline_prefix[:-8]) # extract.timeline_strip(self, self.data['cuts'], stream.info, self.timeline_prefix[:-8])
self.json = self.get_json() self.cache = self.json()
self.update_sort() self.update_sort()
self.select_frame() self.select_frame()
self.make_poster() self.make_poster()
@ -1375,6 +1375,10 @@ class Item(models.Model):
get_sequences(self.public_id) get_sequences(self.public_id)
tasks.load_subtitles.delay(self.public_id) tasks.load_subtitles.delay(self.public_id)
def update_cache(self, **kwargs):
self.cache = self.json()
Item.objects.filter(id=self.id).update(cache=self.cache, **kwargs)
def save_poster(self, data): def save_poster(self, data):
self.poster.name = self.path('poster.jpg') self.poster.name = self.path('poster.jpg')
poster = self.poster.path poster = self.poster.path
@ -1383,11 +1387,9 @@ class Item(models.Model):
self.poster_height = self.poster.height self.poster_height = self.poster.height
self.poster_width = self.poster.width self.poster_width = self.poster.width
self.clear_poster_cache(self.poster.path) self.clear_poster_cache(self.poster.path)
if self.json.get('posterRatio') != self.poster_width / self.poster_height: if self.cache.get('posterRatio') != self.poster_width / self.poster_height:
self.json = self.get_json() self.update_cache(poster_width=self.poster_width,
Item.objects.filter(id=self.id).update(json=self.json, poster_height=self.poster_height)
poster_width=self.poster_width,
poster_height=self.poster_height)
def prefered_poster_url(self): def prefered_poster_url(self):
if settings.DATA_SERVICE: if settings.DATA_SERVICE:
@ -1467,7 +1469,7 @@ class Item(models.Model):
timeline = audio_timeline timeline = audio_timeline
cmd = [settings.ITEM_POSTER, '-d', '-', '-p', poster] cmd = [settings.ITEM_POSTER, '-d', '-', '-p', poster]
data = self.json.copy() data = self.cache.copy()
if frame: if frame:
data['frame'] = frame data['frame'] = frame
if os.path.exists(timeline): if os.path.exists(timeline):
@ -1476,7 +1478,7 @@ class Item(models.Model):
data = utils.normalize_dict('NFC', data) data = utils.normalize_dict('NFC', data)
ox.makedirs(os.path.join(settings.MEDIA_ROOT, self.path())) ox.makedirs(os.path.join(settings.MEDIA_ROOT, self.path()))
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, close_fds=True) p = subprocess.Popen(cmd, stdin=subprocess.PIPE, close_fds=True)
p.communicate(json.dumps(data, default=fields.to_json).encode('utf-8')) p.communicate(json.dumps(data, default=to_json).encode('utf-8'))
self.clear_poster_cache(poster) self.clear_poster_cache(poster)
return poster return poster
@ -1495,8 +1497,8 @@ class Item(models.Model):
}) })
offset += f.duration offset += f.duration
else: else:
if 'videoRatio' in self.json and self.sort.duration and self.streams(): if 'videoRatio' in self.cache and self.sort.duration and self.streams():
width, height = self.json['resolution'] width, height = self.cache['resolution']
if width and height: if width and height:
pos = self.sort.duration / 2 pos = self.sort.duration / 2
for p in [pos/2, pos, pos+pos/2]: for p in [pos/2, pos, pos+pos/2]:
@ -1636,9 +1638,9 @@ class Item(models.Model):
for data in s.srt(offset): for data in s.srt(offset):
subtitles_added = True subtitles_added = True
value = data['value'].replace('\n', '<br>\n').replace('<br><br>\n', '<br>\n') value = data['value'].replace('\n', '<br>\n').replace('<br><br>\n', '<br>\n')
if data['in'] < self.json['duration'] and data['out'] > self.json['duration']: if data['in'] < self.cache['duration'] and data['out'] > self.cache['duration']:
data['out'] = self.json['duration'] data['out'] = self.cache['duration']
if data['in'] < self.json['duration']: if data['in'] < self.cache['duration']:
new.append((float('%0.03f' % data['in']), float('%0.03f' % data['out']), value)) new.append((float('%0.03f' % data['in']), float('%0.03f' % data['out']), value))
# otherwise add empty 5 seconds annotation every minute # otherwise add empty 5 seconds annotation every minute
if not subtitles_added: if not subtitles_added:

View file

@ -175,11 +175,11 @@ def only_p_sums(request, query, m):
if p == 'accessed': if p == 'accessed':
r[p] = m.sort.accessed or '' r[p] = m.sort.accessed or ''
elif p == 'editable': elif p == 'editable':
r[p] = is_editable(request, m.json) r[p] = is_editable(request, m.cache)
elif p in item_sort_keys: elif p in item_sort_keys:
r[p] = getattr(m.sort, p) r[p] = getattr(m.sort, p)
else: else:
r[p] = m.json.get(p) r[p] = m.cache.get(p)
if 'clip_qs' in query: if 'clip_qs' in query:
r['clips'] = get_clips(query, query['clip_qs'].filter(item=m)) r['clips'] = get_clips(query, query['clip_qs'].filter(item=m))
return r return r
@ -207,12 +207,12 @@ def get_items(request, query):
items = [] items = []
qs = _order_query(query['qs'], query['sort']) qs = _order_query(query['qs'], query['sort'])
qs = qs[query['range'][0]:query['range'][1]] qs = qs[query['range'][0]:query['range'][1]]
# items = [m.get_json(_p) for m in qs] # items = [m.json(_p) for m in qs]
if any(p for p in query['keys'] if p in item_sort_keys): if any(p for p in query['keys'] if p in item_sort_keys):
qs = qs.select_related() qs = qs.select_related()
items = [only_p_sums(request, query, m) for m in qs] items = [only_p_sums(request, query, m) for m in qs]
else: else:
items = [only_p(request, query, m['json']) for m in qs.values('json')] items = [only_p(request, query, m['cache']) for m in qs.values('cache')]
return items return items
def get_stats(request, query): def get_stats(request, query):
@ -415,7 +415,7 @@ def findId(request, data):
qs = models.Item.objects.filter(public_id=data['id']) qs = models.Item.objects.filter(public_id=data['id'])
if qs.count() == 1: if qs.count() == 1:
response['data']['items'] = [ response['data']['items'] = [
i.get_json(['title', 'director', 'year', 'id']) for i in qs i.json(['title', 'director', 'year', 'id']) for i in qs
] ]
if not response['data']['items'] \ if not response['data']['items'] \
@ -509,7 +509,7 @@ def get(request, data):
data['keys'] = data.get('keys', []) data['keys'] = data.get('keys', [])
item = get_object_or_404_json(models.Item, public_id=data['id']) item = get_object_or_404_json(models.Item, public_id=data['id'])
if item.access(request.user): if item.access(request.user):
info = item.get_json(data['keys']) info = item.json(data['keys'])
if not data['keys'] or 'stream' in data['keys']: if not data['keys'] or 'stream' in data['keys']:
info['stream'] = item.get_stream() info['stream'] = item.get_stream()
if not data['keys'] or 'streams' in data['keys']: if not data['keys'] or 'streams' in data['keys']:
@ -602,7 +602,7 @@ def add(request, data):
del data['title'] del data['title']
if data: if data:
response = edit_item(request, item, data) response = edit_item(request, item, data)
response['data'] = item.get_json() response['data'] = item.json()
add_changelog(request, request_data, item.public_id) add_changelog(request, request_data, item.public_id)
return render_to_json_response(response) return render_to_json_response(response)
actions.register(add, cache=False) actions.register(add, cache=False)
@ -626,7 +626,7 @@ def edit(request, data):
if item.editable(request.user): if item.editable(request.user):
request_data = data.copy() request_data = data.copy()
response = edit_item(request, item, data) response = edit_item(request, item, data)
response['data'] = item.get_json() response['data'] = item.json()
add_changelog(request, request_data) add_changelog(request, request_data)
else: else:
response = json_response(status=403, text='permission denied') response = json_response(status=403, text='permission denied')
@ -881,7 +881,7 @@ def poster(request, id, size=None):
poster_height=item.poster_height, poster_height=item.poster_height,
poster_width=item.poster_width, poster_width=item.poster_width,
icon=item.icon.name, icon=item.icon.name,
json=item.get_json() json=item.json()
) )
if item.poster and os.path.exists(item.poster.path): if item.poster and os.path.exists(item.poster.path):
return image_to_response(item.poster, size) return image_to_response(item.poster, size)
@ -1040,7 +1040,7 @@ def video(request, id, resolution, format, index=None, track=None):
if not r: if not r:
return HttpResponseForbidden() return HttpResponseForbidden()
path = video.name path = video.name
duration = sum(item.json['durations']) duration = sum(item.cache['durations'])
content_type = mimetypes.guess_type(path)[0] content_type = mimetypes.guess_type(path)[0]
if len(t) == 2 and t[1] > t[0] and duration >= t[1]: if len(t) == 2 and t[1] > t[0] and duration >= t[1]:
@ -1304,7 +1304,7 @@ def item_json(request, id):
response = json_response(status=404, text='not found') response = json_response(status=404, text='not found')
else: else:
item = qs[0] item = qs[0]
response = item.get_json() response = item.json()
response['layers'] = item.get_layers(request.user) response['layers'] = item.get_layers(request.user)
return render_to_json_response(response) return render_to_json_response(response)
@ -1318,7 +1318,7 @@ def item_xml(request, id):
response = render_to_json_response(response) response = render_to_json_response(response)
else: else:
item = qs[0] item = qs[0]
j = item.get_json() j = item.json()
j['layers'] = item.get_layers(request.user) j['layers'] = item.get_layers(request.user)
if 'resolution' in j: if 'resolution' in j:
j['resolution'] = {'width': j['resolution'][0], 'height': j['resolution'][1]} j['resolution'] = {'width': j['resolution'][0], 'height': j['resolution'][1]}

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('itemlist', '0002_list_groups'),
]
operations = [
migrations.RunSQL(
'ALTER TABLE "itemlist_list" ALTER COLUMN "query" TYPE jsonb USING "query"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "itemlist_list" ALTER COLUMN "sort" TYPE jsonb USING "sort"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "itemlist_list" ALTER COLUMN "poster_frames" TYPE jsonb USING "poster_frames"::text::jsonb'
),
]

View file

@ -11,9 +11,9 @@ from django.db.models import Max
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.conf import settings from django.conf import settings
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
import ox from oxdjango.fields import JSONField
from oxdjango.fields import DictField, TupleField import ox
from archive import extract from archive import extract
from user.utils import update_groups from user.utils import update_groups
@ -39,16 +39,16 @@ class List(models.Model):
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')
_status = ['private', 'public', 'featured'] _status = ['private', 'public', 'featured']
query = DictField(default={"static": True}) query = JSONField(default=lambda: {"static": True}, editable=False)
type = models.CharField(max_length=255, default='static') type = models.CharField(max_length=255, default='static')
description = models.TextField(default='') description = models.TextField(default='')
icon = models.ImageField(default=None, blank=True, upload_to=get_icon_path) icon = models.ImageField(default=None, blank=True, upload_to=get_icon_path)
view = models.TextField(default=get_listview) view = models.TextField(default=get_listview)
sort = TupleField(default=get_listsort, editable=False) sort = JSONField(default=get_listsort, editable=False)
poster_frames = TupleField(default=[], editable=False) poster_frames = JSONField(default=[], 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',

View file

@ -5,10 +5,19 @@ import copy
from django.db import models from django.db import models
from django.utils import datetime_safe from django.utils import datetime_safe
import django.contrib.postgres.fields
from django.core.serializers.json import DjangoJSONEncoder
from six import string_types from six import string_types
from ox.utils import json from ox.utils import json
class JSONField(django.contrib.postgres.fields.JSONField):
def __init__(self, *args, **kwargs):
if 'encoder' not in kwargs:
kwargs['encoder'] = DjangoJSONEncoder
super().__init__(*args, **kwargs)
def to_json(python_object): def to_json(python_object):
if isinstance(python_object, datetime.datetime): if isinstance(python_object, datetime.datetime):

View file

@ -55,5 +55,5 @@ class Sequence(models.Model):
if keys: if keys:
for key in keys: for key in keys:
if key not in j: if key not in j:
j[key] = self.sort.item.json.get(key) j[key] = self.sort.item.cache.get(key)
return j return j

View file

@ -87,7 +87,7 @@ class Program(models.Model):
return u"%s %s" % (self.item, self.start) return u"%s %s" % (self.item, self.start)
def json(self, user, current=False): def json(self, user, current=False):
item_json = self.item.get_json() item_json = self.item.json()
r = { r = {
'item': self.item.public_id, 'item': self.item.public_id,
} }

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2018-06-19 17:23
from __future__ import unicode_literals
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0003_sessiondata_numberofcollections')
]
operations = [
migrations.RunSQL(
'ALTER TABLE "user_sessiondata" ALTER COLUMN "info" TYPE jsonb USING "info"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "user_userprofile" ALTER COLUMN "ui" TYPE jsonb USING "ui"::text::jsonb'
),
migrations.RunSQL(
'ALTER TABLE "user_userprofile" ALTER COLUMN "preferences" TYPE jsonb USING "preferences"::text::jsonb'
),
]

View file

@ -9,9 +9,9 @@ from django.db import models
from django.db.models import Max from django.db.models import Max
from django.conf import settings from django.conf import settings
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from oxdjango.fields import JSONField
import ox import ox
from oxdjango.fields import DictField
from ox.utils import json from ox.utils import json
from itemlist.models import List, Position from itemlist.models import List, Position
@ -38,7 +38,7 @@ class SessionData(models.Model):
useragent = models.CharField(max_length=4096, null=True) useragent = models.CharField(max_length=4096, null=True)
windowsize = models.CharField(max_length=255, null=True) windowsize = models.CharField(max_length=255, null=True)
screensize = models.CharField(max_length=255, null=True) screensize = models.CharField(max_length=255, null=True)
info = DictField(default={}) info = JSONField(default=dict, editable=False)
location = models.CharField(max_length=255, null=True) location = models.CharField(max_length=255, null=True)
location_sort = models.CharField(max_length=255, null=True) location_sort = models.CharField(max_length=255, null=True)
@ -178,8 +178,8 @@ class UserProfile(models.Model):
level = models.IntegerField(default=1) level = models.IntegerField(default=1)
files_updated = models.DateTimeField(default=datetime.now) files_updated = models.DateTimeField(default=datetime.now)
newsletter = models.BooleanField(default=True) newsletter = models.BooleanField(default=True)
ui = DictField(default={}) ui = JSONField(default=dict, editable=False)
preferences = DictField(default={}) preferences = JSONField(default=dict, editable=False)
notes = models.TextField(default='') notes = models.TextField(default='')

View file

@ -1,12 +1,12 @@
Django==1.9.4 Django==1.11.13
simplejson simplejson
chardet chardet
celery==3.1.23 celery==3.1.26.post2
django-celery==3.1.17 django-celery==3.2.2
django-extensions==1.6.1 django-extensions==2.0.7
gunicorn==19.4.5 gunicorn==19.8.1
html5lib html5lib
requests==2.9.1 requests==2.19.1
tornado==4.1 tornado==5.0.2
geoip2==2.2.0 geoip2==2.9.0
youtube-dl youtube-dl

View file

@ -247,6 +247,8 @@ if __name__ == "__main__":
run('./bin/pip', 'install', '-r', 'requirements.txt') run('./bin/pip', 'install', '-r', 'requirements.txt')
update_service('pandora-encoding') update_service('pandora-encoding')
update_service('pandora-tasks') update_service('pandora-tasks')
if old < 5972:
run('./bin/pip', 'install', '-r', 'requirements.txt')
else: else:
if len(sys.argv) == 1: if len(sys.argv) == 1:
release = get_release() release = get_release()