| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- (in-package :cl-user)
- (defpackage chatikbot.poller
- (:use :cl :chatikbot.db :chatikbot.utils :chatikbot.secrets)
- (:export :*poller-token*
- :*poller-module*
- :rest-parameters
- :poller-request
- :poller-validate
- :poller-authenticate
- :poller-error
- :poller-no-secret
- :poller-cant-authenticate
- :poller-call
- :poller-poll-lists))
- (in-package :chatikbot.poller)
- (defvar *tokens* (make-hash-table) "Module's tokens store")
- (defvar *state* (make-hash-table) "Module's state store")
- (defvar *poller-token* nil "Current user's API token")
- (defvar *poller-module* nil "Current module")
- (defun rest-parameters (rest)
- (loop for (param value) on rest by #'cddr
- when value collect (cons (dekeyify param) value)))
- (defun get-data (store chat-id &optional (module *poller-module*))
- (let ((module-store (gethash module store)))
- (when module-store (gethash chat-id module-store))))
- (defun set-data (store chat-id data &optional (module *poller-module*))
- (let ((module-store (or (gethash module store)
- (setf (gethash module store)
- (make-hash-table)))))
- (setf (gethash chat-id module-store) data)))
- (defgeneric poller-request (module method &rest params)
- (:documentation "Performs api request to module"))
- (defgeneric poller-validate (module response)
- (:documentation "Performs api result validation"))
- (defgeneric poller-authenticate (module secret)
- (:documentation "Performs api request to module"))
- (define-condition poller-error (error) ())
- (define-condition poller-no-secret (poller-error) ())
- (define-condition poller-cant-authenticate (poller-error) ())
- (defun poller-call (module method &rest params)
- (let* ((chat-id *chat-id*)
- (*poller-module* module)
- (*poller-token* (get-data *tokens* chat-id module))
- (response (apply 'poller-request module method params)))
- (if (poller-validate module response) response
- (with-secret (secret (list module chat-id))
- (unless secret (error 'polller-no-secret))
- (let ((*poller-token* (poller-authenticate module secret)))
- (unless *poller-token* (error 'poller-cant-authenticate))
- (set-data *tokens* chat-id *poller-token* module)
- (values (apply 'poller-request module method params)))))))
- (defun poller-poll-lists (module get-state-fn process-diff-fn &key (test #'equalp) (predicate #'<) key (max-store 200))
- (dolist (*chat-id* (lists-get module))
- (let* ((old (get-data *state* *chat-id* module))
- (new (funcall get-state-fn))
- (diff (sort (set-difference new old :test test)
- predicate :key key)))
- (when diff
- (when old
- (funcall process-diff-fn diff))
- (let ((merged (merge 'list old diff predicate :key key)))
- (set-data *state* *chat-id*
- (subseq merged (max (- (length merged) max-store) 0))
- module))))))
|