1(import [playback.playlist [Song]]
2 [datetime [datetime]])
3(require [hy.contrib.walk [let]]
4 [hy.extra.anaphoric [*]])
5
6;; Mapping of beets tag names to MPD tag names.
7;; See: src/tag/Names.c in MPD source.
8(setv MPD-TAG-NAMES {
9 "title" "Title"
10 "artist" "Artist"
11 "album" "Album"
12 "genre" "Genre"
13 "track" "Track"
14 "disc" "Disc"
15 "albumartist" "AlbumArtist"
16 "id" "Id"
17 ;; TODO: Time
18 "length" "duration"
19 "mtime" "Last-Modified"
20 "year" "Date"
21})
22
23;; Metadata not actually considered tags by MPD itself.
24(setv MPD-BASIC-TAGS
25 ["file" "Last-Modified" "Time" "duration" "Pos" "Id"])
26
27;; Functions for converting a value of the given beets tag name to
28;; the representation used by the corresponding MPD tag (see above).
29(setv conversion-funcs {
30 "length" (fn [v] (round v 3))
31 "mtime" (fn [v] (.isoformat (datetime.fromtimestamp (int v)) "T"))
32})
33
34(defn create-song [metadata]
35 (defn convert-meta [metadata]
36 (defn is-unset [value]
37 (try
38 (or (is None value) (= (len value) 0))
39 (except [TypeError] False)))
40
41 (defn convert-value [tag value]
42 (try
43 ((get conversion-funcs tag) value)
44 (except [KeyError] value)))
45
46 (reduce (fn [dict pair]
47 (if (and (in (first pair) MPD-TAG-NAMES)
48 (not (is-unset (last pair))))
49 (assoc dict (get MPD-TAG-NAMES (first pair))
50 (convert-value (first pair) (last pair))))
51 dict)
52 (.items metadata) {}))
53
54 (Song (get metadata "path")
55 (convert-meta metadata)))