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
(mapcar #'(lambda (word)
(loop for word in term when
(search word (episode-title episode) :test 'string-equal))
(search word (episode-title episode) :test 'string-equal)
term)
collect it))))
'(NIL))
(when (> matches 0)
episode))
matches)))


(defun match-tags (term episode)
(defun match-tags (term episode)
(when (intersection (mapcar #'intern term) (episode-tags episode))
(let ((matches (length (intersection (mapcar #'intern term) (episode-tags episode)))))
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)))))))