| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- (in-package #:chatikbot)
- (defsetting *transmission-settings* nil "ALIST of (chat-id . url)")
- (defvar *transmission-sessions* nil "ALIST of (url . x-transmission-session-id)")
- (defun transmission-get-session (url)
- (multiple-value-bind (body status headers uri stream)
- (drakma:http-request url :force-binary t :decode-content t)
- (declare (ignore body status uri stream))
- (aget :x-transmission-session-id headers)))
- (defun transmission-set-session (url session-id)
- (set-setting '*transmission-sessions*
- (cons (cons url session-id)
- (remove url *transmission-sessions* :test #'equal :key #'car))))
- (defun transmission-request (url method &rest arguments)
- (let ((session-id (aget url *transmission-sessions*))
- (content
- (with-output-to-string (stream)
- (yason:encode (alexandria:plist-hash-table
- (list "method" (dekeyify method t)
- "arguments" (alexandria:plist-hash-table
- (loop for (key value) on arguments by #'cddr
- when value
- appending (list (dekeyify key) value)))))
- stream))))
- (multiple-value-bind (stream status headers uri http-stream)
- (drakma:http-request url :method :post :content content :content-type "application/json"
- :force-binary t :want-stream t :decode-content t
- :additional-headers (list (cons :x-transmission-session-id session-id)))
- (declare (ignore uri))
- (ecase status
- (200 (unwind-protect
- (progn
- (setf (flex:flexi-stream-external-format stream) :utf-8)
- (let* ((response (yason:parse stream :object-as :alist))
- (result (aget "result" response)))
- (unless (equal "success" result)
- (error result))
- (aget "arguments" response)))
- (ignore-errors (close http-stream))))
- (409 (transmission-set-session url (aget :x-transmission-session-id headers))
- (apply #'transmission-request url method arguments))))))
- (defun transmission-get-torrents (url &optional ids (fields '("id" "name" "status" "percentDone" "eta" "totalSize")))
- (aget "torrents" (transmission-request url :torrent-get :ids ids :fields fields)))
- (defun transmission-add-torrent (url &key filename metainfo)
- (let ((torrent-added (transmission-request url :torrent-add :filename filename :metainfo metainfo)))
- (car (transmission-get-torrents url (list (aget "id" (aget "torrent-added" torrent-added)))))))
- (defun %format-torrent-status (status)
- (case status
- (0 "⏹") ;; Stopped
- (1 "🔂") ;; Check wait
- (2 "🔁") ;; Check
- (3 "⏸") ;; Queued to download
- (4 "▶️") ;; Downloading
- (5 "⏸") ;; Queued to seed
- (6 "⏺") ;; Seeding
- ))
- (defun %format-torrent (torrent)
- (let ((eta (aget "eta" torrent)))
- (format nil "~A ~A ~A (~A)~:[~; (~A%~@[, eta ~A~])~]"
- (aget "id" torrent)
- (%format-torrent-status (aget "status" torrent))
- (aget "name" torrent)
- (format-size (aget "totalSize" torrent))
- (eq 4 (aget "status" torrent))
- (smart-f (* 100 (aget "percentDone" torrent)) 1)
- (when (not (= -1 eta)) (format-interval eta)))))
- (def-message-cmd-handler handle-torrents (:torrents)
- (let ((url (aget chat-id *transmission-settings*)))
- (if url
- (bot-send-message chat-id
- (format nil "~{~A~^~%~}" (mapcar #'%format-torrent
- (transmission-get-torrents url))))
- (bot-send-message chat-id "Бота настрой!"))))
- (defparameter +magnet-regex+ (ppcre:create-scanner "magnet:\\?\\S+"))
- (def-message-handler handle-magnet (message)
- (alexandria:when-let* ((url (aget chat-id *transmission-settings*))
- (magnet (ppcre:scan-to-strings +magnet-regex+ text)))
- (bot-send-message chat-id (%format-torrent (transmission-add-torrent url :filename magnet)))))
- (def-message-handler handle-torrent (message)
- (alexandria:when-let* ((url (aget chat-id *transmission-settings*))
- (doc (aget "document" message))
- (file-name (aget "file_name" doc))
- (file-id (aget "file_id" doc)))
- (when (and (equal "torrent" (pathname-type (pathname file-name)))
- (< (aget "file_size" doc) (* 512 1024)))
- (let ((contents (telegram-file-content file-id)))
- (bot-send-message chat-id (%format-torrent (transmission-add-torrent url :metainfo (cl-base64:usb8-array-to-base64-string contents))))))))
|