(in-package :cl-user) (defpackage chatikbot.plugins.aoc (:use :cl :chatikbot.common)) (in-package :chatikbot.plugins.aoc) (defparameter +api-uri+ "https://adventofcode.com/2020/leaderboard/private/view/24158.json") (defparameter +leader-board-link+ "https://adventofcode.com/2020/leaderboard/private/view/24158") (defparameter +advent-time+ (encode-universal-time 0 0 8 25 12 2020 3)) (defmethod poller-request ((module (eql :aoc)) method &rest params) (declare (ignorable params)) (let ((cookie (format nil "session=~a" *poller-token*))) (handler-case (agets (json-request +api-uri+ :headers `((:cookie . ,cookie)))) (dex:http-request-failed (e) e)))) (defmethod poller-validate ((module (eql :aoc)) response) (not (typep response 'dex:http-request-failed))) (defmethod poller-get-token ((module (eql :aoc)) secret) (let* ((*poller-token* secret)) (poller-request :aoc "") (format nil "~a" secret))) (defun leaderboard () (poller-call :aoc "")) (defun get-advent-days-active () (max 0 (min 25 (- 25 (ceiling (/ (- +advent-time+ (get-universal-time)) 86400)))))) (defun format-stars(completions) (format nil "~{~a~^ ~}" (loop for daynum from 1 to (get-advent-days-active) collect (cond ((= 1 (length (agets completions (write-to-string daynum)))) "☆") ((= 2 (length (agets completions (write-to-string daynum)))) "★") (:otherwise "•"))))) (defun format-leaderboard (json) (let ((sorted (sort (loop for (uid . member) in (agets json "members") collect (list (agets member "name") (agets member "local_score") (format-stars (agets member "completion_day_level")))) #'> :key #'second))) (format nil "🏆***Chad AoC Leaderboard***🏆~%~a~%~%~{~a. ~a: ~a ~% ~a~^~%~}" +leader-board-link+ (apply 'append (mapcar #'cons (alexandria:iota (length sorted) :start 1) sorted))))) (defun handle-leaderboard () (bot-send-message (handler-case (format-leaderboard (leaderboard)) (poller-error () "Надо обновить куки, старые истекли")) :parse-mode "markdown")) (defun handle-set-cookie (cookie) (handler-case (progn (poller-authenticate :aoc cookie) (bot-send-message "Кука рабочая, теперь можешь делать запросы.")) (poller-cant-authenticate () (bot-send-message "Чот не смог, пропробуй другие.")))) (def-message-cmd-handler handle-cmd-aoc (:aoc) (cond ((= 1 (length *args*)) (handle-set-cookie (car *args*))) (:otherwise (handle-leaderboard))))