В этом разделе представлен исходный программный код вспомогательных модулей, импортируемых и используемых сценариями страниц, рассмотренными выше. В данной установке все эти модули находятся в том же каталоге, что и сценарии CGI, чтобы упростить их импортирование, — интерпретатор обнаруживает их в текущем рабочем каталоге.
Здесь вы не увидите новых снимков экранов, потому что это вспомогательные модули, а не сценарии CGI. Кроме того, изучать эти модули отдельно не слишком полезно, и они помещены здесь, в основном, чтобы обращаться к ним для справки при изучении программного кода сценариев CGI. Дополнительные сведения, которые приводились в данной главе ранее, здесь повторно не приводятся.
Внешние компоненты и настройки
Когда программа PyMailCGI запускается из своего собственного каталога в дереве примеров к книге, она полагается на ряд внешних модулей, которые теоретически могут находиться в любом месте. Поскольку все модули доступны из корневого каталога PP4E пакета примеров, они могут импортироваться как обычно, с применением точечной нотации, относительно корневого каталога. На случай, если данная структура каталогов когда-либо изменится, я заключил все внешние зависимости во вспомогательный модуль, представленный в примере 16.10, — при изменении структуры каталогов достаточно будет исправить только этот модуль.
Пример 16.10. PP4E\Internet\Web\PyMailCgi\cgi-bin\externs.py
Изолирует операции импортирования модулей, находящихся за пределами каталога PyMailCgi, благодаря чему при изменении их местоположения достаточно будет изменить только этот модуль; мы повторно используем настройки в модуле mailconfig, использовавшиеся в pymailgui2 в главе 13; вмещающий каталог PP4E/ должен находиться в списке sys.path, чтобы обеспечить возможность выполнения последней инструкции import здесь;
import sys
#sys.path.insert(0, r’C:\Users\mark\Stuff\Books\4E\PP4E\dev\Examples’) sys.path.insert(0, r’..\..\..\..’) # относительно каталога сценария
import mailconfig # локальная версия
from PP4E.Internet.Email import mailtools # пакет mailtools
Этот модуль просто импортирует все внешние имена, необходимые программе PyMailCGI, в свое собственное пространство имен. Дополнительную информацию о модулях из пакета mailtools, импортируемого и повторно используемого здесь, смотрите в главе 13 — как и в PyMailGUI, основные операции, которые выполняются за спиной PyMailCGI, реализованы в пакете mailtools.
Пример 16.11. PP4E\Internet\Email\PyMailCgi\cgi-bin\mailconfig.py
Пользовательские настройки для различных почтовых программ (версия для PyMailCGI);
Сценарии для работы с электронной почтой получают имена серверов и другие параметры из этого модуля: измените модуль так, чтобы он отражал имена ваших серверов, вашу подпись и предпочтения;
from PP4E.Internet.Email.mailconfig import * # использовать настройки # из главы 13
fetchlimit = 50 # 4E: максимальное число загружаемых заголовков/сообщений # (по умолчанию = 25)
Интерфейс к протоколу POP
Следующий вспомогательный модуль, файл loadmail, представленный в примере 16.12, зависит от внешних файлов и инкапсулирует операции доступа к почте на удаленном POP-сервере. В настоящее время он экспортирует одну функцию, loadmailhdrs, которая возвращает список заголовков (только) всех почтовых сообщений для указанной учетной записи POP. Вызывающей программе неизвестно, загружается ли эта почта из Сети, находится ли в памяти или загружается из постоянного хранилища на сервере CGI. Так сделано намеренно — изменения в loadmail не оказывают влияния на его клиентов, что оставляет возможность для расширения модуля в будущем.
Пример 16.12. PP4E\Internet\Web\PyMailCgi\cgi-bin\loadmail.py
загружает список заголовков сообщений; на будущее — добавить сохранение списка в промежутках между вызовами сценария CGI, чтобы избежать необходимости всякий раз повторно загружать весь список; если все сделать правильно, это никак не отразится на клиентах; пока, для простоты, при каждом выводе страницы перезагружается весь список;
2.0+: теперь загружаются только заголовки сообщений (с использованием команды TOP), а не все сообщения целиком, но по-прежнему при каждом обращении к странице со списком загружаются все заголовки — кэширование списка в памяти сценариев CGI невозможно, т.к. они не сохраняют информацию о состоянии, и для этого необходимо использовать настоящую базу данных (скорее всего, на стороне сервера);
from commonhtml import runsilent
from externs import mailtools
# загрузить все письма начиная с
import sys
def progress(*args): # не используется sys.stderr.write(str(args) + ‘\n’)
def loadmailhdrs(mailserver, mailuser, mailpswd): fetcher = mailtools.SilentMailFetcher(mailserver, mailuser, mailpswd) hdrs, sizes, full = fetcher.downloadAllHeaders() # получить список # заголовков return hdrs
Особо интересного здесь ничего нет — просто интерфейс и обращения к другим модулям. Класс mailtools.SilentMailFetcher (повторно используется реализация из главы 13) с помощью модуля Python poplib загружает почту через сокеты. Класс SilentMailFetcher подавляет вывод функций print в пакете mailtools, чтобы он не попадал в ответный поток HTML (хотя все исключения распространяются дальше).
Данная версия loadmail загружает только заголовки всех входящих сообщений, чтобы создать страницу со списком выбора. Однако при каждом обращении к странице со списком приходится заново загружать все заголовки. Как говорилось выше, такая реализация более эффективна, чем предыдущая версия, но она все равно оказывается слишком медленной, когда на сервере хранится достаточно много сообщений. Применение базы данных в комбинации с алгоритмом проверки списка при удалении и получении новых сообщений могло бы помочь ликвидировать это узкое место. Поскольку интерфейс, экспортируемый модулем loadmail, не должен измениться при реализации механизма кэширования, клиенты этого модуля смогут использовать его, как и прежде, без необходимости вносить в них какие-либо изменения.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011