Anonymous user
Simple database: Difference between revisions
→{{header|Common Lisp}}: add function to list all episodes, implement some suggestions from the friendly people in #lisp
(→{{header|Common Lisp}}: handle non-numeric month values) |
(→{{header|Common Lisp}}: add function to list all episodes, implement some suggestions from the friendly people in #lisp) |
||
Line 36:
This code is also available under the GNU GPLv3.
<lang lisp>(defvar *db* nil)
(defun get-value (key alist)
(cdr (assoc key alist)))
(defun make-episode (&key series title season episode date tags)
(defun print-episode (episode)
(format t " ~30a ~@[~a-~]~a~40T~a~@[ ~70T(~{~a~^.~})~]~@[ (~{~a~^ ~})~]~%"
(
(
(
(
(
(
(defun print-episodes (episodes series)
Line 58 ⟶ 61:
(cond ((endp database) nil)
(T (cons (cadr (assoc 'episodes (cdar database))) (get-latest (cdr database))))))
(defun get-all (database)
(cond ((endp database) nil)
(T (append (get-value 'episodes (cdar database)) (get-all (cdr database))))))
(defun cal->int (cal)
(cond ((integerp cal) cal)
(T (get-value cal '(('jan . 1) ('feb . 2) ('mar . 3) ('apr . 4)
('may . 5) ('jun . 6) ('jul . 7) ('aug . 8)
('sep . 9) ('oct . 10) ('nov . 11) ('dec . 12))))))
Line 69 ⟶ 76:
((null a) (not (null b)))
((null b) nil)
((= (cal->int (first a)) (cal->int (first b)))
(compare-date (rest a) (rest b)))
(t (< (cal->int (first a)) (cal->int (first b))))))
(defun compare-by-date (a b)
(compare-date (reverse (
(defun prompt-read (prompt &optional default)
Line 80 ⟶ 87:
(force-output *query-io*)
(let ((answer (read-line *query-io*)))
default
answer)))
(defun split (seperator string)
(defun format-ymd ()
(multiple-value-bind (second minute hour date month year day-of-week dst-p tz)
Line 92 ⟶ 102:
(declare (ignore second minute hour day-of-week dst-p tz))
(format nil "~a.~a.~a" date month year)))
(defun parse-date (date)
Line 101 ⟶ 112:
(defun parse-number (number)
(if (stringp number)
(parse-integer number :junk-allowed t)
number))
(defun prompt-for-episode (&optional last)
(defun save-db (filename database)
Line 123 ⟶ 136:
(defun watch-save ()
(defun load-db (filename)
Line 131 ⟶ 144:
(defun get-series (name database)
(
(defun get-episode-list (series database)
(
(defun print-series (series)
(mapcar #'print-episode (
(defun watch-series (title)
(let ((series (get-series title *db*)))
(format t "~30a ~
(mapcar #'print-episode (reverse (
(defun dump-db (database)
Line 150 ⟶ 163:
(defun watch-latest ()
(defun watch-all ()
(mapcar #'print-episode (sort (get-all *db*) #'compare-by-date)))
(defun watch-new-series (&key name
(cdar (push `(,name (
(defun get-or-add-series (name database)
(or (get-series name database)
(if (y-or-n-p "Add new series? [y/n]: ")
(watch-new-series
:name name
:description (prompt-read "Description" name)
:tags (parse-tags (prompt-read "Tags" "active")))
nil)))
(defun watch-add ()
(let* ((series (loop thereis (get-or-add-series (prompt-read "Series") *db*)))
;(
(episodes (get-value 'episodes series))
(episode (prompt-for-episode (car episodes))))
(defun watch-series-names ()
(format T "~{~a~%~}"
(sort (mapcar #'car *db*)
#'(lambda (series1 series2)
(compare-by-date (cadr (assoc 'episodes (
(cadr (assoc 'episodes (
(defun watch-load (dbfile)
(setf *db* (load-db
(defun argv ()
(or
#+clisp (ext:argv)
#+sbcl sb-ext:*posix-argv*
#+clozure (ccl::command-line-arguments)
#+gcl si:*command-args*
#+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
#+cmu extensions:*command-line-strings*
#+allegro (sys:command-line-arguments)
#+lispworks sys:*line-arguments-list*
nil))
(defun main (argv)
(watch-load (make-pathname :name "lwatch" :type nil :defaults *load-truename*))
(cond ((equal (cadr argv) "add") (watch-add) (watch-save))
((equal (cadr argv) "latest") (watch-latest))
((null (cadr argv)) (watch-latest))
((equal (cadr argv) "series") (watch-series-names))
((equal (cadr argv) "all") (watch-all))
(T (watch-series (cadr argv)))))
|