store annotations in db and sync with peers
This commit is contained in:
parent
131a6a3215
commit
e0cba14d6a
21 changed files with 385 additions and 63 deletions
48
oml/annotation/api.py
Normal file
48
oml/annotation/api.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from oxtornado import actions
|
||||
from . import models
|
||||
import settings
|
||||
import state
|
||||
from changelog import add_record
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def getAnnotations(data):
|
||||
response = {}
|
||||
response['annotations'] = models.Annotation.get_by_item(data['id'])
|
||||
return response
|
||||
actions.register(getAnnotations)
|
||||
|
||||
|
||||
def addAnnotation(data):
|
||||
item_id = data.pop('item')
|
||||
a = models.Annotation.create(item_id, settings.USER_ID, data)
|
||||
a.add_record('addannotation')
|
||||
response = a.json()
|
||||
return response
|
||||
actions.register(addAnnotation)
|
||||
|
||||
|
||||
def editNote(data):
|
||||
a = models.Annotation.get(state.user(), data['item'], data['annotation'])
|
||||
if a:
|
||||
a.data['notes'] = data['notes']
|
||||
a.add_record('editannotation')
|
||||
a.save()
|
||||
response = a.json()
|
||||
else:
|
||||
response = {}
|
||||
return response
|
||||
actions.register(editNote)
|
||||
|
||||
|
||||
def removeAnnotation(data):
|
||||
a = models.Annotation.get(state.user(), data['item'], data['annotation'])
|
||||
if a:
|
||||
a.add_record('removeannotation')
|
||||
a.delete()
|
||||
response = {}
|
||||
return response
|
||||
actions.register(removeAnnotation)
|
||||
|
|
@ -4,6 +4,7 @@ import json
|
|||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import unicodedata
|
||||
|
||||
from sqlalchemy.orm import load_only
|
||||
import ox
|
||||
|
|
@ -31,10 +32,15 @@ class Annotation(db.Model):
|
|||
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()
|
||||
|
|
@ -43,28 +49,44 @@ class Annotation(db.Model):
|
|||
self.data = data
|
||||
|
||||
@classmethod
|
||||
def create(cls, **kwargs):
|
||||
a = cls(**kwargs)
|
||||
state.db.session.add(a)
|
||||
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):
|
||||
for a in cls.query.filter_by(item_id=item_id, user=user, _id=annotation_id):
|
||||
if a.data.get('id') == annotation_id:
|
||||
return a
|
||||
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, user, item_id):
|
||||
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
|
||||
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()
|
||||
|
||||
|
|
@ -73,6 +95,30 @@ class Annotation(db.Model):
|
|||
data['created'] = self.created
|
||||
data['modified'] = self.modified
|
||||
data['user'] = self.user_id
|
||||
data['_id'] = ox.toAZ(self.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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue