Zeste de Savoir Documentation

Transcription

Zeste de Savoir Documentation
Zeste de Savoir Documentation
Version 1.0
firm1
20 April 2015
Table des matières
1
Sommaire
1.1 Installation . . . . . . . . . . . . . . .
1.2 Workflow . . . . . . . . . . . . . . . .
1.3 Le back-end . . . . . . . . . . . . . .
1.4 Documentation technique du back-end
1.5 Le front-end . . . . . . . . . . . . . .
1.6 API . . . . . . . . . . . . . . . . . . .
1.7 Autres outils . . . . . . . . . . . . . .
Index des modules Python
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
18
20
43
50
61
67
69
i
ii
Zeste de Savoir Documentation, Version 1.0
Zeste de Savoir est un site internet communautaire codé à l’aide du framework Django 1.7 et de Python 2.7
Voir l’instance en ligne
Voir notre dépôt Github
Table des matières
1
Zeste de Savoir Documentation, Version 1.0
2
Table des matières
CHAPITRE 1
Sommaire
1.1 Installation
Si vous voulez installer et démarrer une instance locale de ZdS, vous devez cliquer sur le lien correspondant à votre
système d’exploitation.
1.1.1 Installation du backend sous Linux
Pour installer une version locale de ZdS sur GNU/Linux, veuillez suivre les instructions suivantes. Si une commande
ne passe pas, essayez de savoir pourquoi avant de continuer.
Certaines des commandes d’installation (débutant par apt-get) sont données ici pour Debian et ses dérivés, pour
lesquels il est sûr qu’elles fonctionnent. Néanmoins, si vous utilisez une distribution différente, le nom des paquets à
installer devrait être fort semblable, n’hésitez dès lors pas à employer la fonction “recherche” de votre gestionnaire de
paquet préféré. Les autres commandes sont génériques et indépendantes de la distribution utilisée.
NB : il est impératif que la locale fr_FR.UTF-8 soit installée sur votre distribution.
Assurez vous que les dépendances suivantes soient résolues :
— git : apt-get install git
— python2.7
— python-dev : apt-get install python-dev
— easy_install : apt-get install python-setuptools
— pip : easy_install pip
— tox : pip install tox
— geoip : apt-get install geoip (peut s’appeler geoip-bin sur certaines distributions telles que Debian)
— libgeoip-dev : apt-get install libgeoip-dev
— libxml2-dev : apt-get install libxml2-dev
— python-lxml : apt-get install python-lxml
— libxlst-dev (peut être appelée libxlst1-dev sur certains OS comme ubuntu
— libz-dev (peut être libz1g-dev sur système 64bits)
— python-sqlparse
— libjpeg8 libjpeg8-dev libfreetype6 libfreetype6-dev : apt-get install libjpeg8 libjpeg8-dev
libfreetype6 libfreetype6-dev
Ou, en une ligne,
apt-get install git python-dev python-setuptools ’^geoip(-bin)?$’ libgeoip-dev libxml2-dev python-lxm
easy_install pip tox
3
Zeste de Savoir Documentation, Version 1.0
Installation et configuration de virtualenv
(cette étape n’est pas obligatoire, mais fortement conseillée)
pip install virtualenv
virtualenv zdsenv --python=python2
À chaque fois que vous souhaitez travailler dans votre environement, activez le via la commande suivante :
source zdsenv/bin/activate
Pour sortir de votre environnement : deactive
Une documentation plus complète de cet outil est disponible ici.
Installation des outils front-end
Il vous faut installer les outils du front-end. Pour cela, rendez-vous sur la documentation dédiée.
Lancer ZdS
Une fois dans votre environnement python (source ../bin/activate si vous utilisez virtualenv, très fortement
conseillé), lancez l’installation complète :
pip install --upgrade -r requirements.txt -r requirements-dev.txt
python manage.py migrate
python manage.py runserver
Aller plus loin
Pour faire fonctionner ZdS dans son ensemble (ceci n’est pas obligatoire) vous pouvez installer les outils LateX,
Pandoc et les polices Microsoft. Ce qui revient à lancer les commmandes suivantes :
apt-get install --reinstall ttf-mscorefonts-installer
apt-get install texlive texlive-xetex texlive-lang-french texlive-latex-extra
apt-get install haskell-platform
cabal update
cabal install pandoc
Vous pouvez également indiquer à Git de ne pas effectuer de commit s’il y a des erreurs de formatage dans le code.
1.1.2 Installation du backend sous OS X
Pour installer une version locale de ZdS sur OS X, veuillez suivre les instructions suivantes. Si une commande ne
passe pas, essayez de savoir pourquoi avant de continuer.
Avant de vous lancez dans l’installation de l’environnement de zds, il faut quelques pré-requis :
— Installer XCode pour pouvoir exécuter des commandes (g)cc.
— Installer MacPorts pour récupérer certains paquets utiles pour l’installation des dépendances de ce projet.
— Installer python 2.7
— Installer pip
— Installer git
— Installer gettext
— Installer GeoIP (brew install geoip)
4
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Une fois les pré-requis terminés, vous pouvez vous lancer dans l’installaton de l’environnement de zds.
Installation de virtualenv
sudo port install virtualenv_select py27-virtualenv py27-virtualenvwrapper py27-tox
mkdir ~/.virtualenvs
echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.bash_profile && export WORKON_HOME=$HOME/.virtuale
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bash_profile && source /usr/local/bin/virtual
Création de votre environnement
mkvirtualenv zdsenv
Récupération de la librairie lxml pour python 2.7 via MacPorts
sudo port install py27-lxml
Ajout de flags pour compiler avec gcc plutôt que clang lors de l’installation de lxml
export CFLAGS=-Qunused-arguments
export CPPFLAGS=-Qunused-arguments
Installation des outils front-end
Il vous faut installer les outils du front-end. Pour cela, rendez-vous sur la documentation dédiée.
Installation de toutes les dépendances
pip install --upgrade -r requirements.txt -r requirements-dev.txt
npm install
gulp build
Pour relancer votre environnement : source ~/.virtualenvs/zdsenv/bin/activate Pour sortir de votre
environnement : deactive
Aller plus loin
Pour faire fonctionner ZdS dans son ensemble vous devez installer les outils LateX et Pandoc.
— Téléchagez et installez BasicTex
sudo port install texlive-basic
— Téléchargez et installez Pandoc
sudo port install pandoc
Vous pouvez également indiquer à Git de ne pas effectuer de commit s’il y a des erreurs de formatage dans le code.
1.1. Installation
5
Zeste de Savoir Documentation, Version 1.0
1.1.3 Installation du backend sous Windows
Pour installer une version locale de ZdS sur Windows, veuillez suivre les instructions suivantes. Si une commande ne
passe pas, essayez de savoir pourquoi avant de continuer.
Prérequis
— Téléchargez et installez les outils suivants :
— PowerShell 3.0+
— Git (Git pour Eclipse ne suffit pas ; associez les .sh)
— gettext
— Téléchargez et installez Python 2.7
— Installez setuptools : Démarrez Powershell en mode administrateur et lancez la commande suivante :
(Invoke-WebRequest https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py).Co
| python — Redémarrez Powershell
— Installez pip : easy_install pip
— Installez tox : pip install tox
— Désactivez la sécurité sur les script powershell Set-ExecutionPolicy RemoteSigned
— Installez Virtualenv avec les commandes suivante :
— pip install virtualenv
— pip install virtualenvwrapper-powershell
— Créez votre workspace dédié à ZdS
— set $env:WORKON_HOME
— mkdir ’~\.virtualenvs’
— Import-Module virtualenvwrapper
— New-VirtualEnvironment zdsenv --no-site-packages
— Cloner le dépot git via la console git (et pas via powershell) windows : git clone
https://github.com/zestedesavoir/zds-site.git
Installation des outils front-end
Il vous faut installer les outils du front-end. Pour cela, rendez-vous sur la documentation dédiée.
Suite de l’installation
— Dans la console PowerShell via l’environnement zdsenv installez les dépendances.
— easy_install lxml
— pip install -r requirements.txt -r requirements-dev.txt
— python manage.py migrate
— python manage.py runserver
— Pour redémarrer virtualenv les fois suivantes : ~\.virtualenvs\zdsenv\Scripts\activate.ps1
Pour faire fonctionner ZdS dans son ensemble vous devez installer les outils LateX et Pandoc.
— Téléchagez et installez MikTex
— Téléchargez et installez Pandoc
1.1.4 Configuration des serveurs de production
Zeste de Savoir est installé en 1 tiers (sur un seul serveur donc).
6
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Paramètres
Paramètres généraux
Paramètre
OS
Serveurs web
Moteur WSGI
SGBD
Contrôle des process
Surveillance
Valeur
Linux, Debian 7 “Wheezy”
Nginx
Gunicorn
MySQL
Supervisor
Munin
Paramètres spécifiques
Nom
IPv4
IPv6
Identifiant
Mot de passe
Préproduction
beta.zestedesavoir.com
46.105.246.77
x
Demande privée
Demande privée
Production
zestedesavoir.com
176.31.187.88
2001:41d0:52:100::b4f
Demande privée
Demande privée
Premier déploiement
Toute la procédure suppose un déploiement dans /opt/zdsenv.
Utilisateur local
Zeste de Savoir tourne sous l’utilisateur zds et le groupe root.
Installation des outils
— python,
— virtualenv (dans /opt/zdsenv/),
— git
Clone du repo et configuration de prod
—
—
—
—
—
git clone https://github.com/zestedesavoir/zds-site.git
mkdir tutoriels-private
mkdir tutoriels-public
mkdir articles-data
vim zds/settings_prod.py
On édite le fichier de manière à rajouter les infos spécifiques au serveur courant. Par exemple :
DEBUG = False
DATABASES = {
’default’: {
’ENGINE’: ’django.db.backends.mysql’,
1.1. Installation
7
Zeste de Savoir Documentation, Version 1.0
’NAME’: ’zdsdb’,
’USER’: ’zds’,
’PASSWORD’: ’mot_de_passe’,
’HOST’: ’localhost’,
’PORT’: ’’,
}
}
EMAIL_HOST = ’mail.geoffreycreation.com’
EMAIL_HOST_USER = ’[email protected]’
EMAIL_HOST_PASSWORD = ’mot_de_passe’
EMAIL_PORT = 25
Installation de l’application de base
Suivre l’installation complète sous Linux en tenant compte des subtilités suivantes :
— Installer les outils front
— Ne pas lancer le serveur à la fin de l’étape “Lancer ZdS”
— Installer toutes les dépendances requises à l’étape “Aller plus loin”
Outils spécifiques à un serveur de run
Gunicorn Installer Gunicorn dans le virtualenv.
Dans /opt/zdsenv/unicorn_start :
#!/bin/bash
NAME="ZesteDeSavoir"
DJANGODIR=/opt/zdsenv/ZesteDeSavoir/
SOCKFILE=/opt/zdsenv/bin/gunicorn.sock
USER=zds
GROUP=root
NUM_WORKERS=7 # how many worker processes
DJANGO_SETTINGS_MODULE=zds.settings # django settings file
DJANGO_WSGI_MODULE=zds.wsgi # WSGI modul
echo "Starting $NAME"
# Activate the virtual environment
cd $DJANGODIR
source ../bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--log-level=debug \
--timeout=300 \
--bind=unix:$SOCKFILE
8
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Nginx Installer nginx. Sous Debian, la configuration est splittée par site. Pour Zeste de Savoir, elle se fait dans
/etc/nginx/sites-available/zestedesavoir :
upstream zdsappserver {
server unix:/opt/zdsenv/bin/gunicorn.sock fail_timeout=0;
}
server {
server_name www.zestedesavoir.com;
rewrite ^(.*) http://zestedesavoir.com$1 permanent;
}
server {
listen [::]:80 ipv6only=on;
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/certs/zds/server.crt;
ssl_certificate_key /etc/ssl/certs/zds/server.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
server_name zestedesavoir.com;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml
access_log off;
access_log /opt/zdsenv/logs/nginx-access.log;
error_log /opt/zdsenv/logs/nginx-error.log;
location = /robots.txt {
alias /opt/zdsenv/ZesteDeSavoir/robots.txt ;
}
location /static/admin/ {
alias /opt/zdsenv/lib/python2.7/site-packages/django/contrib/admin/static/admin/;
}
location /static/ {
alias /opt/zdsenv/ZesteDeSavoir/static/;
expires 1d;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location /media/ {
alias /opt/zdsenv/ZesteDeSavoir/media/;
expires 1d;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location / {
#if ($http_host ~* "^www\.(.+)$"){
#rewrite ^(.*)$ http://%1$request_uri redirect;
#}
if ($uri !~ \. ){
rewrite ^(.*[^/])$ $1/ permanent;
}
client_max_body_size 100M;
proxy_read_timeout 1000s;
proxy_connect_timeout 1000s;
auth_basic "Qui es-tu noble etranger ?";
1.1. Installation
9
Zeste de Savoir Documentation, Version 1.0
auth_basic_user_file /home/zds/.htpasswdclose;
####proxy_pass http://176.31.187.88:8001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwaded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE_ADDR $remote_addr;
add_header P3P ’CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"’;
if (!-f $request_filename) {
proxy_pass http://zdsappserver;
break;
}
}
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /opt/zdsenv/ZesteDeSavoir/templates/;
}
}
Solr Voir la documentation de Solr <install-solr.html>.
Supervisor Installer supervisor.
Créer deux configurations :
Configuration ZdS La conf dans /etc/supervisor/conf.d/zds.conf permet de lancer Solr à l’aide de
supervisorctl start zds et l’arrêter avec supervisorctl stop zds.
[program:zds]
command = /opt/zdsenv/unicorn_start ;
user = zds ;
stdout_logfile = /opt/zdsenv/logs/gunicorn_supervisor.log ;
redirect_stderr = true ;
Configuration Solr La conf dans /etc/supervisor/conf.d/solr.conf permet de lancer Solr à l’aide de
supervisorctl start solr et l’arrêter avec supervisorctl stop solr.
[program:solr]
command=java -jar start.jar
autostart=true
autorestart=true
stderr_logfile=/opt/zdsenv/logs/solr.err.log
stdout_logfile=/opt/zdsenv/logs/solr.out.log
Munin
Configuration générale Installer le noeud Munin : apt-get install munin-node.
On obtient les suggestions de plugins à installer avec munin-node-configure --suggest et les commandes
à lancer pour les activer via munin-node-configure --shell.
10
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Pour l’instant le serveur de graphe est fourni par SpaceFox et est visible ici. Seul SpaceFox peut mettre à jour cette
configuration. Le serveur de graphe accède au serveur en SSH avec cette clé publique :
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBsfYaz5d4wtyTM0Xx1TjpJt0LuZ2Il9JZD2+s4hNQToNBaqT3aafG1SuHuQkqj
Configuration spécifique à ZdS Créer les liens vers le plugin Django-Munin :
ln
ln
ln
ln
ln
ln
ln
ln
ln
ln
-s
-s
-s
-s
-s
-s
-s
-s
-s
-s
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/usr/share/munin/plugins/django.py
/etc/munin/plugins/zds_active_sessions
/etc/munin/plugins/zds_active_users
/etc/munin/plugins/zds_db_performance
/etc/munin/plugins/zds_total_articles
/etc/munin/plugins/zds_total_mps
/etc/munin/plugins/zds_total_posts
/etc/munin/plugins/zds_total_sessions
/etc/munin/plugins/zds_total_topics
/etc/munin/plugins/zds_total_tutorials
/etc/munin/plugins/zds_total_users
Ajouter les métriques suivantes au fichier /etc/munin/plugin-conf.d/munin-node :
[zds_db_performance]
env.url http://zestedesavoir.com/munin/db_performance/
env.graph_category zds
[zds_total_users]
env.url http://zestedesavoir.com/munin/total_users/
env.graph_category zds
[zds_active_users]
env.url http://zestedesavoir.com/munin/active_users/
env.graph_category zds
[zds_total_sessions]
env.url http://zestedesavoir.com/munin/total_sessions/
env.graph_category zds
[zds_active_sessions]
env.url http://zestedesavoir.com/munin/active_sessions/
env.graph_category zds
[zds_total_topics]
env.url http://www.zestedesavoir.com/munin/total_topics/
env.graph_category zds
[zds_total_posts]
env.url http://www.zestedesavoir.com/munin/total_posts/
env.graph_category zds
[zds_total_mps]
env.url http://www.zestedesavoir.com/munin/total_mps/
env.graph_category zds
[zds_total_tutorials]
env.url http://www.zestedesavoir.com/munin/total_tutorials/
env.graph_category zds
[zds_total_articles]
1.1. Installation
11
Zeste de Savoir Documentation, Version 1.0
env.url http://www.zestedesavoir.com/munin/total_articles/
env.graph_category zds
Mise à jour d’une instance existante
Allez jeter un coup d’oeil à
site/blob/dev/server/deploy.sh> ! ;)
notre
script
de
déploiement
<https
://github.com/zestedesavoir/zds-
Personnalisation d’une instance
Il est possible de personnaliser ZdS pour n’importe quel site communautaire de partage. Un ensemble de paramètres
est disponible dans le fichier settings.py via un dictionnaire. Vous pourrez donc écraser ces variables par défaut
dans votre fichier settings_prod.py. Le dictionnaire de variables relatives au site est donc le suivant :
ZDS_APP = {
’site’: {
’name’: u"ZesteDeSavoir",
’litteral_name’: u"Zeste de Savoir",
’slogan’: u"Zeste de Savoir, la connaissance pour tous et sans pépins",
’abbr’: u"zds",
’url’: u"http://127.0.0.1:8000",
’dns’: u"zestedesavoir.com",
’email_contact’: u"[email protected]",
’email_noreply’: u"[email protected]",
’repository’: u"https://github.com/zestedesavoir/zds-site",
’short_description’: u"",
’long_description’: u"Zeste de Savoir est un site de partage de connaissances "
u"sur lequel vous trouverez des tutoriels de tous niveaux, "
u"des articles et des forums d’entraide animés par et pour "
u"la communauté.",
’year’: u"2014",
’association’: {
’name’: u"Zeste de Savoir",
’fee’: u"30 C",
’email’: u"[email protected]",
’email_ca’: u"[email protected]"
},
’licenses’: {
’logo’: {
’code’: u"CC-BY",
’title’: u"Creative Commons License",
’description’: u"Licence Creative Commons Attribution - Pas d’Utilisation Commerciale
u"Partage dans les Mêmes Conditions 4.0 International.",
’url_image’: u"http://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png",
’url_license’: u"http://creativecommons.org/licenses/by-nc-sa/4.0/",
’author’: u"MaxRoyo"
},
’cookies’: {
’code’: u"CC-BY",
’title’: u"Licence Creative Commons",
’description’: u"licence Creative Commons Attribution 4.0 International",
’url_image’: u"http://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png",
’url_license’: u"http://creativecommons.org/licenses/by-nc-sa/4.0/"
},
’source’: {
12
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
’code’: u"GPL v3",
’url_license’: u"http://www.gnu.org/licenses/gpl-3.0.html",
’provider_name’: u"Progdupeupl",
’provider_url’: u"http://pdp.microjoe.org/",
},
’licence_info_title’: u’http://zestedesavoir.com/tutoriels/281/le-droit-dauteur-creative’licence_info_link’: u’Le droit d\’auteur, Creative Commons et les licences sur Zeste de
},
’hosting’: {
’name’: u"OVH",
’address’: u"2 rue Kellermann - 59100 Roubaix - France"
},
’social’: {
’facebook’: u’https://www.facebook.com/ZesteDeSavoir’,
’twitter’: u’https://twitter.com/ZesteDeSavoir’,
’googleplus’: u’https://plus.google.com/u/0/107033688356682807298’
},
’cnil’: u"1771020",
},
’member’: {
’bot_account’: u"admin",
’anonymous_account’: u"anonymous",
’external_account’: u"external",
’bot_group’: u’bot’,
’members_per_page’: 100,
},
’gallery’: {
’image_max_size’: 1024 * 1024,
},
’article’: {
’home_number’: 5,
’repo_path’: os.path.join(SITE_ROOT, ’articles-data’)
},
’tutorial’: {
’repo_path’: os.path.join(SITE_ROOT, ’tutoriels-private’),
’repo_public_path’: os.path.join(SITE_ROOT, ’tutoriels-public’),
’default_license_pk’: 7,
’home_number’: 5,
’helps_per_page’: 20
},
’forum’: {
’posts_per_page’: 21,
’topics_per_page’: 21,
’spam_limit_seconds’: 60 * 15,
’spam_limit_participant’: 2,
’followed_topics_per_page’: 21,
’beta_forum_id’: 1,
’max_post_length’: 1000000,
’top_tag_max’: 5,
},
’paginator’:{
’folding_limit’: 4
}
}
1.1. Installation
13
Zeste de Savoir Documentation, Version 1.0
1.1.5 Création d’un jeu de données de test
Afin de vous permettre de tester rapidement l’application zeste de savoir, nous mettons à votre disposition un jeu
complet de données de test. Ces données sont à séparer en deux types :
— les données totalement sérialisables (les utilisateurs, les forums, les catégories...)
— les données qui nécessitent un traitement lors de leur création (indexation git des tuto, import d’image des
galleries...)
Chacun des jeux de données est géré par deux outils différents :
Les fixtures django
Pour les données totalement sérialisables, nous utilisons la commande python manage.py loaddata de django. Cette
commande prend des fichiers yaml en entrée et crée les données ainsi sérialisées. Le format est documenté sur le site
officiel de django.
Les fixtures ad hoc
Certaines données nécessitent des traitement complexes avant d’être utilisables et donc ne peuvent être plainement
sérialisées et utilisées par l’outil de django. Pour cela, nous avons mis en place un script qui permet d’utiliser les
factories pour créer ces objets et y appliquer les traitements nécessaires.
Pour utiliser les fixtures de ce type, il vous suffira de lancer le script python load_factory_data.py fichier_fixtures.yaml.
Tout comme l’outil django, nous utilisons yaml pour configurer les données, le format d’une fixture sera celui-ci
-
factory: nom_factory
fields:
champ1: "valeur1"
champ2: "valeur2"
champN: "valeurN"
1.1.6 Installation du frontend
Vous voulez nous aider au développement du frontend ? Installez Node.js et npm grâce aux instructions qui suivent !
Installation de Node.js et npm
Windows
Node.js propose un installeur (.msi) pour Windows, disponible à cette adresse. Choisissez Windows Installer, avec
l’architecture adéquate, et installez Node.js en ouvrant le fichier téléchargé.
Mac OS X
Node.js propose un installeur (.pkg) pour Mac OS X, disponible à cette adresse. Choisissez Mac OS X Installer, et
installez Node.js en ouvrant le fichier téléchargé.
14
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Linux
Ubuntu L’installation peut se faire simplement via apt-get :
sudo apt-get install nodejs
Mais il est possible d’avoir une version un peu plus récente avec :
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
Certaines dépendances utilisent node au lieu de nodejs, pour y remédier :
sudo ln -s /usr/bin/nodejs /usr/bin/node
Debian Une version récente de Node.js se trouve dans les dépôts wheezy-backport, jessie et sid. Sur ces versions de
Debian, l’installation peut se faire de cette manière :
sudo apt-get install nodejs
Fedora / CentOS / RHEL Il vous faut tout simplement faire :
sudo curl -sL https://rpm.nodesource.com/setup | bash sudo yum install -y nodejs
Arch Linux Il faut simplement lancer cette commande :
pacman -S nodejs
FreeBSD / OpenBSD
Une installation via pkg devrait suffire :
pkg install node
Les instructions pour installer Node.js sur les distributions CentOS, RHEL, FreeBSD et OpenBSD sont issues du lien
juste en dessous et n’ont pas été testées.
Les instructions détaillées pour toutes les distributions se trouvent dans la documentation officielle (en anglais).
Pour vérifier que Node.js et npm sont installés (et que vous avez les bonnes versions) :
node -v
v0.10.26
npm -v
2.1.7
Vous devez avoir une version de Node.js > 0.10.x et de npm > 2.x.x. Si votre version de npm est 1.x.x, vous devez
le mettre à jour (voir juste en dessous).
1.1. Installation
15
Zeste de Savoir Documentation, Version 1.0
Mise à jour de Node.js et npm
Pour npm, il suffit de le mettre à jour avec cette commande :
sudo npm install -g npm
Pour ce qui est de Node.js, une mise à jour via le gestionnaire de paquets devrait fonctionner.
Installation des dépendances npm
L’installation de Gulp, ainsi que des différentes dépendances et bibliothèques, se fait via npm dans le répertoire du
projet :
npm install
Utilisation des outils
Vous avez installé les outils ? Voilà comment on s’en sert dans notre projet !
Présentation de Gulp
Gulp est un outil permettant d’automatiser les tâches liées au front. Dans notre cas, il permet de :
— Vérifier la syntaxe Javascript
— Minimiser les fichiers Javascript et les rassembler en un fichier
— Compiler les fichiers SCSS pour les transformer CSS
— Compresser les images et créer un sprite
Note : Vous voulez en savoir plus ? Venez ici ! ;)
Utilisation de Gulp
Gulp se lance avec npm run gulp -- [tâche] où [tâche] est la tâche à lancer. Les différentes tâches sont :
— clean : Nettoie le dossier dist/
— build : Compile tout (SCSS, JS et images)
— test : Lance les tests (grâce à JSHint)
— watch : Compile les différents fichiers dès qu’ils sont modifiés (utile pour le développement ; Ctrl+C pour
arrêter)
Si vos modifications n’apparaissent pas dans votre navigateur et que ce n’est pas dû à Gulp, pensez à vider le cache de
votre navigateur !
Pour information, la commande npm run est un raccourci de la commande npm run-script, donc les deux
commandes sont identiques !
Si vous voulez utiliser directement la commande gulp [tâche] au lieu de npm run gulp -- [tâche], il
vous faut lancer cette commande avec les droits administrateurs :
sudo npm install -g gulp
16
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Nettoyage des outils
Désinstaller les dépendances
Il vous suffit pour cela de lancer la commande :
npm uninstall
Si ça ne fonctionne pas, vous pouvez le faire manuellement grâce à rm -rI node_modules/.
Désinstaller les dépendances inutilisées
Il y a une commande toute faite pour ça :
npm prune
1.1.7 Installation de Solr (pour la recherche)
Zeste de Savoir utilise Solr, un moteur de recherche très performant développé par la fondation Apache.
Installer Solr est nécessaire pour faire fonctionner la recherche.
Il existe beaucoup de manières d’installer Solr. L’une des plus simples est d’utiliser les exemples embarqués avec le
paquet de release.
Prérequis sur linux
Avant toute chose soyez-sûr d’avoir Java (disponible dans les dépôts de votre distribution, ou sur le site officiel).
Téléchargez l’archive Solr ou entrez la commande wget http://archive.apache.org/dist/lucene/solr/4.9.0/solr
Puis décompressez l’archive avec unzip solr-4.9.0.zip.
Prérequis sur windows
Avant toute chose soyez-sûr d’avoir Java.
Ajoutez le dossier contenant java à votre PATH : dans “Ordinateur”, clic droit puis “Proprétés”, ouvrez les “propriétés
avancées” puis cliquez sur “Variables d’environnement”.
Téléchargez l’archive Solr. Décompressez-la.
Procédure commune
Ouvrez le terminal ou powershell.
A la racine de votre dépot ZdS, lancez la commande :
python manage.py build_solr_schema > %solr_home%/example/solr/collection1/conf/schema.xml
où %solr_home% est le dossier dans lequel vous avez installé Solr.
Placez-vous dans ce dossier et exécutez :
1.1. Installation
17
Zeste de Savoir Documentation, Version 1.0
cd example/
java -jar start.jar
Vérifiez que solr est fonctionnel en entrant dans votre navigateur l’url http://localhost:8983/solr/
Maintenant que Solr est prêt, allez à la racine de votre dépôt zeste de savoir, une fois votre virtualenv activé, indexez
les les données du site :
python manage.py rebuild_index
Une fois terminé, vous avez une recherche fonctionnelle.
Pour mettre à jour un index existant, la commande est :
python manage.py update_index
1.2 Workflow
Cette page détaille le workflow utilisé sur Zeste de Savoir. Elle est là surtout pour satisfaire votre curiosité, à moins
d’avoir les droits de faire une Mise En Production (MEP). La page de contribution devrait répondre à vos questions
quant au processus de développement.
Ce workflow est très fortement fondé sur le Git flow.
1.2.1 Workflow général
L’idée générale est très simple :
— Le développement se fait sur la branche dev ;
— La branche prod contient la version en production ;
— Lorsqu’on juge qu’on a assez de matière pour un nouveau déploiement, on crée une branche dédiée (par
exemple release-v1.7) que l’on teste en pré-production (les bugs trouvés seront corrigés sur cette
branche) ;
— En cas de bug ultra-urgent à corriger en production, on crée une branche spéciale.
La pré-production (ou béta) est disponible via ce lien. Vous pouvez y accéder avec le nom d’utilisateur “clementine”
et le mot de passe “souris”.
1.2.2 Workflow de développement
Description
1. Les fonctionnalités et corrections de bugs se font via des Pull Requests (PR) depuis des forks via GitHub.
2. Ces PR sont unitaires. Aucune PR qui corrige plusieurs problèmes ou apporte plusieurs fonctionnalité ne sera
acceptée ; la règle est : une fonctionnalité ou une correction = une PR.
3. Ces PR sont mergées dans la branche dev (appelée develop dans le git flow standard), après une Quality
Assurance (QA) légère.
4. La branche prod (appelée master dans le git flow standard) contient exclusivement le code en production,
pas la peine d’essayer de faire le moindre commit dessus !
5. Les branches du dépôt principal (dev, prod et la branche de release) ne devraient contenir que des merge de
PR, aucun commit direct.
18
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Quelques précisions
Où peut-on trouver les détails pratiques ?
Tous ces détails sont dans la page de contribution. On y trouve entre autres les recommendations en terme de PR ou
de messages de commits.
Qu’est-ce qu’une “QA légère” ?
C’est s’assurer que le code fait ce qu’il devrait sans passer des heures à re-tester l’intégralité du site. Concrètement,
cela implique :
— une revue de code ;
— la vérification que des tests correspondants à la fonctionnalité ou à la correction sont présents, cohérents et
passent ;
— des tests manuels dans le cas de fonctionnalités ou corrections complexes et/ou critiques (au cas par cas).
1.2.3 Workflow de mise en production
Description
1. Quand on a assez de nouveautés dans dev (mais pas trop), on décide de faire une release. L’idée est de pouvoir
vérifier et corriger les problèmes de cette release rapidement, en moins de 2 semaines entre le lancement de la
release et sa MEP.
(a) Création d’une nouvelle branche de release du nom de la version (par exemple release-v1.7)
(b) Déploiement de cette branche sur l’environnement de pré-production, avec un dump de données de production
(c) Tests les plus complets possibles sur ce nouvel environnement
(d) Corrections éventuelles sur cette branche de release. Les corrections ne sont pas remontées sur ‘‘dev‘‘
au fur et à mesure. Cf ci-dessous pour les détails.
2. Lorsqu’on a bien testé cette branche, on la met en production :
(a) Merge de la branche de release dans dev
(b) Merge de la branche de release dans prod
(c) Tag avec la nouvelle version
(d) Mise en production sur le serveur
(e) Suppression de la branche de release, devenue inutile
Le temps maximum entre la création d’une branche de release et sa mise en production est de deux semaines. Au-delà
on considère qu’il y a trop de problèmes et qu’ils risquent de bloquer le développement :
1. Merge des corrections de la branche de release dans dev
2. Pas de mise en production
3. Suppression de la branche de release, devenue inutile
En cas de problèmes sur la release
Vous l’avez lu : les corrections de master ne sont pas remontées sur ‘‘dev‘‘ au fur et à mesure. La raison est que
ça prends du temps, de l’énergie et que ça fait beaucoup de merges croisés. Donc toutes les corrections sont remontées
en même temps lors de la mise en production. Conséquences :
— Si vous bossez sur dev pendant qu’une release est en cours, pas la peine de corriger un bug déjà corrigé sur la
release : la PR serait refusée (pour cause de doublon).
— Si un gros problème est détecté sur la release et qu’il est correctible en un temps raisonnable :
1.2. Workflow
19
Zeste de Savoir Documentation, Version 1.0
1. Il est corrigé sur la branche de release.
2. Les merges de PR sur dev qui impliquent un risque même vague de conflit sont bloqués.
3. S’il y a quand même un conflit (à cause d’une PR mergée sur dev avant la détection du problème), la
personne qui règle le problème fournit 2 correctifs : un pour la branche de release et un pour la branche de
de dev.
Ceci fonctionne bien si les développements sont de bonne qualité, donc avec peu de correctifs sur la branche de release
(idéalement aucun !)... les codes approximatifs et non testés seront donc refusés sans la moindre pitié !
1.2.4 Glossaire
— MEP : Mise En Production
— PR : Pull Request (proposition d’une modification de code à un projet)
— QA : Quality Assurance (Assurance Qualité)
1.3 Le back-end
Le terme back-end désigne la partie du code associée à Django et écrite en python. Le but du back-end est de récupérer,
générer et combiner les différentes données du site afin de les envoyer au font-end.
Vous trouverez dans les liens ci-dessous une documentation spécifique à chacun d’entre eux. Vous pouvez également
retrouver la documentation technique des modules ici.
1.3.1 Les articles
A venir
1.3.2 Les forums
Il y a sur Zeste de Savoir, un espace communautaire permettant aux membres, d’échanger entre eux sur divers sujets.
Cette espace est comunément appelé « forums ». L’URL permettant d’accéder à ce service est : /forums, simplement.
Le découpage des forums
La modération des forums
Sur Zeste de Savoir, une modération des forums, autant sur les sujets, que sur les messages inclus, est faite par les
membres possèdant un certain rang. Cette dernière, permet d’éviter tout débordement ou autre.
La modération des sujets
Tout d’abord, il y a une posibilité de faire de la modération par sujet. Ici, cette modération s’effectue grâce aux liens
se trouvant dans sidebar (zone se trouvant sur le côté gauche de la page).
Nous retrouvons ici, trois items :
— Fermer le sujet : ici, le but est de fermer le sujet. Ce qui empêchera quiconque de poster dedans. Un cadena,
apparaîtra aussi à côté du sujet sur la liste des sujets de la catégorie, et, l’encart suivant fera alors son apparition
sur le sujet en lui-même :
20
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
— Marquer en post-it : le sujet sera mis en post-it sur la catégorie dans laquelle il se trouve. Ce qui fait qu’il
surpassera tout les autres sujets et cela, même si une réponse plus récente vient d’être posté dans un autre sujet.
Il ne pourra jamais se retrouver en-dessous des autres. Lors de la mise en post-it, une épingle apparaît à
côté du sujet dans la catégorie où il se trouve.
— Déplacer le sujet : cet item permet de faire un déplacement de sujet, au cas-où un membre se serait trompé en
postant. Cela évite qu’il ait à recréer un sujet et donc un doublon de celui-ci. Le déplacement, se fait via une
modale :
La modération des messages
Il est aussi possible d’effectuer la modération plus finement, en ciblant des messages en particulier dans des sujets.
Cela se fait grâce aux différents liens qui se trouvent sur les messages :
Ici, les différents choses que vous pouvez faire, sont :
— Masquer : cela, rend la lecture du message impossible par les autres membres. Mais l’emplacement du message reste présent, comme le montre la capture ci-dessous. Vous pouvez également contaster sur cette capture,
que vous avez, avec un certain rang, la possibilité de démasquer le message. Avec ce dernier, vous avez la
possiblité de masquer tout les messages des forums. Mais un membre, peut masquer de lui-même, ces propres
messages.
1.3. Le back-end
21
Zeste de Savoir Documentation, Version 1.0
22
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
— Éditer : en cliquant ici, vous accèderez à l’interface d’édition des messages. En tant que modérateur, vous
pouvez éditer tout les messages des forums, dès lors, cette encart apparaît :
— Signaler : cela permet d’envoyer une demande d’intervention à l’équipe modératrice du site. Ce bouton, n’est
pas un résultant de votr rang, tout les membres le possèdes.
— Citer : permet de citer un message lors de la rédaction d’une réponse. Ce bouton, n’est pas un résultant de
votre rang.
Les filtres sur les sujets
Dans un forum
Il existe actuellement 3 filtres pour filtrer les sujets dans un forum :
— Sujets résolus (solve)
— Sujets non résolus (unsolve)
— Sujets sans réponse (noanswer)
Il suffit d’ajouter ?filter=<filtre> à l’URL en remplaçant <filtre> par un des 3 filtre ci-dessus.
Suivre un sujet
Être notifié sur le site lui même
Nous permettons à nos membres de “suivre” un sujet directement sur le site. “Suivre un sujet”, cela signifie que,
lorsqu’un nouveau message est posté sur ce sujet, l’icône de notification nous en informe.
Dès lors vous pourrez par un simple clic allé au dernier message non lu.
Pour repérer qu’un message est lu ou pas, nous utilisons côté backend la classe zds.forum.models.TopicRead
qui retient la date de dernière lecture du topic. De la même manière nous utilisons la classe
zds.forum.models.TopicFollowed pour retenir le fait que vous suivez ou non un sujet.
Pour suivre un sujet, deux méthodes sont envisageables :
— Y participer : dès que vous y inscrivez une réponse, vous suivez le sujet.
— Cliquer sur “Suivre le sujet” dans la sidebar.
Pour cesser de suivre un sujet, et ne plus être notifier de son activité, vous pouvez :
— Vous rendre sur le topic et cliquer sur “Ne plus suivre” en haut de la sidebar.
— Vous rendre sur n’importe quelle page du forum, survoler le titre du sujet et cliquer sur la croix qui apparaît
alors.
En effectuant ces actions vous cessez de suivre le sujet, l’instance de TopicFollowed qui était associée à votre suivi est
supprimée définitivement. Cela a pour effet que vous pourrez à nouveau suivre le sujet dans le future si vous le désirez.
1.3.3 Les galeries
La liste des galeries de l’utilisateur est accessible via l’url suivante : /galerie/.
1.3. Le back-end
23
Zeste de Savoir Documentation, Version 1.0
Généralités
Une galerie rassemble physiquement un certain nombre d’images. Elle peut prendre un titre ainsi qu’un sous-titre.
Création et remplissage
On peut créer une nouvelle galerie via l’url /galerie/nouveau/, où il est nécessaire de renseigner ces deux
champs.
Attention : Des galeries sont créées automatiquement à la création d’un nouveau tutoriel par un utilisateur et
possède alors le même nom que celui-ci.
Il est ensuite possible d’uploader des images via le menu de gauche :
F IGURE 1.1 – Liens permettant d’uploader des images
Via celui-ci, on peut importer des archives contenant des images (au format ZIP) ou des images seules. Dans ce dernier
cas, le formulaire d’upload est le suivant :
F IGURE 1.2 – Formulaire d’upload de nouvelles images
24
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Comme on peut le voir, chaque image doit posséder au minimum un titre et peut posséder une légende, qui sera
employée par la suite. Il est donc conseillé de remplir également ce second champ, bien que ce ne soit pas obligatoire.
Quant à l’image elle-même, sa taille ne peut pas excéder 1024 Kio.
Une fois l’image uploadée, il est possible d’effectuer différentes actions sur celle-ci sur la page spécifique à celle-ci :
Autrement dit,
— En modifier le titre, la légende ou encore l’image en elle-même. À noter que le titre et la légende peuvent être
modifiés sans qu’il ne soit nécessaire d’uploader une nouvelle image.
— Obtenir le code à insérer dans un champ de texte acceptant le markdown pour l’image en elle-même, sa miniature ou encore la miniature accompagnée du lien vers l’image en taille réelle.
Attention : Le titre de l’image n’entre pas en compte dans le nommage de l’image une fois cette dernière téléchargée. Afin de s’assurer l’unicité des noms, nous utilisons un algorithme de hashage pour cela.
Les utilisateurs et leurs droits
Le créateur de la galerie possède un droit d’écriture, mais peut rajouter à tout moment des utilisateurs dans celle-ci :
Lors d’un clic sur “Ajouter un utilisateur”, une fenêtre modale s’ouvre :
Il est alors possible de rajouter un nouvel utilisateur dans la galerie. Les droits de celui-ci peuvent-être les suivants :
— Lecture : (zds.gallery.models.GALLERY_READ) l’utilisateur a seulement le droit de consulter les
images existantes dans la galerie sans pouvoir apporter de modifications ;
— Écriture : (zds.gallery.models.GALLERY_WRITE), inclut Lecture, l’utilisateur peut modifier ou
supprimer des images existantes, en rajouter des nouvelles et changer les attributs de la galerie (y compris
ajouter de nouveaux utilisateurs) ;
Il n’est actuellement pas possible de modifier les droits d’un utilisateur après son ajout à la galerie.
La suppression
Une image peut être supprimée à tout moment en la sélectionnant sur la page de la galerie et en cliquant sur le bouton
suivant :
Attention qu’aucune confirmation n’est demandée pour la suppression d’une image.
Une galerie peut être quant à elle supprimée via la page de gestion des galeries (/galerie/) en cochant la case de
celle-ci et en cliquant sur “supprimer les galeries sélectionnées” dans le menu de gauche :
Une modale s’ouvre ensuite, demandant de confirmer le choix :
Une fois cliqué sur “confirmer”, la galerie et les images qu’elle contient sont supprimées.
Attention : Si une galerie est liée à un tutoriel existant, elle ne peut pas être supprimée.
1.3. Le back-end
25
Zeste de Savoir Documentation, Version 1.0
F IGURE 1.3 – Gestion d’une image
26
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
F IGURE 1.4 – Ajout d’un nouvel utilisateur
F IGURE 1.5 – Choix de l’utilisateur et sélection de ces droits
F IGURE 1.6 – Suppression d’une ou plusieurs image(s)
1.3. Le back-end
27
Zeste de Savoir Documentation, Version 1.0
F IGURE 1.7 – Suppression d’une galerie
F IGURE 1.8 – Confirmation
28
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Lien galerie <-> Tutoriel
Chaque tutoriel possède une galerie en propre. Par défaut cette galerie possède le même nom qui a été donné au tutoriel
lors de sa création.
Chaque auteur possède un droit d’accès en écriture (GALLERY_WRITE) sur la galerie liée au tutoriel.
Si un membre possède un droit de lecture seule (GALLERY_READ) sur la galerie d’un tutoriel, aucun droit n’est
accordé à ce membre quant au tutoriel.
À l’heure actuelle, les articles ne possèdent pas de galerie.
Aspects techniques
Chaque galerie (classe Gallery) est stockée en base de données avec son titre, son sous-titre et son slug (ainsi que la
date de création et de dernière modification). Une galerie est rattachée à l’utilisateur via la classe UserGallery, qui
reprend un lien vers l’utilisateur, la galerie, mais également les droits qu’il possède sur cette dernière, sous la forme
d’une constante : GALLERY_READ pour le droit de lecture ou GALLERY_WRITE pour le droit d’écriture.
Une image (classe Image) est renseignée en base de données avec son titre, sa légende, un lien vers la galerie qui la
contient, son slug et un lien physique vers le fichier image (ainsi que la date de création et de dernière modification).
Les images sont stockées dans le dossier renseigné par la variable MEDIA_URL (dans le fichier settings.py), dans
un sous-dossier dont le nom correspond au pk de la galerie. C’est la librairie easy_thumbnails qui gère la génération
des miniatures correspondantes aux images uploadées, à la demande du back.
Outils logiciels utilisés
Afin d’assurer une compatibilité maximale de toutes les images des galeries, leur redimensionnement au besoin... le
logiciel pyllow est utilisé.
1.3.4 Les membres
Inscription
L’inscription d’un membre se déroule en deux phases :
— Le membre crée son compte et fournit un pseudo, un mot de passe et une adresse mail valide.
— Un mail de confirmation est envoyé avec un jeton qui permettra d’activer le compte.
Attention :
— Les virgules ne sont pas autorisées dans le pseudonyme, qui ne peut également pas commencer ou finir par
des espaces.
— Le mot de passe doit faire au moins 6 caractères.
Désinscription
L’inscription se fait via l’interface utilisateur.
— Le lien de désinscription est accessible via paramètres (/membres/parametres/profil/) puis “Se désinscrire” dans la barre latérale (/membres/desinscrire/avertissement/) :
— Le lien mène alors vers une page expliquant les conséquences de sa désinscription. Il peut alors poursuivre via
un bouton en bas de celle-ci :
— Le clic sur le bouton rouge ouvre une boite modale qui constitue le dernier avertissement avant le déclenchement du processus de désinscription :
1.3. Le back-end
29
Zeste de Savoir Documentation, Version 1.0
F IGURE
1.9 – Position du lien
(/membres/parametres/profil/)
de
désinscription
dans
les
paramètres
du
membre
F IGURE 1.10 – Bouton de confirmation
30
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
F IGURE 1.11 – La dernière étape
Le clic sur “me désinscrire” entraîne alors une série d’action (qui sont irréversibles) :
— Suppression du profil, libèrant le pseudo et l’adresse courriel pour les futures inscriptions ;
— Le membre est déconnecté ;
— Les données du membre sont anonymisées :
— le pseudo anonymous est employé :
— pour les sujets du forum (qui, cependant, restent ouverts)
— pour les messages des MP (le membre quitte les discussions auxquelles il participait) ;
— pour les commentaires aux tutoriels et articles ;
— les galeries non liées à un tutoriel sont données à external (puisque l’image peut être considérée comme
venant d’un “auteur”) avec droit de lecture et d’écriture ;
— les articles et tutoriels suivent ces règles :
— si le tutoriel/article a été écrit par plusieurs personnes : le membre est retiré de la liste des auteurs ;
— si le tutoriel/article est publié, il passe sur le compte “external”. Une demande expresse sera nécessaire
au retrait complet de ces contenus ;
— si le tutoriel/article n’est pas publié (brouillon, bêta, validation) il est supprimé, ainsi que la galerie qui
lui est associée.
Les membres dans les environnement de test et de développement
Afin de faciliter les procédures de tests en local, 6 utilisateurs ont été créés via la fixture users.yaml (utilisateur/mot
de passe) :
— user/user : Utilisateur normal
— staff/staff : Utilisateur avec les droits d’un staff
— admin/admin : Utilisateur avec les droits d’un staff et d’un admin
— anonymous/anonymous : Utilisateur qui permet l’anonymisation des messages sur les forums, dans les commentaires d’articles et de tutoriels ainsi que dans les MPs
1.3. Le back-end
31
Zeste de Savoir Documentation, Version 1.0
— external/external : Utilisateur qui permet de récupérer les tutoriels d’anciens membres et/ou de publier des
tutoriels externes.
— ïtrema/ïtrema : Utilisateur de test supplémentaire sans droit
Pour que ces membres soient ajoutés à la base de données, il est donc nécéssaire d’exécuter la commande, suivante, à
la racine du site
python manage.py loaddata fixtures/users.yaml
Attention : Les utilisateurs anonymous et external doivent être présents dans la base de données pour le
bon fonctionnement du site. En effet, ils permettent le bon fonctionnement du processus d’anonymisation (voir
plus haut)
Les utilisateurs anonymous et external sont totalement paramétrables dans le fichier zds/settings.py :
pour changer le nom d’utilisateur (username) de ces comptes, agissez sur les constantes suivantes (du dictionnaire
ZDS_APP) :
# Constant for anonymisation
anonymous_account = "anonymous"
external_account = "external"
Bien entendu, les comptes correspondants doivent exister dans la base de donnée.
L’interface de promotion
Afin de pouvoir gérer les membres directement depuis le site (c’est à dire sans avoir besoin de passer par l’interface d’administration de Django), une interface de promotion a été développée. Cette interface permet de : 1.
Ajouter/Supprimer un membre dans un/des groupe(s) 2. Ajouter/Supprimer le statut super-utilisateur à un membre 3.
(Dés)activer un compte
Le premier point permet notamment de passer un membre dans le groupe staff ou développeur. Si d’autres groupes
voient le jour (valido ?) alors il sera possible ici aussi de le changer. Le second point permet de donner accès au
membre à l’interface Django et à cette interface de promotion. Enfin, le dernier point concerne simplement l’activation
du compte (normalement faite par le membre à l’inscription).
Elle est géré par le formulaire PromoteMemberForm présent dans le fichier zds/member/forms.py. Elle est ensuite
visible via le template member/settings/promote.html qui peut-être accédé en tant que super-utilisateur via le profil de
n’importe quel membre.
L’interface de karma
Pour pouvoir communiquer entre modérateur, il est utile d’avoir un outil de suivi sur les membres. Ce dernier prend
forme via la gestion du “karma” d’un membre. Le karma est une valeur numérique pouvant aller de -100 à +100.
Cette valeur peut-être modifié via l’ajout de bonus/malus par les modérateurs. Chaque modification du karma doit
s’accompagner d’un commentaire, mais un commentaire n’entraine pas forcément une modification du karma (0 point
de bonus/malus).
Cet outil à deux rôles. Permettre d’identifier les membres perturbateurs mais aussi les membres moteurs qui pourrait
faire l’objet d’un article ou d’une mise en avant de leurs projets.
Pour modifier le karma d’un membre, il faut donc être modérateur sur le site. Sur la fiche profil d’un membre apparait
alors un formulaire pour ajouter un bonus/malus et une liste des modifications précédentes montrant l’impact (+/-), le
message, l’auteur du bonus/malus et la date d’effet de ce dernier.
32
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
L’interface de réinitialisation de mot de passe
Quand le membre du site oublie son mot de passe, il peut le réinitialiser. L’ancien mot de passe est supprimé
et l’utilisateur peut en choisir un nouveau. Pour cela, il se rend sur la page de réinitialisation de mot de passe
(membres/reinitialisation/) à partir de la page de connexion.
Sur cette page l’utilisateur, doit rentrer son nom d’utilisateur ou son adresse de courriel. Pour cela, il clique sur le
lien pour que le formullaire apparaisse. Quand l’utilisateur clique sur le bouton de validation, un jeton est généré
aléatoirement et est stocké dans une base de données.
Un message est envoyé à l’adresse de courriel de l’utilisateur. Ce courriel contient un lien de réinitialisation. Ce lien
contient un paramètre, le jeton de réinitialisation et dirige l’utilisateur vers l’adresse membres/new_password/.
Cette page permet de changer le mot de passe de l’utilisateur. L’utilisateur remplit le formulaire et clique sur le bouton
de validation. Si le mot de passe et le champ confirmation correspondent et que le mot de passe respecte les règles
métiers, le mot de passe est changé. Le systéme affiche un message de confirmation du changement du mot de passe.
Attention :
— Il n’existe aucune restriction sur le nombre de demande de réinitialisation
— Un utilisateur peut avoir le même nom d’utilisateur que l’adresse email de quelqu’un d’autre. Exemple :
username
firm1
[email protected]
email
[email protected]
[email protected]
Attention :
— Le mot de passe doit faire au moins 6 caractères.
— Le lien est valable une heure. Si l’utilisateur ne clique pas sur le lien dans le temps imparti, un message
d’erreur est affiché.
— Le jeton de réinitialisation de mot de passe n’est valide qu’une seule fois. Si l’utilisateur tente de changer
son mot de passe avec le même jeton, une page 404 est affiché à l’utilisateur.
1.3. Le back-end
33
Zeste de Savoir Documentation, Version 1.0
1.3.5 Les messages privés
Envoi et participation
ZDS fournit un module de messagerie privée qui vous permet de communiquer avec les membres possédant un compte
sur le site.
Vous pouvez accéder au module de message privé à tout moment en cliquant sur l’icône :
F IGURE 1.12 – Icône d’accès au module de message privé
Lors de l’envoi du message privé, vous avez accès à cette interface :
F IGURE 1.13 – Interface de rédaction d’un message privé
Tout d’abord, entrez le nom de vos destinataires en les séparant d’une virgule. L’autocomplétion vous aide à trouver
les membres que vous cherchez.
Par conception, la sélection des destinataires a ces propriétés :
— insensible à la casse ;
— contacter un membre du groupe bot_group vous renverra un message d’erreur expliquant que ledit utilisateur
est injoignable ;
— contacter un membre qui n’existe pas vous renverra un message d’erreur expliquant que ledit utilisateur n’existe
pas.
34
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Une fois le message envoyé, tous les destinataires reçoivent un mail. Aucun autre mail ne sera envoyé au fur et à
mesure de la discussion.
Tout participant à la discussion verra l’icône du module notifier l’arrivée d’un message privé :
F IGURE 1.14 – Un nouveau message privé est arrivé
Les règles citées précédemment sont aussi valables lorsque :
— vous ajoutez un participant à la discussion privée a posteriori ;
— vous ajoutez un auteur à un tutoriel ;
— vous ajoutez un auteur à un article.
1.3.6 Les tutoriels
Les composantes d’un tutoriel
Un tutoriel n’est qu’un ensemble d’introduction, de corps et de conclusion. Cependant, selon la taille souhaitée du
tutoriel, il peut nécessiter une organisation particulière. C’est pourquoi les tutoriels de ZdS sont structurés en quatre
niveaux.
Niveau 1 : Le tutoriel
Ce niveau définit l’ensemble des métadonnées associées à un tutoriel, c’est le plus haut niveau de tous les tutoriels. On
y retrouve les informations suivantes :
— titre
— description
— logo
— licence
— sous-catégories
— introduction
— conclusion
Niveau 2 : La partie
Ce niveau adapté à des documents un peu plus longs, permet de subdiviser notre contenu en plusieurs parties. C’est
typiquement le niveau qui sera utile si vous souhaitez rédiger un mémoire, ou une thèse. Par contre, pour un simple
article, ce n’est pas la peine d’en faire des parties. Un tutoriel peut contenir plusieurs parties et une partie comprend
essentiellement les informations suivantes :
— titre
— introduction
— conclusion
— position (dans le tutoriel)
1.3. Le back-end
35
Zeste de Savoir Documentation, Version 1.0
Niveau 3 : Le chapitre
On retrouve là encore les mêmes notions qu’on peut rencontrer dans la rédaction d’un document pédagogique. Si une
partie peut contenir plusieurs chapitres (on le verra plus loin dans le cas des bigtutos), un chapitre peut être rattaché à
un tutoriel directement (minituto). Le chapitre comprend les informations suivantes :
— titre
— introduction
— conclusion
Niveau 4 : L’extrait
L’extrait est le niveau le plus fin de subdivision d’un tutoriel. Il constitue le contenu, ou encore le corps de notre texte.
Un extrait est constitué uniquement d’un bloc de texte.
Les types de tutoriels
Il existe actuellement deux types de tutoriels, les minitutos et les bigtutos, Même s’il y a une réflexion sur la création
de moyen-tutos, laissez moi déjà vous présenter ce qui existe aujourd’hui.
Les minitutos
Un minituto est un format de tutoriel pour du contenu léger. Fonctionnellement il s’agit d’un tutoriel qui ne contient
qu’un seul chapitre (niveau 3) mais peut contenir un ou plusieurs extraits. On pourrait le représenter ainsi :
Tutoriels
-> chapitre
|->
|->
|->
|->
|->
|->
|->
|->
introduction
extrait
extrait
extrait
extrait
1
2
...
n
conclusion
Dans ce cas, le nombre de chapitre est bien limité à 1 et la présentation d’un minituto consiste à présenter un seul
chapitre de la structure globale.
Les bigtutos
Un bigtuto, si on repense à nos niveaux de structure, est un tutoriel dans lequel on peut avoir plusieurs parties, chaque
partie pouvant contenir plusieurs chapitres et chaque chapitre pouvant à leur tour contenir plusieurs extraits. Les
bigtutos reprennent donc ici tous les éléments de la structure. Ce format est adapté aux tutoriels dont le contenu est
assez conséquent, et demandent beaucoup de structuration. On pourrait le représenter ainsi :
Tutoriels -> partie 1 |-> chapitre 1 |->
|->
|->
|->
|->
36
introduction
extrait 1
extrait 2
extrait ...
extrait n
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
|->
|-> chapitre 2 |->
|->
|->
|->
|->
|->
|-> chapitre n |->
|->
|->
|->
|->
|->
conclusion
introduction
extrait 1
extrait 2
extrait ...
extrait n
conclusion
introduction
extrait 1
extrait 2
extrait ...
extrait n
conclusion
-> partie 2 |-> chapitre 1 |->
|->
|->
|->
|->
|->
|-> chapitre 2 |->
|->
|->
|->
|->
|->
|-> chapitre n |->
|->
|->
|->
|->
|->
introduction
extrait 1
extrait 2
extrait ...
extrait n
conclusion
introduction
extrait 1
extrait 2
extrait ...
extrait n
conclusion
introduction
extrait 1
extrait 2
extrait ...
extrait n
conclusion
-> partie n |-> chapitre 1 |->
|->
|->
|->
|->
|->
|-> chapitre 2 |->
|->
|->
|->
|->
|->
|-> chapitre n |->
|->
|->
|->
|->
1.3. Le back-end
introduction
extrait 1
extrait 2
extrait ...
extrait n
conclusion
introduction
extrait 1
extrait 2
extrait ...
extrait n
conclusion
introduction
extrait 1
extrait 2
extrait ...
extrait n
37
Zeste de Savoir Documentation, Version 1.0
|-> conclusion
Import de tutoriels
Zeste de Savoir permet d’importer des tutoriels provenant de sources extérieures. Deux formats d’import sont actuellement supportés.
Les archives zip
Si vous avez commencé a rédiger un tutoriel via l’éditeur en ligne de Zeste de Savoir, vous avez téléchargé l’archive
correspondante et vous avez fait des modifications sur les fichiers en hors-ligne, et vous souhaitez maintenant importer
ces modifications sur le site. Il suffit de faire une archive zip du répertoire dans lequel se trouvent les fichiers de votre
tutoriel et de renseigner les deux champs relatifs à l’import d’une archive, puis de cliquer sur importer.
Attention : Le rajout d’une partie, d’un chapitre ou d’un tutoriel n’est pas encore supporté dans l’import. Le
module n’importera que ce qui a été modifié dans les fichiers markdown.
Le format .tuto
Il s’agit du format dans lequel étaient exportés les tutoriels sur le Site du Zéro. C’est un format de type xml. Cependant,
pour qu’il soit importable sur ZdS il faut le transformer à l’aide d’un outil de conversion en semi-markdown. Si vous
avez besoin d’importer un tutoriel de ce format, vous devez contacter le staff de Zeste de Savoir pour que votre fichier
.tuto soit converti en semi markdown.
Vous aurez aussi besoin du pack d’images (au format zip) qui sont utilisés dans votre tutoriel.
Il ne vous restera plus qu’à renseigner les champs relatifs à l’import de .tuto pour importer le vôtre.
Attention : L’import du tutoriel peut prendre beaucoup de temps en fonction de la taille de votre tutoriel.
Cycle de vie des tutoriels
Quelque soit le type de tutoriel, le cycle de vie de celui-ci reste toujours le même. Un tutoriel peut être rédigé par
un ou plusieurs auteurs. Chaque modification sur le tutoriel est conservée afin de pouvoir retrouver l’historique des
modifications et éventuellement récupérer le contenu perdu. Lorsqu’un tutoriel est créé il rentre dans sa première étape.
38
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Le brouillon
Le brouillon est la première étape du cycle de vie d’un tutoriel. Il donne toujours l’état le plus récent du contenu d’un
tutoriel vu par les auteurs. Chaque fois que le contenu du tutoriel est modifié, c’est la version brouillon qui est mise à
jour. La version brouillon est accessible uniquement pour les auteurs et validateurs d’un tutoriel. Si on souhaite donner
un accès en lecture seule à nos écrits, il faut passer par la méthode adéquate.
La bêta
Lorsque les auteurs estiment que leur tutoriel est arrivé à un certain niveau de maturité, et qu’ils souhaitent recueillir
les premiers retours de lecteurs, ils se doivent de mettre à disposition de la communauté le tutoriel en lecture seule.
C’est le mode bêta.
La procédure voudrait que lors de l’ouverture d’une bêta, l’auteur crée un sujet dans le forum des tutoriels en bêta, en
postant le lien vers la version bêta du tutoriel.
Attention :
Le lien de la bêta, peut être trouvé via votre profil utilisateur, et est
sous la forme /tutoriels/beta/<id>/<slug>. Le lien est aussi disponible via
/tutoriel/off/<id>/<slug>/?version=sha. Seule la première forme doit etre donnée au public.
En fait lorsqu’un tutoriel est en mode bêta, il s’agit d’une version précise qui est mise dans ce mode. On peut continuer à mettre à jour la version brouillon pour rajouter de nouveaux chapitres à notre tutoriel, pendant ce temps, la
communauté lit une version figée de notre tutoriel. L’avantage étant que si le tutoriel prend beaucoup de temps à lire,
le lecteur n’a pas de mauvaise surprise de mise à jour pendant sa lecture. Les auteurs quant à eux doivent mettre à jour
manuellement leur version bêta et ainsi ils contrôlent pleinement ce qu’ils mettent à disposition des lecteurs.
La validation
Une fois que l’auteur a eu assez de retour sur son tutoriel, et qu’il estime qu’il est prêt à être publié, il décide d’envoyer
son tutoriel en validation.
L’envoi en validation n’est pas définitif, dans le sens où, vous pouvez à tout moment mettre à jour la version qui se
trouve du coté des validateurs. Évitez d’en abuser tout de même, car, si un validateur commence à lire votre tutoriel, il
devra recommencer son travail si vous faites une mise à jour dessus. Ce qui pourrait non seulement ralentir le processus
1.3. Le back-end
39
Zeste de Savoir Documentation, Version 1.0
de validation de votre tutoriel, mais décourager aussi le validateur. Donc un conseil à donner serait de n’envoyer que
du contenu sûr en validation.
Comme pour la bêta, la version brouillon du tutoriel peut continuer à être améliorée pendant que la version de validation reste figée. Auteurs et validateurs peuvent donc continuer à travailler chacun de son côté.
La publication
Une fois le contenu, lu et relu par l’équipe staff, le tutoriel est publié. Il faut bien préciser que le processus de validation
peut être assez long en fonction de la taille du tutoriel traité. Un tutoriel n’est pas obligé d’être publié à la suite d’une
demande de validation, il peut aussi être rejeté. Dans tous les cas, un historique de validation est disponible pour les
membres du staff.
La publication d’un tutoriel entraîne la création d’export en plusieurs formats. On a les formats
— Markdown : disponible uniquement pour les membres du staff et les auteurs des tutoriels
— HTML
— PDF
— EPUB : format de lecture adapté aux liseuses
— Archive : un export de l’archive contenant le dépôt git du projet.
Pour différentes raisons, il se peut que l’export dans divers formats échoue. Dans ce cas, le lien de téléchargement
n’est pas présenté. Un fichier de log sur le serveur enregistre les problèmes liés à l’export d’un format.
Aujourd’hui il existe des bugs dans la conversion en PDF (blocs custom), qui devront être réglés plus tard avec la ZEP
05)
L’entraide
Afin d’aider les auteurs de tutoriels à rédiger ces derniers, des options lors de la création/édition de ce dernier sont
disponibles. L’auteur peut ainsi faire aisément une demande d’aide pour les compétences suivantes (liste non exhaustive) :
— Besoin d’aide à l’écriture
— Besoin d’aide à la correction/relecture
— Besoin d’aide pour illustrer
— Désir d’abandonner le tutoriel et recherche d’un repreneur
L’ensemble des tutoriels à la recherche d’aide est visible via la page “/tutoriels/aides/”. Cette page génère un tableau
récapitulatif de toutes les demandes d’aides pour les différents tutoriels et des filtres peuvent être appliqués.
Il est également possible pour tout membre qui n’est pas auteur du tutoriel consulté de signaler une erreur, en
employant le bouton prévu à cet effet et situé en bas d’une page du tutoriel (il est également présent en bas d’un
chapitre, s’il s’agit d’un big-tutoriel).
F IGURE 1.15 – Bouton permentant de signaler une erreur
40
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Ce bouton est disponible sur la version publiée ou en bêta d’un tutoriel. Cliquer sur celui-ci ouvre une boite de
dialogue :
F IGURE 1.16 – Boite de dialogue permetant de signaler à l’auteur une erreur qu’il aurait commise
Le message ne peut pas être vide, mais n’hésitez pas à être précis et a donner des détails. Cliquer sur “Envoyer” envera
un message privé aux auteurs du tutoriels, reprenant votre message. Vous participerez également à la conversation,
afin que les auteurs puissent vous demander plus de détails le cas échéant.
L’aspect technique
Le stockage dans la base de données
Aujourd’hui la base de données est utilisée comme zone tampon, surtout parce que Django propose déjà des méthodes
d’enregistrement des objets en base de données de manière concurrentes et thread safe. L’idée étant de s’en détacher
à terme. La version stockée dans la base de données est le dernier état, c’est-à-dire l’état de la version en brouillon. Il
ne faut donc pas aller chercher en base de données les informations pour les afficher.
Chaque tutoriel possède trois attributs principaux :
— sha_draft : le hash du commit de la version brouillon
— sha_beta : le hash du commit de la version bêta
— sha_validation : le hash du commit de la version validation
1.3. Le back-end
41
Zeste de Savoir Documentation, Version 1.0
— sha_public : le hash du commit de la version publique
On peut les voir comme des pointeurs sur chaque version, et le fait qu’ils soient stockés en base les rends plus accessibles. À terme aussi, on devrait pouvoir en faire des branches.
Il faut aussi noter qu’on ne stocke pas le contenu (introduction, conclusion, extraits) directement en base de données,
on stocke uniquement les chemins relatifs vers les fichiers markdown qui contiennent le contenu.
Les données versionnées
Le module des tutoriels se base sur git pour versionner son contenu. Physiquement, nous avons un répertoire pour
chaque tutoriel (point d’initialisation du dépôt). À l’intérieur nous avons un répertoire par partie, et dans chaque
partie, un répertoire par chapitre, et pour chaque chapitre, un fichier par extrait.
Pour éviter les conflits dans les noms de fichier, le chemin vers un extrait aura souvent le modèle suivant :
[id_partie]_[slug_partie]/[id_chap]_[slug_chap]/[id_extrait]_[slug_extrait].md
Pour pouvoir versionner tout ceci, nous avons un fichier nommé masnifest.json chargé de stocker l’ensemble
des métadonnées versionnées du tutoriel. Ce fichier manifest est lui aussi versionné. Pour chaque version, il suffit
donc de lire ce fichier pour reconstituer un tutoriel. C’est un fichier json qui reprend la structure du document, et les
différents chemins relatifs vers le contenu. Les métadonnées stockées sont :
— Le titre du tutoriel, des parties, des chapitres et des extraits
— Le sous-titre du tutoriel
— La licence du tutoriel
— Les divers chemins relatifs vers les fichiers markdown
L’objectif étant d’arriver à tout versionner (catégories, ...) et de ne plus avoir à lire dans la base de données pour
afficher quelque chose.
NB : A chaque modification d’un élément du tutoriel, l’auteur doit renseigner un message de suivi (ou message de
révision). Ce message (qui se veut court) permet de résumer les modifications qui ont été faites lors de l’édition.
Qu’en est-il des images ? Le versionning des images d’un tutoriel (celles qui font partie de la galerie du tuto)
continue à faire débat, et il a été décidé pour le moment de ne pas les versionner dans un premier temps, pour des
raisons simples :
— versionner les images peut rendre très rapidement une archive lourde si l’auteur change beaucoup d’images, il
va se trouver avec des images plus jamais utilisées qui traînent dans son archive.
— avoir besoin d’interroger le dépôt à chaque fois pour lire les images peut rapidement devenir lourd pour la
lecture.
Le parti a été pris de ne pas versionner les images qui sont stockées sur le serveur, ce n’est pas critique et on peut très
bien travailler ainsi. Par contre, il faudra mieux y réfléchir pour une version 2 afin de proposer la rédaction totalement
en mode hors ligne.
Quid des tutoriels publiés ? Les tutoriels en offline sont tous versionnés, et sont dans le répertoire
tutoriels_private. Lorsqu’ils sont validés le traitement suivant est appliqué.
— On copie le dépôt du tutoriel dans le répertoire tutoriels_public
— On va chercher dans l’historique du dépôt les fichiers correspondant à la version publique
— On converti ces fichiers en html (en utilisant zMarkdown)
— On stocke les fichiers html sur le serveur.
Ainsi, pour lire un tutoriel public, on a juste besoin de lire les fichiers html déjà convertis.
Et si un auteur a besoin d’aide ? Afin d’aider les auteurs de tutoriels à rédiger ces derniers, des options lors de
la création/édition de ce dernier sont disponibles. L’auteur peut ainsi faire aisément une demande d’aide. La liste des
compétences est reprise ci-dessus.
42
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
L’ensemble des tutoriels à la recherche d’aide est visible via la page “help.html” (template dans le fichier
templates/tutorial/tutorial/help.html). Cette page génère un tableau récapitulatif de toutes les demandes d’aides pour les différents tutoriels et des filtres peuvent être appliqués. Toutes les données servant à peupler
ce tableau sont renvoyées via la méthode help_tutorial() dans le fichier zds/tutorial/views.py. Cette
méthode peut prendre en compte un argument en GET nommé type désignant le filtre à appliquer. Cet argument représente le slug d’une des options de la liste précédentes. En cas d’absence du paramètre, tout les tutoriels ayant au
moins une demande d’aide d’activées ou en bêta sont renvoyé au template. De nouveaux types de demande d’aide
peuvent-être rajouté via l’interface d’administration Django dans la classe Utils.HelpWriting.
Sur la page d’entraide, les tutoriels sont ordonnées de la manière suivante (par ordre d’impact/priorité) :
— Les tutos déjà publiés passent à la fin de la liste ;
— Puis on trie par le nombre d’aides différentes demandées ;
— Puis on trie par la date de mise à jour.
Quelques données de test sont présentes dans le fichier fixtures/aide_tuto_media.yaml. En chargeant ces
dernières, un tuto peut alors être modifié pour recevoir des demandes d’aides (en allant les sélectionner dans la liste
à cet effet lors de l’édition du tuto). Pour chaque données de test, il faut aussi passer par l’interface d’administration Django pour ajouter les images relatives à ces aides (limites techniques du chargement automatique). Quatres
illustrations sont présentes dans le dossier de fixtures correspondant aux quatres aides présentes dans les fixtures.
Pour charger ces fixtures, il ne faut pas utiliser la routine habituelle manage.py loaddata. En effet, les demandes d’aide ont besoin d’être liées à des images. C’est pourquoi, nous utilisons la factory
zds.utils.factories.HelpWritingFactory pour mettre en place ces fixtures. Le code sera donc
python manage.py load_factory_data fixtures/advanced/aide_tuto_media.yaml
1.4 Documentation technique du back-end
Cette documentation est générée à partir des commentaires laissés dans le code source de Zeste de Savoir au format
docstring, et qui sont, pour des raisons d’internationalisation, rédigés en anglais.
Vous pouvez également retrouver la documentation fonctionnelle des modules ici.
1.4.1 Arborescence du back-end
Le back-end est divisé en différents modules qui assurent chacun une tâche du site. Ceux-ci sont intégralement localisés
dans le dossier zds/.
Arborescence générale de zds/
On retrouve un dossier pour chaque module du site :
zds/
+-- article/ # module des articles
|
+-- ...
+-- forum/ # module des forums
|
+-- ...
+-- gallery/ # module des galleries
|
+-- ...
+-- member/ # module des membres
|
+-- ...
+-- mp/ # module des messages privés
|
+-- ...
+-- munin/ # module de Munin, utilisé pour le monitoring
1.4. Documentation technique du back-end
43
Zeste de Savoir Documentation, Version 1.0
|
+-|
+-|
+-|
+-|
+-|
+-- ...
pages/ # module pour les autres pages, telles que la page d’accueil, ...
+-- ...
search/ # module de recherche
+-- ...
tutorial/ # module des tutoriels
+-- ...
utils/ # fonctions utiles à chaque module
+-- ...
middlewares/ # codes provenant de sources externes
+-- ...
On retrouve également dans ce dossier les quelques fichiers suivants, nécessaires à la configuration et au fonctionnement de Django :
zds/
+-- urls.py # définition générale des URLs du site, inclus celle de chacun des modules
+-- settings.py # paramètres du site
+-- settings_test.py # paramètres spécifiques aux tests
+-- wsgi.py
Contenu d’un module
Chacun des modules possède dans son dossier une arborescence fort semblable, et dans laquelle il est possible de
trouver :
module/
+-- migrations/
|
+-- ...
+-- api/
|
+-- ...
+-- tests/
|
+-- tests.py
|
+-- ...
+-- admin.py
+-- commons.py
+-- factories.py
+-- feeds.py
+-- forms.py
+-- managers.py
+-- models.py
+-- search_indexes.py
+-- urls.py
+-- views.py
Fichiers principaux
Django étant basé sur une architecture de type Modèle-Vue-Template, on retrouve les modèles dans le fichier
models.py et les contrôles associés à celles-ci dans views.py. Ces dernières peuvent employer des classes formulaires qui sont définis dans forms.py. Les URLs associées au module et permetant d’accéder aux vues sont définies
dans urls.py. On retrouve finalement des vues spécifiques associées aux fils RSS et Atom dans feeds.py.
On retrouve également des validateurs dans le fichier commons.py (voir à ce sujet la documentation de Django).
44
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Tests unitaires
Une partie importante du développement est basée sur les tests unitaires : afin d’éviter qu’un dévellopement futur ne
brise une fonctionnalité, une série de test associé à chaque module est écrite dans des fichiers situés dans le dossier
tests/ de chaque module. Cette série de test peut être lancée en utilisant la commande suivante :
python manage.py test zds.module
où il est nécéssaire de remplacer module par le nom du module associé. Ces tests utilisent des données de tests
générées par des factories (usines) qui sont définies dans factories.py.
Gestion de la base de données
Le dossier migrations/ permet à Django de consigner les changements effectués à des modèles qui modifient
également la structure de la base de donnée. Son contenu ne devrait pas être modifié manuelement, il l’est cependant
de manière automatique lorsque la commande suivante est utilisée :
python manage.py makemigrations
Celle-ci doit être utilisée lorsqu’une variable d’un modèle (dans models.py) est modifiée, ajoutée ou supprimée.
Si tel est le cas, n’oubliez pas d’inclure le fichier résultant (de la forme xxxx_auto_yyy.py) dans votre prochain
commit !
Cela permettra aux autres développeurs de répercuter les modifications en utilisant :
python manage.py migrate
API
Une description fonctionnelle de l’API est faite sur la page correspondante.
Les fichiers correspondants à une API du module (si elle existe) se situent dans le dossier api/. Dans celui-ci, se
trouvent principalement de nouvelles vues (api/views.py), URLs (api/urls.py) et tests (api/tests.py).
On retrouve également des serializers dans api/serializers.py, nécessaires à la création de l’API (voir à ce
sujet la documentation du REST framework (en)).
Autres
Le fichier search_index.py est utilisé par Django pour générer les index de recherche pour Solr.
Le fichier admin.py est quand à lui employé par Django pour la partie administration (accessible en local via
/admin/).
1.4.2 Les articles (article/)
Module situé dans zds/article/.
Fichiers documentés :
— Les articles (article/)
— Modèles (models.py)
— Vues (views.py)
1.4. Documentation technique du back-end
45
Zeste de Savoir Documentation, Version 1.0
Modèles (models.py)
Vues (views.py)
1.4.3 Les forums (forum/)
Module situé dans zds/forum/.
Fichiers documentés :
— Les forums (forum/)
— Modèles (models.py)
— Vues (views.py)
Modèles (models.py)
Vues (views.py)
1.4.4 Les galleries (gallery/)
Module situé dans zds/gallery/.
Fichiers documentés :
— Les galleries (gallery/)
— Modèles (models.py)
— Vues (views.py)
Modèles (models.py)
Vues (views.py)
1.4.5 Les membres (member/)
Module situé dans zds/member/.
Fichiers documentés :
— Les membres (member/)
— Modèles (models.py)
— Vues (views.py)
46
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Modèles (models.py)
Vues (views.py)
1.4.6 Les pages (pages/)
Module situé dans zds/pages/.
Fichiers documentés :
— Les pages (pages/)
— Vues (views.py)
Vues (views.py)
1.4.7 Les messages privés (mp/)
Module situé dans zds/mp/.
Fichiers documentés :
— Les messages privés (mp/)
— Modèles (models.py)
— Vues (views.py)
Modèles (models.py)
class zds.mp.models.PrivatePost(*args, **kwargs)
A private post written by an user.
get_absolute_url()
URL of a single PrivatePost object.
RetournePrivatePost object URL
Type retournéstr
class zds.mp.models.PrivateTopic(*args, **kwargs)
Topic private, containing private posts.
alone()
Check if there just one participant in the conversation (PrivateTopic).
RetourneTrue if there just one participant in PrivateTopic
Type retournébool
first_post()
Get the first answer in the PrivateTopic written by topic’s author, if exists.
RetournePrivateTopic object first answer (PrivatePost)
Type retournéPrivatePost object or None
first_unread_post(user=None)
Get the first PrivatePost the user has unread.
Paramètresuser (User object) – The user is reading the PrivateTopic. If None, the current user
is used.
1.4. Documentation technique du back-end
47
Zeste de Savoir Documentation, Version 1.0
Retournefirst PrivatePost unread
Type retournéPrivatePost object or None
get_absolute_url()
URL of a single PrivateTopic object.
RetournePrivateTopic object URL
Type retournéstr
get_last_answer()
Get the last answer in the PrivateTopic written by topic’s author, if exists.
RetournePrivateTopic object last answer (PrivatePost)
Type retournéPrivatePost object or None
get_post_count()
Get the number of private posts in a single PrivateTopic object.
Retournenumber of post in PrivateTopic object
Type retournéint
last_read_post(user=None)
Get the last PrivatePost the user has read.
Paramètresuser (User object) – The user is reading the PrivateTopic. If None, the current user
is used.
Retournelast PrivatePost read
Type retournéPrivatePost object or None
never_read(user=None)
Check if an user has never read the current PrivateTopic.
Paramètresuser (User object) – an user as Django User object. If None, the current user is used.
RetourneTrue if the PrivateTopic was never read
Type retournébool
slug()
PrivateTopic doesn’t have a slug attribute of a private topic. To be compatible with older private topic, the
slug is always re-calculate when we need one. :return : title slugify.
class zds.mp.models.PrivateTopicRead(*args, **kwargs)
Small model which keeps track of the user viewing private topics.
It remembers the topic he looked and what was the last private Post at this time.
zds.mp.models.mark_read(privatetopic, user=None)
Mark a private topic as read for the user.
Paramètres
—privatetopic (PrivateTopic object) – a PrivateTopic to check
—user (User object) – an user as Django User object. If None, the current user is used
Retournenothing is returned
Type retournéNone
zds.mp.models.never_privateread(privatetopic, user=None)
Check if a private topic has been read by an user since it last post was added.
Paramètres
—privatetopic (PrivateTopic object) – a PrivateTopic to check
—user (User object) – an user as Django User object. If None, the current user is used
RetourneTrue if the PrivateTopic was never read
Type retournébool
48
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Vues (views.py)
1.4.8 Les tutoriels (tutorial/)
Module situé dans zds/tutorial/.
Fichiers documentés :
— Les tutoriels (tutorial/)
— Modèles (models.py)
— Vues (views.py)
Modèles (models.py)
Vues (views.py)
1.4.9 Les utilitaires (utils/)
Module situé dans zds/utils/. Il regroupe certaines fonctions et objets utiles à tout les autres modules.
Fichiers documentés :
— Les utilitaires (utils/)
— Modèles (models.py)
— Articles (articles.py)
— Forums (forums.py)
— Messages privés (mps.py)
— Tutoriels (tutorials.py)
— Les processeurs de contexte (context_processor.py)
— Autres (misc.py)
Modèles (models.py)
Articles (articles.py)
zds.utils.articles.export_article(article)
Export an article to a dict.
Forums (forums.py)
Messages privés (mps.py)
Tutoriels (tutorials.py)
Les processeurs de contexte (context_processor.py)
La doc de Django explique le principe des context_processors comme suit :
1.4. Documentation technique du back-end
49
Zeste de Savoir Documentation, Version 1.0
Un processeur de contexte possède une interface très simple : ce n’est qu’une fonction Python acceptant un
paramètre, un objet HttpRequest, et renvoyant un dictionnaire qui est ensuite ajouté au contexte de gabarit. Chaque
processeur de contexte doit renvoyer un dictionnaire.
Les processeurs de contexte personnalisés peuvent se trouver n’importe où dans le code. Tout ce que Django
demande, c’est que le réglage TEMPLATE_CONTEXT_PROCESSORS contienne le chemin vers le processeur
personnalisé.
(pour plus de détails, voir la documenation de Django à ce sujet)
Autres (misc.py)
zds.utils.misc.compute_hash(filenames)
returns a md5 hexdigest of group of files to check if they have change
zds.utils.misc.has_changed(instance, field, manager=’objects’)
Returns true if a field has changed in a model May be used in a model.save() method.
1.5 Le front-end
Le terme front-end désigne la partie du code associée à l’affichage des données issues du back-end.
Il s’agit donc de la partie du code définissant le design et l’affichage, mais aussi de l’ergonomie, la réactivité et
l’expérience utilisateur. Sa mise en place est basée sur trois langages :
— Le HTML, aidé du langage de gabarit de Django ;
— SASS (en) pour les feuilles de style ;
— Javascript pour les interactions.
NodeJS (en), NPM (en) (gestionaire de paquet pour NodeJS) et Gulp (en) sont utilisés pour générer le code final minifié
et cohérent. Le développement du front-end requiert donc des outils spécifiques dont l’installation est expliquée ici.
1.5.1 Le design
Structure globale du site
Le site est composé de plusieurs grandes parties.
L’en-tête
On peut découper l’en-tête du site en quatre.
Le logo Le logo est simplement un lien qui a pour contenu une image. L’image change en fonction de la taille de
l’écran.
50
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Le menu Le menu est composé soit d’un lien, soit d’un menu déroulant. Ces derniers contiennent des listes de liens.
La logbox La logbox contient trois menus déroulants :
— le premier affiche les messages privés ;
— le deuxième affiche les notifications ;
— et le dernier contient des liens vers les zones réservées à l’utilisateur.
Le fil d’ariane Le fil d’ariane est en deux partie :
— à gauche, une aide à la navigation ;
— à droite, un petit formulaire de recherche.
La barre latérale
La barre latérale contient des listes de liens, boutons ou formulaires permettant à l’utilisateur d’effectuer des actions.
1.5. Le front-end
51
Zeste de Savoir Documentation, Version 1.0
F IGURE 1.17 – Barre latérale de la page d’un profil
52
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
Le contenu principal
Le contenu principal change radicalement suivant les pages, comme son nom l’indique, il contient le contenu principal,
important.
Le bas de page
Le bas de page est sûrement la partie la plus simple du site. Il contient trois flexboxs :
— celui de gauche affiche le nom du site ;
— celui du milieu contient les liens vers les comptes des réseaux sociaux du site ;
— celui de droite contient des liens vers les pages annexes du site, tel que les CGUs par exemple.
Le menu pour mobile
Le menu pour mobile est généré en javascript à partir de l’en-tête et de la barre latérale. Le code est disponible sur
Github.
Quelques éléments propres au site
Les boîtes modales
Une boîte modale est une pseudo-fenêtre qui s’affiche au clique de certains boutons. Elle a pour but de faire confirmer
un choix à l’utilisateur ou de permettre à celui-ci de remplir un formulaire.
La lecture zen
La lecture zen est un mode d’affichage des tutoriels et des articles permettant à l’utilisateur de se concentrer sur sa
lecture. Elle cache l’en-tête et la barre latérale de la page pour ne laisser que le contenu principal. Techniquement,
c’est un mélange de javascript et de (S)CSS.
Arborescence des dossiers
Nous utilisons deux dossiers présents à la racine :
— templates/ pour les fichiers HTML, qui sont agrémentés du langage de gabarit de Django ;
— assets/ pour les images, les smileys et les fichiers SCSS et JS.
Lors du “build”, un dossier dist/ contenant les fichiers optimisés venant de assets/ est créé.
templates/
Voici un extrait du dossier contenant les gabaris :
templates/
+-- tutorial/ # Dossier contenant les gabaris des pages des tutoriels
|
+-- tutorial/
|
+-- chapter/
|
|
+-- edit.html
1.5. Le front-end
53
Zeste de Savoir Documentation, Version 1.0
54
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
F IGURE 1.18 – La boîte modale pour ajouter un participant à un message privé
F IGURE 1.19 – La boîte modale pour confirmer sa désinscription
1.5. Le front-end
55
Zeste de Savoir Documentation, Version 1.0
F IGURE 1.20 – Un tutoriel sans lecture zen
F IGURE 1.21 – Ce même tutoriel avec lecture zen
56
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
|
|
|
|
|
|
|
|
+-|
|
|
|
+-|
|
|
...
|
|
+-|
+-+-...
+-- new.html
...
extract/
base.html
export.html
pages/ # Dossier contenant les pages du site
+-- about.html
+-- contact.html
...
misc/ # Dossier contenant des fichiers utilisés dans plusieurs modules
+-- zen_button.part.html
+-- previsualization.part.html
...
assets/
Voici un aperçu du dossier :
assets/
+-- images/
|
+-- sprite/ # Images qui seront dans le sprite
|
|
+-- arrow-right.png
|
|
+-- arrow-right-blue.png
|
|
...
|
|
|
| # Autres images
|
+-- favicon.ico
|
+-- favicon.png
|
+-- [email protected]
|
+-- logo.png
|
...
|
+-- js/
|
+-- vendors/ # Toutes les bibliothèques (disponibles après l’installation des outils)
|
|
+-- jquery.js
|
|
...
|
|
|
+-- accessibility-links.js
|
+-- data-click.js
|
...
|
+-- scss/
|
+-- layout/
|
|
+-- _header.scss
|
|
+-- _sidebar.scss
|
|
...
|
+-- components/
|
|
|
+-- main.scss # Fichier de configuation
|
+-- sprite-template.mustache # Fichier servant à la génération sprite
|
...
|
1.5. Le front-end
57
Zeste de Savoir Documentation, Version 1.0
+-- smileys/
+-- ange.png
+-- angry.gif
...
dist/
Voilà à peu près ce qui est généré lors du “build” :
dist/
+-- css/
|
+-- main.css # Tout le CSS compilé...
|
+-- main.min.css # ...et minimisé
|
+-- images/ # Toutes les images optimisées
|
+-- favicon.ico
|
+-- favicon.png
|
+-- [email protected]
|
|
|
+-- [email protected] # Sprite haute définition
|
+-- sprite.png # Sprite moyenne définition
|
...
|
+-- js/
|
+-- vendors/ # Toutes les bibliothèques non-minimisées
|
|
+-- jquery.js
|
|
...
|
+-- vendors.js # Toutes les bibliothèques rassemblées...
|
+-- vendors.min.js # ...et minimisées
|
|
|
+-- main.js # Tout le JS customisé rassemblé...
|
+-- main.min.js # ...et minimisé
|
|
|
+-- all.js # Tout le JS rassemblé...
|
+-- all.min.js # ...et minimisé
|
+-- smileys/
+-- ange.png
+-- angry.gif
...
Glossaire
— flexbox : modèle de boîte flexible en HTML/CSS (voir le tutoriel sur Alsacréations)
1.5.2 Elements de templates personnalisés
Le package zds/utils/templatetags contient un ensemble de tags et filtres personnalisés pouvant être utilisés
dans les templates rendues par Django.
La majorité de ces modules proposent aussi des fonctions proposant les même fonctionnalités depuis le reste du code
Python.
58
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
append_to_get
L’élément append_to_get permet de rajouter des paramètres à la requête GET courante. Par exemple, sur une page
module/toto, le code de template suivant :
{% load append_to_get %}
<a href="{% append_to_get key1=var1,key2=var2 %}">Mon lien</a>
produira le code suivant :
<a href="module/toto?key1=1&key2=2">Mon lien</a>
si le contenu de var1 est 1 et le contenu de var2 est 2
captureas
L’élément captureas permet de demander d’effectuer le rendu d’un bloc de template et de stocker son contenu dans
une variable. Ainsi le code suivant :
{% load captureas %}
{% captureas var2 %}
{% for i in ’xxxxxxxxxx’ %}
{{forloop.counter0}}
{% endfor %}
{% endcaptureas %}
ne produit rien en sortie mais affecte le résultat du bloc entre les éléments {% captureas var2 %} et {%
endcaptureas %}, soit 0123456789, dans la variable de template var2
date
Plusieurs filtres sont disponible dans ce module.
format_date
Ce filtre formate une date au format DateTime destiné à être affiché sur le site :
{% load date %}
{{ date | format_date}}
tooltip_date
Ce filtre effectue la même chose que format_date mais à destination des tooltip.
humane_time
Formate une date au format Nombre de seconde depuis Epoch en un élément lisible. Ainsi :
{% load date %}
{{ date_epoch | humane_time}}
sera rendu :
1.5. Le front-end
59
Zeste de Savoir Documentation, Version 1.0
01 Jan 1970, 01:00:42
Si le contenu de date_epoch etait de 42.
emarkdown
Markdown vers HTML
Permet de rendre un texte markdown en HTML :
— emarkdown : Transforamtion classique
— emarkdown_inline : Transforamtion uniquement des éléments inline et donc pas de blocs. Utilisés pour
les signatures des membres.
Markdown vers Markdown
Ces élements sont utilisés dans le cadre de la transformation du markdown avant d’être traité par Pandoc lors de la
génération des fichiers PDF et EPUB des tutos :
— decale_header_1 : Décale les titres de 1 niveau (un titre de niveau 1 devient un titre de niveau 2, etc.)
— decale_header_2 : Décale les titres de 2 niveaux (un titre de niveau 1 devient un titre de niveau 3, etc.)
— decale_header_3 : Décale les titres de 3 niveaux (un titre de niveau 1 devient un titre de niveau 4, etc.)
email_obfuscator
Ces templatetags sont principalement fondés sur https://github.com/morninj/django-email-obfuscator.
obfuscate
L’email va être encodé avec des caractères ASCII pour le protéger des bots :
{% load email_obfuscator %}
{{ ’[email protected]’|obfuscate }}
obfuscate_mailto
Ce templatetag ajoute en plus un mailto. Il prend un paramètre optionnel qui permet d’avoir un text personnalisé
dans la balise <a> :
{% load email_obfuscator %}
{{ ’[email protected]’|obfuscate_mailto:"my custom text" }}
Ce qui donnera :
<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#111;&#117;&#114;&#64;&#101;&#109;&#97;&#105;
60
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
obfuscate_mailto_top_subject
Identique sur le fonctionnement à obfuscate_mailto, ce templatetag ajoute en plus un sujet (qui remplace le
champ pouvant être inséré entre les balises <a> et </a>) ainsi que target="_top".
Il est utilisé sur la page « Contact ».
Exemple :
{% load email_obfuscator %}
{{ ’[email protected]’|obfuscate_mailto_top_subject:"Contact communication" }}
1.6 API
1.6.1 Informations générales
Version courante
L’API est toujours en développement et n’est pas encore versionnée. Même si elle le deviendra une fois son développement stabilisé, elle doit être vue comme une bêta avec les changements que cela peut impliquer dans ses paramètres
et ses réponses.
Schéma
L’API
est
accessible
à
partir
du
domaine
zestedesavoir.com/api/
(prochainement
api.zestedesavoir.com) et en HTTP ou en HTTPS mais dès lors où vous effectuez des requêtes authentifiées,
le HTTPS devient obligatoire. De base, toutes les réponses sont renvoyées en JSON.
$ curl -i https://zestedesavoir.com/api/membres/
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 14 Feb 2015 19:41:29 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
ETag: "d8f9437e4f88b4e6e2ad0a6d770d970bfdd5bbbc689cc3b3390759d06d4f105a"
Vary: Accept, Cookie
Allow: GET, POST, HEAD, OPTIONS
P3P: CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"
{
"count":0,
"next":null,
"previous":null,
"results":[]
}
Tous les timestamp sont retournés sous le format ISO 8601 : YYYY-MM-DDTHH:MM:SSZ.
1.6. API
61
Zeste de Savoir Documentation, Version 1.0
Les verbes HTTP
—
—
—
—
GET : Utilisez pour récupérer des ressources.
POST : Utilisez pour créer des ressources.
PUT : Utilisez pour mettre à jour des ressources.
DELETE : Utilisez pour supprimer des ressources.
Les autres verbes ne sont pas supportés.
Les formats d’entrées/sorties
Par défaut, le serveur renvoie les réponses sous le format JSON mais il gère aussi le XML. Pour demander au serveur
de renvoyer les réponses sous ce dernier format, il faut utiliser l’en-tête Accept en spécifiant application/xml
comme valeur (ou application/json pour renvoyer du JSON).
$ curl -H "Accept: application/xml" https://zestedesavoir.com/api/membres/
Les formats de sorties (en) sont renseignés dans le fichier settings.py sous l’attribut
DEFAULT_RENDERER_CLASSES du dictionnaire REST_FRAMEWORK. Pour Django Rest Framework, tous
les formats de sorties sont des renderer.
REST_FRAMEWORK = {
’DEFAULT_RENDERER_CLASSES’: (
’rest_framework.renderers.JSONRenderer’,
’rest_framework.renderers.XMLRenderer’,
’rest_framework.renderers.BrowsableAPIRenderer’,
),
}
Plusieurs formats d’entrées sont supportés par le serveur, à savoir le JSON (par défaut), l’XML, le formulaire et le multi
part (x-www-form-urlencoded). Ces formats peuvent être renseignées avec l’en-tête Content-Type.
$ curl -H "Content-Type: application/xml" https://zestedesavoir.com/api/membres/
Les formats d’entrées (en) sont renseignés dans le fichier settings.py sous l’attribut
DEFAULT_PARSER_CLASSES du dictionnaire REST_FRAMEWORK. Pour Django Rest Framework, tous les
formats de sorties sont des parser.
REST_FRAMEWORK = {
’DEFAULT_PARSER_CLASSES’: (
’rest_framework.parsers.JSONParser’,
’rest_framework.parsers.XMLParser’,
’rest_framework.parsers.FormParser’,
’rest_framework.parsers.MultiPartParser’,
),
}
Cache
Un cache spécifique à l’API est mis en place pour mettre en cache toutes les méthodes GET. Le système n’est pas
spécifique à Django Rest Framework mais est disponible via une librairie tierce qui a été développée spécialement
pour fonctionner avec DRF, DRF-Extensions (en).
Pour placer un cache, il suffit d’annoter la méthode GET voulue par l’annotation @cache_response() (comme
le mentionne la documentation à ce sujet (en) ). Par exemple, la méthode GET pour récupérer la liste paginée des
membres ressemblerait au code ci-dessous.
62
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
class MemberListAPI(ListCreateAPIView, ProfileCreate, TokenGenerator):
queryset = Profile.objects.all()
list_key_func = PagingSearchListKeyConstructor()
@cache_response(key_func=list_key_func)
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
Dans le contexte de Zeste de Savoir, ce n’est pas suffisant. Comme la plupart des routes GET peuvent prendre des
paramètres, il faut permettre au cache de distinguer une URL X avec des paramètres et une URL Y avec d’autres
paramètres. Ceci se fait en spécifiant une clé au cache de la méthode. Par exemple, pour la pagination, si aucune clé
n’est renseignée, le cache renverra toujours le même résultat peu importe la page souhaitée.
Pour enrichir la clé d’un cache, DRF-Extensions propose les KeyConstructor. Toutes les informations et les
possibilités à ce sujet sont disponibles dans la documentation de cette librairie (en).
ETag
Un ETag est un identifiant unique assigné par le serveur à chaque version d’une ressource accessible via une URL.
Si la ressource accessible via cette URL change, un nouvel ETag différent du précédent sera assigné. Cela permet
notamment d’alléger le serveur lorsque le client utilise cet en-tête pour que le serveur ne calcul que l’ETag de la
ressource et juge nécessaire ou non d’effectuer la requête en base de données si l’ancien et le nouveau ETag sont
différents.
Le calcul de l’ETag n’est pas natif à Django Rest Framework mais est accessible via la bibliothèque DRF-Extensions
(en). Le calcul est ajouté sur toutes les méthodes GET et PUT. Il est inutile de calculer des ETags pour des requêtes
POST et DELETE puisque ces deux méthodes ont pour objectif de créer et supprimer des ressources.
Pour placer un ETag, il suffit d’annoter la méthode voulue par l’annotation @etag(). Par exemple, la méthode GET
pour récupérer la liste paginée des membres ressemblerait au code ci-dessous.
class MemberListAPI(ListCreateAPIView, ProfileCreate, TokenGenerator):
queryset = Profile.objects.all()
list_key_func = PagingSearchListKeyConstructor()
@etag(key_func=list_key_func)
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
Dans le contexte de Zeste de Savoir, ce n’est pas suffisant. Comme la plupart des routes GET et PUT peuvent prendre
des paramètres, il faut permettre au cache de distinguer une URL X avec des paramètres et une URL Y avec d’autres
paramètres. Ceci se fait en spécifiant une clé à l’ETag de la méthode. Par exemple, pour la pagination, si aucune clé
n’est renseignée, l’ETag ne sera jamais recalculé peu importe la page souhaitée.
Pour enrichir la clé de l’ETag, DRF-Extensions propose les KeyConstructor. Toutes les informations et les possibilités à ce sujet sont disponibles dans la documentation de cette librairie (en).
Note : L’ETag et le cache peuvent fonctionner ensemble. Une méthode peut être annotée avec @etag() et
@cache_response().
Pour utiliser un ETag, faite une requête vers n’importe quelle ressource en GET ou PUT. Dans les en-têtes de la
réponse, il y figurera l’ETag avec sa valeur. Pour les prochaines requêtes vers cette même ressource, renseignez l’entête If-None-Match et l’ETag sauvegardé comme valeur.
$ curl -H "If-None-Match: da54a5d285fbfc52bf62637147ecb5c11c7199ed78848b7f43781df0cd039b89" https://z
1.6. API
63
Zeste de Savoir Documentation, Version 1.0
Si le serveur constate qu’il n’y a aucun changement dans la ressource, il renverra une réponse 304 Not Modified
avec un corps vide. Il n’est alors pas nécessaire de mettre à jour les valeurs sauvegardées en locale pour les ressources
désirées. Dans le cas contraire, les ressources demandées seront renvoyées avec un nouvel ETag à sauvegarder.
Throttling
Le throttling permet de poser des limites quant au nombre de requêtes possibles pour un utilisateur anonyme et
connecté. Cette fonctionnalité est native à Django Rest Framework et se met en place facilement via le fichier
settings.py du projet sous l’attribut DEFAULT_THROTTLE_CLASSES du dictionnaire REST_FRAMEWORK
pour spécifier les types de throttling à appliquer et sous DEFAULT_THROTTLE_RATES pour spécifier les taux.
REST_FRAMEWORK = {
’DEFAULT_THROTTLE_CLASSES’: (
’rest_framework.throttling.AnonRateThrottle’,
’rest_framework.throttling.UserRateThrottle’
),
’DEFAULT_THROTTLE_RATES’: {
’anon’: ’60/hour’,
’user’: ’2000/hour’
}
}
Il existe d’autres configurations possibles. Pour en prendre conscience, rendez-vous dans la documentation du throttling (en).
Pagination
La pagination permet d’éviter au serveur de faire des requêtes trop lourdes sur la base de données. Par exemple, si
un client désire récupérer la liste de tous les utilisateurs de la plateforme et que cette même plateforme dispose d’un
très grand nombre d’utilisateurs, la requête en base de données pourrait être lourde. Coupler à ceci des intentions
malveillantes pour faire tomber le serveur, cela en devient presque une sécurité de paginer les listes de ressources.
La pagination peut être configurée directement dans les vues de l’API mais aussi dans le fichier settings.py pour
s’appliquer à l’ensemble des listes de toutes les ressources de l’API. Dans le fichier settings.py, PAGINATE_BY
renseigne la taille d’une page, PAGINATE_BY_PARAM permet aux clients de modifier la taille d’une page et
MAX_PAGINATE_BY permet de limiter cette dernière customisation.
REST_FRAMEWORK = {
’PAGINATE_BY’: 10,
’PAGINATE_BY_PARAM’: ’page_size’,
’MAX_PAGINATE_BY’: 100,
}
# Default to 10
# Allow client to override, using ‘?page_size=xxx‘.
# Maximum limit allowed when using ‘?page_size=xxx‘.
Toutes les informations complémentaires à ce sujet sont disponibles dans la documentation de la pagination (en).
Son utilisation est simple, il suffit de renseigner la page avec le paramètre page et, optionnellement, page_size
pour renseigner la taille de la page. Par exemple, récupérer la page 2 d’une page de taille 2 ressemblera à la requête
suivante.
$ curl https://zestedesavoir.com/api/membres/?page=2&page_size=2
Dans la réponse, on retrouve des méta informations à propos de la liste : la taille totale de la liste, l’URL vers la page
suivante et précédente et la liste attendue avec la ressource souhaitée.
64
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
{
"count": 43,
"next": "https://zestedesavoir.com/api/membres/?page=3&page_size=2",
"previous": "https://zestedesavoir.com/api/membres/?page=1&page_size=2",
"results": [
{
"pk": 41,
"username": "boo123451234",
"is_active": false,
"date_joined": "2015-02-08T15:53:12.666839"
},
{
"pk": 40,
"username": "boo12345123",
"is_active": false,
"date_joined": "2015-02-08T15:53:09.436657"
}
]
}
1.6.2 Authentification
Bibliothèque tierce choisie
Django Rest Framework supporte plusieurs systèmes d’authentification (comme en témoigne la documentation sur
l’authentification (en)). Sur Zeste de Savoir, il a été décidé d’utiliser l’OAuth2 (dont la spécification du protocole est
disponible via ce lien (en)) pour tenter d’avoir le système le plus sécurisé possible.
L’authentification n’est pas directement dans Django Rest Framework, il ne fait que supporter des librairies tierces qui
s’en occupe. La librairie choisie est Django OAuth Toolkit pour sa forte compatibilité avec Django Rest Framework,
sa maintenance et sa compatibilité Python 3 et Django 1.7 (ou plus).
Toute sa configuration est détaillée dans la documentation de cette bibliothèque.
Utilisation
Créer un client
Des requêtes authentifiées ne peuvent se faire sans un client. Ce client est appelé “Application” dans Django OAuth
Toolkit. C’est pourquoi, il sera nommé ainsi dans la suite de cette documentation. Pour créer une application, il faut en
demander la création auprès d’un administrateur de la plateforme où il sera en mesure d’en créer 2 types : confidentiel
et public. Une application confidentielle permet l’utilisation d’un refresh_token au contraire d’une application
publique qui se contente de renvoyer un access_token.
Pour l’administrateur, il doit se rendre dans la section “OAuth2_provider”, puis créer une application. Un identifiant
et une clé secrète cliente seront automatiquement générés et seront les informations à communiquer auprès du développeur tiers. Après, il doit renseigner au minimum l’utilisateur concerné par la demande, le type du client et le grant
type.
— Utilisateur concerné : Cela ne veut pas dire que cet utilisateur est le seul à pouvoir s’authentifier avec l’application. Cela le rend juste responsable en cas de dérive.
— Type du client : Privilégiez le type confidentiel au public pour permettre aux clients tiers de ne pas redemander
aux utilisateurs leurs informations de connexion après l’expiration de leur token.
— grant type : Renseignez Resource owner password-based pour baser l’authentification sur le mot de passe de
l’utilisateur final.
1.6. API
65
Zeste de Savoir Documentation, Version 1.0
Récupérer les tokens d’authentification
Pour récupérer les tokens, le développeur doit exécuter une requête en POST et en spécifiant l’identifiant et la clé
secrète de l’application, le grant type spécifié dans l’application et le pseudo/mot de passe de l’utilisateur qui souhaite
s’authentifier. Une requête basique ressemblerait à la commande ci-dessous. Toute fois, sachez que les caractères
spéciaux doivent être échappés dans une commande curl comme celle exposé dans cette documentation. On ne peut
que vous conseiller d’exécuter cette même requête plutôt dans une console REST comme il en existe des centaines.
$ curl -X POST -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=password&user
Si l’application est bien en confidentielle, la réponse à cette requête exposera 2 tokens, son type, sa date d’expiration
et sa portée.
— access_token : Token a utiliser dans les requêtes que vous souhaitez authentifier.
— token_type : Le type de l’OAuth2 sera toujours Bearer et devra être spécifié dans les prochaines requêtes.
— expires_in : Le timestamp correspondant à la date d’expiration de l’access_token.
— refresh_token : Permet d’effectuer une nouveau requête pour récupérer les tokens d’authentification sans
spécifier le pseudo et le mot de passe de l’utilisateur.
— scope : Portée du token d’authentification générée pour le serveur.
{
"access_token": "wERPXXHpYAsJV29eATLjSO2u5bamyw",
"token_type": "Bearer",
"expires_in": 36000,
"refresh_token": "1HJaUfFYA5jE54e2Wz1yEMRi89z6er",
"scope": "read write"
}
Note : S’il existe déjà un token actif pour l’utilisateur final, l’ancien token sera invalidé au profit du nouveau.
Utiliser un access_token
Pour utiliser l’access_token, il faut le renseigner dans l’en-tête de la requête sous l’attribut Authorization
avec comme valeur Bearer wERPXXHpYAsJV29eATLjSO2u5bamyw.
$ curl -H "Authorization: Bearer wERPXXHpYAsJV29eATLjSO2u5bamyw" https://zestedesavoir.com/api/membre
Attention : La requête doit se faire en HTTPS obligatoirement.
Utiliser un refresh_token
Si le token n’est plus valide ou que vous avez perdu l’access_token de l’utilisateur final, il faut en récupérer un
nouveau grâce au refresh_token. Son utilisation est similaire à l’authentification sauf qu’il n’est pas nécessaire
de renseigner le pseudo et le mot de passe mais le refresh_token à la place et de spécifier un grant_type avec
comme valeur refresh_token.
$ curl -X POST -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=refresh_token
A la suite de cela, de nouveaux tokens seront renvoyés et devront être sauvegardés pour une prochaine utilisation si
nécessaire.
66
Chapitre 1. Sommaire
Zeste de Savoir Documentation, Version 1.0
1.6.3 Django REST Swagger
Django REST Swagger est une bibliothèque qui génère automatiquement la documentation d’une API Django basé
sur la bibliothèque Django REST framework.
Cette documentation est accessible par l’url http://zestedesavoir.com/api/ et, via cette page, il est possible de :
— Lister toutes les APIs pour toutes les ressources.
— Connaitre les paramètres, les codes d’erreur et un exemple de réponse.
— Exécuter toutes les routes disponibles dans l’API.
Pour maintenir cette documentation, rendez-vous sur sa documentation (en) qui explique sur quoi se base la bibliothèque pour générer la documentation et comment y rajouter de l’information.
1.7 Autres outils
Vous retrouverez ici quelques éléments utiles.
1.7.1 Détection automatique des erreurs flake8 avec Git
Afin de s’assurer qu’aucune erreur de mise en forme ne passe les commits, il peut être utile de rajouter un hook de
pre-commit à git. Un hook est un petit programme qui sera exécuté avant une action particulière de git. En l’occurence
nous allons rajouter un hook qui s’executera juste avant la validation d’un commit.
Pour cela, commencer par créer et éditer le fichier .git/hooks/pre-commit
Ensuite, il ne reste plus qu’à rajouter le contenu suivant dans ce fichier et dorénavant le controle flake (pour le respect
PEP) sera exécuté avant la validation du message de commit. Ainsi, plus aucune erreur flake ne viendra vous embêter
à posteriori et la base de code restera propre et lisible au cours du temps !
#!/bin/sh
flake8 --exclude=migrations,urls.py,settings.py --max-line-length=120 zds
# Store tests result
RESULT=$?
[ $RESULT -ne 0 ] && exit 1
exit 0
Enfin n’oubliez pas de le rendre executable via chmod
chmod +x .git/hooks/pre-commit
1.7.2 Installer un plugin de recherche à votre navigateur
Vous pouvez installer un plugin de recherche à votre navigateur en deux clics.
1.7. Autres outils
67
Zeste de Savoir Documentation, Version 1.0
1.7.3 Générer les PDFs des tutoriels
Vous avez la possibilité de générer le (ou les) PDF(s) d’un (ou plusieurs) tutoriel(s) déjà publié(s) en une commande :
python manage.py pdf_generator
Pour préciser le (ou les) tutoriel(s) à générer, il suffit de rajouter l’argument id. Par exemple, pour générer les pdfs
des tutoriels dont l’id est 125, 142, et 56 if faut mettre id=125,142,56.
68
Chapitre 1. Sommaire
Index des modules Python
z
zds.mp.models, 47
zds.utils.articles, 49
zds.utils.misc, 50
69
Zeste de Savoir Documentation, Version 1.0
70
Index des modules Python
Index
A
alone() (méthode zds.mp.models.PrivateTopic), 47
PrivateTopic (classe dans zds.mp.models), 47
PrivateTopicRead (classe dans zds.mp.models), 48
C
S
compute_hash() (dans le module zds.utils.misc), 50
slug() (méthode zds.mp.models.PrivateTopic), 48
E
Z
export_article() (dans le module zds.utils.articles), 49
zds.mp.models (module), 47
zds.utils.articles (module), 49
zds.utils.misc (module), 50
F
first_post() (méthode zds.mp.models.PrivateTopic), 47
first_unread_post()
(méthode
zds.mp.models.PrivateTopic), 47
G
get_absolute_url() (méthode zds.mp.models.PrivatePost),
47
get_absolute_url()
(méthode
zds.mp.models.PrivateTopic), 48
get_last_answer()
(méthode
zds.mp.models.PrivateTopic), 48
get_post_count() (méthode zds.mp.models.PrivateTopic),
48
H
has_changed() (dans le module zds.utils.misc), 50
L
last_read_post() (méthode zds.mp.models.PrivateTopic),
48
M
mark_read() (dans le module zds.mp.models), 48
N
never_privateread() (dans le module zds.mp.models), 48
never_read() (méthode zds.mp.models.PrivateTopic), 48
P
PrivatePost (classe dans zds.mp.models), 47
71