mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-23 15:33:45 +00:00
Handle machine history
This commit is contained in:
parent
fc352948ce
commit
0d9e0ab867
2 changed files with 107 additions and 36 deletions
141
logs/models.py
141
logs/models.py
|
@ -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
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue