diff --git a/notify-mail.hy b/notify-mail.hy new file mode 100755 index 0000000..e60e099 --- /dev/null +++ b/notify-mail.hy @@ -0,0 +1,115 @@ +#!/usr/bin/env hy + +(import subprocess [run PIPE DEVNULL]) +(import threading [Thread]) +(import enum [StrEnum]) +(import os [path]) +(import json) +(import shutil) + +(defclass OutputType [StrEnum] + (setv LINES "text" + JSON "json")) + +(defn notmuch [#* args [output OutputType.LINES]] + (let [result (run ["notmuch" + #* args] + :stdout (if (is-not output None) + PIPE + DEVNULL) + :text True)] + (match output + OutputType.LINES (str.splitlines result.stdout) + OutputType.JSON (let [json-root (json.loads result.stdout)] + (if (!= (len json-root) 0) + (. json-root [0] [0] [(slice None -1)]) + []))))) + +(defclass Message [] + (setv uid None + mail-root None + sender None + subject None + file None + attachment? False + notified? False + read? False) + (defn __init__ [self uid mail-root sender subject + file attachment? notified? read?] + (setv self.uid uid + self.mail-root mail-root + self.sender sender + self.subject subject + self.file file + self.attachment? attachment? + self.notified? notified? + self.notified? read?)) + (defn tag [self #* tags] + (when (is self.uid None) + (raise (ValueError "uid is None"))) + (notmuch "tag" #* tags (+ "id:" self.uid))) + (defn move [self dest] + (let [name (path.basename self.file) + new_path (+ mail-root "/" dest "/cur/" name)] + (shutil.move msg.file new_path))) + (defn from-json [root mail-root] + (let [uid (get root "id") + headers (get root "headers") + sender (parse-from-address (get headers "From")) + subject (get headers "Subject") + file (. root ["filename"] [0]) + tags (get root "tags") + attachment? (in "attachment" tags) + notified? (not-in "notnotified" tags) + read? (not-in "unread" tags)] + (Message uid mail-root sender subject file attachment? notified? read?))) + (defn __str__ [self] + (+ "Message From \"" self.sender "\": " self.subject + " (" + (if self.attachment? "attachment " "") + (if self.notified? "" "un") "notified " + (if self.read? "" "un") "read" + ")"))) + +(defn parse-from-address [header] + (try + (let [index (str.index header "<")] + (get header (slice 1 (- index 2)))) + (except [ValueError] + header))) + +(defn notify-send [title desc [time 0] [actions []]] + (let [cmd ["notify-send" title desc "-t" (str time)]] + (for [action actions] + (cmd.append "-A") + (cmd.append action)) + (let [result (run cmd :stdout PIPE :text True)] + (try + (int result.stdout) + (except [ValueError] + None))))) + +(defn notify-message [msg] + (let [result (notify-send (+ (if msg.attachment? "󰈙 " "") + "New mail from " msg.sender) + msg.subject + :time 10000 + :actions ["Mark Read" "Delete"])] + (match result + 0 (msg.tag "-unread") + 1 (do + (msg.tag "-unread") + (msg.move "Trash"))))) + +(let [mail-root (get (notmuch "config" "get" "database.mail_root") 0) + json-root (notmuch "show" "--format=json" "--body=false" + "tag:notnotified" "and" + "tag:unread" "and" + "folder:Inbox" + :output OutputType.JSON)] + (for [msg-json json-root] + (let [msg (Message.from-json msg-json mail-root)] + (Thread.start (Thread :target notify-message + :args #(msg)))))) + +(notmuch "tag" "-notnotified" "*") diff --git a/notmuch-post.sh b/notmuch-post.sh new file mode 100755 index 0000000..308b7cd --- /dev/null +++ b/notmuch-post.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env zsh + +notmuch tag -deleted not folder:Trash +notmuch tag +deleted folder:Trash + +notmuch tag -spam not folder:Spam +notmuch tag +spam folder:Spam + +notmuch tag -starred not folder:Starred + +hy ~/scripts/notify-mail.hy + +notmuch tag +deleted folder:Trash diff --git a/notmuch-pre.sh b/notmuch-pre.sh new file mode 100755 index 0000000..ef79d92 --- /dev/null +++ b/notmuch-pre.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env zsh + +local mail_root="$(notmuch config get database.mail_root)" + +# copy-by-query [query...] +copy-by-query() { + for old_file in $(notmuch search --output=files not folder:Starred \ + and not folder:Sent \ + and not folder:Drafts \ + and not folder:"${1}" and ${@:2}); do + local name="$(basename "${old_file}")" + local new_file="${mail_root}/${1}/cur/${name}" + cp "${old_file}" "${new_file}" + done +} + +copy-by-query Starred tag:starred