1
0
mirror of https://gitlab.crans.org/bde/nk20-scripts synced 2025-02-25 17:36:33 +00:00

Compare commits

...

5 Commits

Author SHA1 Message Date
erdnaxe
d1990cc63d Merge branch 'l_eveil_du_nanax' into 'master'
L'eveil du nanax

See merge request bde/nk20-scripts!2
2022-08-31 08:24:20 +02:00
c4f128786d
De l'inclusif, partout
Signed-off-by: Emmy D'ANELLO <ynerant@crans.org>
2022-08-29 13:18:58 +02:00
861f03eb6d
[scripts] Remove README and add link to documentation
Signed-off-by: Emmy D'ANELLO <ynerant@crans.org>
2022-08-29 11:54:27 +02:00
48d9a8b5d2
Replace ... by …
Signed-off-by: Emmy D'ANELLO <ynerant@crans.org>
2022-08-29 11:17:17 +02:00
Alexandre Iooss
3442edd2bf
Reorder imports and fix trailing spaces 2021-05-12 17:43:18 +02:00
16 changed files with 62 additions and 143 deletions

View File

@ -1,63 +1,3 @@
# Script de la NoteKfet 2020 # Script de la NoteKfet 2020
## Commandes Django La documentation est disponible sur <https://note.crans.org/doc/scripts/>.
> les commandes sont documentées:
> `./manage.py command --help`
- `import_nk15` :
Importe un dump de la NoteKfet 2015.
- `make_su [--STAFF|-s] [--SUPER|-S]` :
Rend actifs les pseudos renseignés.
* Si `--STAFF` ou `-s` est renseigné, donne en plus le statut d'équipe aux pseudos renseignés,
permettant l'accès à l'interface admin.
* Si `--SUPER` ou `-S` est renseigné, donne en plus le statut de super-utilisateur aux pseudos renseignés,
octroyant tous les droits sur la plateforme.
- `wei_algorithm` :
Lance l'algorithme de répartition des 1A au dernier WEI. Cela a pour effet de suggérer un bus pour tous les 1A
inscrits au dernier WEI en fonction des données rentrées dans le sondage, la validation se faisant ensuite
manuellement via l'interface Web.
- `extract_ml_registrations --type {members, clubs, events, art, sport} [--year|-y YEAR]` :
Récupère la liste des adresses mail à inscrire à une liste de diffusion donnée.
* `members` : Liste des adresses mail des utilisateurs ayant une adhésion BDE (et non Kfet) active.
* `clubs` : Liste des adresses mail de contact de tous les clubs BDE enregistrés.
* `events` : Liste de toutes les adresses mails des utilisateurs inscrits au WEI ayant demandé à s'inscrire sur
la liste de diffusion des événements du BDE.
* `art` : Liste de toutes les adresses mails des utilisateurs inscrits au WEI ayant demandé à s'inscrire sur
la liste de diffusion concertnant les actualités artistiques du BDA.
* `sport` : Liste de toutes les adresses mails des utilisateurs inscrits au WEI ayant demandé à s'inscrire sur
la liste de diffusion concertnant les actualités sportives du BDS.
Le champ `--year` est optionnel : il permet de choisir l'année du WEI en question (pour les trois dernières
options). Si non renseigné, il s'agit du dernier WEI.
Par défaut, si `--type` est non renseigné, la liste des adhérents BDE est renvoyée.
- `extract_wei_registrations [--year|-y YEAR] [--bus|-b BUS] [--team|-t TEAM] [--sep SEP]` :
Récupère la liste des inscriptions au WEI et l'exporte au format CSV. Arguments possibles, optionnels :
* `--year YEAR` : sélectionne l'année du WEI. Par défaut, il s'agit du dernier WEI ayant eu lieu.
* `--bus BUS` : filtre par bus, en récupérant uniquement les inscriptions sur un bus. Par défaut, on affiche
tous les bus.
* `--team TEAM` : filtre par équipe, en récupérant uniquement les inscriptions sur une équipe. Par défaut, on
affiche toutes les équipes. Entrer `"none"` filtre les inscriptions sans équipe (chefs de bus, ...)
* `--sep` : définit le caractère de séparation des colonnes du fichier CSV. Par défaut, il s'agit du caractère `|`.
Merci de ne pas rentrer plus d'un caractère.
## Shell
- Tabula rasa :
```shell script
sudo -u postgres sh -c "dropdb note_db && psql -c 'CREATE DATABASE note_db OWNER note;'"
```

View File

@ -2,7 +2,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig from django.apps import AppConfig
from django.core.signals import got_request_exception
class ScriptsConfig(AppConfig): class ScriptsConfig(AppConfig):

View File

@ -5,10 +5,9 @@ import json
import time import time
from collections import defaultdict from collections import defaultdict
from django.core.management.base import BaseCommand
from django.apps import apps from django.apps import apps
from django.core.management.base import BaseCommand
from django.db import transaction from django.db import transaction
from polymorphic.models import PolymorphicModel from polymorphic.models import PolymorphicModel
@ -16,6 +15,7 @@ def timed(method):
"""" """"
A simple decorator to measure time elapsed in class function (hence the args[0]) A simple decorator to measure time elapsed in class function (hence the args[0])
""" """
def _timed(*args, **kw): def _timed(*args, **kw):
ts = time.time() ts = time.time()
result = method(*args, **kw) result = method(*args, **kw)

View File

@ -13,6 +13,7 @@ class Command(BaseCommand):
""" """
Generate Javascript translation files Generate Javascript translation files
""" """
def handle(self, *args, **kwargs): def handle(self, *args, **kwargs):
for code, _ in settings.LANGUAGES: for code, _ in settings.LANGUAGES:
if code == settings.LANGUAGE_CODE: if code == settings.LANGUAGE_CODE:

View File

@ -5,9 +5,7 @@ from datetime import date
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.management import BaseCommand from django.core.management import BaseCommand
from django.db.models import Q from member.models import Club, Membership
from member.models import Membership, Club
from wei.models import WEIClub
class Command(BaseCommand): class Command(BaseCommand):

View File

@ -11,7 +11,6 @@ from django.core.management.base import BaseCommand
from django.db import transaction from django.db import transaction
from django.db.models import Q from django.db.models import Q
from django.test import override_settings from django.test import override_settings
from note.models import Alias, Transaction from note.models import Alias, Transaction
@ -57,13 +56,13 @@ class Command(BaseCommand):
if user_id.isnumeric(): if user_id.isnumeric():
qs = User.objects.filter(pk=int(user_id)) qs = User.objects.filter(pk=int(user_id))
if not qs.exists(): if not qs.exists():
self.stderr.write(self.style.WARNING(f"User {user_id} was not found. Ignoring...")) self.stderr.write(self.style.WARNING(f"User {user_id} was not found. Ignoring"))
continue continue
user = qs.get() user = qs.get()
else: else:
qs = Alias.objects.filter(normalized_name=Alias.normalize(user_id), note__noteuser__isnull=False) qs = Alias.objects.filter(normalized_name=Alias.normalize(user_id), note__noteuser__isnull=False)
if not qs.exists(): if not qs.exists():
self.stderr.write(self.style.WARNING(f"User {user_id} was not found. Ignoring...")) self.stderr.write(self.style.WARNING(f"User {user_id} was not found. Ignoring"))
continue continue
user = qs.get().note.user user = qs.get().note.user
@ -80,7 +79,7 @@ class Command(BaseCommand):
local_deleted += list(transactions) local_deleted += list(transactions)
for tr in transactions: for tr in transactions:
if kwargs['verbosity'] >= 1: if kwargs['verbosity'] >= 1:
self.stdout.write(f"Removing {tr}...") self.stdout.write(f"Removing {tr}")
if force: if force:
tr.delete() tr.delete()
@ -89,7 +88,7 @@ class Command(BaseCommand):
local_deleted += list(memberships) local_deleted += list(memberships)
if kwargs['verbosity'] >= 1: if kwargs['verbosity'] >= 1:
for membership in memberships: for membership in memberships:
self.stdout.write(f"Removing {membership}...") self.stdout.write(f"Removing {membership}")
if force: if force:
memberships.delete() memberships.delete()
@ -98,7 +97,7 @@ class Command(BaseCommand):
local_deleted += list(alias_set) local_deleted += list(alias_set)
if kwargs['verbosity'] >= 1: if kwargs['verbosity'] >= 1:
for alias in alias_set: for alias in alias_set:
self.stdout.write(f"Removing alias {alias}...") self.stdout.write(f"Removing alias {alias}")
if force: if force:
alias_set.delete() alias_set.delete()
@ -110,7 +109,7 @@ class Command(BaseCommand):
local_deleted += list(entries) local_deleted += list(entries)
if kwargs['verbosity'] >= 1: if kwargs['verbosity'] >= 1:
for entry in entries: for entry in entries:
self.stdout.write(f"Removing {entry}...") self.stdout.write(f"Removing {entry}")
if force: if force:
entries.delete() entries.delete()
@ -119,7 +118,7 @@ class Command(BaseCommand):
local_deleted += list(guests) local_deleted += list(guests)
if kwargs['verbosity'] >= 1: if kwargs['verbosity'] >= 1:
for guest in guests: for guest in guests:
self.stdout.write(f"Removing guest {guest}...") self.stdout.write(f"Removing guest {guest}")
if force: if force:
guests.delete() guests.delete()
@ -131,7 +130,7 @@ class Command(BaseCommand):
local_deleted += list(credits) local_deleted += list(credits)
if kwargs['verbosity'] >= 1: if kwargs['verbosity'] >= 1:
for credit in credits: for credit in credits:
self.stdout.write(f"Removing {credit}...") self.stdout.write(f"Removing {credit}")
if force: if force:
credits.delete() credits.delete()
@ -169,9 +168,9 @@ class Command(BaseCommand):
deleted += local_deleted deleted += local_deleted
if deleted_users: if deleted_users:
message = f"Les utilisateurs {deleted_users} ont été supprimés par {executor}.\n\n" message = f"Les utilisateur⋅rices {deleted_users} ont été supprimé⋅es par {executor}.\n\n"
message += "Ont été supprimés en conséquence les objets suivants :\n\n" message += "Ont été supprimés en conséquence les objets suivants :\n\n"
for obj in deleted: for obj in deleted:
message += f"{repr(obj)} (pk: {obj.pk})\n" message += f"{repr(obj)} (pk: {obj.pk})\n"
if force and kwargs['doit']: if force and kwargs['doit']:
mail_admins("Utilisateurs supprimés", message) mail_admins("Utilisateur⋅rices supprimés", message)

View File

@ -1,23 +1,19 @@
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay # Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import psycopg2 as pg
import psycopg2.extras as pge
import datetime import datetime
import json import json
from django.template.loader import render_to_string import psycopg2 as pg
from django.utils.timezone import make_aware, now import psycopg2.extras as pge
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import transaction from django.db import transaction
from django.utils.timezone import make_aware
from note.models import Note, NoteUser, NoteClub
from note.models import Alias
from member.models import Club, Profile from member.models import Club, Profile
from note.models import Alias, Note, NoteClub, NoteUser
from ._import_utils import ImportCommand, BulkCreateManager, timed from ._import_utils import BulkCreateManager, ImportCommand, timed
M_DURATION = 396 M_DURATION = 396
M_START = datetime.date(2019, 8, 1) M_START = datetime.date(2019, 8, 1)
@ -214,7 +210,7 @@ class Command(ImportCommand):
pk_alias = Alias.objects.order_by('-id').first().id + 1 pk_alias = Alias.objects.order_by('-id').first().id + 1
for idx, row in enumerate(cur): for idx, row in enumerate(cur):
alias_name = row["alias"] alias_name = row["alias"]
alias_name = (alias_name[:252] + '...') if len(alias_name) > 255 else alias_name alias_name = (alias_name[:254] + '') if len(alias_name) > 255 else alias_name
alias_norm = Alias.normalize(alias_name) alias_norm = Alias.normalize(alias_name)
self.update_line(idx, n, alias_norm) self.update_line(idx, n, alias_norm)
# clean pseudo (normalized pseudo must be unique) # clean pseudo (normalized pseudo must be unique)

View File

@ -3,32 +3,30 @@
import psycopg2 as pg import psycopg2 as pg
import psycopg2.extras as pge import psycopg2.extras as pge
import datetime from activity.models import Activity, ActivityType, Entry, Guest
import copy
from django.utils.timezone import make_aware
from django.db import transaction from django.db import transaction
from django.utils.timezone import make_aware
from activity.models import ActivityType, Activity, Guest, Entry
from member.models import Club from member.models import Club
from note.models import Note, NoteUser from note.models import Note, NoteUser
from ._import_utils import ImportCommand, BulkCreateManager, timed
from ._import_utils import BulkCreateManager, ImportCommand, timed
MAP_ACTIVITY = dict() MAP_ACTIVITY = dict()
CLUB_RELOU = [ CLUB_RELOU = [
0, # BDE 0, # BDE
4771, # Kataclist 4771, # Kataclist
5162, # Assurance BDE ?! 5162, # Assurance BDE ?!
5164, # S & L 5164, # S & L
625, # Aspique 625, # Aspique
5154, # Frekens 5154, # Frekens
3944, # DiskJok[ENS] 3944, # DiskJok[ENS]
5153, # Monopo[list] 5153, # Monopo[list]
2351, # JdRM 2351, # JdRM
2365, # Pot Vieux 2365, # Pot Vieux
] ]
class Command(ImportCommand): class Command(ImportCommand):
""" """
Import command for Activities Base Data (Comptes, and Aliases) Import command for Activities Base Data (Comptes, and Aliases)
@ -50,7 +48,7 @@ class Command(ImportCommand):
row["responsable"] = 3508 row["responsable"] = 3508
note = self.MAP_IDBDE[row["responsable"]] note = self.MAP_IDBDE[row["responsable"]]
if note == 6244: if note == 6244:
# Licorne magique ne doit pas utiliser son compte club pour proposer des activités # Licorne magique ne doit pas utiliser son compte club pour proposer des activités
note = Note.objects.get(pk=self.MAP_IDBDE[6524]) note = Note.objects.get(pk=self.MAP_IDBDE[6524])
note = note.id note = note.id
organizer = Club.objects.filter(name=row["signature"]) organizer = Club.objects.filter(name=row["signature"])

View File

@ -3,11 +3,11 @@
import subprocess import subprocess
from django.core.management.base import BaseCommand
from django.core.management import call_command from django.core.management import call_command
from ._import_utils import ImportCommand from ._import_utils import ImportCommand
class Command(ImportCommand): class Command(ImportCommand):
""" """
Command for importing the database of NK15. Command for importing the database of NK15.

View File

@ -1,31 +1,25 @@
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay # Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import copy
import datetime
import re import re
import pytz
import psycopg2 as pg import psycopg2 as pg
import psycopg2.extras as pge import psycopg2.extras as pge
import pytz from activity.models import Entry, GuestTransaction
import datetime
import copy
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.timezone import make_aware
from django.db import transaction
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import transaction
from note.models import (TemplateCategory, from django.utils.timezone import make_aware
TransactionTemplate,
Transaction,
RecurrentTransaction,
SpecialTransaction,
MembershipTransaction,
)
from note.models import Note, NoteClub
from activity.models import Guest, GuestTransaction, Entry
from member.models import Membership from member.models import Membership
from treasury.models import Remittance, SpecialTransactionProxy, SogeCredit from note.models import (MembershipTransaction, Note, NoteClub,
from ._import_utils import ImportCommand, BulkCreateManager, timed RecurrentTransaction, SpecialTransaction,
TemplateCategory, Transaction, TransactionTemplate)
from treasury.models import Remittance, SogeCredit, SpecialTransactionProxy
from ._import_utils import BulkCreateManager, ImportCommand, timed
MAP_TRANSACTION = dict() MAP_TRANSACTION = dict()
MAP_REMITTANCE = dict() MAP_REMITTANCE = dict()
@ -102,7 +96,7 @@ class Command(ImportCommand):
def _basic_transaction(self, row, obj_dict, child_dict): def _basic_transaction(self, row, obj_dict, child_dict):
if len(row["description"]) > 255: if len(row["description"]) > 255:
obj_dict["reason"] = obj_dict["reason"][:250] + "...)" obj_dict["reason"] = obj_dict["reason"][:252] + ")"
return obj_dict, None, None return obj_dict, None, None
def _template_transaction(self, row, obj_dict, child_dict): def _template_transaction(self, row, obj_dict, child_dict):
@ -221,7 +215,7 @@ class Command(ImportCommand):
"valid": row["valide"], "valid": row["valide"],
} }
if len(obj_dict["reason"]) > 255: if len(obj_dict["reason"]) > 255:
obj_dict["reason"] = obj_dict["reason"][:252] + "..." obj_dict["reason"] = obj_dict["reason"][:254] + ""
# for child transaction Models # for child transaction Models
child_dict = {"pk": pk_transaction} child_dict = {"pk": pk_transaction}
ttype = row["type"] ttype = row["type"]

View File

@ -17,10 +17,10 @@ class Command(BaseCommand):
user.is_active = True user.is_active = True
if kwargs['STAFF']: if kwargs['STAFF']:
if kwargs['verbosity'] > 0: if kwargs['verbosity'] > 0:
self.stdout.write(f"Add {user} to staff users...") self.stdout.write(f"Add {user} to staff users")
user.is_staff = True user.is_staff = True
if kwargs['SUPER']: if kwargs['SUPER']:
if kwargs['verbosity'] > 0: if kwargs['verbosity'] > 0:
self.stdout.write(f"Add {user} to superusers...") self.stdout.write(f"Add {user} to superusers")
user.is_superuser = True user.is_superuser = True
user.save() user.save()

View File

@ -2,14 +2,14 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import os import os
from bs4 import BeautifulSoup
from django.core.management import BaseCommand
from django.urls import reverse
from django.utils import timezone
from urllib.parse import urlencode from urllib.parse import urlencode
from urllib.request import Request, urlopen from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
from activity.models import Activity from activity.models import Activity
from django.core.management import BaseCommand
from django.urls import reverse
from django.utils import timezone
class Command(BaseCommand): class Command(BaseCommand):

View File

@ -6,7 +6,6 @@ from datetime import timedelta
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.db.models import Count from django.db.models import Count
from django.utils import timezone from django.utils import timezone
from note.models import RecurrentTransaction, TransactionTemplate from note.models import RecurrentTransaction, TransactionTemplate

View File

@ -8,8 +8,7 @@ from django.core.management import BaseCommand
from django.db.models import Q from django.db.models import Q
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils.translation import activate from django.utils.translation import activate
from note.models import Note
from note.models import NoteUser, Note
class Command(BaseCommand): class Command(BaseCommand):

View File

@ -1,14 +1,11 @@
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay # Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from datetime import timedelta
from django.core.management import BaseCommand from django.core.management import BaseCommand
from django.db.models import Q from django.db.models import Q
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils import timezone from django.utils import timezone
from django.utils.translation import activate from django.utils.translation import activate
from note.models import NoteUser, Transaction from note.models import NoteUser, Transaction
from note.tables import HistoryTable from note.tables import HistoryTable

View File

@ -1,11 +1,9 @@
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay # Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.core.management.base import BaseCommand
from django.apps import apps from django.apps import apps
from django.core.management.base import BaseCommand
from django.db import connection from django.db import connection
from polymorphic.models import PolymorphicModel from polymorphic.models import PolymorphicModel
NO_SEQ = [ NO_SEQ = [
@ -14,6 +12,7 @@ NO_SEQ = [
"WEIRole", # dirty fix "WEIRole", # dirty fix
] ]
class Command(BaseCommand): class Command(BaseCommand):
""" """
Command to synchronise primary sequence of postgres after bulk insert of django. Command to synchronise primary sequence of postgres after bulk insert of django.