diff options
Diffstat (limited to 'server/szurubooru/func/snapshots.py')
| -rw-r--r-- | server/szurubooru/func/snapshots.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/server/szurubooru/func/snapshots.py b/server/szurubooru/func/snapshots.py new file mode 100644 index 0000000..5d366ab --- /dev/null +++ b/server/szurubooru/func/snapshots.py @@ -0,0 +1,89 @@ +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], + 'category': tag.category.name, + 'suggestions': sorted(rel.first_name for rel in tag.suggestions), + 'implications': sorted(rel.first_name for rel in tag.implications), + } + return ret + +def get_tag_category_snapshot(category): + return { + 'name': category.name, + 'color': category.color, + } + +# pylint: disable=invalid-name +serializers = { + 'tag': get_tag_snapshot, + 'tag_category': get_tag_category_snapshot, +} + +def get_resource_info(entity): + table_name = entity.__table__.name + primary_key = inspect(entity).identity + assert table_name in serializers + assert primary_key is not None + assert len(primary_key) == 1 + primary_key = primary_key[0] + return (table_name, primary_key) + +def get_snapshots(entity): + table_name, primary_key = get_resource_info(entity) + return db.session \ + .query(db.Snapshot) \ + .filter(db.Snapshot.resource_type == table_name) \ + .filter(db.Snapshot.resource_id == primary_key) \ + .order_by(db.Snapshot.creation_time.desc()) \ + .all() + +def get_data(entity): + ret = [] + for snapshot in get_snapshots(entity): + ret.append({'data': snapshot.data, 'time': snapshot.creation_time}) + return ret + +def save(operation, entity, auth_user): + table_name, primary_key = get_resource_info(entity) + now = datetime.datetime.now() + + snapshot = db.Snapshot() + snapshot.creation_time = now + snapshot.operation = operation + snapshot.resource_type = table_name + snapshot.resource_id = primary_key + snapshot.data = serializers[table_name](entity) + snapshot.user = auth_user + + earlier_snapshots = get_snapshots(entity) + + 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 + db.session.delete(last_snapshot) + 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: + db.session.add(snapshot) + +def create(entity, auth_user): + save(db.Snapshot.OPERATION_CREATED, entity, auth_user) + +def modify(entity, auth_user): + save(db.Snapshot.OPERATION_MODIFIED, entity, auth_user) + +def delete(entity, auth_user): + save(db.Snapshot.OPERATION_DELETED, entity, auth_user) |