From e634cda3184c5f2642186ab502cc0f738c33b638 Mon Sep 17 00:00:00 2001 From: Bartuccio Antoine Date: Wed, 13 Nov 2019 23:14:21 +0100 Subject: [PATCH 1/3] core/counter: add generic operation logs and implements it for Sellings and Refilling deletions --- core/middleware.py | 20 + core/migrations/0034_operationlog.py | 52 +++ core/models.py | 24 ++ core/templates/core/user_account_detail.jinja | 2 +- core/templates/core/user_tools.jinja | 1 + counter/__init__.py | 5 +- counter/app.py | 34 ++ counter/signals.py | 65 +++ locale/fr/LC_MESSAGES/django.po | 401 +++++++++--------- rootplace/templates/rootplace/logs.jinja | 32 ++ rootplace/urls.py | 2 + rootplace/views.py | 15 +- sith/settings.py | 6 + 13 files changed, 467 insertions(+), 192 deletions(-) create mode 100644 core/migrations/0034_operationlog.py create mode 100644 counter/app.py create mode 100644 counter/signals.py create mode 100644 rootplace/templates/rootplace/logs.jinja diff --git a/core/middleware.py b/core/middleware.py index 2567dc91..45641e1f 100644 --- a/core/middleware.py +++ b/core/middleware.py @@ -23,6 +23,7 @@ # import importlib +import threading from django.conf import settings from django.utils.functional import SimpleLazyObject from django.contrib.auth import get_user @@ -54,3 +55,22 @@ class AuthenticationMiddleware(DjangoAuthenticationMiddleware): "'account.middleware.AuthenticationMiddleware'." ) request.user = SimpleLazyObject(lambda: get_cached_user(request)) + + +class RequestMiddleware: + """ + Allow to access current request in signals + This is a hack that looks into the thread + !!! Do not use if your operation is asynchronus !!! + Mainly used for log purpose + """ + + def __init__(self, get_response, thread_local=threading.local()): + self.get_response = get_response + self.thread_local = thread_local + + def __call__(self, request): + self.thread_local.current_request = request + + response = self.get_response(request) + return response diff --git a/core/migrations/0034_operationlog.py b/core/migrations/0034_operationlog.py new file mode 100644 index 00000000..1cd7b74e --- /dev/null +++ b/core/migrations/0034_operationlog.py @@ -0,0 +1,52 @@ +# Generated by Django 2.2.6 on 2019-11-13 21:17 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("core", "0033_auto_20191006_0049"), + ] + + operations = [ + migrations.CreateModel( + name="OperationLog", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("date", models.DateTimeField(auto_now_add=True, verbose_name="date")), + ("label", models.CharField(max_length=255, verbose_name="label")), + ( + "operation_type", + models.CharField( + choices=[ + ("SELLING_DELETION", "Selling deletion"), + ("REFILLING_DELETION", "Refilling deletion"), + ], + default="SELLING_DELETION", + max_length=40, + verbose_name="operation type", + ), + ), + ( + "operator", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="logs", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] diff --git a/core/models.py b/core/models.py index 1afc9858..84de5bb8 100644 --- a/core/models.py +++ b/core/models.py @@ -1454,3 +1454,27 @@ class Gift(models.Model): def is_owned_by(self, user): return user.is_board_member or user.is_root + + +class OperationLog(models.Model): + """ + General purpose log object to register operations + """ + + date = models.DateTimeField(_("date"), auto_now_add=True) + label = models.CharField(_("label"), max_length=255) + operator = models.ForeignKey( + User, related_name="logs", on_delete=models.SET_NULL, null=True + ) + operation_type = models.CharField( + _("operation type"), + max_length=40, + choices=settings.SITH_LOG_OPERATION_TYPE, + default=settings.SITH_LOG_OPERATION_TYPE[0][0], + ) + + def is_owned_by(self, user): + return user.is_root + + def __str__(self): + return "%s - %s - %s" % (self.operation_type, self.label, self.operator) diff --git a/core/templates/core/user_account_detail.jinja b/core/templates/core/user_account_detail.jinja index 0d1dcac9..7f986516 100644 --- a/core/templates/core/user_account_detail.jinja +++ b/core/templates/core/user_account_detail.jinja @@ -63,7 +63,7 @@ {{ i.amount }} € {{ i.get_payment_method_display() }} {% if i.is_owned_by(user) %} - Delete + {% trans %}Delete{% endtrans %} {% endif %} {% endfor %} diff --git a/core/templates/core/user_tools.jinja b/core/templates/core/user_tools.jinja index 4714a9b9..4804f016 100644 --- a/core/templates/core/user_tools.jinja +++ b/core/templates/core/user_tools.jinja @@ -13,6 +13,7 @@ {% if user.is_root %}
  • {% trans %}Groups{% endtrans %}
  • {% trans %}Merge users{% endtrans %}
  • +
  • {% trans %}Operation logs{% endtrans %}
  • {% trans %}Delete user's forum messages{% endtrans %}
  • {% endif %} {% if user.can_create_subscription or user.is_root %} diff --git a/counter/__init__.py b/counter/__init__.py index 0ace29c4..584960bd 100644 --- a/counter/__init__.py +++ b/counter/__init__.py @@ -1,7 +1,8 @@ # -*- coding:utf-8 -* # -# Copyright 2016,2017 +# Copyright 2016,2017,2019 # - Skia +# - Sli # # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # http://ae.utbm.fr. @@ -21,3 +22,5 @@ # Place - Suite 330, Boston, MA 02111-1307, USA. # # + +default_app_config = "counter.app.CounterConfig" diff --git a/counter/app.py b/counter/app.py new file mode 100644 index 00000000..1e60276c --- /dev/null +++ b/counter/app.py @@ -0,0 +1,34 @@ +# -*- coding:utf-8 -* +# +# Copyright 2019 +# - Sli +# +# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, +# http://ae.utbm.fr. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License a published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple +# Place - Suite 330, Boston, MA 02111-1307, USA. +# +# + +from django.apps import AppConfig +from django.utils.translation import ugettext_lazy as _ + + +class CounterConfig(AppConfig): + name = "counter" + verbose_name = _("counter") + + def ready(self): + import counter.signals diff --git a/counter/signals.py b/counter/signals.py new file mode 100644 index 00000000..5dcbc39f --- /dev/null +++ b/counter/signals.py @@ -0,0 +1,65 @@ +# -*- coding:utf-8 -* +# +# Copyright 2019 +# - Sli +# +# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, +# http://ae.utbm.fr. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License a published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple +# Place - Suite 330, Boston, MA 02111-1307, USA. +# +# + +from django.db.models.signals import pre_delete +from django.dispatch import receiver +from django.conf import settings + +from core.middleware import RequestMiddleware +from core.models import OperationLog + +from counter.models import Selling, Refilling, Counter + + +def write_log(instance, operation_type): + def get_user(): + request = RequestMiddleware(get_response=None).thread_local.current_request + + # Get a random barmen if deletion is from a counter + session_token = request.session.get("counter_token", None) + if session_token: + counter = Counter.objects.filter(token=session_token).first() + if counter: + return counter.get_random_barman() + + # Get the current logged user if not from a counter + if request.user and not request.user.is_anonymous: + return request.user + + # Return None by default + return None + + log = OperationLog( + label=str(instance), operator=get_user(), operation_type=operation_type, + ).save() + + +@receiver(pre_delete, sender=Refilling, dispatch_uid="write_log_refilling_deletion") +def write_log_refilling_deletion(sender, instance, **kwargs): + write_log(instance, "REFILLING_DELETION") + + +@receiver(pre_delete, sender=Selling, dispatch_uid="write_log_refilling_deletion") +def write_log_selling_deletion(sender, instance, **kwargs): + write_log(instance, "SELLING_DELETION") diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index a2c4e0f3..4f3a6080 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-10-21 22:04+0200\n" +"POT-Creation-Date: 2019-11-13 23:14+0100\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -128,10 +128,10 @@ msgid "journal" msgstr "classeur" #: accounting/models.py:290 core/models.py:825 core/models.py:1363 -#: core/models.py:1411 core/models.py:1440 counter/models.py:364 -#: counter/models.py:457 counter/models.py:662 eboutic/models.py:46 -#: eboutic/models.py:93 forum/models.py:311 forum/models.py:408 -#: stock/models.py:104 +#: core/models.py:1411 core/models.py:1440 core/models.py:1464 +#: counter/models.py:364 counter/models.py:457 counter/models.py:662 +#: eboutic/models.py:46 eboutic/models.py:93 forum/models.py:311 +#: forum/models.py:408 stock/models.py:104 msgid "date" msgstr "date" @@ -166,7 +166,8 @@ msgid "accounting type" msgstr "type comptable" #: accounting/models.py:328 accounting/models.py:475 accounting/models.py:510 -#: accounting/models.py:545 core/models.py:1439 counter/models.py:423 +#: accounting/models.py:545 core/models.py:1439 core/models.py:1465 +#: counter/models.py:423 msgid "label" msgstr "étiquette" @@ -218,7 +219,7 @@ msgstr "Compte" msgid "Company" msgstr "Entreprise" -#: accounting/models.py:341 sith/settings.py:380 +#: accounting/models.py:341 sith/settings.py:379 #: stock/templates/stock/shopping_list_items.jinja:37 msgid "Other" msgstr "Autre" @@ -316,7 +317,7 @@ msgstr "Liste des types comptable" #: accounting/templates/accounting/label_list.jinja:10 #: accounting/templates/accounting/operation_edit.jinja:10 #: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:10 -#: core/templates/core/user_tools.jinja:57 +#: core/templates/core/user_tools.jinja:58 msgid "Accounting" msgstr "Comptabilité" @@ -335,7 +336,7 @@ msgstr "Il n'y a pas de types comptable dans ce site web." #: accounting/templates/accounting/bank_account_details.jinja:4 #: accounting/templates/accounting/bank_account_details.jinja:14 -#: core/templates/core/user_tools.jinja:66 +#: core/templates/core/user_tools.jinja:67 msgid "Bank account: " msgstr "Compte en banque : " @@ -425,7 +426,7 @@ msgstr "Nouveau compte club" #: com/templates/com/weekmail.jinja:61 core/templates/core/file.jinja:38 #: core/templates/core/group_list.jinja:24 core/templates/core/page.jinja:35 #: core/templates/core/poster_list.jinja:40 -#: core/templates/core/user_tools.jinja:42 core/views/user.py:228 +#: core/templates/core/user_tools.jinja:43 core/views/user.py:228 #: counter/templates/counter/cash_summary_list.jinja:53 #: counter/templates/counter/counter_list.jinja:17 #: counter/templates/counter/counter_list.jinja:33 @@ -531,7 +532,7 @@ msgid "Effective amount" msgstr "Montant effectif" #: accounting/templates/accounting/club_account_details.jinja:36 -#: sith/settings.py:424 +#: sith/settings.py:423 msgid "Closed" msgstr "Fermé" @@ -576,7 +577,7 @@ msgstr "Voir" #: accounting/templates/accounting/co_list.jinja:4 #: accounting/templates/accounting/journal_details.jinja:19 -#: core/templates/core/user_tools.jinja:62 +#: core/templates/core/user_tools.jinja:63 msgid "Company list" msgstr "Liste des entreprises" @@ -631,7 +632,8 @@ msgstr "No" #: core/templates/core/user_account_detail.jinja:78 #: counter/templates/counter/cash_summary_list.jinja:34 #: counter/templates/counter/last_ops.jinja:14 -#: counter/templates/counter/last_ops.jinja:39 sas/views.py:369 +#: counter/templates/counter/last_ops.jinja:39 +#: rootplace/templates/rootplace/logs.jinja:12 sas/views.py:369 #: stock/templates/stock/stock_shopping_list.jinja:25 #: stock/templates/stock/stock_shopping_list.jinja:54 #: trombi/templates/trombi/user_profile.jinja:40 @@ -642,6 +644,7 @@ msgstr "Date" #: club/templates/club/club_sellings.jinja:24 #: core/templates/core/user_account_detail.jinja:20 #: counter/templates/counter/last_ops.jinja:42 +#: rootplace/templates/rootplace/logs.jinja:14 msgid "Label" msgstr "Étiquette" @@ -711,6 +714,7 @@ msgid "Accounting statement: " msgstr "Bilan comptable : " #: accounting/templates/accounting/journal_statement_accounting.jinja:15 +#: rootplace/templates/rootplace/logs.jinja:13 msgid "Operation type" msgstr "Type d'opération" @@ -1113,7 +1117,7 @@ msgid "inactive" msgstr "inactif" #: club/templates/club/club_list.jinja:34 -#: core/templates/core/user_tools.jinja:23 +#: core/templates/core/user_tools.jinja:24 msgid "New club" msgstr "Nouveau club" @@ -1245,7 +1249,7 @@ msgid "Payment method" msgstr "Méthode de paiement" #: club/templates/club/club_tools.jinja:4 -#: core/templates/core/user_tools.jinja:100 +#: core/templates/core/user_tools.jinja:101 msgid "Club tools" msgstr "Outils club" @@ -1272,7 +1276,7 @@ msgstr "Nouveau Trombi" #: club/templates/club/club_tools.jinja:14 #: com/templates/com/poster_list.jinja:17 #: core/templates/core/poster_list.jinja:17 -#: core/templates/core/user_tools.jinja:90 +#: core/templates/core/user_tools.jinja:91 msgid "Posters" msgstr "Affiches" @@ -1496,7 +1500,7 @@ msgid "Begin date should be before end date" msgstr "La date de début doit être avant celle de fin" #: com/templates/com/mailing_admin.jinja:4 com/views.py:131 -#: core/templates/core/user_tools.jinja:89 +#: core/templates/core/user_tools.jinja:90 msgid "Mailing lists administration" msgstr "Administration des mailing listes" @@ -1544,7 +1548,7 @@ msgstr "Nouvelles" #: com/templates/com/news_admin_list.jinja:11 #: com/templates/com/news_edit.jinja:8 com/templates/com/news_edit.jinja:31 -#: core/templates/core/user_tools.jinja:84 +#: core/templates/core/user_tools.jinja:85 msgid "Create news" msgstr "Créer nouvelle" @@ -1792,7 +1796,7 @@ msgid "Screen - edit" msgstr "Écran - modifier" #: com/templates/com/screen_list.jinja:4 com/templates/com/screen_list.jinja:11 -#: core/templates/core/user_tools.jinja:91 +#: core/templates/core/user_tools.jinja:92 msgid "Screens" msgstr "Écrans" @@ -1807,7 +1811,7 @@ msgid "Slideshow" msgstr "Diaporama" #: com/templates/com/weekmail.jinja:5 com/templates/com/weekmail.jinja:9 -#: com/views.py:108 core/templates/core/user_tools.jinja:82 +#: com/views.py:108 core/templates/core/user_tools.jinja:83 msgid "Weekmail" msgstr "Weekmail" @@ -1905,7 +1909,7 @@ msgstr "Date de début" msgid "Communication administration" msgstr "Administration de la communication" -#: com/views.py:114 core/templates/core/user_tools.jinja:83 +#: com/views.py:114 core/templates/core/user_tools.jinja:84 msgid "Weekmail destinations" msgstr "Destinataires du Weekmail" @@ -2355,6 +2359,10 @@ msgstr "param" msgid "viewed" msgstr "vue" +#: core/models.py:1470 +msgid "operation type" +msgstr "type d'opération" + #: core/templates/core/403.jinja:5 msgid "403, Forbidden" msgstr "403, Non autorisé" @@ -2474,7 +2482,7 @@ msgstr "Photos" #: eboutic/templates/eboutic/eboutic_main.jinja:24 #: eboutic/templates/eboutic/eboutic_makecommand.jinja:8 #: eboutic/templates/eboutic/eboutic_payment_result.jinja:4 -#: sith/settings.py:379 sith/settings.py:387 +#: sith/settings.py:378 sith/settings.py:386 msgid "Eboutic" msgstr "Eboutic" @@ -2498,7 +2506,7 @@ msgstr "Laverie" msgid "Files" msgstr "Fichiers" -#: core/templates/core/base.jinja:189 core/templates/core/user_tools.jinja:108 +#: core/templates/core/base.jinja:189 core/templates/core/user_tools.jinja:109 msgid "Pedagogy" msgstr "Pédagogie" @@ -2687,7 +2695,7 @@ msgstr "Éditer le groupe" #: core/templates/core/group_edit.jinja:9 #: core/templates/core/user_edit.jinja:37 #: core/templates/core/user_group.jinja:8 -#: pedagogy/templates/pedagogy/uv_create.jinja:36 +#: pedagogy/templates/pedagogy/uv_edit.jinja:36 msgid "Update" msgstr "Mettre à jour" @@ -3054,7 +3062,7 @@ msgid "Eboutic invoices" msgstr "Facture eboutic" #: core/templates/core/user_account.jinja:57 -#: core/templates/core/user_tools.jinja:36 counter/views.py:822 +#: core/templates/core/user_tools.jinja:37 counter/views.py:822 msgid "Etickets" msgstr "Etickets" @@ -3373,141 +3381,146 @@ msgid "Merge users" msgstr "Fusionner deux utilisateurs" #: core/templates/core/user_tools.jinja:16 +#: rootplace/templates/rootplace/logs.jinja:5 +msgid "Operation logs" +msgstr "Journal d'opérations" + +#: core/templates/core/user_tools.jinja:17 #: rootplace/templates/rootplace/delete_user_messages.jinja:4 msgid "Delete user's forum messages" msgstr "Supprimer les messages forum d'un utilisateur" -#: core/templates/core/user_tools.jinja:19 +#: core/templates/core/user_tools.jinja:20 msgid "Subscriptions" msgstr "Cotisations" -#: core/templates/core/user_tools.jinja:22 +#: core/templates/core/user_tools.jinja:23 #: subscription/templates/subscription/stats.jinja:4 msgid "Subscription stats" msgstr "Statistiques de cotisation" -#: core/templates/core/user_tools.jinja:28 counter/views.py:792 +#: core/templates/core/user_tools.jinja:29 counter/views.py:792 #: counter/views.py:1000 msgid "Counters" msgstr "Comptoirs" -#: core/templates/core/user_tools.jinja:31 +#: core/templates/core/user_tools.jinja:32 msgid "General counters management" msgstr "Gestion générale des comptoirs" -#: core/templates/core/user_tools.jinja:32 +#: core/templates/core/user_tools.jinja:33 msgid "Products management" msgstr "Gestion des produits" -#: core/templates/core/user_tools.jinja:33 +#: core/templates/core/user_tools.jinja:34 msgid "Product types management" msgstr "Gestion des types de produit" -#: core/templates/core/user_tools.jinja:34 +#: core/templates/core/user_tools.jinja:35 #: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:812 msgid "Cash register summaries" msgstr "Relevés de caisse" -#: core/templates/core/user_tools.jinja:35 +#: core/templates/core/user_tools.jinja:36 #: counter/templates/counter/invoices_call.jinja:4 counter/views.py:817 msgid "Invoices call" msgstr "Appels à facture" -#: core/templates/core/user_tools.jinja:43 core/views/user.py:277 +#: core/templates/core/user_tools.jinja:44 core/views/user.py:277 #: counter/templates/counter/counter_list.jinja:18 #: counter/templates/counter/counter_list.jinja:34 #: counter/templates/counter/counter_list.jinja:56 msgid "Stats" msgstr "Stats" -#: core/templates/core/user_tools.jinja:47 +#: core/templates/core/user_tools.jinja:48 #: counter/templates/counter/counter_list.jinja:38 #: stock/templates/stock/stock_item_list.jinja:11 #: stock/templates/stock/stock_list.jinja:16 msgid "Shopping lists" msgstr "Liste de courses" -#: core/templates/core/user_tools.jinja:49 +#: core/templates/core/user_tools.jinja:50 #: counter/templates/counter/counter_list.jinja:40 msgid "Create new stock" msgstr "Créer nouveau stock" -#: core/templates/core/user_tools.jinja:60 +#: core/templates/core/user_tools.jinja:61 msgid "Refound Account" msgstr "Rembourser un compte" -#: core/templates/core/user_tools.jinja:61 +#: core/templates/core/user_tools.jinja:62 msgid "General accounting" msgstr "Comptabilité générale" -#: core/templates/core/user_tools.jinja:71 +#: core/templates/core/user_tools.jinja:72 msgid "Club account: " msgstr "Compte club : " -#: core/templates/core/user_tools.jinja:78 +#: core/templates/core/user_tools.jinja:79 msgid "Communication" msgstr "Communication" -#: core/templates/core/user_tools.jinja:81 +#: core/templates/core/user_tools.jinja:82 msgid "Create weekmail article" msgstr "Rédiger un nouvel article dans le Weekmail" -#: core/templates/core/user_tools.jinja:85 +#: core/templates/core/user_tools.jinja:86 msgid "Moderate news" msgstr "Modérer les nouvelles" -#: core/templates/core/user_tools.jinja:86 +#: core/templates/core/user_tools.jinja:87 msgid "Edit alert message" msgstr "Éditer le message d'alerte" -#: core/templates/core/user_tools.jinja:87 +#: core/templates/core/user_tools.jinja:88 msgid "Edit information message" msgstr "Éditer le message d'informations" -#: core/templates/core/user_tools.jinja:88 +#: core/templates/core/user_tools.jinja:89 msgid "Moderate files" msgstr "Modérer les fichiers" -#: core/templates/core/user_tools.jinja:94 +#: core/templates/core/user_tools.jinja:95 msgid "Moderate pictures" msgstr "Modérer les photos" -#: core/templates/core/user_tools.jinja:111 +#: core/templates/core/user_tools.jinja:112 #: pedagogy/templates/pedagogy/guide.jinja:20 msgid "Create UV" msgstr "Créer UV" -#: core/templates/core/user_tools.jinja:112 +#: core/templates/core/user_tools.jinja:113 #: pedagogy/templates/pedagogy/guide.jinja:23 #: trombi/templates/trombi/detail.jinja:10 msgid "Moderate comments" msgstr "Modérer les commentaires" -#: core/templates/core/user_tools.jinja:117 +#: core/templates/core/user_tools.jinja:118 msgid "Elections" msgstr "Élections" -#: core/templates/core/user_tools.jinja:119 +#: core/templates/core/user_tools.jinja:120 msgid "See available elections" msgstr "Voir les élections disponibles" -#: core/templates/core/user_tools.jinja:120 +#: core/templates/core/user_tools.jinja:121 msgid "See archived elections" msgstr "Voir les élections archivées" -#: core/templates/core/user_tools.jinja:122 +#: core/templates/core/user_tools.jinja:123 msgid "Create a new election" msgstr "Créer une nouvelle élection" -#: core/templates/core/user_tools.jinja:127 +#: core/templates/core/user_tools.jinja:128 msgid "Other tools" msgstr "Autres outils" -#: core/templates/core/user_tools.jinja:129 +#: core/templates/core/user_tools.jinja:130 msgid "Convert dokuwiki/BBcode syntax to Markdown" msgstr "Convertir de la syntaxe dokuwiki/BBcode vers Markdown" -#: core/templates/core/user_tools.jinja:130 +#: core/templates/core/user_tools.jinja:131 msgid "Trombi tools" msgstr "Outils Trombi" @@ -3677,6 +3690,11 @@ msgstr "Famille" msgid "User already has a profile picture" msgstr "L'utilisateur a déjà une photo de profil" +#: counter/app.py:31 counter/models.py:237 counter/models.py:629 +#: counter/models.py:659 launderette/models.py:41 stock/models.py:43 +msgid "counter" +msgstr "comptoir" + #: counter/migrations/0013_customer_recorded_products.py:26 msgid "Ecocup regularization" msgstr "Régularization des ecocups" @@ -3770,11 +3788,6 @@ msgstr "vendeurs" msgid "token" msgstr "jeton" -#: counter/models.py:237 counter/models.py:629 counter/models.py:659 -#: launderette/models.py:41 stock/models.py:43 -msgid "counter" -msgstr "comptoir" - #: counter/models.py:372 msgid "bank" msgstr "banque" @@ -3799,8 +3812,8 @@ msgstr "quantité" msgid "Sith account" msgstr "Compte utilisateur" -#: counter/models.py:461 sith/settings.py:372 sith/settings.py:377 -#: sith/settings.py:395 +#: counter/models.py:461 sith/settings.py:371 sith/settings.py:376 +#: sith/settings.py:394 msgid "Credit card" msgstr "Carte bancaire" @@ -4320,21 +4333,21 @@ msgid "basket" msgstr "panier" #: eboutic/templates/eboutic/eboutic_main.jinja:35 -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:31 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:32 msgid "Basket amount: " msgstr "Valeur du panier : " -#: eboutic/templates/eboutic/eboutic_main.jinja:37 -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:33 +#: eboutic/templates/eboutic/eboutic_main.jinja:39 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:36 msgid "Current account amount: " msgstr "Solde actuel : " -#: eboutic/templates/eboutic/eboutic_main.jinja:39 -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:35 +#: eboutic/templates/eboutic/eboutic_main.jinja:41 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:38 msgid "Remaining account amount: " msgstr "Solde restant : " -#: eboutic/templates/eboutic/eboutic_main.jinja:45 +#: eboutic/templates/eboutic/eboutic_main.jinja:48 msgid "Proceed to command" msgstr "Procéder à la commande" @@ -4342,18 +4355,18 @@ msgstr "Procéder à la commande" msgid "Basket state" msgstr "État du panier" -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:42 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:47 msgid "Pay with credit card" msgstr "Payer avec une carte bancaire" -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:46 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:52 msgid "" "AE account payment disabled because your basket contains refilling items." msgstr "" "Paiement par compte AE désactivé parce que votre panier contient des bons de " "rechargement." -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:51 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:57 msgid "Pay with Sith account" msgstr "Payer avec un compte AE" @@ -4369,7 +4382,7 @@ msgstr "Le paiement a été effectué" msgid "Return to eboutic" msgstr "Retourner à l'eboutic" -#: eboutic/views.py:219 +#: eboutic/views.py:225 msgid "You do not have enough money to buy the basket" msgstr "Vous n'avez pas assez d'argent pour acheter le panier" @@ -4740,12 +4753,12 @@ msgid "Washing and drying" msgstr "Lavage et séchage" #: launderette/templates/launderette/launderette_book.jinja:27 -#: sith/settings.py:586 +#: sith/settings.py:592 msgid "Washing" msgstr "Lavage" #: launderette/templates/launderette/launderette_book.jinja:31 -#: sith/settings.py:586 +#: sith/settings.py:592 msgid "Drying" msgstr "Séchage" @@ -4788,7 +4801,7 @@ msgstr "Un jeton %(token_name)s existe déjà" msgid "User has booked no slot" msgstr "L'utilisateur n'a pas réservé de créneau" -#: launderette/views.py:452 +#: launderette/views.py:450 msgid "Token not found" msgstr "Jeton non trouvé" @@ -5002,29 +5015,6 @@ msgstr "Supprimer commentaire" msgid "Delete report" msgstr "Supprimer signalement" -#: pedagogy/templates/pedagogy/uv_create.jinja:4 -#: pedagogy/templates/pedagogy/uv_create.jinja:8 -msgid "Edit UV" -msgstr "Éditer" - -#: pedagogy/templates/pedagogy/uv_create.jinja:27 -msgid "Import from UTBM" -msgstr "Importer depuis l'UTBM" - -#: pedagogy/templates/pedagogy/uv_create.jinja:61 -#: pedagogy/templates/pedagogy/uv_create.jinja:84 -msgid "Unknown UV code" -msgstr "Code d'UV inconnu" - -#: pedagogy/templates/pedagogy/uv_create.jinja:76 -#: pedagogy/templates/pedagogy/uv_create.jinja:99 -msgid "Successful autocomplete" -msgstr "Autocomplétion réussite" - -#: pedagogy/templates/pedagogy/uv_create.jinja:79 -msgid "An error occured: " -msgstr "Une erreur est survenue : " - #: pedagogy/templates/pedagogy/uv_detail.jinja:6 msgid "UV Details" msgstr "Détails d'UV" @@ -5120,6 +5110,27 @@ msgstr "Ce commentaire a été signalé" msgid "Report this comment" msgstr "Signaler ce commentaire" +#: pedagogy/templates/pedagogy/uv_edit.jinja:4 +#: pedagogy/templates/pedagogy/uv_edit.jinja:8 +msgid "Edit UV" +msgstr "Éditer" + +#: pedagogy/templates/pedagogy/uv_edit.jinja:27 +msgid "Import from UTBM" +msgstr "Importer depuis l'UTBM" + +#: pedagogy/templates/pedagogy/uv_edit.jinja:62 +msgid "Unknown UV code" +msgstr "Code d'UV inconnu" + +#: pedagogy/templates/pedagogy/uv_edit.jinja:77 +msgid "Successful autocomplete" +msgstr "Autocomplétion réussite" + +#: pedagogy/templates/pedagogy/uv_edit.jinja:80 +msgid "An error occured: " +msgstr "Une erreur est survenue : " + #: rootplace/templates/rootplace/delete_user_messages.jinja:8 msgid "Delete all forum messages from an user" msgstr "Supprimer tous les messages forum d'un utilisateur" @@ -5137,6 +5148,10 @@ msgstr "" "erreur 500), essayez en utilisant l'utilitaire en ligne de commande. " "Utilisez ./manage.py delete_user_messages ID." +#: rootplace/templates/rootplace/logs.jinja:15 +msgid "Operator" +msgstr "Opérateur" + #: rootplace/templates/rootplace/merge.jinja:8 msgid "Merge two users" msgstr "Fusionner deux utilisateurs" @@ -5145,15 +5160,15 @@ msgstr "Fusionner deux utilisateurs" msgid "Merge" msgstr "Fusion" -#: rootplace/views.py:110 +#: rootplace/views.py:112 msgid "User that will be kept" msgstr "Utilisateur qui sera conservé" -#: rootplace/views.py:113 +#: rootplace/views.py:115 msgid "User that will be deleted" msgstr "Utilisateur qui sera supprimé" -#: rootplace/views.py:119 +#: rootplace/views.py:121 msgid "User to be selected" msgstr "Utilisateur à sélectionner" @@ -5237,360 +5252,368 @@ msgstr "Erreur de création de l'album %(album)s : %(msg)s" msgid "Add user" msgstr "Ajouter une personne" -#: sith/settings.py:218 sith/settings.py:432 +#: sith/settings.py:219 sith/settings.py:431 msgid "English" msgstr "Anglais" -#: sith/settings.py:218 sith/settings.py:431 +#: sith/settings.py:219 sith/settings.py:430 msgid "French" msgstr "Français" -#: sith/settings.py:353 +#: sith/settings.py:352 msgid "TC" msgstr "TC" -#: sith/settings.py:354 +#: sith/settings.py:353 msgid "IMSI" msgstr "IMSI" -#: sith/settings.py:355 +#: sith/settings.py:354 msgid "IMAP" msgstr "IMAP" -#: sith/settings.py:356 +#: sith/settings.py:355 msgid "INFO" msgstr "INFO" -#: sith/settings.py:357 +#: sith/settings.py:356 msgid "GI" msgstr "GI" -#: sith/settings.py:358 sith/settings.py:442 +#: sith/settings.py:357 sith/settings.py:441 msgid "E" msgstr "E" -#: sith/settings.py:359 +#: sith/settings.py:358 msgid "EE" msgstr "EE" -#: sith/settings.py:360 +#: sith/settings.py:359 msgid "GESC" msgstr "GESC" -#: sith/settings.py:361 +#: sith/settings.py:360 msgid "GMC" msgstr "GMC" -#: sith/settings.py:362 +#: sith/settings.py:361 msgid "MC" msgstr "MC" -#: sith/settings.py:363 +#: sith/settings.py:362 msgid "EDIM" msgstr "EDIM" -#: sith/settings.py:364 +#: sith/settings.py:363 msgid "Humanities" msgstr "Humanités" -#: sith/settings.py:365 +#: sith/settings.py:364 msgid "N/A" msgstr "N/A" -#: sith/settings.py:369 sith/settings.py:376 sith/settings.py:393 +#: sith/settings.py:368 sith/settings.py:375 sith/settings.py:392 msgid "Check" msgstr "Chèque" -#: sith/settings.py:370 sith/settings.py:378 sith/settings.py:394 +#: sith/settings.py:369 sith/settings.py:377 sith/settings.py:393 msgid "Cash" msgstr "Espèces" -#: sith/settings.py:371 +#: sith/settings.py:370 msgid "Transfert" msgstr "Virement" -#: sith/settings.py:384 +#: sith/settings.py:383 msgid "Belfort" msgstr "Belfort" -#: sith/settings.py:385 +#: sith/settings.py:384 msgid "Sevenans" msgstr "Sevenans" -#: sith/settings.py:386 +#: sith/settings.py:385 msgid "Montbéliard" msgstr "Montbéliard" -#: sith/settings.py:412 +#: sith/settings.py:411 msgid "Free" msgstr "Libre" -#: sith/settings.py:413 +#: sith/settings.py:412 msgid "CS" msgstr "CS" -#: sith/settings.py:414 +#: sith/settings.py:413 msgid "TM" msgstr "TM" -#: sith/settings.py:415 +#: sith/settings.py:414 msgid "OM" msgstr "OM" -#: sith/settings.py:416 +#: sith/settings.py:415 msgid "QC" msgstr "QC" -#: sith/settings.py:417 +#: sith/settings.py:416 msgid "EC" msgstr "EC" -#: sith/settings.py:418 +#: sith/settings.py:417 msgid "RN" msgstr "RN" -#: sith/settings.py:419 +#: sith/settings.py:418 msgid "ST" msgstr "ST" -#: sith/settings.py:420 +#: sith/settings.py:419 msgid "EXT" msgstr "EXT" -#: sith/settings.py:425 +#: sith/settings.py:424 msgid "Autumn" msgstr "Automne" -#: sith/settings.py:426 +#: sith/settings.py:425 msgid "Spring" msgstr "Printemps" -#: sith/settings.py:427 +#: sith/settings.py:426 msgid "Autumn and spring" msgstr "Automne et printemps" -#: sith/settings.py:433 +#: sith/settings.py:432 msgid "German" msgstr "Allemant" -#: sith/settings.py:434 +#: sith/settings.py:433 msgid "Spanich" msgstr "Espagnol" -#: sith/settings.py:438 +#: sith/settings.py:437 msgid "A" msgstr "A" -#: sith/settings.py:439 +#: sith/settings.py:438 msgid "B" msgstr "B" -#: sith/settings.py:440 +#: sith/settings.py:439 msgid "C" msgstr "C" -#: sith/settings.py:441 +#: sith/settings.py:440 msgid "D" msgstr "D" -#: sith/settings.py:443 +#: sith/settings.py:442 msgid "FX" msgstr "FX" -#: sith/settings.py:444 +#: sith/settings.py:443 msgid "F" msgstr "F" -#: sith/settings.py:445 +#: sith/settings.py:444 msgid "Abs" msgstr "Abs" -#: sith/settings.py:474 +#: sith/settings.py:448 +msgid "Selling deletion" +msgstr "Suppression de vente" + +#: sith/settings.py:449 +msgid "Refilling deletion" +msgstr "Suppression de rechargement" + +#: sith/settings.py:480 msgid "One semester" msgstr "Un semestre, 15 €" -#: sith/settings.py:475 +#: sith/settings.py:481 msgid "Two semesters" msgstr "Deux semestres, 28 €" -#: sith/settings.py:477 +#: sith/settings.py:483 msgid "Common core cursus" msgstr "Cursus tronc commun, 45 €" -#: sith/settings.py:481 +#: sith/settings.py:487 msgid "Branch cursus" msgstr "Cursus branche, 45 €" -#: sith/settings.py:482 +#: sith/settings.py:488 msgid "Alternating cursus" msgstr "Cursus alternant, 30 €" -#: sith/settings.py:483 +#: sith/settings.py:489 msgid "Honorary member" msgstr "Membre honoraire, 0 €" -#: sith/settings.py:484 +#: sith/settings.py:490 msgid "Assidu member" msgstr "Membre d'Assidu, 0 €" -#: sith/settings.py:485 +#: sith/settings.py:491 msgid "Amicale/DOCEO member" msgstr "Membre de l'Amicale/DOCEO, 0 €" -#: sith/settings.py:486 +#: sith/settings.py:492 msgid "UT network member" msgstr "Cotisant du réseau UT, 0 €" -#: sith/settings.py:487 +#: sith/settings.py:493 msgid "CROUS member" msgstr "Membres du CROUS, 0 €" -#: sith/settings.py:488 +#: sith/settings.py:494 msgid "Sbarro/ESTA member" msgstr "Membre de Sbarro ou de l'ESTA, 15 €" -#: sith/settings.py:490 +#: sith/settings.py:496 msgid "One semester Welcome Week" msgstr "Un semestre Welcome Week" -#: sith/settings.py:494 +#: sith/settings.py:500 msgid "Two months for free" msgstr "Deux mois gratuits" -#: sith/settings.py:495 +#: sith/settings.py:501 msgid "Eurok's volunteer" msgstr "Bénévole Eurockéennes" -#: sith/settings.py:497 +#: sith/settings.py:503 msgid "Six weeks for free" msgstr "6 semaines gratuites" -#: sith/settings.py:501 +#: sith/settings.py:507 msgid "One day" msgstr "Un jour" -#: sith/settings.py:504 +#: sith/settings.py:510 msgid "One semester (-20%)" msgstr "Un semestre (-20%), 12 €" -#: sith/settings.py:509 +#: sith/settings.py:515 msgid "Two semesters (-20%)" msgstr "Deux semestres (-20%), 22 €" -#: sith/settings.py:514 +#: sith/settings.py:520 msgid "Common core cursus (-20%)" msgstr "Cursus tronc commun (-20%), 36 €" -#: sith/settings.py:519 +#: sith/settings.py:525 msgid "Branch cursus (-20%)" msgstr "Cursus branche (-20%), 36 €" -#: sith/settings.py:524 +#: sith/settings.py:530 msgid "Alternating cursus (-20%)" msgstr "Cursus alternant (-20%), 24 €" -#: sith/settings.py:546 +#: sith/settings.py:552 msgid "President" msgstr "Président" -#: sith/settings.py:547 +#: sith/settings.py:553 msgid "Vice-President" msgstr "Vice-Président" -#: sith/settings.py:548 +#: sith/settings.py:554 msgid "Treasurer" msgstr "Trésorier" -#: sith/settings.py:549 +#: sith/settings.py:555 msgid "Communication supervisor" msgstr "Responsable communication" -#: sith/settings.py:550 +#: sith/settings.py:556 msgid "Secretary" msgstr "Secrétaire" -#: sith/settings.py:551 +#: sith/settings.py:557 msgid "IT supervisor" msgstr "Responsable info" -#: sith/settings.py:552 +#: sith/settings.py:558 msgid "Board member" msgstr "Membre du bureau" -#: sith/settings.py:553 +#: sith/settings.py:559 msgid "Active member" msgstr "Membre actif" -#: sith/settings.py:554 +#: sith/settings.py:560 msgid "Curious" msgstr "Curieux" -#: sith/settings.py:590 +#: sith/settings.py:596 msgid "A new poster needs to be moderated" msgstr "Une nouvelle affiche a besoin d'être modérée" -#: sith/settings.py:591 +#: sith/settings.py:597 msgid "A new mailing list needs to be moderated" msgstr "Une nouvelle mailing list a besoin d'être modérée" -#: sith/settings.py:594 +#: sith/settings.py:600 msgid "A new pedagogy comment has been signaled for moderation" msgstr "" "Un nouveau commentaire de la pédagogie a été signalé pour la modération" -#: sith/settings.py:596 +#: sith/settings.py:602 #, python-format msgid "There are %s fresh news to be moderated" msgstr "Il y a %s nouvelles toutes fraîches à modérer" -#: sith/settings.py:597 +#: sith/settings.py:603 msgid "New files to be moderated" msgstr "Nouveaux fichiers à modérer" -#: sith/settings.py:598 +#: sith/settings.py:604 #, python-format msgid "There are %s pictures to be moderated in the SAS" msgstr "Il y a %s photos à modérer dans le SAS" -#: sith/settings.py:599 +#: sith/settings.py:605 msgid "You've been identified on some pictures" msgstr "Vous avez été identifié sur des photos" -#: sith/settings.py:600 +#: sith/settings.py:606 #, python-format msgid "You just refilled of %s €" msgstr "Vous avez rechargé votre compte de %s€" -#: sith/settings.py:601 +#: sith/settings.py:607 #, python-format msgid "You just bought %s" msgstr "Vous avez acheté %s" -#: sith/settings.py:602 +#: sith/settings.py:608 msgid "You have a notification" msgstr "Vous avez une notification" -#: sith/settings.py:614 +#: sith/settings.py:620 msgid "Success!" msgstr "Succès !" -#: sith/settings.py:615 +#: sith/settings.py:621 msgid "Fail!" msgstr "Échec !" -#: sith/settings.py:616 +#: sith/settings.py:622 msgid "You successfully posted an article in the Weekmail" msgstr "Article posté avec succès dans le Weekmail" -#: sith/settings.py:617 +#: sith/settings.py:623 msgid "You successfully edited an article in the Weekmail" msgstr "Article édité avec succès dans le Weekmail" -#: sith/settings.py:618 +#: sith/settings.py:624 msgid "You successfully sent the Weekmail" msgstr "Weekmail envoyé avec succès" -#: sith/settings.py:626 +#: sith/settings.py:632 msgid "AE tee-shirt" msgstr "Tee-shirt AE" diff --git a/rootplace/templates/rootplace/logs.jinja b/rootplace/templates/rootplace/logs.jinja new file mode 100644 index 00000000..740ec74f --- /dev/null +++ b/rootplace/templates/rootplace/logs.jinja @@ -0,0 +1,32 @@ +{% extends "core/base.jinja" %} +{% from 'core/macros.jinja' import paginate %} + +{% block title %} +{% trans %}Operation logs{% endtrans %} +{% endblock %} + +{% block content %} + + + + + + + + + + + {% for log in object_list %} + + + + + + + {% endfor %} + +
    {% trans %}Date{% endtrans %}{% trans %}Operation type{% endtrans %}{% trans %}Label{% endtrans %}{% trans %}Operator{% endtrans %}
    {{ log.date }} {{ log.get_operation_type_display() }}{{ log.label }}{{ log.operator }}
    + +
    + {{ paginate(page_obj, paginator) }} +{% endblock content %} \ No newline at end of file diff --git a/rootplace/urls.py b/rootplace/urls.py index f2cc97f2..33b3bd6d 100644 --- a/rootplace/urls.py +++ b/rootplace/urls.py @@ -2,6 +2,7 @@ # # Copyright 2016,2017 # - Skia +# - Sli # # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # http://ae.utbm.fr. @@ -33,4 +34,5 @@ urlpatterns = [ DeleteAllForumUserMessagesView.as_view(), name="delete_forum_messages", ), + re_path(r"^logs$", OperationLogListView.as_view(), name="operation_logs"), ] diff --git a/rootplace/views.py b/rootplace/views.py index 41a9690a..570cae7b 100644 --- a/rootplace/views.py +++ b/rootplace/views.py @@ -25,13 +25,15 @@ from django.utils.translation import ugettext as _ from django.views.generic.edit import FormView +from django.views.generic import ListView from django.urls import reverse from django import forms from django.core.exceptions import PermissionDenied from ajax_select.fields import AutoCompleteSelectField -from core.models import User +from core.views import CanEditPropMixin +from core.models import User, OperationLog from counter.models import Customer from forum.models import ForumMessageMeta @@ -165,3 +167,14 @@ class DeleteAllForumUserMessagesView(FormView): def get_success_url(self): return reverse("core:user_profile", kwargs={"user_id": self.user.id}) + + +class OperationLogListView(ListView, CanEditPropMixin): + """ + List all logs + """ + + model = OperationLog + template_name = "rootplace/logs.jinja" + ordering = ["-date"] + paginate_by = 100 diff --git a/sith/settings.py b/sith/settings.py index 19f30ca8..127c223e 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -106,6 +106,7 @@ MIDDLEWARE = ( "django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.security.SecurityMiddleware", "core.middleware.AuthenticationMiddleware", + "core.middleware.RequestMiddleware", ) ROOT_URLCONF = "sith.urls" @@ -443,6 +444,11 @@ SITH_PEDAGOGY_UV_RESULT_GRADE = [ ("ABS", _("Abs")), ] +SITH_LOG_OPERATION_TYPE = [ + (("SELLING_DELETION"), _("Selling deletion")), + (("REFILLING_DELETION"), _("Refilling deletion")), +] + SITH_PEDAGOGY_UTBM_API = "https://extranet1.utbm.fr/gpedago/api/guide" SITH_ECOCUP_CONS = 1152 From 1c03ce621f0ae6284d74483b54dabc2b7d60b30e Mon Sep 17 00:00:00 2001 From: Bartuccio Antoine Date: Thu, 14 Nov 2019 16:11:20 +0100 Subject: [PATCH 2/3] core: remove default value for OperationLog --- core/migrations/0034_operationlog.py | 3 +-- core/models.py | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/core/migrations/0034_operationlog.py b/core/migrations/0034_operationlog.py index 1cd7b74e..93083f99 100644 --- a/core/migrations/0034_operationlog.py +++ b/core/migrations/0034_operationlog.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.6 on 2019-11-13 21:17 +# Generated by Django 2.2.6 on 2019-11-14 15:10 from django.conf import settings from django.db import migrations, models @@ -33,7 +33,6 @@ class Migration(migrations.Migration): ("SELLING_DELETION", "Selling deletion"), ("REFILLING_DELETION", "Refilling deletion"), ], - default="SELLING_DELETION", max_length=40, verbose_name="operation type", ), diff --git a/core/models.py b/core/models.py index 84de5bb8..8ba1e2cc 100644 --- a/core/models.py +++ b/core/models.py @@ -1467,10 +1467,7 @@ class OperationLog(models.Model): User, related_name="logs", on_delete=models.SET_NULL, null=True ) operation_type = models.CharField( - _("operation type"), - max_length=40, - choices=settings.SITH_LOG_OPERATION_TYPE, - default=settings.SITH_LOG_OPERATION_TYPE[0][0], + _("operation type"), max_length=40, choices=settings.SITH_LOG_OPERATION_TYPE, ) def is_owned_by(self, user): From 5c30de5f2287217ea5835f1466531cdf1af9fa58 Mon Sep 17 00:00:00 2001 From: Bartuccio Antoine Date: Thu, 14 Nov 2019 16:18:10 +0100 Subject: [PATCH 3/3] core: redesign request middleware with django latest design and better use of threading --- core/middleware.py | 22 +++++++++++++--------- counter/signals.py | 12 ++++++++---- sith/settings.py | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/core/middleware.py b/core/middleware.py index 45641e1f..538fc7cb 100644 --- a/core/middleware.py +++ b/core/middleware.py @@ -50,27 +50,31 @@ class AuthenticationMiddleware(DjangoAuthenticationMiddleware): def process_request(self, request): assert hasattr(request, "session"), ( "The Django authentication middleware requires session middleware " - "to be installed. Edit your MIDDLEWARE_CLASSES setting to insert " + "to be installed. Edit your MIDDLEWARE setting to insert " "'django.contrib.sessions.middleware.SessionMiddleware' before " "'account.middleware.AuthenticationMiddleware'." ) request.user = SimpleLazyObject(lambda: get_cached_user(request)) -class RequestMiddleware: +_threadlocal = threading.local() + + +def get_signal_request(): """ + !!! Do not use if your operation is asynchronus !!! Allow to access current request in signals This is a hack that looks into the thread - !!! Do not use if your operation is asynchronus !!! Mainly used for log purpose """ - def __init__(self, get_response, thread_local=threading.local()): + return getattr(_threadlocal, "request", None) + + +class SignalRequestMiddleware: + def __init__(self, get_response): self.get_response = get_response - self.thread_local = thread_local def __call__(self, request): - self.thread_local.current_request = request - - response = self.get_response(request) - return response + setattr(_threadlocal, "request", request) + return self.get_response(request) diff --git a/counter/signals.py b/counter/signals.py index 5dcbc39f..0f4fad70 100644 --- a/counter/signals.py +++ b/counter/signals.py @@ -26,7 +26,7 @@ from django.db.models.signals import pre_delete from django.dispatch import receiver from django.conf import settings -from core.middleware import RequestMiddleware +from core.middleware import get_signal_request from core.models import OperationLog from counter.models import Selling, Refilling, Counter @@ -34,13 +34,17 @@ from counter.models import Selling, Refilling, Counter def write_log(instance, operation_type): def get_user(): - request = RequestMiddleware(get_response=None).thread_local.current_request + request = get_signal_request() + + if not request: + return None # Get a random barmen if deletion is from a counter - session_token = request.session.get("counter_token", None) + session = getattr(request, "session", {}) + session_token = session.get("counter_token", None) if session_token: counter = Counter.objects.filter(token=session_token).first() - if counter: + if counter and len(counter.get_barmen_list()) > 0: return counter.get_random_barman() # Get the current logged user if not from a counter diff --git a/sith/settings.py b/sith/settings.py index 127c223e..fa2cb37e 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -106,7 +106,7 @@ MIDDLEWARE = ( "django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.security.SecurityMiddleware", "core.middleware.AuthenticationMiddleware", - "core.middleware.RequestMiddleware", + "core.middleware.SignalRequestMiddleware", ) ROOT_URLCONF = "sith.urls"