def take_snapshot(obj:object, *, comment:str="", user=None, delete:bool=False): """ Given any model instance with registred content type, create new history entry of "change" type. This raises exception in case of object wasn't previously freezed. """ key = make_key_from_model_object(obj) typename = get_typename_for_model_class(obj.__class__) new_fobj = freeze_model_instance(obj) old_fobj, need_real_snapshot = get_last_snapshot_for_key(key) entry_model = apps.get_model("history", "HistoryEntry") user_id = None if user is None else user.id user_name = "" if user is None else user.get_full_name() # Determine history type if delete: entry_type = HistoryType.delete elif new_fobj and not old_fobj: entry_type = HistoryType.create elif new_fobj and old_fobj: entry_type = HistoryType.change else: raise RuntimeError("Unexpected condition") fdiff = make_diff(old_fobj, new_fobj) # If diff and comment are empty, do # not create empty history entry if (not fdiff.diff and not comment and old_fobj is not None and entry_type != HistoryType.delete): return None fvals = make_diff_values(typename, fdiff) if len(comment) > 0: is_hidden = False else: is_hidden = is_hidden_snapshot(fdiff) kwargs = { "user": {"pk": user_id, "name": user_name}, "key": key, "type": entry_type, "snapshot": fdiff.snapshot if need_real_snapshot else None, "diff": fdiff.diff, "values": fvals, "comment": comment, "comment_html": mdrender(obj.project, comment), "is_hidden": is_hidden, "is_snapshot": need_real_snapshot, } return entry_model.objects.create(**kwargs)
def freeze_model_instance(obj: object) -> FrozenObj: """ Creates a new frozen object from model instance. The freeze process consists on converting model instances to hashable plain python objects and wrapped into FrozenObj. """ model_cls = obj.__class__ # Additional query for test if object is really exists # on the database or it is removed. try: obj = model_cls.objects.get(pk=obj.pk) except model_cls.DoesNotExist: return None typename = get_typename_for_model_class(model_cls) if typename not in _freeze_impl_map: raise RuntimeError("No implementation found for {}".format(typename)) key = make_key_from_model_object(obj) impl_fn = _freeze_impl_map[typename] snapshot = impl_fn(obj) assert isinstance(snapshot, dict), \ "freeze handlers should return always a dict" return FrozenObj(key, snapshot)
def freeze_model_instance(obj:object) -> FrozenObj: """ Creates a new frozen object from model instance. The freeze process consists on converting model instances to hashable plain python objects and wrapped into FrozenObj. """ model_cls = obj.__class__ # Additional query for test if object is really exists # on the database or it is removed. try: obj = model_cls.objects.get(pk=obj.pk) except model_cls.DoesNotExist: return None typename = get_typename_for_model_class(model_cls) if typename not in _freeze_impl_map: raise RuntimeError("No implementation found for {}".format(typename)) key = make_key_from_model_object(obj) impl_fn = _freeze_impl_map[typename] snapshot = impl_fn(obj) assert isinstance(snapshot, dict), "freeze handlers should return always a dict" return FrozenObj(key, snapshot)
def take_snapshot(obj:object, *, comment:str="", user=None, delete:bool=False): """ Given any model instance with registred content type, create new history entry of "change" type. This raises exception in case of object wasn't previously freezed. """ key = make_key_from_model_object(obj) typename = get_typename_for_model_class(obj.__class__) new_fobj = freeze_model_instance(obj) old_fobj, need_real_snapshot = get_last_snapshot_for_key(key) entry_model = apps.get_model("history", "HistoryEntry") user_id = None if user is None else user.id user_name = "" if user is None else user.get_full_name() # Determine history type if delete: entry_type = HistoryType.delete elif new_fobj and not old_fobj: entry_type = HistoryType.create elif new_fobj and old_fobj: entry_type = HistoryType.change else: raise RuntimeError("Unexpected condition") fdiff = make_diff(old_fobj, new_fobj) # If diff and comment are empty, do # not create empty history entry if (not fdiff.diff and not comment and old_fobj is not None and entry_type != HistoryType.delete): return None fvals = make_diff_values(typename, fdiff) if len(comment) > 0: is_hidden = False else: is_hidden = is_hidden_snapshot(fdiff) kwargs = { "user": {"pk": user_id, "name": user_name}, "key": key, "type": entry_type, "snapshot": fdiff.snapshot if need_real_snapshot else None, "diff": fdiff.diff, "values": fvals, "comment": comment, "comment_html": mdrender(obj.project, comment), "is_hidden": is_hidden, "is_snapshot": need_real_snapshot, } return entry_model.objects.create(**kwargs)
def decorator(self, *args, **kwargs): from taiga.base.utils.db import get_typename_for_model_class pk = self.kwargs.get(self.pk_url_kwarg, None) tn = get_typename_for_model_class(self.get_queryset().model) key = "{0}:{1}".format(tn, pk) with advisory_lock(key): return func(self, *args, **kwargs)
def decorator(self, *args, **kwargs): from taiga.base.utils.db import get_typename_for_model_class pk = self.kwargs.get(self.pk_url_kwarg, None) tn = get_typename_for_model_class(self.get_queryset().model) key = "{0}:{1}".format(tn, pk) with advisory_lock(key): return func(self, *args, **kwargs)
def make_key_from_model_object(obj: object) -> str: """ Create unique key from model instance. """ tn = get_typename_for_model_class(obj.__class__) return "{0}:{1}".format(tn, obj.pk)
def make_key_from_model_object(obj:object) -> str: """ Create unique key from model instance. """ tn = get_typename_for_model_class(obj.__class__) return "{0}:{1}".format(tn, obj.pk)
def _get_impl_key_from_model(model:Model, event_type:str): if issubclass(model, Model): typename = get_typename_for_model_class(model) return _get_impl_key_from_typename(typename, event_type) raise Exception("Not valid model parameter")
def _get_impl_key_from_model(model: Model, event_type: str): if issubclass(model, Model): typename = get_typename_for_model_class(model) return _get_impl_key_from_typename(typename, event_type) raise Exception("Not valid model parameter")