From 03279ea318805b3fa7545f01385485e8053daea5 Mon Sep 17 00:00:00 2001 From: Luke Smith Date: Thu, 21 Feb 2019 10:14:17 -0500 Subject: [PATCH] rewrite underway --- .gitignore | 10 +- README.md | 189 ++++++------------- autoconf/makedefault.sh | 10 - autoconf/msmtprc_header | 6 - autoconf/msmtprc_profile | 7 - autoconf/mutt_profile | 21 --- autoconf/offlineimap_header | 6 - autoconf/offlineimap_header.macos | 6 - autoconf/offlineimap_profile | 19 -- autoconf/offlineimap_profile.macos | 19 -- autoconf/services.csv | 9 - {etc => bin}/email.gif | Bin {credentials => bin}/getmuttpass | 2 +- {credentials => bin}/imappwd.py | 2 +- {etc => bin}/mailcap | 6 +- etc/mailsync.sh => bin/mailsync | 8 +- etc/muttimage.sh => bin/muttimage | 0 {etc => bin}/notify.opus | Bin etc/openfile.sh => bin/openfile | 5 - autoconf/domains.csv => domains.csv | 16 +- etc/mw.png | Bin 24980 -> 0 bytes mutt-wizard.sh | 276 ---------------------------- muttrc | 6 +- mw | 262 ++++++++++++++++++++++++++ 24 files changed, 338 insertions(+), 547 deletions(-) delete mode 100755 autoconf/makedefault.sh delete mode 100644 autoconf/msmtprc_header delete mode 100644 autoconf/msmtprc_profile delete mode 100644 autoconf/mutt_profile delete mode 100644 autoconf/offlineimap_header delete mode 100644 autoconf/offlineimap_header.macos delete mode 100644 autoconf/offlineimap_profile delete mode 100644 autoconf/offlineimap_profile.macos delete mode 100644 autoconf/services.csv rename {etc => bin}/email.gif (100%) rename {credentials => bin}/getmuttpass (59%) rename {credentials => bin}/imappwd.py (83%) rename {etc => bin}/mailcap (53%) rename etc/mailsync.sh => bin/mailsync (81%) rename etc/muttimage.sh => bin/muttimage (100%) rename {etc => bin}/notify.opus (100%) rename etc/openfile.sh => bin/openfile (98%) rename autoconf/domains.csv => domains.csv (95%) delete mode 100644 etc/mw.png delete mode 100755 mutt-wizard.sh create mode 100755 mw diff --git a/.gitignore b/.gitignore index b2cfbb2..8573c25 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,6 @@ +personal.muttrc *.swp *.gpg -accounts/ *.pyc -personal.muttrc -thunderbird/ -autoconf/log -etc/mailsynclastrun -etc/.mailsynclastrun -.dl +accounts/ +*mailsynclastrun diff --git a/README.md b/README.md index 03a2d1d..01cc62b 100644 --- a/README.md +++ b/README.md @@ -1,138 +1,59 @@ -# Luke's mutt Wizard for automatic Neomutt and OfflineIMAP configuration! - -![mutt wizard preview](etc/mw.png) - -Mutt is one of the most rewarding programs one can use, but can be a pain in -the ass to configure. Since my job is making power-user tools available for the -masses I want to create a tool that automates most of mutt configuration so -that users can simply give their email address and get a /comfy/ setup. At -that, I don't just want a mutt wizard, but an offlineIMAP wizard, so users can -easily access their mail offline as well, and a wizard that makes it easy to -store passwords securely using gpg. - -The mutt-wizard is all of this in a simple ncurses menu. It's really just a -little bash script, but one that can save countless people thousands of -combined manhours of frustratingly trying to get all the moving pieces working -together. - -## User interface - -The system takes an email and autodetect its server settings, generating a -muttrc and offlineimaprc profile automatically. If it can't do so, it simply -prompts you for these (which you can easily look up) and will put them all in -the right places. You get: - -+ Automatic configuration of mutt and offlineimap. -+ Automatic encryption and safe storage of passwords which are used by mutt and - offlineimap when necessary. -+ Multiple account management in mutt: jump from account to account with the - `i` prefix in mutt: `i1`: first email account, `i5`: fifth, etc. -+ Easy movement to mail folders in mutt: `gi`: go to inbox, `gs` to sent mail, - `ga` to archive, `gS` to spam, `gd` to drafts, etc. -+ Some default controls and colors. This system is going to be integrated into - my [public auto-rice script](https://larbs.xyz) so I want it to look pretty - and be usable out the box. -+ An optional autosync script that will smartly run offlineimap when connected - to the internet at what interval you want and will notify you with a ding - when new mail arrives. - -### Will it work on my email? (95% yes) - -Yes! At this point, the only problems are the unexpected ones. Please try it, -and if you do run into problems, email me at -[luke@lukesmith.xyz](mailto:luke@lukesmith.xyz)! I've tried the system -personally on Gmail, Teknik.io, cock.li and Yandex, while others have tried -other providers. - -If you have a ProtonMail account, due to their secure setup, you must have -[ProtonMail Bridge](https://protonmail.com/bridge/) installed and configured. -Compatibility with ProtonMail is still in testing, so be sure to open an issue -if you have problems as I do not have a paid account to test this with. - -Note also that Gmail and some providers require you to enable sign-ins from -third-party (or as they call it "less secure") applications to be able to load -mail with mutt and offlineimap. Be sure to enable that! - -## Installation and Dependencies - -`dialog`, `neomutt`, `offlineimap` and `msmtp` should be installed. You also need to -have a GPG public/private key pair for the wizard to automatically store your -passwords. The whole repo should be cloned to `~/.config/mutt/`. (If you have a -previous mutt folder, you'll want to back it up or delete it first.) - -``` -git clone https://github.com/LukeSmithxyz/mutt-wizard.git ~/.config/mutt -``` - -You will want to delete or rename your current `~/.offlineimaprc` and -`~/.msmtprc` as well, as although you can later modify these files produced by -the script, you must have no file there the first time you add your first -account or the wizard will assume some settings are already set which aren't. - -Just run `mutt-wizard.sh` and choose to add an account. After you do so, you -may run `offlineimap` to begin the mailsync, and you will be able to run -neomutt and see your mail. If mutt doesn't immediately work properly run the -`Redetect mailboxes` option, then open mutt. This may be necessary for some -accounts. - - -### Installation on macOS - -You may need to install or symlink additional packages on macOS. Otherwise the generation of configuration files may fail, or worse. - -``` -ln -s /usr/local/bin/gpg /usr/local/bin/gpg2 -brew install coreutils -ln -s /usr/local/bin/gshred /usr/local/bin/shred -``` - -### Non-essential dependencies for extra features - -The automatically deployed configs will look for certain programs for certain -extra abilities. Consider installing the following for the extra functionality. - -+ `notmuch` -- for mail searching and indexing set to `ctrl-f`. Be sure to run - `notmuch setup`. Remember your mail is in `~/.mail/` when you configure - notmuch. -+ `w3m` and/or `w3mimg` -- for HTML emails and viewing images. Like .pdfs, view in the attachments menu. -+ A cron manager if you want the autosync feature. -+ `iproute2mac` for Mac users who want the autosync feature. -+ `mpv` if you want the autosync feature to notify you with a ding on new mail. - -## The autosync - -If you activate the autosync at a significantly infrequent interval, by -default, your system might prompt you for your GPG password every time. To -prevent this, you can change the time a GPG unlock lasts by adding a time in -seconds as below into `~/.gnupg/gpg-agent.conf`: - -``` -default-cache-ttl -max-cache-ttl -``` - -You can also use [pam-gnupg](https://github.com/cruegge/pam-gnupg) if you want -to just log into your keyring immediately on log in. This is what I do, but -it's less secure if you leave you computer logged on. +# mutt-wizard -## You can help! - -If you use mutt with a particular host or domain, put your server information -in `domains.csv`! This will make everyone else who uses your email provider's -life much easier! - -Or you can help monetarily via [Patreon](https://patreon.com/lukesmith) or -[Paypal](https://paypal.me/LukeMSmith)! - -## Notes +The mutt-wizard is a simple `dialog`-based interface gives you: -Mail is stored in `~/.mail`. mutt configs and caches for each account are in -`~/.config/mutt/accounts/`. Encypted passwords are in -`~/.config/mutt/credentials`. A "personal" muttrc, with the macros for -switching accounts and the default config is in -`~/.config/mutt/personal.muttrc`. +- a fully-functioning neomutt-based terminal email workflow with vim bindings, vibrant display. +- email backed up offline with offlineIMAP, allowing mobile and offline access of all your mail. +- automatically generated shortcuts for jumping between different accounts or mailboxes within an account. +- sensible binds that make managing, moving and reading mail quicker and easier than ever. +- your passwords safely encrypted on your machine so you (and only you) can access your account easily (uses GPG). -## Todo +I maintain mutt-wizard for GNU/Linux, but individual contributors have also made it compatible with Mac. -* Expand the list of server information in `domains.csv`, possibly porting the - Thunderbird autoconfigure settings. +## Use mutt-wizard + +Clone the repo to `~/.config/mutt`. Either move to backup or delete your old `~/.config/mutt` directory if you have one. Remove/backup your old offlineimap and msmtp configs if you have them as well. + +Be sure to install the following programs: + +- `neomutt` - the email client. +- `offlineimap` - downloads the email. +- `msmtp` - sends your email. +- `dialog` - is the mutt-wizard interface. + +**You must have a GPG public/private key pair as well.** This is what will safely encrypt your passwords. + +### Optional dependencies + +mutt-wizard is configured by default for you to use other useful tools, but these are not strictly necessary. + +- `w3m` - You'll probably want this one at least. It will help you read HTML email from those terrible people who send it... if you want to. It will also enable viewing images in mutt. +- `notmuch` - can index your mail to be easily searched. Install it and run `notmuch setup`, tell it that your mail is in `~/.local/share/mail/`. You can run it in mutt with `ctrl-f`. Remember to run `notmuch new` to process new mail, although the included `mailsync` script does this for you. +- `abook` - a terminal-based address book. Pressing tab while typing an address to send mail to will suggest contacts that are in your abook. +- A cron manager - if you want to enable the auto-sync feature. + +## New stuff and improvements since the original release + +- More autogenerated shortcuts that allow quickly moving and copying mail between boxes. +- More elegant attachment handling. Image/video/pdf attachments without relying on the neomutt instance. +- abook integration by default. +- The messy template files have been removed and are now a part of the script itself. +- Optimal XDG standards compliance, moving offlineimap and msmtp configs to `~/.config/` and moving mail to `~/.local/share/mail/`. +- `accounts/` hold account data and `bin/` holds script run by for for mutt. All other directories have been disintegrated. +- Better handling of different gpg versions. +- Narrow POSIX compliance because why not? + +## Known issues (not my fault!) + +- If you're using a Gmail account, check the pinned issue on the Github. Gmail accounts haven't been working properly with offlineimap recently, but there's an easy fix. Remember also to enable third-party ("""less secure""") applications. +- Check the ProtonMail issue as well. ProtonMail recently allows IMAP usage with their Bridge program for paid users. I don't have this, so I can't bugtest on it, but many users have gotten it working. Either way, it requires a little more work than just using the wizard. +- Don't expect mutt-wizard to work out the box on a university email. Universities often have special IMAP policies and server settings. You might be lucky, but you might have to changes some settings in the offlineimap config file to get it to work properly with a university email. +- If you use an email server whose mailboxes are not in English, mutt-wizard might not be able to guess which is which, so you may have to manually set your Inbox, Sent, Trash, Drafts, etc. in your mutt config file. + +## Help! + +- Try mutt-wizard out on weird machines and weird email addresses and report any errors. +- Open a PR to add new server information into `domains.csv` so their users can more easily use mutt-wizard. +- If nothing else, [Donate!](https://paypal.me/LukeMSmith) + +See Luke's website [here](https://lukesmith.xyz). Email him at [luke@lukesmith.xyz](mailto:luke@lukesmith.xyz). diff --git a/autoconf/makedefault.sh b/autoconf/makedefault.sh deleted file mode 100755 index e8b1536..0000000 --- a/autoconf/makedefault.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# Give this script the abstract name of an account and it will make it the default. - -title=$1 -muttdir="$HOME/.config/mutt/" -muttdirsed=$(echo $muttdir | sed -e 's/\//\\\//g') - -grep "$muttdir"personal.muttrc -e "^source .*accounts.*" >/dev/null && \ - sed -i "s/^source .*accounts.*/source ${muttdirsed}accounts\/$title.muttrc/g" "$muttdir"personal.muttrc diff --git a/autoconf/msmtprc_header b/autoconf/msmtprc_header deleted file mode 100644 index 8040e03..0000000 --- a/autoconf/msmtprc_header +++ /dev/null @@ -1,6 +0,0 @@ -defaults -auth on -tls on -tls_trust_file /etc/ssl/certs/ca-certificates.crt -logfile ~/.msmtp.log - diff --git a/autoconf/msmtprc_profile b/autoconf/msmtprc_profile deleted file mode 100644 index 0ec99d0..0000000 --- a/autoconf/msmtprc_profile +++ /dev/null @@ -1,7 +0,0 @@ - -account $title -host $smtp -port $sport -from $login -user $login -passwordeval "gpg -d --quiet --for-your-eyes-only --no-tty ~/.config/mutt/credentials/$title.gpg | sed -e '$a\'" diff --git a/autoconf/mutt_profile b/autoconf/mutt_profile deleted file mode 100644 index a96c93a..0000000 --- a/autoconf/mutt_profile +++ /dev/null @@ -1,21 +0,0 @@ -# vim: filetype=neomuttrc -# muttrc file for account $title -set realname = "$realname" -set from = "$fulladdr" -set sendmail = "/usr/bin/msmtp -a $title" -set folder = "~/.mail/$title" -set header_cache = ~/.config/mutt/accounts/$title/cache/headers -set message_cachedir = ~/.config/mutt/accounts/$title/cache/bodies -set certificate_file = ~/.config/mutt/accounts/$title/certificates -source "~/.config/mutt/credentials/getmuttpass $title |" - -alias me $realname <$fulladdr> - -set mbox_type = Maildir -set ssl_starttls = yes -set ssl_force_tls = yes - -bind index,pager gg noop -bind index,pager g noop -bind index gg first-entry -unmailboxes * diff --git a/autoconf/offlineimap_header b/autoconf/offlineimap_header deleted file mode 100644 index 786f04b..0000000 --- a/autoconf/offlineimap_header +++ /dev/null @@ -1,6 +0,0 @@ -[general] -accounts = -starttls = yes -ssl = yes -pythonfile = ~/.config/mutt/credentials/imappwd.py - diff --git a/autoconf/offlineimap_header.macos b/autoconf/offlineimap_header.macos deleted file mode 100644 index 86d5678..0000000 --- a/autoconf/offlineimap_header.macos +++ /dev/null @@ -1,6 +0,0 @@ -[general] -accounts = -starttls = yes -ssl = true -pythonfile = ~/.config/mutt/credentials/imappwd.py - diff --git a/autoconf/offlineimap_profile b/autoconf/offlineimap_profile deleted file mode 100644 index 48d466d..0000000 --- a/autoconf/offlineimap_profile +++ /dev/null @@ -1,19 +0,0 @@ - - -[Account $title] -localrepository = $title-local -remoterepository = $title-remote - -[Repository $title-remote] -auth_mechanisms = LOGIN -type = $type -remoteuser = $login -remotepasseval = mailpasswd("$title") -remotehost = $imap -remoteport = $iport -folderfilter = lambda foldername: foldername not in ['[Gmail]/All Mail'] -sslcacertfile = /etc/ssl/certs/ca-certificates.crt - -[Repository $title-local] -type = Maildir -localfolders = ~/.mail/$title diff --git a/autoconf/offlineimap_profile.macos b/autoconf/offlineimap_profile.macos deleted file mode 100644 index e985538..0000000 --- a/autoconf/offlineimap_profile.macos +++ /dev/null @@ -1,19 +0,0 @@ -[Account $title] - -localrepository = $title-local -remoterepository = $title-remote - -[Repository $title-remote] -auth_mechanisms = LOGIN -type = $type -remoteuser = $login -sslcacertfile = /usr/local/etc/openssl/cert.pem -remotepasseval = mailpasswd("$title") -remotehost = $imap -remoteport = $iport -folderfilter = lambda foldername: foldername not in ['[Gmail]/All Mail'] -sslcacertfile = /usr/local/etc/openssl/cert.pem - -[Repository $title-local] -type = Maildir -localfolders = ~/.mail/$title diff --git a/autoconf/services.csv b/autoconf/services.csv deleted file mode 100644 index 152be38..0000000 --- a/autoconf/services.csv +++ /dev/null @@ -1,9 +0,0 @@ -SERVICE,IMAP,imap port,SMTP,smtp port,spoolfile,postponed,record -"Zoho",imap.zoho.com,993,smtp.zoho.com,465,,, -"iCloud",imap.mail.me.com,993,smtp.mail.me.com,587,,, -"Inbox.com",imap.inbox.com,993,smtp.inbox.com,465,,, -"Office 365",outlook.office365.com,993,smtp.office365.com,587,INBOX,Drafts,Sent Items -"Host Gator",gator4171.hostgator.com,993,gator4171.hostgator.com,587,INBOX,INBOX.Drafts,INBOX.Sent -"GoDaddy",imap.secureserver.net,993,smtpout.secureserver.net,465,,, -"Yandex",imap.yandex.com,993.00,smtp.yandex.com,465.00,,, -"Muny Mail",mail.muny.us,993,mail.muny.us,465,,, diff --git a/etc/email.gif b/bin/email.gif similarity index 100% rename from etc/email.gif rename to bin/email.gif diff --git a/credentials/getmuttpass b/bin/getmuttpass similarity index 59% rename from credentials/getmuttpass rename to bin/getmuttpass index 1359114..15a1d55 100755 --- a/credentials/getmuttpass +++ b/bin/getmuttpass @@ -1,5 +1,5 @@ #!/bin/bash GPG="gpg"; command -v gpg >/dev/null || GPG="gpg2" -pass=$(printf '%q' "$("$GPG" --decrypt --quiet ~/.config/mutt/credentials/$1.gpg)") +pass=$(printf '%q' "$("$GPG" --decrypt --quiet ~/.local/share/muttwizard/$1.gpg)") echo "set smtp_pass=\"$pass\"" echo "set imap_pass=\"$pass\"" diff --git a/credentials/imappwd.py b/bin/imappwd.py similarity index 83% rename from credentials/imappwd.py rename to bin/imappwd.py index 03611dd..9b25fcc 100755 --- a/credentials/imappwd.py +++ b/bin/imappwd.py @@ -3,7 +3,7 @@ import subprocess home = os.path.expanduser("~") def mailpasswd(acct): acct = os.path.basename(acct) - path = "%s/.config/mutt/credentials/%s.gpg" % (home,acct) + path = "%s/.local/share/muttwizard/%s.gpg" % (home,acct) args = ["gpg2", "--use-agent", "--quiet", "--batch", "-d", path] try: return subprocess.check_output(args).strip().decode('UTF-8') diff --git a/etc/mailcap b/bin/mailcap similarity index 53% rename from etc/mailcap rename to bin/mailcap index 503a75a..6dcca4d 100644 --- a/etc/mailcap +++ b/bin/mailcap @@ -1,7 +1,7 @@ text/plain; vim %s ; -text/html; ~/.config/mutt/etc/openfile.sh %s ; +text/html; ~/.config/mutt/bin/openfile %s ; text/html; w3m -I %{charset} -T text/html; copiousoutput; -image/*; ~/.config/mutt/etc/muttimage.sh %s ; copiousoutput +image/*; ~/.config/mutt/bin/muttimage %s ; copiousoutput video/*; setsid mpv --quiet %s &; copiousoutput -application/pdf; ~/.config/mutt/etc/openfile.sh %s ; +application/pdf; ~/.config/mutt/bin/openfile %s ; application/pgp-encrypted; gpg -d '%s'; copiousoutput; diff --git a/etc/mailsync.sh b/bin/mailsync similarity index 81% rename from etc/mailsync.sh rename to bin/mailsync index 6068464..629f044 100755 --- a/etc/mailsync.sh +++ b/bin/mailsync @@ -16,7 +16,7 @@ if [ "$(uname)" = "Darwin" ] then notify() { osascript -e "display notification \"$2 in $1\" with title \"You've got Mail\" subtitle \"Account: $account\"" && sleep 2 ;} else - notify() { mpv --really-quiet ~/.config/mutt/etc/notify.opus & pgrep -x dunst && notify-send -i ~/.config/mutt/etc/email.gif "$2 new mail(s) in \`$1\` account." ;} + notify() { mpv --really-quiet ~/.config/mutt/bin/notify.opus & pgrep -x dunst && notify-send -i ~/.config/mutt/bin/email.gif "$2 new mail(s) in \`$1\` account." ;} fi echo " 🔃" > /tmp/imapsyncicon @@ -28,10 +28,10 @@ rm -f /tmp/imapsyncicon pkill -RTMIN+12 i3blocks # Check all accounts/mailboxes for new mail. Notify if there is new content. -for account in $(ls ~/.mail) +for account in $(ls ~/.local/share/mail) do #List unread messages newer than last mailsync and count them - newcount=$(find ~/.mail/"$account"/INBOX/new/ -type f -newer ~/.config/mutt/etc/.mailsynclastrun 2> /dev/null | wc -l) + newcount=$(find ~/.mail/"$account"/INBOX/new/ -type f -newer ~/.config/mutt/bin/.mailsynclastrun 2> /dev/null | wc -l) if [ "$newcount" -gt "0" ] then notify "$account" "$newcount" & @@ -40,4 +40,4 @@ done notmuch new #Create a touch file that indicates the time of the last run of mailsync -touch ~/.config/mutt/etc/.mailsynclastrun +touch ~/.config/mutt/bin/.mailsynclastrun diff --git a/etc/muttimage.sh b/bin/muttimage similarity index 100% rename from etc/muttimage.sh rename to bin/muttimage diff --git a/etc/notify.opus b/bin/notify.opus similarity index 100% rename from etc/notify.opus rename to bin/notify.opus diff --git a/etc/openfile.sh b/bin/openfile similarity index 98% rename from etc/openfile.sh rename to bin/openfile index c866932..fdc0e5f 100755 --- a/etc/openfile.sh +++ b/bin/openfile @@ -1,14 +1,9 @@ #!/bin/sh - # Helps open a file with xdg-open from mutt in a external program without weird side effects. base=$(basename "$1") ext="${base##*.}" - file=$(mktemp -u --suffix=".$ext") - rm -f "$file" - cp "$1" "$file" - setsid xdg-open "$file" >/dev/null 2>&1 & diff --git a/autoconf/domains.csv b/domains.csv similarity index 95% rename from autoconf/domains.csv rename to domains.csv index 18b8872..bd17b06 100644 --- a/autoconf/domains.csv +++ b/domains.csv @@ -108,7 +108,7 @@ mortemale.org,mail.autistici.org,993,smtp.autistici.org,465 msn.com,imap-mail.outlook.com,993,smtp-mail.outlook.com,587 muny.us,mail.muny.us,993,mail.muny.us,465 myself.com,imap.mail.com,995,smtp.mail.com,587 -narod.ru,imap.yandex.com,993,smtp.yandex.com,465 +narod.ru,imap.yandex.com,993,smtp.yandex.com,587 national.shitposting.agency,mail.cock.li,993,mail.cock.li,587 nigge.rs,mail.cock.li,993,mail.cock.li,587 nuke.africa,mail.cock.li,993,mail.cock.li,587 @@ -142,14 +142,14 @@ wants.dicksinhisan.us,mail.cock.li,993,mail.cock.li,587 wants.dicksinmyan.us,mail.cock.li,993,mail.cock.li,587 web.de,imap.web.de,993,smtp.web.de,587 writeme.com,imap.mail.com,995,smtp.mail.com,587 -ya.ru,imap.yandex.com,993,smtp.yandex.com,465 +ya.ru,imap.yandex.com,993,smtp.yandex.com,587 yahoo.com,imap.mail.yahoo.com,993,smtp.mail.yahoo.com,587 -yandex.by,imap.yandex.com,993,smtp.yandex.com,465 -yandex.com,imap.yandex.com,993,smtp.yandex.com,465 -yandex.kz,imap.yandex.com,993,smtp.yandex.com,465 -yandex.net,imap.yandex.com,993,smtp.yandex.com,465 -yandex.ru,imap.yandex.com,993,smtp.yandex.com,465 -yandex.ua,imap.yandex.com,993,smtp.yandex.com,465 +yandex.by,imap.yandex.com,993,smtp.yandex.com,587 +yandex.com,imap.yandex.com,993,smtp.yandex.com,587 +yandex.kz,imap.yandex.com,993,smtp.yandex.com,587 +yandex.net,imap.yandex.com,993,smtp.yandex.com,587 +yandex.ru,imap.yandex.com,993,smtp.yandex.com,587 +yandex.ua,imap.yandex.com,993,smtp.yandex.com,587 zoho.com,imap.zoho.com,993,smtp.zoho.com,465 duke.edu,outlook.office365.com,993,smtp.office365.com,587 diff --git a/etc/mw.png b/etc/mw.png deleted file mode 100644 index dd15ce8dc4abd7dc5419b7dcac522161422f60bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24980 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 diff --git a/mutt-wizard.sh b/mutt-wizard.sh deleted file mode 100755 index 4b8a075..0000000 --- a/mutt-wizard.sh +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env bash - -[ "$(uname)" == "Darwin" ] && os=".macos" - -muttdir="$HOME/.config/mutt" -namere="^[a-z_][a-z0-9_-]*$" -emailre=".+@.+\..+" - -createMailboxes() { \ - tmpdir=$(mktemp -d) - offlineimap --info -a "$1" 2&> "$tmpdir"/log - sed -n '/^Folderlist/,/^Folderlist/p' "$tmpdir"/log | - grep "^ " | sed -e "s/\//./g;s/(.*//g;s/^ //g" > "$tmpdir"/lognew - while read box; do mkdir -p "$HOME/.mail/$1/$box"; done <"$tmpdir"/lognew ;} - -testSync() { (crontab -l | grep mailsync.sh && removeSync) || addSync ;} - -addSync() { min=$(dialog --inputbox "How many minutes should be between mail syncs?" 8 60 3>&1 1>&2 2>&3 3>&-) - (crontab -l; echo "*/$min * * * * eval \"export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME -x i3)/environ)\"; "$muttdir"/etc/mailsync.sh") | crontab - && - dialog --msgbox "Cronjob successfully added. Remember you may need to restart or tell systemd/etc. to start your cron manager for this to take effect." 7 60 ;} - -removeSync() { ((crontab -l | sed -e '/mailsync.sh/d') | crontab - >/dev/null) && dialog --msgbox "Cronjob successfully removed. To reactivate, select this option again." 6 60 ;} - -changePassword() { \ - gpgemail=$( dialog --title "Luke's mutt/offlineIMAP password wizard" --inputbox "Insert the email address with which you originally created your GPG key pair. This is NOT necessarily the email you want to configure." 10 60 3>&1 1>&2 2>&3 3>&- ) - while ! [[ "${gpgemail}" =~ ${emailre} ]]; do - gpgemail=$(dialog --no-cancel --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "That's not a valid email address. Please input the entire address." 10 60 3>&1 1>&2 2>&3 3>&1) - done - dialog --title "Luke's mutt/offlineIMAP password wizard" --passwordbox "Enter the new password for the \"$1\" account." 10 60 2> /tmp/$1 - gpg2 -r "$gpgemail" --encrypt /tmp/$1 || (dialog --title "GPG decryption failed." --msgbox "GPG decryption failed. This is either because you do not have a GPG key pair or because your distro uses GPG1 and you thus need to symlink /usr/bin/gpg2 to /usr/bin/gpg." 7 60 && break) - shred -u /tmp/$1 - mv /tmp/$1.gpg "$muttdir"/credentials/ - dialog --title "Finalizing your account." --infobox "The account \"$title\"'s password has been changed. Now attempting to configure mail directories... - - This may take several seconds..." 10 70 - createMailboxes "$title" || (clear && exit) - detectMailboxes "$title" - dialog --title "Password changed." --msgbox "Your \"$fulladdr\" password has been changed. To start the download of your mail, you can manually run \`offlineimap -a $title\` in a terminal. The first sync may take some time depending on the amount of your mail." 8 60 ;} - -chooseDetect() { for x in $(grep "^accounts =" ~/.offlineimaprc | sed -e 's/accounts =\( \)//g;s/\(,\) /\n/g;'); do detectMailboxes $x; done && detectSuccess ;} - -detectWarning() { \ - dialog --title "Mailbox detect requirement" --yesno "In order for the mailbox detection system to work, you must have - -1) already have added the email account with this wizard, and -2) already have run offlineimap at least once to synchronize your mail. - -This detection system only works if you already have begun your first sync. If you have, press 'yes' to continue." 12 70 ;} - -detectSuccess() { dialog --title "Mailbox detect complete." --msgbox "The script has now smartly detected your different mailboxes and has enabled them in the sidebar and given you keyboard shortcuts as below: - -gi for move to the Inbox. -gs for move to Sent Mail. -gd for move to Drafts -gS for move to Spam -ga for move to the Archive. -gj for move to Junk -gt for move to Trash - -These shortcuts will only work if your email system does have that particular folder (i.e. if your email system has a Junk folder, but not a Trash folder, 'gt' will not work, etc." 20 60 ;} - -formatShortcut() { \ - while read data; do - echo "macro index,pager g$1 \"$data\" \"Go to $2.\"" >> "$muttdir"/accounts/$3.muttrc - done ;} - -gen_delim() { \ - delim="=" - for i in `seq $(( $1 - 1 ))` - do - delim="$delim-" - done - echo $delim ;} - -detectMailboxes() { \ - find ~/.mail/$1 -maxdepth 1 -mindepth 1 -type d | sed -e "s/.*\///g;s/^/=/g" > /tmp/$1_boxes - sidebar_width=$(sed -n -e '/^set sidebar_width/p' "$muttdir"/muttrc | awk -F'=' '{print $2}') - delim=$(gen_delim $sidebar_width) - oneline=$(sed -e "s/^\|$/\"/g" /tmp/$1_boxes | tr "\n" " ") - oneline="=$1 $delim $oneline" - sed -i "/^mailboxes\|^set record\|^set postponed\|^set trash\|^set spoolfile/d" "$muttdir"/accounts/$1.muttrc - echo mailboxes $oneline >> "$muttdir"/accounts/$1.muttrc - sed -i "/^macro index,pager g/d" "$muttdir"/accounts/$1.muttrc - grep -i /tmp/$1_boxes -e inbox | sed 1q | formatShortcut i inbox $1 - grep -i /tmp/$1_boxes -e sent | sed 1q | formatShortcut s sent $1 - grep -i /tmp/$1_boxes -e draft | sed 1q | formatShortcut d drafts $1 - grep -i /tmp/$1_boxes -e trash | sed 1q | formatShortcut t trash $1 - grep -i /tmp/$1_boxes -e spam | sed 1q | formatShortcut S spam $1 - grep -i /tmp/$1_boxes -e junk | sed 1q | formatShortcut j junk $1 - grep -i /tmp/$1_boxes -e archive | sed 1q | formatShortcut a archive $1 - spoolfile=$(grep -i /tmp/$1_boxes -e inbox | sed -e 's/=/+/g' | sed 1q) - record=$(grep -i /tmp/$1_boxes -e sent | sed -e 's/=/+/g' | sed 1q) - postponed=$(grep -i /tmp/$1_boxes -e draft | sed -e 's/=/+/g' | sed 1q) - trash=$(grep -i /tmp/$1_boxes -e trash | sed -e 's/=/+/g' | sed 1q) - echo "set spoolfile = \"$spoolfile\"" >> "$muttdir"/accounts/$1.muttrc - echo "set record = \"$record\"" >> "$muttdir"/accounts/$1.muttrc - echo "set postponed = \"$postponed\"" >> "$muttdir"/accounts/$1.muttrc - echo "set trash = \"$trash\"" >> "$muttdir"/accounts/$1.muttrc ;} - -# Get all accounts in ~/.offlineimaprc and load into variable `accounts`. -getAccounts() { \ - grep "^accounts =" ~/.offlineimaprc | sed -e 's/accounts =\( \)//g;s/\(,\) /\n/g;' | nl --number-format=ln > /tmp/numbered - accounts=() - while read n s ; do - accounts+=($n "$s" off) - done < /tmp/numbered ;} - -# Yields a menu of available accounts. -inventory() { \ - getAccounts - choices=$(dialog --separate-output --checklist "Select all desired email accounts with ." 15 40 16 "${accounts[@]}" 2>&1 >/dev/tty) - - if [ -z "$choices" ]; - then - clear - else - userchoices=$(IFS="|"; keys="${choices[*]}"; keys="${keys//|/\\|}"; grep -w "${keys}" /tmp/numbered | awk '{print $2}') - fi ;} - - -removeAccount() { sed -ie " - /Account $1]/,/Account/{//!d} - /Account $1]/d - s/ $1\(,\|$\)//g - s/=$1\(,\|$\)/=/g - s/,$//g - " ~/.offlineimaprc - rm "$muttdir"/accounts/$1.muttrc - rm "$muttdir"/credentials/$1.gpg - rm -rf "$muttdir"/accounts/$1 - sed -i "/$1.muttrc/d" "$muttdir"/personal.muttrc - # Delete from the line matching the account name, until the next account or empty line - sed -i "/account $1/,/^\(\s*$\|account\)/d" ~/.msmtprc ;} - -manual() { \ - imap=$( dialog --inputbox "Insert the IMAP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- ) - iport=$(dialog --inputbox "What is your server's IMAP port number? (Usually 993)" 10 60 3>&1 1>&2 2>&3 3>&-) - smtp=$( dialog --inputbox "Insert the SMTP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- ) - sport=$( dialog --inputbox "What is your server's SMTP port number? (Usually 587 or 465)" 10 60 3>&1 1>&2 2>&3 3>&- ) ;} - - -addloop() { fulladdr=$( dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Insert the full email address for the account you want to configure." 10 60 3>&1 1>&2 2>&3 3>&- ) -while ! [[ "${fulladdr}" =~ ${emailre} ]]; do - fulladdr=$(dialog --no-cancel --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "That's not a valid email address. Please input the entire address." 10 60 3>&1 1>&2 2>&3 3>&1) -done -# Check to see if domain is in domain list -serverinfo=$(grep -w ^${fulladdr##*@} "$muttdir"/autoconf/domains.csv) -if [ -z "$serverinfo" ]; - then - manual - else -# Read in server data as variables -IFS=, read service imap iport smtp sport <&1 1>&2 2>&3 3>&- ) -title=$(dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Give a short, one-word name for this email account that will differentiate it from other email accounts." 10 60 3>&1 1>&2 2>&3 3>&1) || exit -while ! [[ "${title}" =~ ${namere} ]]; do - title=$(dialog --no-cancel --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Account title not valid. Give a username beginning with a letter, with only lowercase letters, - or _." 10 60 3>&1 1>&2 2>&3 3>&1) -done -login=$(dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "If you have a username for the \"$title\" account which is different from your email address, enter it here. Otherwise leave this prompt blank." 10 60 3>&1 1>&2 2>&3 3>&- ) -# Sets the repo type and other variables for the sed regex. -if [[ "$service" == "gmail.com" ]]; - then - type="Gmail" - delet="remotehost" - else - type="IMAP" - delet="Gmail]\/" -fi -if [[ -z "$login" ]]; - then - login=$fulladdr -fi -# The replacements -replacement=" - s/\$realname/$realname/g; - s/\$title/$title/g; - s/\$fulladdr/$fulladdr/g; - s/\$imap/$imap/g; - s/\$iport/$iport/g; - s/\$smtp/$smtp/g; - s/\$sport/$sport/g; - s/\$type/$type/g; - s/\$login/$login/g; - /$delet/d" -# Gets the first unused shortcut number in the muttrc and puts it in $idnum. -grep "i[0-9]" "$muttdir/personal.muttrc" | awk '{print $3}' | sed -e 's/i//g' > /tmp/mutt_used -echo -e "1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9" > /tmp/mutt_all_possible -idnum=$(diff /tmp/mutt_all_possible /tmp/mutt_used | sed -n 2p | awk '{print $2}') -addAccount \ -;} - -addAccount() { - # First, adding the encrypted password. - dialog --title "Luke's mutt/offlineIMAP password wizard" --passwordbox "Enter the password for the \"$title\" account." 10 60 2> /tmp/$title - gpg2 -r $gpgemail --encrypt /tmp/$title || (dialog --title "GPG decryption failed." --msgbox "GPG decryption failed. This is either because you do not have a GPG key pair or because your distro uses GPG1 and you thus need to symlink /usr/bin/gpg2 to /usr/bin/gpg." 7 60 && break) - shred -u "/tmp/$title" - mv "/tmp/$title.gpg" "$muttdir"/credentials/ - - # Adding directory structure for cache. - mkdir -p "$muttdir/accounts/$title/cache/bodies" - - # Creating the offlineimaprc if it doesn't exist already. - if [ ! -f ~/.offlineimaprc ]; then cp "$muttdir"/autoconf/offlineimap_header"$os" ~/.offlineimaprc; fi - sed -e "$replacement" "$muttdir"/autoconf/offlineimap_profile"$os" >> ~/.offlineimaprc - mkdir -p "$HOME/.mail/$title" - - # Creating msmtprc if it doesn't exist already. - if [ ! -f ~/.msmtprc ]; then cp "$muttdir"/autoconf/msmtprc_header ~/.msmtprc; fi - sed -e "$replacement" "$muttdir"/autoconf/msmtprc_profile >> ~/.msmtprc - - # Add the mutt profile. - sed -e "$replacement" "$muttdir"/autoconf/mutt_profile > "$muttdir/accounts/$title.muttrc" - # Add a numbered shortcut in the muttrc - echo "macro index,pager i$idnum 'source \"$muttdir\"/accounts/$title.muttrc!;'" >> "$muttdir"/personal.muttrc - - # Add to offlineimaprc sync list. - sed -i.bu "s/^accounts =.*[a-zA-Z]$/&, $title/g;s/^accounts =\\s*$/accounts = $title/g" ~/.offlineimaprc && rm ~/.offlineimaprc.bu - - # Makes account default if there is no default account. - grep "$muttdir"/personal.muttrc -e "^source .*accounts.*" >/dev/null && echo there || \ - echo "source ${muttdir}/accounts/$title.muttrc" >> "$muttdir"/personal.muttrc - - dialog --title "Finalizing your account." --infobox "The account \"$title\" has been added. Now attempting to configure mail directories... - - This may take several seconds..." 10 70 - createMailboxes "$title" || (clear && exit) - detectMailboxes "$title" - dialog --title "Account added." --msgbox "Your \"$fulladdr\" account has been added. To start the download of your mail, you can manually run \`offlineimap -a $title\` in a terminal. The first sync may take some time depending on the amount of your mail." 8 60 ;} - -# This is run when a user chooses to add an account. -chooseAdd() { \ - mkdir -p "$muttdir"/credentials/ "$muttdir"/accounts/ - gpgemail=$( dialog --title "Luke's mutt/offlineIMAP password wizard" --inputbox "Insert the email address with which you originally created your GPG key pair. This is NOT necessarily the email you want to configure." 10 60 3>&1 1>&2 2>&3 3>&- ) - addloop - while : ; - do - dialog --title "Luke's mutt/offlineIMAP password wizard" --yesno "Would you like to add another email account?" 5 60 || break - addloop - done ;} - -wipe () { rm "$HOME/.offlineimaprc" - rm -rf "$muttdir"/accounts - rm -f "$muttdir"/credentials/*gpg - rm "$muttdir"/personal.muttrc ;} - -while : ; - do -choice=$(dialog --title "Luke's mutt/offlineIMAP wizard" --nocancel \ - --menu "What would you like to do?" 15 45 8 \ - 0 "List all email accounts configured." \ - 1 "Add an email account." \ - 2 "Enable/disable autosync." \ - 3 "Redetect mailboxes." \ - 4 "Change an account's password." \ - 5 "Remove an email account." \ - 6 "Remove all email accounts." \ - 7 "Exit this wizard." \ - 3>&1 1>&2 2>&3 3>&1 ) - -case $choice in -0) dialog --title "Accounts detected" --msgbox "The following accounts have been detected: -$(grep ~/.offlineimaprc -e "^accounts =" | sed 's/accounts =//g') -" 6 60;; -1) chooseAdd;; -2) testSync;; -3) detectWarning && chooseDetect;; -4) inventory && for i in $userchoices; do changePassword "$i" ; done;; -5) inventory && for i in $userchoices; do removeAccount "$i" ; done;; -6) (dialog --defaultno --title "Wipe all custom neomutt/offlineIMAP settings?" --yesno "Would you like to wipe all of the mutt/offlineIMAP settings generated by the system?" 6 60 && wipe) ;; -7) clear && break ;; -*) echo "Unable to read response from dialog. Exiting." >&2; exit 2 -esac -done diff --git a/muttrc b/muttrc index 70d5fb1..d2f3d7d 100644 --- a/muttrc +++ b/muttrc @@ -10,7 +10,7 @@ set editor = $EDITOR #set copy = no set timeout = "5" set mail_check = "10" -set mailcap_path = ~/.config/mutt/etc/mailcap +set mailcap_path = ~/.config/mutt/bin/mailcap set date_format="%y/%m/%d %I:%M" set index_format="%2C %zs %?X?A& ? %D %-15.15F %s (%-4.4c)" set markers = no @@ -65,10 +65,6 @@ macro index \Cr "T~UN." "ma macro index O "$HOME/.config/mutt/etc/mailsync.sh" "run offlineimap to sync all mail" macro index o "$HOME/.config/mutt/etc/mailsync.sh -qf INBOX" "run offlineimap to sync inbox" -#copy/move dialogs -macro index C "?" "copy a message to a mailbox" -macro index M "?" "move a message to a mailbox" - # Notmuch searching macro index \Cf "unset wait_keyread -p 'notmuch query: ' x; echo \$x >~/.cache/mutt_terms~i \"\`notmuch search --output=messages \$(cat ~/.cache/mutt_terms) | head -n 600 | perl -le '@a=<>;chomp@a;s/\^id:// for@a;$,=\"|\";print@a'\`\"" "show only messages matching a notmuch pattern" macro index A "all\n" "show all messages (undo limit)" diff --git a/mw b/mw new file mode 100755 index 0000000..92b11b0 --- /dev/null +++ b/mw @@ -0,0 +1,262 @@ +#!/bin/sh + +muttdir="$HOME/.config/mutt" # Main mutt config location +accdir="$muttdir/accounts" # Directory for account settings +maildir="$HOME/.local/share/mail" # Location of mail storage +creddir="$HOME/.local/share/muttwizard" # Location of encrypted credentials +bindir="$HOME/.config/mutt/bin" # Location of scripts run by mutt or the wizard +namere="^[a-z_][a-z0-9_-]*$" # Regex to ensure viable username +emailre=".\+@.\+\\..\+" # Regex to confirm valid email address +gpgemail="$(cat "$creddir/gpgemail")" # Get previously set gpg email address +tmpdir="$(mktemp -d)" +GPG="gpg"; command -v gpg >/dev/null || GPG="gpg2" # Ensure proper gpg command + +mkdir -p "$maildir" "$creddir" "$bindir" + +# Get certificate location depending on OS. Linux is elsewhere condition. +case "$(uname)" in + "Darwin") sslcert="/usr/local/etc/openssl/cert.pem" ;; + *) sslcert="/etc/ssl/certs/ca-certificates.crt" ;; +esac + +getprofiles() { \ +offlineimap_header="[general] +accounts = +starttls = yes +ssl = true +pythonfile = $bindir/imappwd.py + +" +offlineimap_profile=" +[Account $title] +localrepository = $title-local +remoterepository = $title-remote + +[Repository $title-remote] +auth_mechanisms = LOGIN +type = $type +remoteuser = $login +remotepasseval = mailpasswd(\"$title\") +remoteport = $iport +sslline = $sslcert +$ifgoogleline + +[Repository $title-local] +type = Maildir +localfolders = $maildir/$title +" + +msmtp_header="defaults +auth on +tls on +tls_trust_file $sslcert +logfile ~/.msmtp.log +" + +msmtp_profile=" + +account $title +host $smtp +port $sport +from $login +user $login +passwordeval \"$GPG -d --quiet --for-your-eyes-only --no-tty $creddir/$title.gpg | sed -e '\$a\\'\" +" + +mutt_profile="# vim: filetype=neomuttrc +# muttrc file for account $title +set realname = \"$realname\" +set from = \"$fulladdr\" +set sendmail = \"/usr/bin/msmtp -a $title\" +set folder = \"$maildir/$title\" +set header_cache = $accdir/$title/cache/headers +set message_cachedir = $accdir/$title/cache/bodies +set certificate_file = $accdir/$title/certificates +source \"$bindir/getmuttpass $title |\" + +alias me $realname <$fulladdr> + +set mbox_type = Maildir +set ssl_starttls = yes +set ssl_force_tls = yes + +bind index,pager gg noop +bind index,pager g noop +bind index,pager M noop +bind index,pager C noop +bind index gg first-entry +unmailboxes * +" + +offlineimap_profile=" +[Account $title] +localrepository = $title-local +remoterepository = $title-remote + +[Repository $title-remote] +auth_mechanisms = LOGIN +type = $type +remoteuser = $login +remotepasseval = mailpasswd(\"$title\") +remotehost = $imap +remoteport = $iport +folderfilter = lambda foldername: foldername not in ['[Gmail]/All Mail'] +sslcacertfile = /etc/ssl/certs/ca-certificates.crt + +[Repository $title-local] +type = Maildir +localfolders = $maildir/$title +" +} + +userexit() { clear; exit ;} + +inventory() { \ + grep "^accounts =" "$HOME/.config/offlineimap/config" | sed 's/accounts =\( \)//g;s/\(,\) /\n/g;' | nl --number-format=ln > "$tmpdir/numbered" + accounts=() + while read n s ; do + accounts+=($n "$s" off) + done < "$tmpdir/numbered" + choices=$(dialog --separate-output --checklist "Select all desired email accounts with ." 15 40 16 "${accounts[@]}" 2>&1 >/dev/tty) + + if [ -z "$choices" ]; + then + clear + else + userchoices=$(IFS="|"; keys="${choices[*]}"; keys="${keys//|/\\|}"; grep -w "${keys}" "$tmpdir/numbered" | awk '{print $2}') + fi ;} + +chooseadd() { \ + fulladdr=$( dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Insert the full email address for the account you want to configure." 10 60 3>&1 1>&2 2>&3 3>&- ) || userexit + while ! echo "$fulladdr" | grep "emailre" >/dev/null; do + fulladdr=$(dialog --no-cancel --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "That's not a valid email address. Please input the entire address." 10 60 3>&1 1>&2 2>&3 3>&1) || userexit + done + domain="$(echo "$fulladdr" | sed "s/.*@//")" + serverinfo="$(grep "$domain" "$muttdir/domains.csv")" + if [ -z "$serverinfo" ]; then + imap="$( dialog --inputbox "Insert the IMAP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- )" + iport="$(dialog --inputbox "What is your server's IMAP port number? (Usually 993)" 10 60 3>&1 1>&2 2>&3 3>&-)" + smtp="$(dialog --inputbox "Insert the SMTP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- )" + sport="$(dialog --inputbox "What is your server's SMTP port number? (Usually 587 or 465)" 10 60 3>&1 1>&2 2>&3 3>&- )" + else + IFS=, read service imap iport smtp sport <&1 1>&2 2>&3 3>&- ) || userexit + title=$(dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Give a short, one-word name for this email account that will differentiate it from other email accounts." 10 60 3>&1 1>&2 2>&3 3>&1) || userexit + while ! echo "$title" | grep "$namere" >/dev/null; do + title=$(dialog --no-cancel --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Account title not valid. Give a username beginning with a letter, with only lowercase letters, - or _." 10 60 3>&1 1>&2 2>&3 3>&1) || userexit + done + login=$(dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "If you have a username for the \"$title\" account which is different from your email address, enter it here. Otherwise leave this prompt blank." 10 60 3>&1 1>&2 2>&3 3>&- ) || userexit + [ -z "$login" ] && login="$fulladdr" + #ifgoogleline + grep "i[0-9]" "$muttdir/personal.muttrc" | awk '{print $3}' | sed -e 's/i//g' > "$tmpdir/mutt_used" + printf "1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9" > "$tmpdir/mutt_all_possible" + idnum=$(diff "$tmpdir/mutt_all_possible" "$tmpdir/mutt_used" | sed -n 2p | awk '{print $2}') + getpass "$title" || userexit + addaccount +} + +getpass() { \ + dialog --title "Luke's mutt/offlineIMAP password wizard" --passwordbox "Enter the password for the \"$1\" account." 10 60 2> "$tmpdir/$1" + "$GPG" -r "$gpgemail" --encrypt "$tmpdir/$1" + shred -u "$tmpdir/$1" + mv "$tmpdir/$1.gpg" "$creddir" +} + +addaccount() { \ + getprofiles + mkdir -p "$HOME/.config/offlineimap/" "$HOME/.config/msmtp" + [ ! -f "$HOME/.config/offlineimap/config" ] && echo "$offlineimap_header" > "$HOME/.config/offlineimap/config" + [ ! -f "$HOME/.config/msmtp/config" ] && echo "$msmtp_header" > "$HOME/.config/msmtp/config" + echo "$offlineimap_profile" >> "$HOME/.config/offlineimap/config" + echo "$msmtp_profile" >> "$HOME/.config/msmtp/config" + echo "$mutt_profile" > "$accdir/$title.muttrc" +} + +askgpg() { \ + gpgemail=$(dialog --title "Luke's mutt/offlineIMAP wizard" --inputbox "To safely encrypt passwords, mutt-wizard requires that you have a GPG public/private key pair.\n\nPlease insert the email address for your key pair here, or generate one first with \`$GPG --full-gen-key\` and come back." 12 60 3>&1 1>&2 2>&3 3>&- ) || userexit + while ! echo "$gpgemail" | grep "$emailre"; do + gpgemail=$(dialog --title "Luke's mutt/offlineIMAP wizard" --inputbox "That's not a valid email address. Please input the entire address." 10 60 3>&1 1>&2 2>&3 3>&1) || userexit + + done + if "$GPG" -K | grep "<$gpgemail>"; then + echo "$gpgemail" > "$creddir/gpgemail" + else + dialog --title "Luke's mutt/offlineIMAP wizard" --msgbox "You do not appear to have a private key with that email address.\n\nPlease be sure to create your key with \`$GPG --full-gen-key\` and come back." 8 70 + clear; exit + fi +} + +formatShortcut() { \ + while read data; do { echo "macro index,pager g$1 \"$data\" \"Go to $2.\" # autogenerated" + echo "macro index,pager M$1 \"$data\" \"Move mail to $2.\" # autogenerated" + echo "macro index,pager C$1 \"$data\" \"Copy mail to $2.\" # autogenerated"; } >> "$muttdir/accounts/$3.muttrc" + done ;} + +gen_delim() { \ + delim="=" + for i in $(seq $(( $1 - 1 ))) + do + delim="$delim-" + done + echo $delim ;} + +detectMailboxes() { \ + ls -d "$maildir/$1/"* | sed "s/.*\///;s/^/=/" > "$tmpdir/$1_boxes" + sidebar_width="$(sed -n -e '/^set sidebar_width/p' "$muttdir/muttrc" | awk -F'=' '{print $2}')" + delim="$(gen_delim "$sidebar_width")" + oneline="$(sed -e "s/^\|$/\"/g" "$tmpdir/$1_boxes" | tr "\n" " ")" + oneline="=$1 $delim $oneline" + sed -i "/^mailboxes\|^set record\|^set postponed\|^set trash\|^set spoolfile/d" "$muttdir/accounts/$1.muttrc" + echo mailboxes "$oneline" >> "$muttdir/accounts/$1.muttrc" + sed -i "/# autogenerated/d" "$muttdir/accounts/$1.muttrc" + grep -i "$tmpdir/$1_boxes" -e inbox | sed 1q | formatShortcut i inbox "$1" + grep -i "$tmpdir/$1_boxes" -e sent | sed 1q | formatShortcut s sent "$1" + grep -i "$tmpdir/$1_boxes" -e draft | sed 1q | formatShortcut d drafts "$1" + grep -i "$tmpdir/$1_boxes" -e trash | sed 1q | formatShortcut t trash "$1" + grep -i "$tmpdir/$1_boxes" -e spam | sed 1q | formatShortcut S spam "$1" + grep -i "$tmpdir/$1_boxes" -e junk | sed 1q | formatShortcut j junk "$1" + grep -i "$tmpdir/$1_boxes" -e archive | sed 1q | formatShortcut a archive "$1" + spoolfile=$(grep -i "$tmpdir/$1_boxes" -e inbox | sed -e 's/=/+/g' | sed 1q) + record=$(grep -i "$tmpdir/$1_boxes" -e sent | sed -e 's/=/+/g' | sed 1q) + postponed=$(grep -i "$tmpdir/$1_boxes" -e draft | sed -e 's/=/+/g' | sed 1q) + trash=$(grep -i "$tmpdir/$1_boxes" -e trash | sed -e 's/=/+/g' | sed 1q) + { echo "set spoolfile = \"$spoolfile\""; echo "set record = \"$record\""; echo "set postponed = \"$postponed\""; echo "set trash = \"$trash\""; } >> "$muttdir/accounts/$1.muttrc" +} + + +#wipe () { rm "$HOME/.config/offlineimap/config" "$accdir" "$creddir" "$muttdir/personal.muttrc" ;} + +[ -z "$gpgemail" ] && askgpg + +while : ; + do +choice=$(dialog --title "Luke's mutt/offlineIMAP wizard" --nocancel \ + --menu "What would you like to do?" 15 50 8 \ + 0 "Add email account (Begin installtion)" \ + 1 "Autodetect mailboxes (Finalize installation)" \ + 2 "Enable/disable autosync." \ + 3 "Change an account's password" \ + 4 "Remove an account" \ + 5 "Remove all accounts" \ + 6 "Change your GPG email" \ + 7 "Exit this wizard." \ + 3>&1 1>&2 2>&3 3>&1 ) + +case $choice in +0) dialog --title "Accounts detected" --msgbox "The following accounts have been detected: +$(grep ~/.offlineimaprc -e "^accounts =" | sed 's/accounts =//g') +" 6 60;; +1) chooseadd ;; +2) detectWarning && chooseDetect;; +3) inventory && for i in $userchoices; do getpass "$i" ; done;; +4) inventory && for i in $userchoices; do removeAccount "$i" ; done;; +5) (dialog --defaultno --title "Wipe all custom neomutt/offlineIMAP settings?" --yesno "Would you like to wipe all of the mutt/offlineIMAP settings generated by the system?" 6 60 && wipe) ;; +6) askgpg ;; +7) clear && break ;; +*) echo "Error. Are you sure you have dialog installed?" >&2; exit 2 +esac +done +rm -rf "$tmpdir"