import hashlib from datetime import datetime class Event(object): """ Class that represents something that modifies the state of the system """ def __init__(self, message="", user_id="", date=None, parents=None): self.user_id: str = user_id # id of the user that triggers the modification self.date: datetime | None = date or datetime.now() # when self.message: str = message # user input or whatever that modifies the system self.parents: list[str] = parents # digest(s) of the parent(s) of this event self._digest: str | None = None # digest of the event def __str__(self): return f"{self.date.strftime('%d/%m/%Y %H:%M:%S')} {self.message}" def __repr__(self): return f"{self.get_digest()[:12]} {self.message}" def get_digest(self): """ Returns the digest of the event :return: sha256 of the event """ if self._digest: return self._digest if self.user_id == "": # only possible during the unit test # We use this little trick to speed up the unit test self._digest = self.message[6:] if self.message.startswith("TEST::") else "xxx" return self._digest if not isinstance(self.message, str): raise NotImplementedError(f"message={self.message}") to_hash = f"Event:{self.user_id}{self.date}{self.message}{self.parents}".encode("utf-8") self._digest = hashlib.sha256(to_hash).hexdigest() return self._digest def to_dict(self): return self.__dict__ def from_dict(self, as_dict): self.user_id = as_dict["user_id"] self.date = datetime.fromisoformat(as_dict["date"]) self.message = as_dict["message"] self.parents = as_dict["parents"] self._digest = as_dict["_digest"] # freeze the digest def __eq__(self, other): if id(self) == id(other): return True if isinstance(other, Event): return (self.user_id == other.user_id and self.date == other.date and self.message == other.message and self.parents == other.parents) return False def __hash__(self): return hash(self.get_digest())