From 8796c78b9ee8943bf9a95ea616d4232e997e066d Mon Sep 17 00:00:00 2001 From: Lucian Mogosanu Date: Thu, 25 Apr 2019 12:39:29 +0300 Subject: [PATCH] Add feedbot-iii draft --- drafts/000-feedbot-iii.markdown | 173 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 drafts/000-feedbot-iii.markdown diff --git a/drafts/000-feedbot-iii.markdown b/drafts/000-feedbot-iii.markdown new file mode 100644 index 0000000..e75ab2f --- /dev/null +++ b/drafts/000-feedbot-iii.markdown @@ -0,0 +1,173 @@ +--- +postid: 000 +title: Feedbot [iii]: the IRC bot +date: April 25, 2019 +author: Lucian Mogoșanu +tags: tech, tmsr +--- + +All the basic building blocks pertaining to RSS functionality -- +i.e. the [checker][feedbot-i] and the [announcer][feedbot-ii] -- being +in place, we conclude the [Feedbot][feedbot] series with: + +* The [V patch][feedbot-irc.vpatch]; and +* my [seal][feedbot-irc.vpatch.spyked.sig]. + +The patch in this episode introduces the following changes: + +* Some methods are removed, due to their retrospective uselessness; + some methods are added, due to them being found useful for both IRC + implementation and maintenance operations. +* Auxiliary functions are provided in order to handle IRC operation + and Feedbot command argument parsing. +* Most importantly, functionality is added to: manage the bot state; + glue to Ircbot and adapt the announcer to IRC; and implement + [Trilemabot][trilemabot] commands. + +The remainder of this post will detail the last bullet above. The +reader is however encouraged to read the [V patch][feedbot-irc.vpatch] +in its entirety, to get a broader image of the changes. + +**VII. State management** + +Feedbot state is a list of the form: + +~~~~ {.commonlisp} +(feed-db msg-queue) +~~~~ + +where `feed-db` is a feed db and `msg-queue` is a message queue. + +Feedbot state is kept persistent using principally the feedbot +`save-state` and `load-state` methods: + +~~~~ {.commonlisp} +(defmethod feedbot-save-state ((bot feedbot) &optional (path "state.sexp")) + "Save bot state to disk location given by `path'." + (let ((feed-db (with-feed-db (feed-db) bot feed-db)) + (msg-queue (with-msg-queue (msg-queue) bot msg-queue))) + (with-open-file (out path + :direction :output + :if-does-not-exist :create + :if-exists :supersede) + (write (list feed-db msg-queue) :stream out) + nil))) + +(defmethod feedbot-load-state ((bot feedbot) &optional (path "state.sexp")) + "Load bot state from disk location given by `path'. + +This method throws an error condition if the bot contains pre-existing +state, i.e. `feed-db' and `msg-queue' are non-NIL." + (with-slots (feed-db msg-queue) bot + (assert (not feed-db)) + (assert (not msg-queue))) + (feedbot-reload-state bot path)) +~~~~ + +**VIII. Ircbot glue** + +IRC glue: + +**a\.** implements [entry announcer][announcer] functionality: + +~~~~ {.commonlisp} +(defun announce-irc! (bot msg) + (announce-stdout! msg) + (let ((rcpt (get-msg-to! msg)) + (entry (get-msg-entry! msg))) + (ircbot-send-message bot rcpt + (format nil "~a << ~a -- ~a~%" + (get-entry-link entry) + (get-msg-feed-title! msg) + (get-entry-title entry))))) +~~~~ + +**b\.** starts the checker and announcer threads on rpl_welcome: + +~~~~ {.commonlisp} +(defun feedbot-rpl_welcome (bot message) + (declare (ignore message)) + (feedbot-start-checker-thread bot) + (feedbot-start-announcer-thread bot)) +~~~~ + +**c\.** sends messages to online nicks on rpl_ison + +~~~~ {.commonlisp} +(defun feedbot-rpl_ison (bot message) + ;; Only when our reply contains some nicks... + (when (cdr (arguments message)) + (let ((nicks (parse-ison (cadr (arguments message))))) + ;; Process messages... + (feedbot-process-msg-queue + bot #'(lambda (msg) + ;; Only when msg not send and :to is online... + (when (and (not (get-msg-sent! msg)) + (member (get-msg-to! msg) nicks + :test #'string=)) + ;; Wait a bit + (sleep *announce-delay*) + ;; Announce and mark as sent. + (announce-irc! bot msg) + (set-msg-sent! msg))))))) +~~~~ + +**d\.** implements ircbot-{connect,disconnect} routines + +~~~~ {.commonlisp} +(defmethod ircbot-connect :after ((bot feedbot)) + (feedbot-load-state bot) + (let ((conn (ircbot-connection bot))) + (add-hook conn 'irc-rpl_welcome-message + #'(lambda (message) + (feedbot-rpl_welcome bot message))) + (add-hook conn 'irc-rpl_ison-message + #'(lambda (message) + (feedbot-rpl_ison bot message))))) + +(defmethod ircbot-disconnect :after ((bot feedbot) + &optional (quit-msg "feedbot out")) + (declare (ignore quit-msg)) + (with-slots (db-mutex queue-mutex checker-thread announcer-thread) bot + (ignore-errors + (release-mutex db-mutex :if-not-owner :force) + (release-mutex queue-mutex :if-not-owner :force) + (terminate-thread checker-thread) + (terminate-thread announcer-thread)) + (setf checker-thread nil + announcer-thread nil) + (feedbot-flush-state bot))) +~~~~ + +**IX. Trilemabot commands** + +Consult [the feedbot manual][feedbot-manual] for more details. + +~~~~ {.commonlisp} +(trilemabot-define-cmd (:help bot message target arguments) + (declare (ignore arguments)) + (ircbot-send-message bot (response-rcpt bot message target) + "http://thetarpit.org/posts/y05/081-feedbot-manual.html")) +~~~~ + +**Post codex:** In total, Feedbot weighs circa nine hundred lines of +code, of which almost a hundred comprise auxiliary functionality +(parsing, sanitization and low-level IRC code), the rest being mostly +Feedbot mechanism. Of these, about 23% are comments and another 7% are +inline function documentation strings. + +The mechanism is, as far as I'm concerned, done. There are some +operator-side bits missing (e.g. bulk adding/removal of feeds), but +then again, some of them can be easily scripted, while others are more +indicative of brain-fixing rather than any imagined code-fixing. + +Bug fixes and other comments are, as usual, more than welcome. + +[feedbot-i]: /posts/y05/08a-feedbot-i.html +[feedbot-ii]: /posts/y05/08b-feedbot-ii.html +[feedbot]: http://btcbase.org/log-search?q=feedbot +[feedbot-irc.vpatch]: TODO +[feedbot-irc.vpatch.spyked.sig] +[trilemabot]: /posts/y05/078-trilemabot-ii.html +[announcer]: /posts/y05/08b-feedbot-ii.html#selection-249.0-252.0 +[feedbot-manual]: /posts/y05/081-feedbot-manual.html -- 1.7.10.4