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,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # This class exposes parsed ISUPPORT information of the IRC network.
3
5
  class ISupport < Hash
4
6
  @@mappings = {
5
- %w[PREFIX] => lambda {|v|
7
+ %w[PREFIX] => lambda { |v|
6
8
  modes, prefixes = v.match(/^\((.+)\)(.+)$/)[1..2]
7
9
  h = {}
8
10
  modes.split("").each_with_index do |c, i|
@@ -11,18 +13,18 @@ module Cinch
11
13
  h
12
14
  },
13
15
 
14
- %w[CHANTYPES] => lambda {|v| v.split("")},
15
- %w[CHANMODES] => lambda {|v|
16
+ %w[CHANTYPES] => ->(v) { v.split("") },
17
+ %w[CHANMODES] => lambda { |v|
16
18
  h = {}
17
- h["A"], h["B"], h["C"], h["D"] = v.split(",").map {|l| l.split("")}
19
+ h["A"], h["B"], h["C"], h["D"] = v.split(",").map { |l| l.split("") }
18
20
  h
19
21
  },
20
22
 
21
23
  %w[MODES MAXCHANNELS NICKLEN MAXBANS TOPICLEN
22
- KICKLEN CHANNELLEN CHIDLEN SILENCE AWAYLEN
23
- MAXTARGETS WATCH MONITOR] => lambda {|v| v.to_i},
24
+ KICKLEN CHANNELLEN CHIDLEN SILENCE AWAYLEN
25
+ MAXTARGETS WATCH MONITOR] => ->(v) { v.to_i },
24
26
 
25
- %w[CHANLIMIT MAXLIST IDCHAN] => lambda {|v|
27
+ %w[CHANLIMIT MAXLIST IDCHAN] => lambda { |v|
26
28
  h = {}
27
29
  v.split(",").each do |pair|
28
30
  args, num = pair.split(":")
@@ -33,7 +35,7 @@ module Cinch
33
35
  h
34
36
  },
35
37
 
36
- %w[TARGMAX] => lambda {|v|
38
+ %w[TARGMAX] => lambda { |v|
37
39
  h = {}
38
40
  v.split(",").each do |pair|
39
41
  name, value = pair.split(":")
@@ -42,11 +44,11 @@ module Cinch
42
44
  h
43
45
  },
44
46
 
45
- %w[NETWORK] => lambda {|v| v},
46
- %w[STATUSMSG] => lambda {|v| v.split("")},
47
- %w[CASEMAPPING] => lambda {|v| v.to_sym},
48
- %w[ELIST] => lambda {|v| v.split("")},
49
- # TODO STD
47
+ %w[NETWORK] => ->(v) { v },
48
+ %w[STATUSMSG] => ->(v) { v.split("") },
49
+ %w[CASEMAPPING] => ->(v) { v.to_sym },
50
+ %w[ELIST] => ->(v) { v.split("") },
51
+ # TODO: STD
50
52
  }
51
53
 
52
54
  def initialize(*args)
@@ -56,13 +58,13 @@ module Cinch
56
58
  # allowing the use of strictness=:strict for servers that don't
57
59
  # support ISUPPORT (hopefully none, anyway)
58
60
 
59
- self["PREFIX"] = {"o" => "@", "v" => "+"}
61
+ self["PREFIX"] = { "o" => "@", "v" => "+" }
60
62
  self["CHANTYPES"] = ["#"]
61
63
  self["CHANMODES"] = {
62
- "A" => ["b"],
63
- "B" => ["k"],
64
- "C" => ["l"],
65
- "D" => %w[i m n p s t r]
64
+ "A" => ["b"],
65
+ "B" => ["k"],
66
+ "C" => ["l"],
67
+ "D" => %w[i m n p s t r],
66
68
  }
67
69
  self["MODES"] = 1
68
70
  self["NICKLEN"] = Float::INFINITY
@@ -74,7 +76,7 @@ module Cinch
74
76
  self["AWAYLEN"] = Float::INFINITY
75
77
  self["MAXTARGETS"] = 1
76
78
  self["MAXCHANNELS"] = Float::INFINITY # deprecated
77
- self["CHANLIMIT"] = {"#" => Float::INFINITY}
79
+ self["CHANLIMIT"] = { "#" => Float::INFINITY }
78
80
  self["STATUSMSG"] = []
79
81
  self["CASEMAPPING"] = :rfc1459
80
82
  self["ELIST"] = []
@@ -87,7 +89,7 @@ module Cinch
87
89
  options.each do |option|
88
90
  name, value = option.split("=")
89
91
  if value
90
- proc = @@mappings.find {|key, _| key.include?(name)}
92
+ proc = @@mappings.find { |key, _| key.include?(name) }
91
93
  self[name] = (proc && proc[1].call(value)) || value
92
94
  else
93
95
  self[name] = true
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # LogFilter describes an interface for filtering log messages before
3
5
  # they're printed.
@@ -15,7 +17,6 @@ module Cinch
15
17
  # :error, :fatal] event The kind of message
16
18
  # @return [String, nil] The modified message, as it should be
17
19
  # logged, or nil if the message shouldn't be logged at all
18
- def filter(message, event)
19
- end
20
+ def filter(message, event); end
20
21
  end
21
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # This is the base logger class from which all loggers have to
3
5
  # inherit.
@@ -5,7 +7,7 @@ module Cinch
5
7
  # @version 2.0.0
6
8
  class Logger
7
9
  # @private
8
- LevelOrder = [:debug, :log, :info, :warn, :error, :fatal]
10
+ LevelOrder = %i[debug log info warn error fatal].freeze
9
11
 
10
12
  # @return [Array<:debug, :log, :info, :warn, :error, :fatal>]
11
13
  # The minimum level of events to log
@@ -109,13 +111,15 @@ module Cinch
109
111
  # @version 2.0.0
110
112
  def log(messages, event = :debug, level = event)
111
113
  return unless will_log?(level)
114
+
112
115
  @mutex.synchronize do
113
116
  Array(messages).each do |message|
114
117
  message = format_general(message)
115
118
  message = format_message(message, event)
116
119
 
117
120
  next if message.nil?
118
- @output.puts message.encode("locale", {:invalid => :replace, :undef => :replace})
121
+
122
+ @output.puts message.encode("locale", invalid: :replace, undef: :replace)
119
123
  end
120
124
  end
121
125
  end
@@ -129,6 +133,7 @@ module Cinch
129
133
  end
130
134
 
131
135
  private
136
+
132
137
  def format_message(message, level)
133
138
  __send__ "format_#{level}", message
134
139
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/logger"
2
4
 
3
5
  module Cinch
@@ -6,24 +8,25 @@ module Cinch
6
8
  class FormattedLogger < Logger
7
9
  # @private
8
10
  Colors = {
9
- :reset => "\e[0m",
10
- :bold => "\e[1m",
11
- :red => "\e[31m",
12
- :green => "\e[32m",
13
- :yellow => "\e[33m",
14
- :blue => "\e[34m",
15
- :black => "\e[30m",
16
- :bg_white => "\e[47m",
17
- }
11
+ reset: "\e[0m",
12
+ bold: "\e[1m",
13
+ red: "\e[31m",
14
+ green: "\e[32m",
15
+ yellow: "\e[33m",
16
+ blue: "\e[34m",
17
+ black: "\e[30m",
18
+ bg_white: "\e[47m",
19
+ }.freeze
18
20
 
19
21
  # (see Logger#exception)
20
22
  def exception(e)
21
23
  lines = ["#{e.backtrace.first}: #{e.message} (#{e.class})"]
22
- lines.concat e.backtrace[1..-1].map {|s| "\t" + s}
24
+ lines.concat e.backtrace[1..-1].map { |s| "\t" + s }
23
25
  log(lines, :exception, :error)
24
26
  end
25
27
 
26
28
  private
29
+
27
30
  def timestamp
28
31
  Time.now.strftime("[%Y/%m/%d %H:%M:%S.%L]")
29
32
  end
@@ -34,6 +37,7 @@ module Cinch
34
37
  # @return [String] colorized string
35
38
  def colorize(text, *codes)
36
39
  return text unless @output.tty?
40
+
37
41
  codes = Colors.values_at(*codes).join
38
42
  text = text.gsub(/#{Regexp.escape(Colors[:reset])}/, Colors[:reset] + codes)
39
43
  codes + text + Colors[:reset]
@@ -71,9 +75,9 @@ module Cinch
71
75
  end
72
76
 
73
77
  "%s %s %s %s" % [timestamp,
74
- prefix,
75
- pre_parts.join(" "),
76
- msg ? colorize(":#{msg}", :yellow) : ""]
78
+ prefix,
79
+ pre_parts.join(" "),
80
+ msg ? colorize(":#{msg}", :yellow) : ""]
77
81
  end
78
82
 
79
83
  def format_outgoing(message)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/logger"
2
4
  module Cinch
3
5
  class Logger
@@ -10,10 +12,12 @@ module Cinch
10
12
  # (see Logger#log)
11
13
  def log(messages, event, level = event)
12
14
  return if event != :incoming
15
+
13
16
  super
14
17
  end
15
18
 
16
19
  private
20
+
17
21
  def format_incoming(message)
18
22
  Time.now.strftime("%m/%d/%Y %H:%M:%S ") + message
19
23
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # This class allows Cinch to use multiple loggers at once. A common
3
5
  # use-case would be to log formatted messages to STDERR and a
@@ -22,62 +24,61 @@ module Cinch
22
24
 
23
25
  # (see Logger#level=)
24
26
  def level=(level)
25
- each {|l| l.level = level}
27
+ each { |l| l.level = level }
26
28
  end
27
29
 
28
30
  # (see Logger#log)
29
31
  def log(messages, event = :debug, level = event)
30
- messages = Array(messages).map {|m| filter(m, event)}.compact
31
- each {|l| l.log(messages, event, level)}
32
+ messages = Array(messages).map { |m| filter(m, event) }.compact
33
+ each { |l| l.log(messages, event, level) }
32
34
  end
33
35
 
34
36
  # (see Logger#debug)
35
37
  def debug(message)
36
- (m = filter(message, :debug)) && each {|l| l.debug(m)}
38
+ (m = filter(message, :debug)) && each { |l| l.debug(m) }
37
39
  end
38
40
 
39
41
  # (see Logger#error)
40
42
  def error(message)
41
- (m = filter(message, :error)) && each {|l| l.error(m)}
43
+ (m = filter(message, :error)) && each { |l| l.error(m) }
42
44
  end
43
45
 
44
46
  # (see Logger#error)
45
47
  def fatal(message)
46
- (m = filter(message, :fatal)) && each {|l| l.fatal(m)}
48
+ (m = filter(message, :fatal)) && each { |l| l.fatal(m) }
47
49
  end
48
50
 
49
51
  # (see Logger#info)
50
52
  def info(message)
51
- (m = filter(message, :info)) && each {|l| l.info(m)}
53
+ (m = filter(message, :info)) && each { |l| l.info(m) }
52
54
  end
53
55
 
54
56
  # (see Logger#warn)
55
57
  def warn(message)
56
- (m = filter(message, :warn)) && each {|l| l.warn(m)}
58
+ (m = filter(message, :warn)) && each { |l| l.warn(m) }
57
59
  end
58
60
 
59
61
  # (see Logger#incoming)
60
62
  def incoming(message)
61
- (m = filter(message, :incoming)) && each {|l| l.incoming(m)}
63
+ (m = filter(message, :incoming)) && each { |l| l.incoming(m) }
62
64
  end
63
65
 
64
66
  # (see Logger#outgoing)
65
67
  def outgoing(message)
66
- (m = filter(message, :outgoing)) && each {|l| l.outgoing(m)}
68
+ (m = filter(message, :outgoing)) && each { |l| l.outgoing(m) }
67
69
  end
68
70
 
69
71
  # (see Logger#exception)
70
72
  def exception(e)
71
- each {|l| l.exception(e)}
73
+ each { |l| l.exception(e) }
72
74
  end
73
75
 
74
76
  private
77
+
75
78
  def filter(m, ev)
76
79
  @filters.each do |f|
77
80
  m = f.filter(m, ev)
78
- if m.nil?
79
- break
80
- end
81
+ break if m.nil?
81
82
  end
82
83
  m
83
84
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # This class represents masks, which are primarily used for bans.
3
5
  class Mask
@@ -39,11 +41,11 @@ module Cinch
39
41
  # @return [Boolean]
40
42
  # @version 1.1.2
41
43
  def match(target)
42
- return self.class.from(target).mask =~ @regexp
44
+ self.class.from(target).mask =~ @regexp
43
45
 
44
- # TODO support CIDR (freenode)
46
+ # TODO: support CIDR (freenode)
45
47
  end
46
- alias_method :=~, :match
48
+ alias =~ match
47
49
 
48
50
  # @return [String]
49
51
  def to_s
@@ -57,13 +59,13 @@ module Cinch
57
59
  def self.from(target)
58
60
  return target if target.is_a?(self)
59
61
 
60
- if target.respond_to?(:mask)
61
- mask = target.mask
62
- else
63
- mask = Mask.new(target.to_s)
64
- end
62
+ mask = if target.respond_to?(:mask)
63
+ target.mask
64
+ else
65
+ Mask.new(target.to_s)
66
+ end
65
67
 
66
- return mask
68
+ mask
67
69
  end
68
70
  end
69
71
  end
@@ -108,11 +108,11 @@ module Cinch
108
108
  @params = parse_params(raw_params)
109
109
  @tags = parse_tags(tags)
110
110
 
111
- @user = parse_user
111
+ @user = parse_user
112
112
  @channel, @statusmsg_mode = parse_channel
113
- @target = @channel || @user
114
- @server = parse_server
115
- @error = parse_error
113
+ @target = @channel || @user
114
+ @server = parse_server
115
+ @error = parse_error
116
116
  @message = parse_message
117
117
 
118
118
  @ctcp_message = parse_ctcp_message
@@ -333,9 +333,9 @@ module Cinch
333
333
  statusmsg = @bot.irc.isupport["STATUSMSG"]
334
334
  if statusmsg.include?(s[0]) && chantypes.include?(s[1])
335
335
  status = @bot.irc.isupport["PREFIX"].invert[s[0]]
336
- return s[1..-1], status
336
+ [s[1..-1], status]
337
337
  elsif chantypes.include?(s[0])
338
- return s, nil
338
+ [s, nil]
339
339
  end
340
340
  end
341
341
 
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  require "cinch/open_ended_queue"
3
4
 
4
5
  module Cinch
@@ -11,7 +12,7 @@ module Cinch
11
12
  @socket = socket
12
13
  @bot = bot
13
14
 
14
- @queues = {:generic => OpenEndedQueue.new}
15
+ @queues = { generic: OpenEndedQueue.new }
15
16
  @queues_to_process = Queue.new
16
17
  @queued_queues = Set.new
17
18
 
@@ -61,6 +62,7 @@ module Cinch
61
62
  end
62
63
 
63
64
  private
65
+
64
66
  def wait
65
67
  if @log.size > 1
66
68
  mps = @bot.config.messages_per_second || @bot.irc.network.default_messages_per_second
@@ -74,7 +76,7 @@ module Cinch
74
76
  if effective_size <= 0
75
77
  @log.clear
76
78
  elsif effective_size >= max_queue_size
77
- sleep 1.0/mps
79
+ sleep 1.0 / mps
78
80
  end
79
81
  end
80
82
  end
@@ -102,6 +104,5 @@ module Cinch
102
104
  @bot.loggers.error "Could not send message (connectivity problems): #{message}"
103
105
  end
104
106
  end
105
-
106
107
  end # class MessageQueue
107
108
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/exceptions"
2
4
 
3
5
  module Cinch
@@ -16,7 +18,7 @@ module Cinch
16
18
  # A mapping describing which modes require parameters
17
19
  # @return [(Array<(Symbol<:add, :remove>, String<char>, String<param>), foo)]
18
20
  def self.parse_modes(modes, params, param_modes = {})
19
- if modes.size == 0
21
+ if modes.empty?
20
22
  return nil, ErrEmptyString
21
23
  # raise Exceptions::InvalidModeString, 'Empty mode string'
22
24
  end
@@ -47,8 +49,8 @@ module Cinch
47
49
  count = 0
48
50
  else
49
51
  param = nil
50
- if param_modes.has_key?(direction) && param_modes[direction].include?(ch)
51
- if params.size > 0
52
+ if param_modes.key?(direction) && param_modes[direction].include?(ch)
53
+ if !params.empty?
52
54
  param = params.shift
53
55
  else
54
56
  return changes, NotEnoughParametersError.new(ch)
@@ -60,7 +62,7 @@ module Cinch
60
62
  end
61
63
  end
62
64
 
63
- if params.size > 0
65
+ unless params.empty?
64
66
  return changes, TooManyParametersError.new(modes, params)
65
67
  # raise Exceptions::InvalidModeString, 'Too many parameters: %s %s' % [modes, params]
66
68
  end
@@ -70,7 +72,7 @@ module Cinch
70
72
  # raise Exceptions::InvalidModeString, 'Empty mode sequence: %s' % modes
71
73
  end
72
74
 
73
- return changes, nil
75
+ [changes, nil]
74
76
  end
75
77
  end
76
78
  end