Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

364 linhas
15 KiB

  1. #!/usr/bin/env bash
  2. if [ "$(uname)" == "Darwin" ];
  3. then
  4. sslcert="/etc/ssl/certs/ca-certificates.crt"
  5. else
  6. sslcert="/usr/local/etc/openssl/cert.pem"
  7. fi
  8. muttdir="$HOME/.config/mutt"
  9. namere="^[a-z_][a-z0-9_-]*$"
  10. emailre=".+@.+\\..+"
  11. createMailboxes() { \
  12. tmpdir=$(mktemp -d)
  13. offlineimap --info -a "$1" 2&> "$tmpdir"/log
  14. sed -n '/^Folderlist/,/^Folderlist/p' "$tmpdir"/log |
  15. grep "^ " | sed -e "s/\\//./g;s/(.*//g;s/^ //g" > "$tmpdir"/lognew
  16. while read -r box; do mkdir -p "$HOME/.mail/$1/$box"; done <"$tmpdir"/lognew ;}
  17. testSync() { (crontab -l | grep mailsync.sh && removeSync) || addSync ;}
  18. addSync() { min=$(dialog --inputbox "How many minutes should be between mail syncs?" 8 60 3>&1 1>&2 2>&3 3>&-)
  19. (crontab -l; echo "*/$min * * * * eval \"export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME -x i3)/environ)\"; "$muttdir"/etc/mailsync.sh") | crontab - &&
  20. 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 ;}
  21. removeSync() { ( (crontab -l | sed -e '/mailsync.sh/d') | crontab - >/dev/null) && dialog --msgbox "Cronjob successfully removed. To reactivate, select this option again." 6 60 ;}
  22. msmtp_header="defaults
  23. auth on
  24. tls on
  25. tls_trust_file $sslcert
  26. logfile ~/.msmtp.log
  27. "
  28. offlineimap_header="[general]
  29. accounts =
  30. starttls = yes
  31. ssl = true
  32. pythonfile = ~/.config/mutt/credentials/imappwd.py
  33. "
  34. getprofiles() { \
  35. offlineimap_profile="
  36. [Account $title]
  37. localrepository = $title-local
  38. remoterepository = $title-remote
  39. [Repository $title-remote]
  40. auth_mechanisms = LOGIN
  41. type = $type
  42. remoteuser = $login
  43. remotepasseval = mailpasswd(\"$title\")
  44. remoteport = $iport
  45. sslline = $sslcert
  46. $ifgoogleline
  47. [Repository $title-local]
  48. type = Maildir
  49. localfolders = ~/.mail/$title
  50. "
  51. msmtp_profile="
  52. account $title
  53. host $smtp
  54. port $sport
  55. from $login
  56. user $login
  57. passwordeval \"gpg -d --quiet --for-your-eyes-only --no-tty ~/.config/mutt/credentials/$title.gpg | sed -e '\$a\\'\"
  58. "
  59. mutt_profile="# vim: filetype=neomuttrc
  60. # muttrc file for account $title
  61. set realname = \"$realname\"
  62. set from = \"$fulladdr\"
  63. set sendmail = \"/usr/bin/msmtp -a $title\"
  64. set folder = \"~/.mail/$title\"
  65. set header_cache = ~/.config/mutt/accounts/$title/cache/headers
  66. set message_cachedir = ~/.config/mutt/accounts/$title/cache/bodies
  67. set certificate_file = ~/.config/mutt/accounts/$title/certificates
  68. source \"~/.config/mutt/credentials/getmuttpass $title |\"
  69. alias me $realname <$fulladdr>
  70. set mbox_type = Maildir
  71. set ssl_starttls = yes
  72. set ssl_force_tls = yes
  73. bind index,pager gg noop
  74. bind index,pager g noop
  75. bind index gg first-entry
  76. unmailboxes *
  77. "
  78. mbsync_profile="IMAPAccount $title
  79. Host $imap
  80. User $login
  81. PassCmd \"gpg -d ~/.config/mutt/credentials/$title.gpg\"
  82. SSLType IMAPS
  83. CertificateFile $sslcert
  84. IMAPStore $title-remote
  85. Account $title
  86. MaildirStore $title-local
  87. Subfolders Verbatim
  88. Path ~/.mail/$title
  89. Inbox ~/.mail/$title/INBOX
  90. Channel $title
  91. Master :$title-remote:
  92. Slave :$title-local:
  93. Ceate Both
  94. SyncState *
  95. "
  96. }
  97. changePassword() { \
  98. 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>&- )
  99. while ! [[ "${gpgemail}" =~ ${emailre} ]]; do
  100. 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)
  101. done
  102. dialog --title "Luke's mutt/offlineIMAP password wizard" --passwordbox "Enter the new password for the \"$1\" account." 10 60 2> "/tmp/$1"
  103. 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)
  104. shred -u "/tmp/$1"
  105. mv "/tmp/$1.gpg" "$muttdir"/credentials/
  106. dialog --title "Finalizing your account." --infobox "The account \"$title\"'s password has been changed. Now attempting to configure mail directories...
  107. This may take several seconds..." 10 70
  108. createMailboxes "$title" || (clear && exit)
  109. detectMailboxes "$title"
  110. 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 ;}
  111. chooseDetect() { for x in $(grep "^accounts =" ~/.offlineimaprc | sed -e 's/accounts =\( \)//g;s/\(,\) /\n/g;'); do detectMailboxes "$x"; done && detectSuccess ;}
  112. detectWarning() { \
  113. dialog --title "Mailbox detect requirement" --yesno "In order for the mailbox detection system to work, you must have
  114. 1) already have added the email account with this wizard, and
  115. 2) already have run offlineimap at least once to synchronize your mail.
  116. This detection system only works if you already have begun your first sync. If you have, press 'yes' to continue." 12 70 ;}
  117. 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:
  118. gi for move to the Inbox.
  119. gs for move to Sent Mail.
  120. gd for move to Drafts
  121. gS for move to Spam
  122. ga for move to the Archive.
  123. gj for move to Junk
  124. gt for move to Trash
  125. 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 ;}
  126. formatShortcut() { \
  127. while read -r data; do
  128. echo "macro index,pager g$1 \"<change-folder>$data<enter>\" \"Go to $2.\"" >> "$muttdir/accounts/$3.muttrc"
  129. done ;}
  130. gen_delim() { \
  131. delim="="
  132. for i in $(seq $(( $1 - 1 )))
  133. do
  134. delim="$delim-"
  135. done
  136. echo $delim ;}
  137. detectMailboxes() { \
  138. find ~/.mail/"$1" -maxdepth 1 -mindepth 1 -type d | sed -e "s/.*\\///g;s/^/=/g" > "/tmp/$1_boxes"
  139. sidebar_width=$(sed -n -e '/^set sidebar_width/p' "$muttdir"/muttrc | awk -F'=' '{print $2}')
  140. delim=$(gen_delim "$sidebar_width")
  141. oneline=$(sed -e "s/^\\|$/\"/g" "/tmp/$1_boxes" | tr "\\n" " ")
  142. oneline="=$1 $delim $oneline"
  143. sed -i "/^mailboxes\\|^set record\\|^set postponed\\|^set trash\\|^set spoolfile/d" "$muttdir/accounts/$1.muttrc"
  144. echo mailboxes "$oneline" >> "$muttdir/accounts/$1.muttrc"
  145. sed -i "/^macro index,pager g/d" "$muttdir/accounts/$1.muttrc"
  146. grep -i "/tmp/$1_boxes" -e inbox | sed 1q | formatShortcut i inbox "$1"
  147. grep -i "/tmp/$1_boxes" -e sent | sed 1q | formatShortcut s sent "$1"
  148. grep -i "/tmp/$1_boxes" -e draft | sed 1q | formatShortcut d drafts "$1"
  149. grep -i "/tmp/$1_boxes" -e trash | sed 1q | formatShortcut t trash "$1"
  150. grep -i "/tmp/$1_boxes" -e spam | sed 1q | formatShortcut S spam "$1"
  151. grep -i "/tmp/$1_boxes" -e junk | sed 1q | formatShortcut j junk "$1"
  152. grep -i "/tmp/$1_boxes" -e archive | sed 1q | formatShortcut a archive "$1"
  153. spoolfile=$(grep -i "/tmp/$1_boxes" -e inbox | sed -e 's/=/+/g' | sed 1q)
  154. record=$(grep -i "/tmp/$1_boxes" -e sent | sed -e 's/=/+/g' | sed 1q)
  155. postponed=$(grep -i "/tmp/$1_boxes" -e draft | sed -e 's/=/+/g' | sed 1q)
  156. trash=$(grep -i "/tmp/$1_boxes" -e trash | sed -e 's/=/+/g' | sed 1q)
  157. { echo "set spoolfile = \"$spoolfile\"";
  158. echo "set record = \"$record\"";
  159. echo "set postponed = \"$postponed\"";
  160. echo "set trash = \"$trash\""; } >> "$muttdir/accounts/$1.muttrc"
  161. }
  162. # Get all accounts in ~/.offlineimaprc and load into variable `accounts`.
  163. getAccounts() { \
  164. grep "^accounts =" ~/.offlineimaprc | sed -e 's/accounts =\( \)//g;s/\(,\) /\n/g;' | nl --number-format=ln > /tmp/numbered
  165. accounts=()
  166. while read -r n s ; do
  167. accounts+=("$n" "$s" off)
  168. done < /tmp/numbered ;}
  169. # Yields a menu of available accounts.
  170. inventory() { \
  171. getAccounts
  172. choices=$(dialog --separate-output --checklist "Select all desired email accounts with <SPACE>." 15 40 16 "${accounts[@]}" 2>&1 >/dev/tty)
  173. if [ -z "$choices" ];
  174. then
  175. clear
  176. else
  177. userchoices=$(IFS="|"; keys="${choices[*]}"; keys="${keys//|/\\|}"; grep -w "${keys}" /tmp/numbered | awk '{print $2}')
  178. fi ;}
  179. removeAccount() { sed -ie "
  180. /Account $1]/,/Account/{//!d}
  181. /Account $1]/d
  182. s/ $1\\(,\\|$\\)//g
  183. s/=$1\\(,\\|$\\)/=/g
  184. s/,$//g
  185. " ~/.offlineimaprc
  186. rm "$muttdir/accounts/$1.muttrc"
  187. rm "$muttdir/credentials/$1.gpg"
  188. rm -rf "$muttdir/accounts/$1"
  189. sed -i "/$1.muttrc/d" "$muttdir"/personal.muttrc ;}
  190. manual() { \
  191. imap=$( dialog --inputbox "Insert the IMAP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- )
  192. iport=$(dialog --inputbox "What is your server's IMAP port number? (Usually 993)" 10 60 3>&1 1>&2 2>&3 3>&-)
  193. smtp=$( dialog --inputbox "Insert the SMTP server for your email provider (excluding the port number)" 10 60 3>&1 1>&2 2>&3 3>&- )
  194. sport=$( dialog --inputbox "What is your server's SMTP port number? (Usually 587 or 465)" 10 60 3>&1 1>&2 2>&3 3>&- ) ;}
  195. addloop() { \
  196. serverlist=$(mktemp -u)
  197. curl -sL https://raw.githubusercontent.com/LukeSmithxyz/mutt-wizard/master/autoconf/domains.csv 2>/dev/null > "$serverlist" &
  198. 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>&- )
  199. while ! [[ "${fulladdr}" =~ ${emailre} ]]; do
  200. 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)
  201. done
  202. # Check to see if domain is in domain list
  203. serverinfo=$(grep -w "^${fulladdr##*@}" "$serverlist")
  204. if [ -z "$serverinfo" ];
  205. then
  206. manual
  207. else
  208. # Read in server data as variables
  209. IFS=, read -r service imap iport smtp sport <<EOF
  210. $serverinfo
  211. EOF
  212. fi
  213. realname=$( dialog --title "Luke's mutt/offlineIMAP autoconfig" --inputbox "Enter the full name you'd like to be identified by on this email account." 10 60 3>&1 1>&2 2>&3 3>&- )
  214. 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
  215. while ! [[ "${title}" =~ ${namere} ]]; do
  216. 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)
  217. done
  218. 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>&- )
  219. # Sets the repo type and other variables for the sed regex.
  220. if [[ "$service" == "gmail.com" ]];
  221. then
  222. type="Gmail"
  223. ifgoogleline="remotehost = $imap"
  224. else
  225. type="IMAP"
  226. ifgoogleline="folderfilter = lambda foldername: foldername not in ['[Gmail]/All Mail']"
  227. fi
  228. [[ -z "$login" ]] && login=$fulladdr
  229. # Gets the first unused shortcut number in the muttrc and puts it in $idnum.
  230. grep "i[0-9]" "$muttdir/personal.muttrc" | awk '{print $3}' | sed -e 's/i//g' > /tmp/mutt_used
  231. echo -e "1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9" > /tmp/mutt_all_possible
  232. idnum=$(diff /tmp/mutt_all_possible /tmp/mutt_used | sed -n 2p | awk '{print $2}')
  233. addAccount \
  234. ;}
  235. addAccount() {
  236. # First, adding the encrypted password.
  237. dialog --title "Luke's mutt/offlineIMAP password wizard" --passwordbox "Enter the password for the \"$title\" account." 10 60 2> "/tmp/$title"
  238. 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)
  239. shred -u "/tmp/$title"
  240. mv "/tmp/$title.gpg" "$muttdir"/credentials/
  241. # Adding directory structure for cache.
  242. mkdir -p "$muttdir/accounts/$title/cache/bodies"
  243. # Prepare the account's config variables.
  244. getprofiles
  245. # Creating the offlineimaprc if it doesn't exist already.
  246. [ ! -f ~/.offlineimaprc ] && echo "$offlineimap_header" > ~/.offlineimaprc
  247. echo "$offlineimap_profile" >> ~/.offlineimaprc
  248. mkdir -p "$HOME/.mail/$title"
  249. # Creating msmtprc if it doesn't exist already.
  250. [ ! -f ~/.msmtprc ] && echo "$msmtp_header" > ~/.msmtprc
  251. echo "$msmtp_profile" >> ~/.msmtprc
  252. # Add the mutt profile.
  253. echo "$mutt_profile" >> "$muttdir/accounts/$title.muttrc"
  254. # Add a numbered shortcut in the muttrc
  255. echo "macro index,pager i$idnum '<sync-mailbox><enter-command>source \"$muttdir\"/accounts/$title.muttrc<enter><change-folder>!<enter>;<check-stats>'" >> "$muttdir/personal.muttrc"
  256. # Add to offlineimaprc sync list.
  257. sed -i "s/^accounts =.*[a-zA-Z]$/&, $title/g;s/^accounts =\\s*$/accounts = $title/g" ~/.offlineimaprc
  258. # Makes account default if there is no default account.
  259. grep "$muttdir/personal.muttrc" -e "^source .*accounts.*" >/dev/null || \
  260. echo "source ${muttdir}/accounts/$title.muttrc" >> "$muttdir/personal.muttrc"
  261. dialog --title "Finalizing your account." --infobox "The account \"$title\" has been added. Now attempting to configure mail directories...
  262. This may take several seconds..." 10 70
  263. createMailboxes "$title" || (clear && exit)
  264. detectMailboxes "$title"
  265. 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 ;}
  266. # This is run when a user chooses to add an account.
  267. chooseAdd() { \
  268. mkdir -p "$muttdir"/credentials/ "$muttdir"/accounts/
  269. 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>&- )
  270. addloop
  271. while : ;
  272. do
  273. dialog --title "Luke's mutt/offlineIMAP password wizard" --yesno "Would you like to add another email account?" 5 60 || break
  274. addloop
  275. done ;}
  276. wipe () { rm -f "$HOME/.offlineimaprc"
  277. rm -rf "$muttdir"/accounts
  278. rm -f "$muttdir"/credentials/*gpg
  279. rm -f "$muttdir"/personal.muttrc ;}
  280. while : ;
  281. do
  282. choice=$(dialog --title "Luke's mutt/offlineIMAP wizard" --nocancel \
  283. --menu "What would you like to do?" 15 45 8 \
  284. 0 "List all email accounts configured." \
  285. 1 "Add an email account." \
  286. 2 "Enable/disable autosync." \
  287. 3 "Redetect mailboxes." \
  288. 4 "Change an account's password." \
  289. 5 "Remove an email account." \
  290. 6 "Remove all email accounts." \
  291. 7 "Exit this wizard." \
  292. 3>&1 1>&2 2>&3 3>&1 )
  293. case $choice in
  294. 0) dialog --title "Accounts detected" --msgbox "The following accounts have been detected:
  295. $(grep ~/.offlineimaprc -e "^accounts =" | sed 's/accounts =//g')
  296. " 6 60;;
  297. 1) chooseAdd;;
  298. 2) testSync;;
  299. 3) detectWarning && chooseDetect;;
  300. 4) inventory && for i in $userchoices; do changePassword "$i" ; done;;
  301. 5) inventory && for i in $userchoices; do removeAccount "$i" ; done;;
  302. 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) ;;
  303. 7) clear && break ;;
  304. *) echo "Unable to read response from dialog. Exiting." >&2; exit 2
  305. esac
  306. done