notify-tasks.hy 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/env hy
  2. (import json)
  3. (import time [sleep])
  4. (import threading [Thread])
  5. (import datetime [datetime])
  6. (import subprocess [run PIPE DEVNULL])
  7. (setv notified-tasks #{})
  8. (defn notify-send [title desc [time 0] [actions []]]
  9. (let [cmd ["notify-send" title desc "-t" (str time)]]
  10. (for [action actions]
  11. (list.append cmd "-A")
  12. (list.append cmd action))
  13. (let [result (run cmd :stdout PIPE :text True)]
  14. (try
  15. (int result.stdout)
  16. (except [ValueError]
  17. None)))))
  18. (defn get-tasks []
  19. (let [todo-proc (run ["todo" "--porcelain" "list"]
  20. :stdout PIPE
  21. :text True)]
  22. (json.loads todo-proc.stdout)))
  23. (defn mark-task-done [task]
  24. (run ["todo" "done" (str (get task "id"))]
  25. :stdout DEVNULL))
  26. (defn hash-task [task]
  27. (hash (+ (str (get task "start"))
  28. (str (get task "due"))
  29. (str (get task "description"))
  30. (str (get task "summary")))))
  31. (defn notify-task [task timestamp message]
  32. (let [summary (get task "summary")
  33. time-obj (datetime.fromtimestamp timestamp)
  34. time-str (datetime.strftime time-obj "%Y/%m/%d %H:%M")
  35. result (notify-send
  36. (if summary summary "No Summary")
  37. (+ "Task " message " at " time-str)
  38. :actions
  39. ["Mark Done"])]
  40. (when (= result 0)
  41. (mark-task-done task))))
  42. (defn get-notify-time-and-message [task]
  43. (if (is-not (get task "start") None)
  44. #("Starts" (get task "start"))
  45. #("Due" (get task "due"))))
  46. (defn notify-tasks [tasks]
  47. (global notified-tasks)
  48. (let [now (int (datetime.timestamp (datetime.now)))
  49. notified #{}]
  50. (for [task tasks]
  51. (let [[message time] (get-notify-time-and-message task)]
  52. (when (and (not (get task "completed"))
  53. (is-not time None)
  54. (<= (- time now) 300))
  55. (let [task-hash (hash-task task)]
  56. (when (not-in task-hash notified-tasks)
  57. (Thread.start (Thread :target notify-task
  58. :args #(task time message))))
  59. (set.add notified task-hash)))))
  60. (setv notified-tasks notified)))
  61. (while True
  62. (notify-tasks (get-tasks))
  63. (sleep 60))