Самое существенно обновление в PyMailGUI 3.0 я оставил напоследок: теперь эта программа поддерживает кодировки Юникода для получаемых, сохраняемых и отправляемых писем, насколько это позволяет пакет email в Python 3.1. И текстовые части сообщений, и их заголовки теперь декодируются при отображении и кодируются при отправке. Однако это слишком большое изменение, чтобы описывать его в данном формате, поэтому более подробное описание приводится в следующем разделе.
Политика поддержки Юникода в версии 3.0
Последний пункт в предыдущем списке является, пожалуй, самым важным. Как уже рассказывалось в главе 13, пользовательские настройки в модуле mailconfig, определяющие порядок декодирования байтов полного текста почтового сообщения в строку Юникода при получении и порядок кодирования/декодирования при сохранении сообщений в файлы, действуют на протяжении всего сеанса работы с программой.
Более определенно, при составлении: имеется возможность явно указать в модуле mailconfig или запросить у пользователя кодировку, которая будет применяться к основному тексту и к текстовым вложениям составляемого сообщения; при просмотре: для определения кодировки основного текста, а также текстовых частей, открываемых по требованию, используется информация из заголовков. Кроме того, декодирование интернационализированных заголовков (например, «Subject», «To» и «From») при их отображении выполняется в соответствии со стандартами электронной почты, MIME и Юникода и в зависимости от их содержимого, и они автоматически кодируются при отправке, если содержат текст с символами, не входящими в диапазон ASCII.
Здесь также наследуются и другие особенности поддержки Юникода (и исправления) из пакета mailtools, представленного в главе 13, — подробнее об этом рассказывается в предыдущей главе. Ниже суммируется, как все эти особенности отражаются на пользовательском интерфейсе: Полу чен ные пись ма
При по лу че нии электронных писем для декодирования байтов полного сообщения в строку Юникода, как того требует механизм анализа, реализованный в пакете email, используются пользовательские настройки, действующие на протяжении всего сеанса работы с программой. Если эта операция не увенчалась успехом, выполняется попытка угадать, применив по очереди некоторые из наиболее распространенных кодировок. Большинство почтовых сообщений наверняка будут иметь 7- или 8-битовую природу, поскольку оригинальные стандарты электронной почты требуют, чтобы текст сообщений состоял только из символов ASCII.
Текстовые части при составлении письма
При от прав ке новых писем для определения кодировки основной текстовой части и всех текстовых вложений используются настройки пользователя. Если они отсутствуют в модуле mailconfig, графический интерфейс предложит пользователю указать кодировку для каждой текстовой части. Они также будут использоваться для добавления заголовков с информацией о кодировках и определять формат MIME. Во всех случаях программа будет использовать кодировку UTF-8, если кодировка, указанная в mailconfig или введенная пользователем, окажется неприменимой к отправляемому тексту — например, если пользователь укажет кодировку ASCII для основного текста ответа или пересылаемого письма, содержащего символы за пределами набора ASCII или текстовые вложения с такими символами.
Заголовки составляемого письма
При от прав ке новых писем, если заголовки или компоненты имен в заголовках с адресами содержат символы за пределами набора ASCII, программа пытается закодировать заголовки в соответствии со стандартами интернационализации. Для этого по умолчанию используется кодировка UTF-8, но имеется возможность указать другую кодировку в модуле mailconfig. В адресах, если компонент имени не может быть закодирован, он отбрасывается, и используется только компонент адреса. При этом предполагается, что серверы будут корректно обрабатывать закодированные имена в адресах.
Отображение текстовых частей
При про смотре полученных сообщений везде, где возможно, для декодирования текста используются имена кодировок, указанные в заголовках. Основная текстовая часть декодируется в строку str Юникода согласно информации в заголовке перед вставкой ее в компонент PyEdit. Содержимое всех остальных текстовых частей, а также всех двоичных частей сохраняется в виде строк bytes в двоичные файлы, откуда они могут быть извлечены по требованию позднее в графическом интерфейсе. При открытии по требованию таких текстовых частей они отображаются в отдельных окнах PyEdit, при этом компоненту PyEdit передается имя двоичного файла, где хранится содержимое извлекаемой части, а также имя кодировки, полученное из заголовка этой части.
Если имя кодировки отсутствует в заголовке текстовой части или декодирование с применением этой кодировки не увенчалось успехом, предпринимается попытка применить кодировку основной текстовой части. К частям сообщения, открываемым по требованию, применяется также политика поддержки Юникода, реализованная в редакторе PyEdit (как описывается в главе 11 — он может запросить кодировку у пользователя, если она неизвестна). Кроме того, текстовые части в формате HTML сохраняются в двоичном режиме и открываются в веб-броузере в надежде, что проблема декодирования будет решена механизмом поддержки кодировок в броузере, который может использовать пользовательские настройки или информацию в тегах HTML для определения кодировки.
Отображение заголовков
При про смотре сообщений заголовки автоматически декодируются в соответствии со стандартами электронной почты. Под этим подразумевается декодирование полных заголовков, таких как «Subject», и компонентов имен в заголовках с адресами, таких как «From», «To» и «Cc», при этом допускается, что компоненты имен будут полностью закодированными или содержать подстроки в разных кодировках. Поскольку содержимое заголовков определяет формат MIME и кодировку Юникода, для декодирования заголовков не требуется получать какую-либо информацию от пользователя.
Иными словами, программа PyMailGUI теперь поддерживает отображение и составление ин тер на цио на ли зиро ван ных сообщений, включая интернационализированное содержимое или заголовки. Для большей пользы эта поддержка распределена по множеству пакетов и примеров. Например, декодирование полного текста сообщения в Юникод при получении фактически производится глубоко в классах, импортируемых из пакета mailtools. Благодаря этому полный (не разобранный) текст сообщения всегда будет представлен в программе в виде строки str Юникода. Точно так же декодирование заголовков для отображения выполняется с помощью инструментов, реализованных в пакете mailtools, при этом операция кодирования заголовков инициируется и выполняется непосредственно внутри пакета mailtools во время отправки.
Реализация декодирования полного текста сообщения иллюстрирует способы выбора кодировки. Основная кодировка определяется переменной fetchEncoding в модуле mailconfig. Этот пользовательский параметр используется программой PyMailGUI для декодирования байтов получаемых сообщений в строку str, необходимую механизму анализа, и для сохранения и загрузки полного текста сообщения в файл на протяжении всего сеанса работы. Пользователи могут присвоить этой переменной строку с именем своей кодировки Юникода. Вполне разумным выбором для большинства электронных писем могут оказаться кодировки «latin-1», «utf-8» и «ascii», так как стандарты электронной почты изначально требуют, чтобы почтовые сообщения состояли из символов ASCII (хотя для декодирования некоторых старых файлов, сгенерированных предыдущей версией, требуется использовать кодировку «latin-1»). Если операция декодирования с этим именем кодировки терпит неудачу, выполняется попытка применить другие распространенные кодировки, и в самом крайнем случае отображается содержимое заголовков, если оно может быть декодировано, а тело сообщения заменяется сообщением об ошибке. Чтобы просмотреть такие письма, попробуйте запустить PyMailGUI снова, с другими настройками кодировки.
Из недостатков: в программе не делается ничего, что касается поддержки Юникода для полного текста отправляемого сообщения, сверх того, что предлагается библиотеками Python (как мы узнали в главе 13, модуль smtplib пытается использовать кодировку ASCII при отправке сообщения, что является одной из причин необходимости кодирования заголовков). И, несмотря на то, что обеспечивается полная поддержка наборов символов для содержимого почтовых сообщений, в самом графическом интерфейсе по-прежнему используются надписи на кнопках и в метках на английском языке.
Как описывалось в главе 13, данные решения, касающиеся поддержки Юникода, несмотря на всю их широту, являются неполными, так как пакет email в Python 3.1, на корректную работу которого полагается программа PyMailGUI, еще находится на пути к реализации окончательного правильного решения для некоторых случаев. Обновленная версия пакета, которая будет более точно и полно соответствовать разделению типов str/bytes в Python 3.X, наверняка появится в будущем — следите за страницей с обновлениями для книги (описывается в предисловии), где будет приводиться информация об улучшениях и изменениях, касающаяся поддержки Юникода в программе. Хотелось бы надеяться, что новая версия пакета email, лежащего в основе PyMailGUI 3.0, будет доступна в ближайшее время.
В программном обеспечении всегда есть место для улучшений (смотрите список в конце этой главы), тем не менее, программа PyMailGUI обеспечивает вполне полнофункциональный интерфейс к электронной почте, представляет собой самый существенный пример в этой книге и является демонстрацией практического применения языка Python и принципов разработки программного обеспечения в целом. Как часто отмечают пользователи, может доставлять удовольствие сама работа с языком Python, но кроме того, он также полезен при создании практических и нетривиальных программ. Данный пример более, чем какой-то другой из приводимых в книге, свидетельствует об этом. А как именно, демонстрируется в следующем разделе.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011