-
-(define (echo-back-message socket my-name speaker
- channel-name message is-action)
- (if is-action
- (format #t "~a emoted ~s in channel ~a\n"
- speaker message channel-name)
- (format #t "~a said ~s in channel ~a\n"
- speaker message channel-name)))
-
-(define default-handle-privmsg echo-back-message)
-
-(define* (make-handle-line #:key
- (handle-privmsg default-handle-privmsg))
- (define (handle-line socket line my-username)
- (let ((parsed-line (parse-line line)))
- (match (irc-line-command parsed-line)
- ("PING"
- (irc-display "PONG" socket))
- ("PRIVMSG"
- (receive (channel-name message is-action)
- (condense-privmsg-line (irc-line-params parsed-line))
- (let ((username (irc-line-username parsed-line)))
- (handle-privmsg socket my-username username
- channel-name message is-action))))
- (_
- (display line)
- (newline)))))
- handle-line)
-
-(define (make-basic-irc-handler handle-line username)
- (let ((buffer '()))
- (define (reset-buffer)
- (set! buffer '()))
- (define (should-read-char socket)
- (and (not (port-closed? socket))
- (char-ready? socket)
- (not (eof-object? (peek-char socket)))))
- (define (irc-handler socket)
- (while (should-read-char socket)
- (set! buffer (cons (read-char socket) buffer))
- (match buffer
- ((#\newline #\return (? char? line-chars) ...)
- (let ((ready-line (list->string (reverse line-chars))))
- ;; reset buffer
- (set! buffer '())
- ;; run it
- (%8sync-run (handle-line
- socket
- ready-line
- username))))
- (_ #f)))
- ;; I need to shut things down on EOF object
- (cond
- ((port-closed? socket)
- (display "port closed time\n")
- (port-remove-request socket))
- ((and (char-ready? socket)
- (eof-object? (peek-char socket)))
- (display "port eof time\n")
- (close socket)
- (port-remove-request socket))))
- irc-handler))
-
-(define default-line-handler (make-handle-line))
-
-(define* (queue-and-start-irc-agenda! agenda socket #:key
- (username "syncbot")
- (inet-port default-irc-port)
- (line-handler default-line-handler)
- (channels '()))
- (dynamic-wind
- (lambda () #f)
- (lambda ()
- (enq! (agenda-queue agenda)
- (wrap (install-socket
- socket
- (make-basic-irc-handler
- line-handler
- username))))
- (enq! (agenda-queue agenda) (wrap (handle-login socket username
- #:channels channels)))
- (start-agenda agenda))
- (lambda ()
- (display "Cleaning up...\n")
- (close socket))))
-
-
-\f
-;;; CLI
-;;; ===
-
-(define option-spec
- `((server (single-char #\s) (required? #t) (value #t))
- (port (single-char #\p)
- (value #t)
- (predicate
- ,(lambda (s)
- (if (string->number s) #t #f))))
- (username (single-char #\u) (required? #t) (value #t))
- (channels (value #t))
- (listen)))
-
-(define* (make-irc-bot-cli #:optional
- (line-handler default-line-handler)
- (print-and-continue-on-error #t))
- (define (main args)
- (let* ((options (getopt-long args option-spec))
- (hostname (option-ref options 'server #f))
- (port (or (option-ref options 'port #f)
- default-irc-port))
- (username (option-ref options 'username #f))
- (listen (option-ref options 'listen #f))
- (channels (option-ref options 'channels ""))
- (agenda (if print-and-continue-on-error
- (make-agenda #:pre-unwind-handler print-error-and-continue)
- (make-agenda))))
- (display `((server ,hostname) (port ,port) (username ,username)
- (listen ,listen) (channels-split ,(string-split channels #\space))))
- (newline)
- (if listen
- (spawn-and-queue-repl-server! agenda))
- (queue-and-start-irc-agenda!
- agenda
- (irc-socket-setup hostname port)
- #:inet-port port
- #:username username
- #:channels (string-split channels #\space)
- #:line-handler line-handler)))
- main)
-
-(define main (make-irc-bot-cli))