From: Andrei Date: Wed, 18 Feb 2026 05:53:39 +0000 (-0800) Subject: Migrate the matrix api library to its own system X-Git-Url: https://nullring.xyz/gitweb//%22../style.css/%22?a=commitdiff_plain;h=9122092daa6f42a29c9b60e21df7cec19750a640;p=nullerbot.git Migrate the matrix api library to its own system --- diff --git a/mapi/mapi.asd b/mapi/mapi.asd new file mode 100644 index 0000000..b415c8a --- /dev/null +++ b/mapi/mapi.asd @@ -0,0 +1,31 @@ +(defsystem "mapi" + :version "0.0.1" + :author "Andrei Șova" + :license "MIT" + :depends-on (:com.inuoe.jzon + :dexador + :bordeaux-threads + :cl-hash-util + :quri + :flexi-streams + :split-sequence + :verbose) + :components ((:module "src" + :components + ((:file "package") + (:file "core" :depends-on ("package")) + (:file "commands" :depends-on ("package" "core")) + (:file "util" :depends-on ("package" "core"))))) + :description "Library for interacting with the Matrix Client-Server API" + :in-order-to ((test-op (test-op "mapi/tests")))) + +(defsystem "mapi/tests" + :author "Andrei Șova" + :license "MIT" + :depends-on (:mapi + :rove) + :components ((:module "tests" + :components + ((:file "main")))) + :description "Test system for mapi" + :perform (test-op (op c) (symbol-call :rove :run c))) diff --git a/mapi/src/commands.lisp b/mapi/src/commands.lisp new file mode 100644 index 0000000..ef7a40d --- /dev/null +++ b/mapi/src/commands.lisp @@ -0,0 +1 @@ +(in-package #:org.rm-r.mapi.commands) diff --git a/src/api.lisp b/mapi/src/core.lisp similarity index 73% rename from src/api.lisp rename to mapi/src/core.lisp index 3ed133a..f4b2505 100644 --- a/src/api.lisp +++ b/mapi/src/core.lisp @@ -1,31 +1,4 @@ -;; readers beware: this is currently a very barebones (and amateurish) library -;; -;; In the future it might be packaged into its own thing - -(defpackage nullbot/matrix-api - (:use #:cl - #:cl-hash-util) - (:local-nicknames - (:jzon :com.inuoe.jzon) - (:fs :flexi-streams)) - (:export - #:matrix-user - #:homeserver - #:name - #:listening - #:token - #:lock - #:matrix-bot - #:sendmsg - #:on-event - #:start - #:stop - #:whoami - #:request - #:join - #:leave - #:room-id)) -(in-package #:nullbot/matrix-api) +(in-package #:org.rm-r.mapi) (defclass matrix-client () ((homeserver @@ -92,29 +65,6 @@ (:method ((obj matrix-client) event room-id) (format t "Event Received: ~a~%" event))) -(defun randint (start end) - (+ start (random (+ 1 (- end start))))) - -(defun rand-string (len &aux (arr (make-array len))) - (loop for i from 0 below len do - (setf (aref arr i) (randint 65 90))) - (fs:octets-to-string arr)) - -(defgeneric sendmsg (obj room-id content) - (:method ((obj matrix-client) room-id content - &aux - (msg (make-hash-table :test #'equal)) - (encoded-room-id (quri:url-encode room-id)) - (unique-str (rand-string 20))) - (setf (gethash "msgtype" msg) "m.text") - (setf (gethash "body" msg) content) - (request obj (format nil "/rooms/~a/send/m.room.message/~a" - encoded-room-id - unique-str) - :put - msg - '(("Content-Type" . "application/json"))))) - (defgeneric whoami (obj) (:method ((obj matrix-client)) (request obj "/account/whoami" :get))) @@ -122,12 +72,30 @@ (defgeneric directory-room (obj room-alias) (:method ((obj matrix-client) room-alias) (check-type room-alias room-alias) - )) + (request obj + (format nil "/directory/room/~a" + (quri:url-encode room-alias)) + :get))) (defgeneric join (obj room) (:method ((obj matrix-client) room) - (request obj (format nil "/rooms/~a/join" + (request obj (format nil "/join/~a" (quri:url-encode room)) + :post + (make-hash-table) + '(("Content-Type" . "application/json"))))) + +(defgeneric sync (obj &key timeout since) + (:method ((obj matrix-client) &key timeout since + &aux (params)) + (check-type timeout integer) + (check-type since integer) + (when timeout + (push '("timeout" . timeout) params)) + (when since + (push '("since" . since) params)) + (request obj (format nil "/sync?~a" + (quri:url-encode-params params)) :get))) (defgeneric leave (obj room-id) @@ -153,10 +121,12 @@ (setf (listening obj) t) (bt2:make-thread (lambda (&aux (since) - (sync-route "/sync?timeout=30000")) + ;; TODO: support a configurable timeout + (timeout 30000) + (sync-route (format nil "/sync?timeout=~a" timeout))) (loop while (bt2:with-lock-held ((lock obj)) (listening obj)) do (when since - (setf sync-route (format nil "/sync?timeout=30000&since=~a" since))) + (setf sync-route (format nil "/sync?timeout=~a&since=~a" timeout since))) (let* ((response (request obj sync-route :get)) (rooms-join (hash-get response '("rooms" "join")))) (when rooms-join (loop for room-id being each hash-key of rooms-join diff --git a/mapi/src/package.lisp b/mapi/src/package.lisp new file mode 100644 index 0000000..fb006c9 --- /dev/null +++ b/mapi/src/package.lisp @@ -0,0 +1,36 @@ +(defpackage org.rm-r.mapi + (:use #:cl + #:cl-hash-util) + (:local-nicknames + (#:jzon #:com.inuoe.jzon) + (#:v #:org.shirakumo.verbose)) + (:export + #:matrix-user + #:homeserver + #:name + #:listening + #:token + #:lock + #:matrix-client + #:matrix-bot + #:on-event + #:start + #:stop + #:whoami + #:request + #:join + #:leave + #:room-id)) + +(defpackage org.rm-r.mapi.commands + (:use #:cl) + (:local-nicknames + (#:mapi #:org.rm-r.mapi))) + +(defpackage org.rm-r.mapi.util + (:use #:cl + #:org.rm-r.mapi) + (:export + #:sendmsg) + (:local-nicknames + (#:fs #:flexi-streams))) diff --git a/mapi/src/util.lisp b/mapi/src/util.lisp new file mode 100644 index 0000000..fb4446d --- /dev/null +++ b/mapi/src/util.lisp @@ -0,0 +1,24 @@ +(in-package #:org.rm-r.mapi.util) + +(defun randint (start end) + (+ start (random (+ 1 (- end start))))) + +(defun rand-string (len &aux (arr (make-array len))) + (loop for i from 0 below len do + (setf (aref arr i) (randint 65 90))) + (fs:octets-to-string arr)) + +(defgeneric sendmsg (obj room-id content) + (:method ((obj matrix-client) room-id content + &aux + (msg (make-hash-table :test #'equal)) + (encoded-room-id (quri:url-encode room-id)) + (unique-str (rand-string 20))) + (setf (gethash "msgtype" msg) "m.text") + (setf (gethash "body" msg) content) + (request obj (format nil "/rooms/~a/send/m.room.message/~a" + encoded-room-id + unique-str) + :put + msg + '(("Content-Type" . "application/json"))))) diff --git a/nullbot.asd b/nullbot.asd index 634802d..72c521a 100644 --- a/nullbot.asd +++ b/nullbot.asd @@ -2,7 +2,8 @@ :version "0.0.1" :author "Andrei Șova" :license "MIT" - :depends-on (:com.inuoe.jzon + :depends-on (:mapi + :com.inuoe.jzon :dexador :bordeaux-threads :cl-hash-util @@ -12,8 +13,7 @@ :xmls) :components ((:module "src" :components - ((:file "api") - (:file "main" :depends-on ("api"))))) + ((:file "main")))) :description "A bot for nullring on matrix" :in-order-to ((test-op (test-op "nullbot/tests")))) diff --git a/src/main.lisp b/src/main.lisp index fb74901..d5c6fa8 100644 --- a/src/main.lisp +++ b/src/main.lisp @@ -3,9 +3,10 @@ #:cl-hash-util) (:local-nicknames (:jzon :com.inuoe.jzon) - (:mapi :nullbot/matrix-api) + (:mapi :org.rm-r.mapi) (:sseq :split-sequence) (:dex :dexador)) + (:import-from #:org.rm-r.mapi.util #:sendmsg) (:export #:start)) (in-package #:nullbot) @@ -19,7 +20,6 @@ (defparameter +feed-room-id+ "!ShuXi5ohrPUtKHkrNO:matrix.nullring.xyz") (defparameter +feed-cache-path+ #P"./nullbot_cache.sexp") (defparameter +feed-sleep-minutes+ 1) -(defparameter +weather-vancouver+ ) (defparameter +prefix+ "$") @@ -40,9 +40,9 @@ (when (and (> (length body) 0) (equal (aref (car split-body) 0) #\$)) (cond ((string= command "$help") - (mapi:sendmsg *bot* room-id "Unlike some other bots, I'm nice :3")) + (sendmsg *bot* room-id "Unlike some other bots, I'm nice :3")) ((string= command "$weather") - (mapi:sendmsg *bot* room-id (format nil "It's ~a degrees in Vancouver~%It's ~a degrees in Victoria" (get-temp "YVR") (get-temp "YYJ"))))))) + (sendmsg *bot* room-id (format nil "It's ~a degrees in Vancouver~%It's ~a degrees in Victoria" (get-temp "YVR") (get-temp "YYJ"))))))) (defmethod mapi:on-event ((obj nullbot) event room-id @@ -57,7 +57,7 @@ (car (xmls:node-children obj))) (defun node-attr (obj name) - (second (assoc name (xmls:node-attrs obj) :test #'string=))) + (cdr (assoc name (xmls:node-attrs obj) :test #'string=))) ;; TODO: make this into a generic f-n maybe and also make it not dumb (defun get-node-by-name (obj name) @@ -68,7 +68,7 @@ return child)) (defun send-entry (entry) - (mapi:sendmsg + (sendmsg *bot* +feed-room-id+ (format nil "New message on mailing list!~%Title: ~a~%From: ~a~%Link: ~a~%"