cinch 2.2.5 → 2.2.6

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b1e40f6cd0cfe7e806d4b87bfd591c5320c5a2fc
4
+ data.tar.gz: d7a173c15ed16769d1703ba3dd7b9d1f7c810cba
5
+ SHA512:
6
+ metadata.gz: f687dc8eeffdbb9c455017e679ec0528b09c95aea5e921207f5ccb132d61bfb3ae2d3417db6cdb0500199671d5f5344194d1d021ff8933914254acc78f419b82
7
+ data.tar.gz: 96e85381ff58dc28d4aa457c4985924e1b32fcc708823330e6eb87c71ef7da4c62f36edd4a3c958a640d63135c64c65bccf9a66c39e8c7ecf0270beae52646f4
data/lib/cinch/irc.rb CHANGED
@@ -311,6 +311,11 @@ module Cinch
311
311
  new_network = :jtv
312
312
  new_ircd = :jtv
313
313
  end
314
+ when "004"
315
+ if msg.params == %w{irc.tinyspeck.com IRC-SLACK gateway}
316
+ new_network = :slack
317
+ new_ircd = :slack
318
+ end
314
319
  when "005"
315
320
  case @isupport["NETWORK"]
316
321
  when "NGameTV"
@@ -350,7 +355,7 @@ module Cinch
350
355
  msg.channel.bans_unsynced << ban
351
356
  events << [:ban, ban]
352
357
  else
353
- msg.channel.bans_unsynced.delete_if {|b| b.mask == ban.mask}.first
358
+ msg.channel.bans_unsynced.delete_if {|b| b.mask == ban.mask}
354
359
  events << [:unban, ban]
355
360
  end
356
361
  end
@@ -441,64 +446,83 @@ module Cinch
441
446
  # @version 1.1.0
442
447
  def on_mode(msg, events)
443
448
  if msg.channel?
444
- add_and_remove = @bot.irc.isupport["CHANMODES"]["A"] + @bot.irc.isupport["CHANMODES"]["B"] + @bot.irc.isupport["PREFIX"].keys
445
-
446
- param_modes = {
447
- :add => @bot.irc.isupport["CHANMODES"]["C"] + add_and_remove,
448
- :remove => add_and_remove
449
- }
450
-
451
- modes = ModeParser.parse_modes(msg.params[1], msg.params[2..-1], param_modes)
452
- modes.each do |direction, mode, param|
453
- if @bot.irc.isupport["PREFIX"].keys.include?(mode)
454
- target = User(param)
455
-
456
- # (un)set a user-mode
457
- if direction == :add
458
- msg.channel.users[target] << mode unless msg.channel.users[User(param)].include?(mode)
459
- else
460
- msg.channel.users[target].delete mode
461
- end
449
+ parse_channel_modes(msg, events)
450
+ return
451
+ end
452
+ if msg.params.first == bot.nick
453
+ parse_bot_modes(msg)
454
+ end
455
+ end
462
456
 
463
- user_events = {
464
- "o" => "op",
465
- "v" => "voice",
466
- "h" => "halfop"
467
- }
468
- if user_events.has_key?(mode)
469
- event = (direction == :add ? "" : "de") + user_events[mode]
470
- events << [event.to_sym, target]
471
- end
472
- elsif @bot.irc.isupport["CHANMODES"]["A"].include?(mode)
473
- case mode
474
- when "b"
475
- process_ban_mode(msg, events, param, direction)
476
- when "q"
477
- process_owner_mode(msg, events, param, direction) if @network.owner_list_mode
478
- else
479
- raise Exceptions::UnsupportedMode, mode
480
- end
457
+ def parse_channel_modes(msg, events)
458
+ add_and_remove = @bot.irc.isupport["CHANMODES"]["A"] + @bot.irc.isupport["CHANMODES"]["B"] + @bot.irc.isupport["PREFIX"].keys
459
+
460
+ param_modes = {
461
+ :add => @bot.irc.isupport["CHANMODES"]["C"] + add_and_remove,
462
+ :remove => add_and_remove
463
+ }
464
+
465
+
466
+ modes, err = ModeParser.parse_modes(msg.params[1], msg.params[2..-1], param_modes)
467
+ if err != nil
468
+ if @network.ircd != :slack || !err.is_a?(ModeParser::TooManyParametersError)
469
+ raise Exceptions::InvalidModeString, err
470
+ end
471
+ end
472
+ modes.each do |direction, mode, param|
473
+ if @bot.irc.isupport["PREFIX"].keys.include?(mode)
474
+ target = User(param)
475
+
476
+ # (un)set a user-mode
477
+ if direction == :add
478
+ msg.channel.users[target] << mode unless msg.channel.users[target].include?(mode)
481
479
  else
482
- # channel options
483
- if direction == :add
484
- msg.channel.modes_unsynced[mode] = param.nil? ? true : param
485
- else
486
- msg.channel.modes_unsynced.delete(mode)
487
- end
480
+ msg.channel.users[target].delete mode
488
481
  end
489
- end
490
482
 
491
- events << [:mode_change, modes]
492
- elsif msg.params.first == bot.nick
493
- modes = ModeParser.parse_modes(msg.params[1], msg.params[2..-1])
494
- modes.each do |direction, mode, _|
483
+ user_events = {
484
+ "o" => "op",
485
+ "v" => "voice",
486
+ "h" => "halfop"
487
+ }
488
+ if user_events.has_key?(mode)
489
+ event = (direction == :add ? "" : "de") + user_events[mode]
490
+ events << [event.to_sym, target]
491
+ end
492
+ elsif @bot.irc.isupport["CHANMODES"]["A"].include?(mode)
493
+ case mode
494
+ when "b"
495
+ process_ban_mode(msg, events, param, direction)
496
+ when "q"
497
+ process_owner_mode(msg, events, param, direction) if @network.owner_list_mode
498
+ else
499
+ raise Exceptions::UnsupportedMode, mode
500
+ end
501
+ else
502
+ # channel options
495
503
  if direction == :add
496
- @bot.modes << mode unless @bot.modes.include?(mode)
504
+ msg.channel.modes_unsynced[mode] = param.nil? ? true : param
497
505
  else
498
- @bot.modes.delete(mode)
506
+ msg.channel.modes_unsynced.delete(mode)
499
507
  end
500
508
  end
501
509
  end
510
+
511
+ events << [:mode_change, modes]
512
+ end
513
+
514
+ def parse_bot_modes(msg)
515
+ modes, err = ModeParser.parse_modes(msg.params[1], msg.params[2..-1])
516
+ if err != nil
517
+ raise Exceptions::InvalidModeString, err
518
+ end
519
+ modes.each do |direction, mode, _|
520
+ if direction == :add
521
+ @bot.modes << mode unless @bot.modes.include?(mode)
522
+ else
523
+ @bot.modes.delete(mode)
524
+ end
525
+ end
502
526
  end
503
527
 
504
528
  def on_nick(msg, events)
@@ -556,7 +580,6 @@ module Cinch
556
580
  msg.user.online = true
557
581
  end
558
582
 
559
-
560
583
  if msg.message =~ /^\001DCC SEND (?:"([^"]+)"|(\S+)) (\S+) (\d+)(?: (\d+))?\001$/
561
584
  process_dcc_send($1 || $2, $3, $4, $5, msg, events)
562
585
  end
@@ -595,6 +618,11 @@ module Cinch
595
618
  detect_network(msg, "002")
596
619
  end
597
620
 
621
+ # @since 2.2.6
622
+ def on_004(msg, events)
623
+ detect_network(msg, "004")
624
+ end
625
+
598
626
  def on_005(msg, events)
599
627
  # ISUPPORT
600
628
  @isupport.parse(*msg.params[1..-2].map {|v| v.split(" ")}.flatten)
@@ -647,13 +675,6 @@ module Cinch
647
675
  def on_318(msg, events)
648
676
  # RPL_ENDOFWHOIS
649
677
  user = User(msg.params[1])
650
-
651
- if @whois_updates[user].nil? ||
652
- (@whois_updates[user].empty? && !user.attr(:unknown?, true, true))
653
- user.end_of_whois(nil)
654
- return
655
- end
656
-
657
678
  user.end_of_whois(@whois_updates[user])
658
679
  @whois_updates.delete user
659
680
  end
@@ -828,8 +849,7 @@ module Cinch
828
849
  def on_401(msg, events)
829
850
  # ERR_NOSUCHNICK
830
851
  if user = @bot.user_list.find(msg.params[1])
831
- user.end_of_whois(nil, true)
832
- @whois_updates.delete user
852
+ update_whois(user, {:unknown? => true})
833
853
  end
834
854
  end
835
855
 
@@ -837,7 +857,7 @@ module Cinch
837
857
  # ERR_NOSUCHSERVER
838
858
 
839
859
  if user = @bot.user_list.find(msg.params[1]) # not _ensured, we only want a user that already exists
840
- user.end_of_whois(nil, true)
860
+ user.end_of_whois({:unknown? => true})
841
861
  @whois_updates.delete user
842
862
  # TODO freenode specific, test on other IRCd
843
863
  end
@@ -4,17 +4,26 @@ module Cinch
4
4
  # @api private
5
5
  # @since 1.1.0
6
6
  module ModeParser
7
+ ErrEmptyString = "Empty mode string"
8
+ MalformedError = Struct.new(:modes)
9
+ EmptySequenceError = Struct.new(:modes)
10
+ NotEnoughParametersError = Struct.new(:op)
11
+ TooManyParametersError = Struct.new(:modes, :params)
12
+
7
13
  # @param [String] modes The mode string as sent by the server
8
14
  # @param [Array<String>] params Parameters belonging to the modes
9
15
  # @param [Hash{:add, :remove => Array<String>}] param_modes
10
16
  # A mapping describing which modes require parameters
17
+ # @return [(Array<(Symbol<:add, :remove>, String<char>, String<param>), foo)]
11
18
  def self.parse_modes(modes, params, param_modes = {})
12
19
  if modes.size == 0
13
- raise Exceptions::InvalidModeString, 'Empty mode string'
20
+ return nil, ErrEmptyString
21
+ # raise Exceptions::InvalidModeString, 'Empty mode string'
14
22
  end
15
23
 
16
24
  if modes[0] !~ /[+-]/
17
- raise Exceptions::InvalidModeString, "Malformed modes string: %s" % modes
25
+ return nil, MalformedError.new(modes)
26
+ # raise Exceptions::InvalidModeString, "Malformed modes string: %s" % modes
18
27
  end
19
28
 
20
29
  changes = []
@@ -25,7 +34,8 @@ module Cinch
25
34
  modes.each_char do |ch|
26
35
  if ch =~ /[+-]/
27
36
  if count == 0
28
- raise Exceptions::InvalidModeString, 'Empty mode sequence: %s' % modes
37
+ return changes, EmptySequenceError.new(modes)
38
+ # raise Exceptions::InvalidModeString, 'Empty mode sequence: %s' % modes
29
39
  end
30
40
 
31
41
  direction = case ch
@@ -41,7 +51,8 @@ module Cinch
41
51
  if params.size > 0
42
52
  param = params.shift
43
53
  else
44
- raise Exceptions::InvalidModeString, 'Not enough parameters: %s' % ch.inspect
54
+ return changes, NotEnoughParametersError.new(ch)
55
+ # raise Exceptions::InvalidModeString, 'Not enough parameters: %s' % ch.inspect
45
56
  end
46
57
  end
47
58
  changes << [direction, ch, param]
@@ -50,14 +61,16 @@ module Cinch
50
61
  end
51
62
 
52
63
  if params.size > 0
53
- raise Exceptions::InvalidModeString, 'Too many parameters: %s %s' % [modes, params]
64
+ return changes, TooManyParametersError.new(modes, params)
65
+ # raise Exceptions::InvalidModeString, 'Too many parameters: %s %s' % [modes, params]
54
66
  end
55
67
 
56
68
  if count == 0
57
- raise Exceptions::InvalidModeString, 'Empty mode sequence: %s' % modes
69
+ return changes, EmptySequenceError.new(modes)
70
+ # raise Exceptions::InvalidModeString, 'Empty mode sequence: %s' % modes
58
71
  end
59
72
 
60
- return changes
73
+ return changes, nil
61
74
  end
62
75
  end
63
76
  end
data/lib/cinch/network.rb CHANGED
@@ -39,7 +39,7 @@ module Cinch
39
39
  # @return [String, nil] The mode used for getting the list of
40
40
  # channel owners, if any
41
41
  def owner_list_mode
42
- return "q" if @ircd == :unreal
42
+ return "q" if @ircd == :unreal || @ircd == :inspircd
43
43
  end
44
44
 
45
45
  # @return [String, nil] The mode used for getting the list of
data/lib/cinch/target.rb CHANGED
@@ -103,7 +103,7 @@ module Cinch
103
103
  # @see #safe_notice
104
104
  # @see #notice
105
105
  def safe_notice(text)
106
- safe_msg(text, true)
106
+ safe_send(text, true)
107
107
  end
108
108
 
109
109
  # Invoke an action (/me) in/to the target.
data/lib/cinch/user.rb CHANGED
@@ -274,9 +274,9 @@ module Cinch
274
274
  # @return [void]
275
275
  # @api private
276
276
  # @since 1.0.1
277
- def end_of_whois(values, not_found = false)
277
+ def end_of_whois(values)
278
278
  @in_whois = false
279
- if not_found
279
+ if values[:unknown?]
280
280
  sync(:unknown?, true, true)
281
281
  self.online = false
282
282
  sync(:idle, 0, true)
@@ -34,9 +34,16 @@ module Cinch
34
34
  else
35
35
  raise ArgumentError
36
36
  end
37
+
38
+ if nick == @bot.nick
39
+ user_obj = @bot
40
+ end
41
+
37
42
  downcased_nick = nick.irc_downcase(@bot.irc.isupport["CASEMAPPING"])
38
43
  @mutex.synchronize do
39
- user_obj = @cache[downcased_nick] ||= User.new(*bargs, @bot)
44
+ if user_obj.nil?
45
+ user_obj = @cache[downcased_nick] ||= User.new(*bargs, @bot)
46
+ end
40
47
  if user && host
41
48
  # Explicitly set user and host whenever we request a User
42
49
  # object to update them on e.g. JOIN.
@@ -52,6 +59,10 @@ module Cinch
52
59
  # @param [String] nick nick of a user
53
60
  # @return [User, nil]
54
61
  def find(nick)
62
+ if nick == @bot.nick
63
+ return @bot
64
+ end
65
+
55
66
  downcased_nick = nick.irc_downcase(@bot.irc.isupport["CASEMAPPING"])
56
67
  @mutex.synchronize do
57
68
  return @cache[downcased_nick]
data/lib/cinch/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Cinch
2
2
  # Version of the library
3
- VERSION = '2.2.5'
3
+ VERSION = '2.2.6'
4
4
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cinch
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.5
5
- prerelease:
4
+ version: 2.2.6
6
5
  platform: ruby
7
6
  authors:
8
7
  - Dominik Honnef
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-03-30 00:00:00.000000000 Z
11
+ date: 2015-07-08 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: A simple, friendly DSL for creating IRC bots
15
14
  email:
@@ -18,127 +17,125 @@ executables: []
18
17
  extensions: []
19
18
  extra_rdoc_files: []
20
19
  files:
20
+ - ".yardopts"
21
21
  - LICENSE
22
22
  - README.md
23
- - .yardopts
24
- - docs/changes.md
25
- - docs/getting_started.md
26
- - docs/readme.md
27
23
  - docs/bot_options.md
24
+ - docs/changes.md
28
25
  - docs/common_mistakes.md
29
- - docs/events.md
30
- - docs/plugins.md
26
+ - docs/common_tasks.md
31
27
  - docs/encodings.md
28
+ - docs/events.md
29
+ - docs/getting_started.md
32
30
  - docs/logging.md
33
- - docs/common_tasks.md
34
31
  - docs/migrating.md
35
- - lib/cinch/formatting.rb
36
- - lib/cinch/channel.rb
37
- - lib/cinch/timer.rb
38
- - lib/cinch/sasl/diffie_hellman.rb
39
- - lib/cinch/sasl/plain.rb
40
- - lib/cinch/sasl/dh_blowfish.rb
41
- - lib/cinch/sasl/mechanism.rb
42
- - lib/cinch/network.rb
43
- - lib/cinch/sasl.rb
44
- - lib/cinch/cached_list.rb
45
- - lib/cinch/bot.rb
46
- - lib/cinch/isupport.rb
32
+ - docs/plugins.md
33
+ - docs/readme.md
34
+ - examples/basic/autovoice.rb
35
+ - examples/basic/google.rb
36
+ - examples/basic/hello.rb
37
+ - examples/basic/join_part.rb
38
+ - examples/basic/memo.rb
39
+ - examples/basic/msg.rb
40
+ - examples/basic/seen.rb
41
+ - examples/basic/urban_dict.rb
42
+ - examples/basic/url_shorten.rb
43
+ - examples/plugins/autovoice.rb
44
+ - examples/plugins/custom_prefix.rb
45
+ - examples/plugins/dice_roll.rb
46
+ - examples/plugins/google.rb
47
+ - examples/plugins/hello.rb
48
+ - examples/plugins/hooks.rb
49
+ - examples/plugins/join_part.rb
50
+ - examples/plugins/lambdas.rb
51
+ - examples/plugins/last_nick.rb
52
+ - examples/plugins/msg.rb
53
+ - examples/plugins/multiple_matches.rb
54
+ - examples/plugins/own_events.rb
55
+ - examples/plugins/seen.rb
56
+ - examples/plugins/timer.rb
57
+ - examples/plugins/url_shorten.rb
58
+ - lib/cinch.rb
47
59
  - lib/cinch/#channel.rb#
48
- - lib/cinch/helpers.rb
49
- - lib/cinch/handler.rb
50
- - lib/cinch/handler_list.rb
51
- - lib/cinch/rubyext/module.rb
52
- - lib/cinch/rubyext/float.rb
53
- - lib/cinch/rubyext/string.rb
54
- - lib/cinch/syncable.rb
55
- - lib/cinch/plugin_list.rb
56
- - lib/cinch/message.rb
57
- - lib/cinch/target.rb
58
- - lib/cinch/mask.rb
59
- - lib/cinch/configuration/sasl.rb
60
+ - lib/cinch/ban.rb
61
+ - lib/cinch/bot.rb
62
+ - lib/cinch/cached_list.rb
63
+ - lib/cinch/callback.rb
64
+ - lib/cinch/channel.rb
65
+ - lib/cinch/channel_list.rb
66
+ - lib/cinch/configuration.rb
60
67
  - lib/cinch/configuration/bot.rb
68
+ - lib/cinch/configuration/dcc.rb
61
69
  - lib/cinch/configuration/plugins.rb
70
+ - lib/cinch/configuration/sasl.rb
62
71
  - lib/cinch/configuration/ssl.rb
63
- - lib/cinch/configuration/dcc.rb
64
72
  - lib/cinch/configuration/timeouts.rb
65
- - lib/cinch/pattern.rb
66
- - lib/cinch/open_ended_queue.rb
67
- - lib/cinch/logger_list.rb
68
- - lib/cinch/callback.rb
69
- - lib/cinch/dcc.rb
70
- - lib/cinch/version.rb
71
- - lib/cinch/utilities/deprecation.rb
72
- - lib/cinch/utilities/kernel.rb
73
- - lib/cinch/utilities/encoding.rb
74
73
  - lib/cinch/constants.rb
75
- - lib/cinch/mode_parser.rb
76
- - lib/cinch/user.rb
77
- - lib/cinch/logger/formatted_logger.rb
78
- - lib/cinch/logger/zcbot_logger.rb
79
- - lib/cinch/exceptions.rb
80
- - lib/cinch/logger.rb
81
- - lib/cinch/plugin.rb
82
- - lib/cinch/user_list.rb
83
- - lib/cinch/dcc/incoming/send.rb
74
+ - lib/cinch/dcc.rb
84
75
  - lib/cinch/dcc/dccable_object.rb
85
- - lib/cinch/dcc/outgoing.rb
86
76
  - lib/cinch/dcc/incoming.rb
77
+ - lib/cinch/dcc/incoming/send.rb
78
+ - lib/cinch/dcc/outgoing.rb
87
79
  - lib/cinch/dcc/outgoing/send.rb
80
+ - lib/cinch/exceptions.rb
81
+ - lib/cinch/formatting.rb
82
+ - lib/cinch/handler.rb
83
+ - lib/cinch/handler_list.rb
84
+ - lib/cinch/helpers.rb
88
85
  - lib/cinch/irc.rb
89
- - lib/cinch/channel_list.rb
90
- - lib/cinch/ban.rb
86
+ - lib/cinch/isupport.rb
87
+ - lib/cinch/logger.rb
88
+ - lib/cinch/logger/formatted_logger.rb
89
+ - lib/cinch/logger/zcbot_logger.rb
90
+ - lib/cinch/logger_list.rb
91
+ - lib/cinch/mask.rb
92
+ - lib/cinch/message.rb
91
93
  - lib/cinch/message_queue.rb
92
- - lib/cinch/configuration.rb
93
- - lib/cinch.rb
94
- - examples/plugins/timer.rb
95
- - examples/plugins/msg.rb
96
- - examples/plugins/dice_roll.rb
97
- - examples/plugins/lambdas.rb
98
- - examples/plugins/join_part.rb
99
- - examples/plugins/google.rb
100
- - examples/plugins/autovoice.rb
101
- - examples/plugins/multiple_matches.rb
102
- - examples/plugins/url_shorten.rb
103
- - examples/plugins/own_events.rb
104
- - examples/plugins/seen.rb
105
- - examples/plugins/last_nick.rb
106
- - examples/plugins/hooks.rb
107
- - examples/plugins/hello.rb
108
- - examples/plugins/custom_prefix.rb
109
- - examples/basic/msg.rb
110
- - examples/basic/join_part.rb
111
- - examples/basic/google.rb
112
- - examples/basic/autovoice.rb
113
- - examples/basic/url_shorten.rb
114
- - examples/basic/memo.rb
115
- - examples/basic/seen.rb
116
- - examples/basic/urban_dict.rb
117
- - examples/basic/hello.rb
94
+ - lib/cinch/mode_parser.rb
95
+ - lib/cinch/network.rb
96
+ - lib/cinch/open_ended_queue.rb
97
+ - lib/cinch/pattern.rb
98
+ - lib/cinch/plugin.rb
99
+ - lib/cinch/plugin_list.rb
100
+ - lib/cinch/rubyext/float.rb
101
+ - lib/cinch/rubyext/module.rb
102
+ - lib/cinch/rubyext/string.rb
103
+ - lib/cinch/sasl.rb
104
+ - lib/cinch/sasl/dh_blowfish.rb
105
+ - lib/cinch/sasl/diffie_hellman.rb
106
+ - lib/cinch/sasl/mechanism.rb
107
+ - lib/cinch/sasl/plain.rb
108
+ - lib/cinch/syncable.rb
109
+ - lib/cinch/target.rb
110
+ - lib/cinch/timer.rb
111
+ - lib/cinch/user.rb
112
+ - lib/cinch/user_list.rb
113
+ - lib/cinch/utilities/deprecation.rb
114
+ - lib/cinch/utilities/encoding.rb
115
+ - lib/cinch/utilities/kernel.rb
116
+ - lib/cinch/version.rb
118
117
  homepage: http://cinchrb.org
119
118
  licenses:
120
119
  - MIT
120
+ metadata: {}
121
121
  post_install_message:
122
122
  rdoc_options: []
123
123
  require_paths:
124
124
  - lib
125
125
  required_ruby_version: !ruby/object:Gem::Requirement
126
- none: false
127
126
  requirements:
128
- - - ! '>='
127
+ - - ">="
129
128
  - !ruby/object:Gem::Version
130
129
  version: 1.9.1
131
130
  required_rubygems_version: !ruby/object:Gem::Requirement
132
- none: false
133
131
  requirements:
134
- - - ! '>='
132
+ - - ">="
135
133
  - !ruby/object:Gem::Version
136
134
  version: '0'
137
135
  requirements: []
138
136
  rubyforge_project:
139
- rubygems_version: 1.8.23
137
+ rubygems_version: 2.4.5
140
138
  signing_key:
141
- specification_version: 3
139
+ specification_version: 4
142
140
  summary: An IRC Bot Building Framework
143
141
  test_files: []
144
- has_rdoc: yard