Скрипт Python не будет работать на Autokey
Я пытаюсь сделать HTML-кодировщик / декодер сущностей на Python, который ведет себя подобно PHP htmlentities
а также html_entity_decode
работает нормально как отдельный скрипт:
Мой вклад:
Lorem ÁÉÍÓÚÇÃOÁáéíóúção @#$%*()[]<>+ 0123456789
python decode.py
Выход:
Lorem ÁÉÍÓÚÇÃOÁáéíóúção @#$%*()[]<>+ 0123456789
Теперь, если я запускаю его как скрипт Autokey, я получаю эту ошибку:
Script name: 'html_entity_decode'
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/autokey/service.py", line 454, in execute
exec script.code in scope
File "<string>", line 40, in <module>
File "/usr/local/lib/python2.7/dist-packages/autokey/scripting.py", line 42, in send_keys
self.mediator.send_string(keyString.decode("utf-8"))
File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 6-12: ordinal not in range(128)
Что я делаю неправильно? Вот сценарий:
import htmlentitydefs
import re
entity_re = re.compile(r'&(%s|#(\d{1,5}|[xX]([\da-fA-F]{1,4})));' % '|'.join(
htmlentitydefs.name2codepoint.keys()))
def html_entity_decode(s, encoding='utf-8'):
if not isinstance(s, basestring):
raise TypeError('argument 1: expected string, %s found' \
% s.__class__.__name__)
def entity_2_unichr(matchobj):
g1, g2, g3 = matchobj.groups()
if g3 is not None:
codepoint = int(g3, 16)
elif g2 is not None:
codepoint = int(g2)
else:
codepoint = htmlentitydefs.name2codepoint[g1]
return unichr(codepoint)
if isinstance(s, unicode):
entity_2_chr = entity_2_unichr
else:
entity_2_chr = lambda o: entity_2_unichr(o).encode(encoding,
'xmlcharrefreplace')
def silent_entity_replace(matchobj):
try:
return entity_2_chr(matchobj)
except ValueError:
return matchobj.group(0)
return entity_re.sub(silent_entity_replace, s)
text = clipboard.get_selection()
text = html_entity_decode(text)
keyboard.send_keys("%s" % text)
Я нашел это в Gist https://gist.github.com/607454, я не автор.
2 ответа
Глядя на обратную трассировку, вероятная проблема заключается в том, что вы передаете строку unicode в keyboard.send_keys, которая ожидает кодировку UTF-8 bytestring. Затем autokey пытается декодировать вашу строку, что не удается, потому что ввод unicode вместо utf-8. Это похоже на ошибку в autokey: он не должен пытаться декодировать строки, если они не являются действительно простыми (байтовыми)sstrings.
Если это предположение верно, вы сможете обойти это, убедившись, что передали экземпляр unicode в send_keys. Попробуйте что-то вроде этого:
text = clipboard.get_selection()
if isinstance(text, unicode):
text = text.encode('utf-8')
text = html_entity_decode(text)
assert isinstance(text, str)
keyboard.send_keys(text)
Утверждение не требуется, но является удобной проверкой работоспособности, чтобы убедиться, что html_entity_decode делает правильные вещи.
Проблема заключается в выводе:
clipboard.get_selection()
является строкой Unicode.
Для решения проблемы замените:
text = clipboard.get_selection()
от:
text = clipboard.get_selection().encode("utf8")