8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-23 11:53:12 +00:00

Handle machine history

This commit is contained in:
Jean-Romain Garnier 2020-04-23 19:06:59 +02:00 committed by Gabriel Detraz
parent bf0fa33c5f
commit 875a43ed01
2 changed files with 107 additions and 36 deletions

View file

@ -214,6 +214,18 @@ class MachineHistorySearch:
return self.events return self.events
class RelatedHistory:
def __init__(self, model_name, object_id, detailed=True):
"""
:param model_name: Name of the related model (e.g. "user")
:param object_id: ID of the related object
:param detailed: Whether the related history should be shown in an detailed view
"""
self.model_name = model_name
self.object_id = object_id
self.detailed = detailed
class HistoryEvent: class HistoryEvent:
def __init__(self, version, previous_version=None, edited_fields=None): def __init__(self, version, previous_version=None, edited_fields=None):
""" """
@ -265,7 +277,28 @@ class HistoryEvent:
class History: class History:
def __init__(self): def __init__(self):
self.events = [] self.events = []
self.related = [] # For example, a machine has a list of its interfaces
self._last_version = None self._last_version = None
self.event_type = HistoryEvent
def get(self, instance):
"""
:param interface: The instance to lookup
:return: list or None, a list of HistoryEvent, in reverse chronological order
"""
self.events = []
# Get all the versions for this interface, with the oldest first
self._last_version = None
interface_versions = filter(
lambda x: x.field_dict["id"] == instance.id,
Version.objects.get_for_model(type(instance)).order_by("revision__date_created")
)
for version in interface_versions:
self._add_revision(version)
return self.events[::-1]
def _compute_diff(self, v1, v2, ignoring=[]): def _compute_diff(self, v1, v2, ignoring=[]):
""" """
@ -283,6 +316,24 @@ class History:
return fields return fields
def _add_revision(self, version):
"""
Add a new revision to the chronological order
:param version: Version, The version of the interface for this event
"""
diff = None
if self._last_version is not None:
diff = self._compute_diff(version, self._last_version)
# Ignore "empty" events
if not diff:
self._last_version = version
return
evt = self.event_type(version, self._last_version, diff)
self.events.append(evt)
self._last_version = version
class UserHistoryEvent(HistoryEvent): class UserHistoryEvent(HistoryEvent):
def __init__(self, user, version, previous_version=None, edited_fields=None): def __init__(self, user, version, previous_version=None, edited_fields=None):
@ -386,6 +437,7 @@ class UserHistoryEvent(HistoryEvent):
class UserHistory(History): class UserHistory(History):
def __init__(self): def __init__(self):
super(UserHistory, self).__init__() super(UserHistory, self).__init__()
self.event_type = UserHistoryEvent
def get(self, user): def get(self, user):
""" """
@ -400,6 +452,17 @@ class UserHistory(History):
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
# that were once owned by this user
self.related = list(filter(
lambda x: x.field_dict["user_id"] == user.id,
Version.objects.get_for_model(Machine).order_by("revision__date_created")
))
self.related = sorted(
list(dict.fromkeys(self.related)),
key=lambda r: r.model_name
)
# 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(
@ -452,6 +515,45 @@ class UserHistory(History):
self._last_version = version self._last_version = version
class MachineHistoryEvent(HistoryEvent):
def _repr(self, name, value):
"""
Returns the best representation of the given field
:param name: the name of the field
:param value: the value of the field
:return: object
"""
if name == "user_id":
try:
return User.objects.get(id=value).pseudo
except User.DoesNotExist:
return "{} ({})".format(_("Deleted"), value)
return super(MachineHistoryEvent, self)._repr(name, value)
class MachineHistory(History):
def __init__(self):
super(MachineHistory, self).__init__()
self.event_type = MachineHistoryEvent
def get(self, machine):
super(MachineHistory, self).get(machine)
# Add as "related" histories the list of Interface objects
# that were once assigned to this machine
self.related = list(filter(
lambda x: x.field_dict["machine_id"] == machine.id,
Version.objects.get_for_model(Interface).order_by("revision__date_created")
))
# Remove duplicates and sort
self.related = sorted(
list(dict.fromkeys(self.related)),
key=lambda r: r.model_name
)
class InterfaceHistoryEvent(HistoryEvent): class InterfaceHistoryEvent(HistoryEvent):
def _repr(self, name, value): def _repr(self, name, value):
""" """
@ -490,39 +592,6 @@ class InterfaceHistoryEvent(HistoryEvent):
class InterfaceHistory(History): class InterfaceHistory(History):
def get(self, interface): def __init__(self):
""" super(InterfaceHistory, self).__init__()
:param interface: Interface, the interface to lookup self.event_type = InterfaceHistoryEvent
:return: list or None, a list of InterfaceHistoryEvent, in reverse chronological order
"""
self.events = []
# Get all the versions for this interface, with the oldest first
self._last_version = None
interface_versions = filter(
lambda x: x.field_dict["id"] == interface.id,
Version.objects.get_for_model(Interface).order_by("revision__date_created")
)
for version in interface_versions:
self._add_revision(version)
return self.events[::-1]
def _add_revision(self, version):
"""
Add a new revision to the chronological order
:param version: Version, The version of the interface for this event
"""
diff = None
if self._last_version is not None:
diff = self._compute_diff(version, self._last_version)
# Ignore "empty" events
if not diff:
self._last_version = version
return
evt = InterfaceHistoryEvent(version, self._last_version, diff)
self.events.append(evt)
self._last_version = version

View file

@ -104,6 +104,7 @@ from re2o.acl import can_view_all, can_view_app, can_edit_history, can_view
from .models import ( from .models import (
MachineHistorySearch, MachineHistorySearch,
UserHistory, UserHistory,
MachineHistory,
InterfaceHistory InterfaceHistory
) )
@ -550,6 +551,7 @@ def detailed_history(request, object_name, object_id):
history = UserHistory() history = UserHistory()
elif object_name == "machine": elif object_name == "machine":
model = Machine model = Machine
history = MachineHistory()
elif object_name == "interface": elif object_name == "interface":
model = Interface model = Interface
history = InterfaceHistory() history = InterfaceHistory()