(in-package 3harder)
(defvar *posts* (list))
(when (probe-file #p"posts.txt")
(let ((*read-eval* nil))
(with-open-file (in #p"posts.txt")
(loop for post = (read in nil nil)
while post
do (push post *posts*)))))
(defun serve ()
(let ((socket (usocket:socket-listen "127.0.0.1" 12345)) (connection nil))
(loop
(ignore-errors
(unwind-protect
(setf connection (usocket:socket-accept socket :element-type 'character))
(usocket:wait-for-input connection)
(let* ((*read-eval* nil) (stream (usocket:socket-stream connection)))
(loop initially (format *terminal-io* "Connected at ~d~%" (get-universal-time))
for item-type = (ignore-errors (read-char stream))
for alist = (ignore-errors (read stream))
for message = (ignore-errors (read stream))
do (princ (list item-type alist message))
do (terpri)
do (assert (or (null alist) (consp alist)))
do (unless (or (null message))
(with-open-file (s #p"posts.txt" :direction :output :if-exists :append :if-does-not-exist :create)
(prin1 (cons alist message) s) (terpri s)))
do (if (null message)
(format stream "~{~s~%~}"
(mapcan
(lambda (post) (if (subsetp alist (car post) :test 'equalp) (list post) nil)) *posts*))
(format stream "~{~s~%~}~%"
(mapcan
(lambda (post) (if (subsetp alist (car post) :test 'equalp) (list post) nil))
(push (cons alist message) *posts*))))
do (return))
(format *terminal-io* "finished message")
(terpri stream)
(force-output stream) (sleep 1))
(progn (format *terminal-io* "Connection closing at ~D~%" (get-universal-time))
(usocket:socket-close connection)))))))
(serve)