Browse Source

[zsd] cron and minor improvements

Innocenty Enikeew 8 năm trước cách đây
mục cha
commit
789b1ae8bb
3 tập tin đã thay đổi với 74 bổ sung19 xóa
  1. 18 1
      db.lisp
  2. 51 18
      plugins/zsd.lisp
  3. 5 0
      utils.lisp

+ 18 - 1
db.lisp

@@ -45,7 +45,9 @@
 (defun db-init ()
   (with-db (db)
     (db-execute "create table if not exists settings (var, val)")
-    (db-execute "create unique index if not exists settings_var_unique on settings (var)")))
+    (db-execute "create unique index if not exists settings_var_unique on settings (var)")
+    (db-execute "create table if not exists lists (list, entry)")
+    (db-execute "create unique index if not exists lists_unique on lists (list, entry)")))
 
 (defun load-settings ()
   (let ((*package* (find-package :chatikbot)))
@@ -62,3 +64,18 @@
                     (write-to-string value))
         (setf (symbol-value symbol) value))
     (error (e) (log:error e))))
+
+(defun lists-set-entry (list entry &optional (add t))
+  (with-db (db)
+    (handler-case
+        (if add
+            (db-execute "insert into lists (list, entry) values (?, ?)"
+                        (dekeyify list) entry)
+            (db-execute "delete from lists where list = ? and entry = ?"
+                        (dekeyify list) entry))
+      (sqlite:sqlite-constraint-error ()
+        nil))))
+
+(defun lists-get (list)
+  (with-db (db)
+    (mapcar #'car (db-select "select entry from lists where list = ?" (dekeyify list)))))

+ 51 - 18
plugins/zsd.lisp

@@ -45,30 +45,63 @@
          (place (aget "place" item))
          (cdt (aget "cdt" item)))
     (case event
-      (1 (format nil "_~A_ *~a*: 🚗 ~a, ~a → ~a" cdt amount (or alias pan) entry place))
-      (101 (format nil "_~A_ *~a*: 💶 ~a" cdt amount place)))))
+      (1 (format nil "~A *~aр.*: 🚗 ~a, _~a → ~a_" cdt amount (or alias pan) entry place))
+      (101 (format nil "~A *~aр.*: 💶 _~a_" cdt amount place)))))
 
 (defun zsd/format-changes (old new)
   (let ((wall-diff (set-difference (aget "wall" new) (aget "wall" old) :test #'equal)))
     (when wall-diff
-      (format nil "ZSD balance: *~A*~%~%~{~A~^~%~}"
-              (aget "remainder" (car (aget "contract" new)))
+      (format nil "ЗСД остаток: *~$р.*~%~%~{~A~^~%~}"
+              (parse-float (aget "remainder" (car (aget "contract" new))))
               (loop for item in (reverse wall-diff)
                  collect (%zsd/format-wall item (aget "pan" new)))))))
 
+(defun zsd/handle-set-cron (chat-id enable)
+  (lists-set-entry :zsd chat-id enable)
+  (bot-send-message chat-id
+                    (if enable
+                        "Включил рассылку. '/zsd off' чтобы выключить, /zsd - показать последние."
+                        "Без рассылки. '/zsd on' - включить, /zsd - последние.")))
+
+(defun zsd/handle-auth (chat-id login pass)
+  (bot-send-message chat-id
+                    (let ((token (zsd/auth login pass)))
+                      (if token
+                          (progn
+                            (secret/set `(:zsd ,chat-id) token)
+                            (zsd/handle-set-cron chat-id t))
+                          "Чот не смог, пропробуй другие."))))
+
+(defun zsd/handle-recent (chat-id)
+  (secret/with (token (list :zsd chat-id))
+    (bot-send-message chat-id
+                      (if token
+                          (let ((data (zsd/load-data token)))
+                            (if data
+                                (zsd/format-changes nil data)
+                                "Не смог получить данные. Попробуй перелогинься. /zsd <login> <pass>"))
+                          "Нужен логин-пароль. /zsd <login> <pass>")
+                      :parse-mode "markdown")))
+
 (def-message-cmd-handler handle-cmd-zsd (:zsd)
-  (secret/with (token `(:zsd ,chat-id))
-    (if token
-        (bot-send-message chat-id (zsd/format-changes nil (zsd/load-data token)) :parse-mode "markdown")
-        (send-response chat-id "/zsd-auth"))))
+  (cond
+    ((= 1 (length args))
+     (zsd/handle-set-cron chat-id (equal "on" (car args))))
+    ((= 2 (length args)) (apply 'zsd/handle-auth chat-id args))
+    (:otherwise (zsd/handle-recent chat-id))))
 
-(def-message-cmd-handler handle-cmd-zsd-auth (:zsd-auth)
-  (destructuring-bind (login password) args
-    (if (and login password)
-        (let ((token (zsd/auth login password)))
-          (if token
-              (progn
-                (secret/set `(:zsd ,chat-id) token)
-                (bot-send-message chat-id (zsd/format-changes nil (zsd/load-data token)) :parse-mode "markdown"))
-              (send-response chat-id "Can't auth")))
-        (send-response chat-id "Usage: /zsd-auth <username> <password>"))))
+(defvar *zsd/last-results* (make-hash-table) "Last check results")
+(defcron process-zsd (:minute '(member 0 10 20 30 40 50))
+  (dolist (chat-id (lists-get :zsd))
+    (secret/with (token (list :zsd chat-id))
+      (if token
+          (let ((old (gethash chat-id *zsd/last-results*))
+                (new (zsd/load-data token)))
+            (when new
+              (when old
+                (alexandria:when-let ((changes (zsd/format-changes old new)))
+                  (bot-send-message chat-id changes :parse-mode "markdown")))
+              (setf (gethash chat-id *zsd/last-results*) new)))
+          (progn
+            (log:warn "zsd no token for" chat-id)
+            (lists-set-entry :zsd chat-id nil))))))

+ 5 - 0
utils.lisp

@@ -243,6 +243,11 @@ is replaced with replacement."
                                 :format '(:year "-" (:month 2) "-" (:day 2) " "
                                           (:hour 2) ":" (:min 2) ":" (:sec 2))))
 
+(defun parse-float (string)
+  (let ((*read-eval* nil))
+    (with-input-from-string (stream string)
+      (read stream nil nil))))
+
 (defun smart-f (arg &optional digits)
   (with-output-to-string (s)
     (prin1 (cond ((= (round arg) arg) (round arg))