diff options
Diffstat (limited to 'package.lisp')
-rw-r--r-- | package.lisp | 154 |
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)) |