su6s
Я получаю много почты и привык раскладывать письма по папкам и мейлбоксам. Зачастую, манипуляции с письмами несложно автоматизировать с помощью правил (фильтров), поддерживаемых подавляющим большинством почтовых клиентов. Часто доступ к системе фильтрации почты реализован через веб-интерфейс почтовой службы. Так, интерфейсы Яндекс и Gmail позволяют создать правила. До недавнего времени я пользовался этими возможностями, но "неудобства" накапливались. В этой заметке я опишу инструмент, оказавшийся более удобным.
Нужно:
- Независимость от настроек почтового клиента
- Централизация места описания правил
- Возможность оперировать временем поступления письма
- Поддержка флагов к письму
- Поддержка регулярных выражений при обработке полей письма
Задачу фильтрации, с выполнением всех пунктов списка выше, решает утилита imapfilter.
Честно признаюсь, мне нравится повозиться с разного рода скриптами, нравится разобраться с какой-нибудь неочевидной штуковиной. В общем и целом, я люблю простые решения. Простые в духе Slackware.
Так вот, чтобы отфильтровать почту, нам потребуется настроить imapfilter. Конфигурационный файл этой утилиты представляет собой программу на языке lua.
Lua — язык несложный, пришлось, конечно, полистать документацию, отработать примеры, поэкспериментировать.
Imapfilter же обеспечивает интерфейс доступа к вашему imap-ящику, лишая нас необходимости вникать в тонкости работы протокола IMAP, предоставляя набор методов для манипуляции почтой. Например, метод list_all() позволяет посмотреть список папок и боксов вашего аккаунта, а move_messages() используется для перемещения писем, is_seen() поможет проверить было ли прочитано письмо, is_older() дает возможность управлять письмами определенного возраста.
А как же практика? Начнем!
Открываем в редакторе файл ~/.imapfilter/config.lua, если нет такого файла, то создаем. По тексту придерживаемся правила, что все зеленое идет в конфиг, синее - заметки по lua.
timeout указывает ждать ответ сервера в течение указанного времени (секунды), namespace определяет хотим ли мы вручную адресовать наши мейлбоксы на сервере или нет. false означает, что хотим.
options.timeout = 120
options.namespace = false
Добавим логины
gmail = {username1, username2}
yandex = {username3, username4}
То есть мы определили две таблицы, — gmail и yandex с соответствующими элементами.
На основе таблиц с логинами заполним информацию об аккаунтах
gmail.username1 = IMAP {
server = 'imap.gmail.com',
username = 'username1@gmail.com',
password = 'pass1',
ssl = 'ssl3'
}
gmail.username2 = IMAP {
server = 'imap.gmail.com',
username = 'username2@gmail.com',
password = 'pass2',
ssl = 'ssl3'
}
yandex.username3 = IMAP {
server = 'imap.yandex.ru',
username = 'username3',
password = 'pass3',
ssl = 'ssl3'
}
yandex.username4 = IMAP {
server = 'imap.yandex.ru',
username = 'username4',
password = 'pass4',
ssl = 'ssl3'
}
Добавим подписки на мейл-листы
Lists = {
'@bazar2.conectiva.com.br',
'@lists.hellug.gr'
}
Добавим мейлбоксы, в которые будут раскладываться письма из мейл-листов
(Порядок мейлбоксов должен соответствовать порядку мейл-листов)
Mailboxes = {
'lua',
'imapfilter'
}
Информация о количестве новых, прочитанных и т.д. письмах получается путем указания пути до нужного бокса (INBOX), потом двоеточие (:) и метод check_status().
gmail.username1.INBOX:check_status()
gmail.username2.INBOX:check_status()
yandex.username3.INBOX:check_status()
yandex.username4.INBOX:check_status()
Сохраним в переменную result письма, в теме которых находится выражение, и письма уже просмотрены
result = yandex.username4.INBOX:contain_subject('выражение') *
yandex.username4.INBOX:is_seen()
Основной момент здесь — звездочка (*), которая играет роль логического "И"
Перемещаем письма, удовлетворяющие условию result, в мейлбокс MAILBOX
Тут стоит обратить внимание, что запись yandex.username4.MAILBOX эквивалентна
yandex.username4['MAILBOX']
yandex.username4.INBOX:move_messages(yandex.username4['MAILBOX'],result)
Работаем с мейл-листами. Рассылки будем обрабатывать пачкой. Для начала выясним количество элементов в таблице Lists
Lcount = # Lists
Теперь перебираем в цикле наши подписки, выделяем просмотренные письма
for i=1,Lcount do
result = (
gmail.username1.INBOX:contain_from("'"..Lists[i].."'") +
gmail.username1.INBOX:contain_to("'"..Lists[i].."'")
) *
gmail.username1.INBOX:is_seen()
Как видно выше, правила можно группировать скобками, знак плюс (+) играет роль логического "ИЛИ". Конструкция что-то_..еще_..что-то - конкатенация, результат — что-то_еще_что-то
Раскладываем по мейлбоксам (таблица Mailboxes). Мейлбокс будет создан, если не существует
gmail.username1.INBOX:move_messages(gmail.username1["lists/"..Mailboxes[i]], result)
end
Запустить фильтр легко — достаточно выполнить команду imapfilter.
Не забудем установить права 700 на каталог ~/.imapfilter и 600 на файлы в нем.
При первом старте imapfilter скорее всего предложит сохранить сертификаты для доступа к серверу через протокол ssl, я согласился и сохранил.
В заключение замечу, что imapfilter умеет работать в режиме демона и поддерживает пайпы.
Берегите свое время.
Блог aap-blog.blogspot.com теперь будет здесь. Записи по старому адресу удалять не планирую. Переносить старое сюда пока что тоже не собираюсь.
