cakewalk 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/LICENSE +22 -0
- data/README.md +169 -0
- data/docs/bot_options.md +454 -0
- data/docs/changes.md +541 -0
- data/docs/common_mistakes.md +60 -0
- data/docs/common_tasks.md +57 -0
- data/docs/encodings.md +69 -0
- data/docs/events.md +273 -0
- data/docs/getting_started.md +184 -0
- data/docs/logging.md +90 -0
- data/docs/migrating.md +267 -0
- data/docs/plugins.md +4 -0
- data/docs/readme.md +20 -0
- data/examples/basic/autovoice.rb +32 -0
- data/examples/basic/google.rb +35 -0
- data/examples/basic/hello.rb +15 -0
- data/examples/basic/join_part.rb +34 -0
- data/examples/basic/memo.rb +39 -0
- data/examples/basic/msg.rb +16 -0
- data/examples/basic/seen.rb +36 -0
- data/examples/basic/urban_dict.rb +35 -0
- data/examples/basic/url_shorten.rb +35 -0
- data/examples/plugins/autovoice.rb +37 -0
- data/examples/plugins/custom_prefix.rb +23 -0
- data/examples/plugins/dice_roll.rb +38 -0
- data/examples/plugins/google.rb +36 -0
- data/examples/plugins/hello.rb +22 -0
- data/examples/plugins/hooks.rb +36 -0
- data/examples/plugins/join_part.rb +42 -0
- data/examples/plugins/lambdas.rb +35 -0
- data/examples/plugins/last_nick.rb +24 -0
- data/examples/plugins/msg.rb +22 -0
- data/examples/plugins/multiple_matches.rb +32 -0
- data/examples/plugins/own_events.rb +37 -0
- data/examples/plugins/seen.rb +45 -0
- data/examples/plugins/timer.rb +22 -0
- data/examples/plugins/url_shorten.rb +33 -0
- data/lib/cakewalk/ban.rb +50 -0
- data/lib/cakewalk/bot.rb +479 -0
- data/lib/cakewalk/cached_list.rb +19 -0
- data/lib/cakewalk/callback.rb +20 -0
- data/lib/cakewalk/channel.rb +463 -0
- data/lib/cakewalk/channel_list.rb +29 -0
- data/lib/cakewalk/configuration/bot.rb +48 -0
- data/lib/cakewalk/configuration/dcc.rb +16 -0
- data/lib/cakewalk/configuration/plugins.rb +41 -0
- data/lib/cakewalk/configuration/sasl.rb +19 -0
- data/lib/cakewalk/configuration/ssl.rb +19 -0
- data/lib/cakewalk/configuration/timeouts.rb +14 -0
- data/lib/cakewalk/configuration.rb +73 -0
- data/lib/cakewalk/constants.rb +533 -0
- data/lib/cakewalk/dcc/dccable_object.rb +37 -0
- data/lib/cakewalk/dcc/incoming/send.rb +147 -0
- data/lib/cakewalk/dcc/incoming.rb +1 -0
- data/lib/cakewalk/dcc/outgoing/send.rb +122 -0
- data/lib/cakewalk/dcc/outgoing.rb +1 -0
- data/lib/cakewalk/dcc.rb +12 -0
- data/lib/cakewalk/exceptions.rb +46 -0
- data/lib/cakewalk/formatting.rb +125 -0
- data/lib/cakewalk/handler.rb +118 -0
- data/lib/cakewalk/handler_list.rb +90 -0
- data/lib/cakewalk/helpers.rb +231 -0
- data/lib/cakewalk/irc.rb +913 -0
- data/lib/cakewalk/isupport.rb +98 -0
- data/lib/cakewalk/log_filter.rb +21 -0
- data/lib/cakewalk/logger/formatted_logger.rb +97 -0
- data/lib/cakewalk/logger/zcbot_logger.rb +22 -0
- data/lib/cakewalk/logger.rb +168 -0
- data/lib/cakewalk/logger_list.rb +85 -0
- data/lib/cakewalk/mask.rb +69 -0
- data/lib/cakewalk/message.rb +391 -0
- data/lib/cakewalk/message_queue.rb +107 -0
- data/lib/cakewalk/mode_parser.rb +76 -0
- data/lib/cakewalk/network.rb +89 -0
- data/lib/cakewalk/open_ended_queue.rb +26 -0
- data/lib/cakewalk/pattern.rb +65 -0
- data/lib/cakewalk/plugin.rb +515 -0
- data/lib/cakewalk/plugin_list.rb +38 -0
- data/lib/cakewalk/rubyext/float.rb +3 -0
- data/lib/cakewalk/rubyext/module.rb +26 -0
- data/lib/cakewalk/rubyext/string.rb +33 -0
- data/lib/cakewalk/sasl/dh_blowfish.rb +71 -0
- data/lib/cakewalk/sasl/diffie_hellman.rb +47 -0
- data/lib/cakewalk/sasl/mechanism.rb +6 -0
- data/lib/cakewalk/sasl/plain.rb +26 -0
- data/lib/cakewalk/sasl.rb +34 -0
- data/lib/cakewalk/syncable.rb +83 -0
- data/lib/cakewalk/target.rb +199 -0
- data/lib/cakewalk/timer.rb +145 -0
- data/lib/cakewalk/user.rb +488 -0
- data/lib/cakewalk/user_list.rb +87 -0
- data/lib/cakewalk/utilities/deprecation.rb +16 -0
- data/lib/cakewalk/utilities/encoding.rb +37 -0
- data/lib/cakewalk/utilities/kernel.rb +13 -0
- data/lib/cakewalk/version.rb +4 -0
- data/lib/cakewalk.rb +5 -0
- metadata +140 -0
data/docs/encodings.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# @title Encodings
|
2
|
+
# @markup kramdown
|
3
|
+
|
4
|
+
# Encodings
|
5
|
+
|
6
|
+
The IRC protocol doesn't define a specific encoding that should be
|
7
|
+
used, nor does it provide any information on which encodings _are_
|
8
|
+
being used.
|
9
|
+
|
10
|
+
At the same time, lots of different encodings have become popular on
|
11
|
+
IRC. This presents a big problem, because, if you're using a different
|
12
|
+
encoding than someone else on IRC, you'll receive their text as
|
13
|
+
garbage.
|
14
|
+
|
15
|
+
Cakewalk tries to work around this issue in two ways, while also keeping
|
16
|
+
the usual Ruby behaviour.
|
17
|
+
|
18
|
+
## The `encoding` option
|
19
|
+
By setting {file:docs/bot_options.md#encoding the `encoding` option}, you
|
20
|
+
set your expectations on what encoding other users will use. Allowed
|
21
|
+
values are instances of Encoding, names of valid encodings (as
|
22
|
+
strings) and the special `:irc` encoding, which will be explained
|
23
|
+
further down.
|
24
|
+
|
25
|
+
|
26
|
+
## Encoding.default_internal
|
27
|
+
If set, Cakewalk will automatically convert incoming messages to the
|
28
|
+
encoding defined by `Encoding.default_internal`, unless the special
|
29
|
+
encoding `:irc` is being used as the {file:docs/bot_options.md#encoding
|
30
|
+
`encoding option`}
|
31
|
+
|
32
|
+
## The `:irc` encoding
|
33
|
+
As mentioned earlier, people couldn't decide on a single encoding to
|
34
|
+
use. As such, specifying a single encoding would most likely lead to
|
35
|
+
problems, especially if the bot is in more than one channel.
|
36
|
+
|
37
|
+
Luckily, even though people cannot decide on a single encoding,
|
38
|
+
western countries usually either use CP1252 (Windows Latin-1) or
|
39
|
+
UTF-8. Since text encoded in CP1252 fails validation as UTF-8, it is
|
40
|
+
easy to tell the two apart. Additionally it is possible to losslessly
|
41
|
+
re-encode CP1252 in UTF-8 and as such, a small subset of UTF-8 is also
|
42
|
+
representable in CP1252.
|
43
|
+
|
44
|
+
If incoming text is valid UTF-8, it will be interpreted as such. If it
|
45
|
+
fails validation, a CP1252 → UTF-8 conversion is performed. This
|
46
|
+
ensures that you will always deal with UTF-8 in your code, even if
|
47
|
+
other people use CP1252. Note, however, that we ignore
|
48
|
+
`Encoding.default_internal` in this case and always present you with
|
49
|
+
UTF-8.
|
50
|
+
|
51
|
+
If text you send contains only characters that fit inside the
|
52
|
+
CP1252 code page, the entire line will be sent that way.
|
53
|
+
|
54
|
+
If the text doesn't fit inside the CP1252 code page, (for example if
|
55
|
+
you type Eastern European characters, or Russian) it will be sent as
|
56
|
+
UTF-8. Only UTF-8 capable clients will be able to see these characters
|
57
|
+
correctly.
|
58
|
+
|
59
|
+
## Invalid bytes and unsupported translations
|
60
|
+
If Cakewalk receives text in an encoding other than the one assumed, it
|
61
|
+
can happen that the message contains bytes that are not valid in the
|
62
|
+
assumed encoding. Instead of dropping the complete message, Cakewalk will
|
63
|
+
replace offending bytes with question marks.
|
64
|
+
|
65
|
+
Also, if you expect messages in e.g. UTF-8 but re-encode them in
|
66
|
+
CP1252 (by setting `Encoding.default_internal` to CP1252), it can
|
67
|
+
happen that some characters cannot be represented in CP1252. In such a
|
68
|
+
case, Cakewalk will too replace the offending characters with question
|
69
|
+
marks.
|
data/docs/events.md
ADDED
@@ -0,0 +1,273 @@
|
|
1
|
+
# @title Events
|
2
|
+
# @markup kramdown
|
3
|
+
|
4
|
+
Cakewalk provides three kinds of events:
|
5
|
+
|
6
|
+
1. Events mapping directly to IRC commands
|
7
|
+
|
8
|
+
For example `:topic`, which will be triggered when someone changes
|
9
|
+
the topic, or `:kick`, when someone gets kicked.
|
10
|
+
|
11
|
+
2. Events mapping directly to IRC numeric codes
|
12
|
+
|
13
|
+
For example `:"401"` for `ERR_NOSUCHNICK`, which is triggered when
|
14
|
+
trying to operate on an unknown nickname, or `:"318"` for
|
15
|
+
`RPL_ENDOFWHOIS`, which is triggered after whois information have
|
16
|
+
been received.
|
17
|
+
|
18
|
+
3. Events mapping to more abstract ideas
|
19
|
+
|
20
|
+
For example `:leaving` whenever a user parts, quits or gets
|
21
|
+
kicked/killed or `:message`, which is actually a synonym for
|
22
|
+
`:privmsg`, the underlying IRC command.
|
23
|
+
|
24
|
+
# Events of the first two kinds
|
25
|
+
|
26
|
+
All events of the first two kinds behave exactly the same: When they
|
27
|
+
get triggered, the handler will be passed a single object, a reference
|
28
|
+
to the {Cakewalk::Message Message object}.
|
29
|
+
|
30
|
+
Example:
|
31
|
+
|
32
|
+
on :topic do |m|
|
33
|
+
# m is the message object
|
34
|
+
end
|
35
|
+
|
36
|
+
We will not further describe all possible events of the first two
|
37
|
+
categories.
|
38
|
+
|
39
|
+
# Events of the third kind
|
40
|
+
|
41
|
+
Events of the third kind can each have different signatures, as they
|
42
|
+
get passed objects directly relating to their kind, for example the
|
43
|
+
leaving user in case of `:leaving`. This document will describe all
|
44
|
+
events of that kind, their signature and example usage.
|
45
|
+
|
46
|
+
**Note: Because *all* handlers receive a {Cakewalk::Message Message}
|
47
|
+
object as the first argument, we will only mention and describe
|
48
|
+
additional arguments.**
|
49
|
+
|
50
|
+
## `:action`
|
51
|
+
|
52
|
+
The `:action` event is triggered when a user sends a CTCP ACTION to a
|
53
|
+
channel or the bot. CTCP ACTION is commonly refered to simply as
|
54
|
+
"actions" or "/me's", because that is the command used in most IRC
|
55
|
+
clients.
|
56
|
+
|
57
|
+
Example:
|
58
|
+
|
59
|
+
on :action, "kicks the bot" do |m|
|
60
|
+
m.reply "Ouch! Stop kicking me :(", true
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
## `:away`
|
65
|
+
|
66
|
+
The `:away` event is triggered when a user goes away. This feature
|
67
|
+
only works on networks implementing the "away-notify" extension.
|
68
|
+
|
69
|
+
Example:
|
70
|
+
|
71
|
+
on :away do |m|
|
72
|
+
debug("User %s just went away: %s" % [m.user, m.message])
|
73
|
+
end
|
74
|
+
|
75
|
+
See also {file:docs/events.md#unaway the `:unaway` event}.
|
76
|
+
|
77
|
+
|
78
|
+
## `:ban`
|
79
|
+
|
80
|
+
The `:ban` event is triggered when a user gets banned in a channel.
|
81
|
+
|
82
|
+
One additional argument, a {Cakewalk::Ban Ban object}, gets passed to
|
83
|
+
the handler.
|
84
|
+
|
85
|
+
Example:
|
86
|
+
|
87
|
+
on :ban do |m, ban|
|
88
|
+
debug("%s just banned %s" % [ban.by, ban.mask])
|
89
|
+
end
|
90
|
+
|
91
|
+
See also {file:docs/events.md#unban the `:unban` event}.
|
92
|
+
|
93
|
+
|
94
|
+
## `:catchall`
|
95
|
+
|
96
|
+
`:catchall` is a special event that gets triggered for every incoming
|
97
|
+
IRC message/command, no matter what the type is.
|
98
|
+
|
99
|
+
|
100
|
+
## `:channel`
|
101
|
+
|
102
|
+
The `:channel` event is triggered for channel messages (the usual
|
103
|
+
form of communication on IRC).
|
104
|
+
|
105
|
+
See also {file:docs/events.md#private the `:private` event}.
|
106
|
+
|
107
|
+
|
108
|
+
## `:connect`
|
109
|
+
|
110
|
+
The `:connect` event is triggered after the bot successfully
|
111
|
+
connected to the IRC server.
|
112
|
+
|
113
|
+
One common use case for this event is setting up variables,
|
114
|
+
synchronising information etc.
|
115
|
+
|
116
|
+
|
117
|
+
## `:ctcp`
|
118
|
+
|
119
|
+
The `:ctcp` event is triggered when receiving CTCP-related messages,
|
120
|
+
for example the VERSION request.
|
121
|
+
|
122
|
+
|
123
|
+
## `:dcc_send`
|
124
|
+
|
125
|
+
`:dcc_send` gets triggered when a user tries to send a file to the
|
126
|
+
bot, using the DCC SEND protocol.
|
127
|
+
|
128
|
+
One additional argument, a {Cakewalk::DCC::Incoming::Send DCC::Send
|
129
|
+
object}, gets passed to the handler.
|
130
|
+
|
131
|
+
For example usage and a general explanation of DCC in Cakewalk check
|
132
|
+
{Cakewalk::DCC::Incoming::Send}.
|
133
|
+
|
134
|
+
|
135
|
+
## `:dehalfop`, `:deop`, `:deowner`, `:devoice`
|
136
|
+
|
137
|
+
These events get triggered for the respective channel operations of
|
138
|
+
taking halfop, op, owner and voice from a user.
|
139
|
+
|
140
|
+
One additional argument, the user whose rights are being modifed, gets
|
141
|
+
passed to the handler.
|
142
|
+
|
143
|
+
|
144
|
+
## `:error`
|
145
|
+
|
146
|
+
`:error` gets triggered for all numeric replies that signify errors
|
147
|
+
(`ERR_*`).
|
148
|
+
|
149
|
+
|
150
|
+
## `:halfop`
|
151
|
+
|
152
|
+
This event gets triggered when a user in a channel gets half-opped.
|
153
|
+
|
154
|
+
One additional argument, the user being half-opped, gets passed to the
|
155
|
+
handler.
|
156
|
+
|
157
|
+
|
158
|
+
## `:leaving`
|
159
|
+
|
160
|
+
`:leaving` is an event that is triggered whenever any of the following
|
161
|
+
are triggered as well: `:part`, `:quit`, `:kick`, `:kill`.
|
162
|
+
|
163
|
+
The event can thus be used for noticing when a user leaves a channel
|
164
|
+
or the network, no matter the reason.
|
165
|
+
|
166
|
+
One additional argument, the leaving user, gets passed to the handler.
|
167
|
+
|
168
|
+
Be careful not to confuse the additional argument with
|
169
|
+
{Cakewalk::Message#user}. For example in the case of a kick,
|
170
|
+
{Cakewalk::Message#user} will describe the user kicking someone, not the
|
171
|
+
one who is being kicked.
|
172
|
+
|
173
|
+
Example:
|
174
|
+
|
175
|
+
on :leaving do |m, user|
|
176
|
+
if m.channel?
|
177
|
+
debug("%s just left %s." % [user, m.channel])
|
178
|
+
else
|
179
|
+
debug("%s just left the network." % user)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
## `:mode_change`
|
186
|
+
|
187
|
+
This event gets triggered whenever modes in a channel or on the bot
|
188
|
+
directly change. Unlike events like `:op`, this event is more
|
189
|
+
low-level, as the argument the handler gets passed is an array
|
190
|
+
describing every change.
|
191
|
+
|
192
|
+
|
193
|
+
## `:offline`
|
194
|
+
|
195
|
+
This event is triggered when a
|
196
|
+
{file:docs/common_tasks.md#checking-if-a-user-is-online monitored user}
|
197
|
+
goes offline.
|
198
|
+
|
199
|
+
One additional argument, the user going offline, gets passed to the
|
200
|
+
handler.
|
201
|
+
|
202
|
+
|
203
|
+
## `:online`
|
204
|
+
|
205
|
+
This event is triggered when a
|
206
|
+
{file:docs/common_tasks.md#checking-if-a-user-is-online monitored user}
|
207
|
+
comes online.
|
208
|
+
|
209
|
+
One additional argument, the user coming online, gets passed to the
|
210
|
+
handler.
|
211
|
+
|
212
|
+
|
213
|
+
## `:op`
|
214
|
+
|
215
|
+
This event gets triggered when a user in a channel gets opped.
|
216
|
+
|
217
|
+
One additional argument, the user being opped, gets passed to the
|
218
|
+
handler.
|
219
|
+
|
220
|
+
|
221
|
+
## `:owner`
|
222
|
+
|
223
|
+
|
224
|
+
This event gets triggered when a user in a channel receives
|
225
|
+
owner-status.
|
226
|
+
|
227
|
+
One additional argument, the user receiving owner-status, gets passed
|
228
|
+
to the handler.
|
229
|
+
|
230
|
+
|
231
|
+
## `:message`
|
232
|
+
|
233
|
+
The `:message` event is triggered for messages directed at either a
|
234
|
+
channel or directly at the bot. It's synonymous with `:privmsg`.
|
235
|
+
|
236
|
+
|
237
|
+
## `:private`
|
238
|
+
|
239
|
+
The `:private` event is triggered for messages directly towarded at
|
240
|
+
the bot (think /query in traditional IRC clients).
|
241
|
+
|
242
|
+
See also {file:docs/events.md#channel the `:channel` event}.
|
243
|
+
|
244
|
+
|
245
|
+
## `:unaway`
|
246
|
+
|
247
|
+
The `:unaway` event is triggered when a user no longer is away. This
|
248
|
+
feature only works on networks implementing the "away-notify"
|
249
|
+
extension.
|
250
|
+
|
251
|
+
Example:
|
252
|
+
|
253
|
+
on :unaway do |m|
|
254
|
+
debug("User %s no longer is away." % m.user)
|
255
|
+
end
|
256
|
+
|
257
|
+
See also {file:docs/events.md#away the `:away` event}.
|
258
|
+
|
259
|
+
|
260
|
+
## `:unban`
|
261
|
+
|
262
|
+
The `:unban` event is triggered when a user gets unbanned in a
|
263
|
+
channel.
|
264
|
+
|
265
|
+
One additional argument, a {Cakewalk::Ban Ban object}, gets passed to the
|
266
|
+
handler.
|
267
|
+
|
268
|
+
|
269
|
+
## `:voice`
|
270
|
+
This event gets triggered when a user in a channel gets voiced.
|
271
|
+
|
272
|
+
One additional argument, the user being voiced, gets passed to the
|
273
|
+
handler.
|
@@ -0,0 +1,184 @@
|
|
1
|
+
# @title Getting Started
|
2
|
+
# @markup kramdown
|
3
|
+
|
4
|
+
# Getting Started
|
5
|
+
|
6
|
+
This short guide will show you how to easily and quickly write your
|
7
|
+
own IRC bot with Cakewalk.
|
8
|
+
|
9
|
+
# What Cakewalk really is
|
10
|
+
|
11
|
+
First and foremost, it is important to understand that Cakewalk is more
|
12
|
+
of an API for IRC access than a full-blown bot framework like Autumn
|
13
|
+
or Rbot.
|
14
|
+
|
15
|
+
There will be no enforced directory structures, no magical places from
|
16
|
+
which plugins will be loaded and no obscure, "fancy" names. Plugins
|
17
|
+
will be plugins and not "leaves".
|
18
|
+
|
19
|
+
This, however, does not mean that Cakewalk requires you to be familiar
|
20
|
+
with the internals of the IRC protocol. Quite the opposite: A very
|
21
|
+
high-level abstraction is provided, allowing things such as
|
22
|
+
|
23
|
+
Channel("#cakewalk").users.each do |user, modes|
|
24
|
+
user.send "I am watching you!"
|
25
|
+
end
|
26
|
+
|
27
|
+
to work.
|
28
|
+
|
29
|
+
|
30
|
+
Furthermore, the API has been designed in a way that it sticks true to
|
31
|
+
the way Ruby looks and behaves. Plugins are normal classes that mix-in
|
32
|
+
a module, functions of the bot are implemented as normal methods and
|
33
|
+
so on.
|
34
|
+
|
35
|
+
# Hello, World
|
36
|
+
|
37
|
+
The following will describe one of the most basic IRC bots you can
|
38
|
+
write in Cakewalk: One that joins a specific channel and responds to
|
39
|
+
"hello" by saying "Hello, World".
|
40
|
+
|
41
|
+
|
42
|
+
require "cakewalk"
|
43
|
+
|
44
|
+
bot = Cakewalk::Bot.new do
|
45
|
+
configure do |c|
|
46
|
+
c.server = "irc.libera.chat"
|
47
|
+
c.channels = ["#cakewalk-bots"]
|
48
|
+
end
|
49
|
+
|
50
|
+
on :message, "hello" do |m|
|
51
|
+
m.reply "Hello, World"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
bot.start
|
56
|
+
|
57
|
+
|
58
|
+
Note that this is the entire file and all you need for the basic bot
|
59
|
+
to work. Save the above example to a file and run it with Ruby.
|
60
|
+
|
61
|
+
## In Detail
|
62
|
+
|
63
|
+
So, what are we actually doing in that short piece of code? First, we
|
64
|
+
create a new bot in line 3 and conigure it in lines 4–6 –
|
65
|
+
{Cakewalk::Bot#configure configure} simply yields the configuration
|
66
|
+
object, which allows you to configure various things. In this example,
|
67
|
+
we only set which server to connect to and which channel to join.
|
68
|
+
Another often-used option is the nickname of the bot
|
69
|
+
({file:docs/bot_options.md#nick c.nick}). For an overview of all
|
70
|
+
available options, see {file:docs/bot_options.md the list of options}.
|
71
|
+
|
72
|
+
Following, we define a basic message handler. In its simplest form,
|
73
|
+
{Cakewalk::Bot#on on} expects two arguments: The kind of message to react
|
74
|
+
to and the pattern to match. In this case, the kind is
|
75
|
+
{file:docs/events.md#message :message}, which means that the bot will
|
76
|
+
respond to both messages in channels as well as messages sent directly
|
77
|
+
to the bot. For a list of all kinds, called events, see
|
78
|
+
{file:docs/events.md the list of events}.
|
79
|
+
|
80
|
+
For the pattern we use a basic string, which means that the message
|
81
|
+
has to be exactly that string. It mustn't have anything before or
|
82
|
+
after the word "hello". Another way of using {Cakewalk::Bot#on on} is by using
|
83
|
+
regular expressions:
|
84
|
+
|
85
|
+
on :message, /^\d{4}$/ do |m|
|
86
|
+
# ...
|
87
|
+
end
|
88
|
+
|
89
|
+
will match all messages that consist of exactly four digits and
|
90
|
+
nothing else.
|
91
|
+
|
92
|
+
Whenever a message matches the handler we just defined, the block we
|
93
|
+
provided will be called, with the message object, and optionally
|
94
|
+
capture groups of the regular expression, passed to it.
|
95
|
+
|
96
|
+
The message object allows insight into the nature of the message, i.e.
|
97
|
+
who sent it, when was it sent etc, and also provides the
|
98
|
+
{Cakewalk::Message#reply reply} method, an easy way of responding to a
|
99
|
+
message. If the message was sent to a channel, {Cakewalk::Message#reply
|
100
|
+
reply} will respond to the channel, otherwise directly to the user.
|
101
|
+
|
102
|
+
We then use exactly that {Cakewalk::Message#reply reply} method to send back "Hello, World"
|
103
|
+
whenever someone says "hello".
|
104
|
+
|
105
|
+
That's it!
|
106
|
+
|
107
|
+
# on-handlers vs. plugins
|
108
|
+
|
109
|
+
Using `on` might be nice and handy for writing simple bots, but if you
|
110
|
+
want to write a more complex bot, providing lots of different features
|
111
|
+
to its users, then using plugins might be a better solution.
|
112
|
+
|
113
|
+
But what are plugins, exactly? Technically, plugins are implemented as
|
114
|
+
Ruby classes that mix-in a {Cakewalk::Plugin specific module} to get
|
115
|
+
access to various methods.
|
116
|
+
|
117
|
+
To have an example to work with, we'll convert our "Hello, World" bot
|
118
|
+
to using the plugin API:
|
119
|
+
|
120
|
+
require "cakewalk"
|
121
|
+
|
122
|
+
class HelloWorld
|
123
|
+
include Cakewalk::Plugin
|
124
|
+
|
125
|
+
match "hello"
|
126
|
+
def execute(m)
|
127
|
+
m.reply "Hello, World"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
bot = Cakewalk::Bot.new do
|
132
|
+
configure do |c|
|
133
|
+
c.server = "irc.libera.chat"
|
134
|
+
c.channels = ["#cakewalk-bots"]
|
135
|
+
c.plugins.plugins = [HelloWorld]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
bot.start
|
140
|
+
|
141
|
+
The first thing to notice is that we wrote a new class called
|
142
|
+
`HelloWorld`, and that we use {Cakewalk::Plugin::ClassMethods#match
|
143
|
+
match} instead of `on` to define our handler. Furthermore, we didn't
|
144
|
+
specify a message type nor did we provide any blocks.
|
145
|
+
|
146
|
+
But let's back up and proceed in smaller steps to see how plugins are built.
|
147
|
+
|
148
|
+
First thing after defining a new class is to include {Cakewalk::Plugin} –
|
149
|
+
This module will provide methods like
|
150
|
+
{Cakewalk::Plugin::ClassMethods#match match} and also allows Cakewalk to
|
151
|
+
control the class in specific ways required for plugins to work.
|
152
|
+
|
153
|
+
Then we use aforementioned `match`, instead of `on`, to specify what
|
154
|
+
messages we want to react to. We didn't have to specify the message
|
155
|
+
type because plugins default to {file:docs/events.md#message :message}.
|
156
|
+
|
157
|
+
We then define a method called `execute`, which is pretty much the
|
158
|
+
same as blocks are to on-handlers. And from here on, everything is the
|
159
|
+
same.
|
160
|
+
|
161
|
+
The only thing left to do is to tell Cakewalk to use our plugin, by
|
162
|
+
adding it to {file:docs/bot_options.md#pluginsplugins c.plugins.plugins}.
|
163
|
+
|
164
|
+
One important thing remains to note: Plugins have a
|
165
|
+
{file:docs/bot_options.md#pluginsprefix prefix}, a string (or pattern)
|
166
|
+
that gets appended to all patterns you define, and by default this
|
167
|
+
prefix is `/^!/`. This means that in order to invoke our HelloWorld
|
168
|
+
plugin, a user has to say "!hello" instead of "hello". This prefix can
|
169
|
+
be configured on a per-plugin or global basis, but that's not in the
|
170
|
+
scope of this document.
|
171
|
+
|
172
|
+
# Final Words
|
173
|
+
|
174
|
+
This short guide only explains the basics of using Cakewalk, so that you
|
175
|
+
can get started as quickly as possible. For more advanced topics, you
|
176
|
+
will want to read the specific documents:
|
177
|
+
|
178
|
+
- {file:docs/plugins.md Plugins}
|
179
|
+
- {file:docs/bot_options.md A list of all available bot options}
|
180
|
+
- {file:docs/events.md A list of all available events}
|
181
|
+
- {file:docs/encodings.md Dealing with encodings}
|
182
|
+
- {file:docs/logging.md Logging in Cakewalk}
|
183
|
+
- {file:docs/common_tasks.md A cookbook for common tasks}
|
184
|
+
- {file:docs/common_mistakes.md A list of common mistakes and how to avoid them}
|
data/docs/logging.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# @title Logging
|
2
|
+
# @markup kramdown
|
3
|
+
|
4
|
+
# Using the logger
|
5
|
+
|
6
|
+
Plugins can use the logging facility for logging their own messages,
|
7
|
+
either by using the logging related helper methods (#debug, #info, and
|
8
|
+
so on) or by directly interfacing with {Cakewalk::LoggerList}, which is
|
9
|
+
available via `@bot.loggers`.
|
10
|
+
|
11
|
+
Example:
|
12
|
+
|
13
|
+
class MyPlugin
|
14
|
+
include Cakewalk::Plugin
|
15
|
+
|
16
|
+
match "foo"
|
17
|
+
def execute(m)
|
18
|
+
debug "Starting handler..."
|
19
|
+
info "Some more important information"
|
20
|
+
debug "Done."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Logger levels
|
25
|
+
|
26
|
+
Cakewalk uses a priority-based logging system, using the types `:debug`,
|
27
|
+
`:log`, `:info`, `:warn`, `:error` and `:fatal`, each of them
|
28
|
+
displaying less information than the previous.
|
29
|
+
|
30
|
+
By default, the logging level to display is set to `:debug`, which
|
31
|
+
will include all possible kinds of log events, including the rather
|
32
|
+
verbose debug output caused by plugins.
|
33
|
+
|
34
|
+
`:log` will hide debug output but still contain the raw IRC log and
|
35
|
+
from there on, the levels are rather self-explanatory.
|
36
|
+
|
37
|
+
## Changing the level
|
38
|
+
|
39
|
+
The level can be changed for single loggers or all loggers at once, by either using {Cakewalk::Logger#level=} or {Cakewalk::LoggerList#level=} respectively.
|
40
|
+
|
41
|
+
Example:
|
42
|
+
|
43
|
+
bot = Cakewalk::Bot.new { }
|
44
|
+
bot.loggers << Cakewalk::Logger::FormattedLogger.new(File.open("/tmp/log.log", "a"))
|
45
|
+
bot.loggers.level = :debug
|
46
|
+
bot.loggers.first.level = :info
|
47
|
+
|
48
|
+
This will set all loggers to the `:debug` level (which actually is the
|
49
|
+
default already) and the first logger (which is the default STDOUT
|
50
|
+
logger) to `:info`.
|
51
|
+
|
52
|
+
# Log filtering
|
53
|
+
|
54
|
+
Sometimes it is undesirable to log a message unchanged. For example
|
55
|
+
when identifying to the network, passwords might be sent in plain
|
56
|
+
text. To prevent such information from appearing in logs, {Cakewalk::LogFilter log filters}
|
57
|
+
can be employed.
|
58
|
+
|
59
|
+
Log filters take a log message as input and return a new message. This
|
60
|
+
allows removing/masking out passwords or other undesired information.
|
61
|
+
Additionally, messages can be dropped entirely by returning nil.
|
62
|
+
|
63
|
+
It is possible to use more than one filter, in which case they will be
|
64
|
+
called in order, each acting on the previous filter's output.
|
65
|
+
|
66
|
+
Filters can be installed by adding them to {Cakewalk::LoggerList#filters}.
|
67
|
+
|
68
|
+
An example (and very simple) password filter might look like this:
|
69
|
+
|
70
|
+
class PasswordFilter
|
71
|
+
def initialize(bot)
|
72
|
+
@bot = bot
|
73
|
+
end
|
74
|
+
|
75
|
+
def filter(message, event)
|
76
|
+
message.gsub(@bot.config.password, "*" * @bot.config.password.size)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
This filter will replace the password in all log messages (except for
|
81
|
+
exceptions). It could further discriminate by looking at `event` and
|
82
|
+
only modify outgoing IRC messages. It could also use the
|
83
|
+
{Cakewalk::Message} class to parse the message and only operate on the
|
84
|
+
actual message component, not channel names and similar. How fancy
|
85
|
+
your filtering needs to be depends on you.
|
86
|
+
|
87
|
+
# Writing your own logger
|
88
|
+
|
89
|
+
This section will follow soon. For now just look at the code of
|
90
|
+
already implemented loggers.
|