From 1c8a0424cc060e4415a63b663021e2e608c28753 Mon Sep 17 00:00:00 2001 From: Kai Kuehner Date: Tue, 14 Sep 2021 21:12:08 -0400 Subject: [PATCH 1/2] add undo_info parameter to tabular changelog --- pychunkedgraph/app/segmentation/common.py | 48 +++++++++++++++++++- pychunkedgraph/app/segmentation/v1/routes.py | 6 ++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/pychunkedgraph/app/segmentation/common.py b/pychunkedgraph/app/segmentation/common.py index ad88d65de..69ac16084 100644 --- a/pychunkedgraph/app/segmentation/common.py +++ b/pychunkedgraph/app/segmentation/common.py @@ -846,7 +846,7 @@ def tabular_change_log_recent(table_id): ) -def tabular_change_logs(table_id, root_ids, filtered=False): +def tabular_change_logs(table_id, root_ids, filtered=False, undo_info=False): current_app.request_type = "tabular_changelog_many" current_app.table_id = table_id @@ -863,6 +863,52 @@ def tabular_change_logs(table_id, root_ids, filtered=False): tab = history.tabular_changelogs_filtered else: tab = history.tabular_changelogs + + if undo_info: + undone_ids = np.empty((0, 2), dtype=np.uint64) + undo_ids = np.empty((0, 1), dtype=np.uint64) + redo_ids = np.empty((0, 1), dtype=np.uint64) + log_rows = cg.client.read_log_entries() + + entry_ids = np.sort(list(log_rows.keys())) + for entry_id in entry_ids: + entry = log_rows[entry_id] + + should_check = ( + not OperationLogs.Status in entry + or entry[OperationLogs.Status] == OperationLogs.StatusCodes.SUCCESS.value + ) + if should_check: + # if it is an undo of another operation, mark it as undone + if OperationLogs.UndoOperationID in entry: + undone_id = entry[OperationLogs.UndoOperationID] + undone_ids = np.append(undone_ids, np.array([[undone_id, entry_id]]), axis=0) + undo_ids = np.append(undo_ids, entry_id) + + # if it is a redo of another operation, unmark it as undone + if OperationLogs.RedoOperationID in entry: + redone_id = entry[OperationLogs.RedoOperationID] + undone_ids = undone_ids[undone_ids[:, 0] != redone_id] + redo_ids = np.append(redo_ids, entry_id) + + for tab_k in tab.keys(): + operation_ids = tab[tab_k]["operation_id"] + def get_is_undo(id): + if id in undo_ids: + return "undo" + if id in redo_ids: + return "redo" + return "" + is_undo = np.array(list(map(get_is_undo, operation_ids))) + tab[tab_k]["is_undo"] = is_undo + def get_undone_by(id): + row = undone_ids[np.where(undone_ids[:, 0] == id)] + if len(row) > 0: + return row[0][1] + return None + undone_by = np.array(list(map(get_undone_by, operation_ids))) + tab[tab_k]["undone_by"] = undone_by + all_user_ids = [] for tab_k in tab.keys(): all_user_ids.extend(np.array(tab[tab_k]["user_id"]).reshape(-1)) diff --git a/pychunkedgraph/app/segmentation/v1/routes.py b/pychunkedgraph/app/segmentation/v1/routes.py index a5fcc06eb..d0a9fc530 100644 --- a/pychunkedgraph/app/segmentation/v1/routes.py +++ b/pychunkedgraph/app/segmentation/v1/routes.py @@ -406,7 +406,8 @@ def tabular_change_log(table_id, root_id): disp = request.args.get("disp", default=False, type=toboolean) get_root_ids = request.args.get("root_ids", default=False, type=toboolean) filtered = request.args.get("filtered", default=True, type=toboolean) - tab_change_log_dict = common.tabular_change_logs(table_id, [int(root_id)], filtered) + undo_info = request.args.get("undo_info", default=False, type=toboolean) + tab_change_log_dict = common.tabular_change_logs(table_id, [int(root_id)], filtered, undo_info) tab_change_log = tab_change_log_dict[int(root_id)] if disp: return tab_change_log.to_html() @@ -420,8 +421,9 @@ def tabular_change_log_many(table_id): import numpy as np filtered = request.args.get("filtered", default=True, type=toboolean) + undo_info = request.args.get("undo_info", default=False, type=toboolean) root_ids = np.array(json.loads(request.data)["root_ids"], dtype=np.uint64) - tab_change_log_dict = common.tabular_change_logs(table_id, root_ids, filtered) + tab_change_log_dict = common.tabular_change_logs(table_id, root_ids, filtered, undo_info) return jsonify_with_kwargs( {str(k): tab_change_log_dict[k] for k in tab_change_log_dict.keys()} From b3563e8ade432209fa380472c751ec79c9dbb645 Mon Sep 17 00:00:00 2001 From: Kai Kuehner Date: Tue, 14 Sep 2021 21:18:44 -0400 Subject: [PATCH 2/2] replace None with empty string for undone_by of non-undone edits --- pychunkedgraph/app/segmentation/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pychunkedgraph/app/segmentation/common.py b/pychunkedgraph/app/segmentation/common.py index 69ac16084..6415469a3 100644 --- a/pychunkedgraph/app/segmentation/common.py +++ b/pychunkedgraph/app/segmentation/common.py @@ -905,7 +905,7 @@ def get_undone_by(id): row = undone_ids[np.where(undone_ids[:, 0] == id)] if len(row) > 0: return row[0][1] - return None + return "" undone_by = np.array(list(map(get_undone_by, operation_ids))) tab[tab_k]["undone_by"] = undone_by