|
@@ -0,0 +1,64 @@
|
|
|
|
|
+(in-package #:chatikbot)
|
|
|
|
|
+
|
|
|
|
|
+(defvar *nalunch-username* nil "Username")
|
|
|
|
|
+(defvar *nalunch-password* nil "Password")
|
|
|
|
|
+(defvar *nalunch-cookie-jar* (make-instance 'drakma:cookie-jar) "Cookie storage")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+(defparameter +mobile-ua+ "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.114 Mobile Safari/537.36"
|
|
|
|
|
+ "Mobile UA")
|
|
|
|
|
+(defparameter +nalunch-mobile+ (puri:uri "https://www.nalunch.ru/Mobile/"))
|
|
|
|
|
+(defparameter +nalunch-login+ (puri:uri "https://www.nalunch.ru/Mobile/Account/Login"))
|
|
|
|
|
+
|
|
|
|
|
+(defun nalunch-auth (&optional body)
|
|
|
|
|
+ (let* ((body (or body
|
|
|
|
|
+ (drakma:http-request +nalunch-login+ :cookie-jar *nalunch-cookie-jar* :user-agent +mobile-ua+)))
|
|
|
|
|
+ (dom (plump:parse body))
|
|
|
|
|
+ (form (plump:get-element-by-id dom "LoginForm"))
|
|
|
|
|
+ (parameters
|
|
|
|
|
+ (loop for input in (get-by-tag form "input")
|
|
|
|
|
+ for name = (plump:get-attribute input "name")
|
|
|
|
|
+ for value = (plump:get-attribute input "value")
|
|
|
|
|
+ when (and name value) collect (cons name value)
|
|
|
|
|
+ when (string= name "UserName") collect (cons name *nalunch-username*)
|
|
|
|
|
+ when (string= name "Password") collect (cons name *nalunch-password*)))
|
|
|
|
|
+ (response (drakma:http-request +nalunch-login+
|
|
|
|
|
+ :method :post
|
|
|
|
|
+ :parameters parameters
|
|
|
|
|
+ :cookie-jar *nalunch-cookie-jar*
|
|
|
|
|
+ :user-agent +mobile-ua+)))
|
|
|
|
|
+ (when (search "id=\"LoginForm\"" response)
|
|
|
|
|
+ (error "Bad username or password"))
|
|
|
|
|
+ response))
|
|
|
|
|
+
|
|
|
|
|
+(defun nalunch-recent ()
|
|
|
|
|
+ (multiple-value-bind (body status headers uri)
|
|
|
|
|
+ (drakma:http-request +nalunch-mobile+ :cookie-jar *nalunch-cookie-jar* :user-agent +mobile-ua+)
|
|
|
|
|
+ (declare (ignore status headers))
|
|
|
|
|
+ (let* ((body (if (puri:uri= uri +nalunch-mobile+)
|
|
|
|
|
+ body
|
|
|
|
|
+ (nalunch-auth body)))
|
|
|
|
|
+ (dom (plump:parse body))
|
|
|
|
|
+ (balance (parse-integer (plump:text (elt (clss:select ".newswire-header_balance" dom) 0))))
|
|
|
|
|
+ (recent (loop for day across (clss:select ".day-feed" dom)
|
|
|
|
|
+ append (loop for el across (clss:select ".media" day)
|
|
|
|
|
+ for date = (select-text ".day-feed_date" day)
|
|
|
|
|
+ for time = (select-text ".transaction_time" el)
|
|
|
|
|
+ for price = (parse-integer (select-text ".transaction_price" el))
|
|
|
|
|
+ for place = (select-text ".transaction-title" el)
|
|
|
|
|
+ collect (list (cons :time (format nil "~A ~A" date time))
|
|
|
|
|
+ (cons :price price)
|
|
|
|
|
+ (cons :place place))))))
|
|
|
|
|
+
|
|
|
|
|
+ (list (cons :balance balance)
|
|
|
|
|
+ (cons :recent recent)))))
|
|
|
|
|
+
|
|
|
|
|
+(defun nalunch-format (result &optional last)
|
|
|
|
|
+ (let* ((balance (aget :balance result))
|
|
|
|
|
+ (all (aget :recent result))
|
|
|
|
|
+ (recent (cons (car all) (unless last (cdr all)))))
|
|
|
|
|
+ (format nil "🍴 Баланс ~A руб.~{~&~A~}"
|
|
|
|
|
+ balance
|
|
|
|
|
+ (mapcar (lambda (meal) (format nil "~A @ ~A — ~A руб."
|
|
|
|
|
+ (aget :time meal) (aget :place meal) (aget :price meal)))
|
|
|
|
|
+ recent))))
|