vetinari 0.0.1

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