8
0
Fork 0
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:
Jean-Romain Garnier 2020-04-23 20:26:44 +02:00 committed by Gabriel Detraz
parent ead2609564
commit a383a04181
2 changed files with 49 additions and 35 deletions

View file

@ -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)

View file

@ -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
) )