largely works; annoying problems remain

This commit is contained in:
mehbark 2024-04-17 01:06:24 -04:00
parent 03f0b12ea9
commit cc28c85b38

View file

@ -1,29 +1,69 @@
(ql:quickload '(:cl-yaml :alexandria :cl-ppcre)) (ql:quickload '(:alexandria :cl-yaml :cl-json :yason))
(defpackage :hsmusic (defpackage :hsmusic
(:use :common-lisp :alexandria)) (:use :common-lisp :alexandria))
(in-package :hsmusic) (in-package :hsmusic)
(defpackage :track)
(defparameter tracks (defparameter tracks
(loop for path in (directory #p"hsmusic-data/album/*.yaml") (loop for path in (directory #p"hsmusic-data/album/*.yaml")
appending (loop for entry in (yaml:parse path :multi-document-p t) appending
(let* ((parsed (yaml:parse path :multi-document-p t))
(album (gethash "Album" (cadr parsed))))
(loop for entry in parsed
when (and (not (symbolp entry)) (gethash "Track" entry)) when (and (not (symbolp entry)) (gethash "Track" entry))
collect entry))) collect (progn (setf (gethash "Album" entry) album)
entry)))))
(defun tracks-with-name (name)
(loop for track in tracks
when (equal name (gethash "Track" track))
collect track))
; does a macro really make sense like come on
; w/e
(defmacro apply-regices (target &body regices)
(with-gensyms (new)
`(let ((,new (copy-array ,target)))
,@(loop for (from to) in regices
collecting `(setf ,new (ppcre:regex-replace-all ,from ,new ,to)))
,new)))
(defun default-href (name)
(apply-regices (string-downcase name)
(" " "-")
("&" "-and-")
("\\+" "-plus-")
("%" "-percent-")
("(\\b[^\\s-.]{2,})\\." "\\1-")
("/\\.([^\\s-.]{2,})\\b" "-\\1")
("[/@#$%*()_=,[\\]{}|\\\\;:<>?`~]" "-")
("[áâäàå]" "a")
("[çč]" "c")
("[éêëè]" "e")
("[íîïì]" "i")
("[óôöò]" "o")
("[úûüù]" "u")
("[^a-z0-9-]" "")
("-{2,}" "-")
("^-+|-+$" "")))
; terrible, idc
; lossy! (not surprising)
; upcase for nice interning
(defun track->href (track) (defun track->href (track)
(or (gethash "Directory" track) (or (gethash "Directory" track)
(let ((r (copy-array (gethash "Track" track)))) (default-href (gethash "Track" track))))
(setf r (ppcre:regex-replace-all " " r "-"))
(setf r (ppcre:regex-replace-all "&" r "and")) (defun href->url (href)
(setf r (ppcre:regex-replace-all "[^a-zA-Z0-9-]" r "")) (format nil "https://hsmusic.wiki/track/~a" href))
(setf r (ppcre:regex-replace-all "-{2,}" r ""))
(setf r (ppcre:regex-replace-all "^-+|-+$" r ""))
(nstring-downcase r))))
(defun track->url (track) (defun track->url (track)
(format nil "https://hsmusic.wiki/track/~a" (track->href track))) (href->url (track->href track)))
; let's just store the href because that's unambiguous and links are desirable anyway ; let's just store the href because that's unambiguous and links are desirable anyway
@ -32,8 +72,26 @@
; there's ambiguity here! so consult only when not given a track:! ; there's ambiguity here! so consult only when not given a track:!
(defparameter hrefs (make-hash-table :test 'equal)) (defparameter hrefs (make-hash-table :test 'equal))
; TODO: logically flawed
(defparameter href->track-table (make-hash-table))
(loop for track in tracks (loop for track in tracks
do (setf (gethash (gethash "Track" track) hrefs) (track->href track))) ; works? no. e.g. Buy NAK Sell DOOF has a Directory but is referred to without track:
; track: is a disambiguator
; how do we decide which one is "canon" then? idk! no clue. help
; tomorrow problem
unless (gethash "Directory" track)
do (let ((href (intern (track->href track) :track)))
(setf (gethash (gethash "Track" track) hrefs) href)
(setf (gethash href href->track-table) track)))
(defun track-name->href (name)
(if (string= (ignore-errors (subseq name 0 6)) "track:")
(intern (subseq name 6) :track)
(gethash name hrefs)))
(defun href->track (href)
(gethash href href->track-table))
; a -> b <-> a references b ; a -> b <-> a references b
; screw it! let's use symbols. why not? (LKFDSJKFDJ) ; screw it! let's use symbols. why not? (LKFDSJKFDJ)
@ -42,13 +100,15 @@
(defparameter <- (make-hash-table)) (defparameter <- (make-hash-table))
(loop for track in tracks (loop for track in tracks
do (let ((from-name (intern (track-normalized-name track) :keyword))) do (let ((from-name (intern (track->href track) :track)))
(loop for ref in (append (gethash "Referenced Tracks" track) (gethash "Sampled Tracks" track)) (loop for ref in (append (gethash "Referenced Tracks" track) (gethash "Sampled Tracks" track))
do (let ((to-name (intern (normalize-name ref) :keyword))) do (let ((to-name (track-name->href ref)))
; bodge (when (not to-name) (print ref))
(unless (eq from-name to-name) (if (eq from-name to-name)
(format t "https://hsmusic.wiki/track/~a~%" from-name)
(progn
(unionf (gethash from-name ->) (list to-name)) (unionf (gethash from-name ->) (list to-name))
(unionf (gethash to-name <-) (list from-name))))))) (unionf (gethash to-name <-) (list from-name))))))))
(defun tree (src from depth) (defun tree (src from depth)
(let ((succs (gethash from src))) (let ((succs (gethash from src)))
@ -57,10 +117,10 @@
from))) from)))
(defun ->tree (from depth) (defun ->tree (from depth)
(tree -> from depth)) (tree -> (track-name->href from) depth))
(defun <-tree (from depth) (defun <-tree (from depth)
(tree <- from depth)) (tree <- (track-name->href from) depth))
(defun pp-tree (tree &key (stream t) (indent 0) (indent-increment 2)) (defun pp-tree (tree &key (stream t) (indent 0) (indent-increment 2))
(let ((ind (make-string indent :initial-element #\ ))) (let ((ind (make-string indent :initial-element #\ )))
@ -72,3 +132,27 @@
do (pp-tree to :stream stream do (pp-tree to :stream stream
:indent (+ indent indent-increment) :indent (+ indent indent-increment)
:indent-increment indent-increment)))))) :indent-increment indent-increment))))))
(defun archive (url)
(sb-ext:run-program
"/usr/bin/env"
(list "curl" "--insecure" "-F" (format nil "url=~a" "url=") "-F" "capture_all=on" url)))
(defparameter exif (yason:parse #p"/home/mbk/Music/exif-data.json"))
(defun track->path (track)
(loop for e in exif
when (and (equal (gethash "Title" e) (gethash "Track" track))
(equal (gethash "Album" e) (gethash "Album" track)))
do (return-from track->path (pathname (gethash "SourceFile" e)))))
; TODO: <- & higher-order
; reversed bc personal preference :]
(defun ->m3u (from &optional (depth 413) (stream t))
(dolist (href (reverse (flatten (->tree from depth))))
(let ((path (track->path (href->track href))))
(when path (format stream "~a~%" path)))))
(defun ->link-list (from &optional (depth 413) (stream t))
(dolist (href (reverse (flatten (->tree from depth))))
(format stream "~a~%" (href->url href))))