mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-31 15:50:03 +01:00 
			
		
		
		
	Logging support
This commit is contained in:
		
							
								
								
									
										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 "" | ||||
| "Project-Id-Version: PACKAGE VERSION\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" | ||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | ||||
| @@ -82,6 +82,46 @@ msgstr "" | ||||
| msgid "guests" | ||||
| 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 | ||||
| msgid "member" | ||||
| msgstr "" | ||||
| @@ -244,10 +284,6 @@ msgstr "" | ||||
| msgid "This alias is already taken." | ||||
| msgstr "" | ||||
|  | ||||
| #: apps/note/models/notes.py:105 | ||||
| msgid "user" | ||||
| msgstr "" | ||||
|  | ||||
| #: apps/note/models/notes.py:109 | ||||
| msgid "one's note" | ||||
| msgstr "" | ||||
| @@ -358,15 +394,19 @@ msgstr "" | ||||
| msgid "Transfer money from your account to one or others" | ||||
| msgstr "" | ||||
|  | ||||
| #: note_kfet/settings/base.py:148 | ||||
| msgid "German" | ||||
| msgstr "" | ||||
|  | ||||
| #: note_kfet/settings/base.py:149 | ||||
| msgid "English" | ||||
| #: apps/note/views.py:143 | ||||
| msgid "Consommations" | ||||
| msgstr "" | ||||
|  | ||||
| #: 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" | ||||
| msgstr "" | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\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" | ||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | ||||
| @@ -77,6 +77,50 @@ msgstr "invité" | ||||
| msgid "guests" | ||||
| 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 | ||||
| msgid "member" | ||||
| msgstr "adhérent" | ||||
| @@ -244,10 +288,6 @@ msgstr "Note" | ||||
| msgid "This alias is already taken." | ||||
| msgstr "Cet alias est déjà pris." | ||||
|  | ||||
| #: apps/note/models/notes.py:105 | ||||
| msgid "user" | ||||
| msgstr "utilisateur" | ||||
|  | ||||
| #: apps/note/models/notes.py:109 | ||||
| msgid "one's note" | ||||
| msgstr "note d'un utilisateur" | ||||
| @@ -358,15 +398,21 @@ msgstr "transactions d'adhésion" | ||||
| msgid "Transfer money from your account to one or others" | ||||
| 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" | ||||
| msgstr "" | ||||
|  | ||||
| #: note_kfet/settings/base.py:149 | ||||
| #: note_kfet/settings/base.py:151 | ||||
| msgid "English" | ||||
| msgstr "" | ||||
|  | ||||
| #: note_kfet/settings/base.py:150 | ||||
| #: note_kfet/settings/base.py:152 | ||||
| msgid "French" | ||||
| msgstr "" | ||||
|  | ||||
|   | ||||
| @@ -61,6 +61,7 @@ INSTALLED_APPS = [ | ||||
|     'member', | ||||
|     'note', | ||||
|     'api', | ||||
|     'logs', | ||||
| ] | ||||
| LOGIN_REDIRECT_URL = '/note/transfer/' | ||||
|  | ||||
|   | ||||
| @@ -21,4 +21,6 @@ urlpatterns = [ | ||||
|  | ||||
|     # Include Django REST API | ||||
|     path('api/', include('api.urls')), | ||||
|  | ||||
|     path('logs/', include('logs.urls')), | ||||
| ] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user