ircinch 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.standard.yml +3 -0
  3. data/CHANGELOG.md +298 -0
  4. data/CODE_OF_CONDUCT.md +84 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +23 -0
  7. data/README.md +195 -0
  8. data/Rakefile +14 -0
  9. data/docs/bot_options.md +454 -0
  10. data/docs/changes.md +541 -0
  11. data/docs/common_mistakes.md +60 -0
  12. data/docs/common_tasks.md +57 -0
  13. data/docs/encodings.md +69 -0
  14. data/docs/events.md +273 -0
  15. data/docs/getting_started.md +184 -0
  16. data/docs/logging.md +90 -0
  17. data/docs/migrating.md +267 -0
  18. data/docs/plugins.md +4 -0
  19. data/docs/readme.md +20 -0
  20. data/examples/basic/autovoice.rb +32 -0
  21. data/examples/basic/google.rb +35 -0
  22. data/examples/basic/hello.rb +14 -0
  23. data/examples/basic/join_part.rb +35 -0
  24. data/examples/basic/memo.rb +39 -0
  25. data/examples/basic/msg.rb +15 -0
  26. data/examples/basic/seen.rb +37 -0
  27. data/examples/basic/urban_dict.rb +36 -0
  28. data/examples/basic/url_shorten.rb +36 -0
  29. data/examples/plugins/autovoice.rb +37 -0
  30. data/examples/plugins/custom_prefix.rb +22 -0
  31. data/examples/plugins/dice_roll.rb +38 -0
  32. data/examples/plugins/google.rb +36 -0
  33. data/examples/plugins/hello.rb +21 -0
  34. data/examples/plugins/hooks.rb +34 -0
  35. data/examples/plugins/join_part.rb +41 -0
  36. data/examples/plugins/lambdas.rb +35 -0
  37. data/examples/plugins/last_nick.rb +24 -0
  38. data/examples/plugins/msg.rb +21 -0
  39. data/examples/plugins/multiple_matches.rb +32 -0
  40. data/examples/plugins/own_events.rb +37 -0
  41. data/examples/plugins/seen.rb +44 -0
  42. data/examples/plugins/timer.rb +22 -0
  43. data/examples/plugins/url_shorten.rb +34 -0
  44. data/ircinch.gemspec +43 -0
  45. data/lib/cinch/ban.rb +53 -0
  46. data/lib/cinch/bot.rb +476 -0
  47. data/lib/cinch/cached_list.rb +21 -0
  48. data/lib/cinch/callback.rb +22 -0
  49. data/lib/cinch/channel.rb +465 -0
  50. data/lib/cinch/channel_list.rb +31 -0
  51. data/lib/cinch/configuration/bot.rb +50 -0
  52. data/lib/cinch/configuration/dcc.rb +18 -0
  53. data/lib/cinch/configuration/plugins.rb +43 -0
  54. data/lib/cinch/configuration/sasl.rb +21 -0
  55. data/lib/cinch/configuration/ssl.rb +21 -0
  56. data/lib/cinch/configuration/timeouts.rb +16 -0
  57. data/lib/cinch/configuration.rb +75 -0
  58. data/lib/cinch/constants.rb +535 -0
  59. data/lib/cinch/dcc/dccable_object.rb +39 -0
  60. data/lib/cinch/dcc/incoming/send.rb +149 -0
  61. data/lib/cinch/dcc/incoming.rb +3 -0
  62. data/lib/cinch/dcc/outgoing/send.rb +123 -0
  63. data/lib/cinch/dcc/outgoing.rb +3 -0
  64. data/lib/cinch/dcc.rb +14 -0
  65. data/lib/cinch/exceptions.rb +48 -0
  66. data/lib/cinch/formatting.rb +127 -0
  67. data/lib/cinch/handler.rb +120 -0
  68. data/lib/cinch/handler_list.rb +92 -0
  69. data/lib/cinch/helpers.rb +230 -0
  70. data/lib/cinch/i_support.rb +100 -0
  71. data/lib/cinch/irc.rb +924 -0
  72. data/lib/cinch/log_filter.rb +23 -0
  73. data/lib/cinch/logger/formatted_logger.rb +100 -0
  74. data/lib/cinch/logger/zcbot_logger.rb +26 -0
  75. data/lib/cinch/logger.rb +171 -0
  76. data/lib/cinch/logger_list.rb +88 -0
  77. data/lib/cinch/mask.rb +69 -0
  78. data/lib/cinch/message.rb +397 -0
  79. data/lib/cinch/message_queue.rb +104 -0
  80. data/lib/cinch/mode_parser.rb +78 -0
  81. data/lib/cinch/network.rb +106 -0
  82. data/lib/cinch/open_ended_queue.rb +26 -0
  83. data/lib/cinch/pattern.rb +66 -0
  84. data/lib/cinch/plugin.rb +517 -0
  85. data/lib/cinch/plugin_list.rb +40 -0
  86. data/lib/cinch/rubyext/float.rb +5 -0
  87. data/lib/cinch/rubyext/module.rb +28 -0
  88. data/lib/cinch/rubyext/string.rb +35 -0
  89. data/lib/cinch/sasl/dh_blowfish.rb +73 -0
  90. data/lib/cinch/sasl/diffie_hellman.rb +50 -0
  91. data/lib/cinch/sasl/mechanism.rb +8 -0
  92. data/lib/cinch/sasl/plain.rb +29 -0
  93. data/lib/cinch/sasl.rb +36 -0
  94. data/lib/cinch/syncable.rb +83 -0
  95. data/lib/cinch/target.rb +199 -0
  96. data/lib/cinch/timer.rb +147 -0
  97. data/lib/cinch/user.rb +489 -0
  98. data/lib/cinch/user_list.rb +89 -0
  99. data/lib/cinch/utilities/deprecation.rb +18 -0
  100. data/lib/cinch/utilities/encoding.rb +39 -0
  101. data/lib/cinch/utilities/kernel.rb +15 -0
  102. data/lib/cinch/version.rb +6 -0
  103. data/lib/cinch.rb +7 -0
  104. data/lib/ircinch.rb +7 -0
  105. metadata +205 -0
@@ -0,0 +1,465 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ require_relative "target"
6
+
7
+ module Cinch
8
+ # @attr limit
9
+ # @attr secret
10
+ # @attr moderated
11
+ # @attr invite_only
12
+ # @attr key
13
+ #
14
+ # @version 2.0.0
15
+ class Channel < Target
16
+ include Syncable
17
+ include Helpers
18
+
19
+ # Users are represented by a Hash, mapping individual users to an
20
+ # array of modes (e.g. "o" for opped).
21
+ #
22
+ # @return [Hash{User => Array<String}>] all users in the channel
23
+ # @version 1.1.0
24
+ attr_reader :users
25
+ synced_attr_reader :users
26
+
27
+ # @return [String] the channel's topic
28
+ attr_accessor :topic
29
+ synced_attr_reader :topic
30
+
31
+ # @return [Array<Ban>] all active bans
32
+ attr_reader :bans
33
+ synced_attr_reader :bans
34
+
35
+ # @return [Array<User>] all channel owners
36
+ # @note Only some networks implement this
37
+ attr_reader :owners
38
+ synced_attr_reader :owners
39
+
40
+ # This attribute describes all modes set in the channel. They're
41
+ # represented as a Hash, mapping the mode (e.g. "i", "k", …) to
42
+ # either a value in the case of modes that take an option (e.g.
43
+ # "k" for the channel key) or true.
44
+ #
45
+ # @return [Hash{String => Object}]
46
+ attr_reader :modes
47
+ synced_attr_reader :modes
48
+
49
+ # @note Generally, you shouldn't initialize new instances of this
50
+ # class. Use {ChannelList#find_ensured} instead.
51
+ def initialize(name, bot)
52
+ @bot = bot
53
+ @name = name
54
+ @users = Hash.new { |h, k| h[k] = [] }
55
+ @bans = []
56
+ @owners = []
57
+
58
+ @modes = {}
59
+ # TODO raise if not a channel
60
+
61
+ @topic = nil
62
+
63
+ @in_channel = false
64
+
65
+ @synced_attributes = Set.new
66
+ @when_requesting_synced_attribute = lambda { |attr|
67
+ if @in_channel && attr == :topic && !attribute_synced?(:topic)
68
+ # Even if we are in the channel, if there's no topic set,
69
+ # the attribute won't be synchronised yet. Explicitly
70
+ # request the topic.
71
+ @bot.irc.send "TOPIC #{@name}"
72
+ next
73
+ end
74
+
75
+ unless @in_channel
76
+ unsync(attr)
77
+ case attr
78
+ when :users
79
+ @bot.irc.send "NAMES #{@name}"
80
+ when :topic
81
+ @bot.irc.send "TOPIC #{@name}"
82
+ when :bans
83
+ @bot.irc.send "MODE #{@name} +b"
84
+ when :owners
85
+ if @bot.irc.network.owner_list_mode
86
+ @bot.irc.send "MODE #{@name} +#{@bot.irc.network.owner_list_mode}"
87
+ else
88
+ # the current IRCd does not support channel owners, so
89
+ # just mark the empty array as synced
90
+ mark_as_synced(:owners)
91
+ end
92
+ when :modes
93
+ @bot.irc.send "MODE #{@name}"
94
+ end
95
+ end
96
+ }
97
+ end
98
+
99
+ # @group Checks
100
+
101
+ # @param [User, String] user An {User}-object or a nickname
102
+ # @return [Boolean] Check if a user is in the channel
103
+ # @since 1.1.0
104
+ # @version 1.1.2
105
+ def has_user?(user)
106
+ @users.has_key?(User(user))
107
+ end
108
+
109
+ # @return [Boolean] true if `user` is opped in the channel
110
+ # @since 1.1.0
111
+ def opped?(user)
112
+ @users[User(user)].include? "o"
113
+ end
114
+
115
+ # @return [Boolean] true if `user` is half-opped in the channel
116
+ # @since 1.1.0
117
+ def half_opped?(user)
118
+ @users[User(user)].include? "h"
119
+ end
120
+
121
+ # @return [Boolean] true if `user` is voiced in the channel
122
+ # @since 1.1.0
123
+ def voiced?(user)
124
+ @users[User(user)].include? "v"
125
+ end
126
+
127
+ # @endgroup
128
+
129
+ # @group User groups
130
+ # @return [Array<User>] All ops in the channel
131
+ # @since 2.0.0
132
+ def ops
133
+ @users.select { |user, modes| modes.include?("o") }.keys
134
+ end
135
+
136
+ # @return [Array<User>] All half-ops in the channel
137
+ # @since 2.0.0
138
+ def half_ops
139
+ @users.select { |user, modes| modes.include?("h") }.keys
140
+ end
141
+
142
+ # @return [Array<User>] All voiced users in the channel
143
+ # @since 2.0.0
144
+ def voiced
145
+ @users.select { |user, modes| modes.include?("v") }.keys
146
+ end
147
+
148
+ # @return [Array<User>] All admins in the channel
149
+ # @since 2.0.0
150
+ def admins
151
+ @users.select { |user, modes| modes.include?("a") }.keys
152
+ end
153
+ # @endgroup
154
+
155
+ # @return [Integer] The maximum number of allowed users in the
156
+ # channel. 0 if unlimited.
157
+ def limit
158
+ @modes["l"].to_i
159
+ end
160
+
161
+ def limit=(val)
162
+ if val == -1 || val.nil?
163
+ mode "-l"
164
+ else
165
+ mode "+l #{val}"
166
+ end
167
+ end
168
+
169
+ # @return [Boolean] true if the channel is secret (+s)
170
+ def secret
171
+ @modes["s"]
172
+ end
173
+ alias_method :secret?, :secret
174
+
175
+ def secret=(bool)
176
+ if bool
177
+ mode "+s"
178
+ else
179
+ mode "-s"
180
+ end
181
+ end
182
+
183
+ # @return [Boolean] true if the channel is moderated
184
+ def moderated
185
+ @modes["m"]
186
+ end
187
+ alias_method :moderated?, :moderated
188
+
189
+ def moderated=(bool)
190
+ if bool
191
+ mode "+m"
192
+ else
193
+ mode "-m"
194
+ end
195
+ end
196
+
197
+ # @return [Boolean] true if the channel is invite only (+i)
198
+ def invite_only
199
+ @modes["i"]
200
+ end
201
+ alias_method :invite_only?, :invite_only
202
+
203
+ def invite_only=(bool)
204
+ if bool
205
+ mode "+i"
206
+ else
207
+ mode "-i"
208
+ end
209
+ end
210
+
211
+ # @return [String, nil] The channel's key (aka password)
212
+ def key
213
+ @modes["k"]
214
+ end
215
+
216
+ def key=(new_key)
217
+ if new_key.nil?
218
+ mode "-k #{key}"
219
+ else
220
+ mode "+k #{new_key}"
221
+ end
222
+ end
223
+
224
+ # @api private
225
+ # @return [void]
226
+ def sync_modes
227
+ unsync :users
228
+ unsync :bans
229
+ unsync :modes
230
+ unsync :owners
231
+
232
+ if @bot.irc.isupport["WHOX"]
233
+ @bot.irc.send "WHO #{@name} %acfhnru"
234
+ else
235
+ @bot.irc.send "WHO #{@name}"
236
+ end
237
+ @bot.irc.send "MODE #{@name} +b" # bans
238
+ @bot.irc.send "MODE #{@name}"
239
+ if @bot.irc.network.owner_list_mode
240
+ @bot.irc.send "MODE #{@name} +#{@bot.irc.network.owner_list_mode}"
241
+ else
242
+ mark_as_synced :owners
243
+ end
244
+ end
245
+
246
+ # @group Channel Manipulation
247
+
248
+ # Bans someone from the channel.
249
+ #
250
+ # @param [Mask, String, #mask] target the mask, or an object having a mask, to ban
251
+ # @return [Mask] the mask used for banning
252
+ # @see #unban #unban for unbanning users
253
+ def ban(target)
254
+ mask = Mask.from(target)
255
+
256
+ @bot.irc.send "MODE #{@name} +b #{mask}"
257
+ mask
258
+ end
259
+
260
+ # Unbans someone from the channel.
261
+ #
262
+ # @param [Mask, String, #mask] target the mask to unban
263
+ # @return [Mask] the mask used for unbanning
264
+ # @see #ban #ban for banning users
265
+ def unban(target)
266
+ mask = Mask.from(target)
267
+
268
+ @bot.irc.send "MODE #{@name} -b #{mask}"
269
+ mask
270
+ end
271
+
272
+ # Ops a user.
273
+ #
274
+ # @param [String, User] user the user to op
275
+ # @return [void]
276
+ def op(user)
277
+ @bot.irc.send "MODE #{@name} +o #{user}"
278
+ end
279
+
280
+ # Deops a user.
281
+ #
282
+ # @param [String, User] user the user to deop
283
+ # @return [void]
284
+ def deop(user)
285
+ @bot.irc.send "MODE #{@name} -o #{user}"
286
+ end
287
+
288
+ # Voices a user.
289
+ #
290
+ # @param [String, User] user the user to voice
291
+ # @return [void]
292
+ def voice(user)
293
+ @bot.irc.send "MODE #{@name} +v #{user}"
294
+ end
295
+
296
+ # Devoices a user.
297
+ #
298
+ # @param [String, User] user the user to devoice
299
+ # @return [void]
300
+ def devoice(user)
301
+ @bot.irc.send "MODE #{@name} -v #{user}"
302
+ end
303
+
304
+ # Invites a user to the channel.
305
+ #
306
+ # @param [String, User] user the user to invite
307
+ # @return [void]
308
+ def invite(user)
309
+ @bot.irc.send("INVITE #{user} #{@name}")
310
+ end
311
+
312
+ undef_method(:topic=)
313
+ # Sets the topic.
314
+ #
315
+ # @param [String] new_topic the new topic
316
+ # @raise [Exceptions::TopicTooLong] Raised if the bot is operating
317
+ # in {Bot#strict? strict mode} and when the new topic is too long.
318
+ def topic=(new_topic)
319
+ if new_topic.size > @bot.irc.isupport["TOPICLEN"] && @bot.strict?
320
+ raise Exceptions::TopicTooLong, new_topic
321
+ end
322
+
323
+ @bot.irc.send "TOPIC #{@name} :#{new_topic}"
324
+ end
325
+
326
+ # Kicks a user from the channel.
327
+ #
328
+ # @param [String, User] user the user to kick
329
+ # @param [String] reason a reason for the kick
330
+ # @raise [Exceptions::KickReasonTooLong]
331
+ # @return [void]
332
+ def kick(user, reason = nil)
333
+ if reason.to_s.size > @bot.irc.isupport["KICKLEN"] && @bot.strict?
334
+ raise Exceptions::KickReasonTooLong, reason
335
+ end
336
+
337
+ @bot.irc.send("KICK #{@name} #{user} :#{reason}")
338
+ end
339
+
340
+ # Removes a user from the channel.
341
+ #
342
+ # This uses the REMOVE command, which is a non-standardized
343
+ # extension. Unlike a kick, it makes a user part. This prevents
344
+ # auto-rejoin scripts from firing and might also be perceived as
345
+ # less aggressive by some. Not all IRC networks support this
346
+ # command.
347
+ #
348
+ # @param [User] user the user to remove
349
+ # @param [String] reason a reason for the removal
350
+ # @return [void]
351
+ def remove(user, reason = nil)
352
+ @bot.irc.send("REMOVE #{@name} #{user} :#{reason}")
353
+ end
354
+
355
+ # Sets or unsets modes. Most of the time you won't need this but
356
+ # use setter methods like {Channel#invite_only=}.
357
+ #
358
+ # @param [String] s a mode string
359
+ # @return [void]
360
+ # @example
361
+ # channel.mode "+n"
362
+ def mode(s)
363
+ @bot.irc.send "MODE #{@name} #{s}"
364
+ end
365
+
366
+ # Causes the bot to part from the channel.
367
+ #
368
+ # @param [String] message the part message.
369
+ # @return [void]
370
+ def part(message = nil)
371
+ @bot.irc.send "PART #{@name} :#{message}"
372
+ end
373
+
374
+ # Joins the channel
375
+ #
376
+ # @param [String] key the channel key, if any. If none is
377
+ # specified but @key is set, @key will be used
378
+ # @return [void]
379
+ def join(key = nil)
380
+ if key.nil? && self.key != true
381
+ key = self.key
382
+ end
383
+ @bot.irc.send "JOIN #{[@name, key].compact.join(" ")}"
384
+ end
385
+
386
+ # @endgroup
387
+
388
+ # @api private
389
+ # @return [User] The added user
390
+ def add_user(user, modes = [])
391
+ @in_channel = true if user == @bot
392
+ @users[user] = modes
393
+ user
394
+ end
395
+
396
+ # @api private
397
+ # @return [User, nil] The removed user
398
+ def remove_user(user)
399
+ @in_channel = false if user == @bot
400
+ @users.delete(user)
401
+ end
402
+
403
+ # Removes all users
404
+ #
405
+ # @api private
406
+ # @return [void]
407
+ def clear_users
408
+ @users.clear
409
+ end
410
+
411
+ # @note The aliases `msg` and `privmsg` are deprecated and will be
412
+ # removed in a future version.
413
+ def send(text, notice = false)
414
+ # TODO deprecate 'notice' argument
415
+ text = text.to_s
416
+ if @modes["c"]
417
+ # Remove all formatting and colors if the channel doesn't
418
+ # allow colors.
419
+ text = Cinch::Formatting.unformat(text)
420
+ end
421
+ super(text, notice)
422
+ end
423
+ alias_method :msg, :send # deprecated
424
+ alias_method :privmsg, :send # deprecated
425
+ undef_method(:msg) # yardoc hack
426
+ undef_method(:privmsg) # yardoc hack
427
+
428
+ # @deprecated
429
+ def msg(*args)
430
+ Cinch::Utilities::Deprecation.print_deprecation("2.2.0", "Channel#msg", "Channel#send")
431
+ send(*args)
432
+ end
433
+
434
+ # @deprecated
435
+ def privmsg(*args)
436
+ Cinch::Utilities::Deprecation.print_deprecation("2.2.0", "Channel#privmsg", "Channel#send")
437
+ send(*args)
438
+ end
439
+
440
+ # @return [Fixnum]
441
+ def hash
442
+ @name.hash
443
+ end
444
+
445
+ # @return [String]
446
+ # @note The alias `to_str` is deprecated and will be removed in a
447
+ # future version. Channel objects should not be treated like
448
+ # strings.
449
+ def to_s
450
+ @name
451
+ end
452
+ alias_method :to_str, :to_s # deprecated
453
+ undef_method(:to_str) # yardoc hack
454
+
455
+ def to_str
456
+ Cinch::Utilities::Deprecation.print_deprecation("2.2.0", "Channel#to_str", "Channel#to_s")
457
+ to_s
458
+ end
459
+
460
+ # @return [String]
461
+ def inspect
462
+ "#<Channel name=#{@name.inspect}>"
463
+ end
464
+ end
465
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cached_list"
4
+
5
+ module Cinch
6
+ # @since 2.0.0
7
+ # @version 1.1.0
8
+ # @note In prior versions, this class was called ChannelManager
9
+ class ChannelList < CachedList
10
+ # Finds or creates a channel.
11
+ #
12
+ # @param [String] name name of a channel
13
+ # @return [Channel]
14
+ # @see Helpers#Channel
15
+ def find_ensured(name)
16
+ downcased_name = name.irc_downcase(@bot.irc.isupport["CASEMAPPING"])
17
+ @mutex.synchronize do
18
+ @cache[downcased_name] ||= Channel.new(name, @bot)
19
+ end
20
+ end
21
+
22
+ # Finds a channel.
23
+ #
24
+ # @param [String] name name of a channel
25
+ # @return [Channel, nil]
26
+ def find(name)
27
+ downcased_name = name.irc_downcase(@bot.irc.isupport["CASEMAPPING"])
28
+ @cache[downcased_name]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../configuration"
4
+
5
+ module Cinch
6
+ class Configuration
7
+ # @since 2.0.0
8
+ class Bot < Configuration
9
+ KNOWN_OPTIONS = [:server, :port, :ssl, :password, :nick, :nicks,
10
+ :realname, :user, :messages_per_second, :server_queue_size,
11
+ :strictness, :message_split_start, :message_split_end,
12
+ :max_messages, :plugins, :channels, :encoding, :reconnect, :max_reconnect_delay,
13
+ :local_host, :timeouts, :ping_interval, :delay_joins, :dcc, :shared, :sasl, :default_logger_level]
14
+
15
+ # (see Configuration.default_config)
16
+ def self.default_config
17
+ {
18
+ server: "localhost",
19
+ port: 6667,
20
+ ssl: Configuration::SSL.new,
21
+ password: nil,
22
+ nick: "ircinch",
23
+ nicks: nil,
24
+ realname: "ircinch",
25
+ user: "ircinch",
26
+ modes: [],
27
+ messages_per_second: nil,
28
+ server_queue_size: nil,
29
+ strictness: :forgiving,
30
+ message_split_start: "... ",
31
+ message_split_end: " ...",
32
+ max_messages: nil,
33
+ plugins: Configuration::Plugins.new,
34
+ channels: [],
35
+ encoding: :irc,
36
+ reconnect: true,
37
+ max_reconnect_delay: 300,
38
+ local_host: nil,
39
+ timeouts: Configuration::Timeouts.new,
40
+ ping_interval: 120,
41
+ delay_joins: 0,
42
+ dcc: Configuration::DCC.new,
43
+ sasl: Configuration::SASL.new,
44
+ shared: {},
45
+ default_logger_level: :debug
46
+ }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../configuration"
4
+
5
+ module Cinch
6
+ class Configuration
7
+ # @since 2.0.0
8
+ class DCC < Configuration
9
+ KNOWN_OPTIONS = [:own_ip]
10
+
11
+ def self.default_config
12
+ {
13
+ own_ip: nil
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../configuration"
4
+
5
+ module Cinch
6
+ class Configuration
7
+ # @since 2.0.0
8
+ class Plugins < Configuration
9
+ KNOWN_OPTIONS = [:plugins, :prefix, :suffix, :options]
10
+
11
+ def self.default_config
12
+ {
13
+ plugins: [],
14
+ prefix: /^!/,
15
+ suffix: nil,
16
+ options: Hash.new { |h, k| h[k] = {} }
17
+ }
18
+ end
19
+
20
+ def load(new_config, from_default = false)
21
+ fresh_new_config = {}
22
+ new_config.each do |option, value|
23
+ case option
24
+ when :plugins
25
+ fresh_new_config[option] = value.map { |v| Cinch::Utilities::Kernel.string_to_const(v) }
26
+ when :options
27
+ fresh_value = self[:options]
28
+ value.each do |k, v|
29
+ k = Cinch::Utilities::Kernel.string_to_const(k)
30
+ v = self[:options][k].merge(v)
31
+ fresh_value[k] = v
32
+ end
33
+ fresh_new_config[option] = fresh_value
34
+ else
35
+ fresh_new_config[option] = value
36
+ end
37
+ end
38
+
39
+ super(fresh_new_config, from_default)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../configuration"
4
+ require_relative "../sasl"
5
+
6
+ module Cinch
7
+ class Configuration
8
+ # @since 2.0.0
9
+ class SASL < Configuration
10
+ KNOWN_OPTIONS = [:username, :password, :mechanisms]
11
+
12
+ def self.default_config
13
+ {
14
+ username: nil,
15
+ password: nil,
16
+ mechanisms: [Cinch::SASL::DhBlowfish, Cinch::SASL::Plain]
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../configuration"
4
+
5
+ module Cinch
6
+ class Configuration
7
+ # @since 2.0.0
8
+ class SSL < Configuration
9
+ KNOWN_OPTIONS = [:use, :verify, :client_cert, :ca_path]
10
+
11
+ def self.default_config
12
+ {
13
+ use: false,
14
+ verify: false,
15
+ client_cert: nil,
16
+ ca_path: "/etc/ssl/certs"
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../configuration"
4
+
5
+ module Cinch
6
+ class Configuration
7
+ # @since 2.0.0
8
+ class Timeouts < Configuration
9
+ KNOWN_OPTIONS = [:read, :connect]
10
+
11
+ def self.default_config
12
+ {read: 240, connect: 10}
13
+ end
14
+ end
15
+ end
16
+ end