|
|
@@ -5,7 +5,7 @@
|
|
|
#:load-all))
|
|
|
(in-package :chad-music.rym)
|
|
|
|
|
|
-(defvar *cookies* nil "rateyourmusic.com valid cookies")
|
|
|
+(defvar *cookies* (cl-cookie:make-cookie-jar) "rateyourmusic.com valid cookies")
|
|
|
(defparameter +rym-charts-url+ "https://rateyourmusic.com/customchart")
|
|
|
(defparameter +ua+ "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0")
|
|
|
|
|
|
@@ -118,7 +118,7 @@
|
|
|
(defvar *deluge-api* "http://10.8.77.1:8112/json")
|
|
|
(defvar *deluge-password* "deluge")
|
|
|
(defvar *deluge-request-id* 1)
|
|
|
-(defun deluge-request (method &optional params)
|
|
|
+(defun deluge-request (method &optional params is-auth)
|
|
|
(let* ((content (trivial-utf-8:string-to-utf-8-bytes
|
|
|
(jojo:to-json `(:|id| ,(incf *deluge-request-id*)
|
|
|
:|method| ,method
|
|
|
@@ -126,11 +126,17 @@
|
|
|
(response (json-request *deluge-api* :method :post
|
|
|
:content content
|
|
|
:cookie-jar *cookies*))
|
|
|
- (error (getf response :|error|)))
|
|
|
- (when error (error (getf error :|message|)))
|
|
|
- (getf response :|result|)))
|
|
|
+ (error-message (getf (getf response :|error|) :|message|)))
|
|
|
+ (if error-message
|
|
|
+ (if (and (null is-auth)
|
|
|
+ (equal error-message "Not authenticated"))
|
|
|
+ (progn
|
|
|
+ (deluge-auth)
|
|
|
+ (deluge-request method params t)) ;; Retry original request
|
|
|
+ (error error-message))
|
|
|
+ (getf response :|result|))))
|
|
|
(defun deluge-auth ()
|
|
|
- (deluge-request "auth.login" (list *deluge-password*)))
|
|
|
+ (deluge-request "auth.login" (list *deluge-password*) t))
|
|
|
(defun deluge-add-info-hash (info-hashes)
|
|
|
(unless (listp info-hashes)
|
|
|
(setf info-hashes (list info-hashes)))
|
|
|
@@ -142,6 +148,9 @@
|
|
|
(defun deluge-get-torrents ()
|
|
|
(deluge-request "core.get_session_state"))
|
|
|
|
|
|
+(defun deluge-get-torrents-status (filter fields)
|
|
|
+ (deluge-request "core.get_torrents_status" (list filter fields)))
|
|
|
+
|
|
|
(defparameter +deluge-default-status-fields+ '("files" "file_priorities" "save_path"))
|
|
|
(defun deluge-get-torrent-files (info-hash)
|
|
|
(let* ((status (deluge-request "core.get_torrent_status" (list info-hash +deluge-default-status-fields+)))
|
|
|
@@ -152,6 +161,34 @@
|
|
|
(getf file :|path|) (format nil "~A/~A" save-path (getf file :|path|)))
|
|
|
collect file)))
|
|
|
|
|
|
+(defun deluge-get-seeding-torrents ()
|
|
|
+ (loop for (torrent state) on (deluge-get-torrents-status '(:|state| "Seeding") '("name")) by #'cddr
|
|
|
+ collect (cons (string torrent) (getf state :|name|))))
|
|
|
+
|
|
|
+(defun deluge-pause-torrents (&rest torrents)
|
|
|
+ (deluge-request "core.pause_torrent" (list torrents)))
|
|
|
+
|
|
|
+(defun raw-pathname (pathspec)
|
|
|
+ (values (cl-ppcre:regex-replace-all "\\[" pathspec "\\\\[")))
|
|
|
+
|
|
|
+(defun deluge-delete-skipped (torrent &optional dry)
|
|
|
+ (let* ((status (deluge-request "core.get_torrent_status" (list torrent +deluge-default-status-fields+)))
|
|
|
+ (save-path (getf status :|save_path|)))
|
|
|
+ (loop for file in (getf status :|files|)
|
|
|
+ for prio in (getf status :|file_priorities|)
|
|
|
+ for path = (pathname (raw-pathname (format nil "~A/~A" save-path (getf file :|path|))))
|
|
|
+ when (zerop prio)
|
|
|
+ when (probe-file path)
|
|
|
+ do (if dry (format t "Deleting '~A'~%" path)
|
|
|
+ (uiop:delete-file-if-exists path)))))
|
|
|
+
|
|
|
+(defun deluge-process-downloaded (&optional dry)
|
|
|
+ (loop for (ih . name) in (deluge-get-seeding-torrents)
|
|
|
+ do (progn
|
|
|
+ (format t "Processing '~a'~%" name)
|
|
|
+ (deluge-pause-torrents ih)
|
|
|
+ (deluge-delete-skipped ih dry))))
|
|
|
+
|
|
|
(defun deluge-save-rm-list (filename)
|
|
|
(let ((torrents (deluge-get-torrents)))
|
|
|
(with-output-to-file (s filename)
|