iii-cli.lisp 4.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. ;;;; cli.lisp
  2. (in-package #:iii/cli)
  3. (defmacro with-temporary-hook ((connection class hook) &body body)
  4. (let ((conn (gensym))
  5. (cl (gensym))
  6. (h (gensym)))
  7. `(let ((,conn ,connection)
  8. (,cl ,class)
  9. (,h ,hook))
  10. (unwind-protect
  11. (progn
  12. (irc:add-hook ,conn ,cl ,h)
  13. ,@body)
  14. (irc:remove-hook ,conn ,cl ,h)))))
  15. (defmacro with-temporary-hooks ((connection (&rest hooks)) &body body)
  16. (setf hooks (remove-if-not #'second hooks))
  17. (let ((conn (gensym)))
  18. (if (null hooks)
  19. `(progn ,@body)
  20. `(let ((,conn ,connection))
  21. (with-temporary-hook (,conn ,(caar hooks) ,(cadar hooks))
  22. (with-temporary-hooks (,conn (,@(rest hooks))) ,@body))))))
  23. (defun write-privmsg (message &optional (stream *standard-output*))
  24. (multiple-value-bind (s m h) (decode-universal-time (irc:received-time message))
  25. (declare (ignore s))
  26. (format stream "~2,'0D:~2,'0D <~A> ~A" h m (irc:source message) (second (irc:arguments message)))))
  27. (defun privmsg-watcher (channel &optional (stream *standard-output*))
  28. (lambda (message)
  29. (when (string= (first (irc:arguments message)) channel)
  30. (write-privmsg message stream))))
  31. (defun hhmm (time &optional stream)
  32. (multiple-value-bind (s m h) (decode-universal-time time)
  33. (declare (ignore s))
  34. (format stream "~2,'0D:~2,'0D" h m)))
  35. (defun format-part (message &optional stream)
  36. (format stream "~A -!- ~A abiit~@[ (~A)~]" (hhmm (irc:received-time message) stream) (irc:source message) (second (irc:arguments message))))
  37. (defun format-quit (message &optional stream)
  38. (format stream "~A -!- ~A omnino discessit~@[ (~A)~]" (hhmm (irc:received-time message) stream) (irc:source message) (first (irc:arguments message))))
  39. (defun format-join (message &optional stream)
  40. (format stream "~A -!- ~A advenit" (hhmm (irc:received-time message) stream) (irc:source message)))
  41. (defun ircread-main (argv)
  42. (let ((channel (first argv))
  43. (box (safe-queue:make-mailbox)))
  44. (format t "Praesunt:~%~{ ~A~%~}" (sort (loop for user being the hash-values of (irc:users (gethash channel (irc:channels iii:*connection*)))
  45. collect (irc:nickname user))
  46. #'string-lessp))
  47. (finish-output)
  48. (with-temporary-hooks (iii:*connection* (('irc:irc-privmsg-message (lambda (message)
  49. (when (string= (first (irc:arguments message)) channel)
  50. (safe-queue:mailbox-send-message box (write-privmsg message nil)))))
  51. ('irc:irc-part-message (lambda (message)
  52. (when (string= (first (irc:arguments message)) channel)
  53. (safe-queue:mailbox-send-message box (format-part message)))))
  54. ('irc:irc-quit-message (lambda (message)
  55. (when (gethash (irc:normalize-nickname iii:*connection* (irc:source message)) (irc:users (gethash channel (irc:channels iii:*connection*))))
  56. (safe-queue:mailbox-send-message box (format-quit message)))))
  57. ('irc:irc-join-message (lambda (message)
  58. (when (string= (first (irc:arguments message)) channel)
  59. (safe-queue:mailbox-send-message box (format-join message)))))))
  60. (loop
  61. (let ((line (safe-queue:mailbox-receive-message box :timeout 5)))
  62. (when line
  63. (write-line line)
  64. (finish-output))
  65. ;; an atrocious hack instead of (non-existent) pinging
  66. ;; there was without ignore-errors
  67. (unless (ignore-errors (lserver-impl::ping))
  68. (return)))))))
  69. (defun ircmsg-main (argv)
  70. (let ((channel (first argv))
  71. (text (read-line)))
  72. (irc:privmsg iii:*connection* channel text)))