You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

623 lines
21 KiB

  1. #!/bin/sh
  2. if [ -z "$prefix" ]; then
  3. case "$(uname)" in
  4. Linux) prefix="/usr" ;;
  5. *) prefix="/usr/local" ;;
  6. esac
  7. fi
  8. mwconfigdir=${XDG_CONFIG_HOME:-$HOME/.config}
  9. # Main mutt config location
  10. mwmuttdir="$mwconfigdir/mutt"
  11. mwmuttrc="$mwmuttdir/muttrc"
  12. # Directory for account settings
  13. mwaccmuttdir="$mwmuttdir/accounts"
  14. # Generated at every full sync
  15. mwgenmuttaccs=$mwmuttdir/mw_generated.muttrc
  16. # Location of mail storage
  17. mwmaildir="${MAILDIR:-$HOME/mail}"
  18. # Regex to confirm valid email address
  19. mwemailre=".\+@.\+\\..\+"
  20. mwshare="$prefix/share/mutt-wizard"
  21. mwmbsyncrc="$mwconfigdir/isync/mbsyncrc"
  22. mwgetmaildir=$mwconfigdir/getmail #POP3
  23. mwmsmtprc="$mwconfigdir/msmtp/config"
  24. mwsharerc="$mwshare/mutt-wizard.muttrc"
  25. mwcachedir="${XDG_CACHE_HOME:-$HOME/.cache}/mutt-wizard"
  26. mwssltype="IMAPS"
  27. mwmbsyncbin="$prefix/bin/mbsync -c $mwmbsyncrc"
  28. msmtpbin="$prefix/bin/msmtp"
  29. mwtype=offline
  30. _mwaddrmwtype(){
  31. mwacc="$mwaddr" # let the user always just deal with his email
  32. mwaccmaildir="$mwmaildir/$mwaddr" # mail dir is $MAILDIR/email
  33. mwacccachedir=$mwcachedir/${mwaddr//[.@]/_} # @ cannot stay because of mutt, . could
  34. mwpass=mutt-wizard-$mwaddr
  35. [ -n "$mwidnum" ] && mwaccmuttrc="$mwaccmuttdir/$mwidnum-$mwacc.mwonofftype.$mwtype.muttrc"
  36. }
  37. _mwaccs() {
  38. mwaccs="$(find "$mwaccmuttdir" -type f | grep -o "[1-9]-.*.muttrc" | sed "s/-/: /;s/\.muttrc//" | sort -n)"
  39. }
  40. _mwlist() {
  41. _mwaccs && [ -n "$mwaccs" ] && echo "${mwaccs//.mwonofftype./ }"
  42. }
  43. _mwadd() {
  44. _mwcheckinternet && _mwasktype && _mwaskinfo && _mwtryconnect && _mwfinalize || _mwdelete
  45. }
  46. _mwgetprofiles() {
  47. unset mwmsmtpheader mwmsmtpprofile mwmbsyncprofile
  48. for mwcrt in "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/etc/ssl/ca-bundle.pem" "/etc/pki/tls/cacert.pem" "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" "/etc/ssl/cert.pem" "/usr/local/share/ca-certificates/"
  49. do
  50. [ -f "$mwcrt" ] && mwsslcert="$mwcrt" && break
  51. done || { echo "CA Certificate not found. Please install one or link it to /etc/ssl/certs/ca-certificates.crt" && return 1 ;}
  52. printf "Creating profiles for \`%s\`..." "$mwaddr"
  53. mwmsmtpheader="defaults
  54. auth on
  55. tls on
  56. tls_trust_file $mwsslcert
  57. logfile ${XDG_LOG_HOME:-$HOME}/msmtp.log
  58. "
  59. mwmsmtpprofile="account $mwacc
  60. host $mwsmtp
  61. port $mwsport
  62. from $mwaddr
  63. user $mwlogin
  64. passwordeval \"pass $mwpass\"
  65. $mwstarttlsoff
  66. "
  67. mwmbsyncprofile="IMAPStore $mwacc-remote
  68. Host $mwserver
  69. Port $mwport
  70. User $mwlogin
  71. PassCmd \"pass $mwpass\"
  72. SSLType $mwssltype
  73. CertificateFile $mwsslcert
  74. MaildirStore $mwacc-local
  75. Subfolders Verbatim
  76. Path $mwaccmaildir/
  77. Inbox $mwaccmaildir/INBOX
  78. Flatten .
  79. Channel $mwacc
  80. Expunge Both
  81. Master :$mwacc-remote:
  82. Slave :$mwacc-local:
  83. Patterns * !\"[Gmail]/All Mail\"
  84. Create Both
  85. SyncState *
  86. MaxMessages 0
  87. # End profile
  88. "
  89. printf "DONE.\\n"
  90. }
  91. _mwaskinfo() {
  92. if [ -z "$mwaddr" ]; then
  93. printf "Type the \033[31memail address\033[0m\\n\t\033[36m"
  94. read -r mwaddr
  95. printf "\033[0m"
  96. while ! echo "$mwaddr" | grep "$mwemailre" >/dev/null; do
  97. printf "That is not a valid \033[31memail address\033[0m, please retype\\n\t\033[36m"
  98. read -r mwaddr
  99. printf "\033[0m"
  100. done
  101. fi
  102. mwdomain="$(echo "$mwaddr" | sed "s/.*@//")"
  103. printf "\\nSearching for \033[32m%s\033[0m in \033[34m\`domains.csv\`\033[0m..." "$mwdomain"
  104. mwserverinfo="$(grep "^$mwdomain" "$mwshare/domains.csv" 2>/dev/null)"
  105. if [ -z "$mwserverinfo" ]; then
  106. printf "Your email domain is not known to mutt-wizard.\\nType in your settings.\\nUsually you find them by an internet search.\\n"
  107. printf "Type the IMAP/POP3 server (excluding the port number)\\n\033[36m\t"
  108. read -r mwserver
  109. printf "\033[0mIMAP port number (usually 993)\\n\033[36m\t"
  110. read -r mwport
  111. printf "\033[0mSMTP server (excluding the port number)\\n\033[36m\t"
  112. read -r mwsmtp
  113. printf "\033[0mSMTP port number (usually 587 or 465)\\n\033[36m\t"
  114. read -r mwsport
  115. printf "\033[0m\\nIf you want, you can copy the line below and add it to the \`domains.csv\` file on Github, for others.\\n\\n%s,%s,%s,%s,%s\\n\\nBut be sure the setting works, first! ;-)\\n" "$mwdomain" "$mwserver" "$mwport" "$mwsmtp" "$mwsport"
  116. else
  117. IFS=, read -r mwservice mwserver mwport mwsmtp mwsport <<EOF
  118. $mwserverinfo
  119. EOF
  120. printf "\\n\033[3;33mCongrats!\033[0m Server info is known, so you don't need to look it up!\\n\t\033[1mIMAP server\033[0m: %s\\n\t\033[1mIMAP port\033[0m: %s\\n\t\033[1mSMTP server\033[0m: %s\\n\t\033[1mSMTP port\033[0m: %s\\n" "$mwserver" "$mwport" "$mwsmtp" "$mwsport"
  121. case "$mwservice" in
  122. gmail.com) printf "\033[31mGmail: \"less secure\" must be enabled before you continue.\\nDo it now, if you have not done it already:\\nhttps://support.google.com/accounts/answer/6010255\\n\033[0m" ;;
  123. protonmail.ch|protonmail.com|pm.me) printf "\033[31mProtonmail: Users must install and configure Protonmail Bridge for the sync to work:\\nhttps://protonmail.com/bridge/\\n\033[0m" && ssltype="None" ;;
  124. esac
  125. [ "$mwsport" = 465 ] && mwstarttlsoff="tls_starttls off"
  126. fi
  127. if [ -z "$mwname" ]; then
  128. printf "Name to associate to email.\\n\t"
  129. read -r mwname
  130. fi
  131. if [ -z "$mwlogin" ]; then
  132. printf "Type your account username if different from your email address.\\n\033[34mFor most accounts you can probably leave this blank.\033[0m\\n\tLogin(?): \033[36m"
  133. read -r mwlogin
  134. printf "\033[0m"
  135. [ -z "$mwlogin" ] && mwlogin="$mwaddr"
  136. fi
  137. # if the user has a pass entry he could provide it via mwpass
  138. if [ -z "$mwpass" ]; then
  139. mwpass=mutt-wizard-$mwaddr
  140. _mwgetpass
  141. fi
  142. _mwaddrmwtype
  143. if [ "$mwtype" = "pop" ]; then
  144. cat > "$mwgetmaildir/$mwaddr" << EOF
  145. [retriever]
  146. type = SimplePOP3SSLRetriever
  147. server = $mwserver
  148. username = $mwaddr
  149. port = $mwport
  150. password_command = ("pass", "$mwpass")
  151. [destination]
  152. type = Maildir
  153. path = $mwaccmaildir/INBOX/
  154. [options]
  155. read_all = true
  156. delete = true
  157. message_log = ${XDG_LOG_HOME:-$HOME}/getmail.log
  158. # vim: ft=conf
  159. EOF
  160. #from now on pop is lile offline
  161. mwtype=offline
  162. return 0
  163. fi
  164. _mwgetprofiles || return 1
  165. mkdir -p "$mwmuttdir" "$mwaccmuttdir" "${mwmsmtprc%/*}" "${mwmbsyncrc%/*}"
  166. if [ ! -f "$mwmsmtprc" ]; then
  167. echo "$mwmsmtpheader" > "$mwmsmtprc"
  168. else
  169. sed -i "/account $mwacc/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
  170. fi
  171. echo "$mwmsmtpprofile" >> "$mwmsmtprc"
  172. case "$mwservice" in
  173. protonmail.ch|protonmail.com|pm.me) protonfinger || return 1 ;;
  174. esac
  175. [ -f "$mwmbsyncrc" ] && sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
  176. echo "$mwmbsyncprofile" >> "$mwmbsyncrc"
  177. [ ! -f "$mwmuttrc" ] && echo "# vim: filetype=muttrc" > "$mwmuttrc" && echo "muttrc created."
  178. ! grep "source $mwsharerc" "$mwmuttrc" >/dev/null && echo "source $mwsharerc # mw-autogenerated" >> "$mwmuttrc"
  179. return 0
  180. }
  181. _mwprotonfinger() {
  182. printf "Getting Protonmail bridge fingerprint...\\n"
  183. mwfingerprint="$($msmtpbin --serverinfo --host=127.0.0.1 --port=1025 --tls --tls-certcheck=off)" || return 1
  184. sed -i "s/account $mwacc/&\ntls_trust_file\ntls_fingerprint $mwfingerprint/" "$mwmsmtprc"
  185. }
  186. _mwgetpass() {
  187. while : ; do pass rm -f "$mwpass" >/dev/null 2>&1
  188. pass insert "$mwpass" && break; done ;}
  189. _mwtryconnect() {
  190. if [ ! -d "$mwaccmaildir" ]; then
  191. mwaccmaildirWasThere="NO" # we need to remove again for "online"
  192. mkdir -p "$mwaccmaildir"
  193. fi
  194. if [ -z "$mwmailboxes" ]; then
  195. if [ "$mwtype" = "pop" ]; then
  196. mwgetmailbin --rcfile=$mwaddr --getmaildir=$mwgetmaildir && mwmailboxes="INBOX"
  197. else
  198. mwmailboxes="$($mwmbsyncbin -l $mwacc | sed 's/\//./')" >/dev/null 2>&1
  199. fi
  200. fi
  201. if [ -n "$mwmailboxes" ]; then
  202. mwspoolfile=$(echo "$mwmailboxes" | grep -i -m 1 inbox | sed -ne 's/.*/+\0/p')
  203. [ -z "$mwspoolfile" ] && printf "\033[31m\033[31mNo spoolfile.\033[0m\\n" && return 1
  204. printf "\033[32mMailboxes detected.\033[0m\\n"
  205. echo "$mwmailboxes" | xargs -I {} mkdir -p "$mwaccmaildir/{}/"{cur,new,tmp}
  206. else
  207. printf "\033[31m\033[31mLog-on not successful.\033[0m\\nIt seems that either you inputted the wrong password or server settings, or there are other requirements for your account out of the control of mutt-wizard.\\n"
  208. return 1
  209. fi
  210. }
  211. _mwfinalize() { # new mwaccmuttrc
  212. _genmwaccmuttrc
  213. if [ "$mwtype" = "online" ]; then
  214. cat >> "$mwaccmuttrc" <<EOF
  215. set folder = "imaps://$mwaddr@$mwserver:$mwport"
  216. set header_cache = "$mwacccachedir"
  217. set message_cachedir = \$header_cache
  218. set imap_user = "$mwlogin"
  219. set imap_pass = "\`pass $mwpass\`"
  220. account-hook \$folder 'set imap_user="$mwlogin" imap_pass="\`pass $mwpass\`"'
  221. set mbox_type = Maildir
  222. set ssl_starttls = yes
  223. set ssl_force_tls = yes
  224. EOF
  225. mkdir -p "$mwacccachedir"
  226. sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
  227. [ "$mwaccmaildirWasThere" = "NO" ] && rm -rf "$mwaccmaildir"
  228. else
  229. _mwnotmuchauto
  230. printf "All done.\\n\033[33mYou can now run \`\033[32mmw [%s]\033[33m\` to sync your mail.\033[0m\\n" "$mwacc"
  231. fi
  232. }
  233. _mwconfirm() {
  234. printf "[y/N]: Do you want to %s?\\n\t" "$@" && read -r mwinput && ! echo "$mwinput" | grep -i "^y$\|^yes$" >/dev/null && printf "That doesn't seem like a yes to me.\\n\\n" && return 1
  235. return 0 ;
  236. }
  237. _mwpick() {
  238. printf "Select an accounts to %s:\\n" "$1"
  239. _mwlist
  240. [ -z "$mwpick" ] && read -r mwpick
  241. mwidnum="$mwpick"
  242. [ -z "$mwidnum" ] && return 1
  243. mwaddr="$(echo "$mwaccs" | grep "$mwidnum:" | sed "s/\.mwonofftype\./ /" | awk '{print $2}')"
  244. mwtype="$(echo "$mwaccs" | grep "$mwidnum:" | sed "s/\.mwonofftype\./ /" | awk '{print $3}')"
  245. _mwaddrmwtype
  246. [ -z "$mwacc" ] && printf "Invalid response." && return 1
  247. return 0 ;
  248. }
  249. _mwdelete() {
  250. rm -f "$mwaccmuttrc"
  251. rm -f "$mwgetmaildir/$mwaddr"
  252. sed -i "/$mwaccmuttrc/d" "$mwmuttrc"
  253. if [ "$mwtype" = "offline" ]; then
  254. sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
  255. sed -i "/account $mwacc/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
  256. else
  257. rm -rf "$mwacccachedir"
  258. fi
  259. }
  260. _mwcron() {
  261. ! pgrep cron >/dev/null && echo "No cron manager running. Install/enable one and then select this option again." && return 1
  262. if crontab -l | grep "mw sync" >/dev/null; then
  263. echo "Active mail sync cronjob detected. Do you want to remove it?"
  264. printf "\033[36m\t"
  265. [ -z "$mwcronremove" ] && read -r mwcronremove
  266. printf "\033[0m"
  267. echo "$mwcronremove" | grep -i "^y\(es\)*$" >/dev/null && crontab -l | sed '/mw sync/d' | crontab - >/dev/null && echo "Mail sync turned off."
  268. else
  269. echo "How many minutes between each mail sync?"
  270. printf "\033[36m\t"
  271. [ -z $mwcronminutes ] && read -r mwcronminutes
  272. printf "\033[0m"
  273. while ! echo "$mwcronminutes" | grep "^[1-9]\+$" >/dev/null; do
  274. printf "That doesn't look like a number. How many minutes between each mail sync?\\n\033[36m\t"
  275. read -r mwcronminutes
  276. printf "\033[0m"
  277. done
  278. (crontab -l; echo "*/$mwcronminutes * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; $(type mw | cut -d' ' -f3) sync") | crontab - &&
  279. echo "Cronjob added. Mail will sync every $mwcronminutes minutes. Be sure you have your cron manager running."
  280. fi
  281. }
  282. _mwasktype() {
  283. if [ -z "$mwtype" ]; then
  284. while : ; do
  285. printf "[yes/no]: Local mail via mbsync? No: Mutt remotes (slower).\\n"
  286. printf "[pop]: Local mail from POP3 using getmail.\\n\t"
  287. read -r mwoffline
  288. case "$mwoffline" in
  289. [Yy][Ee][Ss]) mwtype="offline" && break ;;
  290. [Nn][Oo]) mwtype="online" && break ;;
  291. [Pp][Oo][Pp]) mwtype="pop" && break ;;
  292. *) echo "Write out either yes or no completely. Try again or press ctrl-c to quit." ;;
  293. esac
  294. done
  295. fi
  296. }
  297. _mwpurge() {
  298. _mwconfirm "delete all account data" || exit
  299. rm -rf "$mwaccmuttdir/[1-9]-.*.muttrc" "${mwmsmtprc%/*}" "${mwmbsyncrc%/*}" "$mwcachedir" "$mwgenmuttaccs"
  300. sed -i "/\# mw-autogenerated/d" "$mwmuttrc"
  301. pgrep cron >/dev/null && crontab -l | sed '/mw sync/d' | crontab - >/dev/null
  302. echo "All configs and account settings have been purged."
  303. }
  304. _mwnotmuchauto() {
  305. [ -z "$NOTMUCH_CONFIG" ] && NOTMUCH_CONFIG="$HOME/.notmuch-config"
  306. [ -f "$NOTMUCH_CONFIG" ] && return 0
  307. mkdir -p "${NOTMUCH_CONFIG%/*}"
  308. cat > "$NOTMUCH_CONFIG" <<EOF
  309. [database]
  310. path=$mwmaildir
  311. [user]
  312. name=$mwname
  313. primary_email=$mwaddr
  314. [new]
  315. tags=unread;inbox;
  316. ignore=
  317. [search]
  318. exclude_tags=deleted;spam;
  319. [maildir]
  320. synchronize_flags=true
  321. [crypto]
  322. gpg_path=$GPG"
  323. EOF
  324. }
  325. #run after mbsync to create mutt settings for $mwaddr
  326. function _genmwaccmuttrc()
  327. {
  328. mwaccmaildir="$mwmaildir/$mwaddr"
  329. mwaccmuttrc="$mwaccmuttdir/$(find "$mwaccmuttdir" -type f | grep -m 1 -o "[1-9]-$mwacc.mwonofftype.$mwtype.muttrc")"
  330. if [[ ! -f "$mwaccmuttrc" ]]; then
  331. # new mwidnum = first one missing
  332. mwaccs="$(find "$mwaccmuttdir" -type f | grep -o "[1-9]-.*.muttrc" | sort -n)"
  333. for mwx in $(seq 1 9); do echo "$mwaccs" | grep "$mwx:" >/dev/null 2>&1 || { export mwidnum="$mwx"; break ;}; done
  334. mwaccmuttrc="$mwaccmuttdir/$mwidnum-$mwacc.mwonofftype.$mwtype.muttrc"
  335. else
  336. mwidnum=${mwaccmuttrc%%-*}
  337. mwidnum=${mwidnum##*/}
  338. fi
  339. ! grep "source $mwaccmuttrc" "$mwgenmuttaccs" >/dev/null && echo "source $mwaccmuttrc" >> $mwgenmuttaccs
  340. mwmailboxes="$(find "$mwaccmaildir/" -name cur | sed "s,$mwaccmaildir/,,g;s,/cur,,")"
  341. [[ "$mwmailboxes" =~ ^[[:space:]]*$ ]] && echo "no mailboxes" && return
  342. mwspoolfile=$(echo "$mwmailboxes" | grep -i -m 1 inbox | sed -ne 's/.*/+\0/p')
  343. [[ "$mwspoolfile" =~ ^[[:space:]]*$ ]] && return
  344. mwrecord=$(echo "$mwmailboxes" | grep -i -m 1 sent | sed -ne 's/.*/+\0/p')
  345. [ -z "$mwrecord" ] && mkdir -p "$mwaccmaildir/Sent/"{cur,new,tmp} && mwrecord="Sent"
  346. mwpostponed=$(echo "$mwmailboxes" | grep -i -m 1 draft | sed -ne 's/.*/+\0/p')
  347. [ -z "$mwpostponed" ] && mkdir -p "$mwaccmaildir/Drafts/"{cur,new,tmp} && mwpostponed="Drafts"
  348. mwtrash=$(echo "$mwmailboxes" | grep -i -m 1 trash | sed -ne 's/.*/+\0/p')
  349. [ -z "$mwtrash" ] && mkdir -p "$mwaccmaildir/Trash/"{cur,new,tmp} && mwtrash="Trash"
  350. mwaccmutt="${mwaddr//[.@]/_}"
  351. mwmuttsync=$(printf '<sync-mailbox><enter-command>source %s<enter><change-folder>!<enter>;<check-stats>' $mwaccmuttrc)
  352. cat > "$mwaccmuttrc" <<EOF
  353. # vim: filetype=muttrc
  354. # muttrc file for account $mwaddr
  355. # generated by mw
  356. set spoolfile = "$mwspoolfile"
  357. set record = "$mwrecord"
  358. set postponed = "$mwpostponed"
  359. set trash = "$mwtrash"
  360. unmailboxes *
  361. mailboxes =$mwaccmutt ===================== $(echo "$mwmailboxes" | sed -e "s/ //g;s/.*/\"=\0\"/g" | tr "\n" " ")
  362. macro index,pager i$mwidnum '$mwmuttsync' "switch to $mwaddr"
  363. set from = "$mwaddr"
  364. set sendmail = "/usr/bin/msmtp -a \$from"
  365. EOF
  366. [[ -n $realname ]] && cat >> "$mwaccmuttrc" <<EOF
  367. set realname = "$mwname"
  368. alias me $mwname <$mwaddr>
  369. EOF
  370. for eqbox in $mwmailboxes; do
  371. box=${eqbox##*/}
  372. box=${box##*.}
  373. boxi=${box::2}
  374. boxi=${boxi,,}
  375. cat >> $mwaccmuttrc <<EOF
  376. macro index,pager i$boxi "<change-folder>=$eqbox<enter>" "go to $box"
  377. macro index,pager M$boxi "<save-message>=$eqbox<enter>" "move mail to $box"
  378. macro index,pager C$boxi "<copy-message>=$eqbox<enter>" "copy mail to $box"
  379. EOF
  380. done
  381. if [ "$mwtype" = "offline" ]; then #can be online when called from mw
  382. cat >> "$mwaccmuttrc" <<EOF
  383. macro index gm "<shell-escape>mw $mwaddr<enter>" "sync mail $mwaddr"
  384. set folder = "$mwaccmaildir"
  385. folder-hook \$folder '$mwmuttsync'
  386. EOF
  387. fi
  388. }
  389. if [ "$(uname)" = "Darwin" ]; then
  390. _mwnotify() { osascript -e "display notification \"$2 in $1\" with title \"You've got Mail\" subtitle \"Account: $1\"" & ;}
  391. else
  392. if command -v notify-send >/dev/null; then
  393. _mwnotify() { notify-send "mutt-wizard" "📬 $2 new mail(s) in \`$1\` account." &;}
  394. else
  395. _mwnotify() { echo "mutt-wizard: 📬 $2 new mail(s) in \`$1\` account." ;}
  396. fi
  397. function _mwaddr()
  398. {
  399. mwaddr=$1
  400. mwaddr=${mwaddr/#\~/$HOME}
  401. mwaddr=${mwaddr#$mwmaildir/}
  402. mwaddr=${mwaddr%%/*}
  403. mkdir -p $mwmaildir/$mwaddr
  404. }
  405. function _mwgatheremails()
  406. {
  407. unset mwemails
  408. ! grep "source $mwgenmuttaccs" "$mwmuttrc" >/dev/null && echo "source $mwgenmuttaccs # mw-autogenerated" >> "$mwmuttrc"
  409. cat > "$mwgenmuttaccs" <<EOF
  410. # vim: filetype=muttrc
  411. # generated by mw
  412. macro index gM '<shell-escape>mw<enter>' "sync all mail"
  413. EOF
  414. if [[ -f $mwmbsyncrc ]]; then
  415. for store in $(sed -ne 's/^Path\s*//p' $mwmbsyncrc); do
  416. _mwaddr "$store"
  417. mwemails+=" $mwaddr"
  418. done
  419. fi
  420. if [[ -d $mwgetmaildir ]]; then
  421. for gmrc in $mwgetmaildir/*; do
  422. store=$(sed -ne "s/^path\s*=\s*//p" $gmrc)
  423. store=${store/#\~/$HOME}
  424. _mwaddr "$store"
  425. mkdir -p "$store"/{cur,new,tmp}
  426. mwemails+=" $mwaddr"
  427. done
  428. fi
  429. }
  430. _mwsyncandnotify() {
  431. mwaccmaildir="$mwmaildir/$mwaddr"
  432. if [[ -f "$mwgetmaildir/$mwaddr" ]]; then
  433. $mwgetmailbin --rcfile=$mwaddr --getmaildir=$mwgetmaildir
  434. else
  435. $mwmbsyncbin $mwaddr
  436. fi
  437. mwlastrun="$mwaccmaildir/.mw.lastrun"
  438. mwnew=$(find "$mwaccmaildir/INBOX/new/" "$mwaccmaildir/Inbox/new/" "$mwaccmaildir/inbox/new/" -type f -newer "$mwlastrun" 2> /dev/null)
  439. newcount=$(echo "$mwnew" | sed '/^\s*$/d' | wc -l)
  440. if [ "$newcount" -gt "0" ]; then
  441. _mwnotify "$mwaddr" "$newcount"
  442. for file in $mwnew; do
  443. # Extract subject and sender from mail.
  444. from=$(awk '/^From: / && ++n ==1,/^\<.*\>:/' "$file" | perl -CS -MEncode -ne 'print decode("MIME-Header", $_)' | awk '{ $1=""; if (NF>=3)$NF=""; print $0 }' | sed 's/^[[:blank:]]*[\"'\''\<]*//;s/[\"'\''\>]*[[:blank:]]*$//')
  445. subject=$(awk '/^Subject: / && ++n == 1,/^\<.*\>: / && ++i == 2' "$file" | head -n-1 | perl -CS -MEncode -ne 'print decode("MIME-Header", $_)' | sed 's/^Subject: //' | sed 's/^{[[:blank:]]*[\"'\''\<]*//;s/[\"'\''\>]*[[:blank:]]*$//' | tr -d '\n')
  446. _mwnotify "📧$from:" "$subject"
  447. done
  448. fi
  449. touch "$mwlastrun"
  450. }
  451. function _mwsyncemails()
  452. {
  453. for mwaddr in $mwemails; do
  454. _mwsyncandnotify
  455. done
  456. rm $XDG_CONFIG_HOME/getmail/oldmail-* &>/dev/null
  457. echo notmuch+afew ...
  458. notmuch new &>/dev/null
  459. #notmuch also created afew MailMover target mailboxes
  460. }
  461. function _mwmuttemails()
  462. {
  463. for mwaddr in $mwemails; do
  464. _genmwaccmuttrc
  465. done
  466. }
  467. _mwcheckinternet()
  468. {
  469. # Checks for internet connection
  470. if command -v systemctl >/dev/null; then
  471. if ! systemctl --type service | grep net | grep active > /dev/null; then
  472. echo "No internet connection."
  473. return 1
  474. fi
  475. else
  476. if ! ping -q -c 1 1.1.1.1 > /dev/null;
  477. echo "No internet connection (ping failed)."
  478. return 1
  479. fi
  480. fi
  481. }
  482. function _mwsync()
  483. {
  484. unset mwemails
  485. # Run only if user logged in (prevent cron errors)
  486. if ! pgrep -u "$USER" >/dev/null; then
  487. echo "$USER not logged in; sync will not run."
  488. return 1 ;
  489. fi
  490. # Run only if not already running in other instance
  491. if pgrep -x mbsync >/dev/null; then
  492. echo "mbsync is running."
  493. return 1
  494. fi
  495. if pgrep -x notmuch >/dev/null; then
  496. echo "notmuch is running."
  497. return 1
  498. fi
  499. _mwcheckinternet || return 1
  500. _mwaddr "$1"
  501. mwemails="$mwaddr"
  502. [[ $mwemails == "" ]] && _mwgatheremails && _mwsyncemails && _mwmuttemails && return 0
  503. _mwsyncemails
  504. return 0
  505. }
  506. trap 'echo -e "\033[0m\n"; exit' STOP INT ABRT KILL
  507. if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
  508. if [ "$#" -gt 1 ]; then
  509. echo "Command or email or no parameter (=sync all). See --help."
  510. return 1
  511. fi
  512. command -V gpg >/dev/null 2>&1 && GPG="gpg" || GPG="gpg2"
  513. [ -z "$PASSWORD_STORE_DIR" ] && PASSWORD_STORE_DIR="$HOME/.password-store"
  514. [ -r "$PASSWORD_STORE_DIR/.gpg-id" ] &&
  515. "$GPG" --list-secret-keys $(cat "$PASSWORD_STORE_DIR/.gpg-id") >/dev/null 2>&1 || {
  516. printf "\`pass\` must be installed and initialized to encrypt passwords.\\nBe sure it is installed and run \`pass init <yourgpgemail>\`.\\nIf you don't have a GPG public private key pair, run \`$GPG --full-gen-key\` first.\\n"
  517. exit
  518. }
  519. ! command -v "$prefix/bin/mbsync" >/dev/null && printf "\`mbsync\` must be installed to run mutt-wizard.\\n" && exit
  520. ! command -v "$prefix/bin/msmtp" >/dev/null && printf "\`msmtp\` must be installed.\\n" && exit
  521. ! ( command -v mutt >/dev/null || command -v neomutt >/dev/null ) && printf "\`mutt\` must be installed.\\n" && exit
  522. case "$1" in
  523. ls) _mwlist ;;
  524. add) _mwadd ;;
  525. pass) _mwpick "change the password of" && _mwgetpass ;;
  526. delete) _mwpick delete && _mwconfirm "delete the \`$mwacc\` profile" && _mwdelete ;;
  527. purge) _mwpurge ;;
  528. cron) _mwcron ;;
  529. sync) _mwsync ;;
  530. *@*) _mwsync $1 ;;
  531. --help|-h) cat << EOF
  532. mw: mutt-wizard, auto-configure and sync email accounts for mutt,
  533. including mutt-independent sync of mail with \`isync\` or download of pop3 mail with \`getmail\`.
  534. Commands:
  535. add Add and autoconfigure an email address (9 max.)
  536. ls List configured accounts
  537. delete Pick an account to delete
  538. purge Delete all accounts and settings
  539. cron Enable or disable an autosync via cronjob
  540. sync sync/download mail based on config in $mwmbsyncrc and $mwgetmaildir
  541. --help|-h Print this message
  542. With no parameter all configured emails are synced and all account muttrc's are created.
  543. With a parameter containing a @, an mail is assumed and that account is synced.
  544. Config requirements:
  545. - mbsyncrc: "Path" ends in email
  546. - getmail: config file name = email, "path" ends in email
  547. EOF
  548. esac
  549. exit $?
  550. fi