Эх сурвалжийг харах

[music] Auto-rescan, add torrents, db stats.

Innokentiy Enikeev 4 жил өмнө
parent
commit
ace3f4dbb1
3 өөрчлөгдсөн 50 нэмэгдсэн , 17 устгасан
  1. 1 0
      common.lisp
  2. 6 0
      macros.lisp
  3. 43 17
      plugins/music.lisp

+ 1 - 0
common.lisp

@@ -164,6 +164,7 @@
            :def-oauth-handler
            :def-oauth-section-handler
            :with-random-state
+           :with-chat-in-list
            :defcron
 
            :handle-update

+ 6 - 0
macros.lisp

@@ -12,6 +12,7 @@
            :def-oauth-handler
            :def-oauth-section-handler
            :with-random-state
+           :with-chat-in-list
            :defcron))
 (in-package #:chatikbot.macros)
 
@@ -61,6 +62,11 @@
            ,@body
            t)))))
 
+(defmacro with-chat-in-list (list-id &body body)
+  `(if (member *chat-id* (chatikbot.db:lists-get ,list-id))
+       (progn ,@body)
+       (bot-send-message "А вот хуй!")))
+
 (defmacro with-parsed-callback (callback &body body)
   `(let* ((*callback* ,callback)
           (*query-id* (agets *callback* "id"))

+ 43 - 17
plugins/music.lisp

@@ -7,6 +7,8 @@
 (defvar *deluge-api* "http://localhost:8112/json")
 (defvar *deluge-password* "chads")
 (defvar *deluge-request-id* 1)
+(defvar *chad-music-stats-url* "http://localhost:5000/api/stats"))
+(defvar *chad-music-rescan-url* "http://localhost:5000/api/rescan"))
 
 (defun jojo-request (url &rest args &key method parameters content headers basic-auth cookie-jar keep-alive use-connection-pool timeout ssl-key-file ssl-cert-file ssl-key-password stream verbose proxy insecure ca-path user-agent (as :plist))
   (declare (ignore method parameters basic-auth cookie-jar keep-alive use-connection-pool timeout ssl-key-file ssl-cert-file ssl-key-password stream verbose proxy insecure ca-path user-agent))
@@ -15,7 +17,10 @@
     (push (cons :content-type "application/json") headers))
   (remf args :headers)
   (multiple-value-bind (body status headers uri)
-      (apply #'http-request url :headers headers args)
+      (handler-bind
+	  ((sb-int:broken-pipe #'(lambda (c) (declare (ignorable c))
+				   (invoke-restart (find-restart 'dexador:retry-request)))))
+	(apply #'http-request url :headers headers args))
     (unless (stringp body)
       (setf body (trivial-utf-8:utf-8-bytes-to-string body)))
     (values (jojo:parse body :as as) status headers uri)))
@@ -75,7 +80,10 @@
        for prio in (getf status :|file_priorities|)
        do (setf (getf file :|prio|) prio
                 (getf file :|path|) (pathname (raw-pathname (format nil "~A/~A" save-path (getf file :|path|)))))
-       collect file)))
+	  collect file)))
+
+(defun deluge-add-torrent-magnet (uri &optional options)
+  (deluge-request "core.add_torrent_magnet" (list uri options)))
 
 (defun get-non-skipped (files)
   (remove 0 files :key (lambda (f) (getf f :|prio|))))
@@ -108,9 +116,9 @@
        :wanted-files (length wanted-dirs)
        :media-dirs (remove-duplicates wanted-dirs :test #'equal)))))
 
-(defun get-import-notify (info)
+(defun get-import-notify (info action)
   (labels ((f (fl) (getf info fl)))
-    (format nil "[[🎶]] Добавляем *~a*, ~a альбомов с ~a треками. Весит ~a"
+    (format nil "[[🎶]] ~a *~a*, ~a альбомов с ~a треками. Весит ~a" action
             (f :name) (length (f :media-dirs)) (f :wanted-files) (format-size (f :total-wanted)))))
 
 (defun get-root-paths (info)
@@ -157,23 +165,21 @@
 (defun process-downloaded (ih &optional dry)
   (let* ((status (deluge-get-torrent-status ih +deluge-default-status-fields+))
          (info (get-torrent-info status))
-         (notify (get-import-notify info))
+         (notify (get-import-notify info "Добавляем"))
          (paths (get-root-paths info)))
     (send-admins notify dry)
     (deluge-pause-torrents ih)
     (deluge-delete-skipped ih dry)
     (run-import paths dry)
+    (json-request *chad-music-rescan-url* :method :post)
     (if dry (format t "Removing torrent ~a" ih)
       (deluge-remove-torrent ih))))
 
 (defun process-imports ()
   (loop
-    (handler-bind
-	((sb-int:broken-pipe #'(lambda (c) (declare (ignorable c))
-				 (invoke-restart (find-restart 'dexador:retry-request))))
-	 (error #'(lambda (c) (log:error "Error processing torrent" c))))
-      (loop for (ih . name) in (deluge-get-seeding-torrents)
-	    do (process-downloaded ih)))
+    (loop for (ih . name) in (deluge-get-seeding-torrents)
+	  do (handler-case (process-downloaded ih)
+	       (error (c) (log:error "Error processing torrent" name c))))
     (sleep 1)))
 
 (defvar *watcher* nil "Importer thread ")
@@ -194,20 +200,40 @@
   (bot-send-message (if enable "[🎶] Импортим музло" "[🎶] Пусть мешки парятся")))
 
 (defun handle-status ()
-  (let ((stats (loop
+  (let* ((db-stats (when *chad-music-stats-url*
+		     (json-request *chad-music-stats-url*)))
+	 (stats (loop
 		 for (torrent status) on (deluge-get-torrents-status nil '("state" "name" "total_wanted")) by #'cddr
 		 for state = (getf status :|state|)
 		 when (equal state "Downloading") counting t into down
 		 when (equal state "Seeding") counting t into seed
 		 summing (getf status :|total_wanted|) into size
 		 finally (return (list :down down :seed seed :size size)))))
-    (bot-send-message (format nil "[[🎶]] Осталось скачать ~a, заимпортить ~a торрентов, общий объём ~a" (getf stats :down) (getf stats :seed) (format-size (getf stats :size)))
+	 (bot-send-message (format nil "[[🎶]] Осталось скачать ~a, заимпортить ~a торрентов, общий объём ~a.~%Сейчас в базе ~a исполнителей с ~a альбомами и ~a треками, общей длительностью ~a"
+				   (getf stats :down) (getf stats :seed) (format-size (getf stats :size))
+				   (agets db-stats "artists")
+				   (agets db-stats "albums")
+				   (agets db-stats "tracks")
+				   (agets db-stats "duration"))
 		      :parse-mode "markdown")))
 
+
+(defparameter +magnet-regex+ (ppcre:create-scanner "magnet:\\?\\S+"))
+(defun handle-add-torrent (magnet)
+  (let* ((ih (deluge-add-torrent-magnet magnet))
+	 (status (deluge-get-torrent-status ih +deluge-default-status-fields+))
+         (info (get-torrent-info status))
+         (notify (get-import-notify info "Качаем")))
+    (bot-send-message notify)))
+
 (def-message-cmd-handler handle-cmd-music (:music)
-  (cond
-    ((= 1 (length *args*))
-     (handle-set-watch (equal "on" (car *args*))))
-    (:otherwise (handle-status))))
+  (with-chat-in-list :music-admins
+    (let ((arg (car *args*)))
+    (cond
+      ((and (= 1 (length *args*)) (member (string-downcase arg) '("on" "off") :test 'equal))
+       (handle-set-watch (equal "on" arg)))
+      ((ppcre:scan-to-strings +magnet-regex+ arg)
+       (handle-add-torrent (ppcre:scan-to-strings +magnet-regex+ arg)))
+      (:otherwise (handle-status))))))
 
 (add-hook :starting #'ensure-watcher)