as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!
¿Cómo solucionarlo?
En algunas otras aplicaciones de blogs estáticos basados en python, los posts chinos pueden ser publicados con éxito. Como esta aplicación: http://github.com/vrypan/bucket3. En mi sitio http://bc3.brite.biz/, los mensajes en chino pueden ser publicados con éxito.
Finalmente lo conseguí:
as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
**Déjame comprobarlo.
as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec 6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.getdefaultencoding()
'utf8'
>>>
Lo anterior muestra que la codificación por defecto de python es utf8
. Entonces el error no es más.
Este es el clásico "problema de unicode". Creo que explicar esto está más allá del alcance de una respuesta de StackOverflow para explicar completamente lo que está sucediendo.
Está bien explicado aquí.
En muy breve resumen, has pasado algo que está siendo interpretado como una cadena de bytes a algo que necesita decodificarlo en caracteres Unicode, pero el códec por defecto (ascii) está fallando.
La presentación a la que te apunté proporciona consejos para evitar esto. Haz que tu código sea un "sándwich de unicode". En Python 2, el uso de from __future__ import unicode_literals
ayuda.
Actualización: cómo se puede arreglar el código:
OK - en tu variable "source" tienes algunos bytes. No está claro en tu pregunta cómo llegaron allí - ¿quizás los leíste de un formulario web? En cualquier caso, no están codificados con ascii, pero python está intentando convertirlos a unicode asumiendo que lo están. Necesitas decirle explícitamente cuál es la codificación. Esto significa que tiene que saber cuál es la codificación. Esto no siempre es fácil, y depende totalmente de la procedencia de la cadena. Puedes experimentar con algunas codificaciones comunes - por ejemplo UTF-8. Le dices a unicode() la codificación como segundo parámetro:
source = unicode(source, 'utf-8')
En algunos casos, cuando comprueba su codificación por defecto (print sys.getdefaultencoding()
), devuelve que está usando ASCII. Si cambias a UTF-8, no funciona, dependiendo del contenido de tu variable.
He encontrado otra forma:
import sys
reload(sys)
sys.setdefaultencoding('Cp1252')