From fa035655d8bd4c983573e05e9bac8cd23393057e Mon Sep 17 00:00:00 2001 From: pierre-24 Date: Mon, 22 Feb 2016 23:03:49 +0100 Subject: [PATCH 1/3] Freeze the version of `python-slugify` to 1.1.4 (fix #3383) (and provide a command to fix broken contents) --- doc/source/back-end/contents.rst | 10 ++++++ requirements.txt | 1 + update.md | 8 +++++ .../management/commands/adjust_slugs.py | 31 +++++++++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 zds/tutorialv2/management/commands/adjust_slugs.py diff --git a/doc/source/back-end/contents.rst b/doc/source/back-end/contents.rst index 86f43d633d..0ba35739a0 100644 --- a/doc/source/back-end/contents.rst +++ b/doc/source/back-end/contents.rst @@ -177,6 +177,16 @@ une contrainte sur la taille maximum d'un nom de fichier sur les différents sys *slug*, pour des raisons de stockage (voir plus bas). Il ne faut pas oublier la contrainte d'unicité à l'intérieur d'un conteneur. +.. attention:: + + Suite à un changement majeur dans la librairie ``python-slugify``, une différence peu apparaitre dans le *slug* + généré à partir de titres contenant des espaces. Dès lors, pour des raisons de rétro-compatibilités, c'est la version + 1.1.4 de cette librairie qui est utilisée par ZdS. Par ailleurs, la commande ``python manage.py adjust_slugs`` a été + créée pour réparer les éventuels dommages, en détectant les titres posant potentielement des problèmes et en tentant + de les faire correspondre à nouveau à leur contrepartie dans le système de fichier. + + `Plus d'information ici `_. + Cycle de vie des contenus ========================= diff --git a/requirements.txt b/requirements.txt index 2b19845689..e81213f749 100644 --- a/requirements.txt +++ b/requirements.txt @@ -34,4 +34,5 @@ dry-rest-permissions==0.1.6 # Zep 12 dependency django-uuslug==1.0.3 +python-slugify==1.1.4 # next versions of this library break previous behavior for slug generation from string with single quotes watchdog==0.8.3 # use last non-bc-breaking version diff --git a/update.md b/update.md index c661da29ee..2727b3a95b 100644 --- a/update.md +++ b/update.md @@ -432,3 +432,11 @@ systemctl start zds-watchdog.service Il est possible de configurer le logging de ce module en surchargeant les logger `logging.getLogger("zds.pandoc-publicator")`, `logging.getLogger("zds.watchdog-publicator")`. +Repasser à l'ancienne version de `python-slugify` et sauver les contenus (#3383) +-------------------------------------------------------------------------------- + +1. Passer en maintenance ; +2. Mettre à jour les dépendances de zds afin de *downgrader* `python-slugify` : `pip install --upgrade -r requirements.txt` ; +3. Exécuter la commande suivante : `python manage.py adjust_slugs`. Noter les éventuels contenus pour lesquels cela ne fonctionnerai pas ; +4. Si pour certains contenus la commande échoue, il faut retrouver le dossier correspondant dans `/contents-private/` et donner à ce contenu le même slug ; +5. Quitter la maintenance. \ No newline at end of file diff --git a/zds/tutorialv2/management/commands/adjust_slugs.py b/zds/tutorialv2/management/commands/adjust_slugs.py new file mode 100644 index 0000000000..b3ac5a7b71 --- /dev/null +++ b/zds/tutorialv2/management/commands/adjust_slugs.py @@ -0,0 +1,31 @@ +# 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)): + self.stdout.write(u'Fixing 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]') + else: + self.stderr.write( + u'Content #{} (« {} ») cannot be fixed: there is no directory named "{}" in "{}".\n'. + format(c.pk, c.title, good_slug, ZDS_APP['content']['repo_private_path'])) From 0857df08f998f08e086d14c230753942bf450d4e Mon Sep 17 00:00:00 2001 From: pierre-24 Date: Tue, 23 Feb 2016 11:58:00 +0100 Subject: [PATCH 2/3] Also deal with contents that would have been created DURING v16. --- .../management/commands/adjust_slugs.py | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/zds/tutorialv2/management/commands/adjust_slugs.py b/zds/tutorialv2/management/commands/adjust_slugs.py index b3ac5a7b71..a52838fa04 100644 --- a/zds/tutorialv2/management/commands/adjust_slugs.py +++ b/zds/tutorialv2/management/commands/adjust_slugs.py @@ -5,6 +5,7 @@ from django.core.management.base import BaseCommand from zds.settings import ZDS_APP from zds.tutorialv2.models.models_database import PublishableContent +from django.utils.translation import ugettext_lazy as _ class Command(BaseCommand): @@ -19,13 +20,35 @@ def handle(self, *args, **options): 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)): - self.stdout.write(u'Fixing content #{} (« {} ») ... '.format(c.pk, c.title), ending='') + # 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=_(u'[hotfix] Corrige le slug pour éviter un bug')) + + 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 #{} (« {} ») cannot be fixed: there is no directory named "{}" in "{}".\n'. - format(c.pk, c.title, good_slug, ZDS_APP['content']['repo_private_path'])) + u'Content #{} (« {} ») is an orphan: there is no directory named "{}" or "{}".\n'. + format(c.pk, c.title, good_slug, c.slug)) From c7e586eba0abbc5d1c54fb3acc679021d2ea9e11 Mon Sep 17 00:00:00 2001 From: hcourte Date: Tue, 23 Feb 2016 18:09:22 +0100 Subject: [PATCH 3/3] Correct commit name --- zds/tutorialv2/management/commands/adjust_slugs.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zds/tutorialv2/management/commands/adjust_slugs.py b/zds/tutorialv2/management/commands/adjust_slugs.py index a52838fa04..71ce79b676 100644 --- a/zds/tutorialv2/management/commands/adjust_slugs.py +++ b/zds/tutorialv2/management/commands/adjust_slugs.py @@ -5,7 +5,6 @@ from django.core.management.base import BaseCommand from zds.settings import ZDS_APP from zds.tutorialv2.models.models_database import PublishableContent -from django.utils.translation import ugettext_lazy as _ class Command(BaseCommand): @@ -40,7 +39,7 @@ def handle(self, *args, **options): good_slug, versioned.get_introduction(), versioned.get_conclusion(), - commit_message=_(u'[hotfix] Corrige le slug pour éviter un bug')) + commit_message='[hotfix] Corrige le slug') c.save()