Logging support

This commit is contained in:
Yohann D'ANELLO 2020-02-24 18:18:44 +01:00
parent c8dd41c1d7
commit fd529a53c8
11 changed files with 279 additions and 19 deletions

4
apps/api/__init__.py Normal file
View File

@ -0,0 +1,4 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'api.apps.APIConfig'

10
apps/api/apps.py Normal file
View File

@ -0,0 +1,10 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class APIConfig(AppConfig):
name = 'api'
verbose_name = _('API')

4
apps/logs/__init__.py Normal file
View File

@ -0,0 +1,4 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'logs.apps.LogsConfig'

14
apps/logs/apps.py Normal file
View File

@ -0,0 +1,14 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class LogsConfig(AppConfig):
name = 'logs'
verbose_name = _('Logs')
def ready(self):
# noinspection PyUnresolvedReferences
import logs.signals

63
apps/logs/models.py Normal file
View File

@ -0,0 +1,63 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.utils.translation import gettext_lazy as _
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
class Changelog(models.Model):
"""
Store each modification on the database (except sessions and logging),
including creating, editing and deleting models.
"""
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
null=True,
verbose_name=_('user'),
)
model = models.CharField(
max_length=255,
null=False,
blank=False,
verbose_name=_('model'),
)
instance_pk = models.CharField(
max_length=255,
null=False,
blank=False,
verbose_name=_('identifier'),
)
previous = models.TextField(
null=True,
verbose_name=_('previous data'),
)
data = models.TextField(
null=True,
verbose_name=_('new data'),
)
action = models.CharField( # create, edit or delete
max_length=16,
null=False,
blank=False,
verbose_name=_('action'),
)
timestamp = models.DateTimeField(
null=False,
blank=False,
auto_now_add=True,
name='timestamp',
verbose_name=_('timestamp'),
)
def delete(self, using=None, keep_parents=False):
raise ValidationError(_("Logs cannot be destroyed."))

68
apps/logs/signals.py Normal file
View File

@ -0,0 +1,68 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import inspect
from django.core import serializers
from django.db.models.signals import pre_save, pre_delete
from django.dispatch import receiver
from .models import Changelog
def get_user_in_signal(sender, **kwargs):
user = None
for entry in reversed(inspect.stack()):
try:
user = entry[0].f_locals['request'].user
break
except:
pass
if not user:
print("WARNING: Attempt to save " + str(sender) + " with no user")
return user
EXCLUDED = [
'Changelog',
'Migration',
'Session',
]
@receiver(pre_save)
def save_object(sender, instance, **kwargs):
model_name = sender.__name__
if model_name in EXCLUDED:
return
previous = sender.objects.filter(pk=instance.pk).all()
user = get_user_in_signal(sender, **kwargs)
if previous.exists:
previous_json = serializers.serialize('json', previous)[1:-1]
else:
previous_json = None
instance_json = serializers.serialize('json', [instance, ],)[1:-1]
Changelog.objects.create(user=user,
model=model_name,
instance_pk=instance.pk,
previous=previous_json,
data=instance_json,
action=("edit" if previous.exists() else "create")
)#.save()
@receiver(pre_delete)
def delete_object(sender, instance, **kwargs):
model_name = sender.__name__
if model_name in EXCLUDED:
return
user = get_user_in_signal(sender, **kwargs)
instance_json = serializers.serialize('json', [instance, ])[1:-1]
Changelog.objects.create(user=user,
model=model_name,
instance_pk=instance.pk,
previous=instance_json,
data=None,
action="delete"
).save()

8
apps/logs/urls.py Normal file
View File

@ -0,0 +1,8 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
app_name = 'logs'
# TODO User interface
urlpatterns = [
]

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-02-21 13:50+0100\n" "POT-Creation-Date: 2020-02-24 17:15+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -82,6 +82,46 @@ msgstr ""
msgid "guests" msgid "guests"
msgstr "" msgstr ""
#: apps/api/apps.py:10
msgid "API"
msgstr ""
#: apps/logs/apps.py:10
msgid "Logs"
msgstr ""
#: apps/logs/models.py:20 apps/note/models/notes.py:105
msgid "user"
msgstr ""
#: apps/logs/models.py:27
msgid "model"
msgstr ""
#: apps/logs/models.py:34
msgid "identifier"
msgstr ""
#: apps/logs/models.py:39
msgid "previous data"
msgstr ""
#: apps/logs/models.py:44
msgid "new data"
msgstr ""
#: apps/logs/models.py:51
msgid "action"
msgstr ""
#: apps/logs/models.py:59
msgid "timestamp"
msgstr ""
#: apps/logs/models.py:63
msgid "Logs cannot be destroyed."
msgstr ""
#: apps/member/apps.py:10 #: apps/member/apps.py:10
msgid "member" msgid "member"
msgstr "" msgstr ""
@ -244,10 +284,6 @@ msgstr ""
msgid "This alias is already taken." msgid "This alias is already taken."
msgstr "" msgstr ""
#: apps/note/models/notes.py:105
msgid "user"
msgstr ""
#: apps/note/models/notes.py:109 #: apps/note/models/notes.py:109
msgid "one's note" msgid "one's note"
msgstr "" msgstr ""
@ -358,15 +394,19 @@ msgstr ""
msgid "Transfer money from your account to one or others" msgid "Transfer money from your account to one or others"
msgstr "" msgstr ""
#: note_kfet/settings/base.py:148 #: apps/note/views.py:143
msgid "German" msgid "Consommations"
msgstr ""
#: note_kfet/settings/base.py:149
msgid "English"
msgstr "" msgstr ""
#: note_kfet/settings/base.py:150 #: note_kfet/settings/base.py:150
msgid "German"
msgstr ""
#: note_kfet/settings/base.py:151
msgid "English"
msgstr ""
#: note_kfet/settings/base.py:152
msgid "French" msgid "French"
msgstr "" msgstr ""

View File

@ -3,7 +3,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-02-21 13:50+0100\n" "POT-Creation-Date: 2020-02-24 17:15+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -77,6 +77,50 @@ msgstr "invité"
msgid "guests" msgid "guests"
msgstr "invités" msgstr "invités"
#: apps/api/apps.py:10
msgid "API"
msgstr ""
#: apps/logs/apps.py:10
msgid "Logs"
msgstr ""
#: apps/logs/models.py:20 apps/note/models/notes.py:105
msgid "user"
msgstr "utilisateur"
#: apps/logs/models.py:27
msgid "model"
msgstr "Modèle"
#: apps/logs/models.py:34
msgid "identifier"
msgstr "Identifiant"
#: apps/logs/models.py:39
msgid "previous data"
msgstr "Données précédentes"
#: apps/logs/models.py:44
#, fuzzy
#| msgid "end date"
msgid "new data"
msgstr "Nouvelles données"
#: apps/logs/models.py:51
#, fuzzy
#| msgid "section"
msgid "action"
msgstr "Action"
#: apps/logs/models.py:59
msgid "timestamp"
msgstr "Date"
#: apps/logs/models.py:63
msgid "Logs cannot be destroyed."
msgstr "Les logs ne peuvent pas être détruits."
#: apps/member/apps.py:10 #: apps/member/apps.py:10
msgid "member" msgid "member"
msgstr "adhérent" msgstr "adhérent"
@ -244,10 +288,6 @@ msgstr "Note"
msgid "This alias is already taken." msgid "This alias is already taken."
msgstr "Cet alias est déjà pris." msgstr "Cet alias est déjà pris."
#: apps/note/models/notes.py:105
msgid "user"
msgstr "utilisateur"
#: apps/note/models/notes.py:109 #: apps/note/models/notes.py:109
msgid "one's note" msgid "one's note"
msgstr "note d'un utilisateur" msgstr "note d'un utilisateur"
@ -358,15 +398,21 @@ msgstr "transactions d'adhésion"
msgid "Transfer money from your account to one or others" msgid "Transfer money from your account to one or others"
msgstr "Transfert d'argent de ton compte vers un ou plusieurs autres" msgstr "Transfert d'argent de ton compte vers un ou plusieurs autres"
#: note_kfet/settings/base.py:148 #: apps/note/views.py:143
#, fuzzy
#| msgid "transactions"
msgid "Consommations"
msgstr "transactions"
#: note_kfet/settings/base.py:150
msgid "German" msgid "German"
msgstr "" msgstr ""
#: note_kfet/settings/base.py:149 #: note_kfet/settings/base.py:151
msgid "English" msgid "English"
msgstr "" msgstr ""
#: note_kfet/settings/base.py:150 #: note_kfet/settings/base.py:152
msgid "French" msgid "French"
msgstr "" msgstr ""

View File

@ -61,6 +61,7 @@ INSTALLED_APPS = [
'member', 'member',
'note', 'note',
'api', 'api',
'logs',
] ]
LOGIN_REDIRECT_URL = '/note/transfer/' LOGIN_REDIRECT_URL = '/note/transfer/'

View File

@ -21,4 +21,6 @@ urlpatterns = [
# Include Django REST API # Include Django REST API
path('api/', include('api.urls')), path('api/', include('api.urls')),
path('logs/', include('logs.urls')),
] ]