Alpine + IMAP offline na macOS
Posted on Tue 04 February 2020 in Hacks (wannabe), Linux, Macbook • 4 min read
Postanowiłem przestać się męczyć środowiskiem graficznym i powrócić do źródeł. Moim pierwszym programem do poczty był Pine i o nim będzie mowa. A raczej o jego nowszym bracie: Alpine.
Instalacja i konfiguracja na macOS-ie jest prościutka. Będę ją rozbudowywał i dostosowywał w miarę używania. Na początek postanowiłem skończyć z bezpośrednim dostępem do skrzynek na serwerze. Alpine będzie czytał pocztę z lokalnych folderów, które z kolei będą synchronizowane w obie strony - między moim laptopem, a serwerem - za pomocą narzędzia: offlineimap.
Instalacja offlineimap
Zatem najpierw zainstaluję offlineimap-a za pomocą Homebrew:
brew install offlineimap
Konfiguracja kilku kont
Przykładowa konfiguracja dwóch kont (foo i bar) w .offlineimaprc:
[general] accounts = foo,bar # The pre-defined options are: # Blinkenlights -- A fancy (terminal) interface # TTYUI -- a text-based (terminal) interface # Basic -- Noninteractive interface suitable for cron'ing # Quiet -- Noninteractive interface, generates no output # except for errors. # MachineUI -- Interactive interface suitable for machine ui = quiet ##### FOO #################### [Account foo] localrepository = Local_foo remoterepository = Remote_foo # Jak często sprawdzać pocztę (minuty) autorefresh = 1 # Zrób 10 szybkich synchronizacji zanim zrobisz pełną quick = 10 [Repository Local_foo] type = Maildir localfolders = ~/POCZTA/FOO # kasuj na serwerze co skasuje lokalnie sync_deletes = yes [Repository Remote_foo] type = IMAP remotehost = mail.foo.pl remoteuser = trompka@foo.pl starttls = yes sslcacertfile = /usr/local/etc/openssl/cert.pem ##### BAR #################### [Account bar] localrepository = Local_bar remoterepository = Remote_bar autorefresh = 1 quick = 10 [Repository Local_bar] type = Maildir localfolders = ~/POCZTA/BAR sync_deletes = yes [Repository Remote_bar] type = IMAP remotehost = mail.bar.com remoteuser = trompka starttls = yes cert_fingerprint = 4375fcdalefh952z3b307f84350dupaec103ea62b32zbita ##### BAZ #################### [Account baz] localrepository = Local_baz remoterepository = Remote_baz ...
Jak widać z powyższego, poczta jest pobierana z serwera i zachowywana w podfolderach w ~/POCZTA.
Skrypty dla Launchd uruchamiające agentów offlineimapa
W folderze ~/Library/LaunchAgents/ utworzyłem plisty dla każdego konta. Przykładowo dla konta FOO plik wygląda tak:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>local.alpine.foo</string> <key>OnDemand</key> <true/> <key>ProgramArguments</key> <array> <string>~/bin/offlineimap</string> <string>-a foo</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <dict> <key>NetworkState</key> <true/> </dict> <key>StandardInPath</key> <string>/tmp/offlineimap-foo.stdin</string> <key>StandardOutPath</key> <string>/tmp/offlineimap-foo.stdout</string> <key>StandardErrorPath</key> <string>/tmp/offlineimap-foo.stderr</string> <key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>~/bin:/bin:/usr/bin:/usr/local/bin</string> </dict> </dict> </plist>
Launchd-em ładuję jeszcze dodatkowy skrypt, którego plist jest poniżej:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>local.poczta-ok</string> <key>Program</key> <string>~/bin/alpine_czy_poczta_ok.sh</string> <key>RunAtLoad</key> <true/> <key>StartInterval</key> <integer>60</integer> <key>StandardInPath</key> <string>/tmp/poczta-ok.stdin</string> <key>StandardOutPath</key> <string>/tmp/poczta-ok.stdout</string> <key>StandardErrorPath</key> <string>/tmp/poczta-ok.stderr</string> <key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>~/homebrew/bin:/bin:/usr/bin:/usr/local/bin</string> </dict> </dict> </plist>
A sam skrypt wygląda tak:
#!/bin/bash SERVERS=(foo bar) for server in ${SERVERS[*]} do FILE="/tmp/offlineimap-$server.stdout" if [ -s $FILE ] then MSG=`tail -n 1 $FILE` ANSWER="$(~/bin/alerter -message "$MSG" -closeLabel POKAŻ -title "`echo $server | tr '[:lower:]' '[:upper:]'`" -sound default -actions NAPRAW -timeout 10)" fi if [ "$ANSWER" == "POKAŻ" ] then ANSWER="$(~/bin/alerter -message "`tail -n 4 $FILE`" -closeLabel ZAMKNIJ -title "`echo $server | tr '[:lower:]' '[:upper:]'`" -sound default -actions NAPRAW -timeout 10)" fi if [ "$ANSWER" == "NAPRAW" ] then rm -f $FILE touch $FILE fi if [ "$ANSWER" == "@TIMEOUT" ] then rm -f $FILE touch $FILE fi done
Zadaniem tego skryptu jest wykrywanie błędów offlineimapa i pokazywanie ich w postaci Notification (za pomocą alertera: https://github.com/alloy/terminal-notifier) oraz umożliwienia podstawowej ich obłsugi. Polega to na ich kasowaniu i tworzeniu. ;)
Jest jeszcze jeden skrypt, którym od czasu do czasu przeładowuję offlineimapa, nie dodałem go do obsługi bo już się praktycznie przeniosłem na Macbooka pod Debiana, a tam wszystko działa bez zarzutu. Ten skrypt to taki prymityw:
#!/bin/sh LISTA=`ls -1 ~/Library/LaunchAgents/*.alpine.*.plist` for i in $LISTA; do launchctl unload $i done for i in $LISTA; do launchctl load $i done launchctl unload ~/Library/LaunchAgents/local.poczta-ok.plist launchctl load ~/Library/LaunchAgents/local.poczta-ok.plist
Instalacja Alpine
Alpine można zaisntalować z paczki, ja jednak wolałem skompilować go ze źródeł, aby wyposażyć swoją wersję w aktualne patche.
Instalacja paczki:
brew install alpine
Instalacja ze źródeł przebiega następująco:
mkdir Alpine cd Alpine wget http://alpine.x10host.com/alpine/release/src/alpine-2.22.tar.xz tar zxvf alpine-2.22.tar.xz wget http://alpine.x10host.com/alpine/patches/alpine-2.22/all.patch.gz gunzip all.patch.gz cd alpine-2.22 patch -p 1 < ../all.patch xcode-select --install # instalacja "command line tools" w macOS-ie ./configure --disable-debug --with-passfile=.pine-passfile make sudo make install
Warto odwiedzić stronę http://alpine.x10host.com/alpine/ i poczytać co zmieniają w Alpinie poszczególne łaty.
Konfiguracja Alpine
Mój plik jest bardzo długi, więc skupię się na najważnieszych ustawieniach, których Alpine szuka w ~/.pinerc.
Podstawową rzeczą jest podanie serwera wysyłającego pocztę:
smtp-server=mail.foo.pl:587/tls/user=trompka@foo.pl
Następną mega-ważną sprawą jest prawidłowe ustawienie ścieżek do plików poczty pobranych przez offlineimapa, u mnie każde konto ma własny podfolder w folderze ~/POCZTA, czyli dla trzech kont foo, bar i baz, wygląda to tak:
~ |____POCZTA |____FOO |____BAR |____BAZ
Zatem dla konta FOO (mojego domyślnego) ścieżka do Inboxa to:
inbox-path=#md/POCZTA/FOO/inbox
Pozostałe Inboksy są w tzw. kolekcji (dodałem konto BAZ, żeby łatwiej było zrozumieć):
# Lista pozostałych Inboxów, poza głównym incoming-folders=#md/POCZTA/BAR/inbox, #md/POCZTA/BAZ/inbox # Lista folderów, do których trafiają zachowane emaile, pierwszy jest folderem domyślnym (w moim pzypadku: dla konta FOO) folder-collections=FOO #md/POCZTA/FOO/[], BAR #md/POCZTA/BAR/[], BAZ #md/POCZTA/BAZ/[] # Ścieżka względna do homedira, w której leżą foldery z moją pocztą maildir-location=POCZTA
Jeszcze ustawienie wymuszające na Alpine, żeby po starcie wyświetlał indeks emaili w Inboksie i podświetlił najnowszy email:
initial-keystroke-list=I, j, ^v
Alpine można bardzo ściśle dopasować do własnych przyzwyczajeń ale wymaga to porządnego zapoznania się z opcjami dostępnymiu w programie, przy każdej z nich znajduje się obszerna Pomoc w języku angielskim. Naprawdę warto to przeczytać, serdecznie polecam tzw. Role pozwalające na kolorowanie emaili czy uruchamianie własnych poleceń np. na podstawie adresu nadawcy, itp.