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
  require "cinch/cached_list"
2
4
 
3
5
  module Cinch
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # @since 2.0.0
3
5
  class Configuration < OpenStruct
4
- KnownOptions = []
6
+ KnownOptions = [].freeze
5
7
 
6
8
  # Generate a default configuration.
7
9
  #
@@ -21,14 +23,16 @@ module Cinch
21
23
  end
22
24
 
23
25
  def [](key)
24
- # FIXME also adjust method_missing
26
+ # FIXME: also adjust method_missing
25
27
  raise ArgumentError, "Unknown option #{key}" unless self.class::KnownOptions.include?(key)
28
+
26
29
  @table[key]
27
30
  end
28
31
 
29
32
  def []=(key, value)
30
- # FIXME also adjust method_missing
33
+ # FIXME: also adjust method_missing
31
34
  raise ArgumentError, "Unknown option #{key}" unless self.class::KnownOptions.include?(key)
35
+
32
36
  modifiable[new_ostruct_member(key)] = value
33
37
  end
34
38
 
@@ -42,9 +46,7 @@ module Cinch
42
46
  # configuration.
43
47
  # @return [void]
44
48
  def load(new_config, from_default = false)
45
- if from_default
46
- @table = self.class.default_config
47
- end
49
+ @table = self.class.default_config if from_default
48
50
 
49
51
  new_config.each do |option, value|
50
52
  if value.is_a?(Hash)
@@ -1,46 +1,48 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/configuration"
2
4
 
3
5
  module Cinch
4
6
  class Configuration
5
7
  # @since 2.0.0
6
8
  class Bot < Configuration
7
- KnownOptions = [:server, :port, :ssl, :password, :nick, :nicks,
8
- :realname, :user, :messages_per_second, :server_queue_size,
9
- :strictness, :message_split_start, :message_split_end,
10
- :max_messages, :plugins, :channels, :encoding, :reconnect, :max_reconnect_delay,
11
- :local_host, :timeouts, :ping_interval, :delay_joins, :dcc, :shared, :sasl, :default_logger_level]
9
+ KnownOptions = %i[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].freeze
12
14
 
13
15
  # (see Configuration.default_config)
14
16
  def self.default_config
15
17
  {
16
- :server => "localhost",
17
- :port => 6667,
18
- :ssl => Configuration::SSL.new,
19
- :password => nil,
20
- :nick => "cinch",
21
- :nicks => nil,
22
- :realname => "cinch",
23
- :user => "cinch",
24
- :modes => [],
25
- :messages_per_second => nil,
26
- :server_queue_size => nil,
27
- :strictness => :forgiving,
28
- :message_split_start => '... ',
29
- :message_split_end => ' ...',
30
- :max_messages => nil,
31
- :plugins => Configuration::Plugins.new,
32
- :channels => [],
33
- :encoding => :irc,
34
- :reconnect => true,
35
- :max_reconnect_delay => 300,
36
- :local_host => nil,
37
- :timeouts => Configuration::Timeouts.new,
38
- :ping_interval => 120,
39
- :delay_joins => 0,
40
- :dcc => Configuration::DCC.new,
41
- :sasl => Configuration::SASL.new,
42
- :shared => {},
43
- :default_logger_level => :debug
18
+ server: "localhost",
19
+ port: 6667,
20
+ ssl: Configuration::SSL.new,
21
+ password: nil,
22
+ nick: "cinch",
23
+ nicks: nil,
24
+ realname: "cinch",
25
+ user: "cinch",
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,
44
46
  }
45
47
  end
46
48
  end
@@ -1,14 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/configuration"
2
4
 
3
5
  module Cinch
4
6
  class Configuration
5
7
  # @since 2.0.0
6
8
  class DCC < Configuration
7
- KnownOptions = [:own_ip]
9
+ KnownOptions = [:own_ip].freeze
8
10
 
9
11
  def self.default_config
10
12
  {
11
- :own_ip => nil,
13
+ own_ip: nil,
12
14
  }
13
15
  end
14
16
  end
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/configuration"
2
4
 
3
5
  module Cinch
4
6
  class Configuration
5
7
  # @since 2.0.0
6
8
  class Plugins < Configuration
7
- KnownOptions = [:plugins, :prefix, :suffix, :options]
9
+ KnownOptions = %i[plugins prefix suffix options].freeze
8
10
 
9
11
  def self.default_config
10
12
  {
11
- :plugins => [],
12
- :prefix => /^!/,
13
- :suffix => nil,
14
- :options => Hash.new {|h,k| h[k] = {}},
13
+ plugins: [],
14
+ prefix: /^!/,
15
+ suffix: nil,
16
+ options: Hash.new { |h, k| h[k] = {} },
15
17
  }
16
18
  end
17
19
 
@@ -20,7 +22,7 @@ module Cinch
20
22
  new_config.each do |option, value|
21
23
  case option
22
24
  when :plugins
23
- _new_config[option] = value.map{|v| Cinch::Utilities::Kernel.string_to_const(v)}
25
+ _new_config[option] = value.map { |v| Cinch::Utilities::Kernel.string_to_const(v) }
24
26
  when :options
25
27
  _value = self[:options]
26
28
  value.each do |k, v|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/configuration"
2
4
  require "cinch/sasl"
3
5
 
@@ -5,13 +7,13 @@ module Cinch
5
7
  class Configuration
6
8
  # @since 2.0.0
7
9
  class SASL < Configuration
8
- KnownOptions = [:username, :password, :mechanisms]
10
+ KnownOptions = %i[username password mechanisms].freeze
9
11
 
10
12
  def self.default_config
11
13
  {
12
- :username => nil,
13
- :password => nil,
14
- :mechanisms => [Cinch::SASL::DH_Blowfish, Cinch::SASL::Plain]
14
+ username: nil,
15
+ password: nil,
16
+ mechanisms: [Cinch::SASL::DH_Blowfish, Cinch::SASL::Plain],
15
17
  }
16
18
  end
17
19
  end
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/configuration"
2
4
 
3
5
  module Cinch
4
6
  class Configuration
5
7
  # @since 2.0.0
6
8
  class SSL < Configuration
7
- KnownOptions = [:use, :verify, :client_cert, :ca_path]
9
+ KnownOptions = %i[use verify client_cert ca_path].freeze
8
10
 
9
11
  def self.default_config
10
12
  {
11
- :use => false,
12
- :verify => false,
13
- :client_cert => nil,
14
- :ca_path => "/etc/ssl/certs",
13
+ use: false,
14
+ verify: false,
15
+ client_cert: nil,
16
+ ca_path: "/etc/ssl/certs",
15
17
  }
16
18
  end
17
19
  end
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/configuration"
2
4
 
3
5
  module Cinch
4
6
  class Configuration
5
7
  # @since 2.0.0
6
8
  class Timeouts < Configuration
7
- KnownOptions = [:read, :connect]
9
+ KnownOptions = %i[read connect].freeze
8
10
 
9
11
  def self.default_config
10
- {:read => 240, :connect => 10,}
12
+ { read: 240, connect: 10 }
11
13
  end
12
14
  end
13
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # All standard and some non-standard numeric replies used by the IRC
3
5
  # protocol.
@@ -274,7 +276,7 @@ module Cinch
274
276
  # revisions) and the &lt;debuglevel&gt; is used to indicate if the
275
277
  # server is running in "debug mode".
276
278
  #
277
- #The "comments" field may contain any comments about the version or
279
+ # The "comments" field may contain any comments about the version or
278
280
  # further version details.
279
281
  RPL_VERSION = 351
280
282
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/dcc/outgoing"
2
4
  require "cinch/dcc/incoming"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  module DCC
3
5
  # This module describes the required interface for objects that should
@@ -12,26 +14,22 @@ module Cinch
12
14
  # @param [Integer] number Read `number` bytes at most
13
15
  # @return [String] The read data
14
16
  # @return [nil] If no more data can be read
15
- def read(number)
16
- end
17
+ def read(number); end
17
18
 
18
19
  # Seek to a specific position.
19
20
  #
20
21
  # @param [Integer] position The position in bytes to seek to
21
22
  # @return [void]
22
- def seek(position)
23
- end
23
+ def seek(position); end
24
24
 
25
25
  # @return [String] A string representing the object's path or name.
26
26
  #
27
27
  # @note This is only required if calling {User#dcc_send} with only
28
28
  # one argument
29
- def path
30
- end
29
+ def path; end
31
30
 
32
31
  # @return [Integer] The total size of the data, in bytes.
33
- def size
34
- end
32
+ def size; end
35
33
  end
36
34
  end
37
35
  end
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/dcc/incoming/send"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "socket"
2
4
  require "ipaddr"
3
5
 
@@ -50,11 +52,11 @@ module Cinch
50
52
  PRIVATE_NETS = [IPAddr.new("fc00::/7"),
51
53
  IPAddr.new("10.0.0.0/8"),
52
54
  IPAddr.new("172.16.0.0/12"),
53
- IPAddr.new("192.168.0.0/16")]
55
+ IPAddr.new("192.168.0.0/16")].freeze
54
56
 
55
57
  # @private
56
58
  LOCAL_NETS = [IPAddr.new("127.0.0.0/8"),
57
- IPAddr.new("::1/128")]
59
+ IPAddr.new("::1/128")].freeze
58
60
 
59
61
  # @return [User]
60
62
  attr_reader :user
@@ -123,23 +125,23 @@ module Cinch
123
125
  end
124
126
 
125
127
  socket.close
126
- return true
128
+ true
127
129
  rescue EOFError
128
- return false
130
+ false
129
131
  end
130
132
 
131
133
  # @return [Boolean] True if the DCC originates from a private ip
132
134
  # @see #from_localhost?
133
135
  def from_private_ip?
134
- ip = IPAddr.new(@ip)
135
- PRIVATE_NETS.any? {|n| n.include?(ip)}
136
+ ip = IPAddr.new(@ip)
137
+ PRIVATE_NETS.any? { |n| n.include?(ip) }
136
138
  end
137
139
 
138
140
  # @return [Boolean] True if the DCC originates from localhost
139
141
  # @see #from_private_ip?
140
142
  def from_localhost?
141
- ip = IPAddr.new(@ip)
142
- LOCAL_NETS.any? {|n| n.include?(ip)}
143
+ ip = IPAddr.new(@ip)
144
+ LOCAL_NETS.any? { |n| n.include?(ip) }
143
145
  end
144
146
  end
145
147
  end
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cinch/dcc/outgoing/send"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "socket"
2
4
  require "ipaddr"
3
5
  require "timeout"
@@ -73,16 +75,14 @@ module Cinch
73
75
  # @return [void]
74
76
  # @note This method blocks.
75
77
  def listen
76
- begin
77
- fd = nil
78
- Timeout.timeout(30) do
79
- fd, _ = @socket.accept
80
- end
81
- send_data(fd)
82
- fd.close
83
- ensure
84
- @socket.close
78
+ fd = nil
79
+ Timeout.timeout(30) do
80
+ fd, _ = @socket.accept
85
81
  end
82
+ send_data(fd)
83
+ fd.close
84
+ ensure
85
+ @socket.close
86
86
  end
87
87
 
88
88
  # Seek to `pos` in the data.
@@ -100,16 +100,15 @@ module Cinch
100
100
  end
101
101
 
102
102
  private
103
+
103
104
  def send_data(fd)
104
105
  @io.advise(:sequential)
105
106
 
106
107
  while chunk = @io.read(8096)
107
- while true
108
+ loop do
108
109
  rs, ws = IO.select([fd], [fd])
109
- if !rs.empty?
110
- rs.first.recv(8096)
111
- end
112
- if !ws.empty?
110
+ rs.first.recv(8096) unless rs.empty?
111
+ unless ws.empty?
113
112
  ws.first.write(chunk)
114
113
  break
115
114
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # A collection of exceptions.
3
5
  module Exceptions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Cinch
2
4
  # This module can be used for adding and removing colors and
3
5
  # formatting to/from messages.
@@ -41,34 +43,34 @@ module Cinch
41
43
  module Formatting
42
44
  # @private
43
45
  Colors = {
44
- :white => "00",
45
- :black => "01",
46
- :blue => "02",
47
- :green => "03",
48
- :red => "04",
49
- :brown => "05",
50
- :purple => "06",
51
- :orange => "07",
52
- :yellow => "08",
53
- :lime => "09",
54
- :teal => "10",
55
- :aqua => "11",
56
- :royal => "12",
57
- :pink => "13",
58
- :grey => "14",
59
- :silver => "15",
60
- }
46
+ white: "00",
47
+ black: "01",
48
+ blue: "02",
49
+ green: "03",
50
+ red: "04",
51
+ brown: "05",
52
+ purple: "06",
53
+ orange: "07",
54
+ yellow: "08",
55
+ lime: "09",
56
+ teal: "10",
57
+ aqua: "11",
58
+ royal: "12",
59
+ pink: "13",
60
+ grey: "14",
61
+ silver: "15",
62
+ }.freeze
61
63
 
62
64
  # @private
63
65
  Attributes = {
64
- :bold => 2.chr,
65
- :underlined => 31.chr,
66
- :underline => 31.chr,
67
- :reversed => 22.chr,
68
- :reverse => 22.chr,
69
- :italic => 29.chr,
70
- :reset => 15.chr,
71
- }
66
+ bold: 2.chr,
67
+ underlined: 31.chr,
68
+ underline: 31.chr,
69
+ reversed: 22.chr,
70
+ reverse: 22.chr,
71
+ italic: 29.chr,
72
+ reset: 15.chr,
73
+ }.freeze
72
74
 
73
75
  # @param [Array<Symbol>] settings The colors and attributes to apply.
74
76
  # When supplying two colors, the first will be used for the
@@ -82,10 +84,10 @@ module Cinch
82
84
  # @example Nested formatting, combining text styles and colors
83
85
  # reply = Format(:underline, "Hello %s! Is your favourite color %s?" % [Format(:bold, "stranger"), Format(:red, "red")])
84
86
  def self.format(*settings, string)
85
- string = string.dup
87
+ string = string.dup
86
88
 
87
- attributes = settings.select {|k| Attributes.has_key?(k)}.map {|k| Attributes[k]}
88
- colors = settings.select {|k| Colors.has_key?(k)}.map {|k| Colors[k]}
89
+ attributes = settings.select { |k| Attributes.key?(k) }.map { |k| Attributes[k] }
90
+ colors = settings.select { |k| Colors.key?(k) }.map { |k| Colors[k] }
89
91
  if colors.size > 2
90
92
  raise ArgumentError, "At most two colors (foreground and background) might be specified"
91
93
  end
@@ -108,7 +110,7 @@ module Cinch
108
110
  # Replace the reset code of nested strings to continue the
109
111
  # formattings of the outer string.
110
112
  string.gsub!(/#{Attributes[:reset]}/, Attributes[:reset] + prepend)
111
- return prepend + string + append
113
+ prepend + string + append
112
114
  end
113
115
 
114
116
  # Deletes all mIRC formatting codes from the string. This strips
@@ -119,7 +121,7 @@ module Cinch
119
121
  # @return [String] The filtered string
120
122
  # @since 2.2.0
121
123
  def self.unformat(string)
122
- string.gsub(/[\x02\x0f\x16\x1d\x1f\x12]|\x03(\d{1,2}(,\d{1,2})?)?/, '')
124
+ string.gsub(/[\x02\x0f\x16\x1d\x1f\x12]|\x03(\d{1,2}(,\d{1,2})?)?/, "")
123
125
  end
124
126
  end
125
127
  end