|
|
@@ -3,43 +3,39 @@
|
|
|
(:use :cl :chatikbot.common))
|
|
|
(in-package :chatikbot.plugins.zsd)
|
|
|
|
|
|
-(defparameter +zsd-api-url+ "https://mcabinet.nch-spb.com/onyma/system/api/json")
|
|
|
-(defparameter +zsd-auth-url+ "https://mcabinet.nch-spb.com/onyma/system/api/jsonex?function=open_session")
|
|
|
+(defparameter +api-uri+ "https://mcabinet.nch-spb.com/onyma/system/api/json")
|
|
|
+(defparameter +auth-uri+ "https://mcabinet.nch-spb.com/onyma/system/api/jsonex?function=open_session")
|
|
|
+(defparameter +method-prefix+ "onm_api_toll_api_")
|
|
|
|
|
|
-(defun %zsd/api (token method &optional args)
|
|
|
- (let* ((f (concatenate 'string "onm_api_toll_api_" method))
|
|
|
- (params (loop for (k . v) in args when v
|
|
|
- collect (cons (princ-to-string k) (princ-to-string v))))
|
|
|
- (response
|
|
|
- (json-request
|
|
|
- +zsd-api-url+
|
|
|
- :parameters (append params `(("function" . ,f)
|
|
|
- ("auth_token" . ,token))))))
|
|
|
- (values (aget "return" response) (aget "more_rows" response))))
|
|
|
+;; poller methods
|
|
|
+(defmethod poller-request ((module (eql :zsd)) method &rest params)
|
|
|
+ (agets (json-request +api-uri+
|
|
|
+ :parameters (append
|
|
|
+ `(("function" . ,(concatenate 'string +method-prefix+ method))
|
|
|
+ ("auth_token" . ,*poller-token*))
|
|
|
+ (rest-parameters params)))
|
|
|
+ "return"))
|
|
|
+(defmethod poller-validate ((module (eql :zsd)) response)
|
|
|
+ response)
|
|
|
+(defmethod poller-authenticate ((module (eql :zsd)) secret)
|
|
|
+ (destructuring-bind (username . password) secret
|
|
|
+ (agets (json-request +auth-uri+ :method :post
|
|
|
+ :content (plist-json (list :realm "WHSD"
|
|
|
+ :user username
|
|
|
+ :pass password)))
|
|
|
+ "return")))
|
|
|
|
|
|
-(defun zsd/auth (login password)
|
|
|
- (aget "return"
|
|
|
- (json-request +zsd-auth-url+ :method :post
|
|
|
- :content (plist-json (list :realm "WHSD"
|
|
|
- :user login
|
|
|
- :pass password)))))
|
|
|
+;; API
|
|
|
+(defun pan ()
|
|
|
+ (poller-call :zsd "mobile_pan"))
|
|
|
|
|
|
-(defun zsd/pan (token)
|
|
|
- (%zsd/api token "mobile_pan"))
|
|
|
+(defun contract ()
|
|
|
+ (poller-call :zsd "contract_info"))
|
|
|
|
|
|
-(defun zsd/contract (token)
|
|
|
- (%zsd/api token "contract_info"))
|
|
|
+(defun wall (&optional (offset 0) (limit 5))
|
|
|
+ (poller-call :zsd "mobile_wall" :rows-skip offset :rows-limit limit))
|
|
|
|
|
|
-(defun zsd/wall (token &optional (offset 0) (limit 5))
|
|
|
- (%zsd/api token "mobile_wall"
|
|
|
- `(("rows_skip" . ,offset) ("rows_limit" . ,limit))))
|
|
|
-
|
|
|
-(defun zsd/load-data (token &optional (limit 5))
|
|
|
- `(("contract" . ,(zsd/contract token))
|
|
|
- ("pan" . ,(zsd/pan token))
|
|
|
- ("wall" . ,(zsd/wall token 0 limit))))
|
|
|
-
|
|
|
-(defun %zsd/format-wall (item pans)
|
|
|
+(defun format-wall (item pans)
|
|
|
(let* ((pan (aget "pan" item))
|
|
|
(alias (aget "alias" (find pan pans :test #'equal :key (lambda (el) (aget "pan" el)))))
|
|
|
(event (parse-integer (aget "event_type" item)))
|
|
|
@@ -51,56 +47,47 @@
|
|
|
(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 "ЗСД остаток: *~$р.*~%~%~{~A~^~%~}"
|
|
|
- (parse-float (aget "remainder" (car (aget "contract" new))))
|
|
|
- (loop for item in wall-diff
|
|
|
- collect (%zsd/format-wall item (aget "pan" new)))))))
|
|
|
+(defun format-changes (wall-diff contract pans)
|
|
|
+ (format nil "ЗСД остаток: *~$р.*~%~%~{~A~^~%~}"
|
|
|
+ (parse-float (aget "remainder" (car contract)))
|
|
|
+ (loop for item in wall-diff
|
|
|
+ collect (format-wall item pans))))
|
|
|
|
|
|
-(defun zsd/handle-set-cron (enable)
|
|
|
+(defcron process-zsd (:minute '(member 0 5 10 15 20 25 30 35 40 45 50 55))
|
|
|
+ (poller-poll-lists :zsd
|
|
|
+ #'wall
|
|
|
+ #'(lambda (diff)
|
|
|
+ (bot-send-message (format-changes diff (contract) (pan))
|
|
|
+ :parse-mode "markdown"))
|
|
|
+ :key #'(lambda (w) (local-time:timestamp-to-universal
|
|
|
+ (local-time:parse-timestring (aget "dt" w))))))
|
|
|
+
|
|
|
+(defun handle-set-cron (enable)
|
|
|
(lists-set-entry :zsd *chat-id* enable)
|
|
|
(bot-send-message (if enable
|
|
|
"Включил рассылку. '/zsd off' чтобы выключить, /zsd - показать последние."
|
|
|
"Без рассылки. '/zsd on' - включить, /zsd - последние.")))
|
|
|
|
|
|
-(defun zsd/handle-auth (login pass)
|
|
|
- (let ((token (zsd/auth login pass)))
|
|
|
- (if token
|
|
|
+(defun handle-auth (login pass)
|
|
|
+ (let ((secret (cons login pass)))
|
|
|
+ (if (poller-authenticate :zsd secret)
|
|
|
(progn
|
|
|
- (secret-set `(:zsd ,*chat-id*) token)
|
|
|
- (zsd/handle-set-cron t))
|
|
|
+ (log:info secret *chat-id*)
|
|
|
+ (secret-set `(:zsd ,*chat-id*) secret)
|
|
|
+ (handle-set-cron t))
|
|
|
(bot-send-message "Чот не смог, пропробуй другие."))))
|
|
|
|
|
|
-(defun zsd/handle-recent ()
|
|
|
- (with-secret (token (list :zsd *chat-id*))
|
|
|
- (bot-send-message (if token
|
|
|
- (let ((data (zsd/load-data token)))
|
|
|
- (if data
|
|
|
- (zsd/format-changes nil data)
|
|
|
- "Не смог получить данные. Попробуй перелогинься. /zsd <login> <pass>"))
|
|
|
- "Нужен логин-пароль. /zsd <login> <pass>")
|
|
|
- :parse-mode "markdown")))
|
|
|
+(defun handle-recent ()
|
|
|
+ (bot-send-message
|
|
|
+ (handler-case
|
|
|
+ (format-changes (wall) (contract) (pan))
|
|
|
+ (poller-error ()
|
|
|
+ "Нужен логин-пароль. /zsd <login> <pass>"))
|
|
|
+ :parse-mode "markdown"))
|
|
|
|
|
|
(def-message-cmd-handler handle-cmd-zsd (:zsd)
|
|
|
(cond
|
|
|
((= 1 (length *args*))
|
|
|
- (zsd/handle-set-cron (equal "on" (car *args*))))
|
|
|
- ((= 2 (length *args*)) (apply 'zsd/handle-auth *args*))
|
|
|
- (:otherwise (zsd/handle-recent))))
|
|
|
-
|
|
|
-(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))
|
|
|
- (with-secret (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 changes :parse-mode "markdown")))
|
|
|
- (setf (gethash *chat-id* *zsd/last-results*) new)))
|
|
|
- (progn
|
|
|
- (log:warn "zsd no token for" *chat-id*))))))
|
|
|
+ (handle-set-cron (equal "on" (car *args*))))
|
|
|
+ ((= 2 (length *args*)) (apply 'handle-auth *args*))
|
|
|
+ (:otherwise (handle-recent))))
|