Example #1
0
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)
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
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)
Example #8
0
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)
Example #9
0
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")
Example #10
0
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")