aboutsummaryrefslogtreecommitdiff
path: root/package.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'package.lisp')
-rw-r--r--package.lisp154
1 files changed, 154 insertions, 0 deletions
diff --git a/package.lisp b/package.lisp
new file mode 100644
index 0000000..d334845
--- /dev/null
+++ b/package.lisp
@@ -0,0 +1,154 @@
+(defpackage #:autotag
+ (:use #:cl
+ #:alexandria
+ #:split-sequence
+ #:just-getopt-parser)
+ (:export #:main))
+
+(in-package #:autotag)
+
+(cl-interpol:enable-interpol-syntax)
+
+(defparameter *quiet-p* nil
+ "Should autotag be quiet?")
+
+(defparameter *order-p* nil
+ "Apply tags in the same order as in release? (ignore name matching
+ or keywords)")
+
+(defparameter *rename-p* t
+ "Should files be renamed by default?")
+
+(defparameter *use-id-p* nil
+ "")
+
+(defparameter *print-tags-p* nil
+ "")
+
+(defvar *album-name* nil)
+(defvar *album-artist* nil)
+(defvar *npathnames* nil)
+
+(defvar *database* "https://musicbrainz.org/ws/2/")
+
+(defparameter *valid-cmd-line-args*
+ '(;;
+ (:artist "artist" :required)
+ ;;
+ (:album #\A :required)
+ (:album "album" :required)
+ ;;
+ (:order #\o)
+ (:order "order")
+ ;;
+ (:id #\i)
+ (:id "id")
+ ;;
+ (:use-id #\u :required)
+ (:use-id "use-id" :required)
+ ;;
+ (:print-tags #\p)
+ (:print-tags "print-tags")
+ ;;
+ (:dont-rename #\n)
+ (:dont-rename "dont-rename")
+ ;;
+ (:quiet #\q)
+ (:quiet "quiet")
+ ;;
+ (:help #\h)
+ (:help "help")))
+
+(defun chomp (string)
+ (if (and (string/= string "") (eql (last-elt string) #\Newline))
+ (subseq string 0 (1- (length string)))
+ string))
+
+(defun dmenu (options &key (printer #'princ-to-string) (lines 10) prompt text-output)
+ (let ((text-options (mapcar printer options)))
+ (multiple-value-bind (output error-output exit-status)
+ (trivial-shell:shell-command
+ (format nil "dmenu~@[ -l '~A'~]~@[ -p \"~A\"~]"
+ lines
+ (str:replace-using '("\"" "\\\"" "$" "\\$") prompt))
+ :input (format nil "~{~A~%~}" text-options))
+ (declare (ignore error-output exit-status))
+ (if text-output
+ (chomp output)
+ (let ((position (position (chomp output) text-options :test #'string=)))
+ (and position (elt options position)))))))
+
+(defun info (control-string &rest format-arguments)
+ (unless *quiet-p*
+ (apply #'format t control-string format-arguments)))
+
+;; Tags used by this autotagger, each track has one instance of this
+;; struct
+(defstruct tag
+ (title "")
+ (album "")
+ (artist "")
+ (date "")
+ (track "")
+ (keywords nil))
+
+(defparameter *ogg-tags*
+ `((:title "TITLE" ,#'tag-title ,#'(setf tag-title))
+ (:artist "ARTIST" ,#'tag-artist ,#'(setf tag-artist))
+ (:album "ALBUM" ,#'tag-album ,#'(setf tag-album))
+ (:date "DATE" ,#'tag-date ,#'(setf tag-date))
+ (:track "TRACKNUMBER" ,#'tag-track ,#'(setf tag-track))))
+
+;; (defun read-ogg-tags (pathname)
+;; (flet ((ogg-field-reader (line)
+;; (unless (string= line "")
+;; (let* ((fields (split-sequence #\= line))
+;; (name (car (rassoc (car fields) *ogg-tags*
+;; :test #'string= :key #'first)))
+;; (value (apply #'concatenate 'string (cdr fields))))
+;; (list name value)))))
+;; (read-tags (format nil "vorbiscomment -l ~A" pathname) #'ogg-field-reader)))
+
+(defun print-tag (tag)
+ (dolist (field *ogg-tags*)
+ (format t "~A=~A" (elt field 1) (funcall (elt field 2) tag))))
+
+(defun write-ogg-tags (pathname tag)
+ (trivial-shell:shell-command
+ (with-open-stream (stream (make-string-output-stream))
+ (format stream "vorbiscomment -w \"~A\"" pathname)
+ (loop :for (tag-name ogg-name reader writer) :in *ogg-tags*
+ :for value = (funcall reader tag)
+ :do
+ (format stream " -t \"~A=~A\"" ogg-name value))
+ (get-output-stream-string stream))))
+
+(defun help ()
+ (format t #?|~&Usage: autotag [OPTION...] [DIRECTORY... \| FILE...]
+
+autotag - Uses metadata from musicbrainz.org to fill song files with
+the tags of a given album.
+
+Examples:
+
+Assume that the directory working on has the same name as <ALBUM>
+ autotag --artist=<ARTIST> -A <ALBUM>
+
+Options:
+ --artist=ARTIST improve search results by providing an artist
+ -A, --album=ALBUM name of the album the files belong to
+ -i, --id get album id
+ -u, --use-id=ID use ID as release id
+ -p, --print-tags write tags to stdout instead of file
+ -o, --order ignore file names and assume that files are in order
+ (useful for ripped CDs)
+ -q, --quiet do not output operations being done
+ -h, --help show help options
+
+autotag
+Copyright (C) 2020 Thomas Albers Raviola <thomas@thomaslabs.org>
+This program comes with ABSOLUTELY NO WARRANTY.
+This is free software, and you are welcome to redistribute it
+under the terms of the GNU General Public License.
+|)
+ (uiop:quit))