mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-23 11:53:12 +00:00
Allow viewing history of deleted elements
This commit is contained in:
parent
ead2609564
commit
a383a04181
2 changed files with 49 additions and 35 deletions
|
@ -290,18 +290,19 @@ class History:
|
||||||
self._last_version = None
|
self._last_version = None
|
||||||
self.event_type = HistoryEvent
|
self.event_type = HistoryEvent
|
||||||
|
|
||||||
def get(self, instance):
|
def get(self, instance_id, model):
|
||||||
"""
|
"""
|
||||||
:param interface: The instance to lookup
|
:param instance_id: int, The id of the instance to lookup
|
||||||
|
:param model: class, The type of object to lookup
|
||||||
:return: list or None, a list of HistoryEvent, in reverse chronological order
|
:return: list or None, a list of HistoryEvent, in reverse chronological order
|
||||||
"""
|
"""
|
||||||
self.events = []
|
self.events = []
|
||||||
|
|
||||||
# Get all the versions for this interface, with the oldest first
|
# Get all the versions for this instance, with the oldest first
|
||||||
self._last_version = None
|
self._last_version = None
|
||||||
interface_versions = filter(
|
interface_versions = filter(
|
||||||
lambda x: x.field_dict["id"] == instance.id,
|
lambda x: x.field_dict["id"] == instance_id,
|
||||||
Version.objects.get_for_model(type(instance)).order_by("revision__date_created")
|
Version.objects.get_for_model(model).order_by("revision__date_created")
|
||||||
)
|
)
|
||||||
|
|
||||||
for version in interface_versions:
|
for version in interface_versions:
|
||||||
|
@ -345,16 +346,6 @@ class History:
|
||||||
|
|
||||||
|
|
||||||
class UserHistoryEvent(HistoryEvent):
|
class UserHistoryEvent(HistoryEvent):
|
||||||
def __init__(self, user, version, previous_version=None, edited_fields=None):
|
|
||||||
"""
|
|
||||||
:param user: User, The user who's history is being built
|
|
||||||
:param version: Version, the version of the user for this event
|
|
||||||
:param previous_version: Version, the version of the user before this event
|
|
||||||
:param edited_fields: list, The list of modified fields by this event
|
|
||||||
"""
|
|
||||||
super(UserHistoryEvent, self).__init__(version, previous_version, edited_fields)
|
|
||||||
self.user = user
|
|
||||||
|
|
||||||
def _repr(self, name, value):
|
def _repr(self, name, value):
|
||||||
"""
|
"""
|
||||||
Returns the best representation of the given field
|
Returns the best representation of the given field
|
||||||
|
@ -424,7 +415,6 @@ class UserHistoryEvent(HistoryEvent):
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return (
|
return (
|
||||||
self.user.id == other.user.id
|
|
||||||
and self.edited_fields == other.edited_fields
|
and self.edited_fields == other.edited_fields
|
||||||
and self.date == other.date
|
and self.date == other.date
|
||||||
and self.performed_by == other.performed_by
|
and self.performed_by == other.performed_by
|
||||||
|
@ -432,13 +422,12 @@ class UserHistoryEvent(HistoryEvent):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash((self.user.id, frozenset(self.edited_fields), self.date, self.performed_by, self.comment))
|
return hash((frozenset(self.edited_fields), self.date, self.performed_by, self.comment))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "{} edited fields {} of {} ({})".format(
|
return "{} edited fields {} ({})".format(
|
||||||
self.performed_by,
|
self.performed_by,
|
||||||
self.edited_fields or "nothing",
|
self.edited_fields or "nothing",
|
||||||
self.user,
|
|
||||||
self.comment or "No comment"
|
self.comment or "No comment"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -448,24 +437,24 @@ class UserHistory(History):
|
||||||
super(UserHistory, self).__init__()
|
super(UserHistory, self).__init__()
|
||||||
self.event_type = UserHistoryEvent
|
self.event_type = UserHistoryEvent
|
||||||
|
|
||||||
def get(self, user):
|
def get(self, user_id):
|
||||||
"""
|
"""
|
||||||
:param user: User, the user to lookup
|
:param user_id: int, the id of the user to lookup
|
||||||
:return: list or None, a list of UserHistoryEvent, in reverse chronological order
|
:return: list or None, a list of UserHistoryEvent, in reverse chronological order
|
||||||
"""
|
"""
|
||||||
self.events = []
|
self.events = []
|
||||||
|
|
||||||
# Find whether this is a Club or an Adherent
|
# Find whether this is a Club or an Adherent
|
||||||
try:
|
try:
|
||||||
obj = Adherent.objects.get(user_ptr_id=user.id)
|
obj = Adherent.objects.get(user_ptr_id=user_id)
|
||||||
except Adherent.DoesNotExist:
|
except Adherent.DoesNotExist:
|
||||||
obj = Club.objects.get(user_ptr_id=user.id)
|
obj = Club.objects.get(user_ptr_id=user_id)
|
||||||
|
|
||||||
# Add as "related" histories the list of Machine objects
|
# Add as "related" histories the list of Machine objects
|
||||||
# that were once owned by this user
|
# that were once owned by this user
|
||||||
self.related = filter(
|
self.related = filter(
|
||||||
lambda x: x.field_dict["user_id"] == user.id,
|
lambda x: x.field_dict["user_id"] == user_id,
|
||||||
Version.objects.get_for_model(Machine).order_by("-revision__date_created")
|
Version.objects.get_for_model(Machine).order_by("revision__date_created")
|
||||||
)
|
)
|
||||||
self.related = [RelatedHistory(
|
self.related = [RelatedHistory(
|
||||||
m.field_dict["name"] or _("None"),
|
m.field_dict["name"] or _("None"),
|
||||||
|
@ -476,7 +465,7 @@ class UserHistory(History):
|
||||||
# Get all the versions for this user, with the oldest first
|
# Get all the versions for this user, with the oldest first
|
||||||
self._last_version = None
|
self._last_version = None
|
||||||
user_versions = filter(
|
user_versions = filter(
|
||||||
lambda x: x.field_dict["id"] == user.id,
|
lambda x: x.field_dict["id"] == user_id,
|
||||||
Version.objects.get_for_model(User).order_by("revision__date_created")
|
Version.objects.get_for_model(User).order_by("revision__date_created")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -547,12 +536,12 @@ class MachineHistory(History):
|
||||||
super(MachineHistory, self).__init__()
|
super(MachineHistory, self).__init__()
|
||||||
self.event_type = MachineHistoryEvent
|
self.event_type = MachineHistoryEvent
|
||||||
|
|
||||||
def get(self, machine):
|
def get(self, machine_id):
|
||||||
# Add as "related" histories the list of Interface objects
|
# Add as "related" histories the list of Interface objects
|
||||||
# that were once assigned to this machine
|
# that were once assigned to this machine
|
||||||
self.related = list(filter(
|
self.related = list(filter(
|
||||||
lambda x: x.field_dict["machine_id"] == machine.id,
|
lambda x: x.field_dict["machine_id"] == machine_id,
|
||||||
Version.objects.get_for_model(Interface).order_by("-revision__date_created")
|
Version.objects.get_for_model(Interface).order_by("revision__date_created")
|
||||||
))
|
))
|
||||||
|
|
||||||
# Create RelatedHistory objects and remove duplicates
|
# Create RelatedHistory objects and remove duplicates
|
||||||
|
@ -562,7 +551,7 @@ class MachineHistory(History):
|
||||||
i.field_dict["id"]) for i in self.related]
|
i.field_dict["id"]) for i in self.related]
|
||||||
self.related = list(dict.fromkeys(self.related))
|
self.related = list(dict.fromkeys(self.related))
|
||||||
|
|
||||||
return super(MachineHistory, self).get(machine)
|
return super(MachineHistory, self).get(machine_id, Machine)
|
||||||
|
|
||||||
|
|
||||||
class InterfaceHistoryEvent(HistoryEvent):
|
class InterfaceHistoryEvent(HistoryEvent):
|
||||||
|
@ -606,3 +595,6 @@ class InterfaceHistory(History):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(InterfaceHistory, self).__init__()
|
super(InterfaceHistory, self).__init__()
|
||||||
self.event_type = InterfaceHistoryEvent
|
self.event_type = InterfaceHistoryEvent
|
||||||
|
|
||||||
|
def get(self, interface_id):
|
||||||
|
return super(InterfaceHistory, self).get(machine_id, Interface)
|
||||||
|
|
|
@ -514,22 +514,44 @@ def stats_search_machine_history(request):
|
||||||
return render(request, "logs/search_machine_history.html", {"history_form": history_form})
|
return render(request, "logs/search_machine_history.html", {"history_form": history_form})
|
||||||
|
|
||||||
|
|
||||||
def get_history_object(request, model, object_name, object_id):
|
def get_history_object(request, model, object_name, object_id, allow_deleted=False):
|
||||||
"""Get the objet of type model with the given object_id
|
"""Get the objet of type model with the given object_id
|
||||||
Handles permissions and DoesNotExist errors
|
Handles permissions and DoesNotExist errors
|
||||||
"""
|
"""
|
||||||
|
instance = None
|
||||||
|
is_deleted = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
object_name_id = object_name + "id"
|
object_name_id = object_name + "id"
|
||||||
kwargs = {object_name_id: object_id}
|
kwargs = {object_name_id: object_id}
|
||||||
instance = model.get_instance(**kwargs)
|
instance = model.get_instance(**kwargs)
|
||||||
except model.DoesNotExist:
|
except model.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if instance is None and allow_deleted:
|
||||||
|
# Try to find an instance among the Version objects
|
||||||
|
is_deleted = True
|
||||||
|
versions = filter(
|
||||||
|
lambda x: x.field_dict["id"] == object_id,
|
||||||
|
Version.objects.get_for_model(model)
|
||||||
|
)
|
||||||
|
versions = list(versions)
|
||||||
|
if len(versions):
|
||||||
|
instance = versions[0]
|
||||||
|
|
||||||
|
if instance is None:
|
||||||
messages.error(request, _("Nonexistent entry."))
|
messages.error(request, _("Nonexistent entry."))
|
||||||
return False, redirect(
|
return False, redirect(
|
||||||
reverse("users:profil", kwargs={"userid": str(request.user.id)})
|
reverse("users:profil", kwargs={"userid": str(request.user.id)})
|
||||||
)
|
)
|
||||||
|
|
||||||
can, msg, _permissions = instance.can_view(request.user)
|
if is_deleted:
|
||||||
if not can:
|
can_view = can_view_app("logs")
|
||||||
|
msg = None
|
||||||
|
else:
|
||||||
|
can_view, msg, _permissions = instance.can_view(request.user)
|
||||||
|
|
||||||
|
if not can_view:
|
||||||
messages.error(
|
messages.error(
|
||||||
request, msg or _("You don't have the right to access this menu.")
|
request, msg or _("You don't have the right to access this menu.")
|
||||||
)
|
)
|
||||||
|
@ -559,7 +581,7 @@ def detailed_history(request, object_name, object_id):
|
||||||
raise Http404(_("No model found."))
|
raise Http404(_("No model found."))
|
||||||
|
|
||||||
# Get instance and check permissions
|
# Get instance and check permissions
|
||||||
can_view, instance = get_history_object(request, model, object_name, object_id)
|
can_view, instance = get_history_object(request, model, object_name, object_id, allow_deleted=True)
|
||||||
if not can_view:
|
if not can_view:
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
@ -567,7 +589,7 @@ def detailed_history(request, object_name, object_id):
|
||||||
max_result = GeneralOption.get_cached_value("pagination_number")
|
max_result = GeneralOption.get_cached_value("pagination_number")
|
||||||
events = re2o_paginator(
|
events = re2o_paginator(
|
||||||
request,
|
request,
|
||||||
history.get(instance),
|
history.get(object_id),
|
||||||
max_result
|
max_result
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue