#|
Well! This phlog post implements comprehension of the storm radio recordings by jns:
gopher://gopher.linkerror.com/0/phlog/2023/20230403
"
The filenames start with the talkgroup id followed by the timestamp
of the recording. For example:
9021-1680324909_855162500-call_4036.m4a
would be tgid: 9021 and timestamp: 1680324909
Standard unix timestamp, you should be able to convert it to human-
readable text with the date command, eg:
> date -d @1680324909
Fri Mar 31 11:55:09 PM CDT 2023
"
And I used macros.
Including! In order to be able to READ - and _ I modified the readtable;
which clojure says isn't a good idea,
so I only modified a local copy of the readtable.
Example:
Having recordings/9021-1680324909_855162500-call_4036.m4a
$ rlwrap ecl -load jns-storm-filenames.lisp
> (comprehend-directory #p"recordings/*.*")
(((NAMESTRING . "9021-1680324909_855162500-call_4036.m4a")
(DECODED-TIME (YEA . 2023) (MON . 3) (DAY . 31) (HOU . 23) (MIN . 55)
(SEC . 9))
(TGID . 9021) (UNIX-TIME . 1680324909) (LOCATION? . 855162500)
(UNUSED . CALL) (INDEX . 4036)))
This solves sorting and filtering in lisp using association list tools.
Common Lisp has its own directory wildcard stuff #p"foo/*.*"
|#
(defun do-nothing (s c) "
Placed in tmp *readtable* for #\- and #\_
"
(read s t nil t))
(defmacro decode-unix-time (time &aux
(fields
'(sec min hou day mon yea))) "
(decode-universal-time (+ time 2208970800))
2208970800 seconds seem to be the difference.
"
`(multiple-value-bind ,fields
(decode-universal-time (+ ,time 2208970800))
(pairlis
'(,@fields)
,(append '(list) fields))))
(defmacro comprehend-path-name (name) "
(comprehend-namestring name)
name is actually the string from (pathname-name path)
"
`(let ((*readtable* (copy-readtable nil)))
(set-macro-character #\- #'do-nothing)
(set-macro-character #\_ #'do-nothing)
(with-input-from-string (in ,name)
(loop for no = (handler-case (read in nil nil) (end-of-file (e) nil))
for field in '(tgid unix-time location? unused index)
while no collect `(,field . ,no)))))
(defun comprehend-directory (dir &aux (files (directory dir))) "
(comprehend-directory #p\"path/to/files/*.*\")
"
(loop for file in files
for namestring = (file-namestring file)
for path-name = (pathname-name file)
for alist = (comprehend-path-name path-name)
for time = (decode-unix-time
(cdr (assoc 'unix-time alist)))
collect
(append `((namestring . ,namestring)
(decoded-time . ,time))
alist)))