Simple database: Difference between revisions

(see also)
Line 24:
 
See also [[Take notes on the command line]] for a related task.
=={{header|Common Lisp}}==
 
a tool to track the episodes you have watched in a series.
tested with [[SBCL]] but should work with other implementations.
 
run from the commandline as:
sbcl --script watch.lisp
 
without arguments the function <code>(watch-list)</code> is invoked to show the last episode of each series.
with the argument <code>add</code> the function <code>(watch-add)</code> will allow you to add a new episode with series name, episode title, episode number and date watched. if the series does not yet exist you will be asked if you want to create it.
 
this code is also available under the GNU GPLv3.
 
<lang lisp>(defun make-episode (series title episode date-watched)
`((series . ,series) (episode . ,episode) (title . ,title) (date . ,date-watched)))
 
(defvar db nil)
 
 
(defun dump-db (database)
(format t "~{~{~a:~10t~a~%~}~%~}" database))
 
(defun print-episode (episode)
(format t "~30a ~10a ~30a (~{~a~^.~})~%" (cdr (assoc 'series episode)) (cdr (assoc 'episode episode)) (cdr (assoc 'title episode)) (cdr (assoc 'date episode))))
 
(defun get-latest (database)
(cond ((endp database) nil)
(T (cons (cadr (assoc 'episodes (cdar database))) (get-latest (cdr database))))))
 
(defun compare-date (a b)
(cond ((not (and (listp a) (listp b))) nil)
((null a) (not (null b)))
((null b) nil)
((= (first a) (first b)) (compare-date (rest a) (rest b)))
(t (< (first a) (first b))) ))
 
(defun compare-by-date (a b)
(compare-date (reverse (cdr (assoc 'date a))) (reverse (cdr (assoc 'date b)))))
 
(defun watch-list ()
(mapcar #'print-episode (sort (get-latest db) #'compare-by-date)))
 
(defun prompt-read (prompt)
(format *query-io* "~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))
 
(defun split (seperator string)
(loop for i = 0 then (1+ j)
as j = (search seperator string :start2 i)
collect (subseq string i j)
while j))
 
(defun parse-date (date)
(mapcar #'parse-integer (split "." date)))
 
(defun prompt-for-episode ()
(make-episode
(prompt-read "Series")
(prompt-read "Title")
(prompt-read "Episode")
(parse-date (prompt-read "Date watched"))))
 
(defun add-episodes ()
(loop (push (prompt-for-episode) db)
(if (not (y-or-n-p "Another? [y/n]: ")) (return))))
 
(defun save-db (filename database)
(with-open-file (out filename
:direction :output
:if-exists :supersede)
(with-standard-io-syntax
(pprint database out))))
 
(defun watch-save ()
(save-db "lwatch" db))
 
(defun load-db (filename database)
(with-open-file (in filename)
(with-standard-io-syntax
(setf database (read in)))))
 
(defun has-series (name list)
(assoc name list :test #'equal))
 
(defun get-series (name list)
(cdr (assoc name list :test #'equal)))
 
(defun get-episode-list (series list)
(cdr (assoc 'episodes (get-series series list))))
 
(defun watch-add-series (name status)
(cdar (push `(,name (series . ,name) (status . ,status) (episodes)) db)))
 
(defun get-or-add-series (name database)
(or (get-series name database)
(if (y-or-n-p "Add new series? [y/n]: ")
(watch-add-series name 'active) nil)))
 
(defun watch-add ()
(let* ((episode (prompt-for-episode))
(series-name (cdr (assoc 'series episode)))
(series (get-or-add-series series-name db)))
(if (endp series) (watch-add)
(rplacd (assoc 'episodes series)
(cons episode (get-episode-list series-name db))))))
 
(defun watch-load ()
(with-open-file (in "lwatch") (with-standard-io-syntax (setf db (read in)))))
 
 
(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)
(cond ((equal (cadr argv) "add") (watch-add) (watch-save))
(T (watch-list))))
 
(main (argv))</lang>
 
=={{header|UNIX Shell}}==
This format is guaranteed to be human readable: if you can type it, you can read it.
Anonymous user