diff options
author | Colin Okay <cbeok@protonmail.com> | 2020-04-12 13:33:22 -0500 |
---|---|---|
committer | Colin Okay <cbeok@protonmail.com> | 2020-04-12 13:33:22 -0500 |
commit | 370fa3f483aae8c932fd42a5ad76c017fcf0c060 (patch) | |
tree | c4554bd7e8969b98a88a4dc840be20a6eae65966 |
initial commit
-rw-r--r-- | package.lisp | 4 | ||||
-rw-r--r-- | posterbot.asd | 11 | ||||
-rw-r--r-- | posterbot.lisp | 43 |
3 files changed, 58 insertions, 0 deletions
diff --git a/package.lisp b/package.lisp new file mode 100644 index 0000000..53845d9 --- /dev/null +++ b/package.lisp @@ -0,0 +1,4 @@ +;;;; package.lisp + +(defpackage #:posterbot + (:use #:cl #:granolin)) diff --git a/posterbot.asd b/posterbot.asd new file mode 100644 index 0000000..18f8cc9 --- /dev/null +++ b/posterbot.asd @@ -0,0 +1,11 @@ +;;;; posterbot.asd + +(asdf:defsystem #:posterbot + :description "A Matrix bot to post media links." + :author "Colin Okay <cbeok@protonmail.com>" + :license "AGPL" + :version "0.0.1" + :serial t + :depends-on (#:granolin #:cl-ppcre #:alexandria #:cl-fad) + :components ((:file "package") + (:file "posterbot"))) diff --git a/posterbot.lisp b/posterbot.lisp new file mode 100644 index 0000000..0ff3160 --- /dev/null +++ b/posterbot.lisp @@ -0,0 +1,43 @@ +;;;; posterbot.lisp + +(in-package #:posterbot) + +(defclass posterbot (client auto-joiner) ()) + +(defvar *posterbot* nil "dynamic variable holding the bot so I dont have to pass it around") + +(defparameter +image-link-regex+ + (ppcre:create-scanner "http.+\.(png|gif|jpeg|bmp|jpg)" + :case-insensitive-mode t)) + +(defun download-link (link) + (cl-fad:with-output-to-temporary-file (out :element-type '(unsigned-byte 8)) + (let ((buffer (make-array 4096 :element-type '(unsigned-byte 8))) + (file-stream (drakma:http-request link :want-stream t))) + (loop :for bytes = (read-sequence buffer file-stream) + :while (plusp bytes) :do (write-sequence buffer out))))) + + +(defun filename-from-link (link) + (first (last (ppcre:split "/" link)))) + +(defun make-mime-type (filename) + (format nil "image/~a" (pathname-type filename))) + +(defun handle-link-candiate (word) + (let ((link (ppcre:scan-to-strings +image-link-regex+ word))) + (when link + (let* ((file-path (download-link link)) + (file-name (filename-from-link link)) + (mxc-uri + (upload *posterbot* + file-name + (alexandria:read-file-into-byte-vector file-path) + :content-type (make-mime-type word)))) + (send-image-message *posterbot* *room-id* file-name mxc-uri + :info (list :|mimetype| (make-mime-type word))))))) + +;; look for links to images, one word at a time, downloading and +;; posting any images found to the room at the current *ROOM-ID* +(defmethod handle-event :after ((*posterbot* posterbot) (event text-message-event)) + (mapc #'handle-link-candiate (ppcre:split " " (msg-body event)))) |