|
|
@@ -151,11 +151,55 @@
|
|
|
root (car (getf params :splat))))))
|
|
|
(if file (list 200 nil file) +404+))))
|
|
|
|
|
|
+;; Admin tools
|
|
|
+(defvar *rescans* nil)
|
|
|
+(defun update-db ()
|
|
|
+ (let (added updated removed)
|
|
|
+ (sb-impl::call-with-timing #'(lambda (&rest args)
|
|
|
+ (push (append args
|
|
|
+ (list :timestamp (get-universal-time)
|
|
|
+ :added added
|
|
|
+ :updated updated
|
|
|
+ :removed removed))
|
|
|
+ *rescans*))
|
|
|
+ #'(lambda ()
|
|
|
+ (multiple-value-bind (a u r) (rescan)
|
|
|
+ (save-db)
|
|
|
+ (setf added a updated u removed r))))))
|
|
|
+
|
|
|
+(defvar *rescan-lock* (bt:make-lock "Rescan lock"))
|
|
|
+(defvar *rescan-cond* (bt:make-condition-variable :name "Rescan requested"))
|
|
|
+(defvar *rescan-thread* nil)
|
|
|
+(defvar *rescan-active* nil)
|
|
|
+
|
|
|
+(defun rescanner ()
|
|
|
+ (loop
|
|
|
+ (bt:with-lock-held (*rescan-lock*)
|
|
|
+ (bt:condition-wait *rescan-cond* *rescan-lock*)
|
|
|
+ (setf *rescan-active* t)
|
|
|
+ (handler-case (update-db)
|
|
|
+ (error (e) (format t "Error updating db: ~a" e)))
|
|
|
+ (setf *rescan-active* nil))))
|
|
|
+
|
|
|
+(defun request-rescan (params)
|
|
|
+ (declare #.*standard-optimize-settings* (ignorable params))
|
|
|
+ (bt:condition-notify *rescan-cond*)
|
|
|
+ +200-empty+)
|
|
|
+
|
|
|
+(defun stats (params)
|
|
|
+ (declare #.*standard-optimize-settings* (ignorable params))
|
|
|
+ (let ((stats (db-stats)))
|
|
|
+ (setf (getf stats :|duration|) (format-interval (getf stats :|duration|)))
|
|
|
+ (200-json (append stats
|
|
|
+ (list :|rescans| (subseq *rescans* 0 (min (length *rescans*) 10)))))))
|
|
|
+
|
|
|
(defvar *mapper* (myway:make-mapper))
|
|
|
(myway:connect *mapper* "/api/cat/:category/size" 'get-category-size)
|
|
|
(myway:connect *mapper* "/api/cat/:category" 'get-category)
|
|
|
(myway:connect *mapper* "/api/cat" 'get-category-list)
|
|
|
(myway:connect *mapper* "/api/album/:id/tracks" 'get-album-tracks)
|
|
|
+(myway:connect *mapper* "/api/stats" 'stats)
|
|
|
+(myway:connect *mapper* "/api/rescan" 'request-rescan :method :POST)
|
|
|
|
|
|
(defun main (&rest args &key (port 5000) (debug nil) (use-thread t) (serve-files nil) &allow-other-keys)
|
|
|
;; Load config file
|
|
|
@@ -176,6 +220,9 @@
|
|
|
do (myway:connect *mapper* (concatenate 'string url-prefix "*")
|
|
|
(file-server path-prefix))))
|
|
|
|
|
|
+ ;; Start rescan processor
|
|
|
+ (setf *rescan-thread* (bt:make-thread 'rescanner :name "DB rescanner"))
|
|
|
+
|
|
|
;; Start application
|
|
|
(apply #'clack:clackup
|
|
|
(myway:to-app *mapper*)
|