8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-27 07:02:26 +00:00

Add or translate some docstrings in logs/

This commit is contained in:
Laouen Fernet 2020-04-27 17:57:31 +02:00 committed by Gabriel Detraz
parent 02678b7ccd
commit ebd4fb8ac9
3 changed files with 278 additions and 133 deletions

View file

@ -53,6 +53,15 @@ CHOICES_TYPE = (
def all_classes(module): def all_classes(module):
"""Get the list of all class names of the module.
Args:
module: the module in which to retrieve classes.
Returns:
A list containing the names of all classes that are defined in
the module.
"""
classes = [] classes = []
for name, obj in inspect.getmembers(module): for name, obj in inspect.getmembers(module):
@ -63,8 +72,16 @@ def all_classes(module):
def classes_for_action_type(action_type): def classes_for_action_type(action_type):
"""Return the list of class names to be displayed for a """Get the list of class names to be displayed for a given action type
given actions type filter""" filter.
Args:
action_type: the string used to filter the class names.
Returns:
A list containing the class names corresponding to the action type
filter.
"""
if action_type == "users": if action_type == "users":
return [ return [
users.models.User.__name__, users.models.User.__name__,
@ -96,7 +113,7 @@ def classes_for_action_type(action_type):
class ActionsSearchForm(Form): class ActionsSearchForm(Form):
"""The form for a simple search""" """Form used to do an advanced search through the logs."""
u = forms.ModelChoiceField( u = forms.ModelChoiceField(
label=_("Performed by"), label=_("Performed by"),
queryset=users.models.User.objects.all(), queryset=users.models.User.objects.all(),
@ -123,7 +140,7 @@ class ActionsSearchForm(Form):
class MachineHistorySearchForm(Form): class MachineHistorySearchForm(Form):
"""The form for a simple search""" """Form used to do a search through the machine histories."""
q = forms.CharField( q = forms.CharField(
label=_("Search"), label=_("Search"),
max_length=100, max_length=100,

View file

@ -69,12 +69,16 @@ def make_version_filter(key, value):
class MachineHistorySearchEvent: class MachineHistorySearchEvent:
def __init__(self, user, machine, interface, start=None, end=None): def __init__(self, user, machine, interface, start=None, end=None):
""" """Initialise an instance of MachineHistorySearchEvent.
:param user: User, The user owning the maching at the time of the event
:param machine: Version, the machine version related to the interface Args:
:param interface: Version, the interface targeted by this event user: User, the user owning the machine at the time of the event.
:param start: datetime, the date at which this version was created machine: Version, the machine version related to the interface.
:param end: datetime, the date at which this version was replace by a new one interface: Version, the interface targeted by this event.
start: datetime, the date at which this version was created
(default: None).
end: datetime, the date at which this version was replace by a new
one (default: None).
""" """
self.user = user self.user = user
self.machine = machine self.machine = machine
@ -86,9 +90,13 @@ class MachineHistorySearchEvent:
self.comment = interface.revision.get_comment() or None self.comment = interface.revision.get_comment() or None
def is_similar(self, elt2): def is_similar(self, elt2):
""" """Check whether two events are similar enough to be merged.
Checks whether two events are similar enough to be merged
:return: bool Args:
elt2: MachineHistorySearchEvent, the event to compare with self.
Returns:
A boolean, True if the events can be merged and False otherwise.
""" """
return ( return (
elt2 is not None elt2 is not None
@ -115,10 +123,14 @@ class MachineHistorySearch:
self._last_evt = None self._last_evt = None
def get(self, search, params): def get(self, search, params):
""" """Get the events in machine histories related to the search.
:param search: ip or mac to lookup
:param params: dict built by the search view Args:
:return: list or None, a list of MachineHistorySearchEvent in reverse chronological order search: the IP or MAC address used in the search.
params: the dictionary built by the search view.
Returns:
A list of MachineHistorySearchEvent in reverse chronological order.
""" """
self.start = params.get("s", None) self.start = params.get("s", None)
self.end = params.get("e", None) self.end = params.get("e", None)
@ -140,11 +152,12 @@ class MachineHistorySearch:
return [] return []
def _add_revision(self, user, machine, interface): def _add_revision(self, user, machine, interface):
""" """Add a new revision to the chronological order.
Add a new revision to the chronological order
:param user: User, The user owning the maching at the time of the event Args:
:param machine: Version, the machine version related to the interface user: User, the user owning the maching at the time of the event.
:param interface: Version, the interface targeted by this event machine: Version, the machine version related to the interface.
interface: Version, the interface targeted by this event.
""" """
evt = MachineHistorySearchEvent(user, machine, interface) evt = MachineHistorySearchEvent(user, machine, interface)
evt.start_date = interface.revision.date_created evt.start_date = interface.revision.date_created
@ -171,10 +184,15 @@ class MachineHistorySearch:
self._last_evt = evt self._last_evt = evt
def _get_interfaces_for_ip(self, ip): def _get_interfaces_for_ip(self, ip):
""" """Get the Version objects of interfaces with the given IP
:param ip: str address.
:return: An iterable object with the Version objects
of Interfaces with the given IP Args:
ip: the string corresponding to the IP address.
Returns:
An iterable object with the Version objects of interfaces with the
given IP address.
""" """
# TODO: What if ip list was deleted? # TODO: What if ip list was deleted?
try: try:
@ -189,10 +207,15 @@ class MachineHistorySearch:
) )
def _get_interfaces_for_mac(self, mac): def _get_interfaces_for_mac(self, mac):
""" """Get the Version objects of interfaces with the given MAC
:param mac: str address.
:return: An iterable object with the Version objects
of Interfaces with the given MAC address Args:
mac: the string corresponding to the MAC address.
Returns:
An iterable object with the Version objects of interfaces with the
given MAC address.
""" """
return ( return (
Version.objects.get_for_model(Interface) Version.objects.get_for_model(Interface)
@ -201,10 +224,14 @@ class MachineHistorySearch:
) )
def _get_machines_for_interface(self, interface): def _get_machines_for_interface(self, interface):
""" """Get the Version objects of machines with the given interface.
:param interface: Version, the interface for which to find the machines
:return: An iterable object with the Version objects of Machine to Args:
which the given interface was attributed interface: Version, the interface used to find machines.
Returns:
An iterable object with the Version objects of machines to which
the given interface was assigned.
""" """
machine_id = interface.field_dict["machine_id"] machine_id = interface.field_dict["machine_id"]
return ( return (
@ -214,18 +241,27 @@ class MachineHistorySearch:
) )
def _get_user_for_machine(self, machine): def _get_user_for_machine(self, machine):
""" """Get the User instance owning the given machine.
:param machine: Version, the machine of which the owner must be found
:return: The user to which the given machine belongs Args:
machine: Version, the machine used to find its owner.
Returns:
The User instance of the owner of the given machine.
""" """
# TODO: What if user was deleted? # TODO: What if user was deleted?
user_id = machine.field_dict["user_id"] user_id = machine.field_dict["user_id"]
return User.objects.get(id=user_id) return User.objects.get(id=user_id)
def _get_by_ip(self, ip): def _get_by_ip(self, ip):
""" """Get events related to the given IP address.
:param ip: str, The IP to lookup
:returns: list, a list of MachineHistorySearchEvent Args:
ip: the string corresponding to the IP address.
Returns:
A list of MachineHistorySearchEvent related to the given IP
address.
""" """
interfaces = self._get_interfaces_for_ip(ip) interfaces = self._get_interfaces_for_ip(ip)
@ -239,9 +275,14 @@ class MachineHistorySearch:
return self.events return self.events
def _get_by_mac(self, mac): def _get_by_mac(self, mac):
""" """Get events related to the given MAC address.
:param mac: str, The MAC address to lookup
:returns: list, a list of MachineHistorySearchEvent Args:
mac: the string corresponding to the MAC address.
Returns:
A list of MachineHistorySearchEvent related to the given MAC
address.
""" """
interfaces = self._get_interfaces_for_mac(mac) interfaces = self._get_interfaces_for_mac(mac)
@ -261,10 +302,10 @@ class MachineHistorySearch:
class RelatedHistory: class RelatedHistory:
def __init__(self, version): def __init__(self, version):
""" """Initialise an instance of RelatedHistory.
:param name: Name of this instance
:param model_name: Name of the related model (e.g. "user") Args:
:param object_id: ID of the related object version: Version, the version related to the history.
""" """
self.version = version self.version = version
self.app_name = version.content_type.app_label self.app_name = version.content_type.app_label
@ -287,10 +328,14 @@ class RelatedHistory:
class HistoryEvent: class HistoryEvent:
def __init__(self, version, previous_version=None, edited_fields=None): def __init__(self, version, previous_version=None, edited_fields=None):
""" """Initialise an instance of HistoryEvent.
:param version: Version, the version of the object for this event
:param previous_version: Version, the version of the object before this event Args:
:param edited_fields: list, The list of modified fields by this event version: Version, the version of the object for this event.
previous_version: Version, the version of the object before this
event (default: None).
edited_fields: list, The list of modified fields by this event
(default: None).
""" """
self.version = version self.version = version
self.previous_version = previous_version self.previous_version = previous_version
@ -300,11 +345,15 @@ class HistoryEvent:
self.comment = version.revision.get_comment() or None self.comment = version.revision.get_comment() or None
def _repr(self, name, value): def _repr(self, name, value):
""" """Get the appropriate representation of the given field.
Returns the best representation of the given field
:param name: the name of the field Args:
:param value: the value of the field name: the name of the field
:return: object value: the value of the field
Returns:
The string corresponding to the appropriate representation of the
given field.
""" """
if value is None: if value is None:
return _("None") return _("None")
@ -312,10 +361,14 @@ class HistoryEvent:
return value return value
def edits(self, hide=[]): def edits(self, hide=[]):
""" """Get the list of the changes performed during this event.
Build a list of the changes performed during this event
:param hide: list, the list of fields for which not to show details Args:
:return: str hide: the list of fields for which not to show details (default:
[]).
Returns:
The list of fields edited by the event to display.
""" """
edits = [] edits = []
@ -342,10 +395,15 @@ class History:
self.event_type = HistoryEvent self.event_type = HistoryEvent
def get(self, instance_id, model): def get(self, instance_id, model):
""" """Get the list of history events of the given object.
:param instance_id: int, The id of the instance to lookup
:param model: class, The type of object to lookup Args:
:return: list or None, a list of HistoryEvent, in reverse chronological order instance_id: int, the id of the instance to lookup.
model: class, the type of object to lookup.
Returns:
A list of HistoryEvent, in reverse chronological order, related to
the given object or None if no version was found.
""" """
self.events = [] self.events = []
@ -368,12 +426,16 @@ class History:
return self.events[::-1] return self.events[::-1]
def _compute_diff(self, v1, v2, ignoring=[]): def _compute_diff(self, v1, v2, ignoring=[]):
""" """Find the edited fields between two versions.
Find the edited field between two versions
:param v1: Version Args:
:param v2: Version v1: Version to compare.
:param ignoring: List, a list of fields to ignore v2: Version to compare.
:return: List of field names ignoring: a list of fields to ignore.
Returns:
The list of field names in v1 that are different from the ones in
v2.
""" """
fields = [] fields = []
@ -384,9 +446,10 @@ class History:
return fields return fields
def _add_revision(self, version): def _add_revision(self, version):
""" """Add a new revision to the chronological order.
Add a new revision to the chronological order
:param version: Version, The version of the interface for this event Args:
version: Version, the version of the interface for this event.
""" """
diff = None diff = None
if self._last_version is not None: if self._last_version is not None:
@ -427,6 +490,15 @@ class VersionAction(HistoryEvent):
return apps.get_model(self.application(), self.model_name()) return apps.get_model(self.application(), self.model_name())
def edits(self, hide=["password", "pwd_ntlm", "gpg_fingerprint"]): def edits(self, hide=["password", "pwd_ntlm", "gpg_fingerprint"]):
"""Get the list of the changes performed during this event.
Args:
hide: the list of fields for which not to show details (default:
["password", "pwd_ntlm", "gpg_fingerprint"]).
Returns:
The list of fields edited by the event to display.
"""
self.previous_version = self._previous_version() self.previous_version = self._previous_version()
if self.previous_version is None: if self.previous_version is None:
@ -436,6 +508,12 @@ class VersionAction(HistoryEvent):
return super(VersionAction, self).edits(hide) return super(VersionAction, self).edits(hide)
def _previous_version(self): def _previous_version(self):
"""Get the previous version of self.
Returns:
The Version corresponding to the previous version of self, or None
in case of exception.
"""
model = self.object_type() model = self.object_type()
try: try:
query = ( query = (
@ -451,12 +529,16 @@ class VersionAction(HistoryEvent):
return None return None
def _compute_diff(self, v1, v2, ignoring=["pwd_ntlm"]): def _compute_diff(self, v1, v2, ignoring=["pwd_ntlm"]):
""" """Find the edited fields between two versions.
Find the edited field between two versions
:param v1: Version Args:
:param v2: Version v1: Version to compare.
:param ignoring: List, a list of fields to ignore v2: Version to compare.
:return: List of field names ignoring: a list of fields to ignore (default: ["pwd_ntlm"]).
Returns:
The list of field names in v1 that are different from the ones in
v2.
""" """
fields = [] fields = []
@ -468,7 +550,8 @@ class VersionAction(HistoryEvent):
class RevisionAction: class RevisionAction:
"""A Revision may group multiple Version objects together""" """A Revision may group multiple Version objects together."""
def __init__(self, revision): def __init__(self, revision):
self.performed_by = revision.user self.performed_by = revision.user
self.revision = revision self.revision = revision
@ -486,9 +569,13 @@ class RevisionAction:
class ActionsSearch: class ActionsSearch:
def get(self, params): def get(self, params):
""" """Get the Revision objects corresponding to the search.
:param params: dict built by the search view
:return: QuerySet of Revision objects Args:
params: dictionary built by the search view.
Returns:
The QuerySet of Revision objects corresponding to the search.
""" """
user = params.get("u", None) user = params.get("u", None)
start = params.get("s", None) start = params.get("s", None)
@ -540,11 +627,15 @@ class ActionsSearch:
class UserHistoryEvent(HistoryEvent): class UserHistoryEvent(HistoryEvent):
def _repr(self, name, value): def _repr(self, name, value):
""" """Get the appropriate representation of the given field.
Returns the best representation of the given field
:param name: the name of the field Args:
:param value: the value of the field name: the name of the field
:return: object value: the value of the field
Returns:
The string corresponding to the appropriate representation of the
given field.
""" """
if name == "groups": if name == "groups":
if len(value) == 0: if len(value) == 0:
@ -599,10 +690,14 @@ class UserHistoryEvent(HistoryEvent):
return super(UserHistoryEvent, self)._repr(name, value) return super(UserHistoryEvent, self)._repr(name, value)
def edits(self, hide=["password", "pwd_ntlm", "gpg_fingerprint"]): def edits(self, hide=["password", "pwd_ntlm", "gpg_fingerprint"]):
""" """Get the list of the changes performed during this event.
Build a list of the changes performed during this event
:param hide: list, the list of fields for which not to show details Args:
:return: str hide: the list of fields for which not to show details (default:
["password", "pwd_ntlm", "gpg_fingerprint"]).
Returns:
The list of fields edited by the event to display.
""" """
return super(UserHistoryEvent, self).edits(hide) return super(UserHistoryEvent, self).edits(hide)
@ -631,9 +726,14 @@ class UserHistory(History):
self.event_type = UserHistoryEvent self.event_type = UserHistoryEvent
def get(self, user_id, model): def get(self, user_id, model):
""" """Get the the list of UserHistoryEvent related to the object.
:param user_id: int, the id of the user to lookup
:return: list or None, a list of UserHistoryEvent, in reverse chronological order Args:
user_id: int, the id of the user to lookup.
Returns:
The list of UserHistoryEvent, in reverse chronological order,
related to the object, or None if nothing was found.
""" """
self.events = [] self.events = []
@ -710,10 +810,10 @@ class UserHistory(History):
) )
def _add_revision(self, version): def _add_revision(self, version):
""" """Add a new revision to the chronological order.
Add a new revision to the chronological order
:param user: User, The user displayed in this history Args:
:param version: Version, The version of the user for this event version: Version, the version of the user for this event.
""" """
diff = None diff = None
if self._last_version is not None: if self._last_version is not None:
@ -736,11 +836,15 @@ class UserHistory(History):
class MachineHistoryEvent(HistoryEvent): class MachineHistoryEvent(HistoryEvent):
def _repr(self, name, value): def _repr(self, name, value):
""" """Return the appropriate representation of the given field.
Returns the best representation of the given field
:param name: the name of the field Args:
:param value: the value of the field name: the name of the field
:return: object value: the value of the field
Returns:
The string corresponding to the appropriate representation of the
given field.
""" """
if name == "user_id": if name == "user_id":
try: try:
@ -757,6 +861,15 @@ class MachineHistory(History):
self.event_type = MachineHistoryEvent self.event_type = MachineHistoryEvent
def get(self, machine_id, model): def get(self, machine_id, model):
"""Get the the list of MachineHistoryEvent related to the object.
Args:
machine_id: int, the id of the machine to lookup.
Returns:
The list of MachineHistoryEvent, in reverse chronological order,
related to the object.
"""
self.related = ( self.related = (
Version.objects.get_for_model(Interface) Version.objects.get_for_model(Interface)
.filter(make_version_filter("machine", machine_id)) .filter(make_version_filter("machine", machine_id))
@ -772,11 +885,15 @@ class MachineHistory(History):
class InterfaceHistoryEvent(HistoryEvent): class InterfaceHistoryEvent(HistoryEvent):
def _repr(self, name, value): def _repr(self, name, value):
""" """Get the appropriate representation of the given field.
Returns the best representation of the given field
:param name: the name of the field Args:
:param value: the value of the field name: the name of the field
:return: object value: the value of the field
Returns:
The string corresponding to the appropriate representation of the
given field.
""" """
if name == "ipv4_id" and value is not None: if name == "ipv4_id" and value is not None:
try: try:
@ -813,6 +930,15 @@ class InterfaceHistory(History):
self.event_type = InterfaceHistoryEvent self.event_type = InterfaceHistoryEvent
def get(self, interface_id, model): def get(self, interface_id, model):
"""Get the the list of InterfaceHistoryEvent related to the object.
Args:
interface_id: int, the id of the interface to lookup.
Returns:
The list of InterfaceHistoryEvent, in reverse chronological order,
related to the object.
"""
return super(InterfaceHistory, self).get(interface_id, Interface) return super(InterfaceHistory, self).get(interface_id, Interface)
@ -829,10 +955,15 @@ HISTORY_CLASS_MAPPING = {
def get_history_class(model): def get_history_class(model):
""" """Get the most appropriate History subclass to represent the given model's
Find the mos appropriate History subclass to represent history.
the given model's history
:model: class Args:
model: the class for which to get the history.
Returns:
The most appropriate History subclass for the given model's history,
or History if no other was found.
""" """
try: try:
return HISTORY_CLASS_MAPPING[model]() return HISTORY_CLASS_MAPPING[model]()

View file

@ -113,8 +113,7 @@ from .forms import ActionsSearchForm, MachineHistorySearchForm
@login_required @login_required
@can_view_app("logs") @can_view_app("logs")
def index(request): def index(request):
"""Affiche les logs affinés, date reformatées, selectionne """View used to display summary of events about users."""
les event importants (ajout de droits, ajout de ban/whitelist)"""
pagination_number = GeneralOption.get_cached_value("pagination_number") pagination_number = GeneralOption.get_cached_value("pagination_number")
# The types of content kept for display # The types of content kept for display
content_type_filter = ["ban", "whitelist", "vente", "interface", "user"] content_type_filter = ["ban", "whitelist", "vente", "interface", "user"]
@ -155,8 +154,7 @@ def index(request):
@login_required @login_required
@can_view_all(GeneralOption) @can_view_all(GeneralOption)
def stats_logs(request): def stats_logs(request):
"""Affiche l'ensemble des logs et des modifications sur les objets, """View used to do an advanced search through the logs."""
classés par date croissante, en vrac"""
actions_form = ActionsSearchForm(request.GET or None) actions_form = ActionsSearchForm(request.GET or None)
if actions_form.is_valid(): if actions_form.is_valid():
@ -185,7 +183,7 @@ def stats_logs(request):
@login_required @login_required
@can_edit_history @can_edit_history
def revert_action(request, revision_id): def revert_action(request, revision_id):
""" Annule l'action en question """ """View used to revert actions."""
try: try:
revision = Revision.objects.get(id=revision_id) revision = Revision.objects.get(id=revision_id)
except Revision.DoesNotExist: except Revision.DoesNotExist:
@ -204,9 +202,10 @@ def revert_action(request, revision_id):
@login_required @login_required
@can_view_all(IpList, Interface, User) @can_view_all(IpList, Interface, User)
def stats_general(request): def stats_general(request):
"""Statistiques générales affinées sur les ip, activées, utilisées par """View used to display general statistics about users (activated,
range, et les statistiques générales sur les users : users actifs, disabled, archived etc.) and IP addresses (ranges, number of assigned
cotisants, activés, archivés, etc""" addresses etc.).
"""
ip_dict = dict() ip_dict = dict()
for ip_range in IpType.objects.select_related("vlan").all(): for ip_range in IpType.objects.select_related("vlan").all():
all_ip = IpList.objects.filter(ip_type=ip_range) all_ip = IpList.objects.filter(ip_type=ip_range)
@ -377,9 +376,9 @@ def stats_general(request):
@login_required @login_required
@can_view_app("users", "cotisations", "machines", "topologie") @can_view_app("users", "cotisations", "machines", "topologie")
def stats_models(request): def stats_models(request):
"""Statistiques générales, affiche les comptages par models: """View used to display general statistics about the number of objects
nombre d'users, d'écoles, de droits, de bannissements, stored in the database, for each model.
de factures, de ventes, de banque, de machines, etc""" """
stats = { stats = {
_("Users (members and clubs)"): { _("Users (members and clubs)"): {
"users": [User._meta.verbose_name, User.objects.count()], "users": [User._meta.verbose_name, User.objects.count()],
@ -452,10 +451,9 @@ def stats_models(request):
@login_required @login_required
@can_view_app("users") @can_view_app("users")
def stats_users(request): def stats_users(request):
"""Affiche les statistiques base de données aggrégées par user : """View used to display statistics aggregated by user (number of machines,
nombre de machines par user, d'etablissements par user, bans, whitelists, rights etc.).
de moyens de paiements par user, de banque par user, """
de bannissement par user, etc"""
stats = { stats = {
User._meta.verbose_name: { User._meta.verbose_name: {
Machine._meta.verbose_name_plural: User.objects.annotate( Machine._meta.verbose_name_plural: User.objects.annotate(
@ -496,9 +494,7 @@ def stats_users(request):
@login_required @login_required
@can_view_app("users") @can_view_app("users")
def stats_actions(request): def stats_actions(request):
"""Vue qui affiche les statistiques de modifications d'objets par """View used to display the number of actions, aggregated by user."""
utilisateurs.
Affiche le nombre de modifications aggrégées par utilisateurs"""
stats = { stats = {
User._meta.verbose_name: { User._meta.verbose_name: {
_("actions"): User.objects.annotate(num=Count("revision")).order_by("-num")[ _("actions"): User.objects.annotate(num=Count("revision")).order_by("-num")[
@ -512,8 +508,9 @@ def stats_actions(request):
@login_required @login_required
@can_view_app("users") @can_view_app("users")
def stats_search_machine_history(request): def stats_search_machine_history(request):
"""View which displays the history of machines with the given """View used to display the history of machines with the given IP or MAC
une IP or MAC adresse""" address.
"""
history_form = MachineHistorySearchForm(request.GET or None) history_form = MachineHistorySearchForm(request.GET or None)
if history_form.is_valid(): if history_form.is_valid():
history = MachineHistorySearch() history = MachineHistorySearch()