mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-09 19:40:19 +00:00
move old pdf to the repo github wiki
This commit is contained in:
Binary file not shown.
1
docs/archives/TO_Skia_LoJ/.gitignore
vendored
1
docs/archives/TO_Skia_LoJ/.gitignore
vendored
@ -1 +0,0 @@
|
||||
_minted-Rapport/
|
Binary file not shown.
Binary file not shown.
@ -1,13 +0,0 @@
|
||||
CC=pdflatex
|
||||
|
||||
all: rapport clean
|
||||
|
||||
rapport: Rapport.tex
|
||||
@echo "Compiling "$<
|
||||
$(CC) -shell-escape $<
|
||||
$(CC) -shell-escape $<
|
||||
|
||||
clean:
|
||||
@echo "Cleaning folder"
|
||||
rm *.aux; rm *.log; rm *.out; rm *.toc; rm *.snm; rm *.nav; rm *.lof
|
||||
|
Binary file not shown.
@ -1,490 +0,0 @@
|
||||
%%
|
||||
%
|
||||
% Skia
|
||||
% skia@libskia.so
|
||||
%
|
||||
%%
|
||||
|
||||
\documentclass[a4paper]{report}
|
||||
|
||||
%packages
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[francais]{babel}
|
||||
\usepackage{graphicx}\graphicspath{{pix/}}
|
||||
\usepackage{float}
|
||||
\usepackage{scrextend}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{color}
|
||||
\usepackage{fancyhdr}
|
||||
%Options: Sonny, Lenny, Glenn, Conny, Rejne, Bjarne, Bjornstrup
|
||||
\usepackage[Bjornstrup]{fncychap}
|
||||
\usepackage{minted}
|
||||
\usepackage[colorlinks=true,linkcolor=black]{hyperref}
|
||||
\usepackage{pdfpages}
|
||||
%\usepackage{titlesec, blindtext, color}
|
||||
|
||||
%pdf metadata
|
||||
\hypersetup{
|
||||
unicode=true,
|
||||
colorlinks=true,
|
||||
citecolor=black,
|
||||
filecolor=black,
|
||||
linkcolor=black,
|
||||
urlcolor=black,
|
||||
pdfauthor={Skia <skia@libskia.so>},
|
||||
pdftitle={},
|
||||
pdfcreator={pdftex},
|
||||
pdfsubject={},
|
||||
pdfkeywords={},
|
||||
}
|
||||
|
||||
|
||||
\definecolor{keywords}{RGB}{200,0,90}
|
||||
\definecolor{comments}{RGB}{50,50,253}
|
||||
\definecolor{red}{RGB}{160,0,0}
|
||||
\definecolor{brown}{RGB}{160,100,100}
|
||||
\definecolor{green}{RGB}{0,200,0}
|
||||
\definecolor{darkgreen}{RGB}{0,130,0}
|
||||
\definecolor{gray}{RGB}{100,100,100}
|
||||
|
||||
|
||||
%inner meta
|
||||
\title{Sith: Développement de nouvelles applications}
|
||||
\author{Florent \textsc{Jacquet}\\
|
||||
Guillaume \textsc{Renaud}}
|
||||
\date{Dernière version: \today}
|
||||
|
||||
\begin{document}
|
||||
|
||||
% \maketitle
|
||||
\includepdf[pages={1}]{Couvertures.pdf}
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\chapter*{Remerciements}
|
||||
\section*{Guillaume \textsc{Renaud}}
|
||||
\par Je remercie tout d'abord Monsieur Frédéric \textsc{Lassabe} qui nous a permis d'effectuer cette TO52 lors de notre cursus à
|
||||
l'UTBM, nous permettant ainsi de mêler nôtre travail scolaire à nôtre envie de participer à l'amélioration de la vie
|
||||
associative de l'UTBM.
|
||||
|
||||
\par Je tiens aussi à remercier Florent \textsc{Jacquet} qui m'a aidé tout au long de ce travail et à qui j'ai pu poser mes
|
||||
différentes questions pour apprendre et comprendre plus rapidement que si j'avais été seul.
|
||||
|
||||
\section*{Florent \textsc{Jacquet}}
|
||||
\par Je remercie également Frédéric \textsc{Lassabe} , non seulement pour la TO, mais également pour la précédente TW. Sans ces
|
||||
deux UV hors emploi du temps, jamais un projet comme ce site de l'AE n'aurait pu voir le jour. Cela a demandé beaucoup
|
||||
d'investissement, et il est plus qu'appréciable de pouvoir obtenir quelques crédits en retour.
|
||||
|
||||
\par Je tiens également à remercier l'ensemble de l'équipe info de l'AE qui s'est motivée ce semestre à organiser des
|
||||
réunions hebdomadaires afin de reprendre le projet du mieux possible. C'est maintenant à eux que va être confié le
|
||||
projet, et il est agréable de constater qu'ils n'ont pas attendu le dernier moment pour se pencher sur la question.
|
||||
|
||||
|
||||
\chapter*{Introduction}
|
||||
\addcontentsline{toc}{chapter}{Introduction}
|
||||
\par Après le développement de la base du nouveau site de l'AE, le projet \emph{Sith}, au Printemps 2016, la mise en
|
||||
production a pu avoir lieu avec succès fin Août 2016.
|
||||
|
||||
\par Mais le site était encore très incomplet, et il était nécessaire d'y ajouter un grand nombre de fonctionnalités
|
||||
moins critiques, celles-ci n'ayant pas de rapport avec l'argent, mais tout de même très utiles pour le fonctionnement
|
||||
de l'AE.
|
||||
|
||||
\par Parmis elles, se trouvait notamment une application de gestion des stocks, qui a été confiée à Guillaume, puisqu'elle
|
||||
concernait en premier lieu le \emph{Bureau des Festivités} et qu'il en était le président. Il était donc parmis les
|
||||
mieux placé pour évaluer le besoin et développer l'outil, d'autant qu'il fallait le concevoir depuis le début, ces
|
||||
fonctions n'étant pas du tout présentes dans l'ancien site.
|
||||
|
||||
\par Du reste, Florent a eu la responsabilité de développer les autres applications, ou bien de gérer leur développement
|
||||
lors qu'il était fait par quelqu'un d'autre.
|
||||
|
||||
\chapter{Eboutic}
|
||||
\label{sec:eboutic}
|
||||
\par Développeur principal: Florent
|
||||
|
||||
\section{But}
|
||||
\label{sub:but}
|
||||
\par Fournir une boutique en ligne, avec paiement sécurisé, compatible avec l'API de paiement du Crédit Agricole.
|
||||
\begin{itemize}
|
||||
\item Gérer les cotisations
|
||||
\item Gérer les rechargements de compte AE
|
||||
\item Gérer différents groupes de vente
|
||||
\end{itemize}
|
||||
|
||||
\section{Principaux problèmes}
|
||||
\label{sec:principaux_problemes}
|
||||
|
||||
\subsection{Interaction avec l'API}
|
||||
\label{sub:interaction_avec_l_api}
|
||||
\par C'est la principale contrainte de cette application. On doit interagir avec les serveurs du Crédit Agricole, et
|
||||
pour cela, ces derniers n'aident pas beaucoup.
|
||||
|
||||
\par Ils fournissent un PDF peu clair\footnote{disponible dans le dossier \url{doc/Etransaction/} des sources du site}
|
||||
expliquant l'implémentation d'un site marchand, en plus des nombreux autres PDF de documentation disponibles à l'adresse
|
||||
\url{https://e-transactions.avem-groupe.com/pages/global.php?page=telechargement}.
|
||||
|
||||
\par Une implémentation de référence uniquement en PHP, et contenant que peut de fonctionnalités par rapport à ce
|
||||
que dit le PDF peut aussi être obtenue, mais n'est guère utile excepté pour la vérification cryptographique de la
|
||||
signature de la réponse. Mais encore, il faut arriver à traduire les fonctions propres à PHP, et ce n'est pas toujours
|
||||
une mince affaire, mais fort heureusement, les algorithmes sont encore assez standards et l'on trouve vite de l'aide
|
||||
quant à ces fonctions.
|
||||
|
||||
\par De plus, certaines informations concernants les numéros d'identification de marchand son incohérents
|
||||
d'une documentation à l'autre, et le plus simple à ce niveau est encore de contacter le support.
|
||||
|
||||
\subsection{Accès concurrentiels}
|
||||
\label{sub:acces_concurrentiels}
|
||||
\par En production, le projet Sith tourne à l'aide d'\textbf{uWSGI}, qui s'occupe lui de gérer les différents processus du
|
||||
logiciel. Cela se traduit par des accès concurrentiels à la base de donnée lors de l'appel de deux pages simultanément
|
||||
qui ont besoin d'accèder aux mêmes ressources.
|
||||
|
||||
\par Le problème n'en est la plupart du temps pas un, mais il devient très critique lorsque la page appelée permet par
|
||||
exemple de recharger un compte AE. Il ne faut alors surtout faire l'opération en double.
|
||||
|
||||
\par Pour protéger ces accès en double, on peut alors utiliser des transactions, et \textbf{Django} fournit une
|
||||
abstraction très pratique: \verb-with transaction.atomic():-.
|
||||
|
||||
\par L'Eboutic, avec sa réponse de la banque, est très sujette à ces accès concurrents, et cela a posé quelques
|
||||
problèmes dans les débuts. La plupart ont été résolu, mais il arrive encore dans les comptoirs d'avoir une vente en
|
||||
double, sans pour autant avoir le débit du compte qui soit doublé. Cela ne pose pas foncièrement de problèmes, puisque
|
||||
le solde du compte est tout de même valide, et c'est un problème très compliqué à debugger, puisqu'il survient très
|
||||
rarement, mais il faudrait tout de même arriver à le résoudre un jour.
|
||||
|
||||
|
||||
\chapter{Le SAS}
|
||||
\label{sec:le_sas}
|
||||
\par Développeur principal: Florent
|
||||
|
||||
\section{But}
|
||||
\label{sub:but}
|
||||
\par Fournir un système de galerie de photo:
|
||||
\begin{itemize}
|
||||
\item Upload en ligne via un formulaire pour tous les cotisants.
|
||||
\item Modération pour l'équipe du SAS.
|
||||
\item Système d'identification des membres pour retrouver rapidement ses photos.
|
||||
\item Affichage des photos dans les différents album et sur la page "photo" du profil d'un utilisateur.
|
||||
\end{itemize}
|
||||
|
||||
\section{Principaux problèmes}
|
||||
\label{sec:principaux_problemes}
|
||||
|
||||
\subsection{Gestion des fichiers}
|
||||
\label{sub:gestion_des_fichiers}
|
||||
\par L'envoie en grande quantité de photos nécéssite une gestion des fichiers solide, en même temps qu'un formulaire
|
||||
d'envoie efficace, capable d'envoyer plusieurs dizaines de photos en une seule action de l'utilisateur.
|
||||
|
||||
\par L'envoie est donc fait à l'aide de requêtes AJAX pour envoyer les photos une par une et éviter alors le timeout.
|
||||
|
||||
\par Concernant les fichiers une fois envoyé, ils sont en réalité traités par la classe \verb#SithFile# qui gère tous
|
||||
les fichiers du site. Cela ne fait qu'une seule classe à développer, de même qu'un seul système de fichier avec une
|
||||
seule arborescence, ce qui est beaucoup plus robuste.
|
||||
|
||||
\par La difficulté a aussi été de permettre le déplacement des fichiers, par couper-coller, tout en faisant de même dans
|
||||
le système de fichier réel, afin d'avoir une arborescence cohérente même en cas de perte de la base de données.
|
||||
|
||||
\subsection{Optimisation des pages}
|
||||
\label{sub:optimisation_des_pages}
|
||||
\par La génération d'un grand nombre de requêtes SQL est un des principaux problèmes de ralentissement d'un site. Le
|
||||
SAS, avec ses très nombreuses photos, qui requierent une validation des droits, a posé un gros problème à ce niveau.
|
||||
|
||||
\par Certaines pages ont pu mettre jusqu'à plus de 10 secondes à générer, ce qui est inconcevable pour une galerie de
|
||||
photos, mais ce temps à pu être réduit à moins de 3 secondes.
|
||||
|
||||
\par L'astuce à été d'utiliser des actions utilisateurs, comme l'upload de nouvelles photos, pour faire plus de
|
||||
traitement que nécessaire, afin de mettre en "cache" une grande partie des actions, comme par exemple la génération des
|
||||
miniatures des albums.
|
||||
|
||||
\par Une autre technique pour gagner du temps est de mettre en cache certaines requêtes en forcant les \emph{QuerySet}
|
||||
à s'évaluer dans une \emph{list} \textbf{Python} que l'on stocke afin d'obtenir sa longueur, au lieu de lancer d'abord
|
||||
un \emph{count}, puis une itération des résultats, qui en utilisant directement l'ORM, conduit à réaliser deux
|
||||
requêtes SQL.
|
||||
|
||||
\par Enfin, le passage à \textbf{HTTP/2} permettrait d'améliorer encore les performances côté utilisateur puisqu'il n'y
|
||||
aurait plus qu'un seul \emph{socket} d'ouvert pour transférer toutes les photos d'une page par exemple, sans avoir
|
||||
pour autant à toucher au code.
|
||||
|
||||
|
||||
\chapter{Les élections}
|
||||
\label{sec:les_elections}
|
||||
\par Développeur principal: Antoine
|
||||
|
||||
\section{But}
|
||||
\label{sub:but}
|
||||
\par Fournir un système d'élections:
|
||||
\begin{itemize}
|
||||
\item Gestion des différentes élections comprenants à chaque fois une liste de postes pour lesquels les gens
|
||||
candidatent, ainsi qu'une gestion des listes, pour pouvoir classifier et répartir les candidatures.
|
||||
\item Gestion d'une page de vote, permettant aux gens autorisés de pouvoir voter.
|
||||
\item Affichage des résultats une fois le vote terminé.
|
||||
\item Pas compatible avec la législation française: trop contraignant et pas utile, puisque validation officiel en
|
||||
AG.
|
||||
\end{itemize}
|
||||
|
||||
\section{Principaux problèmes}
|
||||
\label{sec:principaux_problemes}
|
||||
|
||||
\subsection{Automatisation d'un widget particulier pour les formulaires}
|
||||
\label{sub:automatisation_d_un_widget_particulier_pour_les_formulaires}
|
||||
\par La demande est venue du \textbf{BdF} qui a voulu autoriser pour certains poste un nombre de vote supérieur à 1.
|
||||
Cela signifie que l'on passe d'un choix simple, type \verb#radio# à un choix multiple, type \verb#checkbox#, tout cela
|
||||
étant paramètrable dans l'élection.
|
||||
|
||||
\par Ce genre de choix n'étant pas disponible dans \textbf{Django} de base, il a fallut développer le \emph{widget} à
|
||||
utiliser dans le formulaire qui permette cette configuration tout en validant bien les données reçues par rapport au
|
||||
modèle, et éviter ainsi de pouvoir "tricher" en envoyant des requêtes erronées.
|
||||
|
||||
\subsection{Revue du code d'un autre développeur}
|
||||
\label{sub:revue_du_code_d_un_autre_developpeur}
|
||||
\par \emph{Antoine} étant le principal développeur de cette application, un gros travail de revue de code a dû être
|
||||
effectuer afin de garantir une certaine cohérence avec le reste du projet.
|
||||
|
||||
\par C'est un travail très long et fastidieux, car il faut bien revérifier chaque ligne, sur chaque fichier, tout en
|
||||
faisant des commentaire lorsque quelque chose ne va pas. \textbf{Gitlab} a, à ce niveau, grandement facilité la tâche, à
|
||||
l'aide de ses outils de \emph{merge request} assez avancés.
|
||||
|
||||
\par En plus du code en lui-même, il a fallut porter une attention particulière aux migrations. Ces fichiers générés
|
||||
automatiquement par \textbf{Django} sont responsables du maintient d'une base de donnée cohérente malgré les évolutions
|
||||
des modèles. Même si le code parait donc valide, il est impératif de surveiller que la chaîne de dépendance des dites
|
||||
migrations ne soit pas cassée, au risque de problèmes potentiels au moment de la mise en production, ce qui entraînent à
|
||||
coup sûr un \emph{downtime}.
|
||||
|
||||
\chapter{Les stocks}
|
||||
\label{sub:les_stocks}
|
||||
\par Développeur principal: Guillaume
|
||||
\vskip 2em
|
||||
|
||||
\par Cette application s'occupe de la gestion des stocks des comptoirs de type « BAR ». Elle permet de suivre les
|
||||
quantités restantes afin de pouvoir déterminer de manière automatisée quels sont les produits qu'il faut acheter et en
|
||||
quelle quantité.
|
||||
|
||||
\section{Liste des modèles}
|
||||
\label{sec:liste_des_modeles}
|
||||
|
||||
\subsection{Stock}
|
||||
\par Un Stock possède un nom et est lié à la classe Counter. Ainsi, chaque Comptoir peut avoir son propre Stock.
|
||||
|
||||
\subsection{StockItem}
|
||||
\par Un StockItem possède un nom, une quantité unitaire, une quantité effective, une quantité minimale et est lié à la
|
||||
classe Stock ainsi qu'à la classe ProductType. De cette manière, chaque élément appartient à un Stock et il est
|
||||
catégorisé de la même manière que les Products (qui sont les objets utilisés pour la vente dans les comptoirs).
|
||||
|
||||
\subsection{ShoppingList}
|
||||
\par Une ShoppingList possède un nom, une date, un booléen (fait ou à faire), un commentaire et est liée à un Stock.
|
||||
Chaque ShoppingList est donc liée à un Stock ce qui permet d'avoir des listes de courses spécifique à chaque comptoir.
|
||||
|
||||
\subsection{ShoppingListItem}
|
||||
\par Un ShoppingListItem possède un nom, une quantité demandée, une quantité achetée et est lié à la classe StockItem, à
|
||||
la classe ShoppingList et à la classe ProductType. Cela permet de pouvoir faire plusieurs listes de courses différentes
|
||||
en même temps et d'en garder un historique.
|
||||
|
||||
\section{Fonctionnement}
|
||||
\label{sec:fonctionnement}
|
||||
|
||||
\par Au départ, si le comptoir de type « BAR » n'a pas de stock, la seule chose qu'il est possible de faire est d'en
|
||||
créer un. Ensuite, il va falloir créer les objets StockItem en indiquant pour chacun les quantités qu'il y a dans le
|
||||
stock.
|
||||
|
||||
\par De plus, la personne (généralement le Responsable du lieu de vie) qui aura la responsabilité d'informatiser les
|
||||
stocks devra aussi définir la quantité unitaire, effective et minimale.
|
||||
\par Par exemple, les Cheeseburger vendus aux différents comptoirs sont achetés par boite de 6, la quantité unitaire
|
||||
sera donc 6, la quantité effective correspondra au nombre de boites restantes dans le stock (c'est à dire dans la
|
||||
réserve du lieu de vie, une boite sortie du stock est considérée comme consommée) et enfin, la quantité minimale servira
|
||||
de valeur seuil.
|
||||
\par Une fois l'état de la réserve retranscrit dans le site, il reste encore gérer les stocks de manière quotidienne.
|
||||
Pour ce faire, l'application se décompose en 3 parties :
|
||||
\begin{itemize}
|
||||
\item Création automatique des listes de courses
|
||||
\item Approvisionnement du stock
|
||||
\item Prise d'éléments dans le stock
|
||||
\end{itemize}
|
||||
|
||||
\par Lorsque l'on accède à la partie qui s'occupe de la gestion des listes de courses, il y a un bouton permettant de
|
||||
créer une liste de courses en fonction de l'état des stocks à cet instant, puis un premier tableau contenant les listes
|
||||
de courses qu'il faut faire et enfin un second tableau servant d'historique des listes de courses déjà effectuées.
|
||||
\par Pour chaque liste de course ainsi créée, qu'elle soit « faite » ou « à faire », il est possible de cliquer sur son
|
||||
nom pour voir le détail de ce qu'elle comprend.
|
||||
|
||||
\subsection{Création automatique des listes de courses}
|
||||
\par En cliquant sur le bouton permettant de créer une nouvelle liste de courses, il faut remplir un formulaire. Les
|
||||
informations à donner dans ce formulaire sont le nom de la liste de course (par exemple, une liste spéciale pour
|
||||
Leclerc), ensuite, apparaissent tous les StockItem ayant une quantité effective inférieure au seuil fixé par leur
|
||||
quantité minimale. Il faut donc donner pour chacun de ces éléments une quantité à acheter. Enfin, un dernier champ de
|
||||
commentaire peut être compléter, il sert à demander l'achat d'éléments qui n'apparaissent pas dans le Stock, par
|
||||
exemple, des couteaux, fourchettes ou encore tasses...
|
||||
\par Lors de la validation de ce formulaire, la liste de courses est créée et est ajoutée au tableau contenant les
|
||||
listes de courses à faire.
|
||||
|
||||
\subsection{Approvisionnement du stock}
|
||||
\par Au retour des courses, il faut ranger les produits achetés dans la réserve. À ce moment-là, il faut aussi mettre à
|
||||
jour le stock. Une opération « Mettre à jour le stock » est disponible pour chaque liste de courses du tableau « À
|
||||
faire ».
|
||||
\par En effectuant cette action, il va falloir indiquer les quantités effectivement achetées. En effet, les quantités
|
||||
demandées ne sont pas forcément celles achetées, c'est donc les quantités effectives qu'il faut ajouter au stock. Une
|
||||
fois ce formulaire validé, la liste de couses passera de l'état « à faire » à l'état « faite ».
|
||||
|
||||
\subsection{Prise d'éléments dans le stock}
|
||||
\par La réserve étant accessible aux barmen afin qu'ils puissent réapprovisionner les réfrigérateurs à tout moment,
|
||||
l'interface permettant de prendre des éléments dans le stock a été ajoutée dans les onglets de l'interface des ventes
|
||||
(là où le barman inscrit le code du compte du client qui souhaite commander quelque chose). Ainsi, en revenant de la
|
||||
réserve, le barman doit indiquer le nombre de chaque produit qu'il a rapporté.
|
||||
\par Dans un souci de simplicité pour le gérant du lieu de vie, ce formulaire de prise des éléments dans le stock est
|
||||
aussi accessible depuis son interface de gestion.
|
||||
|
||||
|
||||
\section{Améliorations à apporter}
|
||||
\label{sec:amelioration_a_apporter}
|
||||
|
||||
\begin{itemize}
|
||||
\item Il n'est pas encore possible de modifier les quantités demandées pour un ou plusieurs des produits d'une liste
|
||||
de course. Il faudrait rendre cela possible car actuellement, il faut supprimer la liste de courses et la
|
||||
refaire en changeant les quantités souhaitées.
|
||||
\item Il faudrait améliorer la manière dont on ajoute les éléments non définis en tant que StockItem dans la liste
|
||||
de course. Un objet ShoppingListItem avec une référence « Null » vers la classe StockItem pourrait être créé à
|
||||
la place de compléter le champ de commentaires.
|
||||
\item Dans les améliorations sur le long terme, il faudrait que la décrémentation des quantités de chaque élément
|
||||
dans le stock soit automatique. En repensant une partie de l'architecture de l'application, on pourrait faire en
|
||||
sorte que chaque vente faite au comptoir face diminuer les quantités restantes (cela remplacerait le formulaire
|
||||
de « Prise d'éléments dans le stock », mais cela ne serait pas applicable à tous les produits mis en vente. Par
|
||||
exemple, pour les cacahuètes que nous vendons au bol et non par paquet)
|
||||
\item Avec le système de notifications qui a été mis en place sur le site, on pourrait faire en sorte que le ou les
|
||||
responsables des lieux de vie reçoivent une notification lorsque la liste de courses contient plus de 5 éléments
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\chapter{La laverie}
|
||||
\label{sec:la_laverie}
|
||||
\par Développeur principal: Florent
|
||||
|
||||
\section{But}
|
||||
\label{sub:but}
|
||||
\par Cette application doit fournir un système de gestion de laverie. Cela comprend:
|
||||
\begin{itemize}
|
||||
\item Un système de planning et de réservation de créneaux
|
||||
\item Un système de vente de jetons de laverie, lié aux comptoirs et au compte AE, permettant aux permanenciers de
|
||||
cliquer les jetons en même temps qu'ils vérifient l'état de la cotisation.
|
||||
\item Un système d'inventaire, pour gérer les différentes machines dans les différents lieux, et gérer également le
|
||||
retour des jetons après utilisation.
|
||||
\end{itemize}
|
||||
|
||||
\section{Principaux problèmes}
|
||||
\label{sec:principaux_problemes}
|
||||
|
||||
\subsection{Génération de plannings}
|
||||
\label{sub:generation_de_plannings}
|
||||
\par Il y a là beaucoup de cas à prendre en compte. Lorsque que quelqu'un veut réserver directement un "Lavage +
|
||||
Séchage", un simple "Lavage", ou un simple "Séchage", il faut toujours vérifier la disponibilité des créneaux en
|
||||
fonction du nombre de machine de chaque type présent dans la laverie en question \footnote{Belfort ou Sevenans, en
|
||||
l'occurrence}, et cela représente vite un grand nombre de combinaisons à vérifier.
|
||||
|
||||
\par De plus, la réservation doit rester ergonomique, et s'afficher dans un format le plus lisible possible pour un
|
||||
humain. Là dessus, un tableau est le plus approprié, avec chaque jour représenté par une colonne, et chaque créneau par
|
||||
une ligne.\\
|
||||
Mais cela ne représente malheureusement pas la temporalité, et la génération du tableau devient alors plutôt compliquée,
|
||||
et d'autant plus si l'on veut qu'il soit sémantiquement correct en HTML.
|
||||
|
||||
\subsection{Gestion des timezones}
|
||||
\label{sub:gestion_des_timezones}
|
||||
\par La gestion et le stockage des crénaux implique l'utilisation de champs de type \verb#DateTime#. \textbf{Django} les
|
||||
gère très bien, particulièrement au niveau des \emph{timezones}, où ce dernier n'hésite pas à lancer un warning lorsque
|
||||
l'objet \emph{date} passé ne contient pas d'information de fuseau horaire.
|
||||
|
||||
\par Mais avec notre décalage d'une heure par rapport au temps UTC, tous les horaires se retrouvent décalés, et gérer
|
||||
cela convenablement sans sortir d'avertissement a été plutôt compliqué. La solution a été de forcer un peu partout la
|
||||
\emph{timezone} à UTC, afin de ne pas créer de décalage, mais en conservant tout de même l'information de fuseau
|
||||
horaire, et sans tout casser lors du passage à l'heure d'hiver.
|
||||
|
||||
|
||||
\chapter{La communication}
|
||||
\label{sec:la_communication}
|
||||
\par Développeur principal: Florent
|
||||
|
||||
\section{But}
|
||||
\label{sub:but}
|
||||
\par Cette application a plusieurs but:
|
||||
\begin{itemize}
|
||||
\item Donner la possibilité au responsable communication d'éditer les différents textes, messages, et pages
|
||||
statiques du site.
|
||||
\item Fournir un système de news.
|
||||
\item Fournir un système de newsletter: le Weekmail.
|
||||
\end{itemize}
|
||||
|
||||
\section{Principaux problèmes}
|
||||
\label{sec:principaux_problemes}
|
||||
|
||||
\subsection{Envoie de mails}
|
||||
\label{sub:envoie_de_mails}
|
||||
\par Un outil de \emph{newsletter} nécessite l'envoie de mail. C'est là quelque chose de relativement compliqué à
|
||||
tester, d'autant plus lorsqu'il s'agit de mailing-list contenant l'intégralité des étudiants de l'UTBM.
|
||||
|
||||
\par \textbf{Django} fournit toutefois un outil très pratique: il contient plusieurs \emph{backend} d'emails, dont entre
|
||||
autre un \emph{SMTP}, et un \emph{console}. Le \emph{SMTP} est bien évidemment utilisé en production pour envoyer
|
||||
effectivement les mails, mais il est compliqué à utiliser en développement, car il suppose que le développeur a à sa
|
||||
disposition un serveur de ce type. On utilise alors le backend \emph{console}, qui affiche simplement dans le thread
|
||||
d'execution de \textbf{Django} une version texte de l'email envoyé, avec d'une part les entêtes, d'autre part le corps
|
||||
de message.
|
||||
|
||||
\par Mais autant pour tester l'envoie d'un mail unique à une adresse unique, cela fonctionne parfaitement bien, ce n'est
|
||||
toutefois pas suffisant pour tester un envoie massif à plusieurs mailings, avec en plus encore d'autres adresses en
|
||||
\emph{Bcc} pour les gens ne faisant pas partie des mailings "classiques", mais souhaitant quand même recevoir le
|
||||
\textbf{Weekmail}.
|
||||
|
||||
\subsection{Amélioration de l'outil de recherche}
|
||||
\label{sub:amelioration_de_l_outil_de_recherche}
|
||||
\par Pour la gestion de l'AE, il est nécessaire de pouvoir rechercher et trouver efficacement n'importe quel membre, en
|
||||
tapant au choix son nom, prénom, ou surnom, voire une combinaison de ces trois champs.
|
||||
|
||||
\par Mais une fonction de recherche aussi complexe est très difficile a mettre en place efficacement sans un traitement
|
||||
préalable, d'où la nécessité d'indexer les entrées à chercher. Un indexeur étant très complexe, mais également très
|
||||
courant, il n'a pas été difficile de trouver une application déjà existante fournissant ces fonctionnalités.
|
||||
|
||||
\par Le choix s'est porté sur \textbf{Haystack}, en l'utilisant avec l'indexeur \textbf{Whoosh}, plutôt efficace pour
|
||||
des bases raisonnables, et surtout écrit en pure \textbf{Python}, donc ne nécessitant pas d'installation compliquée en
|
||||
parallèle du site.
|
||||
|
||||
\par Le résultat est plutôt satisfaisant, mais il faudrait encore améliorer les résultats en utilisant les fonctions de
|
||||
\emph{boost} pour certains champs. De plus, une certaine lenteur se fait encore sentir avec certaines recherches trop
|
||||
communes ou générales.
|
||||
|
||||
|
||||
\chapter{Conclusions personnelles}
|
||||
\section{Florent}
|
||||
\label{sec:skia}
|
||||
\par Développer de nouvelles application m'a permis d'apréhender d'autres problématiques, comme la gestion des fichiers
|
||||
dans le SAS, ou bien des contraintes de concurrence et d'atomicité sur l'Eboutic.
|
||||
|
||||
\par Mais la plus grosse partie de mon travail ce semestre a surtout été de superviser une équipe de développement
|
||||
naissante, de relire les "Merge request", et de m'assurer de la cohérence du code des contributeurs avec le reste du
|
||||
projet.
|
||||
|
||||
\par J'ai églament pu approfondir mon utilisation de Gitlab à travers ses outils de gestion de projet, de revue de code,
|
||||
et de gestion des permissions sur les différentes branches.
|
||||
|
||||
\section{Guillaume}
|
||||
\label{sec:lo_j}
|
||||
\par Je suis très heureux d'avoir pu participer à ce projet de TO52 sur le développement de modules sur le site de
|
||||
l'Association des Étudiants. J'ai pu apprendre à travailler avec un nouvel environnement informatique tout en
|
||||
contribuant au développement d'outils pour l'association dont je suis Président, le Bureau des Festivités.
|
||||
|
||||
\subsection{Django}
|
||||
\par Ayant déjà travaillé avec le framework Spring et Java durant mon stage ST40, j'ai pu m'appuyer sur des notions
|
||||
générales afin d'apprendre et de comprendre le fonctionnement du Python et de Django que je ne connaissais pas du tout.
|
||||
|
||||
\par Mon apprentissage a été assez long au départ, car il y avait beaucoup d'informations à intégrer. Django est un
|
||||
framework très pratique qui permet d'effectuer de nombreuses tâches assez rébarbatives de manière automatique certes,
|
||||
mais encore faut-il comprendre ce qu'il se passe en arrière-plan. C'est cet apprentissage qui m'a pris le plus de temps.
|
||||
|
||||
\par Mon deuxième point de difficulté a été les formulaires. Là encore, Django est très pratique dès lors qu'il s'agit
|
||||
de faire un formulaire avec tous les champs d'un même Model. Cependant, il m'a fallu de l'aide et du temps pour
|
||||
comprendre comment faire pour ajouter d'autres champs en plus de ceux du Model au formulaire et pour comprendre comment
|
||||
récupérer les valeurs associées à chacun d'eux.
|
||||
|
||||
\subsection{Git}
|
||||
\par J'ai eu aussi à apprendre le fonctionnement de Git que j'avais déjà pu manipuler quelque peu mais il me manquait
|
||||
quand même beaucoup d'éléments.
|
||||
|
||||
\par Aujourd'hui, je pense pouvoir dire que j'ai progressé dans ce domaine mais il me reste encore bien des choses à
|
||||
apprendre pour être capable de l'utiliser de manière efficace.
|
||||
|
||||
\includepdf[pages={2}]{Couvertures.pdf}
|
||||
|
||||
\end{document}
|
||||
|
@ -1,18 +0,0 @@
|
||||
LATEX := pdflatex
|
||||
TARGET := slide.pdf
|
||||
|
||||
.PHONY: all clean distclean
|
||||
|
||||
all: $(TARGET) clean
|
||||
|
||||
%.pdf: %.tex
|
||||
echo "Building pdf"
|
||||
$(LATEX) --shell-escape $<
|
||||
rm -f $@
|
||||
$(LATEX) --shell-escape $<
|
||||
|
||||
clean:
|
||||
rm -f *.log *.nav *.snm *.aux *.out *.toc *.pyg
|
||||
|
||||
distclean: clean
|
||||
rm -f $(TARGET)
|
@ -1,133 +0,0 @@
|
||||
%%
|
||||
%% This is file `beamercolorthememetropolis.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% beamercolorthememetropolis.dtx (with options: `package')
|
||||
%% ---------------------------------------------------------------------------
|
||||
%% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of
|
||||
%% contributors can be found at
|
||||
%%
|
||||
%% https://github.com/matze/mtheme/graphs/contributors
|
||||
%%
|
||||
%% and the original template was based on the HSRM theme by Benjamin Weiss.
|
||||
%%
|
||||
%% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
|
||||
%% International License (https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
%% ---------------------------------------------------------------------------
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{beamercolorthememetropolis}[2016/02/21 Metropolis color theme]
|
||||
\RequirePackage{pgfopts}
|
||||
\pgfkeys{
|
||||
/metropolis/color/block/.cd,
|
||||
.is choice,
|
||||
transparent/.code=\metropolis@block@transparent,
|
||||
fill/.code=\metropolis@block@fill,
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/color/background/.cd,
|
||||
.is choice,
|
||||
dark/.code=\metropolis@colors@dark,
|
||||
light/.code=\metropolis@colors@light,
|
||||
}
|
||||
\newcommand{\metropolis@color@setdefaults}{
|
||||
\pgfkeys{/metropolis/color/.cd,
|
||||
background=light,
|
||||
block=transparent,
|
||||
}
|
||||
}
|
||||
\definecolor{mDarkBrown}{HTML}{604c38}
|
||||
\definecolor{mDarkTeal}{HTML}{23373b}
|
||||
\definecolor{mLightBrown}{HTML}{EB811B}
|
||||
\definecolor{mLightGreen}{HTML}{14B03D}
|
||||
\newcommand{\metropolis@colors@dark}{
|
||||
\setbeamercolor{normal text}{%
|
||||
fg=black!2,
|
||||
bg=mDarkTeal
|
||||
}
|
||||
}
|
||||
\newcommand{\metropolis@colors@light}{
|
||||
\setbeamercolor{normal text}{%
|
||||
fg=mDarkTeal,
|
||||
bg=black!2
|
||||
}
|
||||
}
|
||||
\setbeamercolor{alerted text}{%
|
||||
fg=mLightBrown
|
||||
}
|
||||
\setbeamercolor{example text}{%
|
||||
fg=mLightGreen
|
||||
}
|
||||
\setbeamercolor{titlelike}{use=normal text, parent=normal text}
|
||||
\setbeamercolor{author}{use=normal text, parent=normal text}
|
||||
\setbeamercolor{date}{use=normal text, parent=normal text}
|
||||
\setbeamercolor{institute}{use=normal text, parent=normal text}
|
||||
\setbeamercolor{structure}{use=normal text, fg=normal text.fg}
|
||||
\setbeamercolor{palette primary}{%
|
||||
use=normal text,
|
||||
fg=normal text.bg,
|
||||
bg=normal text.fg
|
||||
}
|
||||
\setbeamercolor{frametitle}{%
|
||||
use=palette primary,
|
||||
parent=palette primary
|
||||
}
|
||||
\setbeamercolor{progress bar}{%
|
||||
use=alerted text,
|
||||
fg=alerted text.fg,
|
||||
bg=alerted text.fg!50!black!30
|
||||
}
|
||||
\setbeamercolor{title separator}{
|
||||
use=progress bar,
|
||||
parent=progress bar
|
||||
}
|
||||
\setbeamercolor{progress bar in head/foot}{%
|
||||
use=progress bar,
|
||||
parent=progress bar
|
||||
}
|
||||
\setbeamercolor{progress bar in section page}{
|
||||
use=progress bar,
|
||||
parent=progress bar
|
||||
}
|
||||
\newcommand{\metropolis@block@transparent}{
|
||||
\setbeamercolor{block title}{%
|
||||
use=normal text,
|
||||
fg=normal text.fg,
|
||||
bg=
|
||||
}
|
||||
\setbeamercolor{block body}{
|
||||
bg=
|
||||
}
|
||||
}
|
||||
\newcommand{\metropolis@block@fill}{
|
||||
\setbeamercolor{block title}{%
|
||||
use=normal text,
|
||||
fg=normal text.fg,
|
||||
bg=normal text.bg!80!fg
|
||||
}
|
||||
\setbeamercolor{block body}{
|
||||
use={block title, normal text},
|
||||
bg=block title.bg!50!normal text.bg
|
||||
}
|
||||
}
|
||||
\setbeamercolor{block title alerted}{%
|
||||
use={block title, alerted text},
|
||||
bg=block title.bg,
|
||||
fg=alerted text.fg
|
||||
}
|
||||
\setbeamercolor{block title example}{%
|
||||
use={block title, example text},
|
||||
bg=block title.bg,
|
||||
fg=example text.fg
|
||||
}
|
||||
\setbeamercolor{block body alerted}{use=block body, parent=block body}
|
||||
\setbeamercolor{block body example}{use=block body, parent=block body}
|
||||
\setbeamercolor{footnote}{fg=normal text.fg!90}
|
||||
\setbeamercolor{footnote mark}{fg=.}
|
||||
\metropolis@color@setdefaults
|
||||
\ProcessPgfPackageOptions{/metropolis/color}
|
||||
\mode<all>
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `beamercolorthememetropolis.sty'.
|
@ -1,283 +0,0 @@
|
||||
%%
|
||||
%% This is file `beamerfontthememetropolis.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% beamerfontthememetropolis.dtx (with options: `package')
|
||||
%% ---------------------------------------------------------------------------
|
||||
%% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of
|
||||
%% contributors can be found at
|
||||
%%
|
||||
%% https://github.com/matze/mtheme/graphs/contributors
|
||||
%%
|
||||
%% and the original template was based on the HSRM theme by Benjamin Weiss.
|
||||
%%
|
||||
%% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
|
||||
%% International License (https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
%% ---------------------------------------------------------------------------
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{beamerfontthememetropolis}[2016/02/21 Metropolis font theme]
|
||||
\RequirePackage{etoolbox}
|
||||
\RequirePackage{ifxetex}
|
||||
\RequirePackage{ifluatex}
|
||||
\RequirePackage{pgfopts}
|
||||
\ifboolexpr{bool {xetex} or bool {luatex}}{
|
||||
\RequirePackage[no-math]{fontspec}
|
||||
\newcounter{fontsnotfound}
|
||||
\newcommand{\checkfont}[1]{%
|
||||
\suppressfontnotfounderror=1%
|
||||
\font\x = "#1" at 10pt
|
||||
\selectfont
|
||||
\ifx\x\nullfont%
|
||||
\stepcounter{fontsnotfound}%
|
||||
\fi%
|
||||
\suppressfontnotfounderror=0%
|
||||
}
|
||||
|
||||
\newcommand{\iffontsavailable}[3]{%
|
||||
\setcounter{fontsnotfound}{0}%
|
||||
\expandafter\forcsvlist\expandafter%
|
||||
\checkfont\expandafter{#1}%
|
||||
\ifnum\value{fontsnotfound}=0%
|
||||
#2%
|
||||
\else%
|
||||
#3%
|
||||
\fi%
|
||||
}
|
||||
\iffontsavailable{Fira Sans Light,%
|
||||
Fira Sans Light Italic,%
|
||||
Fira Sans,%
|
||||
Fira Sans Italic}%
|
||||
{%
|
||||
\setsansfont[ItalicFont={Fira Sans Light Italic},%
|
||||
BoldFont={Fira Sans},%
|
||||
BoldItalicFont={Fira Sans Italic}]%
|
||||
{Fira Sans Light}%
|
||||
}{%
|
||||
\iffontsavailable{Fira Sans Light OT,%
|
||||
Fira Sans Light Italic OT,%
|
||||
Fira Sans OT,%
|
||||
Fira Sans Italic OT}%
|
||||
{%
|
||||
\setsansfont[ItalicFont={Fira Sans Light Italic OT},%
|
||||
BoldFont={Fira Sans OT},%
|
||||
BoldItalicFont={Fira Sans Italic OT}]%
|
||||
{Fira Sans Light OT}%
|
||||
}{%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Could not find Fira Sans fonts%
|
||||
}
|
||||
}
|
||||
}
|
||||
\iffontsavailable{Fira Mono, Fira Mono Bold}{%
|
||||
\setmonofont[BoldFont={Fira Mono Medium}]{Fira Mono}%
|
||||
}{%
|
||||
\iffontsavailable{Fira Mono OT, Fira Mono Bold OT}{%
|
||||
\setmonofont[BoldFont={Fira Mono Medium OT}]{Fira Mono OT}%
|
||||
}{%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Could not find Fira Mono fonts%
|
||||
}
|
||||
}
|
||||
}
|
||||
\AtBeginEnvironment{tabular}{%
|
||||
\addfontfeature{Numbers={Monospaced}}%
|
||||
}
|
||||
}{%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
You need to compile with XeLaTeX or LuaLaTeX to use the Fira fonts%
|
||||
}
|
||||
}
|
||||
\setbeamerfont{title}{size=\Large,%
|
||||
series=\bfseries}
|
||||
\setbeamerfont{author}{size=\small}
|
||||
\setbeamerfont{date}{size=\small}
|
||||
\setbeamerfont{section title}{size=\Large,%
|
||||
series=\bfseries}
|
||||
\setbeamerfont{block title}{size=\normalsize,%
|
||||
series=\bfseries}
|
||||
\setbeamerfont{block title alerted}{size=\normalsize,%
|
||||
series=\bfseries}
|
||||
\setbeamerfont*{subtitle}{size=\large}
|
||||
\setbeamerfont{frametitle}{size=\large,%
|
||||
series=\bfseries}
|
||||
\setbeamerfont{caption}{size=\small}
|
||||
\setbeamerfont{caption name}{series=\bfseries}
|
||||
\setbeamerfont{description item}{series=\bfseries}
|
||||
\setbeamerfont{page number in head/foot}{size=\scriptsize}
|
||||
\setbeamerfont{bibliography entry author}{size=\normalsize,%
|
||||
series=\normalfont}
|
||||
\setbeamerfont{bibliography entry title}{size=\normalsize,%
|
||||
series=\bfseries}
|
||||
\setbeamerfont{bibliography entry location}{size=\normalsize,%
|
||||
series=\normalfont}
|
||||
\setbeamerfont{bibliography entry note}{size=\small,%
|
||||
series=\normalfont}
|
||||
\setbeamerfont{standout}{size=\Large,%
|
||||
series=\bfseries}
|
||||
\pgfkeys{
|
||||
/metropolis/font/titleformat title/.cd,
|
||||
.is choice,
|
||||
regular/.code={%
|
||||
\let\metropolis@titleformat\@empty%
|
||||
\setbeamerfont{title}{shape=\normalfont}%
|
||||
},
|
||||
smallcaps/.code={%
|
||||
\let\metropolis@titleformat\@empty%
|
||||
\setbeamerfont{title}{shape=\scshape}%
|
||||
},
|
||||
allsmallcaps/.code={%
|
||||
\let\metropolis@titleformat\lowercase%
|
||||
\setbeamerfont{title}{shape=\scshape}%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat title=allsmallcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
allcaps/.code={%
|
||||
\let\metropolis@titleformat\uppercase%
|
||||
\setbeamerfont{title}{shape=\normalfont}
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat title=allcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/font/titleformat subtitle/.cd,
|
||||
.is choice,
|
||||
regular/.code={%
|
||||
\let\metropolis@subtitleformat\@empty%
|
||||
\setbeamerfont{subtitle}{shape=\normalfont}%
|
||||
},
|
||||
smallcaps/.code={%
|
||||
\let\metropolis@subtitleformat\@empty%
|
||||
\setbeamerfont{subtitle}{shape=\scshape}%
|
||||
},
|
||||
allsmallcaps/.code={%
|
||||
\let\metropolis@subtitleformat\lowercase%
|
||||
\setbeamerfont{subtitle}{shape=\scshape}%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat subtitle=allsmallcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
allcaps/.code={%
|
||||
\let\metropolis@subtitleformat\uppercase%
|
||||
\setbeamerfont{subtitle}{shape=\normalfont}%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat subtitle=allcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/font/titleformat section/.cd,
|
||||
.is choice,
|
||||
regular/.code={%
|
||||
\let\metropolis@sectiontitleformat\@empty%
|
||||
\setbeamerfont{section title}{shape=\normalfont}%
|
||||
},
|
||||
smallcaps/.code={%
|
||||
\let\metropolis@sectiontitleformat\@empty%
|
||||
\setbeamerfont{section title}{shape=\scshape}%
|
||||
},
|
||||
allsmallcaps/.code={%
|
||||
\let\metropolis@sectiontitleformat\MakeLowercase%
|
||||
\setbeamerfont{section title}{shape=\scshape}%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat section=allsmallcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
allcaps/.code={%
|
||||
\let\metropolis@sectiontitleformat\MakeUppercase%
|
||||
\setbeamerfont{section title}{shape=\normalfont}%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat section=allcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/font/titleformat frame/.cd,
|
||||
.is choice,
|
||||
regular/.code={%
|
||||
\let\metropolis@frametitleformat\@empty%
|
||||
\setbeamerfont{frametitle}{shape=\normalfont}%
|
||||
},
|
||||
smallcaps/.code={%
|
||||
\let\metropolis@frametitleformat\@empty%
|
||||
\setbeamerfont{frametitle}{shape=\scshape}%
|
||||
},
|
||||
allsmallcaps/.code={%
|
||||
\let\metropolis@frametitleformat\MakeLowercase%
|
||||
\setbeamerfont{frametitle}{shape=\scshape}%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat frame=allsmallcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
allcaps/.code={%
|
||||
\let\metropolis@frametitleformat\MakeUppercase%
|
||||
\setbeamerfont{frametitle}{shape=\normalfont}
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat frame=allcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/font/.cd,
|
||||
titleformattitle/.code=\pgfkeysalso{titleformat title=#1},
|
||||
titleformatsubtitle/.code=\pgfkeysalso{titleformat subtitle=#1},
|
||||
titleformatsection/.code=\pgfkeysalso{titleformat section=#1},
|
||||
titleformatframe/.code=\pgfkeysalso{titleformat frame=#1},
|
||||
}
|
||||
\newcommand{\metropolis@font@setdefaults}{
|
||||
\pgfkeys{/metropolis/font/.cd,
|
||||
titleformat title=regular,
|
||||
titleformat subtitle=regular,
|
||||
titleformat section=regular,
|
||||
titleformat frame=regular,
|
||||
}
|
||||
}
|
||||
\def\metropolis@titleformat#1{#1}
|
||||
\def\metropolis@subtitleformat#1{#1}
|
||||
\def\metropolis@sectiontitleformat#1{#1}
|
||||
\def\metropolis@frametitleformat#1{#1}
|
||||
\patchcmd{\beamer@title}%
|
||||
{\def\inserttitle{#2}}%
|
||||
{\def\inserttitle{\metropolis@titleformat{#2}}}%
|
||||
{}%
|
||||
{\PackageError{beamerfontthememetropolis}{Patching title failed}}
|
||||
\patchcmd{\beamer@subtitle}%
|
||||
{\def\insertsubtitle{#2}}%
|
||||
{\def\insertsubtitle{\metropolis@subtitleformat{#2}}}%
|
||||
{}%
|
||||
{\PackageError{beamerfontthememetropolis}{Patching subtitle failed}}
|
||||
\patchcmd{\sectionentry}
|
||||
{\def\insertsectionhead{#2}}
|
||||
{\def\insertsectionhead{\metropolis@sectiontitleformat{#2}}}
|
||||
{}
|
||||
{\PackageError{beamerfontthememetropolis}{Patching section title failed}}
|
||||
\patchcmd{\beamer@section}
|
||||
{\def\insertsectionhead{\hyperlink{Navigation\the\c@page}{#1}}}
|
||||
{\def\insertsectionhead{\hyperlink{Navigation\the\c@page}{%
|
||||
\metropolis@sectiontitleformat{#1}}}}
|
||||
{}
|
||||
{\PackageError{beamerfontthememetropolis}{Patching section title failed}}
|
||||
\patchcmd{\beamer@@frametitle}
|
||||
{\beamer@ifempty{#2}{}{%
|
||||
\gdef\insertframetitle{{#2\ifnum\beamer@autobreakcount>0\relax{}\space%
|
||||
\usebeamertemplate*{frametitle continuation}\fi}}%
|
||||
\gdef\beamer@frametitle{#2}%
|
||||
\gdef\beamer@shortframetitle{#1}%
|
||||
}}
|
||||
{\beamer@ifempty{#2}{}{%
|
||||
\gdef\insertframetitle{{\metropolis@frametitleformat{#2}\ifnum%
|
||||
\beamer@autobreakcount>0\relax{}\space%
|
||||
\usebeamertemplate*{frametitle continuation}\fi}}%
|
||||
\gdef\beamer@frametitle{#2}%
|
||||
\gdef\beamer@shortframetitle{#1}%
|
||||
}}
|
||||
{}
|
||||
{\PackageError{beamerfontthememetropolis}{Patching frame title failed}}
|
||||
\metropolis@font@setdefaults
|
||||
\ProcessPgfPackageOptions{/metropolis/font}
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `beamerfontthememetropolis.sty'.
|
@ -1,281 +0,0 @@
|
||||
%%
|
||||
%% This is file `beamerinnerthememetropolis.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% beamerinnerthememetropolis.dtx (with options: `package')
|
||||
%% ---------------------------------------------------------------------------
|
||||
%% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of
|
||||
%% contributors can be found at
|
||||
%%
|
||||
%% https://github.com/matze/mtheme/graphs/contributors
|
||||
%%
|
||||
%% and the original template was based on the HSRM theme by Benjamin Weiss.
|
||||
%%
|
||||
%% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
|
||||
%% International License (https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
%% ---------------------------------------------------------------------------
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{beamerinnerthememetropolis}[2016/02/21 Metropolis inner theme]
|
||||
\RequirePackage{etoolbox}
|
||||
\RequirePackage{keyval}
|
||||
\RequirePackage{calc}
|
||||
\RequirePackage{pgfopts}
|
||||
\RequirePackage{tikz}
|
||||
\pgfkeys{
|
||||
/metropolis/inner/sectionpage/.cd,
|
||||
.is choice,
|
||||
none/.code=\metropolis@disablesectionpage,
|
||||
simple/.code={\metropolis@enablesectionpage
|
||||
\setbeamertemplate{section page}[simple]},
|
||||
progressbar/.code={\metropolis@enablesectionpage
|
||||
\setbeamertemplate{section page}[progressbar]},
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/inner/subsectionpage/.cd,
|
||||
.is choice,
|
||||
none/.code=\metropolis@disablesubsectionpage,
|
||||
simple/.code={\metropolis@enablesubsectionpage
|
||||
\setbeamertemplate{section page}[simple]},
|
||||
progressbar/.code={\metropolis@enablesubsectionpage
|
||||
\setbeamertemplate{section page}[progressbar]},
|
||||
}
|
||||
\newcommand{\metropolis@inner@setdefaults}{
|
||||
\pgfkeys{/metropolis/inner/.cd,
|
||||
sectionpage=progressbar,
|
||||
subsectionpage=none
|
||||
}
|
||||
}
|
||||
\setbeamertemplate{title page}{
|
||||
\begin{minipage}[b][\paperheight]{\textwidth}
|
||||
\ifx\inserttitlegraphic\@empty\else\usebeamertemplate*{title graphic}\fi
|
||||
\vfill%
|
||||
\ifx\inserttitle\@empty\else\usebeamertemplate*{title}\fi
|
||||
\ifx\insertsubtitle\@empty\else\usebeamertemplate*{subtitle}\fi
|
||||
\usebeamertemplate*{title separator}
|
||||
\ifx\beamer@shortauthor\@empty\else\usebeamertemplate*{author}\fi
|
||||
\ifx\insertdate\@empty\else\usebeamertemplate*{date}\fi
|
||||
\ifx\insertinstitute\@empty\else\usebeamertemplate*{institute}\fi
|
||||
\vfill
|
||||
\vspace*{1mm}
|
||||
\end{minipage}
|
||||
}
|
||||
\def\maketitle{%
|
||||
\ifbeamer@inframe
|
||||
\titlepage
|
||||
\else
|
||||
\frame[plain,noframenumbering]{\titlepage}
|
||||
\fi
|
||||
}
|
||||
\def\titlepage{%
|
||||
\usebeamertemplate{title page}
|
||||
}
|
||||
\setbeamertemplate{title graphic}{
|
||||
\vbox to 0pt {
|
||||
\vspace*{2em}
|
||||
\inserttitlegraphic%
|
||||
}%
|
||||
\nointerlineskip%
|
||||
}
|
||||
\setbeamertemplate{title}{
|
||||
\raggedright%
|
||||
\linespread{1.0}%
|
||||
\inserttitle%
|
||||
\par%
|
||||
\vspace*{0.5em}
|
||||
}
|
||||
\setbeamertemplate{subtitle}{
|
||||
\insertsubtitle%
|
||||
\par%
|
||||
\vspace*{0.5em}
|
||||
}
|
||||
\setbeamertemplate{title separator}{
|
||||
\begin{tikzpicture}
|
||||
\draw[fg, fill=fg] (0,0) rectangle (\textwidth, 0.4pt);
|
||||
\end{tikzpicture}%
|
||||
\par%
|
||||
}
|
||||
\setbeamertemplate{author}{
|
||||
\vspace*{2em}
|
||||
\insertauthor%
|
||||
\par%
|
||||
\vspace*{0.25em}
|
||||
}
|
||||
\setbeamertemplate{date}{
|
||||
\insertdate%
|
||||
\par%
|
||||
}
|
||||
\setbeamertemplate{institute}{
|
||||
\vspace*{3mm}
|
||||
\insertinstitute%
|
||||
\par%
|
||||
}
|
||||
\defbeamertemplate{section page}{simple}{
|
||||
\begin{center}
|
||||
\usebeamercolor[fg]{section title}
|
||||
\usebeamerfont{section title}
|
||||
\insertsectionhead\par
|
||||
\ifx\insertsubsection\@empty\else
|
||||
\usebeamercolor[fg]{subsection title}
|
||||
\usebeamerfont{subsection title}
|
||||
\insertsubsection
|
||||
\fi
|
||||
\end{center}
|
||||
}
|
||||
\defbeamertemplate{section page}{progressbar}{
|
||||
\centering
|
||||
\begin{minipage}{22em}
|
||||
\raggedright
|
||||
\usebeamercolor[fg]{section title}
|
||||
\usebeamerfont{section title}
|
||||
\insertsectionhead\\[-1ex]
|
||||
\usebeamertemplate*{progress bar in section page}
|
||||
\par
|
||||
\ifx\insertsubsection\@empty\else%
|
||||
\usebeamercolor[fg]{subsection title}%
|
||||
\usebeamerfont{subsection title}%
|
||||
\insertsubsection
|
||||
\fi
|
||||
\end{minipage}
|
||||
\par
|
||||
\vspace{\baselineskip}
|
||||
}
|
||||
\newcommand{\metropolis@disablesectionpage}{
|
||||
\AtBeginSection{
|
||||
% intentionally empty
|
||||
}
|
||||
}
|
||||
\newcommand{\metropolis@enablesectionpage}{
|
||||
\AtBeginSection{
|
||||
\ifbeamer@inframe
|
||||
\sectionpage
|
||||
\else
|
||||
\frame[plain,c,noframenumbering]{\sectionpage}
|
||||
\fi
|
||||
}
|
||||
}
|
||||
\setbeamertemplate{subsection page}{%
|
||||
\usebeamertemplate*{section page}
|
||||
}
|
||||
\newcommand{\metropolis@disablesubsectionpage}{
|
||||
\AtBeginSubsection{
|
||||
% intentionally empty
|
||||
}
|
||||
}
|
||||
\newcommand{\metropolis@enablesubsectionpage}{
|
||||
\AtBeginSubsection{
|
||||
\ifbeamer@inframe
|
||||
\subsectionpage
|
||||
\else
|
||||
\frame[plain,c,noframenumbering]{\subsectionpage}
|
||||
\fi
|
||||
}
|
||||
}
|
||||
\newlength{\metropolis@progressonsectionpage}
|
||||
\setbeamertemplate{progress bar in section page}{
|
||||
\setlength{\metropolis@progressonsectionpage}{%
|
||||
\textwidth * \ratio{\insertframenumber pt}{\inserttotalframenumber pt}%
|
||||
}%
|
||||
\begin{tikzpicture}
|
||||
\draw[bg, fill=bg] (0,0) rectangle (\textwidth, 0.4pt);
|
||||
\draw[fg, fill=fg] (0,0) rectangle (\metropolis@progressonsectionpage, 0.4pt);
|
||||
\end{tikzpicture}%
|
||||
}
|
||||
\def\inserttotalframenumber{100}
|
||||
\newlength{\metropolis@blocksep}
|
||||
\newlength{\metropolis@blockadjust}
|
||||
\setlength{\metropolis@blocksep}{0.75ex}
|
||||
\setlength{\metropolis@blockadjust}{0.25ex}
|
||||
\providecommand{\metropolis@strut}{%
|
||||
\vphantom{ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz()}%
|
||||
}
|
||||
\newcommand{\metropolis@block}[1]{
|
||||
\par\vskip\medskipamount%
|
||||
\setlength{\parskip}{0pt}
|
||||
\ifbeamercolorempty[bg]{block title#1}{%
|
||||
\begin{beamercolorbox}[rightskip=0pt plus 4em]{block title#1}}{%
|
||||
\ifbeamercolorempty[bg]{block title}{%
|
||||
\begin{beamercolorbox}[rightskip=0pt plus 4em]{block title#1}%
|
||||
}%
|
||||
{%
|
||||
\begin{beamercolorbox}[
|
||||
sep=\dimexpr\metropolis@blocksep-\metropolis@blockadjust\relax,
|
||||
leftskip=\metropolis@blockadjust,
|
||||
rightskip=\dimexpr\metropolis@blockadjust plus 4em\relax
|
||||
]{block title#1}%
|
||||
}}%
|
||||
\usebeamerfont*{block title#1}%
|
||||
\metropolis@strut%
|
||||
\insertblocktitle%
|
||||
\metropolis@strut%
|
||||
\end{beamercolorbox}%
|
||||
\nointerlineskip%
|
||||
\ifbeamercolorempty[bg]{block body#1}{%
|
||||
\begin{beamercolorbox}[vmode]{block body#1}}{
|
||||
\ifbeamercolorempty[bg]{block body}{%
|
||||
\begin{beamercolorbox}[vmode]{block body#1}%
|
||||
}{%
|
||||
\begin{beamercolorbox}[sep=\metropolis@blocksep, vmode]{block body#1}%
|
||||
\vspace{-\metropolis@parskip}
|
||||
}}%
|
||||
\usebeamerfont{block body#1}%
|
||||
\setlength{\parskip}{\metropolis@parskip}%
|
||||
}
|
||||
\setbeamertemplate{block begin}{\metropolis@block{}}
|
||||
\setbeamertemplate{block alerted begin}{\metropolis@block{ alerted}}
|
||||
\setbeamertemplate{block example begin}{\metropolis@block{ example}}
|
||||
\setbeamertemplate{block end}{\end{beamercolorbox}\vspace*{0.2ex}}
|
||||
\setbeamertemplate{block alerted end}{\end{beamercolorbox}\vspace*{0.2ex}}
|
||||
\setbeamertemplate{block example end}{\end{beamercolorbox}\vspace*{0.2ex}}
|
||||
\setbeamertemplate{itemize items}{\textbullet}
|
||||
\setbeamertemplate{caption label separator}{: }
|
||||
\setbeamertemplate{caption}[numbered]
|
||||
\setbeamertemplate{footnote}{%
|
||||
\parindent 0em\noindent%
|
||||
\raggedright
|
||||
\usebeamercolor{footnote}\hbox to 0.8em{\hfil\insertfootnotemark}\insertfootnotetext\par%
|
||||
}
|
||||
\newlength{\metropolis@parskip}
|
||||
\setlength{\metropolis@parskip}{0.5em}
|
||||
\setlength{\parskip}{\metropolis@parskip}
|
||||
\linespread{1.15}
|
||||
\define@key{beamerframe}{c}[true]{% centered
|
||||
\beamer@frametopskip=0pt plus 1fill\relax%
|
||||
\beamer@framebottomskip=0pt plus 1fill\relax%
|
||||
\beamer@frametopskipautobreak=0pt plus .4\paperheight\relax%
|
||||
\beamer@framebottomskipautobreak=0pt plus .6\paperheight\relax%
|
||||
\def\beamer@initfirstlineunskip{}%
|
||||
}
|
||||
\providebool{metropolis@standout}
|
||||
\define@key{beamerframe}{standout}[true]{%
|
||||
\booltrue{metropolis@standout}
|
||||
\begingroup
|
||||
\setkeys{beamerframe}{c}
|
||||
\setkeys{beamerframe}{noframenumbering}
|
||||
\ifbeamercolorempty[bg]{palette primary}{
|
||||
\setbeamercolor{background canvas}{
|
||||
use=palette primary,
|
||||
bg=-palette primary.fg
|
||||
}
|
||||
}{
|
||||
\setbeamercolor{background canvas}{
|
||||
use=palette primary,
|
||||
bg=palette primary.bg
|
||||
}
|
||||
}
|
||||
\centering
|
||||
\usebeamercolor[fg]{palette primary}
|
||||
\usebeamerfont{standout}
|
||||
}
|
||||
\apptocmd{\beamer@reseteecodes}{%
|
||||
\ifbool{metropolis@standout}{
|
||||
\endgroup
|
||||
\boolfalse{metropolis@standout}
|
||||
}{}
|
||||
}{}{}
|
||||
\metropolis@inner@setdefaults
|
||||
\ProcessPgfPackageOptions{/metropolis/inner}
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `beamerinnerthememetropolis.sty'.
|
@ -1,126 +0,0 @@
|
||||
%%
|
||||
%% This is file `beamerouterthememetropolis.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% beamerouterthememetropolis.dtx (with options: `package')
|
||||
%% ---------------------------------------------------------------------------
|
||||
%% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of
|
||||
%% contributors can be found at
|
||||
%%
|
||||
%% https://github.com/matze/mtheme/graphs/contributors
|
||||
%%
|
||||
%% and the original template was based on the HSRM theme by Benjamin Weiss.
|
||||
%%
|
||||
%% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
|
||||
%% International License (https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
%% ---------------------------------------------------------------------------
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{beamerouterthememetropolis}[2016/02/21 Metropolis outer theme]
|
||||
\RequirePackage{etoolbox}
|
||||
\RequirePackage{calc}
|
||||
\RequirePackage{pgfopts}
|
||||
\pgfkeys{
|
||||
/metropolis/outer/numbering/.cd,
|
||||
.is choice,
|
||||
none/.code=\setbeamertemplate{frame numbering}[none],
|
||||
counter/.code=\setbeamertemplate{frame numbering}[counter],
|
||||
fraction/.code=\setbeamertemplate{frame numbering}[fraction],
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/outer/progressbar/.cd,
|
||||
.is choice,
|
||||
none/.code={%
|
||||
\setbeamertemplate{headline}[plain]
|
||||
\setbeamertemplate{frametitle}[plain]
|
||||
\setbeamertemplate{footline}[plain]
|
||||
},
|
||||
head/.code={\pgfkeys{/metropolis/outer/progressbar=none}
|
||||
\addtobeamertemplate{headline}{}{%
|
||||
\usebeamertemplate*{progress bar in head/foot}
|
||||
}
|
||||
},
|
||||
frametitle/.code={\pgfkeys{/metropolis/outer/progressbar=none}
|
||||
\addtobeamertemplate{frametitle}{}{%
|
||||
\usebeamertemplate*{progress bar in head/foot}
|
||||
}
|
||||
},
|
||||
foot/.code={\pgfkeys{/metropolis/outer/progressbar=none}
|
||||
\addtobeamertemplate{footline}{}{%
|
||||
\usebeamertemplate*{progress bar in head/foot}%
|
||||
}
|
||||
},
|
||||
}
|
||||
\newcommand{\metropolis@outer@setdefaults}{
|
||||
\pgfkeys{/metropolis/outer/.cd,
|
||||
numbering=counter,
|
||||
progressbar=none,
|
||||
}
|
||||
}
|
||||
\setbeamertemplate{navigation symbols}{}
|
||||
\defbeamertemplate{frame footer}{none}{}
|
||||
\defbeamertemplate{frame footer}{custom}[1]{ #1 }
|
||||
\defbeamertemplate{frame numbering}{none}{}
|
||||
\defbeamertemplate{frame numbering}{counter}{\insertframenumber}
|
||||
\defbeamertemplate{frame numbering}{fraction}{
|
||||
\insertframenumber/\inserttotalframenumber
|
||||
}
|
||||
\defbeamertemplate{headline}{plain}{}
|
||||
\defbeamertemplate{footline}{plain}{%
|
||||
\begin{beamercolorbox}[wd=\textwidth, sep=3ex]{footline}%
|
||||
\usebeamerfont{page number in head/foot}%
|
||||
\usebeamertemplate*{frame footer}
|
||||
\hfill%
|
||||
\usebeamertemplate*{frame numbering}
|
||||
\end{beamercolorbox}%
|
||||
}
|
||||
\newlength{\metropolis@frametitle@padding}
|
||||
\setlength{\metropolis@frametitle@padding}{2.2ex}
|
||||
\newcommand{\metropolis@frametitlestrut@start}{
|
||||
\rule{0pt}{\metropolis@frametitle@padding +%
|
||||
\totalheightof{%
|
||||
\ifcsdef{metropolis@frametitleformat}{\metropolis@frametitleformat X}{X}%
|
||||
}%
|
||||
}%
|
||||
}
|
||||
\newcommand{\metropolis@frametitlestrut@end}{
|
||||
\rule[-\metropolis@frametitle@padding]{0pt}{\metropolis@frametitle@padding}
|
||||
}
|
||||
\defbeamertemplate{frametitle}{plain}{%
|
||||
\nointerlineskip%
|
||||
\begin{beamercolorbox}[%
|
||||
wd=\paperwidth,%
|
||||
sep=0pt,%
|
||||
leftskip=\metropolis@frametitle@padding,%
|
||||
rightskip=\metropolis@frametitle@padding,%
|
||||
]{frametitle}%
|
||||
\metropolis@frametitlestrut@start\insertframetitle\metropolis@frametitlestrut@end%
|
||||
\end{beamercolorbox}%
|
||||
}
|
||||
\newlength{\metropolis@progressinheadfoot}
|
||||
\setbeamertemplate{progress bar in head/foot}{
|
||||
\nointerlineskip
|
||||
\setlength{\metropolis@progressinheadfoot}{%
|
||||
\paperwidth * \ratio{\insertframenumber pt}{\inserttotalframenumber pt}%
|
||||
}%
|
||||
\begin{beamercolorbox}[wd=\paperwidth]{progress bar in head/foot}
|
||||
\begin{tikzpicture}
|
||||
\draw[bg, fill=bg] (0,0) rectangle (\paperwidth, 0.4pt);
|
||||
\draw[fg, fill=fg] (0,0) rectangle (\metropolis@progressinheadfoot, 0.4pt);
|
||||
\end{tikzpicture}%
|
||||
\end{beamercolorbox}
|
||||
}
|
||||
\AtBeginDocument{%
|
||||
\apptocmd{\appendix}{%
|
||||
\pgfkeys{%
|
||||
/metropolis/outer/.cd,
|
||||
numbering=none,
|
||||
progressbar=none}
|
||||
}{}{}
|
||||
}
|
||||
\metropolis@outer@setdefaults
|
||||
\ProcessPgfPackageOptions{/metropolis/outer}
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `beamerouterthememetropolis.sty'.
|
@ -1,105 +0,0 @@
|
||||
%%
|
||||
%% This is file `beamerthememetropolis.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% beamerthememetropolis.dtx (with options: `package')
|
||||
%% ---------------------------------------------------------------------------
|
||||
%% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of
|
||||
%% contributors can be found at
|
||||
%%
|
||||
%% https://github.com/matze/mtheme/graphs/contributors
|
||||
%%
|
||||
%% and the original template was based on the HSRM theme by Benjamin Weiss.
|
||||
%%
|
||||
%% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
|
||||
%% International License (https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
%% ---------------------------------------------------------------------------
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{beamerthememetropolis}
|
||||
[2016/02/21 v1.1 Metropolis Beamer theme]
|
||||
\RequirePackage{etoolbox}
|
||||
\RequirePackage{pgfopts}
|
||||
\pgfkeys{/metropolis/.cd,
|
||||
.search also={
|
||||
/metropolis/inner,
|
||||
/metropolis/outer,
|
||||
/metropolis/color,
|
||||
/metropolis/font,
|
||||
}
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/titleformat plain/.cd,
|
||||
.is choice,
|
||||
regular/.code={%
|
||||
\let\metropolis@plaintitleformat\@empty%
|
||||
\setbeamerfont{standout}{shape=\normalfont}%
|
||||
},
|
||||
smallcaps/.code={%
|
||||
\let\metropolis@plaintitleformat\@empty%
|
||||
\setbeamerfont{standout}{shape=\scshape}%
|
||||
},
|
||||
allsmallcaps/.code={%
|
||||
\let\metropolis@plaintitleformat\MakeLowercase%
|
||||
\setbeamerfont{standout}{shape=\scshape}%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat plain=allsmallcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
allcaps/.code={%
|
||||
\let\metropolis@plaintitleformat\MakeUppercase%
|
||||
\setbeamerfont{standout}{shape=\normalfont}%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
Be aware that titleformat plain=allcaps can lead to problems%
|
||||
}
|
||||
},
|
||||
}
|
||||
\pgfkeys{
|
||||
/metropolis/titleformat/.code=\pgfkeysalso{
|
||||
font/titleformat title=#1,
|
||||
font/titleformat subtitle=#1,
|
||||
font/titleformat section=#1,
|
||||
font/titleformat frame=#1,
|
||||
titleformat plain=#1,
|
||||
}
|
||||
}
|
||||
\pgfkeys{/metropolis/.cd,
|
||||
usetitleprogressbar/.code=\pgfkeysalso{outer/progressbar=frametitle},
|
||||
noslidenumbers/.code=\pgfkeysalso{outer/numbering=none},
|
||||
usetotalslideindicator/.code=\pgfkeysalso{outer/numbering=fraction},
|
||||
nosectionslide/.code=\pgfkeysalso{inner/sectionpage=none},
|
||||
darkcolors/.code=\pgfkeysalso{color/background=dark},
|
||||
blockbg/.code=\pgfkeysalso{color/block=fill, inner/block=fill},
|
||||
}
|
||||
\newcommand{\metropolis@setdefaults}{
|
||||
\pgfkeys{/metropolis/.cd,
|
||||
titleformat plain=regular,
|
||||
}
|
||||
}
|
||||
\useinnertheme{metropolis}
|
||||
\useoutertheme{metropolis}
|
||||
\usecolortheme{metropolis}
|
||||
\usefonttheme{metropolis}
|
||||
\AtEndPreamble{%
|
||||
\@ifpackageloaded{pgfplots}{%
|
||||
\RequirePackage{pgfplotsthemetol}
|
||||
}{}
|
||||
}
|
||||
\newcommand{\metroset}[1]{\pgfkeys{/metropolis/.cd,#1}}
|
||||
\def\metropolis@plaintitleformat#1{#1}
|
||||
\newcommand{\plain}[2][]{%
|
||||
\PackageWarning{beamerthememetropolis}{%
|
||||
The syntax `\plain' may be deprecated in a future version of Metropolis.
|
||||
Please use a frame with [standout] instead.
|
||||
}
|
||||
\begin{frame}[standout]{#1}
|
||||
\metropolis@plaintitleformat{#2}
|
||||
\end{frame}
|
||||
}
|
||||
\newcommand{\mreducelistspacing}{\vspace{-\topsep}}
|
||||
\metropolis@setdefaults
|
||||
\ProcessPgfOptions{/metropolis}
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `beamerthememetropolis.sty'.
|
@ -1,123 +0,0 @@
|
||||
%%
|
||||
%% This is file `pgfplotsthemetol.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% pgfplotsthemetol.dtx (with options: `package')
|
||||
%% ---------------------------------------------------------------------------
|
||||
%% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of
|
||||
%% contributors can be found at
|
||||
%%
|
||||
%% https://github.com/matze/mtheme/graphs/contributors
|
||||
%%
|
||||
%% and the original template was based on the HSRM theme by Benjamin Weiss.
|
||||
%%
|
||||
%% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
|
||||
%% International License (https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
%% ---------------------------------------------------------------------------
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{pgfplotsthemetol}
|
||||
[2015/06/16 PGFplots colors based on Paul Tol's SRON technical note]
|
||||
\definecolor{TolDarkPurple}{HTML}{332288}
|
||||
\definecolor{TolDarkBlue}{HTML}{6699CC}
|
||||
\definecolor{TolLightBlue}{HTML}{88CCEE}
|
||||
\definecolor{TolLightGreen}{HTML}{44AA99}
|
||||
\definecolor{TolDarkGreen}{HTML}{117733}
|
||||
\definecolor{TolDarkBrown}{HTML}{999933}
|
||||
\definecolor{TolLightBrown}{HTML}{DDCC77}
|
||||
\definecolor{TolDarkRed}{HTML}{661100}
|
||||
\definecolor{TolLightRed}{HTML}{CC6677}
|
||||
\definecolor{TolLightPink}{HTML}{AA4466}
|
||||
\definecolor{TolDarkPink}{HTML}{882255}
|
||||
\definecolor{TolLightPurple}{HTML}{AA4499}
|
||||
\pgfplotscreateplotcyclelist{mbarplot cycle}{%
|
||||
{draw=TolDarkBlue, fill=TolDarkBlue!70},
|
||||
{draw=TolLightBrown, fill=TolLightBrown!70},
|
||||
{draw=TolLightGreen, fill=TolLightGreen!70},
|
||||
{draw=TolDarkPink, fill=TolDarkPink!70},
|
||||
{draw=TolDarkPurple, fill=TolDarkPurple!70},
|
||||
{draw=TolDarkRed, fill=TolDarkRed!70},
|
||||
{draw=TolDarkBrown, fill=TolDarkBrown!70},
|
||||
{draw=TolLightRed, fill=TolLightRed!70},
|
||||
{draw=TolLightPink, fill=TolLightPink!70},
|
||||
{draw=TolLightPurple, fill=TolLightPurple!70},
|
||||
{draw=TolLightBlue, fill=TolLightBlue!70},
|
||||
{draw=TolDarkGreen, fill=TolDarkGreen!70},
|
||||
}
|
||||
\pgfplotscreateplotcyclelist{mlineplot cycle}{%
|
||||
{TolDarkBlue, mark=*, mark size=1.5pt},
|
||||
{TolLightBrown, mark=square*, mark size=1.3pt},
|
||||
{TolLightGreen, mark=triangle*, mark size=1.5pt},
|
||||
{TolDarkBrown, mark=diamond*, mark size=1.5pt},
|
||||
}
|
||||
\pgfplotsset{
|
||||
compat=1.9,
|
||||
mlineplot/.style={
|
||||
mbaseplot,
|
||||
xmajorgrids=true,
|
||||
ymajorgrids=true,
|
||||
major grid style={dotted},
|
||||
axis x line=bottom,
|
||||
axis y line=left,
|
||||
legend style={
|
||||
cells={anchor=west},
|
||||
draw=none
|
||||
},
|
||||
cycle list name=mlineplot cycle,
|
||||
},
|
||||
mbarplot base/.style={
|
||||
mbaseplot,
|
||||
bar width=6pt,
|
||||
axis y line*=none,
|
||||
},
|
||||
mbarplot/.style={
|
||||
mbarplot base,
|
||||
ybar,
|
||||
xmajorgrids=false,
|
||||
ymajorgrids=true,
|
||||
area legend,
|
||||
legend image code/.code={%
|
||||
\draw[#1] (0cm,-0.1cm) rectangle (0.15cm,0.1cm);
|
||||
},
|
||||
cycle list name=mbarplot cycle,
|
||||
},
|
||||
horizontal mbarplot/.style={
|
||||
mbarplot base,
|
||||
xmajorgrids=true,
|
||||
ymajorgrids=false,
|
||||
xbar stacked,
|
||||
area legend,
|
||||
legend image code/.code={%
|
||||
\draw[#1] (0cm,-0.1cm) rectangle (0.15cm,0.1cm);
|
||||
},
|
||||
cycle list name=mbarplot cycle,
|
||||
},
|
||||
mbaseplot/.style={
|
||||
legend style={
|
||||
draw=none,
|
||||
fill=none,
|
||||
cells={anchor=west},
|
||||
},
|
||||
x tick label style={
|
||||
font=\footnotesize
|
||||
},
|
||||
y tick label style={
|
||||
font=\footnotesize
|
||||
},
|
||||
legend style={
|
||||
font=\footnotesize
|
||||
},
|
||||
major grid style={
|
||||
dotted,
|
||||
},
|
||||
axis x line*=bottom,
|
||||
},
|
||||
disable thousands separator/.style={
|
||||
/pgf/number format/.cd,
|
||||
1000 sep={}
|
||||
},
|
||||
}
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `pgfplotsthemetol.sty'.
|
Binary file not shown.
@ -1,158 +0,0 @@
|
||||
\documentclass[10pt]{beamer}
|
||||
\beamertemplatenavigationsymbolsempty
|
||||
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{default}
|
||||
|
||||
\usepackage{graphicx}
|
||||
\graphicspath{{pictures/}}
|
||||
|
||||
\usepackage[french]{babel}
|
||||
\usepackage[T1]{fontenc}
|
||||
|
||||
\usetheme{metropolis}
|
||||
%\usecolortheme{dove}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Université de Technologie de Belfort-Montbéliard\\
|
||||
Département informatique}
|
||||
\vskip 4em
|
||||
\begin{center}
|
||||
{\LARGE Développement de nouveaux modules sur le projet Sith}\\
|
||||
\end{center}
|
||||
\vskip 4em
|
||||
Florent \textsc{Jacquet}\\
|
||||
Guillaume \textsc{Renaud}\\
|
||||
{\scriptsize TO52 - A16}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}
|
||||
\frametitle{Sommaire}
|
||||
\tableofcontents
|
||||
\end{frame}
|
||||
|
||||
\section{Les nouvelles applications}
|
||||
\subsection{Eboutic}
|
||||
\begin{frame}[fragile]\frametitle{Eboutic}
|
||||
\begin{itemize}
|
||||
\item Fournir une boutique
|
||||
\item Paiement en ligne en lien avec l'API du Credit Agricole
|
||||
\item Gestion des cotisations et rechargements
|
||||
\item Attention aux accès concurrentiels: pas visibles pendant le développement, car mono-thread, mais problèmes
|
||||
à la mise en production
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Le SAS}
|
||||
\begin{frame}[fragile]\frametitle{Le SAS - Stock à Souvenirs}
|
||||
\begin{itemize}
|
||||
\item Galerie de photos
|
||||
\item Upload simple pour tout le monde, même pour plusieurs dizaines de photos
|
||||
\item Modération et gestion des droits basée sur la gestion des fichiers, ce qui a permis d'améliorer ces
|
||||
derniers
|
||||
\item Problèmes d'optimisation de certaines pages qui mettaient plus de 9 secondes à générer (plus que 2s
|
||||
maintenant)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Les élections}
|
||||
\begin{frame}[fragile]\frametitle{Les élections}
|
||||
\begin{itemize}
|
||||
\item Grosse partie "gestion": c'est Sli qui a principalement développé l'application
|
||||
\item Revue des \textsc{merges request} et choix de design
|
||||
\item Problèmatique de législation vite ignorées puisque validation officielle en AG
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\subsection{La laverie}
|
||||
\begin{frame}[fragile]\frametitle{La laverie}
|
||||
\begin{itemize}
|
||||
\item Gestion d'un planning de reservation en prenant bien en compte les différents états (hors-service, ...) de
|
||||
chaque machine
|
||||
\item Génération de formulaires dynamiques en fonction des réservations (factory design pattern)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\subsection{La communication}
|
||||
\begin{frame}[fragile]\frametitle{La communication}
|
||||
\begin{itemize}
|
||||
\item Dynamise le site avec tous les textes paramètrables
|
||||
\item Fourni un système de news
|
||||
\item Fourni une newsletter
|
||||
\end{itemize}
|
||||
\begin{itemize}
|
||||
\item Envoie de mails en masse
|
||||
\item Beaucoup de templates
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\section{La gestion des stocks}
|
||||
|
||||
\subsection{Fonctionnement}
|
||||
\begin{frame}[fragile]{Fonctionnement}
|
||||
\begin{itemize}
|
||||
\item Création automatique des listes de courses
|
||||
\item Approvisionnement des stocks
|
||||
\item Prise d'éléments dans le stock
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Améliorations et difficultés}
|
||||
\begin{frame}[fragile]\frametitle{Améliorations et difficultés}
|
||||
\begin{itemize}
|
||||
\item Mise à jour quantité liste de courses
|
||||
\item Mise à jour automatique du stock selon les ventes
|
||||
\item Ajout au système de notifications
|
||||
\end{itemize}
|
||||
\textbf{Difficultés}
|
||||
\begin{itemize}
|
||||
\item Découverte du design pattern "factory" pour les formulaires dynamiques
|
||||
\item Apprentissage de Python, en plus du framework
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\section{Le rôle de mainteneur}
|
||||
|
||||
\subsection{Réviser les merge requests}
|
||||
\begin{frame}[fragile]\frametitle{Réviser les merge requests}
|
||||
\begin{itemize}
|
||||
\item Long et fastidieux
|
||||
\item Nécessaire pour maintenir une base de code cohérente
|
||||
\item Permet de retrouver les bugs des nouveaux contributeurs
|
||||
\item Oriente les contributeurs sur la bonne voie et la marche à suivre avec Django/Jinja2/etc...
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Gestion des bugs, des tickets, de la mise en production...}
|
||||
\begin{frame}[fragile]\frametitle{Gestion des bugs, des tickets, de la mise en production...}
|
||||
\begin{itemize}
|
||||
\item Ouverture/fermeture des tickets
|
||||
\item Mailing list/IRC
|
||||
\item Mise en production, gestion des migrations
|
||||
\item Restauration de la base de tests régulièrement
|
||||
\end{itemize}
|
||||
\par Organisation de la passation
|
||||
\end{frame}
|
||||
|
||||
\section{Conclusion}
|
||||
\begin{frame}[fragile]\frametitle{Conclusion}
|
||||
\begin{itemize}
|
||||
\item Apprentissage Django/Git
|
||||
\item Nouvelle mise en pratique des concepts de base de données relationnelles
|
||||
\item Utilisation poussée de Gitlab
|
||||
\item Formation de nouveaux contributeurs
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\begin{center}
|
||||
\textbf{Merci de votre attention}\\
|
||||
Questions?\\
|
||||
Remarques?\\
|
||||
\end{center}
|
||||
\end{frame}
|
||||
|
||||
\end{document}
|
1
docs/archives/TW_Skia/.gitignore
vendored
1
docs/archives/TW_Skia/.gitignore
vendored
@ -1 +0,0 @@
|
||||
_minted-Rapport
|
@ -1,13 +0,0 @@
|
||||
CC=pdflatex
|
||||
|
||||
all: rapport clean
|
||||
|
||||
rapport: Rapport.tex
|
||||
@echo "Compiling "$<
|
||||
$(CC) -shell-escape $<
|
||||
$(CC) -shell-escape $<
|
||||
|
||||
clean:
|
||||
@echo "Cleaning folder"
|
||||
rm *.aux; rm *.log; rm *.out; rm *.toc; rm *.snm; rm *.nav; rm *.lof
|
||||
|
Binary file not shown.
@ -1,683 +0,0 @@
|
||||
%%
|
||||
%
|
||||
% Skia
|
||||
% skia@libskia.so
|
||||
%
|
||||
%%
|
||||
|
||||
\documentclass[a4paper]{report}
|
||||
|
||||
%packages
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[francais]{babel}
|
||||
\usepackage{graphicx}\graphicspath{{pix/}}
|
||||
\usepackage{float}
|
||||
\usepackage{scrextend}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{color}
|
||||
\usepackage{fancyhdr}
|
||||
%Options: Sonny, Lenny, Glenn, Conny, Rejne, Bjarne, Bjornstrup
|
||||
\usepackage[Bjornstrup]{fncychap}
|
||||
\usepackage{minted}
|
||||
\usepackage[colorlinks=true,linkcolor=black]{hyperref}
|
||||
\usepackage{pdfpages}
|
||||
\usepackage{titlesec, blindtext, color}
|
||||
|
||||
%pdf metadata
|
||||
\hypersetup{
|
||||
unicode=true,
|
||||
colorlinks=true,
|
||||
citecolor=black,
|
||||
filecolor=black,
|
||||
linkcolor=black,
|
||||
urlcolor=black,
|
||||
pdfauthor={Skia <skia@libskia.so>},
|
||||
pdftitle={},
|
||||
pdfcreator={pdftex},
|
||||
pdfsubject={},
|
||||
pdfkeywords={},
|
||||
}
|
||||
|
||||
|
||||
\definecolor{keywords}{RGB}{200,0,90}
|
||||
\definecolor{comments}{RGB}{50,50,253}
|
||||
\definecolor{red}{RGB}{160,0,0}
|
||||
\definecolor{brown}{RGB}{160,100,100}
|
||||
\definecolor{green}{RGB}{0,200,0}
|
||||
\definecolor{darkgreen}{RGB}{0,130,0}
|
||||
\definecolor{gray}{RGB}{100,100,100}
|
||||
|
||||
|
||||
%inner meta
|
||||
\title{Architecture de Sith: le nouveau site AE}
|
||||
\author{Skia (Florent JACQUET)}
|
||||
\date{Dernière version: \today}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\maketitle
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\chapter{Introduction}
|
||||
\par Il y a longtemps, au début des années 2000, l'Association des Étudiants a mis en place un site internet qui n'a eu de
|
||||
cesse d'évoluer au fil des ans. Grâce aux différents contributeurs qui s'y sont plongés, et qui ont pu y ajouter leurs
|
||||
bouts de code plus ou moins utiles, le site possède désormais un ensemble de fonctionnalités impressionnant.
|
||||
\par De la comptabilité à la gestion de la laverie, en passant par le forum ou le Matmatronch', le site de l'AE prend
|
||||
actuellement en charge la quasi totalité de la gestion de l'argent, et c'est là un de ses rôles les plus importants.
|
||||
\par Mais les vieilles technologies qu'il emploie, et l'entretien plus ou moins aléatoire qu'il a subit, en font un
|
||||
outil très difficile à maintenir à l'heure actuelle, et le besoin d'une refonte s'imposait de plus en plus.
|
||||
\par Le choix de technologies récentes, maintenues, et éprouvées a donc été fait, et le développement a pu commencer dès
|
||||
Novembre 2015, avec l'objectif d'une mise en production dans l'été 2016, au moins dans une version incluant
|
||||
l'intégralité des fonctions liées à l'argent, qui sont les plus critiques.
|
||||
\par Soutenant les projets libres, j'ai décidé de placer le projet sous licence MIT, assurant ainsi une pérénité aux
|
||||
source. Si quelqu'un dans le futur souhaite le relicencier sous GPL (ou autre licence plus restrictive que la MIT, voire
|
||||
contagieuse), cela reste possible, mais je n'impose au départ que très peu de restrictions \footnote{La seule condition
|
||||
en réalité, est de toujours garder à sa place une copie de la licence originale, à savoir le fichier LICENSE à la racine
|
||||
du site.} .
|
||||
|
||||
\chapter{Les technologies}
|
||||
\label{cha:les_technologies}
|
||||
\par C'est là un des choix les plus important lors d'un tel projet, puisqu'il se fait au début, et qu'il n'est ensuite plus
|
||||
possible de revenir en arrière. Le PHP vieillissant, et
|
||||
piègeux\footnote{\url{https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/}} a donc été mis de côté au profit
|
||||
d'un language plus stable, le \emph{Python} dans sa version 3.
|
||||
|
||||
\section{Python3}
|
||||
\label{sec:python3}
|
||||
\par Le site étant développé en \emph{Python}, il est impératif d'avoir un environnement de développement approprié à ce
|
||||
language. L'outil \verb#virtualenv# permet d'installer un environnement \emph{Python} de manière locale, sans avoir besoin des
|
||||
droits root pour installer des packages. De plus cela permet d'avoir sur sa machine plusieurs environnements différents,
|
||||
adaptés à chaque projet, avec chacun des versions différentes des même paquets.
|
||||
\par La procédure pour installer son \verb#virtualenv# est décrite dans le fichier \verb#README# situé à la racine du
|
||||
projet.
|
||||
|
||||
\section{Django}
|
||||
\label{sec:django}
|
||||
\par \emph{Django} est un framework web pour \emph{Python}, apparu en 2005, et fournissant un grand nombre de
|
||||
fonctionnalités pour développer un site rapidement et simplement. Cela inclut entre autre un serveur Web, pour les
|
||||
échanges HTTP, un parseur d'URL, pour le routage des différentes URI du site, un ORM\footnote{Object-Relational Mapper}
|
||||
pour la gestion de la base de donnée, ou encore un moteur de templates, pour les rendus HTML.
|
||||
\par La version 1.8 de \emph{Django} a été choisie pour le développement de ce projet, car c'est une version LTS (Long Term
|
||||
Support), c'est à dire qu'elle restera stable et maintenue plus longtemps que les autres (au moins jusqu'en Avril 2018).
|
||||
\par La documentation est disponible à cette addresse: \url{https://docs.djangoproject.com/en/1.8/}. Bien que ce rapport
|
||||
présente dans les grandes lignes le fonctionnement de \emph{Django}, il n'est pas et ne se veut pas exhaustif, et la
|
||||
documentation restera donc toujours la référence à ce sujet.
|
||||
|
||||
\subsection{Le fichier de management et l'organisation d'un projet}
|
||||
\label{sub:Le fichier de management et l'organisation d'un projet}
|
||||
|
||||
\par Lors de la création d'un projet \emph{Django}, plusieurs fichiers sont créés. Ces fichiers sont essentiels pour le projet,
|
||||
mais ne contiennent en général pas de code à proprement parler. Ce n'est pas là qu'on y développe quoi que ce soit.
|
||||
|
||||
\subsubsection{manage.py}
|
||||
\label{ssub:manage.py}
|
||||
|
||||
\par Le fichier \verb-manage.py-, situé à la racine, permet de lancer toutes les tâches d'administration du site. Parmis
|
||||
elles:
|
||||
\begin{itemize}
|
||||
\item \textbf{startapp} \\
|
||||
Créer une application.
|
||||
\item \textbf{makemigrations} \\
|
||||
Parser les modèles pour créer les fichiers de migration de la base de donnée.
|
||||
\item \textbf{migrate} \\
|
||||
Appliquer les migrations sur la base de données.
|
||||
\item \textbf{runserver} \\
|
||||
Pour lancer le serveur Web, et donc le site en lui même, dans une version de développement.
|
||||
\item \textbf{makemessages} \\
|
||||
Pour générer les fichiers de traduction, dans le dossier \verb#locale#.
|
||||
\item \textbf{compilemessages} \\
|
||||
Pour compiler les fichiers de traduction, dans le dossier \verb#locale#, et passer de \verb#django.po# à
|
||||
\verb#django.mo#, sa version binaire, optimisée pour l'utilisation.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Un premier dossier}
|
||||
\label{ssub:Un premier dossier}
|
||||
\par Un premier dossier est toujours créé, du nom du projet, et contenant plusieurs fichiers: \verb#settings.py#,
|
||||
\verb#urls.py#, et \verb#wsgi.py#.
|
||||
|
||||
\par \verb#settings.py# est un fichier \emph{Python} servant à définir un grand nombre de constantes paramètrant le
|
||||
fonctionnement du site. L'avantage par rapport à un fichier de configuration classique est que ce dernier est
|
||||
executable, et on peut donc y mettre de la logique, afin d'avoir des paramètres dynamiques.
|
||||
|
||||
\par \verb#urls.py# est le fichier principale contenant les routes du site, c'est à dire les URLs existantes. Il se
|
||||
charge en général d'inclure les fichiers \verb#urls.py# de chaque application afin de garder une architecture modulaire
|
||||
et simple.
|
||||
|
||||
\par \verb#wsgi.py# contient quant à lui les paramètres pour la mise en production du site en tant qu'application WSGI
|
||||
(Web Server Gateway Interface) pour tourner derrière un serveur Web.
|
||||
|
||||
\subsection{Organisation d'une application}
|
||||
\label{sub:organisation_d_une_application}
|
||||
\par Lorsque l'on créer une application avec \verb#./manage.py startapp#, on obtient une fois de plus un dossier type.
|
||||
On trouve dans celui-ci un certain nombre de fichiers:
|
||||
\begin{itemize}
|
||||
\item \textbf{\_\_init\_\_.py} \\
|
||||
Permet de définir le dossier comme un package \emph{Python}. Ce fichier est généralement vide.
|
||||
\item \textbf{models.py} \\
|
||||
C'est là que l'on définit tous les modèles, c'est à dire toutes les classes qui définissent des tables dans la base
|
||||
de donnée.
|
||||
\item \textbf{views.py} \\
|
||||
Les vues y sont définies.
|
||||
\item \textbf{admin.py} \\
|
||||
C'est là que l'on déclare quels modèles doivent apparaîtrent dans l'interface fournie par le module
|
||||
d'administration.
|
||||
\item \textbf{tests.py} \\
|
||||
Ce dernier fichier sert à écrire les tests fonctionnels, unitaires, ou d'intégation à l'aide de la librairie de
|
||||
test de \emph{Django}.
|
||||
\item \textbf{migrations} \\
|
||||
Ce dossier sert à stocker les fichiers de migration de la base de donnée générés par \verb#./manage.py makemigrations#.
|
||||
\end{itemize}
|
||||
\vskip 1em
|
||||
\par On rajoute par la suite généralement plusieurs fichiers:
|
||||
\begin{itemize}
|
||||
\item \textbf{urls.py} \\
|
||||
Pour y définir toutes les URLs de l'application, et ensuite inclure ce fichier dans le fichier \verb#urls.py#
|
||||
global au projet.
|
||||
\item \textbf{templates} \\
|
||||
Celui-ci est un dossier, et on y remet en général un sous dossier du nom de l'application afin de s'en servir de
|
||||
namespace pour les templates.
|
||||
\end{itemize}
|
||||
\vskip 1em
|
||||
\par Dans le cas où un fichier \emph{Python} deviendrait trop gros ou trop complexe, il est toujours possible de le diviser en
|
||||
plusieurs fichiers que l'on met dans un dossier du même nom que ce fichier de départ, et contenant en plus un fichier
|
||||
\verb#__init__.py#. De plus, pour faciliter les imports depuis ce dossier, on peut mettre dans \verb#__init__.py# la
|
||||
ligne\footnote{Un exemple est disponible dans l'application core}:
|
||||
\mint{python}|from .[nom_de_fichier_sans_le_.py] import *|
|
||||
|
||||
\subsection{Les modèles avec l'ORM}
|
||||
\label{sub:les_modèles_avec_l_orm}
|
||||
|
||||
\subsubsection{Le modèle en lui même}
|
||||
\label{ssub:Le modèle en lui même}
|
||||
\par Rien ne vaudra un bon exemple pour comprendre comment sont construits les modèles avec \emph{Django}:
|
||||
\begin{addmargin}[-7em]{0em}
|
||||
\begin{minted}{python}
|
||||
class Club(models.Model): # (1)
|
||||
"""
|
||||
The Club class, made as a tree to allow nice tidy organization
|
||||
""" # (2)
|
||||
name = models.CharField(_('name'), max_length=30) # (3)
|
||||
parent = models.ForeignKey('Club', related_name='children', null=True, blank=True) # (4)
|
||||
unix_name = models.CharField(_('unix name'), max_length=30, unique=True,
|
||||
validators=[ # (5)
|
||||
validators.RegexValidator(
|
||||
r'^[a-z0-9][a-z0-9._-]*[a-z0-9]$',
|
||||
_('Enter a valid unix name. This value may contain only '
|
||||
'letters, numbers ./-/_ characters.')
|
||||
),
|
||||
],
|
||||
error_messages={ # (6)
|
||||
'unique': _("A club with that unix name already exists."),
|
||||
},
|
||||
)
|
||||
address = models.CharField(_('address'), max_length=254)
|
||||
email = models.EmailField(_('email address'), unique=True)
|
||||
owner_group = models.ForeignKey(Group, related_name="owned_club",
|
||||
default=settings.SITH_GROUP_ROOT_ID) # (7)
|
||||
edit_groups = models.ManyToManyField(Group, related_name="editable_club", blank=True) # (8)
|
||||
view_groups = models.ManyToManyField(Group, related_name="viewable_club", blank=True)
|
||||
home = models.OneToOneField(SithFile, related_name='home_of_club', verbose_name=_("home"), null=True, blank=True,
|
||||
on_delete=models.SET_NULL) # (9)
|
||||
\end{minted}
|
||||
\end{addmargin}
|
||||
\par Explications:
|
||||
\begin{description}
|
||||
\item[(1)] Un modèle hérite toujours de \verb#models.Model#. Il peut y avoir des intermédiaires, mais \verb#Model#
|
||||
sera toujours en haut.
|
||||
\item[(2)] Toujours penser à commenter le modèle.
|
||||
\item[(3)] Un premier attribut: \verb#name#, de type \verb#CharField#. Il constitue une colonne dans la base de
|
||||
donnée une fois que \verb#./manage.py migrate# a été appliqué.
|
||||
\item[(4)] Une \verb#ForeignKey#, l'une des relations les plus utilisées. \verb#related_name# précise le nom qui sert
|
||||
de retour vers cette classe depuis la classe pointée. Ici, elle est même récursive, puisque l'on pointe vers la
|
||||
classe que l'on est en train de définir, ce qui donne au final une structure d'arbre.
|
||||
\item[(5)] On peut toujours préciser des \verb#validators#, afin que le modèle soit contraint, et que \emph{Django}
|
||||
maintienne toujours des informations cohérentes dans la base.
|
||||
\item[(6)] Un message d'erreur peut être précisé pour expliciter à l'utilisateur les problèmes rencontrés.
|
||||
\item[(7)] On utilise ici le champ \verb#default# pour préciser une valeur par défaut au modèle, et celui-ci est
|
||||
affecté à une valeur contenue dans les \verb#settings# de \emph{Django}.
|
||||
\item[(8)] Les \verb#ManyToManyField# permettent de générer automatiquement une table intermédiaire de manière
|
||||
transparente afin d'avoir des relations doubles dans les deux classes mises en jeu.
|
||||
\item[(9)] Le \verb#OneToOneField# est très utilisé pour étendre une table avec des informations supplémentaires
|
||||
sans toucher à la table originale.
|
||||
\item[PRIMARY KEY] Les plus observateurs d'entre vous auront remarqué qu'il n'y a pas ici de \verb#PRIMARY KEY# de précisé. En
|
||||
effet, \emph{Django} s'en occupe automatiquement en rajoutant un champ \verb#id# jouant ce rôle. On peut alors y
|
||||
accèder en l'appelant par son nom, \verb#id# la plupart du temps, sauf s'il a été personnalisé, ou bien par
|
||||
l'attribut générique \verb#pk#, toujours présent pour désigner la \verb#PRIMARY KEY# d'un modèle, quelle qu'elle
|
||||
soit.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{Les migrations}
|
||||
\label{ssub:Les migrations}
|
||||
\par Les migrations sont à lancer à chaque fois que l'on modifie un modèle. Elles permettent de conserver la base de
|
||||
donnée tout en la faisant évoluer dans sa structure, pour ajouter ou supprimer une colonne dans une table par exemple.
|
||||
\par Lancer la commande \verb#./manage.py makemigrations [nom de l'appli]# va permettre de générer un fichier \emph{Python}
|
||||
automatiquement, qui sera mis à la suite des précédents, et qui sera appliqué sur la base au moment du lancement de
|
||||
\verb#./manage.py migrate#.
|
||||
|
||||
\subsection{Les vues}
|
||||
\label{sub:les_vues}
|
||||
\par Les vues sont les parties de code s'occupant de l'interface avec l'utilisateur. Elles sont appelées par les URLs,
|
||||
et renvoient des réponses HTTP en fonction du traitement effectué.
|
||||
|
||||
\subsubsection{Les URL}
|
||||
\label{ssub:Les URL}
|
||||
\par Les URLs sont définies par application, et centralisées dans le dossier du projet. Il s'agit à chaque fois d'une
|
||||
liste d'appel à la fonction \verb#url()#, qui comprends toujours une expression rationnelle décrivant l'URL, une
|
||||
fonction passée en tant que callback qui sera appelé au moment où l'URL est résolue, et enfin un nom, permettant de s'y
|
||||
référer dans les fonctions de résolution inverse, comme dans les templates par exemple. Nous détaillerons cette
|
||||
utilisation plus tard.
|
||||
|
||||
\par Pour garder une organisation claire, les URLs sont classées par espaces de noms (namespace) afin d'avoir à éviter
|
||||
de préfixer tous les noms pour s'y retrouver. Le namespace d'une URL est généralement le même nom que celui de
|
||||
l'application dans laquelle elle se trouve.
|
||||
|
||||
\subsubsection{Les fonctions de vue}
|
||||
\label{ssub:Les fonctions de vue}
|
||||
\par Une fonction de vue prend toujours en paramètre une variable \verb#request# et renvoie toujours un objet
|
||||
\verb#HTTPResponse#, contenant un code de retour HTTP, ainsi qu'une chaîne de caractères contenant la réponse en elle
|
||||
même.
|
||||
\par Entre temps, le traitement des informations permet de mettre à jour, de créer, ou de supprimer les objets définis
|
||||
dans les modèles, par le biais des paramètres passé dans la requête. Ainsi, on peut accèder aux informations des
|
||||
variables \verb#GET# et \verb#POST# très facilement en appelant respectivement \verb#request.GET['ma_clef']# et
|
||||
\verb#request.POST['ma_clef']#, ces deux variables fonctionnant comme des dictionnaires.
|
||||
|
||||
\subsubsection{Des vues basées sur des classes}
|
||||
\label{ssub:Des vues basées sur des classes}
|
||||
\par Les vues avec \emph{Django} peuvent aussi être définies comme des classes. Elles héritent alors à ce moment là
|
||||
toutes de la classe \verb#View#, mais ont toutefois souvent beaucoup d'intermédiaires et n'héritent donc pas directement
|
||||
de cette dernière.
|
||||
\par L'avantage de ces vues sous forme de classe est de pouvoir séparer toute la chaîne de traitement entre les
|
||||
différentes méthodes, et ainsi permettre, en jouant avec l'héritage, de fournir alors très peu d'informations à la
|
||||
classe, tout en lui permettant d'effectuer un travail correct.
|
||||
\par Ainsi, on retrouve de base, dans les filles de \verb#View#, un grand nombre de classes prédéfinies pour la plupart
|
||||
des comportement. \verb#DetailView#, \verb#CreateView#, \verb#ListView#, sont quelques exemples de classes renvoyant
|
||||
respectivement un objet en détails, un formulaire pour créer un nouvel objet, et enfin une liste d'objets. Il existe
|
||||
cependant un bon nombre de ces vues fournissant d'autres fonctionnalités, et si malgré tout, aucune ne peut convenir, il
|
||||
reste possible de se baser sur l'une d'elle et surcharger l'une de ses fonctions pour l'adapter à ses besoins.
|
||||
\par L'écosystème des \verb#class-based views# étant toutefois assez complexe et riche, un site web a été créé afin
|
||||
d'offrir un bon résumé de la situation: \emph{Classy class-based views}, accessible à l'adresse
|
||||
\url{http://ccbv.co.uk/}.
|
||||
|
||||
\section{Jinja2}
|
||||
\label{sec:jinja2}
|
||||
\par \emph{Jinja2} est un moteur de template écrit en \emph{Python} qui s'inspire fortement de la syntaxe des templates de
|
||||
\emph{Django}, mais qui apporte toutefois son lot d'améliorations non négligeables. En effet, l'ajout des macros, par
|
||||
exemple, permet de factoriser une grande partie du code.
|
||||
\par Un moteur de template permet de générer du contenu textuel de manière procédural en fonction des données à
|
||||
afficher. Cela permet en pratique de pouvoir inclure du code proche de \emph{Python} dans la syntaxe au milieu d'un
|
||||
document contenant principalement du HTML. Ainsi, si on a une liste d'objets, on peut facilement executer une boucle
|
||||
\verb#for# afin de faire afficher simplement tous les objets selon le même format.
|
||||
\noindent De même, il est facile d'inclure un \verb#if# pour décider à l'execution d'afficher ou non un lien en fonction
|
||||
des droits que l'utilisateur possède sur le site, par exemple.
|
||||
\par En plus des structures conditionnelles classiques, un moteur de templates permet de formater des données plus
|
||||
simplement, comme par exemple des dates, en fonction de la langue actuellement utilisée par l'utilisateur.
|
||||
\par Enfin, bien utilisés, les templates permettent d'utiliser des fonctions d'inclusion, ce qui permet de hiérarchiser
|
||||
les fichiers, et de s'assurer de l'unité de certaines parties du site. Ainsi, les \emph{headers}, les \emph{footers}, et
|
||||
autres menus que l'on retrouve sur toutes les pages du site sont définis chacun dans un seul fichier et inclus dans
|
||||
tous les autres.
|
||||
|
||||
\subsection{Exemple de template Jinja2}
|
||||
\label{sub:exemple_de_template_jinja2}
|
||||
|
||||
\begin{addmargin}[-4em]{0em}
|
||||
\begin{minted}{jinja}
|
||||
{% extends "core/base.jinja" %} {# (1) #}
|
||||
|
||||
{% block title %} {# (2) #}
|
||||
{% trans user_name=user.get_display_name() %}{{ user_name }}'s tools{% endtrans %} {# (3) #}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h3>{% trans %}User Tools{% endtrans %}</h3> {# (4) #}
|
||||
<p><a href="{{ url('core:user_profile', user_id=request.user.id) }}{# (5) #}">
|
||||
{% trans %}Back to profile{% endtrans %}</a>
|
||||
</p>
|
||||
|
||||
<h4>{% trans %}Sith management{% endtrans %}</h4>
|
||||
<ul>
|
||||
{% if user.is_root %} {# (6) #}
|
||||
<li><a href="{{ url('core:group_list') }}">{% trans %}Groups{% endtrans %}</a></li>
|
||||
{% endif %}
|
||||
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
||||
<li><a href="{{ url('accounting:bank_list') }}">Accounting</a></li>
|
||||
{% endif %}
|
||||
{% if user.is_board_member or user.is_root %}
|
||||
<li><a href="{{ url('subscription:subscription') }}">Subscriptions</a></li>
|
||||
<li><a href="{{ url('counter:admin_list') }}">Counters management</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
<h4>{% trans %}Club tools{% endtrans %}</h4>
|
||||
<ul>
|
||||
{% for m in user.memberships.filter(end_date=None).all() %} {# (7) #}
|
||||
<li><a href="{{ url('club:tools', club_id=m.club.id) }}">{{ m.club }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
\end{minted}
|
||||
\end{addmargin}
|
||||
|
||||
\begin{description}
|
||||
\item[(1)] Nous faisons ici une extension d'un template existant afin de bénéficier des blocs déjà défini, et afin
|
||||
d'intégrer le contenu de ce template dans celui déjà défini.
|
||||
\item[(2)] \verb#title# est un bloc défini dans le template \verb#base.jinja#. Le redéfinir joue alors le même rôle
|
||||
qu'une surcharge de méthode dans de l'héritage, et permet de remplacer le contenu du bloc, tout en conservant sa
|
||||
place dans le template parent.
|
||||
\item[(3)] La variable \verb#user# faisant ici partie du contexte, nous pouvons donc appeler une de ses méthodes
|
||||
pour obtenir un contenu dynamiquement.
|
||||
\item[(4)] Les blocs \verb#{% trans %}# et \verb#{% endtrans %}# permettent de définir les chaînes qui vont ensuite
|
||||
être traduites.
|
||||
\item[(5)] L'appel à la fonction \verb#url()# permet de résoudre la route afin d'obtenir l'adresse appropriée en
|
||||
fonction des arguments passé. Cette fonction fait généralement partie du contexte global, et est donc accessible
|
||||
dans tous les templates.
|
||||
\item[(6)] Les structures conditionnelles permettent d'afficher ou pas un élément en fonction de la valeur d'une
|
||||
variable ou du retour d'une fonction.
|
||||
\item[(7)] Le \verb#for# permet, comme en Python, d'itérer sur les éléments d'une liste. Ici, on fait même une
|
||||
requête via l'ORM de \emph{Django} en utilisant un filtre pour obtenir directement des valeurs depuis la base de
|
||||
donnée de manière transparente.
|
||||
\end{description}
|
||||
|
||||
\subsection{Le contexte}
|
||||
\label{sub:le_contexte}
|
||||
\par Le contexte dans lequel le template s'execute influe beaucoup sur la capacité de \emph{Jinja} à s'adapter
|
||||
dynamiquement au contenu. Plus on a de variables disponibles, plus on va pouvoir générer un contenu s'y adaptant.
|
||||
\par Il est possible de définir le contexte global, et donc ce qui est accessible dans tous les templates, comme il est
|
||||
possible d'ajouter manuellement et spécifiquement des variables au contexte pour un template particulier, dans une vue
|
||||
particulière.
|
||||
|
||||
\chapter{Organisation du projet}
|
||||
\label{cha:organisation_du_projet}
|
||||
|
||||
\par Après cette présentations des différentes technologies employées dans le projet, passons maintenant à une partie plus
|
||||
spécifique à Sith en lui même.
|
||||
|
||||
\section{Les options spécifiques}
|
||||
\label{sec:les_options_sp_cifiques}
|
||||
|
||||
\subsection{Django-jinja}
|
||||
\label{sub:django_jinja}
|
||||
\par \emph{Jinja} n'étant pas inclus de base dans \emph{Django}, le paquet \emph{Django-jinja} a été mis en place afin
|
||||
de bénéficier au mieux des performances de chacun, comme les filtres personnalisés de \emph{Django} dans la puissance des
|
||||
macros de \emph{Jinja}. Tout cela se trouve dans la variable \verb#TEMPLATES#.
|
||||
\par \emph{Jinja} a été ajouté afin de s'occuper uniquement des fichiers ayant l'extension \verb#.jinja# dans les
|
||||
dossiers \verb#templates# de chaque application.
|
||||
\par Un certain nombre de variables et fonctions ont été ajoutés au contexte global. Parmis elles, l'ensemble des
|
||||
filtres que \emph{Django} fournit, mais aussi un filtre pour passer de \emph{Markdown} à \emph{HTML}, l'ensemble du
|
||||
contenu de \verb#settings#, et enfin des fonction utiles dont voici la liste:
|
||||
\begin{itemize}
|
||||
\item \textbf{can\_edit\_prop} permet, en fonction d'une variable \verb#user# et d'un objet, de savoir si
|
||||
l'utilisateur donnée peut modifier les propriétés de cet objet.
|
||||
\item \textbf{can\_edit} permet, en fonction d'une variable \verb#user# et d'un objet, de savoir si
|
||||
l'utilisateur donnée peut éditer l'objet.
|
||||
\item \textbf{can\_view} permet, en fonction d'une variable \verb#user# et d'un objet, de savoir si
|
||||
l'utilisateur donnée peut voir l'objet.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Le fichier \textbf{settings\_custom.py}}
|
||||
\label{sub:le_fichier_settings_custom.py}
|
||||
\par Afin de faciliter la configuration des différentes instances du projet, un fichier \verb#settings_custom.py# a été
|
||||
créé à côté de \verb#settings.py#. Celui-ci est automatiquement inclu à la fin de \verb#settings.py#, pour que tout ce
|
||||
qui est défini dans le \verb#_custom# vienne remplacer les valeurs par défaut. Seul \verb#settings.py# est versionné
|
||||
dans \emph{Git}, et est exhaustif concernant la configuration et les variables requises. \verb#settings_custom.py# quant
|
||||
à lui n'est même pas obligatoire, et s'il existe, ne peut contenir que quelques variables qui diffèrent de la
|
||||
configuration par défaut\footnote{Typiquement, ajouter \textbf{DEBUG=True} }.
|
||||
|
||||
|
||||
\section{Les commandes ajoutées}
|
||||
\label{sec:les_commandes_ajoutees}
|
||||
\par Si cela ne suffit pas, il est possible d'enrichir de nouvelles commandes le script \verb#manage.py#. Cela a été fait
|
||||
pour \emph{Sith}, afin de pouvoir très rapidement déployer un environnement en ayant déjà les quelques données
|
||||
nécéssaires au fonctionnement du projet, comme le groupe \verb#root# par exemple.
|
||||
|
||||
\subsection{setup}
|
||||
\label{sub:setup}
|
||||
\par La fonction \verb#setup# s'occupe simplement de supprimer le fichier \verb#db.sqlite3#, qui est le fichier de base
|
||||
de donnée utilisé pour le développement, et relance une procédure de migration pour reconstruire une base de donnée
|
||||
propre avant de la peupler.
|
||||
\par Cette commande permet donc de s'assurer que la base de donnée utilisée est neuve et non corrompue.
|
||||
|
||||
\subsection{populate}
|
||||
\label{sub:populate}
|
||||
\par \verb#populate# permet de remplir la base de donnée avec dans un premier temps les données \textbf{nécessaires} au
|
||||
bon fonctionnement du site. Cela comprend notamment un superutilisateur, les groupes définis dans
|
||||
\verb#settings.SITH_GROUP_*_ID#, dont le groupe \verb#root# fait partie, une première page de Wiki, ainsi qu'un club
|
||||
racine, l'AE dans notre cas.
|
||||
\par Cette fonction prend un éventuel argument, \verb#--prod#, qui lui permet de mettre en place le strict minimum
|
||||
énoncé précédemment. Sinon, elle continue en ajoutant un certain nombre de données pratiques pour le développement,
|
||||
comme un certain nombre d'utilisateurs avec différents droits, de nouvelles pages dans le Wiki, de nouveaux clubs, des
|
||||
comptoirs et des produits, ou encore des données de comptabilité.
|
||||
\par L'argument \verb#--prod# peut, en outre, être passé directement depuis la fonction \verb#setup#.
|
||||
|
||||
\chapter{Les applications}
|
||||
\label{cha:les_applications}
|
||||
\par Chaque application va être détaillée ici. Cela permet de mettre en valeur le rôle de chacune, et de signaler les
|
||||
éventuelles particularités qui peuvent s'y trouver.
|
||||
|
||||
\section{Core}
|
||||
\label{sec:core}
|
||||
\subsection{Résumé}
|
||||
\label{sub:resume}
|
||||
\par L'application \emph{Core} est de loin la plus importante de toutes. C'est elle qui gère les utilisateurs ainsi que
|
||||
leurs droits. Le CMS y est aussi définit pour tout ce qui est pages de Wiki, pages statiques, ou l'ajout du filtre
|
||||
\verb#markdown# pour les templates.
|
||||
|
||||
\subsection{Liste des modèles}
|
||||
\label{sub:liste_des_modeles}
|
||||
\begin{itemize}
|
||||
\item \textbf{Group} \\
|
||||
Ce modèle se subdivise en deux: RealGroup et MetaGroup, décrivants respectivement un vrai groupe géré à la main
|
||||
dans la liste des groupes, et un meta-groupe, géré automatiquement, en général par les clubs, ou bien par les
|
||||
cotisations.
|
||||
\item \textbf{User} \\
|
||||
Le modèle des utilisateurs, qui est ensuite décliné ou référencé dans beaucoup d'applications pour les
|
||||
utilisations spécifiques. C'est toutefois ici que sont déclarés les fonctions de gestion des droits des
|
||||
utilisateurs, afin de pouvoir les utiliser partout ailleurs.
|
||||
\item \textbf{AnonymousUser} \\
|
||||
Cette classe n'est pas un modèle stocké en base, puisqu'elle sert à instancier la variable \verb#user#
|
||||
lorsqu'aucun utilisateur n'est connecté au site.
|
||||
\item \textbf{Page} \\
|
||||
Décrit une entité page, servant dans le Wiki ou pour les pages statiques du site. Cette classe s'occupe des
|
||||
méta-données de la page, comme ses droits, mais son contenu est en réalité stocké dans un objet \verb#PageRev#.
|
||||
\item \textbf{PageRev} \\
|
||||
Décrit une révision de page. Utiliser une autre classe avec une \verb#ForeignKey# permet de gérer facilement un
|
||||
historique des révisions.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{La gestion des droits}
|
||||
\label{sub:la_gestion_des_droits}
|
||||
\par La gestion des droits est implémentée de manière globale dans l'application Core.
|
||||
\par On trouve en effet dans \verb#views/__init__.py# un certain nombre de mixins \footnote{Un mixin est, dans
|
||||
\emph{Django}, un terme désignant une classe abstraite qui ne peut pas servir de parente seule. Elle permet de
|
||||
surcharger certaines méthodes d'une autre classe abstraite afin de l'adapter à un comportement plus spécifique, mais
|
||||
reste totalement inutile quand elle est seule. La gestion des droits est un bon exemple puisqu'elle ne s'occupe pas
|
||||
vraiment de traitement des données comme les autres vues le feraient, elle permet simplement d'ajouter une condition à une
|
||||
autre classe où cette dernière renverrait un \emph{403 Forbidden} } s'occupant de cela, en se basant sur
|
||||
un modèle général permettant de rendre compatible rapidement n'importe quel modèle que l'on voudrait protéger. Il suffit
|
||||
alors de déclarer dans la classe une certain nombre de méthodes et/ou d'attributs, le reste étant simplement déjà pris
|
||||
en charge par les mixins suivants:
|
||||
\begin{itemize}
|
||||
\item \textbf{CanCreateMixin} \\
|
||||
Cette classe est à mettre en parente d'une classe héritant de \verb#CreateView#, afin d'empêcher quelqu'un
|
||||
n'ayant pas les droits de créer un objet.\\
|
||||
Méthode correspondante à créer dans les modèles: \\
|
||||
\verb#def can_be_created_by(user):# \\
|
||||
(Attention, ce n'est pas une méthode prenant \verb#self# en premier paramètre!)
|
||||
\item \textbf{CanEditPropMixin} \\
|
||||
Cette classe protège l'objet pour l'édition avancée. Par exemple: éditer les droits sur une page, ou éditer les
|
||||
droits accordé à un utilisateur. \\
|
||||
Attribut correspondant à créer dans les modèles: \\
|
||||
\verb#owner_group = models.ForeignKey(Group, # \\
|
||||
\verb# related_name="owned_user", default=settings.SITH_GROUP_ROOT_ID)# \\
|
||||
Méthode correspondante à créer dans les modèles: \\
|
||||
\verb#def is_owned_by(self, user):# \\
|
||||
\item \textbf{CanEditMixin} \\
|
||||
Cette classe protège l'objet pour l'édition non avancée. Par exemple: éditer une page, ou éditer le profil d'un
|
||||
utilisateur. \\
|
||||
Attribut correspondant à créer dans les modèles: \\
|
||||
\verb#edit_groups = models.ManyToManyField(Group, # \\
|
||||
\verb# related_name="editable_user", blank=True)# \\
|
||||
Méthode correspondante à créer dans les modèles: \\
|
||||
\verb#def can_be_edited_by(self, user):# \\
|
||||
\item \textbf{CanViewMixin} \\
|
||||
Cette classe protège l'objet pour la vue. Par exemple: consulter une page, ou voir le profil d'un utilisateur. \\
|
||||
Attribut correspondant à créer dans les modèles: \\
|
||||
\verb#view_groups = models.ManyToManyField(Group, # \\
|
||||
\verb# related_name="viewable_user", blank=True)# \\
|
||||
Méthode correspondante à créer dans les modèles: \\
|
||||
\verb#def can_be_viewed_by(self, user):# \\
|
||||
\end{itemize}
|
||||
\par Pour savoir si l'on doit implémenter les méthodes, les attributs, ou les deux, il faut simplement se poser la
|
||||
question de savoir si l'objet en question requiert une gestion des droits à l'échelle de la classe ou à l'échelle de
|
||||
l'objet, et si cette gestion peut être calculé par de la logique.
|
||||
\par Si on a besoin d'une gestion pour la classe, ou si du code peut être implémenter pour déterminer qui peut avoir tel
|
||||
droit, alors la méthode suffira. Mais si on a besoin d'une gestion au niveau de l'objet, alors il faudra certainement
|
||||
recourir aux attributs.
|
||||
\par Exemples:
|
||||
\begin{itemize}
|
||||
\item Les comptes en banque sont gérés uniquement par les personnes faisant partie du groupe \verb#admin-compta#.
|
||||
Ils ont donc tous les mêmes droits, c'est une gestion au niveau de la classe, donc les méthodes suffisent.
|
||||
\item Les classeurs de comptabilité sont gérés par les trésoriers des clubs, ils n'ont pas tous les mêmes droits,
|
||||
mais cela peut tout de même se calculer en fonction des postes dans les clubs correspondants. On a donc besoin
|
||||
des méthodes uniquement.
|
||||
\item Les pages n'appartiennent pas forcément à un club, ni à une quelconque entité, mais ont tout de même besoin de
|
||||
gestion des droits au niveau de l'objet. L'ajout des attributs est donc nécessaire pour pouvoir gérer cela au
|
||||
cas par cas.
|
||||
\end{itemize}
|
||||
|
||||
\section{Subscription}
|
||||
\label{sec:subscription}
|
||||
\subsection{Résumé}
|
||||
\label{sub:resume}
|
||||
\par Cette application ajoute le support des cotisations. Elle fournit également les interfaces de cotisation.
|
||||
|
||||
\subsection{Liste des modèles}
|
||||
\label{sub:liste_des_modeles}
|
||||
\begin{itemize}
|
||||
\item \textbf{Subscription} \\
|
||||
Un modèle cotisation, pour stocker ces dernières. Cette classe fait automatiquement les calculs de début et de
|
||||
fin de cotisation en fonction de la date du jour, du type de cotisation, et de la durée en semestre de
|
||||
cotisation.
|
||||
\end{itemize}
|
||||
|
||||
\section{Accounting}
|
||||
\label{sec:accounting}
|
||||
\subsection{Résumé}
|
||||
\label{sub:resume}
|
||||
\par Cette application sert à gérer la comptabilité. Elle est architecturée de façon hiérarchique, avec en haut, les
|
||||
comptes bancaires réels, qui contiennent eux des comptes de clubs, permettant de les diviser en plusieurs petits comptes
|
||||
en interne, et enfin les classeurs de trésorerie, propres à chaque compte club, permettant de faire les comptes en
|
||||
triant par semestre.
|
||||
\par De plus, cette application définit un nouveau type de champ dans la base de donnée: le champ \verb#CurrencyField#,
|
||||
permettant de stocker de valeurs monétaires.
|
||||
|
||||
\subsection{Liste des modèles}
|
||||
\label{sub:liste_des_modeles}
|
||||
\begin{itemize}
|
||||
\item \textbf{BankAccount} \\
|
||||
Le modèle des comptes bancaires.
|
||||
\item \textbf{ClubAccount} \\
|
||||
Le modèle des comptes clubs.
|
||||
\item \textbf{GeneralJournal} \\
|
||||
Le modèle des classeurs de comptabilité, généralement semestriels, mais ils peuvent toutefois fonctionner en
|
||||
année pour les activités plus longues comme le Gala.
|
||||
\item \textbf{AccountingType} \\
|
||||
Le modèle pour stocker les types comptables, servant à remplir les opérations.
|
||||
\item \textbf{SimpleAccountingType} \\
|
||||
Le modèle pour stocker les types comptables simplifiés, servant à remplir les opérations.
|
||||
\item \textbf{Label} \\
|
||||
Le modèle pour stocker les étiquettes, servant à classifer les opérations.
|
||||
\item \textbf{Operation} \\
|
||||
Le modèle des opérations, servant à remplir les classeurs comptables. Une opération peut être un débit ou un
|
||||
crédit, et permet ensuite d'éditer des factures, par exemple.
|
||||
\end{itemize}
|
||||
|
||||
\section{Counter}
|
||||
\label{sec:counter}
|
||||
\subsection{Résumé}
|
||||
\label{sub:resume}
|
||||
\par Cette application s'occupe de la gestion des comptoirs. Elle définit ainsi des produits, et ajoute également le
|
||||
support du compte AE pour les utilisateurs.
|
||||
|
||||
\subsection{Liste des modèles}
|
||||
\label{sub:liste_des_modeles}
|
||||
\begin{itemize}
|
||||
\item \textbf{Customer} \\
|
||||
Ce modèle étend l'utilisateur pour lui rajouter un compte AE. Il est lié à la classe \verb#User# par un
|
||||
\verb#OneToOneField#.
|
||||
\item \textbf{ProductType} \\
|
||||
Ce modèle ajoute des types de produits afin de catégoriser ces derniers.
|
||||
\item \textbf{Product} \\
|
||||
Ce modèle décrit les produits pouvant être vendus dans les différents comptoirs.
|
||||
\item \textbf{Counter} \\
|
||||
Ce modèle décrit les comptoirs, qui permettent de générer des recharges de compte et des ventes de produits.
|
||||
\item \textbf{Refilling} \\
|
||||
Ce modèle permet de stocker les rechargements de compte.
|
||||
\item \textbf{Selling} \\
|
||||
Ce modèle permet d'enregistrer toutes les ventes de produits.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\section{Club}
|
||||
\label{sec:club}
|
||||
\subsection{Résumé}
|
||||
\label{sub:resume}
|
||||
\par Cette application permet de générer les clubs et les adhésions des utilisateurs à ceux-ci.
|
||||
|
||||
\subsection{Liste des modèles}
|
||||
\label{sub:liste_des_modeles}
|
||||
\begin{itemize}
|
||||
\item \textbf{Club} \\
|
||||
Le modèle des clubs.
|
||||
\item \textbf{Membership} \\
|
||||
Le modèle des adhésions. Stocker cela dans un modèle à part permet de conserver un historique des personnes
|
||||
ayant eu un rôle quelconque dans un club quelconque.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
\chapter{Conclusion}
|
||||
\par Encore une fois, ce rapport ne se veut absolument pas exhaustif sur quoi que ce soit.
|
||||
\par Concernant \emph{Python}, \emph{Django}, ou \emph{Jinja}, les documentations respectives sont toujours très bien
|
||||
faites, et permettront de répondre à toutes les questions techniques concernant les technologies.
|
||||
\par Concernant le projet \emph{Sith} en lui-même, ce rapport n'est pas non plus exhaustif. Pour cela, lire le code des
|
||||
différentes sections sera le meilleur moyen de comprendre le fonctionnement des différentes applications. Pour obtenir plus
|
||||
rapidement un résumé à jour des sources, le fichier \verb#Doxyfile# présent à la racine du site permet de regénérer de
|
||||
la documentation exhaustive rapidement à l'aide de \emph{Doxygen} (voir la section correspondante dans le README).
|
||||
\par J'espère toutefois que même s'il n'est pas complet, ce rapport permettra à tout futur contributeur de rentrer plus
|
||||
rapidement dans le projet.
|
||||
\par L'idéal serait également de maintenir à jour ce rapport du mieux possible en même temps que le développement
|
||||
avance, même si je ne me fais guère d'illusions en pratique.
|
||||
|
||||
\section{Pour le futur...}
|
||||
\label{sec:pour_le_futur}
|
||||
\par En l'état actuel des choses, un grand nombre d'éléments sont encore manquants au site:
|
||||
\begin{itemize}
|
||||
\item Une API REST pour pouvoir facilement intégrer d'autres outils autour du site.
|
||||
\item Du CSS, pour qu'il soit un peu plus joli à regarder.
|
||||
\item Du Javascript, et particulièrement de l'AJAX pour améliorer l'ergonomie de certaines pages.
|
||||
\item Un grand nombre de vues pour aider à gérer les données plus efficacement, ou à les gérer tout court dans
|
||||
certains cas.
|
||||
\item Quelques applications utiles à qui existent sur le site actuel, mais que je n'ai pas encore eu le temps de
|
||||
développer: un forum, une galerie de photos, une gestion basique des fichiers pour uploader des documents dans
|
||||
les pages ou le forum, un système de news, une newsletter (Weekmail), une gestion des sondages et des élections,
|
||||
etc...
|
||||
\end{itemize}
|
||||
|
||||
\section{Apports personnels}
|
||||
\label{sec:apports_personnels}
|
||||
\par Même s'il est vrai que j'ai beaucoup appris en développant ce site, cela reste avant tout un travail de quantité
|
||||
plus que de qualité: on définit des modèles, puis les vues correspondantes en terminant par les templates, et on répète
|
||||
l'opération pour l'application suivante.
|
||||
\par Mais j'ai tout de même pu mettre en place de l'intégration continue pour ce projet, ce qui a été certes, très
|
||||
rapide, mais toutefois très enrichissant, étant donnée que ces méthodes sont très en vogue ces derniers temps.
|
||||
\par J'ai également pu me familiariser d'avantage avec le fonctionnement d'un ORM, et la magie noire que cela permet de
|
||||
faire \footnote{Je trouve toujours magique de pouvoir faire une requête SQL au milieu d'un template sans que cela
|
||||
paraisse affreux :)}.
|
||||
\par Enfin, j'espère que ce projet va, en plus d'être correctement mené au bout, pouvoir être repris par la suite par
|
||||
les futurs membres de l'équipe info de l'AE, et pourquoi pas par d'autres contributeurs...
|
||||
\vskip 3em
|
||||
\emph{Skia <skia@libskia.so> - 2016}
|
||||
|
||||
\end{document}
|
||||
|
8
docs/explanation/archives.md
Normal file
8
docs/explanation/archives.md
Normal file
@ -0,0 +1,8 @@
|
||||
!!!note "Page générée"
|
||||
Cette page est générée à partir du wiki GitHub du projet puisqu'elle
|
||||
héberge du contenu binaire lourd qui encombrerait le repo git.
|
||||
La [page originale ici](https://github.com/ae-utbm/sith3/wiki/Archives) peut être plus à jour puisque le contenu
|
||||
de cette page date de la dernière génération de la documentation.
|
||||
|
||||
{! include-markdown 'https://raw.githubusercontent.com/wiki/ae-utbm/sith3/Archives.md', '') !}
|
||||
|
Reference in New Issue
Block a user