diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.fnl | 44 | ||||
-rw-r--r-- | src/main.fnl | 51 | ||||
-rw-r--r-- | src/mpv.fnl | 4 | ||||
-rw-r--r-- | src/pls.fnl | 51 | ||||
-rw-r--r-- | src/test.pls | 18 | ||||
-rw-r--r-- | src/util.fnl | 9 |
6 files changed, 177 insertions, 0 deletions
diff --git a/src/lib.fnl b/src/lib.fnl new file mode 100644 index 0000000..de7bf31 --- /dev/null +++ b/src/lib.fnl | |||
@@ -0,0 +1,44 @@ | |||
1 | ;;; LIB.fnl | ||
2 | ;; Radish library | ||
3 | |||
4 | (local util (require :util)) | ||
5 | (local pls (require :pls)) | ||
6 | (local mpv (require :mpv)) | ||
7 | |||
8 | (local protocols {:http (fn [url] | ||
9 | (mpv.play)) | ||
10 | :https :find | ||
11 | :shuf :noise}) | ||
12 | |||
13 | (local radish-config (.. (or (os.getenv :XDG_CONFIG_HOME) | ||
14 | (.. (os.getenv :HOME) :/.config)) | ||
15 | :/radish/stations)) | ||
16 | |||
17 | (local radish-pid :/tmp/radish.pid) | ||
18 | (local radish-lp (.. (or (os.getenv :XDG_CACHE_HOME) | ||
19 | (.. (os.getenv :HOME) :/.cache)) | ||
20 | :/radish.lastplayed)) | ||
21 | |||
22 | (local radish-status :/tmp/radish.status) | ||
23 | |||
24 | (fn play [?station] | ||
25 | "Begin playing STATION. | ||
26 | STATION can be a stream using one of `protocols', which see. If it's not | ||
27 | present, or if STATION doesn't match a protocol in `protocols', allow the user | ||
28 | to choose one from their favorites.") | ||
29 | |||
30 | (fn kill [] | ||
31 | "Kill the current invocation of `radish'." | ||
32 | (let [pid ()])) | ||
33 | |||
34 | (fn add [?station] | ||
35 | (print :add)) | ||
36 | |||
37 | (fn del [?station] | ||
38 | (print :del)) | ||
39 | |||
40 | (fn edit [?station] | ||
41 | (print :edit)) | ||
42 | |||
43 | {: play : kill : add : del : edit} | ||
44 | |||
diff --git a/src/main.fnl b/src/main.fnl new file mode 100644 index 0000000..79fed85 --- /dev/null +++ b/src/main.fnl | |||
@@ -0,0 +1,51 @@ | |||
1 | ;;; RADISH | ||
2 | ;; A tuner for various streams | ||
3 | ;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net> | ||
4 | ;; License: Good Choices (https://acdw.casa/gcl) | ||
5 | |||
6 | (local util (require :util)) | ||
7 | (local pls (require :pls)) | ||
8 | (local radish (require :lib)) | ||
9 | |||
10 | (fn usage [?exit-code] | ||
11 | (print "RADISH: a tuner for various streams | ||
12 | Copyright (C) 2022 Case Duckworth <acdw@acdw.net> | ||
13 | License: Good Choices (https://acdw.casa/gcl) | ||
14 | |||
15 | Commands | ||
16 | radish [STATION] | ||
17 | Begin playing STATION. If STATION is not | ||
18 | provided, display a list of favorites and | ||
19 | allow the user to choose one to play. | ||
20 | radish play [STATION] | ||
21 | Begin playing STATION. If STATION is not | ||
22 | provided, play the most recently-played. | ||
23 | radish kill | ||
24 | Kill the currently-playing station. | ||
25 | radish add [STATION] | ||
26 | Add STATION or the currently-playing one | ||
27 | to the favorites list. | ||
28 | radish del [STATION] | ||
29 | Remove STATION or the currently-playing | ||
30 | one from the favorites list. | ||
31 | radish edit [STATION] | ||
32 | Edit the information of STATION, or the | ||
33 | current one if not given. | ||
34 | |||
35 | See radish(1) for more details.") | ||
36 | (os.exit (or ?exit-code 0))) | ||
37 | |||
38 | (fn main [...] | ||
39 | "Program entry point. | ||
40 | See `usage' for usage details." | ||
41 | (match [...] | ||
42 | [:help] (usage) | ||
43 | [:play ?station] (radish.play ?station) | ||
44 | [:kill] (radish.kill) | ||
45 | [:add ?station] (radish.add ?station) | ||
46 | [:del ?station] (radish.del ?station) | ||
47 | [:edit ?station] (radish.edit ?station) | ||
48 | [station] (radish.play ?station))) | ||
49 | |||
50 | (main ...) | ||
51 | |||
diff --git a/src/mpv.fnl b/src/mpv.fnl new file mode 100644 index 0000000..11510a8 --- /dev/null +++ b/src/mpv.fnl | |||
@@ -0,0 +1,4 @@ | |||
1 | ;;; MPV.fnl | ||
2 | ;; bad bindings to mpv | ||
3 | |||
4 | (fn ) | ||
diff --git a/src/pls.fnl b/src/pls.fnl new file mode 100644 index 0000000..b3bc575 --- /dev/null +++ b/src/pls.fnl | |||
@@ -0,0 +1,51 @@ | |||
1 | ;;; PLS.fnl | ||
2 | ;; a parser for *.pls files | ||
3 | ;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net> | ||
4 | ;; License: Good Choices (https://acdw.casa/gcl) | ||
5 | |||
6 | ;; https://en.wikipedia.org/wiki/PLS_(file_format) | ||
7 | |||
8 | (fn split-lines [str] | ||
9 | "Split STR into a list of lines." | ||
10 | (icollect [ln (: str :gmatch "([^\n]*)\n?")] | ||
11 | ln)) | ||
12 | |||
13 | (fn parse [str] | ||
14 | "Parse a list of LINES into a playlist." | ||
15 | ;; This /maybe/ should take a string, I suppose. | ||
16 | (let [t []] | ||
17 | (each [_ l (ipairs (split-lines str))] | ||
18 | (let [(ltype num title) (: l :match "^(.*)([0-9]+)=(.*)")] | ||
19 | (when (and ltype num title) | ||
20 | (let [ltype (string.lower ltype) | ||
21 | num (tonumber num)] | ||
22 | (if (. t num) | ||
23 | (tset t num ltype title) | ||
24 | (tset t num {ltype title})))))) | ||
25 | t)) | ||
26 | |||
27 | (fn read [file] | ||
28 | "Read a .pls FILE into a playlist." | ||
29 | (with-open [p (io.open file)] | ||
30 | (parse (: p :read :*a)))) | ||
31 | |||
32 | (fn serialize [playlist] | ||
33 | "Serialize a PLAYLIST into a .pls-formatted string." | ||
34 | (let [s (icollect [n i (ipairs playlist)] | ||
35 | (.. (string.format "File%d=%s\n" n (. i :file)) | ||
36 | (if (. i :title) | ||
37 | (string.format "Title%d=%s\n" n (. i :title)) | ||
38 | "") | ||
39 | (if (. i :length) | ||
40 | (string.format "Length%d=%s\n" n (. i :length)) | ||
41 | "")))] | ||
42 | (.. "[playlist]\n\n" (table.concat s "\n") "\n\n" :NumberOfEntries= | ||
43 | (length s) "\n" "Version=2\n"))) | ||
44 | |||
45 | (fn write [playlist file] | ||
46 | "Write PLAYLIST to FILE." | ||
47 | (with-open [p (io.open file :w)] | ||
48 | (: p :write (serialize playlist)))) | ||
49 | |||
50 | {: parse : read : serialize : write} | ||
51 | |||
diff --git a/src/test.pls b/src/test.pls new file mode 100644 index 0000000..8192fe9 --- /dev/null +++ b/src/test.pls | |||
@@ -0,0 +1,18 @@ | |||
1 | [playlist] | ||
2 | |||
3 | File1=http://relay5.181.fm:8068 | ||
4 | Length1=-1 | ||
5 | |||
6 | File2=example2.mp3 | ||
7 | Title2=Just some local audio that is 2mins long | ||
8 | Length2=120 | ||
9 | |||
10 | File3=F:\Music\whatever.m4a | ||
11 | Title3=absolute path on Windows | ||
12 | |||
13 | File4=%UserProfile%\Music\short.ogg | ||
14 | Title4=example for an Environment variable | ||
15 | Length4=5 | ||
16 | |||
17 | NumberOfEntries=4 | ||
18 | Version=2 | ||
diff --git a/src/util.fnl b/src/util.fnl new file mode 100644 index 0000000..9801154 --- /dev/null +++ b/src/util.fnl | |||
@@ -0,0 +1,9 @@ | |||
1 | ;;; UTIL.fnl | ||
2 | ;; Utility functions | ||
3 | ;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net> | ||
4 | ;; License: Good Choices (https://acdw.casa/gcl) | ||
5 | |||
6 | (local util {}) | ||
7 | |||
8 | util | ||
9 | |||