grinch 1.0.1 → 1.1.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -2
  3. data/lib/cinch.rb +7 -5
  4. data/lib/cinch/ban.rb +6 -2
  5. data/lib/cinch/bot.rb +21 -31
  6. data/lib/cinch/cached_list.rb +2 -0
  7. data/lib/cinch/callback.rb +2 -0
  8. data/lib/cinch/channel.rb +43 -44
  9. data/lib/cinch/channel_list.rb +2 -0
  10. data/lib/cinch/configuration.rb +8 -6
  11. data/lib/cinch/configuration/bot.rb +35 -33
  12. data/lib/cinch/configuration/dcc.rb +4 -2
  13. data/lib/cinch/configuration/plugins.rb +8 -6
  14. data/lib/cinch/configuration/sasl.rb +6 -4
  15. data/lib/cinch/configuration/ssl.rb +7 -5
  16. data/lib/cinch/configuration/timeouts.rb +4 -2
  17. data/lib/cinch/constants.rb +3 -1
  18. data/lib/cinch/dcc.rb +2 -0
  19. data/lib/cinch/dcc/dccable_object.rb +6 -8
  20. data/lib/cinch/dcc/incoming.rb +2 -0
  21. data/lib/cinch/dcc/incoming/send.rb +10 -8
  22. data/lib/cinch/dcc/outgoing.rb +2 -0
  23. data/lib/cinch/dcc/outgoing/send.rb +13 -14
  24. data/lib/cinch/exceptions.rb +2 -0
  25. data/lib/cinch/formatting.rb +32 -30
  26. data/lib/cinch/handler.rb +15 -13
  27. data/lib/cinch/handler_list.rb +13 -13
  28. data/lib/cinch/helpers.rb +16 -16
  29. data/lib/cinch/irc.rb +118 -142
  30. data/lib/cinch/isupport.rb +22 -20
  31. data/lib/cinch/log_filter.rb +3 -2
  32. data/lib/cinch/logger.rb +7 -2
  33. data/lib/cinch/logger/formatted_logger.rb +17 -13
  34. data/lib/cinch/logger/zcbot_logger.rb +4 -0
  35. data/lib/cinch/logger_list.rb +15 -14
  36. data/lib/cinch/mask.rb +11 -9
  37. data/lib/cinch/message.rb +6 -6
  38. data/lib/cinch/message_queue.rb +5 -4
  39. data/lib/cinch/mode_parser.rb +7 -5
  40. data/lib/cinch/network.rb +2 -0
  41. data/lib/cinch/open_ended_queue.rb +5 -5
  42. data/lib/cinch/pattern.rb +11 -8
  43. data/lib/cinch/plugin.rb +43 -49
  44. data/lib/cinch/plugin_list.rb +4 -4
  45. data/lib/cinch/rubyext/float.rb +3 -3
  46. data/lib/cinch/rubyext/module.rb +2 -0
  47. data/lib/cinch/rubyext/string.rb +8 -6
  48. data/lib/cinch/sasl.rb +2 -0
  49. data/lib/cinch/sasl/dh_blowfish.rb +5 -3
  50. data/lib/cinch/sasl/diffie_hellman.rb +6 -3
  51. data/lib/cinch/sasl/mechanism.rb +2 -0
  52. data/lib/cinch/sasl/plain.rb +2 -0
  53. data/lib/cinch/syncable.rb +10 -9
  54. data/lib/cinch/target.rb +15 -17
  55. data/lib/cinch/timer.rb +9 -7
  56. data/lib/cinch/user.rb +52 -48
  57. data/lib/cinch/user_list.rb +8 -11
  58. data/lib/cinch/utilities/deprecation.rb +5 -5
  59. data/lib/cinch/utilities/encoding.rb +9 -9
  60. data/lib/cinch/utilities/kernel.rb +4 -1
  61. data/lib/cinch/version.rb +3 -1
  62. metadata +4 -4
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # @since 2.0.0
3
5
  class Target
@@ -30,7 +32,7 @@ module Cinch
30
32
  # @note The aliases `msg` and `privmsg` are deprecated and will be
31
33
  # removed in a future version.
32
34
  def send(text, notice = false)
33
- # TODO deprecate `notice` argument, put splitting into own
35
+ # TODO: deprecate `notice` argument, put splitting into own
34
36
  # method
35
37
  text = text.to_s
36
38
  split_start = @bot.config.message_split_start || ""
@@ -42,12 +44,12 @@ module Cinch
42
44
  splitted = split_message(line, prefix, split_start, split_end)
43
45
 
44
46
  splitted[0, (@bot.config.max_messages || splitted.size)].each do |string|
45
- @bot.irc.send("#{command} #@name :#{string}")
47
+ @bot.irc.send("#{command} #{@name} :#{string}")
46
48
  end
47
49
  end
48
50
  end
49
- alias_method :msg, :send # deprecated
50
- alias_method :privmsg, :send # deprecated
51
+ alias msg send # deprecated
52
+ alias privmsg send # deprecated
51
53
  undef_method(:msg) # yardoc hack
52
54
  undef_method(:privmsg) # yardoc hack
53
55
 
@@ -78,8 +80,8 @@ module Cinch
78
80
  def safe_send(text, notice = false)
79
81
  send(Cinch::Helpers.sanitize(text), notice)
80
82
  end
81
- alias_method :safe_msg, :safe_send # deprecated
82
- alias_method :safe_privmsg, :safe_msg # deprecated
83
+ alias safe_msg safe_send # deprecated
84
+ alias safe_privmsg safe_msg # deprecated
83
85
  undef_method(:safe_msg) # yardoc hack
84
86
  undef_method(:safe_privmsg) # yardoc hack
85
87
 
@@ -95,7 +97,6 @@ module Cinch
95
97
  send(*args)
96
98
  end
97
99
 
98
-
99
100
  # Like {#safe_msg} but for notices.
100
101
  #
101
102
  # @return (see #safe_msg)
@@ -113,7 +114,7 @@ module Cinch
113
114
  # @see #safe_action
114
115
  def action(text)
115
116
  line = text.to_s.each_line.first.chomp
116
- @bot.irc.send("PRIVMSG #@name :\001ACTION #{line}\001")
117
+ @bot.irc.send("PRIVMSG #{@name} :\001ACTION #{line}\001")
117
118
  end
118
119
 
119
120
  # Like {#action}, but remove any non-printable characters from
@@ -163,28 +164,25 @@ module Cinch
163
164
  left <=> other.name.irc_downcase(casemapping)
164
165
  elsif other.is_a?(String)
165
166
  left <=> other.irc_downcase(casemapping)
166
- else
167
- nil
168
167
  end
169
168
  end
170
169
 
171
170
  private
171
+
172
172
  def split_message(msg, prefix, split_start, split_end)
173
173
  max_bytesize = 510 - prefix.bytesize
174
174
  max_bytesize_without_end = max_bytesize - split_end.bytesize
175
175
 
176
- if msg.bytesize <= max_bytesize
177
- return [msg]
178
- end
176
+ return [msg] if msg.bytesize <= max_bytesize
179
177
 
180
178
  splitted = []
181
179
  while msg.bytesize > max_bytesize_without_end
182
180
  acc = 0
183
- acc_rune_sizes = msg.each_char.map {|ch|
181
+ acc_rune_sizes = msg.each_char.map do |ch|
184
182
  acc += ch.bytesize
185
- }
183
+ end
186
184
 
187
- max_rune = acc_rune_sizes.rindex {|bs| bs <= max_bytesize_without_end} || 0
185
+ max_rune = acc_rune_sizes.rindex { |bs| bs <= max_bytesize_without_end } || 0
188
186
  r = [msg.rindex(/\s/, max_rune) || (max_rune + 1), 1].max
189
187
 
190
188
  splitted << (msg[0...r] + split_end)
@@ -193,7 +191,7 @@ module Cinch
193
191
  splitted << msg
194
192
 
195
193
  # clean string from any substitute characters
196
- splitted.map {|string| string.tr("\cz", " ")}
194
+ splitted.map { |string| string.tr("\cz", " ") }
197
195
  end
198
196
  end
199
197
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/helpers"
2
4
 
3
5
  module Cinch
@@ -41,8 +43,8 @@ module Cinch
41
43
  # will stop. This value will automatically reset after
42
44
  # restarting the timer.
43
45
  attr_accessor :shots
44
- alias_method :threaded?, :threaded
45
- alias_method :started?, :started
46
+ alias threaded? threaded
47
+ alias started? started
46
48
 
47
49
  # @return [ThreadGroup]
48
50
  # @api private
@@ -62,7 +64,7 @@ module Cinch
62
64
  # @option options [Boolean] :stop_automaticall (true) If true, the
63
65
  # timer will automatically stop when the bot disconnects.
64
66
  def initialize(bot, options, &block)
65
- options = {:threaded => true, :shots => Float::INFINITY, :start_automatically => true, :stop_automatically => true}.merge(options)
67
+ options = { threaded: true, shots: Float::INFINITY, start_automatically: true, stop_automatically: true }.merge(options)
66
68
 
67
69
  @bot = bot
68
70
  @interval = options[:interval].to_f
@@ -76,13 +78,13 @@ module Cinch
76
78
  @thread_group = ThreadGroup.new
77
79
 
78
80
  if options[:start_automatically]
79
- @bot.on :connect, //, self do |m, timer|
81
+ @bot.on :connect, //, self do |_m, timer|
80
82
  timer.start
81
83
  end
82
84
  end
83
85
 
84
86
  if options[:stop_automatically]
85
- @bot.on :disconnect, //, self do |m, timer|
87
+ @bot.on :disconnect, //, self do |_m, timer|
86
88
  timer.stop
87
89
  end
88
90
  end
@@ -104,7 +106,7 @@ module Cinch
104
106
  @shots = @orig_shots
105
107
 
106
108
  @thread_group.add Thread.new {
107
- while @shots > 0 do
109
+ while @shots > 0
108
110
  sleep @interval
109
111
  if threaded?
110
112
  Thread.new do
@@ -133,7 +135,7 @@ module Cinch
133
135
 
134
136
  @bot.loggers.debug "[timer] Stopping timer #{self}"
135
137
 
136
- @thread_group.list.each { |thread| thread.kill }
138
+ @thread_group.list.each(&:kill)
137
139
  @started = false
138
140
  end
139
141
 
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  require "cinch/target"
3
4
  require "timeout"
4
5
 
@@ -37,7 +38,7 @@ module Cinch
37
38
  # @return [Boolean]
38
39
  attr_reader :synced
39
40
  # @since 2.1.0
40
- alias_method :synced?, :synced
41
+ alias synced? synced
41
42
 
42
43
  # @return [Boolean]
43
44
  # @api private
@@ -74,7 +75,7 @@ module Cinch
74
75
  def unknown
75
76
  attr(:unknown?, true, false)
76
77
  end
77
- alias_method :unknown?, :unknown
78
+ alias unknown? unknown
78
79
 
79
80
  # @note This attribute will be updated by various events, but
80
81
  # unless {#monitor} is being used, this information cannot be
@@ -82,7 +83,7 @@ module Cinch
82
83
  def online
83
84
  attr(:online?, true, false)
84
85
  end
85
- alias_method :online?, :online
86
+ alias online? online
86
87
 
87
88
  def channels
88
89
  attr(:channels, true, false)
@@ -91,13 +92,13 @@ module Cinch
91
92
  def secure
92
93
  attr(:secure?, true, false)
93
94
  end
94
- alias_method :secure?, :secure
95
+ alias secure? secure
95
96
 
96
97
  # @since 2.1.0
97
98
  def oper
98
99
  attr(:oper?, true, false)
99
100
  end
100
- alias_method :oper?, :oper
101
+ alias oper? oper
101
102
 
102
103
  # @private
103
104
  def user_unsynced
@@ -180,7 +181,7 @@ module Cinch
180
181
  # @note The attribute writer is in fact part of the private API
181
182
  attr_reader :monitored
182
183
  # @since 2.1.0
183
- alias_method :monitored?, :monitored
184
+ alias monitored? monitored
184
185
 
185
186
  # @api private
186
187
  attr_writer :monitored
@@ -189,18 +190,18 @@ module Cinch
189
190
  # class. Use {UserList#find_ensured} instead.
190
191
  def initialize(*args)
191
192
  @data = {
192
- :user => nil,
193
- :host => nil,
194
- :realname => nil,
195
- :authname => nil,
196
- :idle => 0,
197
- :signed_on_at => nil,
198
- :unknown? => false,
199
- :online? => false,
200
- :channels => [],
201
- :secure? => false,
202
- :away => nil,
203
- :oper? => false,
193
+ user: nil,
194
+ host: nil,
195
+ realname: nil,
196
+ authname: nil,
197
+ idle: 0,
198
+ signed_on_at: nil,
199
+ unknown?: false,
200
+ online?: false,
201
+ channels: [],
202
+ secure?: false,
203
+ away: nil,
204
+ oper?: false,
204
205
  }
205
206
  case args.size
206
207
  when 2
@@ -211,9 +212,9 @@ module Cinch
211
212
  raise ArgumentError
212
213
  end
213
214
 
214
- @synced_attributes = Set.new
215
+ @synced_attributes = Set.new
215
216
 
216
- @when_requesting_synced_attribute = lambda {|attr|
217
+ @when_requesting_synced_attribute = lambda { |attr|
217
218
  unless attribute_synced?(attr)
218
219
  @data[:unknown?] = false
219
220
  unsync :unknown?
@@ -248,18 +249,19 @@ module Cinch
248
249
  # future version.
249
250
  def refresh
250
251
  return if @in_whois
252
+
251
253
  @data.keys.each do |attr|
252
254
  unsync attr
253
255
  end
254
256
 
255
257
  @in_whois = true
256
258
  if @bot.irc.network.whois_only_one_argument?
257
- @bot.irc.send "WHOIS #@name"
259
+ @bot.irc.send "WHOIS #{@name}"
258
260
  else
259
- @bot.irc.send "WHOIS #@name #@name"
261
+ @bot.irc.send "WHOIS #{@name} #{@name}"
260
262
  end
261
263
  end
262
- alias_method :whois, :refresh # deprecated
264
+ alias whois refresh # deprecated
263
265
  undef_method(:whois) # yardoc hack
264
266
 
265
267
  # @deprecated
@@ -303,16 +305,16 @@ module Cinch
303
305
  end
304
306
 
305
307
  if values[:registered]
306
- values[:authname] ||= self.nick
308
+ values[:authname] ||= nick
307
309
  values.delete(:registered)
308
310
  end
309
311
  {
310
- :authname => nil,
311
- :idle => 0,
312
- :secure? => false,
313
- :oper? => false,
314
- :away => nil,
315
- :channels => [],
312
+ authname: nil,
313
+ idle: 0,
314
+ secure?: false,
315
+ oper?: false,
316
+ away: nil,
317
+ channels: [],
316
318
  }.merge(values).each do |attr, value|
317
319
  sync(attr, value, true)
318
320
  end
@@ -351,20 +353,20 @@ module Cinch
351
353
  #
352
354
  # @return [Mask]
353
355
  def mask(s = "%n!%u@%h")
354
- s = s.gsub(/%(.)/) {
355
- case $1
356
+ s = s.gsub(/%(.)/) do
357
+ case Regexp.last_match(1)
356
358
  when "n"
357
359
  @name
358
360
  when "u"
359
- self.user
361
+ user
360
362
  when "h"
361
- self.host
363
+ host
362
364
  when "r"
363
- self.realname
365
+ realname
364
366
  when "a"
365
- self.authname
367
+ authname
366
368
  end
367
- }
369
+ end
368
370
 
369
371
  Mask.new(s)
370
372
  end
@@ -376,7 +378,7 @@ module Cinch
376
378
  def match(other)
377
379
  Mask.from(other) =~ Mask.from(self)
378
380
  end
379
- alias_method :=~, :match
381
+ alias =~ match
380
382
 
381
383
  # Starts monitoring a user's online state by either using MONITOR
382
384
  # or periodically running WHOIS.
@@ -386,12 +388,12 @@ module Cinch
386
388
  # @see #unmonitor
387
389
  def monitor
388
390
  if @bot.irc.isupport["MONITOR"] > 0
389
- @bot.irc.send "MONITOR + #@name"
391
+ @bot.irc.send "MONITOR + #{@name}"
390
392
  else
391
393
  refresh
392
- @monitored_timer = Timer.new(@bot, interval: 30) {
394
+ @monitored_timer = Timer.new(@bot, interval: 30) do
393
395
  refresh
394
- }
396
+ end
395
397
  @monitored_timer.start
396
398
  end
397
399
 
@@ -405,9 +407,9 @@ module Cinch
405
407
  # @see #monitor
406
408
  def unmonitor
407
409
  if @bot.irc.isupport["MONITOR"] > 0
408
- @bot.irc.send "MONITOR - #@name"
410
+ @bot.irc.send "MONITOR - #{@name}"
409
411
  else
410
- @monitored_timer.stop if @monitored_timer
412
+ @monitored_timer&.stop
411
413
  end
412
414
 
413
415
  @monitored = false
@@ -425,8 +427,7 @@ module Cinch
425
427
  dcc = DCC::Outgoing::Send.new(receiver: self,
426
428
  filename: filename,
427
429
  io: io,
428
- own_ip: own_ip
429
- )
430
+ own_ip: own_ip)
430
431
 
431
432
  dcc.start_server
432
433
 
@@ -435,6 +436,7 @@ module Cinch
435
436
  /\001DCC RESUME #{filename} #{dcc.port} (\d+)\001/,
436
437
  /$/)) do |m, position|
437
438
  next unless m.user == self
439
+
438
440
  dcc.seek(position.to_i)
439
441
  m.user.send "\001DCC ACCEPT #{filename} #{dcc.port} #{position}\001"
440
442
 
@@ -460,10 +462,11 @@ module Cinch
460
462
  # @return [void]
461
463
  # @api private
462
464
  def online=(bool)
463
- notify = self.__send__("online?_unsynced") != bool && @monitored
465
+ notify = __send__("online?_unsynced") != bool && @monitored
464
466
  sync(:online?, bool, true)
465
467
 
466
468
  return unless notify
469
+
467
470
  if bool
468
471
  @bot.handlers.dispatch(:online, nil, self)
469
472
  else
@@ -477,7 +480,8 @@ module Cinch
477
480
  # @api private
478
481
  # @return [void]
479
482
  def update_nick(new_nick)
480
- @last_nick, @name = @name, new_nick
483
+ @last_nick = @name
484
+ @name = new_nick
481
485
  # Unsync authname because some networks tie authentication to
482
486
  # the nick, so the user might not be authenticated anymore after
483
487
  # changing their nick
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/cached_list"
2
4
 
3
5
  module Cinch
@@ -22,7 +24,8 @@ module Cinch
22
24
  # @return [User]
23
25
  # @see Bot#User
24
26
  def find_ensured(*args)
25
- user, host = nil, nil
27
+ user = nil
28
+ host = nil
26
29
  case args.size
27
30
  when 1
28
31
  nick = args.first
@@ -35,15 +38,11 @@ module Cinch
35
38
  raise ArgumentError
36
39
  end
37
40
 
38
- if nick == @bot.nick
39
- user_obj = @bot
40
- end
41
+ user_obj = @bot if nick == @bot.nick
41
42
 
42
43
  downcased_nick = nick.irc_downcase(@bot.irc.isupport["CASEMAPPING"])
43
44
  @mutex.synchronize do
44
- if user_obj.nil?
45
- user_obj = @cache[downcased_nick] ||= User.new(*bargs, @bot)
46
- end
45
+ user_obj = @cache[downcased_nick] ||= User.new(*bargs, @bot) if user_obj.nil?
47
46
  if user && host
48
47
  # Explicitly set user and host whenever we request a User
49
48
  # object to update them on e.g. JOIN.
@@ -59,9 +58,7 @@ module Cinch
59
58
  # @param [String] nick nick of a user
60
59
  # @return [User, nil]
61
60
  def find(nick)
62
- if nick == @bot.nick
63
- return @bot
64
- end
61
+ return @bot if nick == @bot.nick
65
62
 
66
63
  downcased_nick = nick.irc_downcase(@bot.irc.isupport["CASEMAPPING"])
67
64
  @mutex.synchronize do
@@ -81,7 +78,7 @@ module Cinch
81
78
  # @api private
82
79
  # @return [void]
83
80
  def delete(user)
84
- @cache.delete_if {|n, u| u == user }
81
+ @cache.delete_if { |_n, u| u == user }
85
82
  end
86
83
  end
87
84
  end