2016-04-18 18:44:39 +00:00
|
|
|
import datetime
|
|
|
|
from sqlalchemy.inspection import inspect
|
|
|
|
from szurubooru import db
|
|
|
|
|
|
|
|
def get_tag_snapshot(tag):
|
|
|
|
ret = {
|
|
|
|
'names': [tag_name.name for tag_name in tag.names],
|
2016-04-20 09:15:36 +00:00
|
|
|
'category': tag.category.name,
|
|
|
|
'suggestions': sorted(rel.first_name for rel in tag.suggestions),
|
|
|
|
'implications': sorted(rel.first_name for rel in tag.implications),
|
2016-04-18 18:44:39 +00:00
|
|
|
}
|
|
|
|
return ret
|
|
|
|
|
2016-04-19 16:11:00 +00:00
|
|
|
def get_tag_category_snapshot(category):
|
|
|
|
return {
|
|
|
|
'name': category.name,
|
|
|
|
'color': category.color,
|
|
|
|
}
|
|
|
|
|
2016-04-18 20:41:39 +00:00
|
|
|
# pylint: disable=invalid-name
|
2016-04-18 18:44:39 +00:00
|
|
|
serializers = {
|
2016-04-21 16:59:44 +00:00
|
|
|
'tag': (
|
|
|
|
get_tag_snapshot,
|
|
|
|
lambda tag: tag.first_name),
|
|
|
|
'tag_category': (
|
|
|
|
get_tag_category_snapshot,
|
|
|
|
lambda category: category.name),
|
2016-04-18 18:44:39 +00:00
|
|
|
}
|
|
|
|
|
2016-04-20 09:15:36 +00:00
|
|
|
def get_resource_info(entity):
|
2016-04-21 16:59:44 +00:00
|
|
|
resource_type = entity.__table__.name
|
|
|
|
assert resource_type in serializers
|
|
|
|
|
2016-04-18 18:44:39 +00:00
|
|
|
primary_key = inspect(entity).identity
|
2016-04-19 16:11:00 +00:00
|
|
|
assert primary_key is not None
|
2016-04-18 18:44:39 +00:00
|
|
|
assert len(primary_key) == 1
|
2016-04-21 16:59:44 +00:00
|
|
|
|
|
|
|
resource_repr = serializers[resource_type][1](entity)
|
|
|
|
assert resource_repr
|
|
|
|
|
|
|
|
resource_id = primary_key[0]
|
|
|
|
assert resource_id
|
|
|
|
|
|
|
|
return (resource_type, resource_id, resource_repr)
|
2016-04-20 09:15:36 +00:00
|
|
|
|
|
|
|
def get_snapshots(entity):
|
2016-04-21 16:59:44 +00:00
|
|
|
resource_type, resource_id, _ = get_resource_info(entity)
|
2016-04-20 09:15:36 +00:00
|
|
|
return db.session \
|
|
|
|
.query(db.Snapshot) \
|
2016-04-21 16:59:44 +00:00
|
|
|
.filter(db.Snapshot.resource_type == resource_type) \
|
|
|
|
.filter(db.Snapshot.resource_id == resource_id) \
|
2016-04-20 09:15:36 +00:00
|
|
|
.order_by(db.Snapshot.creation_time.desc()) \
|
|
|
|
.all()
|
|
|
|
|
2016-04-21 16:59:44 +00:00
|
|
|
def serialize_snapshot(snapshot, earlier_snapshot):
|
|
|
|
return {
|
|
|
|
'operation': snapshot.operation,
|
|
|
|
'type': snapshot.resource_type,
|
|
|
|
'id': snapshot.resource_repr,
|
|
|
|
'user': snapshot.user.name,
|
|
|
|
'data': snapshot.data,
|
|
|
|
'earlier-data': earlier_snapshot.data if earlier_snapshot else None,
|
|
|
|
'time': snapshot.creation_time,
|
|
|
|
}
|
|
|
|
|
|
|
|
def get_serialized_history(entity):
|
2016-04-20 09:15:36 +00:00
|
|
|
ret = []
|
2016-04-21 16:59:44 +00:00
|
|
|
earlier_snapshot = None
|
|
|
|
for snapshot in reversed(get_snapshots(entity)):
|
|
|
|
ret.insert(0, serialize_snapshot(snapshot, earlier_snapshot))
|
|
|
|
earlier_snapshot = snapshot
|
2016-04-20 09:15:36 +00:00
|
|
|
return ret
|
|
|
|
|
|
|
|
def save(operation, entity, auth_user):
|
2016-04-21 16:59:44 +00:00
|
|
|
resource_type, resource_id, resource_repr = get_resource_info(entity)
|
2016-04-18 18:44:39 +00:00
|
|
|
now = datetime.datetime.now()
|
|
|
|
|
|
|
|
snapshot = db.Snapshot()
|
|
|
|
snapshot.creation_time = now
|
|
|
|
snapshot.operation = operation
|
2016-04-21 16:59:44 +00:00
|
|
|
snapshot.resource_type = resource_type
|
|
|
|
snapshot.resource_id = resource_id
|
|
|
|
snapshot.resource_repr = resource_repr
|
|
|
|
snapshot.data = serializers[resource_type][0](entity)
|
2016-04-18 18:44:39 +00:00
|
|
|
snapshot.user = auth_user
|
|
|
|
|
2016-04-20 09:15:36 +00:00
|
|
|
earlier_snapshots = get_snapshots(entity)
|
2016-04-18 18:44:39 +00:00
|
|
|
|
|
|
|
delta = datetime.timedelta(minutes=10)
|
|
|
|
snapshots_left = len(earlier_snapshots)
|
|
|
|
while earlier_snapshots:
|
|
|
|
last_snapshot = earlier_snapshots.pop(0)
|
|
|
|
is_fresh = now - last_snapshot.creation_time <= delta
|
|
|
|
if snapshot.data != last_snapshot.data:
|
|
|
|
if not is_fresh or last_snapshot.user != auth_user:
|
|
|
|
break
|
2016-04-19 15:39:16 +00:00
|
|
|
db.session.delete(last_snapshot)
|
2016-04-18 18:44:39 +00:00
|
|
|
if snapshot.operation != db.Snapshot.OPERATION_DELETED:
|
|
|
|
snapshot.operation = last_snapshot.operation
|
|
|
|
snapshots_left -= 1
|
|
|
|
|
|
|
|
if not snapshots_left and operation == db.Snapshot.OPERATION_DELETED:
|
|
|
|
pass
|
|
|
|
else:
|
2016-04-19 15:39:16 +00:00
|
|
|
db.session.add(snapshot)
|
2016-04-18 18:44:39 +00:00
|
|
|
|
2016-04-18 20:41:39 +00:00
|
|
|
def create(entity, auth_user):
|
|
|
|
save(db.Snapshot.OPERATION_CREATED, entity, auth_user)
|
2016-04-18 18:44:39 +00:00
|
|
|
|
2016-04-18 20:41:39 +00:00
|
|
|
def modify(entity, auth_user):
|
|
|
|
save(db.Snapshot.OPERATION_MODIFIED, entity, auth_user)
|
2016-04-18 18:44:39 +00:00
|
|
|
|
2016-04-18 20:41:39 +00:00
|
|
|
def delete(entity, auth_user):
|
|
|
|
save(db.Snapshot.OPERATION_DELETED, entity, auth_user)
|