Repository: zestedesavoir/zds-site

Issue:
Nom de partie a surveiller
Via [pierre_24](http://zestedesavoir.com/forums/sujet/272/erreur-sur-les-noms-des-extraits-fichiers-qui-secrasent/)

Lorqu'on teste la rédaction des tutos et qu'on ne réfléchis, on nomme un des extraits "introduction". Ce qui a pour effet d'écraser l'introduction du tuto telle que créée au moment de la création générale (celle ou on demande le titre, l'icône et etc). Je crois comprendre que c'est "tout" simplement parce que les fichiers markdown qui traînent derrière ont le même nom. N'empêche, c'est un cas à traiter pour éviter que ça ne se passe dans la vraie vie ;)

[EDIT:] du coup, je me tape une "Internal Server Error" quand je tente d'éditer les paramètres du tuto

Nom de partie a surveiller
Via [pierre_24](http://zestedesavoir.com/forums/sujet/272/erreur-sur-les-noms-des-extraits-fichiers-qui-secrasent/)

Lorqu'on teste la rédaction des tutos et qu'on ne réfléchis, on nomme un des extraits "introduction". Ce qui a pour effet d'écraser l'introduction du tuto telle que créée au moment de la création générale (celle ou on demande le titre, l'icône et etc). Je crois comprendre que c'est "tout" simplement parce que les fichiers markdown qui traînent derrière ont le même nom. N'empêche, c'est un cas à traiter pour éviter que ça ne se passe dans la vraie vie ;)

[EDIT:] du coup, je me tape une "Internal Server Error" quand je tente d'éditer les paramètres du tuto



Discussion:
assignez-la moi, je vous propose une PR demain soir au plus tard. Si vous désirez une solution plus tôt, alors tant pis ^^.

On ne fonctionne pas avec les assignements, mais simplement avec le fait que tu te propose, on considère que tu vas le faire :)

Si quelqu'un l'a fait avant toi et que c'est de qualité on prendra cette solution a priori.

Ok, alors je propose dès que j'ai sauf si vous avez avant, compris ^^.

Du coup j'ai mis le label "en cours", comme ca tout le monde voit que quelqu'un est dessus et je te met la pression na ! :D

assignez-la moi, je vous propose une PR demain soir au plus tard. Si vous désirez une solution plus tôt, alors tant pis ^^.

On ne fonctionne pas avec les assignements, mais simplement avec le fait que tu te propose, on considère que tu vas le faire :)

Si quelqu'un l'a fait avant toi et que c'est de qualité on prendra cette solution a priori.

Ok, alors je propose dès que j'ai sauf si vous avez avant, compris ^^.

Du coup j'ai mis le label "en cours", comme ca tout le monde voit que quelqu'un est dessus et je te met la pression na ! :D


Resolving patch:
diff --git a/zds/tutorial/models.py b/zds/tutorial/models.py
--- a/zds/tutorial/models.py
+++ b/zds/tutorial/models.py
@@ -794,7 +794,7 @@ def get_path(self, relative=False):
                         self.chapter.part.slug),
                     self.chapter.slug)
 
-        return os.path.join(chapter_path, slugify(self.title) + '.md')
+        return os.path.join(chapter_path, self.slugify_title()) + '.md'
 
     def get_prod_path(self):
         if self.chapter.tutorial:
@@ -816,7 +816,8 @@ def get_prod_path(self):
                     self.chapter.part.slug),
                 self.chapter.slug)
 
-        return os.path.join(chapter_path, slugify(self.title) + '.md.html')
+        return os.path.join(chapter_path, self.slugify_title()
+             + '.md.html')
 
     def get_text(self):
         if self.chapter.tutorial:
@@ -857,6 +858,11 @@ def get_text_online(self):
         else:
             return None
 
+    def slugify_title(self):
+        toEscape = ["introduction","conclusion"]
+        if slugify(self.title) in toEscape :
+            return "p-"+self.title
+        return slugify(self.title)
 
 class Validation(models.Model):
 
diff --git a/zds/tutorial/views.py b/zds/tutorial/views.py
--- a/zds/tutorial/views.py
+++ b/zds/tutorial/views.py
@@ -1832,10 +1832,9 @@ def edit_extract(request):
                                                 extract.chapter.slug)
 
                 # Use path retrieve before and use it to create the new slug.
-
-                new_slug = os.path.join(chapter_part, slugify(data["title"])
-                                        + ".md")
                 extract.save()
+                new_slug = extract.get_path()
+                
                 maj_repo_extract(
                     request,
                     old_slug_path=old_slug,
@@ -1893,7 +1892,7 @@ def modify_extract(request):
 
         # Use path retrieve before and use it to create the new slug.
 
-        old_slug = os.path.join(chapter_path, slugify(extract.title) + ".md")
+        old_slug = extract.get_path()
         maj_repo_extract(request, old_slug_path=old_slug, extract=extract,
                          action="del")
         extract.delete()


Test patch:
diff --git a/zds/tutorial/tests.py b/zds/tutorial/tests.py
--- a/zds/tutorial/tests.py
+++ b/zds/tutorial/tests.py
@@ -14,7 +14,7 @@
 from zds.settings import SITE_ROOT
 from zds.tutorial.factories import BigTutorialFactory, MiniTutorialFactory, PartFactory, \
     ChapterFactory, NoteFactory
-from zds.tutorial.models import Note, Tutorial, Validation
+from zds.tutorial.models import Note, Tutorial, Validation, Extract
 from zds.utils.models import Alert
 
 
@@ -782,6 +782,54 @@ def setUp(self):
 
         mail.outbox = []
 
+    def add_test_extract_named_introduction(self):
+        """test the use of an extract named introduction"""
+        
+        self.client.login(username=self.user_author,
+            password='hostel77')
+        
+        result = self.client.post(
+            reverse( 'zds.tutorial.views.add_extract') +
+            '?chapitre={0}'.format(
+                self.chapter.pk),
+            
+            {
+            'title' : "Introduction",
+            'text' : u"Le contenu de l'extrait"
+            })
+        self.assertEqual(result.status_code, 302)
+        tuto = Tutorial.objects.get(pk=self.minituto.pk)
+        self.assertEqual(Extract.objects.all().count(),1)
+        intro_path = os.path.join(tuto.get_path(),"introduction.md")
+        extract_path =  Extract.objects.get(pk=1).get_path()
+        self.assertNotEqual(intro_path,extract_path)
+        self.assertTrue(os.path.isfile(intro_path))
+        self.assertTrue(os.path.isfile(extract_path))
+
+    def add_test_extract_named_conclusion(self):
+        """test the use of an extract named introduction"""
+        
+        self.client.login(username=self.user_author,
+            password='hostel77')
+        
+        result = self.client.post(
+            reverse( 'zds.tutorial.views.add_extract') +
+            '?chapitre={0}'.format(
+                self.chapter.pk),
+            
+            {
+            'title' : "Conclusion",
+            'text' : u"Le contenu de l'extrait"
+            })
+        self.assertEqual(result.status_code, 302)
+        tuto = Tutorial.objects.get(pk=self.minituto.pk)
+        self.assertEqual(Extract.objects.all().count(),1)
+        ccl_path = os.path.join(tuto.get_path(),"conclusion.md")
+        extract_path =  Extract.objects.get(pk=1).get_path()
+        self.assertNotEqual(ccl_path,extract_path)
+        self.assertTrue(os.path.isfile(ccl_path))
+        self.assertTrue(os.path.isfile(extract_path))
+        
     def test_add_note(self):
         """To test add note for tutorial."""
         user1 = ProfileFactory().user