`_)
+
+L'aspect technique
+==================
+
+Le stockage dans la base de donnée
+----------------------------------
+
+Aujourd'hui la base de données est utilisée comme zone tampon, surtout parce que Django propose déjà des methodes
+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 brouillon
+- sha_validation : le hash du commit de la version validation
+- 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. A terme aussi, on devrait pouvoir en faire des branches.
+
+Il faut aussi noter qu'on ne stocke pas le contenu (introduction, conclusion, extrait) directement en base de données, on stocke uniquement les chemin relatif vers le fichiers markdown qui contiennent le contenu.
+
+Les données versionnés
+----------------------
+
+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épot). A 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 chemin 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ée pour afficher quelque chose.
+
+Qu'en est-il des images ?
++++++++++++++++++++++++++
+
+Le versionning des images d'un tutoriel (celles qui font partie de la gallerie du tuto) continue a 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 traine dans son archive.
+- avoir besoin d'interroger le dépot à 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épot 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.
diff --git a/doc/sphinx/source/utils/templatetags.rst b/doc/sphinx/source/utils/templatetags.rst
new file mode 100644
index 0000000000..dcf979854b
--- /dev/null
+++ b/doc/sphinx/source/utils/templatetags.rst
@@ -0,0 +1,102 @@
+
+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.
+
+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 %}
+ Mon lien
+
+produira le code suivant ::
+
+ Mon lien
+
+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 ::
+
+ 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.)
+
+
+
+autres
+------
+
+**TODO**
diff --git a/doc/sphinx/source/utils/utils.rst b/doc/sphinx/source/utils/utils.rst
new file mode 100644
index 0000000000..9422b32f8c
--- /dev/null
+++ b/doc/sphinx/source/utils/utils.rst
@@ -0,0 +1,10 @@
+=============
+Autres outils
+=============
+
+Le package ``zds/utils`` contient un certains nombres d'outils transverses.
+
+.. toctree::
+ :maxdepth: 2
+
+ templatetags
\ No newline at end of file
diff --git a/doc/workflow.md b/doc/workflow.md
new file mode 100644
index 0000000000..86eb432d54
--- /dev/null
+++ b/doc/workflow.md
@@ -0,0 +1,76 @@
+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](CONTRIBUTING.md) devrait répondre à vos questions quant au processus de développement.
+
+Ce _workflow_ est très fortement basé sur le [Git flow](http://nvie.com/posts/a-successful-git-branching-model/).
+
+# _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`), qui est testée en pré-production et corrigée sur cette branche
+- En cas de bug ultra-urgent à corriger en production, on crée une branche spéciale
+
+# _Workflow_ de développement
+
+## Description
+
+1. Les arrivées fonctionnalités et corrections de gros bugs se font via des _Pull Requests_ (PR) depuis des _forks_.
+2. Ces PR sont unitaires. Aucune PR qui corrige plusieurs problèmes ou apporte plusieurs fonctionnalité ne sera accepté ; 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.
+
+## Quelques précisions
+
+**Où peut-on trouver les détails pratiques ?**
+
+Tous ces détails sont [dans la page de contribution](CONTRIBUTING.md). 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)
+
+# _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.
+ 1. Création d'une **nouvelle branche de release** du nom de la version (par exemple `release-v1.7`)
+ 2. Déploiement de cette branche sur l'environnement de pré-production, avec un _dump_ de données de production
+ 3. Tests les plus complets possibles sur ce nouvel environnement
+ 4. 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 :
+ 1. Merge de la branche de _release_ dans `dev`
+ 2. Merge de la branche de _release_ dans `prod`
+ 3. Tag avec la nouvelle version
+ 4. Mise en production sur le serveur
+ 5. 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. 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é !
+
+# Glossaire
+
+- **MEP** : Mise En Production
+- **PR** : _Pull Request_
+- **QA** : _Quality Assurance_
diff --git a/fixtures/archive-gallery.zip b/fixtures/archive-gallery.zip
new file mode 100644
index 0000000000..d6d0c7a03d
Binary files /dev/null and b/fixtures/archive-gallery.zip differ
diff --git a/fixtures/users.yaml b/fixtures/users.yaml
index 70d5317d02..cb659b80c3 100644
--- a/fixtures/users.yaml
+++ b/fixtures/users.yaml
@@ -52,6 +52,22 @@
username: ïtrema
password: pbkdf2_sha256$12000$FssznaRHkjFK$8GvNM2oqOIHRNNr4G+8s+cbk6LIYXaxGOsI1Hh6cswI=
is_superuser: False
+- model: auth.user
+ pk: 5
+ fields:
+ first_name: Anonymous
+ last_name: User
+ username: anonymous
+ password: pbkdf2_sha256$12000$DWHNLpO3jXIv$MrnMZblGu1Q+xemP4XK2keLtbyfkRXxczPTLhSJ0AAM=
+ is_superuser: False
+- model: auth.user
+ pk: 6
+ fields:
+ first_name: Auteur externe
+ last_name: User
+ username: Auteur externe
+ password: pbkdf2_sha256$12000$DWHNLpO3jXIv$MrnMZblGu1Q+xemP4XK2keLtbyfkRXxczPTLhSJ0AAM=
+ is_superuser: False
- model: member.Profile
pk: 1
fields:
@@ -72,3 +88,13 @@
fields:
user: 4
last_ip_address: 192.168.0.1
+- model: member.Profile
+ pk: 5
+ fields:
+ user: 5
+ last_ip_address: 192.168.0.1
+- model: member.Profile
+ pk: 6
+ fields:
+ user: 6
+ last_ip_address: 192.168.0.1
\ No newline at end of file
diff --git a/package.json b/package.json
index bc1c02e576..7461686ffc 100644
--- a/package.json
+++ b/package.json
@@ -22,26 +22,27 @@
"homepage": "https://github.com/zestedesavoir/zds-site",
"dependencies": {
"gulp": "^3.7.0",
- "gulp-autoprefixer": "0.0.7",
- "gulp-cache": "^0.1.11",
+ "gulp-autoprefixer": "0.0.9",
+ "gulp-cache": "^0.2.1",
"gulp-clean": "^0.3.0",
"gulp-compass": "^1.1.9",
"gulp-concat": "^2.2.0",
- "gulp-filter": "^0.4.1",
+ "gulp-filter": "^1.0.0",
"gulp-flatten": "0.0.2",
- "gulp-imagemin": "^0.5.1",
+ "gulp-imagemin": "^1.0.1",
"gulp-jshint": "^1.6.2",
"gulp-livereload": "^2.0.0",
"gulp-load-plugins": "^0.5.1",
"gulp-minify-css": "^0.3.4",
"gulp-newer": "^0.3.0",
"gulp-rename": "^1.2.0",
+ "gulp-rimraf": "^0.1.0",
"gulp-sass": "^0.7.2",
- "gulp-size": "^0.3.1",
+ "gulp-size": "^1.0.0",
"gulp-uglify": "^0.3.0",
- "gulp-zip": "^0.3.4",
+ "gulp-zip": "^2.0.1",
"gulp.spritesmith": "^1.1.0",
- "jshint-stylish": "^0.2.0",
- "main-bower-files": "~1.0.0"
+ "jshint-stylish": "^0.4.0",
+ "main-bower-files": "^2.0.0"
}
}
diff --git a/quotes.txt b/quotes.txt
index 2c7e3ea9f6..b69d314c3d 100644
--- a/quotes.txt
+++ b/quotes.txt
@@ -7,6 +7,8 @@ Sortez vos cahiers de zeste.
Un concentré de connaissances, sans ajout ni conservateur, sans zeste déplacé.
Faites un zeste envers votre prochain.
Ici, vous êtes libres de vos faits et zestes.
+Alea Jacta Zeste !
+Partagez vos connaissances pour la beauté du zeste
ZdS c'est la classe, tu peux pas zeste.
Un petit zeste pour l'homme, un grand pas pour la connaissance !
J'y suis, j'y zeste !
diff --git a/requirements.txt b/requirements.txt
index 89291943fa..99841e8e71 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -30,6 +30,7 @@ pygeoip==0.3.1
pillow
https://github.com/zestedesavoir/GitPython/archive/0.3.2-RC1.z2.zip
https://github.com/zestedesavoir/Python-ZMarkdown/archive/2.4.1-zds.10.zip
-flake8
+flake8==2.2.3
autopep8
easy-thumbnails
+sphinx
diff --git a/robots.txt b/robots.txt
index d24009198d..0119839971 100644
--- a/robots.txt
+++ b/robots.txt
@@ -3,4 +3,6 @@
Sitemap: http://zestedesavoir.com/sitemap.xml
User-agent: *
-Disallow: /mp/
\ No newline at end of file
+Disallow: /mp/
+Disallow: /tutoriels/off/
+Disallow: /articles/off/
diff --git a/templates/article/member/edit.html b/templates/article/member/edit.html
index f98ed703be..50511bf3aa 100644
--- a/templates/article/member/edit.html
+++ b/templates/article/member/edit.html
@@ -54,4 +54,8 @@ Éditer l'article : {{ article.title }}
{% endif %}
{% crispy form %}
+
+ {% if form.text.value %}
+ {% include "misc/previsualization.part.html" with text=form.text.value %}
+ {% endif %}
{% endblock %}
diff --git a/templates/article/member/history.html b/templates/article/member/history.html
index cc368a5290..6857cb2e02 100644
--- a/templates/article/member/history.html
+++ b/templates/article/member/history.html
@@ -1,5 +1,4 @@
{% extends "article/base_content.html" %}
-{% load emarkdown %}
{% load profile %}
{% load date %}
{% load thumbnail %}
diff --git a/templates/article/reaction/new.html b/templates/article/reaction/new.html
index 15e2048d9a..0229d0a522 100644
--- a/templates/article/reaction/new.html
+++ b/templates/article/reaction/new.html
@@ -1,5 +1,6 @@
{% extends "article/base.html" %}
{% load crispy_forms_tags %}
+{% load captureas %}
@@ -35,4 +36,30 @@
{% if form.text.value %}
{% include "misc/previsualization.part.html" with text=form.text.value %}
{% endif %}
+
+
+ {% for message in reactions %}
+ {% captureas edit_link %}
+ {% url "zds.article.views.edit_reaction" %}?message={{ message.pk }}
+ {% endcaptureas %}
+
+ {% captureas cite_link %}
+ {% url "zds.article.views.answer" %}?article={{ topic.pk }}&cite={{ message.pk }}
+ {% endcaptureas %}
+
+ {% captureas upvote_link %}
+ {% url "zds.article.views.like_reaction" %}?message={{ message.pk }}
+ {% endcaptureas %}
+
+ {% captureas downvote_link %}
+ {% url "zds.article.views.dislike_reaction" %}?message={{ message.pk }}
+ {% endcaptureas %}
+
+ {% captureas alert_solve_link %}
+ {% url "zds.article.views.solve_alert" %}
+ {% endcaptureas %}
+
+ {% include "misc/message.part.html" with perms_change=perms.tutorial.change_article %}
+ {% endfor %}
+
{% endblock %}
\ No newline at end of file
diff --git a/templates/article/view.html b/templates/article/view.html
index b1565dbc84..436d9aa0ba 100644
--- a/templates/article/view.html
+++ b/templates/article/view.html
@@ -230,7 +230,7 @@ Gestion
Télécharger
@@ -553,8 +564,7 @@ {{ headlin
{% else %}
-
-
+
{% endif %}
@@ -567,7 +577,7 @@ {{ headlin
displayMath: [['$$','$$']],
processEscapes: true,
},
- TeX: { extensions: ["color.js", "cancel.js", "enclose.js", "bbox.js", "mathchoice.js", "newcommand.js", "verb.js", "unicode.js", "autobold.js"] },
+ TeX: { extensions: ["color.js", "cancel.js", "enclose.js", "bbox.js", "mathchoice.js", "newcommand.js", "verb.js", "unicode.js", "autobold.js", "mhchem.js"] },
messageStyle: "none",
});
diff --git a/templates/email/assoc/subscribe.html b/templates/email/assoc/subscribe.html
index e214d40e25..be2a2d2f71 100644
--- a/templates/email/assoc/subscribe.html
+++ b/templates/email/assoc/subscribe.html
@@ -7,15 +7,13 @@
- Le membre {{ username }} demande à adhérer à Zeste de Savoir.
+ Le membre {{ username }} souhaiterait adhérer à Zeste de Savoir.
- - Prénom : {{ first_name }}
- - Nom de famille : {{ surname }}
+ - Identité : {{ full_name }}
- Adresse courriel : {{ email }}
- - Adresse : {{ adresse }}, {{ adresse_complement }}
- - CP et ville : {{ code_postal }} {{ ville }}
- - Pays : {{ pays }}
+ - Date de naissance : {{ naissance }}
+ - Adresse : {{ adresse|linebreaks }}
Raison de cette demande :
diff --git a/templates/email/assoc/subscribe.txt b/templates/email/assoc/subscribe.txt
index 6feb56e9d2..b08e7f4296 100644
--- a/templates/email/assoc/subscribe.txt
+++ b/templates/email/assoc/subscribe.txt
@@ -2,16 +2,15 @@ Bonjour, membres du CA !
Le membre {{ username }} demande à adhérer à Zeste de Savoir !
-Prénom : {{ first_name }}
-Nom de famille : {{ surname }}
+Identité : {{ full_name }}
Adresse courriel : {{ email }}
-Adresse : {{ adresse }}, {{ adresse_complement }}
-CP et ville : {{ code_postal }} {{ ville }}
-Pays : {{ pays }}
+Date de naissance : {{ naissance }}
+Adresse :
+{{ adresse }}
Raison de cette demande :
{{ justification }}
-Cliquez ici pour voir son profil sur le site : {{ profile_url }}
+Lien du profil sur le site : {{ profile_url }}
Cordialement,
Clem
\ No newline at end of file
diff --git a/templates/email/register/confirm.html b/templates/email/register/confirm.html
index 957d5fab25..c14fbacb85 100644
--- a/templates/email/register/confirm.html
+++ b/templates/email/register/confirm.html
@@ -7,12 +7,18 @@
- Merci de votre inscription sur Zeste de Savoir. Pour activer votre profil, cliquez sur le lien ci-dessous :
+ Vous vous êtes inscrit sur Zeste de Savoir et nous vous en remercions.
+ En étant membre de notre communauté, vous aurez la possibilité de rédiger des tutoriels et des articles
+ que vous pourrez ensuite publier et ainsi de rendre vos connaissances accessibles au plus grand nombre.
+ Vous pourrez également échanger avec les autres membres sur nos forums !
+
+ Il ne vous reste plus qu'à activer votre profil ! Pour ce faire, visitez le lien ci-dessous :
{{ url }}
+
+
+ A très bientôt !
+
+ L'équipe Zeste de Savoir
-
- Cordialement,
-
- L'équipe Zeste de Savoir
-