random-scripts/notify-mail.hy

122 lines
3.9 KiB
Hy
Raw Normal View History

2023-05-26 06:36:05 -07:00
#!/usr/bin/env hy
(import subprocess [run PIPE DEVNULL])
(import threading [Thread])
(import enum [StrEnum])
(import os [path])
2023-05-26 14:59:27 -07:00
(import re)
2023-05-26 06:36:05 -07:00
(import json)
(import shutil)
2023-05-26 14:59:27 -07:00
(setv global-did-delete False)
2023-05-26 06:36:05 -07:00
(defclass OutputType [StrEnum]
(setv LINES "text"
JSON "json"))
2023-05-26 14:59:27 -07:00
(defn notmuch [#* args [output None]]
2023-05-26 06:36:05 -07:00
(let [result (run ["notmuch"
#* args]
:stdout (if (is-not output None)
PIPE
DEVNULL)
:text True)]
(match output
OutputType.LINES (str.splitlines result.stdout)
2023-05-26 13:27:43 -07:00
OutputType.JSON (json.loads result.stdout))))
2023-05-26 06:36:05 -07:00
(defclass Message []
(setv uid None
mail-root None
sender None
subject None
attachment? False
notified? False
read? False)
(defn __init__ [self uid mail-root sender subject
2023-05-26 14:59:27 -07:00
attachment? notified? read?]
2023-05-26 06:36:05 -07:00
(setv self.uid uid
self.mail-root mail-root
self.sender sender
self.subject subject
self.attachment? attachment?
self.notified? notified?
self.notified? read?))
(defn tag [self #* tags]
(notmuch "tag" #* tags (+ "id:" self.uid)))
(defn move [self dest]
2023-05-26 14:59:27 -07:00
(let [old-path (self.get-filename)
name (re.sub "U=[0-9]+:[0-9]+,([DFPRS]*$)"
r"\1" (path.basename old-path))
new-path (+ self.mail-root "/" dest "/cur/" name)]
(shutil.move old-path new-path)))
(defn get-filename [self]
(get (notmuch "search" "--output=files" (+ "id:" (str self.uid))
:output OutputType.LINES) 0))
2023-05-26 06:36:05 -07:00
(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")
tags (get root "tags")
attachment? (in "attachment" tags)
notified? (not-in "notnotified" tags)
read? (not-in "unread" tags)]
2023-05-26 14:59:27 -07:00
(Message uid mail-root sender subject attachment? notified? read?)))
2023-05-26 06:36:05 -07:00
(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]
2023-05-26 13:41:29 -07:00
(msg.tag "-notnotified")
2023-05-26 06:36:05 -07:00
(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
2023-05-26 14:59:27 -07:00
(setv global-did-delete True)
2023-05-26 06:36:05 -07:00
(msg.tag "-unread")
(msg.move "Trash")))))
2023-05-26 14:59:27 -07:00
(let [mail-root (get (notmuch "config" "get" "database.mail_root"
:output OutputType.LINES) 0)
2023-05-26 06:36:05 -07:00
json-root (notmuch "show" "--format=json" "--body=false"
"tag:notnotified" "and"
"tag:unread" "and"
"folder:Inbox"
:output OutputType.JSON)]
(for [msg-json json-root]
2023-05-26 13:27:43 -07:00
(let [msg (Message.from-json (. msg-json [0] [0]) mail-root)]
2023-05-26 06:36:05 -07:00
(Thread.start (Thread :target notify-message
:args #(msg))))))
(notmuch "tag" "-notnotified" "*")
2023-05-26 14:59:27 -07:00
(when global-did-delete
(notmuch "tag" "+deleted" "folder:Trash")
(notmuch "new" "--no-hooks"))