diff options
author | Frederick Yin <fkfd@fkfd.me> | 2021-10-31 17:03:19 +0800 |
---|---|---|
committer | Frederick Yin <fkfd@fkfd.me> | 2021-10-31 17:13:01 +0800 |
commit | 7644830f34f3bd81d3b21b2d05710fbc91f20eb6 (patch) | |
tree | d20b89bacc2cec650e00d3f1e9ba68d8d699356b /jimbrella | |
parent | 59c899e372a6d5e0309c585de43df015f775ebe7 (diff) |
Implement ADMIN_MODIFY_DB logs
When an admin requests /admin/umbrella/edit and the request succeeds, an
ADMIN_MODIFY_DB log is kept. `Database.update` will keep track of the
updated columns.
Diffstat (limited to 'jimbrella')
-rw-r--r-- | jimbrella/admin.py | 16 | ||||
-rw-r--r-- | jimbrella/admin_log.py | 10 | ||||
-rw-r--r-- | jimbrella/database.py | 19 |
3 files changed, 39 insertions, 6 deletions
diff --git a/jimbrella/admin.py b/jimbrella/admin.py index 9a9f6c8..eaf0e54 100644 --- a/jimbrella/admin.py +++ b/jimbrella/admin.py @@ -72,9 +72,8 @@ def umbrellas_edit(): ]: data[key] = request.form.get(key) - error = None try: - db.update(data) + diff = db.update(data) except UmbrellaValueError as e: # invalid field is in `e.message`. return redirect( @@ -85,6 +84,19 @@ def umbrellas_edit(): except UmbrellaNotFoundError: pass # impossible on web console + for column, value_pair in diff.items(): + past, new = value_pair + admin_log.log( + "ADMIN_MODIFY_DB", + { + "admin_name": session["username"], + "serial": data["serial"], + "column": column, + "past_value": past, + "new_value": new, + }, + ) + return redirect(url_for("admin.umbrellas")) diff --git a/jimbrella/admin_log.py b/jimbrella/admin_log.py index 8b5bb09..622abec 100644 --- a/jimbrella/admin_log.py +++ b/jimbrella/admin_log.py @@ -106,7 +106,15 @@ class AdminLog: "{name} missed the due for umbrella #{key}. " + tenant_info ) elif event == "ADMIN_MODIFY_DB": - description = "{admin_name} changed {column} of umbrella #{serial} from {past_value} to {new_value}." + if not entry["past_value"]: + description = "{admin_name} set {column} of umbrella #{serial} to {new_value}." + elif not entry["new_value"]: + description = "{admin_name} cleared {column} of umbrella #{serial} (was {past_value})." + else: + description = ( + "{admin_name} changed {column} of umbrella #{serial} " + "from {past_value} to {new_value}." + ) friendly_logs.append( { diff --git a/jimbrella/database.py b/jimbrella/database.py index a8d480b..9b6e51f 100644 --- a/jimbrella/database.py +++ b/jimbrella/database.py @@ -91,7 +91,7 @@ class Database(CsvTable): umbrellas[idx]["lent_time_ago_str"] = human_timedelta(lent_time_ago) return umbrellas - def update(self, umb) -> list: + def update(self, umb) -> dict: """An interface to `_update()` with added convenience and safeguards. Convenience: Not all fields in an umbrella dict need to be present in `umb`. If an @@ -117,7 +117,8 @@ class Database(CsvTable): fields mentioned above are made blank, and these fields supplied in `umb` are ignored. - Returns updated database (same as `_update()`). + Returns a dict, where the keys are all modified columns of the updated row, and the value + of each is a 2-tuple (<past value>, <new value>). """ # `serial` must be specified. if "serial" not in umb: @@ -169,7 +170,19 @@ class Database(CsvTable): if not umb["lent_at"]: raise UmbrellaValueError("lent_at") - return self._update(umb) + # commit update + self._update(umb) + + # find updated columns + # essentially "diff umb_in_db umb" + diff = {} + for key, new in umb.items(): + past = umb_in_db[key] + if any([new, past]) and new != past: + # new and past are not both null values, and they are unequal + diff[key] = (past, new) + + return diff @staticmethod def group_by_status(umbrellas) -> dict: |