diff --git a/python/nistoar/midas/dap/service/mds3.py b/python/nistoar/midas/dap/service/mds3.py index 1b25143..d94ed14 100644 --- a/python/nistoar/midas/dap/service/mds3.py +++ b/python/nistoar/midas/dap/service/mds3.py @@ -736,7 +736,7 @@ def clear_data(self, id, part=None, message: str=None, _prec=None) -> bool: part = ("/"+part) if part.startswith("pdr:") else ("."+part) provact.add_subaction(Action(Action.DELETE, _prec.id+"#data"+part, self.who, message)) - _prec.status.act(self.STATUS_ACTION_CLEAR, "cleared "+what) + _prec.status.act(self.STATUS_ACTION_CLEAR, "cleared "+what, self.who.actor) else: nerd.authors.empty() @@ -748,7 +748,7 @@ def clear_data(self, id, part=None, message: str=None, _prec=None) -> bool: if not message: message = "clearing all NERDm data" provact = Action(Action.PATCH, _prec.id, self.who, message) - _prec.status.act(self.STATUS_ACTION_CLEAR, "cleared all NERDm data") + _prec.status.act(self.STATUS_ACTION_CLEAR, "cleared all NERDm data", self.who.actor) except PartNotAccessible: # client request error; don't record action @@ -761,7 +761,7 @@ def clear_data(self, id, part=None, message: str=None, _prec=None) -> bool: provact.message = "Failed to clear requested NERDm data" self._record_action(provact) - _prec.status.act(self.STATUS_ACTION_CLEAR, "Failed to clear NERDm data") + _prec.status.act(self.STATUS_ACTION_CLEAR, "Failed to clear NERDm data", self.who.actor) _prec.set_state(status.EDIT) _prec.data = self._summarize(nerd) self._try_save(_prec) diff --git a/python/nistoar/midas/dbio/project.py b/python/nistoar/midas/dbio/project.py index 95af9dd..7339f05 100644 --- a/python/nistoar/midas/dbio/project.py +++ b/python/nistoar/midas/dbio/project.py @@ -159,7 +159,7 @@ def create_record(self, name, data=None, meta=None) -> ProjectRecord: elif not prec.meta: prec.meta = self._new_metadata_for(shoulder) prec.data = self._new_data_for(prec.id, prec.meta) - prec.status.act(self.STATUS_ACTION_CREATE, "draft created") + prec.status.act(self.STATUS_ACTION_CREATE, "draft created", self.who.actor) if data: self.update_data(prec.id, data, message=None, _prec=prec) # this will call prec.save() else: @@ -528,7 +528,7 @@ def _save_data(self, indata: Mapping, prec: ProjectRecord, # update the record status according to the inputs if action: - prec.status.act(action, message) + prec.status.act(action, message, self.who.actor) elif message is not None: prec.message = message prec.status.set_state(status.EDIT) @@ -571,7 +571,7 @@ def clear_data(self, id: str, part: str=None, message: str=None, prec=None) -> b prec.data = initdata if message is None: message = "reset draft to initial defaults" - prec.status.act(self.STATUS_ACTION_CLEAR, message) + prec.status.act(self.STATUS_ACTION_CLEAR, message, self.who.actor) else: # clearing only part of the data @@ -594,7 +594,7 @@ def clear_data(self, id: str, part: str=None, message: str=None, prec=None) -> b if message is None: message = "reset %s to initial defaults" % part - prec.status.act(self.STATUS_ACTION_UPDATE, message) + prec.status.act(self.STATUS_ACTION_UPDATE, message, self.who.actor) # prep the provenance record tgt = prec.id @@ -673,7 +673,7 @@ def finalize(self, id, message=None, as_version=None, _prec=None) -> status.Reco raise NotEditable(id) stat.set_state(status.PROCESSING) - stat.act(self.STATUS_ACTION_FINALIZE, "in progress") + stat.act(self.STATUS_ACTION_FINALIZE, "in progress", self.who.actor) _prec.save() try: @@ -684,7 +684,7 @@ def finalize(self, id, message=None, as_version=None, _prec=None) -> status.Reco self._record_action(Action(Action.PROCESS, _prec.id, self.who, emsg, {"name": "finalize", "errors": ex.errors})) stat.set_state(status.EDIT) - stat.act(self.STATUS_ACTION_FINALIZE, ex.format_errors()) + stat.act(self.STATUS_ACTION_FINALIZE, ex.format_errors(), self.who.actor) self._try_save(_prec) raise @@ -694,7 +694,7 @@ def finalize(self, id, message=None, as_version=None, _prec=None) -> status.Reco self._record_action(Action(Action.PROCESS, _prec.id, self.who, emsg, {"name": "finalize", "errors": [emsg]})) stat.set_state(status.EDIT) - stat.act(self.STATUS_ACTION_FINALIZE, emsg) + stat.act(self.STATUS_ACTION_FINALIZE, emsg, self.who.actor) self._try_save(_prec) raise @@ -704,7 +704,7 @@ def finalize(self, id, message=None, as_version=None, _prec=None) -> status.Reco if reset_state: stat.set_state(status.READY) - stat.act(self.STATUS_ACTION_FINALIZE, message or defmsg) + stat.act(self.STATUS_ACTION_FINALIZE, message or defmsg, self.who.actor) _prec.save() self.log.info("Finalized %s record %s (%s) for %s", @@ -822,7 +822,7 @@ def submit(self, id: str, message: str=None, _prec=None) -> status.RecordStatus: self._record_action(Action(Action.PROCESS, _prec.id, self.who, emsg, {"name": "submit", "errors": ex.errors})) stat.set_state(status.EDIT) - stat.act(self.STATUS_ACTION_SUBMIT, ex.format_errors()) + stat.act(self.STATUS_ACTION_SUBMIT, ex.format_errors(), self.who.actor) self._try_save(_prec) raise @@ -831,7 +831,7 @@ def submit(self, id: str, message: str=None, _prec=None) -> status.RecordStatus: self._record_action(Action(Action.PROCESS, _prec.id, self.who, emsg, {"name": "submit", "errors": [emsg]})) stat.set_state(status.EDIT) - stat.act(self.STATUS_ACTION_SUBMIT, emsg) + stat.act(self.STATUS_ACTION_SUBMIT, emsg, self.who.actor) self._try_save(_prec) raise @@ -840,7 +840,7 @@ def submit(self, id: str, message: str=None, _prec=None) -> status.RecordStatus: self.dbcli.record_action(Action(Action.PROCESS, _prec.id, self.who, defmsg, {"name": "submit"})) stat.set_state(status.SUBMITTED) - stat.act(self.STATUS_ACTION_SUBMIT, message or defmsg) + stat.act(self.STATUS_ACTION_SUBMIT, message or defmsg, self.who.actor) _prec.save() self.log.info("Submitted %s record %s (%s) for %s", diff --git a/python/nistoar/midas/dbio/status.py b/python/nistoar/midas/dbio/status.py index 2952aef..54bac3e 100644 --- a/python/nistoar/midas/dbio/status.py +++ b/python/nistoar/midas/dbio/status.py @@ -31,6 +31,7 @@ _modified_p = "modified" _created_p = "created" _message_p = "message" +_bywho_p = "byWho" # Common record actions # @@ -139,6 +140,14 @@ def action(self) -> str: """ return self._data[_action_p] + @property + def by_who(self) -> str: + """ + the identifier of the agent that committed the last action applied to the record. If None, + the agent is unknown. + """ + return self._data.get(_bywho_p) + @property def modified(self) -> float: """ @@ -168,7 +177,7 @@ def message(self) -> str: def message(self, val): self._data[_message_p] = val - def act(self, action: str, message: str="", when: float=0): + def act(self, action: str, message: str="", who: str=None, when: float=0): """ record the application of a particular action on the record :param str action: the name of the action being applied @@ -190,6 +199,7 @@ def act(self, action: str, message: str="", when: float=0): self._data[_modified_p] = when if self._data[_created_p] < 1: self._data[_created_p] = when + self._data[_bywho_p] = who def set_state(self, state, when: float=-1): """ diff --git a/python/tests/nistoar/midas/dbio/test_status.py b/python/tests/nistoar/midas/dbio/test_status.py index b0f5038..8714f28 100644 --- a/python/tests/nistoar/midas/dbio/test_status.py +++ b/python/tests/nistoar/midas/dbio/test_status.py @@ -25,6 +25,7 @@ def test_act(self): self.assertEqual(stat.id, "goob") self.assertEqual(stat.state, status.EDIT) self.assertEqual(stat.action, status.ACTION_CREATE) + self.assertIsNone(stat.by_who) self.assertEqual(stat.message, "") self.assertGreater(stat.since, 0) self.assertGreater(stat.modified, 0) @@ -36,6 +37,7 @@ def test_act(self): stat.act(Action.PATCH, "made updates") self.assertEqual(stat.state, status.EDIT) self.assertEqual(stat.action, Action.PATCH) + self.assertIsNone(stat.by_who) self.assertEqual(stat.message, "made updates") self.assertEqual(stat.modified, 0) self.assertGreater(stat.created, 0) @@ -46,14 +48,25 @@ def test_act(self): stat.act(Action.PUT) self.assertEqual(stat.state, status.EDIT) self.assertEqual(stat.action, Action.PUT) + self.assertIsNone(stat.by_who) self.assertEqual(stat.message, "") self.assertEqual(stat.modified, 0) self.assertNotEqual(stat.since_date, "pending") self.assertEqual(stat.modified_date, "pending") - stat.act(Action.COMMENT, "Whoa", -1) + stat.act(Action.COMMENT, "Whoa", when=-1) self.assertEqual(stat.state, status.EDIT) self.assertEqual(stat.action, Action.COMMENT) + self.assertIsNone(stat.by_who) + self.assertEqual(stat.message, "Whoa") + self.assertGreater(stat.modified, stat.since) + self.assertNotEqual(stat.since_date, "pending") + self.assertNotEqual(stat.modified_date, "pending") + + stat.act(Action.COMMENT, "Whoa", "nstr1", -1) + self.assertEqual(stat.state, status.EDIT) + self.assertEqual(stat.action, Action.COMMENT) + self.assertEqual(stat.by_who, "nstr1") self.assertEqual(stat.message, "Whoa") self.assertGreater(stat.modified, stat.since) self.assertNotEqual(stat.since_date, "pending")