Finished the first draft (I think). Added options to documentation.
This commit is contained in:
parent
36d8db1f86
commit
a1dd0a8313
18
README
18
README
|
@ -1,4 +1,20 @@
|
|||
This is a distribution of mp_suggest, an organization tool for MP3 libraries
|
||||
This is a distribution of mp_suggest, an organization tool for MP3
|
||||
libraries. It was written primarily as an experiment in learning Hy.
|
||||
Hy is a lisp-like programming language that runs on top of the Python VM
|
||||
and exploits Python's access to the running AST in order to build
|
||||
working Python programs.
|
||||
|
||||
Writing mp_suggest was an interesting exercise in returning to Lisp
|
||||
after all these years. I find that I really enjoyed it (although,
|
||||
honestly, Hy's debugging facilities leave a lot to be desired). The
|
||||
style used inside mp_suggest is most definitely not Lispy; looking
|
||||
through it, with its persistent use of cheap anonymous functions and
|
||||
closures and its function-level metaprogramming, I guess the best
|
||||
language I could compare it to is Coffeescript. I like Coffeescript a
|
||||
lot, but I don't get many opportunities to use it professionally, but
|
||||
the sensibilities of Coffeescript (especially Reginald Braithwaite's
|
||||
Ristrettology and his other books on functional programming) heavily
|
||||
influenced the design decisions I made in mp_suggest.
|
||||
|
||||
* Licensing
|
||||
|
||||
|
|
|
@ -17,35 +17,39 @@
|
|||
|
||||
(defn print-version []
|
||||
(print (.format "mp_suggest (hy version {})" *version*))
|
||||
(sys.exit 0))
|
||||
(print "Copyright (c) 2008, 2014 Elf M. Sternberg <elf.sternberg@gmail.com>")
|
||||
(sys.exit))
|
||||
|
||||
(defn print-help []
|
||||
(print "Usage:")
|
||||
(ap-each optlist (print (.format " -{} --{} {}" (get it 0) (get it 1) (get it 3))))
|
||||
(sys.exit 0))
|
||||
(sys.exit))
|
||||
|
||||
; Given a set of command-line arguments, compare that to a mapped
|
||||
; version of the optlist and return a canonicalized dictionary of all
|
||||
; the arguments that have been set.
|
||||
|
||||
(defn find-opt-reducer [acc it]
|
||||
(let [[(, o a) it]
|
||||
[optmap (ap-reduce (do (assoc acc (+ "-" (. it [0])) (. it [1])) acc) optlist {})]]
|
||||
(if (.has_key optmap o) (let [[full (car (get optmap o))]
|
||||
[hasargs (car (cdr (get optmap o)))]]
|
||||
(assoc acc full (if hasargs a true))))
|
||||
acc))
|
||||
(defn make-opt-assoc [prefix pos]
|
||||
(fn [acc it] (assoc acc (+ prefix (get it pos)) (get it 1)) acc))
|
||||
|
||||
(defn make-options-rationalizer [optlist]
|
||||
(let [
|
||||
[short-opt-assoc (make-opt-assoc "-" 0)]
|
||||
[long-opt-assoc (make-opt-assoc "--" 1)]
|
||||
[fullset
|
||||
(ap-reduce (-> (short-opt-assoc acc it)
|
||||
(long-opt-assoc it)) optlist {})]]
|
||||
(fn [acc it] (do (assoc acc (get fullset (get it 0)) (get it 1)) acc))))
|
||||
|
||||
; Assuming the directory name looked like "Artist - Album", return the
|
||||
; two names separately. If only one name is here, assume a compilation
|
||||
; or mixtape album and default to "VA" (Various Artists).
|
||||
|
||||
(defn artist-album []
|
||||
(let [[aa (.split (. (.split (.getcwd os) "/") [-1]) " - ")]
|
||||
[sp (fn [i] (.strip i))]]
|
||||
(let [[aa (-> (.getcwd os) (.split "/") (get -1) (.split " - "))]]
|
||||
(if (= (len aa) 1)
|
||||
(, "VA" (get aa 0))
|
||||
(, (sp (get aa 0)) (sp (get aa 1))))))
|
||||
(, (.strip (get aa 0)) (.strip (get aa 1))))))
|
||||
|
||||
; A long list of substitutions intended to turn a filename into a
|
||||
; human-readable strategy. This operation is the result of weeks
|
||||
|
@ -64,7 +68,6 @@
|
|||
; filesystem access is a point of failure, but this is mostly
|
||||
; reliable.
|
||||
|
||||
|
||||
(defn tag-deriver [usefilenames]
|
||||
(fn [mp3s]
|
||||
(defn derive-tag [pos mp3]
|
||||
|
@ -146,23 +149,39 @@
|
|||
[artist
|
||||
(if (.has_key opts "artist")
|
||||
(get opts "artist")
|
||||
(sfix loc_artist))]]
|
||||
(sfix loc_artist))]
|
||||
|
||||
[format-string
|
||||
(string.join ["id3v2 -T \"{}\""
|
||||
"--album \"{}\""
|
||||
"--artist \"{}\""
|
||||
"--genre \"{}\""
|
||||
"--song \"{}\""
|
||||
"\"{}\""] " ")]]
|
||||
|
||||
(print genre album artist)))
|
||||
(ap-each mp3s
|
||||
(print (.format format-string (get it 5) album artist genre (get it 4) (get it 0))))))
|
||||
|
||||
(defmain [&rest args]
|
||||
(try
|
||||
(let [[optstringsshort
|
||||
(string.join (ap-map (. it [0]) optlist) ":")]
|
||||
(string.join (ap-map (+ (. it [0]) (cond [(. it [2]) ":"] [true ""])) optlist) "")]
|
||||
|
||||
[optstringslong
|
||||
(list (ap-map (+ (. it [1]) (cond [(. it [2]) "="] [true ""])) optlist))]
|
||||
|
||||
[(, opt arg)
|
||||
(getopt.getopt (slice args 1) optstringsshort optstringslong)]
|
||||
|
||||
[rationalize-options
|
||||
(make-options-rationalizer optlist)]
|
||||
|
||||
[options
|
||||
(ap-reduce (find-opt-reducer acc it) opt {})]]
|
||||
(cond [(.has_key options "h") (print-help)]
|
||||
[(.has_key options "v") (print-version)]
|
||||
[true (suggest options)]))))
|
||||
(ap-reduce (rationalize-options acc it) opt {})]]
|
||||
|
||||
(cond [(.has_key options "help") (print-help)]
|
||||
[(.has_key options "version") (print-version)]
|
||||
[true (suggest options)]))))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -62,6 +62,35 @@ commands can be tweaked, and all of them override the techniques
|
|||
This is probably completely idiosyncratic to the way I do things in my
|
||||
own music archive, but as an exercise in writing Hy, it was fun.
|
||||
|
||||
\section{Options}
|
||||
%%%%%%%%%%%%%%%%%
|
||||
\begin{Description}
|
||||
\item[\OptArg{--genre}{genre}] Set the genre manually from the command
|
||||
line. This overrides any settings found in the ID3 tag. A short form
|
||||
of this tag is ``-g''
|
||||
|
||||
\item[\OptArg{--album}{album}] Set the album manually from the command
|
||||
line. This overrides any settings found in the ID3 tag. A short form
|
||||
of this tag is ``-a''
|
||||
|
||||
\item[\OptArg{--artist}{artist}] Set the artist manually from the command
|
||||
line. This overrides any settings found in the ID3 tag. A short form
|
||||
of this tag is ``-r''
|
||||
|
||||
\item[\Opt{--usedir}] Use the directory name for artist and album
|
||||
information. This overrides anything found in the ID3 tags. A short
|
||||
form of this tag is ``-n''.
|
||||
|
||||
\item[\Opt{--usefilename}] Use the filename as the song title. This
|
||||
overrides anything found in the ID3 tags. A short form of this tag is
|
||||
``-t''.
|
||||
|
||||
\item[\Opt{--help}] Print a short help message. A short form of this
|
||||
tag is ``-h''
|
||||
|
||||
\item[\Opt{--version}] Print the version information. A short form of this
|
||||
tag is ``-v''
|
||||
|
||||
\section{Requirements}
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
|
Loading…
Reference in New Issue