summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2025-10-12 22:14:39 +0300
committerGravatar Uko Kokņevičs2025-10-12 22:14:39 +0300
commit31a972d6825114b1a971e42cdc86e1bd7a9834c3 (patch)
treeb40ff73cc76ff88d969b9e12325fd4b17e68dadc /src
parentmsginfo: pretty print the response (diff)
downloadukkoclot-31a972d6825114b1a971e42cdc86e1bd7a9834c3.tar.gz
ukkoclot-31a972d6825114b1a971e42cdc86e1bd7a9834c3.tar.xz
ukkoclot-31a972d6825114b1a971e42cdc86e1bd7a9834c3.zip
Introduce enums and a pretty parse-mode type
Diffstat (limited to 'src')
-rw-r--r--src/bot/methods.lisp7
-rw-r--r--src/enum.lisp59
-rw-r--r--src/inline-bots.lisp2
-rw-r--r--src/main.lisp14
-rw-r--r--src/tg-types.lisp1
-rw-r--r--src/tg-types/parse-mode.lisp11
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>&gt;:3</b>" :parse-mode "HTML")) 146 (reply-message bot msg "<b>&gt;: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 &gt; H.</code>" :parse-mode "HTML")) 170 (reply-message bot msg "<code>Randomly selected reminder that h &gt; 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"))