aboutsummaryrefslogtreecommitdiffhomepage
path: root/downloader.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'downloader.lisp')
-rw-r--r--downloader.lisp62
1 files changed, 62 insertions, 0 deletions
diff --git a/downloader.lisp b/downloader.lisp
new file mode 100644
index 0000000..5f7077a
--- /dev/null
+++ b/downloader.lisp
@@ -0,0 +1,62 @@
+;;;; downloader.lisp
+
+(in-package #:vampire)
+
+(defvar *dl-cluster*
+ nil)
+
+(defun start-downloader-service (&key (count 5))
+ (setf *dl-cluster* (or *dl-cluster* (legion:make-cluster count 'run-job)))
+ (legion:start *dl-cluster*))
+
+(defun run-job (thunk)
+ (funcall thunk))
+
+(defun add-fetch-track-job (url ok err)
+ (legion:add-job
+ *dl-cluster*
+ (lambda ()
+ (if-let (track (download-media url))
+ (funcall ok track)
+ (funcall err url)))))
+
+(defun info-file-with-name (dir name)
+ (merge-pathnames
+ (format nil "~a.info.json" name)
+ dir))
+
+(defun trackinfo (path)
+ "Returns a trackinfo object - a list whose first member is a path to
+ a file and whose CDR is a PLIST of attributes to pass
+ to (make-instance 'track ...)"
+ (with-plist ((title :|title|)
+ (album :|album|)
+ (codec :|acodec|)
+ (artist :|artist|)
+ (dur :|duration|)
+ (file :|filename|)
+ (thumbs :|thumbnails|)
+ (source :|webpage_url|))
+ (jonathan:parse (alexandria:read-file-into-string path))
+ (with-plist ((url :|url|)) (first thumbs)
+ (cons file
+ (list
+ :source source
+ :title title
+ :album album
+ :codec codec
+ :artist artist
+ :duration dur
+ :thumb-url url)))))
+
+(defun download-media (url)
+ (with-temp-dir (tmpdir)
+ (let* ((tmpname
+ (default-name "media"))
+ (trackinfo-file
+ (info-file-with-name tmpdir tmpname)))
+ (uiop:run-program
+ (format nil "youtube-dl --write-info-json -x -o \"~a/~a.%(ext)s\" ~a"
+ tmpdir tmpname url))
+ (when (uiop:file-exists-p trackinfo-file)
+ (new-track (trackinfo trackinfo-file))))))