mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-11-27 02:43:01 +00:00
Logging support
This commit is contained in:
parent
c8dd41c1d7
commit
fd529a53c8
4
apps/api/__init__.py
Normal file
4
apps/api/__init__.py
Normal 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
10
apps/api/apps.py
Normal 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
4
apps/logs/__init__.py
Normal 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
14
apps/logs/apps.py
Normal 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
63
apps/logs/models.py
Normal 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
68
apps/logs/signals.py
Normal 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
8
apps/logs/urls.py
Normal 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 = [
|
||||||
|
]
|
@ -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 ""
|
||||||
|
|
||||||
|
@ -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 ""
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ INSTALLED_APPS = [
|
|||||||
'member',
|
'member',
|
||||||
'note',
|
'note',
|
||||||
'api',
|
'api',
|
||||||
|
'logs',
|
||||||
]
|
]
|
||||||
LOGIN_REDIRECT_URL = '/note/transfer/'
|
LOGIN_REDIRECT_URL = '/note/transfer/'
|
||||||
|
|
||||||
|
@ -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')),
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user