vetinari 0.0.1

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.
@@ -0,0 +1,260 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vetinari::ISupport do
4
+ describe 'CASEMAPPING' do
5
+ it 'sets CASEMAPPING correctly' do
6
+ subject.parse('bot_nick CASEMAPPING=foobar')
7
+ expect(subject['CASEMAPPING']).to eq('foobar')
8
+ end
9
+ end
10
+
11
+ describe 'CHANLIMIT' do
12
+ it 'sets CHANLIMIT correctly having one argument' do
13
+ subject.parse('bot_nick CHANLIMIT=#:120')
14
+ expect(subject['CHANLIMIT']).to eq({'#' => 120})
15
+ end
16
+
17
+ it 'sets CHANLIMIT correctly having many argument' do
18
+ subject.parse('bot_nick CHANLIMIT=#+:10,&')
19
+ expect(subject['CHANLIMIT']).to eq({'#' => 10, '+' => 10, '&' => Float::INFINITY})
20
+ end
21
+ end
22
+
23
+ describe 'CHANMODES' do
24
+ it 'sets CHANMODES correctly' do
25
+ subject.parse('bot_nick CHANMODES=eIbq,k,flj,CFLMPQcgimnprstz')
26
+ expect(subject['CHANMODES']).to eq({
27
+ 'A' => %w(e I b q),
28
+ 'B' => %w(k),
29
+ 'C' => %w(f l j),
30
+ 'D' => %w(C F L M P Q c g i m n p r s t z)
31
+ })
32
+ end
33
+ end
34
+
35
+ describe 'CHANNELLEN' do
36
+ it 'sets CHANNELLEN correctly' do
37
+ subject.parse('bot_nick CHANNELLEN=50')
38
+ expect(subject['CHANNELLEN']).to eq(50)
39
+ end
40
+ end
41
+
42
+ describe 'CHANTYPES' do
43
+ it 'sets CHANTYPES correctly having one type' do
44
+ subject.parse('bot_nick CHANTYPES=#')
45
+ expect(subject['CHANTYPES']).to eq(['#'])
46
+ end
47
+
48
+ it 'sets CHANTYPES correctly having many types' do
49
+ subject.parse('bot_nick CHANTYPES=+#&')
50
+ expect(subject['CHANTYPES']).to eq(%w(+ # &))
51
+ end
52
+ end
53
+
54
+ describe 'EXCEPTS' do
55
+ it 'sets EXCEPTS correctly with mode_char' do
56
+ subject.parse('bot_nick EXCEPTS')
57
+ expect(subject['EXCEPTS']).to be_true
58
+ end
59
+
60
+ it 'sets EXCEPTS correctly without mode_char' do
61
+ subject.parse('bot_nick EXCEPTS=e')
62
+ expect(subject['EXCEPTS']).to eq('e')
63
+ end
64
+ end
65
+
66
+ describe 'IDCHAN' do
67
+ it 'sets IDCHAN correctly having one argument' do
68
+ subject.parse('bot_nick IDCHAN=!:5')
69
+ expect(subject['IDCHAN']).to eq({'!' => 5})
70
+ end
71
+
72
+ it 'sets IDCHAN correctly having many arguments' do
73
+ subject.parse('bot_nick IDCHAN=!:5,?:4')
74
+ expect(subject['IDCHAN']).to eq({'!' => 5, '?' => 4})
75
+ end
76
+ end
77
+
78
+ describe 'INVEX' do
79
+ it 'sets INVEX correctly having no argument' do
80
+ subject.parse('bot_nick INVEX')
81
+ expect(subject['INVEX']).to be_true
82
+ end
83
+
84
+ it 'sets IDCHAN correctly having one argument' do
85
+ subject.parse('bot_nick INVEX=a')
86
+ expect(subject['INVEX']).to eq('a')
87
+ end
88
+ end
89
+
90
+ describe 'KICKLEN' do
91
+ it 'sets KICKLEN correctly' do
92
+ subject.parse('bot_nick KICKLEN=100')
93
+ expect(subject['KICKLEN']).to be(100)
94
+ end
95
+ end
96
+
97
+ describe 'MAXLIST' do
98
+ it 'sets MAXLIST correctly having one argument' do
99
+ subject.parse('bot_nick MAXLIST=b:25')
100
+ expect(subject['MAXLIST']).to eq({'b' => 25})
101
+ end
102
+
103
+ it 'sets MAXLIST correctly having many arguments' do
104
+ subject.parse('bot_nick MAXLIST=b:25,eI:50')
105
+ expect(subject['MAXLIST']).to eq({'b' => 25, 'e' => 50, 'I' => 50})
106
+ end
107
+ end
108
+
109
+ describe 'MODES' do
110
+ it 'sets MODES correctly having no argument' do
111
+ subject.parse('bot_nick MODES')
112
+ expect(subject['MODES']).to be(Float::INFINITY)
113
+ end
114
+
115
+ it 'sets MODES correctly having one argument' do
116
+ subject.parse('bot_nick MODES=5')
117
+ expect(subject['MODES']).to be(5)
118
+ end
119
+ end
120
+
121
+ describe 'NETWORK' do
122
+ it 'sets NETWORK correctly' do
123
+ subject.parse('bot_nick NETWORK=freenode')
124
+ expect(subject['NETWORK']).to eq('freenode')
125
+ end
126
+ end
127
+
128
+ describe 'NICKLEN' do
129
+ it 'sets NICKLEN correctly' do
130
+ subject.parse('bot_nick NICKLEN=9')
131
+ expect(subject['NICKLEN']).to be(9)
132
+ end
133
+ end
134
+
135
+ describe 'PREFIX' do
136
+ it 'sets PREFIX correctly' do
137
+ subject.parse('bot_nick PREFIX=(ohv)@%+')
138
+ expect(subject['PREFIX']).to eq({'o' => '@', 'h' => '%', 'v' => '+'})
139
+ end
140
+ end
141
+
142
+ describe 'SAFELIST' do
143
+ it 'sets SAFELIST correctly' do
144
+ subject.parse('bot_nick SAFELIST')
145
+ expect(subject['SAFELIST']).to be_true
146
+ end
147
+ end
148
+
149
+ describe 'STATUSMSG' do
150
+ it 'sets STATUSMSG correctly having one argument' do
151
+ subject.parse('bot_nick STATUSMSG=+')
152
+ expect(subject['STATUSMSG']).to eq(['+'])
153
+ end
154
+
155
+ it 'sets STATUSMSG correctly having many arguments' do
156
+ subject.parse('bot_nick STATUSMSG=@+')
157
+ expect(subject['STATUSMSG']).to eq(['@', '+'])
158
+ end
159
+ end
160
+
161
+ describe 'STD' do
162
+ it 'sets STD correctly having one argument' do
163
+ subject.parse('bot_nick STD=foo')
164
+ expect(subject['STD']).to eq(['foo'])
165
+ end
166
+
167
+ it 'sets STD correctly having many arguments' do
168
+ subject.parse('bot_nick STD=foo,bar,baz')
169
+ expect(subject['STD']).to eq(['foo', 'bar', 'baz'])
170
+ end
171
+ end
172
+
173
+ describe 'TARGMAX' do
174
+ it 'sets TARGMAX correctly having limits' do
175
+ subject.parse('bot_nick TARGMAX=NAMES:1,LIST:2,KICK:3')
176
+ expect(subject['TARGMAX']).to eq({'NAMES' => 1, 'LIST' => 2, 'KICK' => 3})
177
+ end
178
+
179
+ it 'sets TARGMAX correctly having limits and no limits' do
180
+ subject.parse('bot_nick TARGMAX=NAMES:1,LIST:2,KICK:3,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR:')
181
+ expect(subject['TARGMAX']).to eq({
182
+ 'NAMES' => 1,
183
+ 'LIST' => 2,
184
+ 'KICK' => 3,
185
+ 'WHOIS' => 1,
186
+ 'PRIVMSG' => 4,
187
+ 'NOTICE' => 4,
188
+ 'ACCEPT' => Float::INFINITY,
189
+ 'MONITOR' => Float::INFINITY
190
+ })
191
+ end
192
+ end
193
+
194
+ describe 'TOPICLEN' do
195
+ it 'sets TOPICLEN correctly' do
196
+ subject.parse('bot_nick TOPICLEN=250')
197
+ expect(subject['TOPICLEN']).to be(250)
198
+ end
199
+ end
200
+
201
+ describe 'Different' do
202
+ it 'sets non mentioned keys correclty aswell' do
203
+ subject.parse('bot_nick AWAYLEN=160')
204
+ subject.parse('bot_nick CNOTICE')
205
+ subject.parse('bot_nick EXTBAN=$,arx')
206
+ expect(subject['AWAYLEN']).to eq('160')
207
+ expect(subject['CNOTICE']).to be_true
208
+ expect(subject['EXTBAN']).to eq(['$', 'arx'])
209
+ end
210
+ end
211
+
212
+ describe 'Several arguments at once' do
213
+ it 'sets several arguments at once correcty' do
214
+ subject.parse('bot_nick CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQcgimnprstz CHANLIMIT=#:120 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=freenode KNOCK STATUSMSG=@+ CALLERID=g :are supported by this server')
215
+ subject.parse('bot_nick CASEMAPPING=strict CHARSET=ascii NICKLEN=16 CHANNELLEN=50 TOPICLEN=390 ETRACE CPRIVMSG CNOTICE DEAF=D MONITOR=100 FNC TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: :are supported by this server')
216
+ subject.parse('bot_nick EXTBAN=$,arx WHOX CLIENTVER=3.0 SAFELIST ELIST=CTU :are supported by this server')
217
+ expect(subject['CHANTYPES']).to eq(['#'])
218
+ expect(subject['EXCEPTS']).to be_true
219
+ expect(subject['INVEX']).to be_true
220
+ expect(subject['CHANMODES']).to eq({
221
+ 'A' => %w(e I b q),
222
+ 'B' => %w(k),
223
+ 'C' => %w(f l j),
224
+ 'D' => %w(C F L M P Q c g i m n p r s t z)
225
+ })
226
+ expect(subject['CHANLIMIT']).to eq({'#' => 120})
227
+ expect(subject['MAXLIST']).to eq({'b' => 100, 'q' => 100, 'e' => 100, 'I' => 100})
228
+ expect(subject['MODES']).to be(4)
229
+ expect(subject['KNOCK']).to be_true
230
+ expect(subject['STATUSMSG']).to eq(['@', '+'])
231
+ expect(subject['CALLERID']).to eq('g')
232
+ expect(subject['CASEMAPPING']).to eq('strict')
233
+ expect(subject['CHARSET']).to eq('ascii')
234
+ expect(subject['NICKLEN']).to be(16)
235
+ expect(subject['CHANNELLEN']).to be(50)
236
+ expect(subject['TOPICLEN']).to be(390)
237
+ expect(subject['ETRACE']).to be_true
238
+ expect(subject['CPRIVMSG']).to be_true
239
+ expect(subject['CNOTICE']).to be_true
240
+ expect(subject['DEAF']).to eq('D')
241
+ expect(subject['MONITOR']).to eq('100')
242
+ expect(subject['FNC']).to be_true
243
+ expect(subject['TARGMAX']).to eq({
244
+ 'NAMES' => 1,
245
+ 'LIST' => 1,
246
+ 'KICK' => 1,
247
+ 'WHOIS' => 1,
248
+ 'PRIVMSG' => 4,
249
+ 'NOTICE' => 4,
250
+ 'ACCEPT' => Float::INFINITY,
251
+ 'MONITOR' => Float::INFINITY
252
+ })
253
+ expect(subject['EXTBAN']).to eq(['$', 'arx'])
254
+ expect(subject['WHOX']).to be_true
255
+ expect(subject['CLIENTVER']).to eq('3.0')
256
+ expect(subject['SAFELIST']).to be_true
257
+ expect(subject['ELIST']).to eq('CTU')
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,19 @@
1
+ require 'rspec'
2
+ require 'vetinari'
3
+ # require 'pry'
4
+
5
+ RSpec.configure do |config|
6
+ config.color_enabled = true
7
+ end
8
+
9
+ Celluloid.logger = nil
10
+
11
+ module Vetinari
12
+ class Callback
13
+ undef :call
14
+
15
+ def call(env)
16
+ @proc.call(env) if matching?(env)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'User Management' do
4
+ subject { Vetinari::Bot.new { |c| c.verbose = false } }
5
+
6
+ context 'Connecting to the server' do
7
+ it 'adds itself to the user_list when connected to the server' do
8
+ expect(subject.users.users).to be_empty
9
+ subject.parse(":server 001 Vetinari :Welcome message")
10
+ subject.parse(':server 376 Vetinari :End of /MOTD command.')
11
+ expect(subject.users.users).to have(1).user
12
+ expect(subject.users.users.first).to be(subject.user)
13
+ end
14
+ end
15
+
16
+ context 'Connected to the server' do
17
+ before(:each) do
18
+ subject.parse(":server 001 Vetinari :Welcome message")
19
+ subject.parse(":server 376 Vetinari :End of /MOTD command.")
20
+ end
21
+
22
+ it 'adds an user to the user_list when the user joins a channel the Thaum is in' do
23
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
24
+ expect(subject.users.users).to have(1).user
25
+ subject.parse(':TheLibrarian!foo@bar JOIN #mended_drum')
26
+ expect(subject.users.users).to have(2).users
27
+ end
28
+
29
+ it 'adds an user to the channel when the user joins a channel the Thaum is in' do
30
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
31
+ channel = subject.channels['#mended_drum']
32
+ expect(channel.users).to have(1).user
33
+ subject.parse(':TheLibrarian!foo@bar JOIN #mended_drum')
34
+ expect(channel.users).to have(2).users
35
+ end
36
+
37
+ it 'adds user to the user_list when the Thaum joins a channel with users in it' do
38
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
39
+ expect(subject.users.users).to have(1).user
40
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian +Ridcully')
41
+ expect(subject.users.users).to have(3).users
42
+ end
43
+
44
+ it 'adds user to the user_list when the Thaum joins a channel with users in it without doublets' do
45
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
46
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian +Ridcully')
47
+ subject.parse(':Vetinari!foo@bar JOIN #library')
48
+ subject.parse(':server 353 Vetinari @ #library :Vetinari TheLibrarian')
49
+ expect(subject.users.users).to have(3).users
50
+ end
51
+
52
+ it 'adds user to a channel when the Thaum joins a channel with users in it' do
53
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
54
+ channel = subject.channels['#mended_drum']
55
+ expect(channel.users).to have(1).user
56
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian +Ridcully')
57
+ expect(channel.users).to have(3).users
58
+ end
59
+
60
+ it 'removes an user from the user_list when quitting' do
61
+ expect(subject.users.users).to have(1).user
62
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
63
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian +Ridcully')
64
+ expect(subject.users.users).to have(3).users
65
+ subject.parse(':TheLibrarian!foo@bar QUIT :Going to eat a banana.')
66
+ expect(subject.users.users).to have(2).users
67
+ end
68
+
69
+ it 'removes an user from all channels when quitting' do
70
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
71
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian')
72
+ subject.parse(':Vetinari!foo@bar JOIN #library')
73
+ subject.parse(':server 353 Vetinari @ #library :Vetinari +TheLibrarian')
74
+ mended_drum = subject.channels['#mended_drum']
75
+ expect(mended_drum.users).to have(2).users
76
+ library = subject.channels['#library']
77
+ expect(library.users).to have(2).users
78
+ subject.parse(':TheLibrarian!foo@bar QUIT :Going to eat a banana.')
79
+ expect(mended_drum.users).to have(1).users
80
+ expect(library.users).to have(1).users
81
+ end
82
+
83
+ it 'removes an user from a channel when the user parts' do
84
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
85
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian')
86
+ channel = subject.channels['#mended_drum']
87
+ expect(channel.users).to have(2).users
88
+ subject.parse(':TheLibrarian!foo@bar PART #mended_drum')
89
+ expect(channel.users).to have(1).user
90
+ end
91
+
92
+ it 'removes an user from a channel when being kicked' do
93
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
94
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian')
95
+ channel = subject.channels['#mended_drum']
96
+ expect(channel.users).to have(2).users
97
+ subject.parse(':Vetinari!foo@bar KICK #mended_drum TheLibrarian :Go out!')
98
+ expect(channel.users).to have(1).user
99
+ end
100
+
101
+ it 'does not remove an user from the user_list when the user parts a channel and the user in another channel the Thaum is in' do
102
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
103
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian')
104
+ subject.parse(':Vetinari!foo@bar JOIN #library')
105
+ subject.parse(':server 353 Vetinari @ #library :Vetinari @TheLibrarian')
106
+ expect(subject.users.users).to have(2).users
107
+ subject.parse(':TheLibrarian!foo@bar PART #mended_drum')
108
+ expect(subject.users.users).to have(2).users
109
+ end
110
+
111
+ it 'removes an user from the users when the user parting the last channel the Thaum is in' do
112
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
113
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian')
114
+ expect(subject.users.users).to have(2).users
115
+ subject.parse(':TheLibrarian!foo@bar PART #mended_drum')
116
+ expect(subject.users.users).to have(1).user
117
+ end
118
+
119
+ it 'removes an user from the user_list when being kicked from the last channel the Thaum is in' do
120
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
121
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian')
122
+ expect(subject.users.users).to have(2).users
123
+ subject.parse(':Vetinari!foo@bar KICK #mended_drum TheLibrarian :Go out!')
124
+ expect(subject.users.users).to have(1).user
125
+ end
126
+
127
+ it 'removes an user from the user_list when parting if the user is no other channel the Thaum is in' do
128
+ subject.parse(':Vetinari!foo@bar JOIN #mended_drum')
129
+ subject.parse(':server 353 Vetinari @ #mended_drum :Vetinari @TheLibrarian')
130
+ expect(subject.users.users).to have(2).users
131
+ subject.parse(':Vetinari!foo@bar PART #mended_drum')
132
+ expect(subject.users.users).to have(1).users
133
+ end
134
+ end
135
+ end
data/vetinari.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vetinari/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'vetinari'
8
+ spec.version = Vetinari::VERSION
9
+ spec.authors = ['Tobias Bühlmann']
10
+ spec.email = ['tobias.buehlmann@gmx.de']
11
+ spec.description = <<-EOS
12
+ Vetinari is a multithreaded IRC Bot Framework using the Celluloid::IO
13
+ library.
14
+ EOS
15
+ spec.summary = 'Multithreaded IRC Bot Framework.'
16
+ spec.homepage = 'https://github.com/tbuehlmann/vetinari'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files`.split("\n")
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.required_ruby_version = '>= 1.9.2'
24
+ spec.add_dependency 'celluloid-io', '~> 0.14'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.3'
27
+ spec.add_development_dependency 'pry', '~> 0.9'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rspec', '~> 2.13'
30
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vetinari
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tobias Bühlmann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: celluloid-io
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.14'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '2.13'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '2.13'
83
+ description: |2
84
+ Vetinari is a multithreaded IRC Bot Framework using the Celluloid::IO
85
+ library.
86
+ email:
87
+ - tobias.buehlmann@gmx.de
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - .gitignore
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - examples/echo_bot.rb
97
+ - lib/vetinari.rb
98
+ - lib/vetinari/bot.rb
99
+ - lib/vetinari/callback.rb
100
+ - lib/vetinari/callback_container.rb
101
+ - lib/vetinari/channel.rb
102
+ - lib/vetinari/channel_container.rb
103
+ - lib/vetinari/configuration.rb
104
+ - lib/vetinari/dcc/incoming/file.rb
105
+ - lib/vetinari/dcc/server.rb
106
+ - lib/vetinari/dcc/server_manager.rb
107
+ - lib/vetinari/irc.rb
108
+ - lib/vetinari/isupport.rb
109
+ - lib/vetinari/logging/logger.rb
110
+ - lib/vetinari/logging/logger_list.rb
111
+ - lib/vetinari/logging/null_logger.rb
112
+ - lib/vetinari/message_parser.rb
113
+ - lib/vetinari/mode_parser.rb
114
+ - lib/vetinari/user.rb
115
+ - lib/vetinari/user_container.rb
116
+ - lib/vetinari/version.rb
117
+ - spec/callback_spec.rb
118
+ - spec/channel_management_spec.rb
119
+ - spec/default_callbacks_spec.rb
120
+ - spec/isupport_spec.rb
121
+ - spec/spec_helper.rb
122
+ - spec/user_management_spec.rb
123
+ - vetinari.gemspec
124
+ homepage: https://github.com/tbuehlmann/vetinari
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - '>='
135
+ - !ruby/object:Gem::Version
136
+ version: 1.9.2
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.0.3
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Multithreaded IRC Bot Framework.
148
+ test_files:
149
+ - spec/callback_spec.rb
150
+ - spec/channel_management_spec.rb
151
+ - spec/default_callbacks_spec.rb
152
+ - spec/isupport_spec.rb
153
+ - spec/spec_helper.rb
154
+ - spec/user_management_spec.rb