1
0
mirror of https://gitlab.crans.org/mediatek/med.git synced 2025-07-09 22:50:20 +02:00

Compare commits

..

8 Commits

8 changed files with 130 additions and 64 deletions

View File

@ -167,22 +167,26 @@ PAGINATION_NUMBER = 25
AUTH_USER_MODEL = 'users.User' AUTH_USER_MODEL = 'users.User'
# AUTHLIB CLIENTS NOTE_KFET_URL = 'https://note.crans.org'
AUTHLIB_OAUTH_CLIENTS = { NOTE_KFET_CLIENT_ID = 'CHANGE_ME'
'notekfet': { NOTE_KFET_CLIENT_SECRET = 'CHANGE_ME'
'client_id': 'qtElmOUj67YNvSZjA5l70ITUMxd3NJ9kksBsK5e9', NOTE_KFET_SCOPES = '1_1 2_1 48_1'
'client_secret': 'SwF909sLIeU5GhruXsFzKfdBhFNgs8nvkVpFKgP4pIQ80BmLLlf3ZkMoNL7Cpox6Ke3MXNWGswTtbKkM8AiB9v6pys8PNfYH0MDFWAi3tnffjwaMQBzRFhjx20qb6S4W',
'access_token_url': 'https://note-dev.crans.org/o/token/',
'refresh_token_url': 'https://note-dev.crans.org/o/token/',
'authorize_url': 'https://note-dev.crans.org/o/authorize/',
'userinfo_endpoint': 'https://note-dev.crans.org/api/me/',
'client_kwargs': {
'scope': '1_1 2_1 48_1',
}
}
}
try: try:
from .settings_local import * from .settings_local import *
except ImportError: except ImportError:
pass pass
AUTHLIB_OAUTH_CLIENTS = {
'notekfet': {
'client_id': f'{NOTE_KFET_CLIENT_ID}',
'client_secret': f'{NOTE_KFET_CLIENT_SECRET}',
'access_token_url': f'{NOTE_KFET_URL}/o/token/',
'refresh_token_url': f'{NOTE_KFET_URL}/o/token/',
'authorize_url': f'{NOTE_KFET_URL}/o/authorize/',
'userinfo_endpoint': f'{NOTE_KFET_URL}/api/me/',
'client_kwargs': {
'scope': NOTE_KFET_SCOPES,
}
}
}

View File

@ -40,3 +40,8 @@ DATABASES = {
'PORT': '', 'PORT': '',
} }
} }
NOTE_KFET_URL = 'https://note.crans.org'
NOTE_KFET_CLIENT_ID = 'CHANGE_ME'
NOTE_KFET_CLIENT_SECRET = 'CHANGE_ME'
NOTE_KFET_SCOPES = '1_1 2_1 48_1'

View File

@ -142,8 +142,8 @@ class BorrowAdmin(VersionAdmin):
class GameAdmin(VersionAdmin, PolymorphicChildModelAdmin): class GameAdmin(VersionAdmin, PolymorphicChildModelAdmin):
list_display = ('title', 'owner', 'duration', 'players_min', list_display = ('title', 'owner', 'duration', 'players_min',
'players_max', 'comment') 'players_max', 'comment', 'isbn')
search_fields = ('name', 'owner__username', 'duration', 'comment') search_fields = ('isbn', 'title', 'owner__username', 'duration', 'comment')
autocomplete_fields = ('owner',) autocomplete_fields = ('owner',)
show_in_index = True show_in_index = True

View File

@ -1,4 +1,7 @@
import os.path
from django.core.management import BaseCommand from django.core.management import BaseCommand
from media.models import Comic, CD, Manga, Review, Novel, Vinyl, Game from media.models import Comic, CD, Manga, Review, Novel, Vinyl, Game
@ -13,18 +16,18 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
directory = options["directory"] directory = options["directory"]
with open(directory + "/docs/index.md", "w") as f: with open(os.path.join(directory, 'docs', 'index.md'), "w") as f:
f.write("# Media de la Mediatek\n\n\n") f.write("# Media de la Mediatek\n\n\n")
f.write("Ce site répertorie l'intégralité des media présents " f.write("Ce site répertorie l'intégralité des media présents "
"à la Mediatek de l'ENS Paris-Saclay.\n") "à la Mediatek de l'ENS Paris-Saclay.\n")
for model_class, file_name in [(Comic, "bd.md"), (Manga, "mangas.md"), for model_class, file_name in [(Manga, "mangas.md"),
(Novel, "romans.md"), (Novel, "romans.md"),
(CD, "cd.md"), (Vinyl, "vinyles.md")]: (CD, "cd.md"), (Vinyl, "vinyles.md")]:
self.process_model_class(model_class, file_name, f, directory) self.process_model_class(model_class, file_name, f, directory)
# Traitement différent pour les revues # Traitement différent pour les revues
with open(directory + "/docs/revues.md", "w") as f: with open(os.path.join(directory, 'docs', 'revues.md'), "w") as f:
f.write("# Revues\n\n\n") f.write("# Revues\n\n\n")
titles = list(set(obj["title"] for obj in titles = list(set(obj["title"] for obj in
@ -48,11 +51,13 @@ class Command(BaseCommand):
f.write("\n\n\n") f.write("\n\n\n")
# Traitement différent pour les jeux # Traitement différent pour les jeux
with open(directory + "/docs/jeux.md", "w") as f: with open(os.path.join(directory, 'docs', 'jeux.md'), "w") as f:
f.write("# Jeux\n\n\n") f.write("# Jeux\n\n\n")
for game in Game.objects.order_by("name").all(): for game in Game.objects.order_by("title").all():
f.write(f"## {game.name}\n\n\n") f.write(f"## {game.title}\n\n\n")
if hasattr(medium, "isbn"):
f.write(f"ISBN : {game.isbn}\n\n")
f.write(f"Durée : {game.duration}\n\n") f.write(f"Durée : {game.duration}\n\n")
f.write(f"Nombre de joueurs : {game.players_min} " f.write(f"Nombre de joueurs : {game.players_min} "
f"- {game.players_max}\n\n") f"- {game.players_max}\n\n")
@ -62,8 +67,54 @@ class Command(BaseCommand):
f.write(f"Commentaire : {game.comment}\n\n") f.write(f"Commentaire : {game.comment}\n\n")
f.write("\n\n\n") f.write("\n\n\n")
# Traitement différent pour les bds
# Regroupement par le premier caractère
titles = list(set(obj["title"] for obj in Comic.objects
.values("title").distinct().all()))
category = lambda s: s[0].lower() if 'a' <= s[0].lower() <= 'z' else '#'
db = {}
for title in titles:
c = category(title)
if c not in db:
db[c] = []
db[c].append(title)
for letter, titles in db.items():
with open(os.path.join(directory, 'docs', 'bds', f'{letter}.md'), 'w') as f:
f.write("# " + str(Comic._meta.verbose_name_plural)
.capitalize() + f" - {letter.upper()}\n\n\n")
titles.sort()
for title in titles:
f.write(f"## {title}\n\n\n")
for medium in Comic.objects.filter(title=title) \
.order_by("side_identifier").all():
if hasattr(medium, "subtitle"):
f.write(f"### {medium.subtitle}\n\n\n")
if hasattr(medium, "isbn"):
f.write(f"ISBN : {medium.isbn}\n\n")
f.write(f"Cote : {medium.side_identifier}\n\n")
f.write("Auteurs : " + ", ".join(
author.name for author in medium.authors.all())
+ "\n\n")
if hasattr(medium, "number_of_pages"):
f.write(f"Nombre de pages : "
f"{medium.number_of_pages}\n\n")
if hasattr(medium, "rpm"):
f.write(f"Tours par minute : "
f"{medium.rpm}\n\n")
if hasattr(medium, "publish_date"):
f.write(f"Publié le : "
f"{medium.publish_date}\n\n")
if hasattr(medium, "external_url"):
f.write(f"Lien : [{medium.external_url}]"
f"({medium.external_url})\n\n")
f.write("\n\n\n")
def process_model_class(self, model_class, file_name, f, directory): def process_model_class(self, model_class, file_name, f, directory):
with open(directory + "/docs/" + file_name, "w") as f: with open(os.path.join(directory, 'docs', file_name), "w") as f:
f.write("# " + str(model_class._meta.verbose_name_plural) f.write("# " + str(model_class._meta.verbose_name_plural)
.capitalize() + "\n\n\n") .capitalize() + "\n\n\n")

View File

@ -3,11 +3,9 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import admin from django.contrib import admin
from django.contrib import messages
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import PasswordResetForm from django.utils import timezone
from django.urls import reverse from django.utils.safestring import mark_safe
from django.utils.html import format_html
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from med.admin import admin_site from med.admin import admin_site
@ -25,7 +23,12 @@ class IsMemberFilter(admin.SimpleListFilter):
) )
def queryset(self, request, queryset): def queryset(self, request, queryset):
# FIXME Replace with imported Note Kfet memberships if self.parameter_name in request.GET:
queryset = queryset.filter(
membership__date_start__lte=timezone.now(),
membership__date_end__gte=timezone.now(),
).distinct()
return queryset return queryset
@ -45,39 +48,21 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
list_filter = (IsMemberFilter, 'is_staff', 'is_superuser', 'is_active', list_filter = (IsMemberFilter, 'is_staff', 'is_superuser', 'is_active',
'groups') 'groups')
def save_model(self, request, obj, form, change): def has_add_permission(self, request):
""" # Only add users through Note Kfet login
On creation, send a password init mail return False
"""
super().save_model(request, obj, form, change)
if not change:
# Virtually fill the password reset form
password_reset = PasswordResetForm(data={'email': obj.email})
if password_reset.is_valid():
password_reset.save(request=request,
use_https=request.is_secure())
messages.success(request, _("An email to set the password"
" was sent."))
else:
messages.error(request, _("The email is invalid."))
def is_member(self, obj): def is_member(self, obj):
""" """
Get current membership year and check if user is there Get current membership year and check if user is there
""" """
# FIXME Use NK20 if obj.is_member:
is_member = True return mark_safe(
if is_member:
return format_html(
'<img src="/static/admin/img/icon-yes.svg" alt="True">' '<img src="/static/admin/img/icon-yes.svg" alt="True">'
) )
else: else:
return format_html( return mark_safe(
'<img src="/static/admin/img/icon-no.svg" alt="False"> ' '<img src="/static/admin/img/icon-no.svg" alt="False">'
'<a class="button" href="{}">{}</a>',
reverse('users:adherer', args=[obj.pk]),
_('Adhere')
) )
is_member.short_description = _('is member') is_member.short_description = _('is member')

View File

@ -17,7 +17,7 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('access_token', models.CharField(max_length=32, verbose_name='access token')), ('access_token', models.CharField(max_length=32, verbose_name='access token')),
('expires_in', models.PositiveSmallIntegerField(verbose_name='expires in')), ('expires_in', models.PositiveIntegerField(verbose_name='expires in')),
('scopes', models.CharField(max_length=255, verbose_name='scopes')), ('scopes', models.CharField(max_length=255, verbose_name='scopes')),
('refresh_token', models.CharField(max_length=32, verbose_name='refresh token')), ('refresh_token', models.CharField(max_length=32, verbose_name='refresh token')),
('expires_at', models.DateTimeField(verbose_name='expires at')), ('expires_at', models.DateTimeField(verbose_name='expires at')),

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2.24 on 2021-11-14 15:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0045_auto_20211114_1423'),
]
operations = [
migrations.AlterField(
model_name='membership',
name='date_end',
field=models.DateField(verbose_name='start date'),
),
migrations.AlterField(
model_name='membership',
name='date_start',
field=models.DateField(verbose_name='start date'),
),
]

View File

@ -59,12 +59,12 @@ class User(AbstractUser):
data : dict data : dict
Dictionary with user data to update. Dictionary with user data to update.
""" """
self.email = data['email'] self.email = data['email'] or ''
self.first_name = data['first_name'] self.first_name = data['first_name'] or ''
self.last_name = data['last_name'] self.last_name = data['last_name'] or ''
self.phone_number = data['profile']['phone_number'] self.phone_number = data['profile']['phone_number'] or ''
self.address = data['profile']['address'] self.address = data['profile']['address'] or ''
self.comment = data['profile']['section'] self.comment = data['profile']['section'] or ''
for membership_dict in data['memberships']: for membership_dict in data['memberships']:
if membership_dict['club'] != 22: # Med if membership_dict['club'] != 22: # Med
@ -88,12 +88,10 @@ class Membership(models.Model):
) )
date_start = models.DateField( date_start = models.DateField(
auto_now_add=True,
verbose_name=_('start date'), verbose_name=_('start date'),
) )
date_end = models.DateField( date_end = models.DateField(
auto_now_add=True,
verbose_name=_('start date'), verbose_name=_('start date'),
) )
@ -119,7 +117,7 @@ class AccessToken(models.Model):
verbose_name=_('access token'), verbose_name=_('access token'),
) )
expires_in = models.PositiveSmallIntegerField( expires_in = models.PositiveIntegerField(
verbose_name=_('expires in'), verbose_name=_('expires in'),
) )
@ -178,7 +176,7 @@ class AccessToken(models.Model):
Extract information about the Note Kfet API by using the current Extract information about the Note Kfet API by using the current
access token. access token.
""" """
data = requests.get('https://note-dev.crans.org/api/me/', data = requests.get(f'{settings.NOTE_KFET_URL}/api/me/',
headers=self.auth_header()).json() headers=self.auth_header()).json()
username = data['username'] username = data['username']
email = data['email'] email = data['email']