From 425edff4ff3d312a879258ca7387d53498ba94ef Mon Sep 17 00:00:00 2001 From: Frederick Yin Date: Sun, 6 Feb 2022 16:44:18 +0800 Subject: Adapt to new AdminLog interface --- jimbrella/umbrellas.py | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) (limited to 'jimbrella/umbrellas.py') diff --git a/jimbrella/umbrellas.py b/jimbrella/umbrellas.py index b3a261d..9b5c7b8 100644 --- a/jimbrella/umbrellas.py +++ b/jimbrella/umbrellas.py @@ -2,6 +2,7 @@ import sqlite3 from datetime import datetime, timezone, timedelta from dateutil.parser import isoparse from typing import Union +from .admin_log import AdminLog from .utils import human_datetime, human_timedelta, CST from .exceptions import * @@ -13,7 +14,8 @@ class Umbrellas: """A database of all umbrellas and their current state. Currently, the data are represented in a SQLite database. Only admins have access to the - database, and have the power to modify it arbitrarily. + database, and have the power to modify it arbitrarily. Each time a modification is made, + AdminLog keeps a log. An SQL row for an umbrella consists of these columns: - id | int. unique identifier for the umbrella. @@ -42,11 +44,12 @@ class Umbrellas: ); """ self.path = path + self.admin_log = AdminLog(path) def read(self, umbid=None) -> Union[dict, list]: """Read umbrella data from database. - If umbid is an integer, returns dict pertaining to umbrella #. + If umbid is an integer, returns dict pertaining to umbrella #, or None if not found. If umbid is None, returns list of dicts for all umbrellas. """ db = sqlite3.connect(self.path) @@ -61,7 +64,7 @@ class Umbrellas: db.close() return data - def update(self, umb) -> dict: + def update(self, umb) -> None: """Update Umbrella table with new data given in `umb`. Not all fields in an umbrella dict need to be present in `umb`. Only `id` is required. @@ -95,15 +98,10 @@ class Umbrellas: if umb_in_db is None: raise UmbrellaNotFoundError(umbid) - diff = {} - status = umb_in_db["status"] if "status" in umb: if umb["status"] in STATUSES: status = umb["status"] - if umb_in_db["status"] != umb["status"]: - diff["status"] = (umb_in_db["status"], umb["status"]) - db.execute( "UPDATE Umbrellas SET status = ? WHERE id = ?", (status, umbid) ) @@ -118,9 +116,6 @@ class Umbrellas: "tenant_email", ): if col in umb: - if umb_in_db[col] != umb[col]: - diff[col] = (umb_in_db[col], umb[col]) - db.execute( f"UPDATE Umbrellas SET {col} = ? WHERE id = ?", ( @@ -143,11 +138,6 @@ class Umbrellas: if lent_at.tzinfo is None: lent_at = lent_at.replace(tzinfo=CST) - diff["lent_at"] = ( - umb_in_db["lent_at"], - lent_at.isoformat(timespec="milliseconds"), - ) - db.execute( "UPDATE Umbrellas SET lent_at = ? WHERE id = ?", ( @@ -169,7 +159,32 @@ class Umbrellas: # now that new data are validated, commit the SQL transaction db.commit() db.close() - return diff + + def admin_modify(self, actor: str, umb: dict, note="") -> None: + """Update db with `umb`, and also keep a log with AdminLog. + + Similar to AdminLog.log, this method does no authentication either. + """ + try: + umbid = umb["id"] + except KeyError: + raise UmbrellaValueError("id") + + umb_old = dict(self.read(umbid)) + if umb_old is None: + raise UmbrellaNotFoundError(umbid) + + self.update(umb) + umb_new = dict(self.read(umbid)) + if umb_old != umb_new: + self.admin_log.log( + datetime.now(tz=CST).isoformat(timespec="milliseconds"), + actor, + umbid, + umb_old, + umb_new, + note, + ) def take_away( self, umbid, date, tenant_name, tenant_id, tenant_phone="", tenant_email="" -- cgit v1.2.3