ledger.lisp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. (in-package :cl-user)
  2. (defpackage chatikbot.plugins.ledger
  3. (:use :cl :chatikbot.common))
  4. (in-package :chatikbot.plugins.ledger)
  5. (eval-when (:compile-toplevel :load-toplevel :execute)
  6. (ql:quickload :pta-ledger))
  7. (defsetting *ledger/default-timezone* -3 "Default timezone for time display. GMT+3")
  8. (defvar *ledger/chat-journals* (make-hash-table))
  9. (defun ledger/get-hook-url (chat-id url)
  10. (declare (ignore url))
  11. (get-webhook-url "ledger" chat-id (token-hmac (write-to-string chat-id))))
  12. (defun ledger/parse-uri (chat-id uri)
  13. (setf (gethash chat-id *ledger/chat-journals*)
  14. (cons (pta-ledger:parse-journal (http-request uri))
  15. (get-universal-time))))
  16. (defun ledger/format-uri (url)
  17. (let ((uri (quri:uri url)))
  18. (quri:render-uri (quri:make-uri :userinfo (when (quri:uri-userinfo uri) "*:*")
  19. :defaults url))))
  20. (defun ledger/handle-set-uri (chat-id uri)
  21. (handler-case
  22. (destructuring-bind (journal . ut)
  23. (ledger/parse-uri chat-id uri)
  24. (declare (ignore ut))
  25. (secret-set (list :ledger chat-id) uri)
  26. (send-response chat-id (format nil "Добавил журнал с ~D записями. Веб-хук для обновления: ~A"
  27. (length journal)
  28. (ledger/get-hook-url chat-id uri))))
  29. (pta-ledger:journal-failed (e)
  30. (send-response chat-id (format nil "Не смог спарсить: ~A" e)))
  31. (dex:http-request-failed (e)
  32. (send-response chat-id (format nil "Не смог в урл: ~A" (dex:response-body e))))))
  33. (defun ledger/format-time (universal-time)
  34. (when universal-time
  35. (multiple-value-bind (sec min hour day month year dow dst-p tz)
  36. (decode-universal-time universal-time *ledger/default-timezone*)
  37. (declare (ignore dow dst-p tz))
  38. (format nil "~4,'0D-~2,'0D-~2,'0D ~2,'0D:~2,'0D:~2,'0D"
  39. year month day hour min sec))))
  40. (defun ledger/handle-info (chat-id)
  41. (with-secret (uri (list :ledger chat-id))
  42. (if uri
  43. (destructuring-bind (journal . ut)
  44. (or (gethash chat-id *ledger/chat-journals*)
  45. (ledger/parse-uri chat-id uri))
  46. (bot-send-message chat-id (format nil "Журнал с ~D записями, из ~A, обновлён ~A.~%Веб-хук: ~A"
  47. (length journal)
  48. (ledger/format-uri uri)
  49. (ledger/format-time ut)
  50. (ledger/get-hook-url chat-id uri))
  51. :disable-web-preview t))
  52. (send-response chat-id "Добавь урл журнала, /ledger <url>"))))
  53. (def-message-cmd-handler handler-ledger (:ledger)
  54. (cond
  55. ((= 1 (length args)) (ledger/handle-set-uri chat-id (car args)))
  56. (:otherwise (ledger/handle-info chat-id))))
  57. (defun ledger/handle-balance (chat-id query)
  58. (let ((pair (gethash chat-id *ledger/chat-journals*)))
  59. (if pair
  60. (destructuring-bind (journal . ut) pair
  61. (bot-send-message chat-id (format nil "```~%~A~%```Обновлено: ~A"
  62. (pta-ledger:journal-balance journal query)
  63. (ledger/format-time ut))
  64. :parse-mode "markdown"))
  65. (with-secret (uri (list :ledger chat-id))
  66. (if uri
  67. (progn (ledger/parse-uri chat-id uri)
  68. (ledger/handle-balance chat-id query))
  69. (send-response chat-id "Добавь урл журнала, /ledger <url>"))))))
  70. (def-message-cmd-handler handler-balance (:balance :bal)
  71. (cond
  72. ((null args) (ledger/handle-balance chat-id "assets"))
  73. (:otherwise (ledger/handle-balance chat-id (spaced args)))))
  74. (def-webhook-handler ledger/handle-webhook ("ledger")
  75. (when (= 2 (length paths))
  76. (destructuring-bind (chat-id hmac) paths
  77. (let ((true-hmac (token-hmac chat-id)))
  78. (when (string= true-hmac hmac)
  79. (with-secret (uri (list :ledger chat-id))
  80. (when uri
  81. (ledger/parse-uri (parse-integer chat-id) uri))))))))