Simple database: Difference between revisions
Content added Content deleted
m (→{{header|Common Lisp}}: improve search, add match by words, search tags) |
(→{{header|Common Lisp}}: edit episode feature, with flexible commandline parsing to select episode) |
||
Line 380: | Line 380: | ||
(defun get-series (name database) |
(defun get-series (name database) |
||
(cdr (assoc name database :test #'equal))) |
(cdr (assoc name database :test #'string-equal))) |
||
(defun get-episode-list (series database) |
(defun get-episode-list (series database) |
||
Line 435: | Line 435: | ||
(defun fuzzy-title (term episode) |
(defun fuzzy-title (term episode) |
||
(let ((matches (length |
|||
(when (set-difference |
|||
(loop for word in term when |
|||
(search word (episode-title episode) :test 'string-equal) |
|||
collect it)))) |
|||
(when (> matches 0) |
|||
matches))) |
|||
(defun match-tags (term episode) |
(defun match-tags (term episode) |
||
( |
(let ((matches (length (intersection (mapcar #'intern term) (episode-tags episode))))) |
||
(when (> matches 0) |
|||
matches))) |
|||
(defun search-title (term database) |
|||
(loop for episode in (get-all database) |
|||
when (match-title term episode) collect it)) |
|||
(defun search-tags (term database) |
|||
(sort (loop for episode in (get-all database) |
|||
for matches = (match-tags term episode) |
|||
when matches collect (list matches episode)) |
|||
#'> :key #'car)) |
|||
(defun search-title-fuzzy (term database) |
|||
(sort (loop for episode in (get-all database) |
|||
for matches = (fuzzy-title term episode) |
|||
when matches collect (list matches episode)) |
|||
#'> :key #'car)) |
|||
(defun search-all (term database) |
(defun search-all (term database) |
||
Line 475: | Line 492: | ||
(list-all-tags *db*)) |
(list-all-tags *db*)) |
||
(terpri)) |
(terpri)) |
||
(defun find-series-episode (term database) |
|||
(let ((series (get-series (format nil "~{~a~^ ~}" (butlast term)) database))) |
|||
(if series |
|||
(let* ((season-episode (car (last term))) |
|||
(pos (position #\- season-episode)) |
|||
(season-str (when pos (subseq season-episode 0 pos))) |
|||
(season (or (parse-integer-quietly season-str) season-str)) |
|||
(episode-str (if pos |
|||
(subseq season-episode (1+ pos)) |
|||
season-episode)) |
|||
(episode-nr (or (parse-integer-quietly episode-str) episode-str))) |
|||
(loop for episode in (series-episodes series) |
|||
when (and (equal (episode-episode episode) episode-nr) |
|||
(equal (episode-season episode) season)) |
|||
collect episode)) |
|||
(let ((series (get-series (format nil "~{~a~^ ~}" term) database))) |
|||
(if series |
|||
(list (car (series-episodes series)))))))) |
|||
(defun find-episode (term database) |
|||
(or (find-series-episode term database) |
|||
(search-title term database) |
|||
(let* ((res (or (search-tags term database) |
|||
(search-title-fuzzy term database))) |
|||
(max (caar res))) |
|||
(loop for (matches episode) in res when (equal matches max) collect episode)))) |
|||
(defun edit-episode (episode database) |
|||
(format t "editing:~%~a~%" episode) |
|||
(setf (episode-series episode) |
|||
(prompt-read "Series Title" (episode-series episode))) |
|||
(setf (episode-title episode) |
|||
(prompt-read "Title" (episode-title episode))) |
|||
(setf (episode-season episode) |
|||
(parse-number (prompt-read "Season" (episode-season episode)))) |
|||
(setf (episode-episode episode) |
|||
(parse-number (prompt-read "Episode" (episode-episode episode)))) |
|||
(setf (episode-part episode) |
|||
(parse-number (prompt-read "Part" (episode-part episode)))) |
|||
(setf (episode-date episode) |
|||
(parse-date (prompt-read "Date watched" (format-ymd (episode-date episode))))) |
|||
(setf (episode-tags episode) |
|||
(parse-tags (prompt-read "Tags" (format nil "~{~a~^ ~}" (episode-tags episode)))))) |
|||
(defun watch-edit (term) |
|||
(let ((episodes (find-episode term *db*))) |
|||
(if (> (length episodes) 1) |
|||
(format t "found more than one episode, please be more specific:~%~{~& ~a~%~}" episodes) |
|||
(edit-episode (car episodes) *db*)))) |
|||
(defun watch-load (dbfile) |
(defun watch-load (dbfile) |
||
Line 501: | Line 569: | ||
((equal (cadr argv) "tags") (watch-tags)) |
((equal (cadr argv) "tags") (watch-tags)) |
||
((equal (cadr argv) "search") (watch-search (cddr argv))) |
((equal (cadr argv) "search") (watch-search (cddr argv))) |
||
((equal (cadr argv) "edit") (watch-edit (cddr argv)) (watch-save dbfile)) |
|||
(T (watch-series (format nil "~{~a~^ ~}" (cdr argv))))))) |
(T (watch-series (format nil "~{~a~^ ~}" (cdr argv))))))) |
||