124 lines
3.6 KiB
Python
124 lines
3.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
from datetime import datetime
|
|
import json
|
|
import logging
|
|
import os
|
|
import shutil
|
|
import unicodedata
|
|
|
|
from sqlalchemy.orm import load_only
|
|
import ox
|
|
import sqlalchemy as sa
|
|
|
|
from changelog import add_record
|
|
from db import MutableDict
|
|
import db
|
|
import json_pickler
|
|
import settings
|
|
import state
|
|
import utils
|
|
import media
|
|
from websocket import trigger_event
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class Annotation(db.Model):
|
|
__tablename__ = 'annotation'
|
|
|
|
_id = sa.Column(sa.Integer(), primary_key=True)
|
|
id = sa.Column(sa.String(43))
|
|
created = sa.Column(sa.DateTime())
|
|
modified = sa.Column(sa.DateTime())
|
|
|
|
user_id = sa.Column(sa.String(43), sa.ForeignKey('user.id'))
|
|
user = sa.orm.relationship('User', backref=sa.orm.backref('annotations', lazy='dynamic'))
|
|
item_id = sa.Column(sa.String(43), sa.ForeignKey('item.id'))
|
|
item = sa.orm.relationship('Item', backref=sa.orm.backref('items', lazy='dynamic'))
|
|
data = sa.Column(MutableDict.as_mutable(sa.PickleType(pickler=json_pickler)))
|
|
|
|
findquotes = sa.Column(sa.Text(), index=True)
|
|
findnotes = sa.Column(sa.Text(), index=True)
|
|
|
|
def __init__(self, item_id, user_id, data):
|
|
self.created = datetime.utcnow()
|
|
self.modified = datetime.utcnow()
|
|
self.item_id = item_id
|
|
self.user_id = user_id
|
|
self.data = data
|
|
|
|
@classmethod
|
|
def create(cls, item_id, user_id, data):
|
|
a = cls(item_id, user_id, data)
|
|
a.save()
|
|
return a
|
|
|
|
def delete(self):
|
|
state.db.session.delete(self)
|
|
state.db.session.commit()
|
|
|
|
@classmethod
|
|
def get(cls, user, item_id, annotation_id):
|
|
if isinstance(user, str):
|
|
qs = cls.query.filter_by(item_id=item_id, user_id=user, id=annotation_id)
|
|
else:
|
|
qs = cls.query.filter_by(item_id=item_id, user=user, id=annotation_id)
|
|
for a in qs:
|
|
return a
|
|
|
|
@classmethod
|
|
def get_by_item(cls, item_id):
|
|
annotations = []
|
|
for a in cls.query.filter_by(item_id=item_id):
|
|
annotations.append(a.json())
|
|
return annotations
|
|
|
|
def save(self):
|
|
id = self.data.get('id')
|
|
if id:
|
|
self.id = id
|
|
self.findquotes = unicodedata.normalize('NFKD', self.data.get('text', '')).lower()
|
|
note = self.data.get('notes', {})
|
|
if isinstance(note, list) and note:
|
|
note = note[0]
|
|
if isinstance(note, dict):
|
|
note = note.get('value', '')
|
|
else:
|
|
note = ''
|
|
self.findnotes = unicodedata.normalize('NFKD', note).lower()
|
|
state.db.session.add(self)
|
|
state.db.session.commit()
|
|
|
|
def json(self):
|
|
data = self.data.copy()
|
|
data['created'] = self.created
|
|
data['modified'] = self.modified
|
|
data['user'] = self.user_id
|
|
data['_id'] = ox.toAZ(self._id)
|
|
if isinstance(data.get('notes'), dict):
|
|
note = data['notes']
|
|
if self.user_id != settings.USER_ID:
|
|
note['user'] = self.user_id
|
|
if not note.get('id'):
|
|
note['id'] = 'A'
|
|
data['notes'] = [data['notes']]
|
|
if 'notes' not in data:
|
|
data['notes'] = []
|
|
return data
|
|
|
|
def add_record(self, action):
|
|
args = [self.item_id]
|
|
if action == 'addannotation':
|
|
args.append(self.data)
|
|
elif action == 'editannotation':
|
|
args.append(self.id)
|
|
args.append({
|
|
'notes': self.data['notes']
|
|
})
|
|
elif action == 'removeannotation':
|
|
args.append(self.id)
|
|
else:
|
|
raise Exception('unknown action')
|
|
add_record(action, *args)
|
|
|