Skip to content
Commits on Source (12)
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import date
from django.contrib.auth.models import User
from django.core.management import BaseCommand
from django.db.models import Q
from member.models import Membership, Club
from wei.models import WEIClub
class Command(BaseCommand):
help = "Get mailing list registrations from the last wei. " \
"Usage: manage.py extract_ml_registrations -t {events,art,sport} -t {fr, en}. " \
"You can write this into a file with a pipe, then paste the document into your mail manager."
def add_arguments(self, parser):
parser.add_argument('--type', '-t', choices=["members", "clubs", "events", "art", "sport"], default="members",
help='Select the type of the mailing list (default members)')
parser.add_argument('--lang', '-l', type=str, choices=['fr', 'en'], default='fr',
help='Select the registred users of the ML of the given language. Useful only for the '
'events mailing list.')
def handle(self, *args, **options):
# TODO: Improve the mailing list extraction system, and link it automatically with Mailman.
if options["type"] == "members":
for membership in Membership.objects.filter(
club__name="BDE",
date_start__lte=date.today(),
date_end__gte=date.today(),
).all():
self.stdout.write(membership.user.email)
return
if options["type"] == "clubs":
for club in Club.objects.all():
self.stdout.write(club.email)
return
# Get the list of mails that want to be registered to the events mailing list.
# Don't filter to valid members, old members can receive these mails as long as they want.
if options["type"] == "events":
for user in User.objects.filter(profile__ml_events_registration=options["lang"]).all():
self.stdout.write(user.email)
return
if options["type"] == "art":
for user in User.objects.filter(profile__ml_art_registration=True).all():
self.stdout.write(user.email)
return
if options["type"] == "sport":
for user in User.objects.filter(profile__ml_sport_registration=True).all():
self.stdout.write(user.email)
return
......@@ -94,7 +94,7 @@ class Command(ImportCommand):
# clean pseudo (normalized pseudo must be unique and not empty)
if not pseudo_norm or pseudo_norm in ALIAS_SET:
pseudo = pseudo + str(row["idbde"])
CHANGED_USERNAMES.append((pk_note, row[pseudo], pseudo))
CHANGED_USERNAMES.append((pk_note, row["idbde"], pseudo))
else:
ALIAS_SET.add(pseudo_norm)
# clean date
......@@ -138,7 +138,7 @@ class Command(ImportCommand):
"registration_valid": True,
"email_confirmed": True,
"promotion": MAP_IDBDE_PROMOTION[row["idbde"]]["promo"],
"report_frequency": row["report_period"],
"report_frequency": max(row["report_period"], 0),
"last_report": make_aware(row["previous_report_date"]),
}
note_dict["created_at"] = make_aware(MAP_IDBDE_PROMOTION[row["idbde"]]["created_at"])
......@@ -246,20 +246,7 @@ class Command(ImportCommand):
filename = kwargs["save"]
with open(filename, 'w') as fp:
json.dump(MAP_IDBDE, fp, sort_keys=True, indent=2)
for pk_user, old_username, new_username in CHANGED_USERNAMES:
user = User.objects.get(pk_user)
mail_text = render_to_string("scripts/unsupported_username.txt", dict(
user=user,
old_username=old_username,
new_username=new_username,
))
user.email_user("Transition à la Note Kfet 2020 : pseudo non supporté", mail_text)
for pk_user, aliases_list in CHANGED_USERNAMES:
user = User.objects.get(pk_user)
mail_text = render_to_string("scripts/deleted_aliases.txt", dict(
user=user,
aliases_list=aliases_list,
))
user.email_user("Transition à la Note Kfet 2020 : suppression d'alias", mail_text)
with open(filename + ".changed-usernames", 'w') as fp:
json.dump(CHANGED_USERNAMES, fp, sort_keys=True, indent=2)
with open(filename + ".removed-aliases", 'w') as fp:
json.dump(LOST_ALIASES, fp, sort_keys=True, indent=2)
......@@ -214,7 +214,7 @@ class Command(ImportCommand):
"amount": row["montant"],
"created_at": date,
"destination_alias": "",
"invalidity_reason": None,
"invalidity_reason": "",
"quantity": row["quantite"],
"reason": row["description"],
"source_alias": "",
......
......@@ -13,7 +13,7 @@ from activity.models import Activity
class Command(BaseCommand):
acl_header = "#acl NoteKfet2015:read,write,admin NoteKfet2020:read,write,admin All:read Default\n"
acl_header = "#acl NoteKfet2020:read,write,admin All:read Default\n"
warning_header = """## NE PAS ÉDITER CETTE PAGE MANUELLEMENT
## ELLE EST GÉNÉRÉE AUTOMATIQUEMENT PAR LA NOTE KFET 2020
......@@ -24,7 +24,7 @@ class Command(BaseCommand):
* Ne pas éditer cette page manuellement, toute modification sera annulée automatiquement.
* Pour annoncer un nouvel événement, rendez-vous sur {activities_url}
""".format(activities_url="https://" + os.getenv("NOTE_URL") + reverse("activity:activity_list"))
""".format(activities_url="https://" + os.getenv("NOTE_URL", "") + reverse("activity:activity_list"))
@staticmethod
def connection(url):
......@@ -100,7 +100,7 @@ class Command(BaseCommand):
title=act.name,
start=timezone.localtime(act.date_start).strftime("%Y-%m-%d %H:%M"),
end=timezone.localtime(act.date_end).strftime("%Y-%m-%d %H:%M"),
description=act.description,
description=act.description.replace("\r", "").replace("\n", "<<BR>>"),
club=act.organizer.name,
location=act.location,
)
......@@ -108,7 +108,7 @@ class Command(BaseCommand):
return "|| {start} || {title} || {description} || {club} || {location} ||".format(
title=act.name,
start=timezone.localtime(act.date_start).strftime("%d/%m/%Y"),
description=act.description,
description=act.description.replace("\r", "").replace("\n", "<<BR>>"),
club=act.organizer.name,
location=act.location,
)
......@@ -150,30 +150,31 @@ class Command(BaseCommand):
return page, header + body
@staticmethod
def refresh_raw_wiki_page(comment="refresh", debug=True):
def refresh_raw_wiki_page(comment="refresh", print_stdout=False, edit_wiki=False):
page, content = Command.get_raw_page()
if debug:
if print_stdout:
print(content)
else:
if edit_wiki:
Command.edit_wiki(page, content, comment)
@staticmethod
def refresh_human_readable_wiki_page(comment="refresh", debug=True):
def refresh_human_readable_wiki_page(comment="refresh", print_stdout=False, edit_wiki=False):
page, content = Command.get_human_readable_page()
if debug:
if print_stdout:
print(content)
else:
if edit_wiki:
Command.edit_wiki(page, content, comment)
def add_arguments(self, parser):
parser.add_argument("--human", "-H", action="store_true", help="Save human readable page")
parser.add_argument("--raw", "-r", action="store_true", help="Save raw page, for the calendar")
parser.add_argument("--comment", "-c", action="store", type=str, default="", help="Comment of the modification")
parser.add_argument("--debug", "-d", action="store_true", help="Don't commit to the wiki, render in stdout")
parser.add_argument("--stdout", "-o", action="store_true", help="Render the wiki page in stdout")
parser.add_argument("--wiki", "-w", action="store_true", help="Send modifications to the wiki")
def handle(self, *args, **options):
if options["raw"]:
Command.refresh_raw_wiki_page(options["comment"], options["debug"])
Command.refresh_raw_wiki_page(options["comment"], options["stdout"], options["wiki"])
if options["human"]:
Command.refresh_human_readable_wiki_page(options["comment"], options["debug"])
Command.refresh_human_readable_wiki_page(options["comment"], options["stdout"], options["wiki"])
......@@ -14,12 +14,19 @@ from note.tables import HistoryTable
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('--notes', '-n', type=int, nargs='+', help='Select note ids')
parser.add_argument('--debug', '-d', action='store_true', help='Debug mode, print mails in stdout')
def handle(self, *args, **options):
activate('fr')
notes = NoteUser.objects.filter(
user__memberships__date_end__gte=timezone.now(),
user__profile__report_frequency__gt=0,
).distinct().all()
if "notes" in options:
notes = NoteUser.objects.filter(pk__in=options["notes"]).all()
else:
notes = NoteUser.objects.filter(
user__memberships__date_end__gte=timezone.now(),
user__profile__report_frequency__gt=0,
).distinct().all()
for note in notes:
now = timezone.now()
last_report = note.user.profile.last_report
......@@ -41,11 +48,16 @@ class Command(BaseCommand):
context = dict(
user=note.user,
table=table,
last_transactions=last_transactions,
incoming=incoming,
outcoming=outcoming,
diff=incoming - outcoming,
now=now,
last_report=last_report,
)
plain = render_to_string("note/mails/weekly_report.txt", context)
html = render_to_string("note/mails/weekly_report.html", context)
note.user.email_user("[Note Kfet] Rapport de la Note Kfet", html, html_message=html)
if options["debug"]:
self.stdout.write(plain)
else:
note.user.email_user("[Note Kfet] Rapport de la Note Kfet", plain, html_message=html)
#!/bin/bash
# Create backups directory
[[ -d /var/www/note_kfet/backups ]] || (mkdir /var/www/note_kfet/backups && chown www-data:www-data /var/www/note_kfet/backups)
# Create temporary backups directory
[[ -d /tmp/note-backups ]] || mkdir /tmp/note-backups
date=$(date +%Y-%m-%d)
# Backup database and save it as tar archive
su postgres -c "pg_dump -F t note_db" | tee "/var/www/note_kfet/backups/$date.tar" > /dev/null
su postgres -c "pg_dump -F t note_db" | tee "/tmp/note-backups/$date.tar" > /dev/null
# Compress backup as gzip
gzip "/var/www/note_kfet/backups/$date.tar"
chown www-data:www-data "/var/www/note_kfet/backups/$date.tar.gz"
# Delete backups that have more than 30 days
find /var/www/note_kfet/backups -type f -mtime +30 -exec rm {} \;
\ No newline at end of file
gzip "/tmp/note-backups/$date.tar"
scp "/tmp/note-backups/$date.tar.gz" "club-bde@zamok.crans.org:backup/$date.tar.gz"
......@@ -3,7 +3,7 @@
if [ -r Dockerfile ]; then
if [ -w /var/run/docker.sock ]; then
docker build -t nk20 .
docker run -it --rm -v "$(pwd):/var/www/note_kfet/" -p 80:8080 nk20 bash
docker run -it -u $(id -u):$(id -g) --rm -v "$(pwd):/var/www/note_kfet/" -p 80:8080 nk20 bash
else
echo "Merci de rejoindre le groupe docker (ou lancez ce script en sudo) afin de pouvoir vous connecter au socket Docker."
fi
......
......@@ -3,7 +3,5 @@ sudo service postgresql stop
sudo service postgresql start
sudo -u postgres sh -c "dropdb note_db && psql -c 'CREATE DATABASE note_db OWNER note;'";
echo 'reset db';
find apps/ -path "*/migrations/*.py*" -not -name "__init__.py" -delete
./manage.py makemigrations
./manage.py migrate
./manage.py loaddata initial