grinch 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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