diff options
| author | 2025-10-12 22:14:39 +0300 | |
|---|---|---|
| committer | 2025-10-12 22:14:39 +0300 | |
| commit | 31a972d6825114b1a971e42cdc86e1bd7a9834c3 (patch) | |
| tree | b40ff73cc76ff88d969b9e12325fd4b17e68dadc | |
| parent | msginfo: pretty print the response (diff) | |
| download | ukkoclot-31a972d6825114b1a971e42cdc86e1bd7a9834c3.tar.gz ukkoclot-31a972d6825114b1a971e42cdc86e1bd7a9834c3.tar.xz ukkoclot-31a972d6825114b1a971e42cdc86e1bd7a9834c3.zip | |
Introduce enums and a pretty parse-mode type
| -rw-r--r-- | src/bot/methods.lisp | 7 | ||||
| -rw-r--r-- | src/enum.lisp | 59 | ||||
| -rw-r--r-- | src/inline-bots.lisp | 2 | ||||
| -rw-r--r-- | src/main.lisp | 14 | ||||
| -rw-r--r-- | src/tg-types.lisp | 1 | ||||
| -rw-r--r-- | src/tg-types/parse-mode.lisp | 11 |
6 files changed, 83 insertions, 11 deletions
diff --git a/src/bot/methods.lisp b/src/bot/methods.lisp index 7ccc4ad..984646a 100644 --- a/src/bot/methods.lisp +++ b/src/bot/methods.lisp | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | (message-id (or integer null) nil) | 23 | (message-id (or integer null) nil) |
| 24 | (inline-message-id (or string null) nil) | 24 | (inline-message-id (or string null) nil) |
| 25 | (text string) | 25 | (text string) |
| 26 | (parse-mode (or string null) nil) | 26 | (parse-mode (or parse-mode null) nil) |
| 27 | (entities (or (array message-entity) null) nil) | 27 | (entities (or (array message-entity) null) nil) |
| 28 | (link-preview-options (or link-preview-options null) nil) | 28 | (link-preview-options (or link-preview-options null) nil) |
| 29 | (reply-markup (or inline-keyboard-markup null) nil)) | 29 | (reply-markup (or inline-keyboard-markup null) nil)) |
| @@ -56,7 +56,7 @@ | |||
| 56 | (height (or integer null) nil) | 56 | (height (or integer null) nil) |
| 57 | (thumbnail (or pathname string null) nil) | 57 | (thumbnail (or pathname string null) nil) |
| 58 | (caption (or string null) nil) | 58 | (caption (or string null) nil) |
| 59 | (parse-mode (or string null) nil) | 59 | (parse-mode (or parse-mode null) nil) |
| 60 | (caption-entities (or (array message-entity) null) nil) | 60 | (caption-entities (or (array message-entity) null) nil) |
| 61 | (show-caption-above-media boolean nil) | 61 | (show-caption-above-media boolean nil) |
| 62 | (has-spoiler boolean nil) | 62 | (has-spoiler boolean nil) |
| @@ -73,8 +73,7 @@ | |||
| 73 | (chat-id (or integer string)) | 73 | (chat-id (or integer string)) |
| 74 | (message-thread-id (or integer null) nil) | 74 | (message-thread-id (or integer null) nil) |
| 75 | (text string) | 75 | (text string) |
| 76 | ;; TODO: parse-mode should maybe be keywords? | 76 | (parse-mode (or parse-mode null) nil) |
| 77 | (parse-mode (or string null) nil) | ||
| 78 | (entities (or (array message-entity) null) nil) | 77 | (entities (or (array message-entity) null) nil) |
| 79 | (link-preview-options (or link-preview-options null) nil) | 78 | (link-preview-options (or link-preview-options null) nil) |
| 80 | (disable-notification (or boolean null) nil) | 79 | (disable-notification (or boolean null) nil) |
diff --git a/src/enum.lisp b/src/enum.lisp new file mode 100644 index 0000000..c678ec7 --- /dev/null +++ b/src/enum.lisp | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | ;; SPDX-License-Identifier: EUPL-1.2 | ||
| 2 | ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> | ||
| 3 | (defpackage :ukkoclot/enum | ||
| 4 | (:use :c2cl :iterate) | ||
| 5 | (:import-from :ukkoclot/bot/impl :fixup-value :parse-value) | ||
| 6 | (:import-from :string-case :string-case) | ||
| 7 | (:local-nicknames | ||
| 8 | (:jzon :com.inuoe.jzon)) | ||
| 9 | (:export :define-enum)) | ||
| 10 | (in-package :ukkoclot/enum) | ||
| 11 | |||
| 12 | (eval-when (:compile-toplevel :load-toplevel :execute) | ||
| 13 | (defstruct (field (:constructor make-field%)) name string) | ||
| 14 | |||
| 15 | (defun make-field (name string) | ||
| 16 | (make-field% :name name :string string)) | ||
| 17 | |||
| 18 | (defun parse-field-specs (field-specs) | ||
| 19 | (iter (for field-spec in field-specs) | ||
| 20 | (collect (apply #'make-field field-spec)))) | ||
| 21 | |||
| 22 | (defun emit-defconst (field) | ||
| 23 | `(defconstant ,(field-name field) ',(field-name field))) | ||
| 24 | |||
| 25 | (defun emit-deftype (name fields) | ||
| 26 | `(deftype ,name () | ||
| 27 | '(member ,@(iter (for field in fields) (collect (field-name field)))))) | ||
| 28 | |||
| 29 | (defun emit-fixup-method (field) | ||
| 30 | (let ((arg (gensym "ARG"))) | ||
| 31 | `(defmethod fixup-value ((,arg (eql ',(field-name field)))) | ||
| 32 | ,(field-string field)))) | ||
| 33 | |||
| 34 | (defun emit-jzon-write-method (field) | ||
| 35 | (let ((writer (gensym "WRITER")) | ||
| 36 | (arg (gensym "ARG"))) | ||
| 37 | `(defmethod jzon:write-value (,writer (,arg (eql ',(field-name field)))) | ||
| 38 | (jzon::write-string ,(field-string field) ,writer)))) | ||
| 39 | |||
| 40 | (defun emit-parse-value (name fields) | ||
| 41 | (let ((type (gensym "TYPE")) | ||
| 42 | (source (gensym "SOURCE"))) | ||
| 43 | `(defmethod parse-value ((,type (eql ',name)) ,source) | ||
| 44 | ;; nil in, nil out | ||
| 45 | (when ,source | ||
| 46 | (string-case (,source) | ||
| 47 | ,@(iter (for field in fields) | ||
| 48 | (collect `(,(field-string field) ,(field-name field)))))))))) | ||
| 49 | |||
| 50 | (defmacro define-enum (name &body field-specs) | ||
| 51 | (let ((fields (parse-field-specs field-specs))) | ||
| 52 | `(progn | ||
| 53 | ,(emit-deftype name fields) | ||
| 54 | ,(emit-parse-value name fields) | ||
| 55 | ,@(iter (for field in fields) | ||
| 56 | (collect `(progn | ||
| 57 | ,(emit-defconst field) | ||
| 58 | ,(emit-fixup-method field) | ||
| 59 | ,(emit-jzon-write-method field))))))) | ||
diff --git a/src/inline-bots.lisp b/src/inline-bots.lisp index eb20f21..3ed85e9 100644 --- a/src/inline-bots.lisp +++ b/src/inline-bots.lisp | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | :text (format nil "Deleted a message sent via inline bot @~A <code>~A</code>" | 32 | :text (format nil "Deleted a message sent via inline bot @~A <code>~A</code>" |
| 33 | (user-username via) | 33 | (user-username via) |
| 34 | (user-id via)) | 34 | (user-id via)) |
| 35 | :parse-mode "HTML" | 35 | :parse-mode html |
| 36 | :reply-markup (make-inline-keyboard-markup | 36 | :reply-markup (make-inline-keyboard-markup |
| 37 | :inline-keyboard | 37 | :inline-keyboard |
| 38 | (make-array '(1 2) :initial-contents (list (list whitelist blacklist))))))) | 38 | (make-array '(1 2) :initial-contents (list (list whitelist blacklist))))))) |
diff --git a/src/main.lisp b/src/main.lisp index 96f73a0..4b05ee2 100644 --- a/src/main.lisp +++ b/src/main.lisp | |||
| @@ -110,7 +110,7 @@ | |||
| 110 | :text (concatenate 'string "Hello there, " | 110 | :text (concatenate 'string "Hello there, " |
| 111 | (user-format-name new-member) | 111 | (user-format-name new-member) |
| 112 | "! Be on your bestest behaviour now!!") | 112 | "! Be on your bestest behaviour now!!") |
| 113 | :parse-mode "HTML" | 113 | :parse-mode html |
| 114 | :caption-above t | 114 | :caption-above t |
| 115 | :allow-sending-without-reply t))) | 115 | :allow-sending-without-reply t))) |
| 116 | 116 | ||
| @@ -138,11 +138,12 @@ | |||
| 138 | (= (message-entity-offset entity) 0)) | 138 | (= (message-entity-offset entity) 0)) |
| 139 | do (on-text-command bot msg text (message-entity-extract entity text)))) | 139 | do (on-text-command bot msg text (message-entity-extract entity text)))) |
| 140 | 140 | ||
| 141 | ;; TODO: Replace this cond with a nicer dispatch. Something like string-case? | ||
| 141 | (cond ((equal text ":3") | 142 | (cond ((equal text ":3") |
| 142 | (reply-message bot msg ">:3")) | 143 | (reply-message bot msg ">:3")) |
| 143 | 144 | ||
| 144 | ((equal text ">:3") | 145 | ((equal text ">:3") |
| 145 | (reply-message bot msg "<b>>:3</b>" :parse-mode "HTML")) | 146 | (reply-message bot msg "<b>>:3</b>" :parse-mode html)) |
| 146 | 147 | ||
| 147 | ((starts-with-ignore-case text "big ") | 148 | ((starts-with-ignore-case text "big ") |
| 148 | (let ((the-text (subseq text 4))) | 149 | (let ((the-text (subseq text 4))) |
| @@ -152,7 +153,7 @@ | |||
| 152 | "<b>" | 153 | "<b>" |
| 153 | (escape-xml (string-upcase the-text)) | 154 | (escape-xml (string-upcase the-text)) |
| 154 | "</b>") | 155 | "</b>") |
| 155 | :parse-mode "HTML")))) | 156 | :parse-mode html)))) |
| 156 | 157 | ||
| 157 | ((string-equal text "dio cane") | 158 | ((string-equal text "dio cane") |
| 158 | (reply-message bot | 159 | (reply-message bot |
| @@ -166,7 +167,7 @@ | |||
| 166 | (reply-message bot msg "idgi")) | 167 | (reply-message bot msg "idgi")) |
| 167 | 168 | ||
| 168 | ((string= text "H") | 169 | ((string= text "H") |
| 169 | (reply-message bot msg "<code>Randomly selected reminder that h > H.</code>" :parse-mode "HTML")) | 170 | (reply-message bot msg "<code>Randomly selected reminder that h > H.</code>" :parse-mode html)) |
| 170 | 171 | ||
| 171 | ((string-equal text "porco dio") | 172 | ((string-equal text "porco dio") |
| 172 | (reply-message bot | 173 | (reply-message bot |
| @@ -216,9 +217,10 @@ | |||
| 216 | (defun on-text-command (bot msg text cmd) | 217 | (defun on-text-command (bot msg text cmd) |
| 217 | (let ((simple-cmd (simplify-cmd bot cmd))) | 218 | (let ((simple-cmd (simplify-cmd bot cmd))) |
| 218 | (log-debug "text-command: ~A AKA ~A" cmd simple-cmd) | 219 | (log-debug "text-command: ~A AKA ~A" cmd simple-cmd) |
| 220 | ;; TODO: Replace this cond with a nicer dispatch. Something like string-case? | ||
| 219 | (acond | 221 | (acond |
| 220 | ((equal simple-cmd "chatid") | 222 | ((equal simple-cmd "chatid") |
| 221 | (reply-message bot msg (format nil "<code>~A</code>" (message-chat-id msg)) :parse-mode "HTML")) | 223 | (reply-message bot msg (format nil "<code>~A</code>" (message-chat-id msg)) :parse-mode html)) |
| 222 | 224 | ||
| 223 | ((and (equal simple-cmd "msginfo") | 225 | ((and (equal simple-cmd "msginfo") |
| 224 | (message-reply-to-message msg)) | 226 | (message-reply-to-message msg)) |
| @@ -252,4 +254,4 @@ Send time: ...")) | |||
| 252 | (send-message bot | 254 | (send-message bot |
| 253 | :chat-id (config-dev-group (bot-config bot)) | 255 | :chat-id (config-dev-group (bot-config bot)) |
| 254 | :text msg | 256 | :text msg |
| 255 | :parse-mode "HTML"))) | 257 | :parse-mode html))) |
diff --git a/src/tg-types.lisp b/src/tg-types.lisp index ba3ec3b..ec14363 100644 --- a/src/tg-types.lisp +++ b/src/tg-types.lisp | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | :ukkoclot/tg-types/link-preview-options | 18 | :ukkoclot/tg-types/link-preview-options |
| 19 | :ukkoclot/tg-types/message | 19 | :ukkoclot/tg-types/message |
| 20 | :ukkoclot/tg-types/message-entity | 20 | :ukkoclot/tg-types/message-entity |
| 21 | :ukkoclot/tg-types/parse-mode | ||
| 21 | :ukkoclot/tg-types/photo-size | 22 | :ukkoclot/tg-types/photo-size |
| 22 | :ukkoclot/tg-types/reply-keyboard-markup | 23 | :ukkoclot/tg-types/reply-keyboard-markup |
| 23 | :ukkoclot/tg-types/reply-keyboard-remove | 24 | :ukkoclot/tg-types/reply-keyboard-remove |
diff --git a/src/tg-types/parse-mode.lisp b/src/tg-types/parse-mode.lisp new file mode 100644 index 0000000..80c24aa --- /dev/null +++ b/src/tg-types/parse-mode.lisp | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | ;; SPDX-License-Identifier: EUPL-1.2 | ||
| 2 | ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> | ||
| 3 | (defpackage :ukkoclot/tg-types/parse-mode | ||
| 4 | (:use :c2cl :ukkoclot/enum) | ||
| 5 | (:export :html :markdown-legacy :markdown :parse-mode)) | ||
| 6 | (in-package :ukkoclot/tg-types/parse-mode) | ||
| 7 | |||
| 8 | (define-enum parse-mode | ||
| 9 | (markdown-legacy "Markdown") | ||
| 10 | (markdown "MarkdownV2") | ||
| 11 | (html "HTML")) | ||