patacrep / patanet

Web interface for LaTeX songbook generation
GNU Affero General Public License v3.0
10 stars 3 forks source link

Problème d'encoding avec la locale C #134

Closed Luthaf closed 8 years ago

Luthaf commented 9 years ago

J'ai cette stacktrace sur l'instance que je tente de déployer :

[ERROR] -- 2015-04-29 21:48:13,759 -- base : Internal Server Error: /fr/songs/la-compagnie-creole/la-machine-a-danser/
Traceback (most recent call last):
  File "/home/patanet/pyvenv/lib/python3.4/site-packages/django/core/handlers/base.py", line 111, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/patanet/pyvenv/lib/python3.4/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/patanet/pyvenv/lib/python3.4/site-packages/django/views/generic/base.py", line 87, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/patanet/pyvenv/lib/python3.4/site-packages/django/views/generic/detail.py", line 115, in get
    context = self.get_context_data(object=self.object)
  File "./generator/views/songs.py", line 70, in get_context_data
    context['content'] = _read_song(context['song'])
  File "./generator/views/songs.py", line 55, in _read_song
    return parse_song(path)
  File "./generator/songs.py", line 25, in parse_song
    return fd.read()
  File "/usr/local/lib/python3.4/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 62: ordinal not in range(128)

Je vais regarder d'où ça peut venir, et si je la reproduis en local, mais si vous avez une idée je suis preneur. Ping @paternal pour les erreurs d'encoding =)

Luthaf commented 9 years ago

Non reproductible en local, la seule différence porte sur la locale du système : C sur le serveur, fr_FR.UTF-8 chez moi. En changeant la locale du serveur, tout refonctionne.

oliverpool commented 9 years ago

Ca correspond à cela vraisemblablement : https://bugs.python.org/issue19846

Luthaf commented 9 years ago

Youpi, un bug python ... Bon, je m'en vais documenter ça, étant donné qu'il s'agit d'une erreur peut courante et facile à corriger.

oliverpool commented 9 years ago

Est-il possible de détecter la locale lors du démarrage ? (et d'afficher un message d'erreur avec correction si la locale est "C").

Luthaf commented 9 years ago

Ça peut se faire aussi en effet.

paternal commented 9 years ago

Yo! J'ai essayé de jeter un œil à ça. J'ai suivi la doc (avec python 3.4.2) pour installer et lancer l'application, mais j'obtiens l'erreur suivante :

$ ./manage.py migrate
Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/core/management/__init__.py", line 312, in execute
    django.setup()
  File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/apps/config.py", line 198, in import_models
    self.models_module = import_module(models_module_name)
  File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/importlib/__init__.py", line 109, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1129, in _exec
  File "<frozen importlib._bootstrap>", line 1471, in exec_module
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
  File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/background_task/models.py", line 8, in <module>
    from StringIO import StringIO
ImportError: No module named 'StringIO'

Que faire (puisque StringIO ne fait pas partie de python 3.4) ?

Luthaf commented 9 years ago

Il faut se baser sur la branche python3, qui n'est pas encore mergée dans master.

paternal commented 9 years ago

Je suis bien dans cette branche, à jour, avec python 3. Pas le temps d'enquêter davantage ce soir. Je regarde plus tard dans un virtualenv neuf, avec un dépôt neuf.

paternal commented 9 years ago

Vous êtes sûrs que background task est compatible python 3 ? Rien n'est précisé sur le dépôt ou pypi, et le fichier models.py contient l'import à StringIO, qui n'existe plus sous Python3.

La question maintenant, c'est : Pourquoi ça marche chez vous et pas chez moi ? La suite au prochain épisode…

oliverpool commented 9 years ago

Cf: https://github.com/patacrep/patanet/issues/100#issuecomment-59687874 (apparemment, ça n'a pas encore été mergé...)

pip install git+https://github.com/Luthaf/django-background-task.git

Luthaf commented 9 years ago

La question maintenant, c'est : Pourquoi ça marche chez vous et pas chez moi ? La suite au prochain épisode…

My bad ... J'étais persuadé d'avoir mis à jour le Requirement.txt

paternal commented 9 years ago

Merci pour les réponses. Je ré-essaye tout ça à l'occasion.

paternal commented 9 years ago

Bon, j'ai un problème : chez moi ça marche.

$ LANG=C ./manage.py runserver                                                                               
/home/louis/projets/patacrep/virtualenv/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes.
  return f(*args, **kwds)

/home/louis/projets/patacrep/virtualenv/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes.
  return f(*args, **kwds)

Performing system checks...

System check identified no issues (0 silenced).
May 03, 2015 - 19:39:31
Django version 1.8.1, using settings 'patanet.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Et a priori, tous les paquets sont à jour.

$ python --version
Python 3.4.1

$ pip freeze
Babel==1.3
Django==1.8.1
Jinja2==2.7.3
MarkupSafe==0.23
Pillow==2.8.1
Pygments==2.0.2
Sphinx==1.3.1
Unidecode==0.04.17
alabaster==0.7.3
argparse==1.2.1
astroid==1.3.6
cffi==0.9.2
chardet==2.2.1
django-background-task==0.1.8
django-simple-captcha==0.4.5
docutils==0.12
ipdb==0.8
ipython==3.1.0
jsonfield==1.0.3
lesscpy==0.10.2
logilab-common==0.63.2
patacrep==4.0.0
ply==3.4
pycparser==2.12
pygit2==0.21.0
pylint==1.4.3
pytz==2015.2
six==1.9.0
snowballstemmer==1.2.0
sphinx-rtd-theme==0.1.7

Une idée ?

Luthaf commented 9 years ago

Le serveur se lance sans problème, mais c'est en accédant à une chanson que ça plante. Donc si tu as importé des chansons, va sur la page des paroles de cette chanson.

paternal commented 9 years ago

Je ne sais pas d'ou vient le problème, mais en diagnostiquant, j'ai l'impression d'avoir trouvé par hasard un moyen de contourner le problème.

diff --git a/generator/songs.py b/generator/songs.py
index 772a496..d89573e 100644
--- a/generator/songs.py
+++ b/generator/songs.py
@@ -18,8 +18,10 @@
 Functions for song file (.sg) rendering.
 """

+import codecs
+
 def parse_song(filename):
     """Parse song 'filename', and return the corresponding HTML code."""
     # TODO
-    with open(filename) as fd:
+    with codecs.open(filename) as fd:
         return fd.read()

Dites moi ce que vous en pensez…

oliverpool commented 9 years ago

Selon http://programmers.stackexchange.com/a/168645, open(filename, encoding='utf-8') devrait aussi fonctionner.

Luthaf commented 9 years ago

L'une ou l'autre solution me convient totalement =)

paternal commented 9 years ago

Pendant le développement, je pense que c'est bien de cherche à corriger cela. En production, ça pourra être bien d'utiliser l'option errors="replace" de open(), pour que de telles erreurs, qu'elles viennent de l'utilisateur ou des développeurs, ne renvoient pas une erreur moche à l'utilisateur. Le mauvais côté, c'est qu'on ignore les erreurs, et qu'on ne va plus les corriger…

oliverpool commented 9 years ago

Je pense qu'en production il faut éviter d'afficher les erreurs, mais les reporter aux dev (dans ce cas, afficher une page "Erreur 500" et avoir des logs quelque part qui indiquent le problème). Sinon on risque des pertes de données (des caractères seront remplacés par '?' et le débogage deviendra impossible)

Luthaf commented 8 years ago

Cette issue semble résolue (au moins dans mon test avec #142). Vous confirmez ?

oliverpool commented 8 years ago

Je n'ai jamais eu ce problème, mais la lecture étant désormais effectuée par patacrep, je pense qu'on peut clore cette issue (mais j'ai quand même un problème d'encodage qui traîne)