From c9a942aca66903d817b3b7df46488451a0bd7004 Mon Sep 17 00:00:00 2001
From: Case Duckworth
Date: Sun, 21 Aug 2022 18:02:46 -0500
Subject: Move into src/

---
 lib.fnl      | 24 ------------------------
 pls.fnl      | 10 ----------
 radish       | 33 +++++++++++++++++++++++++++------
 radish.fnl   | 47 -----------------------------------------------
 src/lib.fnl  | 44 ++++++++++++++++++++++++++++++++++++++++++++
 src/main.fnl | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/mpv.fnl  |  4 ++++
 src/pls.fnl  | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/test.pls | 18 ++++++++++++++++++
 src/util.fnl |  9 +++++++++
 util.fnl     | 13 -------------
 11 files changed, 204 insertions(+), 100 deletions(-)
 delete mode 100644 lib.fnl
 delete mode 100644 pls.fnl
 delete mode 100644 radish.fnl
 create mode 100644 src/lib.fnl
 create mode 100644 src/main.fnl
 create mode 100644 src/mpv.fnl
 create mode 100644 src/pls.fnl
 create mode 100644 src/test.pls
 create mode 100644 src/util.fnl
 delete mode 100644 util.fnl

diff --git a/lib.fnl b/lib.fnl
deleted file mode 100644
index a08fcc8..0000000
--- a/lib.fnl
+++ /dev/null
@@ -1,24 +0,0 @@
-;;; LIB.fnl
-;; Radish library
-
-(local util (require :util))
-
-(local radish {})
-
-(lambda radish.play [?station]
-  (print "play"))
-
-(lambda radish.kill []
-  (print "kill"))
-
-(lambda radish.add [?station]
-  (print "add"))
-
-(lambda radish.del [?station]
-  (print "del"))
-
-(lambda radish.edit [?station]
-  (print "edit"))
-
-radish
-
diff --git a/pls.fnl b/pls.fnl
deleted file mode 100644
index 4d55dd5..0000000
--- a/pls.fnl
+++ /dev/null
@@ -1,10 +0,0 @@
-;;; PLS.fnl
-;; a parser for *.pls files
-;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
-;; License: Good Choices (https://acdw.casa/gcl)
-
-(local pls {})
-
-
-
-pls
diff --git a/radish b/radish
index 3cc4eb7..a5d5d07 100755
--- a/radish
+++ b/radish
@@ -6,7 +6,7 @@
 usage() {
 	cat <<EOF
 RADISH: radio, music, static
-USAGE:	radish [-h|-k|-r|-s|-S]
+USAGE:	radish [-h|-k|-r|-s|-S|-i]
 	radish -l [NAME]
 	radish [STATION]
 
@@ -16,6 +16,7 @@ FLAGS:
  -S		Show radish's status indefinitely.
  -k		Kill the currently-playing radish invocation.
  -r		Replay most recently-played station.
+ -i		Show information about currently-playing station.
 
 OPTIONS:
  -l [NAME]	List available stations.
@@ -40,7 +41,7 @@ config() {
 
 main() {
 	config
-	while getopts :hkrsSl: opt; do
+	while getopts :hkrsSl:L:i opt; do
 		case "$opt" in
 		h) usage ;;
 		k) radish_kill ;;
@@ -48,9 +49,12 @@ main() {
 		s) radish_status ;;
 		S) radish_status -follow ;;
 		l) radish_list "$OPTARG" ;;
+		L) radish_list -r "$OPTARG" ;;
+		i) radish_info ;;
 		:)
 			case "$OPTARG" in
 			l) radish_list ;;
+			L) radish_list -r ;;
 			*)
 				echo >&2 "Option -$OPTARG requires an argument"
 				usage 1
@@ -127,6 +131,12 @@ echo() { printf '%s\n' "$*"; }
 
 ### Main functionality
 
+radish_info() {
+	url="$(cat "$RADISH_LP_FILE")"
+	grep "$url" "$RADISH_STATION_FILE"
+	exit
+}
+
 radish_kill() {
 	if [ -f "$RADISH_PID_FILE" ]; then
 		printf >&2 '%s' "Killing radish..."
@@ -151,14 +161,25 @@ radish_status() {
 }
 
 radish_list() {
-	_radish_stations | grep -i "${1:-}" | awk -F '\t' '{
-		desc = $'$_schema_desc'
-		url = $'$_schema_url'
-		tags = $'$_schema_tags'
+	if [ "x$1" = x-r ]; then
+		raw=true
+		shift
+	else
+		raw=false
+	fi
+	_radish_stations | grep -i "${1:-}" |
+		if "$raw"; then
+			awk 'BEGIN{FS="\t";OFS="\t"}{print $2, $1, $3}'
+		else
+			awk -F '\t' '{
+		desc = $2
+		url = $1
+		tags = $3
 		printf "%-23s |", substr(desc,1,20) (length(desc)>20?"...":"")
 		printf "%-23s |", substr(tags,1,20) (length(tags)>20?"...":"")
 		printf "%-23s\n", substr(url,1,20) (length(url)>20?"...":"")
 		}'
+		fi
 	exit
 }
 
diff --git a/radish.fnl b/radish.fnl
deleted file mode 100644
index acba83f..0000000
--- a/radish.fnl
+++ /dev/null
@@ -1,47 +0,0 @@
-;;; RADISH
-;; A tuner for various streams
-;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
-;; License: Good Choices (https://acdw.casa/gcl)
-
-(local util (require :util))
-(local pls (require :pls))
-(local radish (require :lib))
-
-(fn usage []
-  (util.printlns "RADISH: a tuner for various streams"
-                 "Copyright (C) 2022 Case Duckworth <acdw@acdw.net>"
-                 "License: Good Choices (https://acdw.casa/gcl)"
-                 ""
-                 "Commands"
-                 "    radish [STATION]"
-                 "        Begin playing STATION.  If STATION is not"
-                 "        provided, display a list of favorites and"
-                 "        allow the user to choose one to play."
-                 "    radish play [STATION]"
-                 "        Begin playing STATION.  If STATION is not"
-                 "        provided, play the most recently-played."
-                 "    radish kill"
-                 "        Kill the currently-playing station."
-                 "    radish add [STATION]"
-                 "        Add STATION or the currently-playing one"
-                 "        to the favorites list."
-                 "    radish del [STATION]"
-                 "        Remove STATION or the currently-playing"
-                 "        one from the favorites list."
-                 "    radish edit [STATION]"
-                 "        Edit the information of STATION, or the"
-                 "        current one if not given."
-                 ""
-                 "See radish(1) for more details."))
-
-(fn main [args]
-  (match args
-    [:play ?station] (radish.play ?station)
-    [:kill] (radish.kill)
-    [:add ?station] (radish.add ?station)
-    [:del ?station] (radish.del ?station)
-    [:edit ?station] (radish.edit ?station)
-    [station] (radish.play station)
-    _ (usage)))
-
-(main arg)
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 @@
+;;; LIB.fnl
+;; Radish library
+
+(local util (require :util))
+(local pls (require :pls))
+(local mpv (require :mpv))
+
+(local protocols {:http (fn [url]
+                          (mpv.play))
+                  :https :find
+                  :shuf :noise})
+
+(local radish-config (.. (or (os.getenv :XDG_CONFIG_HOME)
+                             (.. (os.getenv :HOME) :/.config))
+                         :/radish/stations))
+
+(local radish-pid :/tmp/radish.pid)
+(local radish-lp (.. (or (os.getenv :XDG_CACHE_HOME)
+                         (.. (os.getenv :HOME) :/.cache))
+                     :/radish.lastplayed))
+
+(local radish-status :/tmp/radish.status)
+
+(fn play [?station]
+  "Begin playing STATION.
+STATION can be a stream using one of `protocols', which see.  If it's not
+present, or if STATION doesn't match a protocol in `protocols', allow the user
+to choose one from their favorites.")
+
+(fn kill []
+  "Kill the current invocation of `radish'."
+  (let [pid ()]))
+
+(fn add [?station]
+  (print :add))
+
+(fn del [?station]
+  (print :del))
+
+(fn edit [?station]
+  (print :edit))
+
+{: play : kill : add : del : edit}
+
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 @@
+;;; RADISH
+;; A tuner for various streams
+;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
+;; License: Good Choices (https://acdw.casa/gcl)
+
+(local util (require :util))
+(local pls (require :pls))
+(local radish (require :lib))
+
+(fn usage [?exit-code]
+  (print "RADISH: a tuner for various streams
+Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
+License: Good Choices (https://acdw.casa/gcl)
+
+Commands
+    radish [STATION]
+        Begin playing STATION.  If STATION is not
+        provided, display a list of favorites and
+        allow the user to choose one to play.
+    radish play [STATION]
+        Begin playing STATION.  If STATION is not
+        provided, play the most recently-played.
+    radish kill
+        Kill the currently-playing station.
+    radish add [STATION]
+        Add STATION or the currently-playing one
+        to the favorites list.
+    radish del [STATION]
+        Remove STATION or the currently-playing
+        one from the favorites list.
+    radish edit [STATION]
+        Edit the information of STATION, or the
+        current one if not given.
+
+See radish(1) for more details.")
+  (os.exit (or ?exit-code 0)))
+
+(fn main [...]
+  "Program entry point.
+See `usage' for usage details."
+  (match [...]
+    [:help] (usage)
+    [:play ?station] (radish.play ?station)
+    [:kill] (radish.kill)
+    [:add ?station] (radish.add ?station)
+    [:del ?station] (radish.del ?station)
+    [:edit ?station] (radish.edit ?station)
+    [station] (radish.play ?station)))
+
+(main ...)
+
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 @@
+;;; MPV.fnl
+;; bad bindings to mpv
+
+(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 @@
+;;; PLS.fnl
+;; a parser for *.pls files
+;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
+;; License: Good Choices (https://acdw.casa/gcl)
+
+;; https://en.wikipedia.org/wiki/PLS_(file_format)
+
+(fn split-lines [str]
+  "Split STR into a list of lines."
+  (icollect [ln (: str :gmatch "([^\n]*)\n?")]
+    ln))
+
+(fn parse [str]
+  "Parse a list of LINES into a playlist."
+  ;; This /maybe/ should take a string, I suppose.
+  (let [t []]
+    (each [_ l (ipairs (split-lines str))]
+      (let [(ltype num title) (: l :match "^(.*)([0-9]+)=(.*)")]
+        (when (and ltype num title)
+          (let [ltype (string.lower ltype)
+                num (tonumber num)]
+            (if (. t num)
+                (tset t num ltype title)
+                (tset t num {ltype title}))))))
+    t))
+
+(fn read [file]
+  "Read a .pls FILE into a playlist."
+  (with-open [p (io.open file)]
+    (parse (: p :read :*a))))
+
+(fn serialize [playlist]
+  "Serialize a PLAYLIST into a .pls-formatted string."
+  (let [s (icollect [n i (ipairs playlist)]
+            (.. (string.format "File%d=%s\n" n (. i :file))
+                (if (. i :title)
+                    (string.format "Title%d=%s\n" n (. i :title))
+                    "")
+                (if (. i :length)
+                    (string.format "Length%d=%s\n" n (. i :length))
+                    "")))]
+    (.. "[playlist]\n\n" (table.concat s "\n") "\n\n" :NumberOfEntries=
+        (length s) "\n" "Version=2\n")))
+
+(fn write [playlist file]
+  "Write PLAYLIST to FILE."
+  (with-open [p (io.open file :w)]
+    (: p :write (serialize playlist))))
+
+{: parse : read : serialize : write}
+
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 @@
+[playlist]
+
+File1=http://relay5.181.fm:8068
+Length1=-1
+
+File2=example2.mp3
+Title2=Just some local audio that is 2mins long
+Length2=120
+
+File3=F:\Music\whatever.m4a
+Title3=absolute path on Windows
+
+File4=%UserProfile%\Music\short.ogg
+Title4=example for an Environment variable
+Length4=5
+
+NumberOfEntries=4
+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 @@
+;;; UTIL.fnl
+;; Utility functions
+;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
+;; License: Good Choices (https://acdw.casa/gcl)
+
+(local util {})
+
+util
+
diff --git a/util.fnl b/util.fnl
deleted file mode 100644
index c884a01..0000000
--- a/util.fnl
+++ /dev/null
@@ -1,13 +0,0 @@
-;;; UTIL.fnl
-;; Utility functions
-;; Copyright (C) 2022 Case Duckworth <acdw@acdw.net>
-;; License: Good Choices (https://acdw.casa/gcl)
-
-(local util {})
-
-(lambda util.printlns [?sep ...]
-  "Print arguments as strings, delimited by ?SEP.
-?SEP defaults to '\n', but can be anything."
-  (print (table.concat [...] (or ?sep "\n"))))
-
-util
-- 
cgit 1.4.1-21-gabe81