diff --git a/app/settings.py b/app/settings.py index d5fedac..73da621 100644 --- a/app/settings.py +++ b/app/settings.py @@ -144,6 +144,8 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' TIMELINE_PREFIX = "https://aab21.pad.ma/" +DEFAULT_PANDORA_API = "https://pad.ma/api/" + URL_PREFIX = 'polis+' try: diff --git a/app/text/migrations/0007_text_annotations.py b/app/text/migrations/0007_text_annotations.py new file mode 100644 index 0000000..eac84ca --- /dev/null +++ b/app/text/migrations/0007_text_annotations.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.7 on 2021-10-23 09:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('text', '0006_text_position'), + ] + + operations = [ + migrations.AddField( + model_name='text', + name='annotations', + field=models.JSONField(default=dict), + ), + ] diff --git a/app/text/models.py b/app/text/models.py index 81c540b..16b08d3 100644 --- a/app/text/models.py +++ b/app/text/models.py @@ -4,10 +4,13 @@ import json from django.conf import settings from django.contrib.auth import get_user_model from django.db import models +import ox logger = logging.getLogger(__name__) User = get_user_model() +DEFAULT_LAYER = 'descriptions' + class Page(models.Model): created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) @@ -42,6 +45,7 @@ class Text(models.Model): body = models.TextField(default="", blank=True) data = models.JSONField(default=dict) + annotations = models.JSONField(default=dict, blank=True, editable=False) def __str__(self): return self.title @@ -49,10 +53,93 @@ class Text(models.Model): def get_absolute_url(self): return '/' + settings.URL_PREFIX + 'assemblies/' + self.slug + def get_annotations(self): + api = ox.api.signin(settings.DEFAULT_PANDORA_API) + if 'item' in self.data: + return self.get_item_annotations(api) + elif 'edit' in self.data: + return self.get_edit_annotations(api) + else: + raise Exception('Text does not have item or edit.') + + def get_item_annotations(self, api): + query = { + 'id': self.data['item'], + 'keys': [ + 'layers' + ] + } + layer = self.data.get('layer', None) or DEFAULT_LAYER + annotations = api.get(**query)['data']['layers'][layer] + user = self.data.get('user', None) + if user: + annotations = list(filter(lambda annot: annot['user'] == user, annotations)) + return self.get_clips(api, annotations) + + def get_edit_annotations(self, api): + query = { + 'id': self.data['edit'], + 'keys': [] + } + clips = api.getEdit(**query)['data']['clips'] + annotations = [] + layer = self.data.get('layer', None) or DEFAULT_LAYER + for clip in clips: + for annotation in clip['layers'][layer]: + if 'user' in self.data and annotation['user'] == self.data['user']: + continue + annotation['title'] = clip['title'] + annotations.append(annotation) + return self.get_clips(api, annotations) + + def get_clips(self, api, annotations): + item_ids = [annot['id'].split('/')[0] for annot in annotations] + query = { + 'itemsQuery': { + 'conditions': [{ + 'key': 'id', + 'operator': '&', + 'value': item_ids + }] + }, + 'range': [0, 10000], + 'keys': [ + 'id', + 'hue', + 'saturation', + 'lightness' + ] + } + items = api.findClips(**query)['data']['items'] + colors = {} + for item in items: + colors[item['id']] = item + previous = None + for annot in annotations: + annot_id = annot['id'].split('/')[0] + annot_in = '{:.3f}'.format(annot['in']) + annot_out = '{:.3f}'.format(annot['out']) + clip_id = f'{annot_id}/{annot_in}-{annot_out}' + annot['color1'] = colors[clip_id] + if previous: + previous['color2'] = annot['color1'] + previous = annot + if len(annotations) > 0: + annotations[len(annotations) - 1]['color2'] = annotations[0]['color1'] + return annotations + + def save(self, *args, **kwargs): + annotations = self.get_annotations() + self.annotations = annotations + super().save(*args, **kwargs) + + def json(self): data = {} data['title'] = self.title data['byline'] = self.byline data['body'] = self.body + if isinstance(self.annotations, list) and len(self.annotations) > 0: + data['annotations'] = self.annotations data.update(self.data) return json.dumps(data) diff --git a/app/video/management/commands/load_titles.py b/app/video/management/commands/load_titles.py index a2fc9d7..bc16a5c 100644 --- a/app/video/management/commands/load_titles.py +++ b/app/video/management/commands/load_titles.py @@ -1,5 +1,5 @@ from django.core.management.base import BaseCommand - +from django.conf import settings import ox from ... import models @@ -7,7 +7,7 @@ class Command(BaseCommand): help = 'import titles from pan.do/ra' def add_arguments(self, parser): - parser.add_argument("--api", dest="api", type=str, default='https://pad.ma/api/'), + parser.add_argument("--api", dest="api", type=str, default=settings.DEFAULT_PANDORA_API), parser.add_argument("--group", dest="group", type=str, default='Asian Art Biennial 2021'), def handle(self, *args, **options):