Repository: zestedesavoir/zds-site

Issue:
Impossible de retrouver mon tutoriel après tentative d'ajout d'un auteur
J'ai essayé d'ajouter un auteur à [mon tutoriel](https://zestedesavoir.com/tutoriels/391/comment-reussir-votre-entretien-dembauche/), et en validant sur le bouton, je me suis pris une 404 et maintenant je n'ai plus accès à la version brouillon de mon tutoriel (je me prend une 404 sur la version brouillon).

ça semble lié à la problématique que j'ai eu pour les déplacement avec la V16.



Discussion:
Malheureusement, c'est même bloquant puisque tu ne peux plus accéder à ton contenu pour y contribuer.

J'attend que Sentry nous dise quelque chose, mais j'ai peu d'espoir, si c'était une 404 :/

Malheureusement, un problème qui me semble similaire chez moi : en voulant valider les modifications que j'ai apportées sur un article, je me suis pris une 404. Depuis, je me prends également une 404 lorsque j'essaye d'y accéder.

Un bug similaire sur le forum : https://zestedesavoir.com/forums/sujet/5440/404-sur-un-tuto-en-redaction/

Bon on passe à un stade ARCHI-BLOQUANT là. Je suis dessus, n'hésitez pas à passer sur IRC ou à commenter ici si vous avez une idée.

Liste de ce qui peut créer un erreur 404 :    
- pk invalide  
- pas de `versioned` associé  
- slug invalide  

cf `zds.tutorialv2.mixins.SingleContentViewMixin`.

**Remarque importante** : tous les contenus avec des 404 contiennent une « ' » dans leur titre. Hasard ? Je creuse.

OK je confirme.

Avant v16 : linterface-dadministration-avec-django

Après v16 : l-interface-d-administration-avec-django

putin c'est toujours ce putin de bug.
Je ne sais pas d'où il vient mais il a fait mal avec les déplacement. Maintenant il fait mal avec les auteurs.

Oh nooooooooooooooooon, pas (encore) ce bug ! Comment, c'est encore possible ? On a mis à jour `uuslug` ?

@pierre-24 Malheureusement oui. Par contre, @gustavi a émit une piste intéressante à travers cette [méthode](https://github.com/zestedesavoir/zds-site/blob/dev/zds/tutorialv2/utils.py#L628-L652) qui utilise `uuslug` ou `django` pour générer un slug (et ce, pour des soucis de compatibilité je suppose).

L'avis d'un connaisseur sur ce module serait une bonne indication.

D'après une analyse de @artragis, il semblerait bien aussi que la cause est une "désynchronisation" des slugs entre le repo (niveau système de fichier) et le slug enregistré en base de données. @gustavi propose cette [commande](http://paste.awesom.eu/3CKH) pour tout remettre d'équerre mais elle est à tester.

> et ce, pour des soucis de compatibilité je suppose

Toutafé: tout un moment, le slug de Django et le slug généré par `uuslug` n'étaient pas exactement les même au niveau des apostrophes, justement. Alors évidement, si le responsable d'`uuslug` a décidé de changer ça en cours de route, eh bien c'est chiant ;)

Pour ce qui est de la commande de gustavi, à priori oui, sauf que j'aurais plutôt vu une solution à base de `os.move()`, puisque dès qu'on va redemander un slug, l’erreur va nous retomber dessus. De plus, on ne sais pas encore si ce bug se traduit aussi sur les conteneur/extraits.

C'est la m*** :p 

Il n'y a eu aucune mise à jour de `uuslug`. Par contre, il est possible que dans un cas précis, vous utilisez le générateur de slug de django alors que vous devriez utiliser `uuslug`.

Il m'a l'air bizarre ce uuslug: https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/models/models_database.py#L26 .

Pas un expert dans le domaine mais quelqu'un peut regarder rapidement ? pas de pc, semaine de partiel !

Pourquoi bizarre?

2016-02-22 17:02 GMT+01:00 Hugo Courtecuisse notifications@github.com:

> Il m'a l'air bizarre ce uuslug:
> https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/models/models_database.py#L26
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/zestedesavoir/zds-site/issues/3383#issuecomment-187245196
> .

Car on utilise slugify (from uuslug import uuslug vs from uuslug import slugify) , d'habitude:
- https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/models/models_versioned.py#L15
- https://github.com/zestedesavoir/zds-site/blob/dev/zds/tutorialv2/views/views_contents.py#L44
- https://github.com/zestedesavoir/zds-site/blob/dd8e28affc05f023dd1dda4d1a5f230c82a61d46/zds/tutorialv2/utils.py#L15

Bah voilà on l'a trouvé le bug \o/ merci l'ami !

2016-02-22 17:35 GMT+01:00 Hugo Courtecuisse notifications@github.com:

> Car on utilise slugify, d'habitude:
> 
>    -
>    https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/models/models_versioned.py#L15
>    -
>    https://github.com/zestedesavoir/zds-site/blob/dev/zds/tutorialv2/views/views_contents.py#L44
>    -
>    https://github.com/zestedesavoir/zds-site/blob/dd8e28affc05f023dd1dda4d1a5f230c82a61d46/zds/tutorialv2/utils.py
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/zestedesavoir/zds-site/issues/3383#issuecomment-187256118
> .

@DevHugo Je suis content que tu restes quand même dans les parages. :-°

Je veux pas casser votre joie, mais vous êtes sûr, sur celle là ? (magnifique usage de l'accent circonflexe, ici, #réformeOrthographe)

Parce que sur ce fichier, `uuslug` est utilisé [là](https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/models/models_database.py#L140), comme il me semble qu'il doit l'être (uuslug appelant `slugify`, mais se permettant d'abord un _check_ en base de donnée pour vérifier qu'il est unique). Non ?

Après, y'a ce [`if kwargs.pop(...)`](https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/models/models_database.py#L139) dont je me souviens pas, donc peut être qu'il y a à creuser par là.

Le kwargs.pop vient du bugfix durant la béta.

Le 22 février 2016 à 17:57, Pierre Beaujean notifications@github.com a
écrit :

> Je veux pas casser votre joie, mais vous êtes sur, sur celle là ?
> 
> Parce que sur ce fichier, uuslug est utilisé là
> https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/models/models_database.py#L140,
> comme il me semble qu'il doit l'être (uuslug appelant slugify, mais se
> permettant d'abord un _check_ en base de donnée pour vérifier qu'il est
> unique). Non ?
> 
> Après, y'a ce if kwargs.pop()
> https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/models/models_database.py#L139
> dont je me souviens pas, donc peut être qu'il y a à creuser par là.
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/zestedesavoir/zds-site/issues/3383#issuecomment-187265627
> .

Je suis pas sur d'avoir bien compris ton point de vue @pierre-24 si je te l’interprète mal toutes mes excuses. 

Si on regarde cette ligne [là](https://github.com/zestedesavoir/zds-site/blob/dev/zds/tutorialv2/views/views_contents.py#L1646), on voit que quand on bouge une partie, on ne passe pas dans le if qui cause des soucis (celui que tu vient de citer) et du coup ça marche ce qui à fait passer la QA.

Mais dans les autres cas, [ajout d'un auteur](https://github.com/zestedesavoir/zds-site/blob/42875047d7f94e330033474f93186b739c1bc121/zds/tutorialv2/views/views_contents.py#L1705) et [validation](https://github.com/zestedesavoir/zds-site/blob/dev/zds/tutorialv2/views/views_validations.py#L400), on met pas le slug le `force_slug_update` à False et du coup, on passe dans le if et du coup souci.

Après j'ai rien testé donc euh j'affirme rien ^^, je donne juste mon avis théorique sur une question :p. 
(La bonne différence entre pratique et théorie <3)


Resolving patch:
diff --git a/zds/tutorialv2/management/commands/adjust_slugs.py b/zds/tutorialv2/management/commands/adjust_slugs.py
new file mode 100644
--- /dev/null
+++ b/zds/tutorialv2/management/commands/adjust_slugs.py
@@ -0,0 +1,53 @@
+# coding: utf-8
+import os
+from uuslug import slugify
+
+from django.core.management.base import BaseCommand
+from zds.settings import ZDS_APP
+from zds.tutorialv2.models.models_database import PublishableContent
+
+
+class Command(BaseCommand):
+    """
+    `python manage.py adjust_slugs`; fix content's slugs for which the title contains single quote(s).
+    """
+
+    def handle(self, *args, **options):
+
+        for c in PublishableContent.objects.all():
+            if '\'' in c.title:
+                good_slug = slugify(c.title)
+                if c.slug != good_slug:
+                    if os.path.isdir(os.path.join(ZDS_APP['content']['repo_private_path'], good_slug)):
+                        # this content was created before v16 and is probably broken
+                        self.stdout.write(u'Fixing pre-v16 content #{} (« {} ») ... '.format(c.pk, c.title), ending='')
+                        c.save()
+                        if os.path.isdir(c.get_repo_path()):
+                            self.stdout.write(u'[OK]')
+                        else:
+                            self.stdout.write(u'[KO]')
+                    elif os.path.isdir(os.path.join(ZDS_APP['content']['repo_private_path'], c.slug)):
+                        # this content was created during v16 and will be broken if nothing is done
+                        self.stdout.write(u'Fixing in-v16 content #{} (« {} ») ... '.format(c.pk, c.title), ending='')
+                        try:
+                            versioned = c.load_version()
+                        except IOError:
+                            self.stdout.write(u'[KO]')
+                        else:
+                            c.sha_draft = versioned.repo_update_top_container(
+                                c.title,
+                                good_slug,
+                                versioned.get_introduction(),
+                                versioned.get_conclusion(),
+                                commit_message='[hotfix] Corrige le slug')
+
+                            c.save()
+
+                            if os.path.isdir(c.get_repo_path()):
+                                self.stdout.write(u'[OK]')
+                            else:
+                                self.stdout.write(u'[KO]')
+                    else:
+                        self.stderr.write(
+                            u'Content #{} (« {} ») is an orphan: there is no directory named "{}" or "{}".\n'.
+                            format(c.pk, c.title, good_slug, c.slug))


Test patch: