blog-public/content/post/gnus-multi-accounts.md
Denis Zheleztsov a5dd73f274 Initial public
Some content was deleted before this project
has been moved to public
2021-10-18 19:45:57 +03:00

10 KiB
Raw Blame History

+++ date = "2018-08-21T10:30:12+03:00" draft = false title = "Читаем почту в GNU Emacs" tags = ["emacs", "linux"] comments = true +++

И так по обсуждению из вот этого вот треда(стартовый пост) у меня получилось настроить Gnus для работы с пятью почтовыми аккаунтами и отказаться от Evolution.

На самом деле связка получилась такая: fetchmail забирает письма, раз в 5 минут и запускает procmail для фильтрации сообщений, procmail сохраняет сообщения в $MAILDIR, дальше уже Gnus читает почту и показывает ее. Чтобы иметь нормальные уведомления я использую индексер почты mu, i3blocks запускает раз в 30 секунд скрипт проверки на новые письма и отправляет уведовления через libnotify, ну и иконку на панели рисует.

Вот так примерно это выглядит в ASCII-арте:

+-----------+     +------------+    +------------+    +------------+
| fetchmail |     |procmail    |    |Maildir     |    |Gnus        |
|           +-----+filters     +----+            +----+            |
+----+------+     +------------+    +-----+------+    +------+-----+
     |                                    |                  |
     |                                    |                  |
     |                                    |                  |
     |    +--------------+          +-----+------+     +-----+-----+
     |    |i3blocks      |          |mu indexer  |     |BBDB       |
     |    |libnotify     +----------+            |     |contacts   |
     |    +--------------+          +-----+------+     +-----------+
     |                                    |
     |                                    |
     |                              +-----+------+
     +------------------------------+systemd user|
                                    |and timers  |
                                    +------------+

Такие cхемки, кстати, очень удобно рисовать в artist-mode

Я настраивал все на Arch Linux, но на самом деле это все заработает в любом GNU Linux.

Ставим пакеты

Ставим пакеты:

pacman -S mu fetchmail procmail msmtp

Ставим BBDB в Emacs

M-x package-install RET bbdb RET
M-x package-install RET all-the-icons-gnus RET

BBDB нам нужен для автодополнения контактов в поле To. Да и вообще это хорошая быстрая база контактов для Emacs. А вот пакет all-the-icons-gnus рисует красивые иконки :).

Правим конфиги

fetchmail

Для начала нам необходимо настроить fetchmail, который будет забирать почту по IMAP/POP.

Редактируем ~/.fetchmailrc:

set daemon 300 # fetch mail every 5 minutes
set logfile ~/Mail/fetchmail.log # Logfile

poll imap.gmail.com with proto IMAP
    user 'YOU_USER' there with password 'YOU_PASSWORD'
    options ssl keep
    mda 'procmail -d %T'

Подобным образом определяем все свои аккаунты.

Чтобы не использовать пароли в открытом виде можно наложить патч на fetchmail.

procmail

Для фильтрации почты и расскидывания ее по каталогам будем использовать procmail - у него отличная гибкая система фильтров на регекспах.

Редактируем ~/.procmailrc:

MAILDIR=$HOME/Mail	# You'd better make sure it exists

DEFAULT=$MAILDIR/mbox/
LOGFILE=$MAILDIR/log
LOCKFILE=$HOME/.lockmail

:0 # socials
* ^From.*@.*(twitter|vk\.com|facebook|golos\.io)
social/	

:0 # JIRA
* .*Subject.*(\[JIRA\]|\[WGJIRA\]).*
jira/

:0 # Gitlab
* ^From.*gitlab@gitlab.*
Gitlab/

Свои фильтры пишем дальше аналогично -- тут все просто. Да, и убедитесь, что каталог $MAILDIR существует.

msmtp

msmtp эта штука, которая позволяет отправлять письма через нужный сервер smtp. Определяет аккаунт она по полю From.

Редактируем ~/.msmtprc:

defaults
auth on
tls on
logfile ~/.msmtp.log
tls_certcheck on
tls_trust_file /etc/ssl/cert.pem

account difrex
host smtp.googlemail.com
port 587
from my.mail@gmail.com
user USERNAME
password PASSWORD

Аналогично для остальных аккаунтов.

Systemd

Теперь необходимо написать нужные юниты и таймеры. Юнит для fetchmail будет выглядеть так:

~/.config/systemd/system/fetchmail.service

[Unit]
Description=Fetchmail
After=network-online.target

[Service]
Type=forking
ExecStart=/usr/bin/fetchmail

[Install]
WantedBy=default.target

Включаем и запускаем его:

systemctl --user enable fetchmail.service
systemctl --user start fetchmail.service

Теперь fetchmail будет стартовать после успешного логина в систему.

Настроим индексацию почты в mu:

~/.config/systemd/user/mu.timer

[Unit]
Description=mu mail indexer timer
Documentation=man:mu(1)

[Timer]
OnCalendar=*:0/5

[Install]
WantedBy=timers.target

И сервис

~/.config/systemd/system/mu.service

[Unit]
Description=mu email indexer
After=fetchmail.service

[Service]
Type=oneshot
ExecStart=/usr/bin/mu index
Environment=MAILDIR=/home/difrex/Mail # тут нужно указать свой MAILDIR

Включаем и стартуем

systemctl --user enable mu.timer
systemctl --user start my.timer

i3blocks

Настроим вывод значка с колличеством непрочтенных писем в i3bar и отправку уведомлений. Для этого напишем простой скрипт на bash.

~/.config/i3/mail.sh

#!/bin/bash

MAILDIR=/home/difrex/Mail; export MAILDIR # тут нужно указать свой MAILDIR
COUNT="$(/usr/bin/mu find date:15m..now and flag:unread 2>/dev/null | wc -l)"

# Write notify lock
write_notify_lock() {
    mkdir -p ~/.cache
    echo $COUNT > ~/.cache/.mail_notify_lock
}

# Cleanup lock
clean_notify_lock() {
    rm -f ~/.cache/.mail_notify_lock
}

if [[ $COUNT -gt 0 ]]; then
    if [[ ! -f ~/.cache/.mail_notify_lock ]] || [[ $COUNT -gt $(/usr/bin/cat ~/.cache/.mail_notify_lock) ]]; then
        write_notify_lock
        /usr/bin/notify-send 'New mail' "$(/usr/bin/mu find date:15m..now and flag:unread 2>/dev/null | tail -1)"
    fi
else
    if [[ -f ~/.cache/.mail_notify_lock ]]; then
        clean_notify_lock
    fi
fi

echo $COUNT

Не забываем сделать скрипт исполняемым

И в конфиг i3blocks.conf нужно добать секцию с нашим скриптом:

[mail]
label=
interval=30
command=~/.config/i3/mail.sh

Выглядит иконка в баре вот так: i3bar mail icon

А уведомление в dunst так: dunst notification

Gnus

Переходим к самому интересному, а именно к настройке Gnus.

Редактируем файл ~/.gnus.el.

;;; .gnus.el --- GNUs configuration
;;; Commentary:
;;; Code:

(require 'all-the-icons-gnus) ;; Наводим красоту
(all-the-icons-gnus-setup)

(setq user-mail-address "my_email@example.com") ;; Будет по-умолчанию в поле From
(setq user-full-name "Denis Zheleztsov") ;; Устанавливаем, как нас зовут

;; Показываем, что нужно смотреть в MAILDIR
(setq gnus-select-method
            '(nnmaildir "mail" (directory "~/Mail"))
	    mail-sources '((maildir :path "~/Mail" :subdirs ("cur" "new")))
	    mail-source-delete-incoming nil)

;; arbitrary name after "nnmaildir+"
(setq gnus-message-archive-group "nnmaildir+mail:outbox")
(setq message-sendmail-envelope-from 'header)
(setq mail-envelope-from 'header)
(setq message-send-mail-function 'message-send-mail-with-sendmail)

;; Устанавливаем в качестве программы для отправки писем msmtp
(setq sendmail-program "/usr/bin/msmtp")
(setq message-sendmail-envelope-from 'header)

;; Сортируем письма по дате
(setq gnus-thread-sort-functions '(gnus-thread-sort-by-most-recent-date))

;; Добавляем автодополнение по TAB для поля To
(add-hook 'message-mode-hook
          (function (lambda()
                        (local-set-key (kbd "<tab>") 'bbdb-complete-mail))))

;; Если адресса получателя нет в базе BBDB - добавляем
(add-hook 'message-setup-hook 'bbdb-mail-aliases)

;; Добавляем в базу контактов адресатов из входящей почты
(bbdb-initialize 'gnus 'message)
(bbdb-mua-auto-update-init 'gnus)
(setq bbdb-mua-auto-update-p 'create)

;; Говорим демону Gnus проверять новую почту каждые пять минут
(gnus-demon-add-handler 'gnus-demon-scan-news 5 t)
(gnus-demon-init)

;;; .gnus.el ends here

Все! Нажимаем M-x RET gnus RET и радуемся.

Так выглядит буфер с группами и непрочитанными сообщениями: gnus groups buffer

А так список сабжей в группе(синим цветом показаны прочитанные сообщения):

gnus view group

Обновлять групповой буфер можно по g, а написать новое сообщение по m. Отправить набраное сообщение через C-c C-c. Ответ на сообщение с цитатой R, без - r.