rlyeh 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,206 @@
1
+ module Rlyeh
2
+ module NumericReply
3
+ class << self
4
+ def map
5
+ @map ||= {
6
+ # Numerics in the range from 001 to 099 are used for client-server
7
+ # connections only and should never travel between servers.
8
+ # Replies generated in the response to commands are found in the range from 200 to 399.
9
+ :welcome => 1,
10
+ :yourhost => 2,
11
+ :created => 3,
12
+ :myinfo => 4,
13
+ :bounce => 5,
14
+ :userhost => 302,
15
+ :ison => 303,
16
+ :away => 301,
17
+ :unaway => 305,
18
+ :nowaway => 306,
19
+ :whoisuser => 311,
20
+ :whoisserver => 312,
21
+ :whoisoperator => 313,
22
+ :whoisidle => 317,
23
+ :endofwhois => 318,
24
+ :whoischannels => 319,
25
+ :whowasuser => 314,
26
+ :endofwhowas => 369,
27
+ :liststart => 321,
28
+ :list => 322,
29
+ :listend => 323,
30
+ :uniqopis => 325,
31
+ :channelmodeis => 324,
32
+ :notopic => 331,
33
+ :topic => 332,
34
+ :inviting => 341,
35
+ :summoning => 342,
36
+ :invitelist => 346,
37
+ :endofinvitelist => 347,
38
+ :exceptlist => 348,
39
+ :endofexceptlist => 349,
40
+ :version => 351,
41
+ :whoreply => 352,
42
+ :endofwho => 315,
43
+ :namreply => 353,
44
+ :endofnames => 366,
45
+ :links => 364,
46
+ :endoflinks => 365,
47
+ :banlist => 367,
48
+ :endofbanlist => 368,
49
+ :info => 371,
50
+ :endofinfo => 374,
51
+ :motdstart => 375,
52
+ :motd => 372,
53
+ :endofmotd => 376,
54
+ :youreoper => 381,
55
+ :rehashing => 382,
56
+ :youreservice => 383,
57
+ :time => 391,
58
+ :usersstart => 392,
59
+ :users => 393,
60
+ :endofusers => 394,
61
+ :nousers => 395,
62
+ :tracelink => 200,
63
+ :traceconnecting => 201,
64
+ :tracehandshake => 202,
65
+ :traceunknown => 203,
66
+ :traceoperator => 204,
67
+ :traceuser => 205,
68
+ :traceserver => 206,
69
+ :traceservice => 207,
70
+ :tracenewtype => 208,
71
+ :traceclass => 209,
72
+ :tracereconnect => 210,
73
+ :tracelog => 261,
74
+ :traceend => 262,
75
+ :statslinkinfo => 211,
76
+ :statscommands => 212,
77
+ :endofstats => 219,
78
+ :statsuptime => 242,
79
+ :statsoline => 243,
80
+ :umodeis => 221,
81
+ :servlist => 234,
82
+ :servlistend => 235,
83
+ :luserclient => 251,
84
+ :luserop => 252,
85
+ :luserunknown => 253,
86
+ :luserchannels => 254,
87
+ :luserme => 255,
88
+ :adminme => 256,
89
+ :adminloc1 => 257,
90
+ :adminloc2 => 258,
91
+ :adminemail => 259,
92
+ :tryagain => 263,
93
+
94
+ # Error replies are found in the range from 400 to 599.
95
+ :nosuchnick => 401,
96
+ :nosuchserver => 402,
97
+ :nosuchchannel => 403,
98
+ :cannotsendtochan => 404,
99
+ :toomanychannels => 405,
100
+ :wasnosuchnick => 406,
101
+ :toomanytargets => 407,
102
+ :nosuchservice => 408,
103
+ :noorigin => 409,
104
+ :norecipient => 411,
105
+ :notexttosend => 412,
106
+ :notoplevel => 413,
107
+ :wildtoplevel => 414,
108
+ :badmask => 415,
109
+ :unknowncommand => 421,
110
+ :nomotd => 422,
111
+ :noadmininfo => 423,
112
+ :fileerror => 424,
113
+ :nonicknamegiven => 431,
114
+ :erroneusnickname => 432,
115
+ :nicknameinuse => 433,
116
+ :nickcollision => 436,
117
+ :unavailresource => 437,
118
+ :usernotinchannel => 441,
119
+ :notonchannel => 442,
120
+ :useronchannel => 443,
121
+ :nologin => 444,
122
+ :summondisabled => 445,
123
+ :usersdisabled => 446,
124
+ :notregistered => 451,
125
+ :needmoreparams => 461,
126
+ :alreadyregistred => 462,
127
+ :nopermforhost => 463,
128
+ :passwdmismatch => 464,
129
+ :yourebannedcreep => 465,
130
+ :youwillbebanned => 466,
131
+ :keyset => 467,
132
+ :channelisfull => 471,
133
+ :unknownmode => 472,
134
+ :inviteonlychan => 473,
135
+ :bannedfromchan => 474,
136
+ :badchannelkey => 475,
137
+ :badchanmask => 476,
138
+ :nochanmodes => 477,
139
+ :banlistfull => 478,
140
+ :noprivileges => 481,
141
+ :chanoprivsneeded => 482,
142
+ :cantkillserver => 483,
143
+ :restricted => 484,
144
+ :uniqopprivsneeded => 485,
145
+ :nooperhost => 491,
146
+ :umodeunknownflag => 501,
147
+ :usersdontmatch => 502,
148
+ }
149
+ end
150
+
151
+ def map_invert
152
+ @map_invert ||= map.invert
153
+ end
154
+
155
+ def to_value(value)
156
+ case value
157
+ when Integer
158
+ numeric_to_value value
159
+ when Symbol
160
+ name_to_value value
161
+ else
162
+ str = value.to_s
163
+ begin
164
+ numeric = Integer(str)
165
+ numeric_to_value numeric
166
+ rescue ArgumentError
167
+ name_to_value str
168
+ end
169
+ end
170
+ end
171
+
172
+ def to_key(value)
173
+ case value
174
+ when Integer
175
+ numeric_to_key value
176
+ when Symbol
177
+ name_to_key value
178
+ else
179
+ str = value.to_s
180
+ begin
181
+ numeric = Integer(str)
182
+ numeric_to_key numeric
183
+ rescue ArgumentError
184
+ name_to_key str
185
+ end
186
+ end
187
+ end
188
+
189
+ def numeric_to_value(numeric)
190
+ numeric.to_s.rjust(3, '0')
191
+ end
192
+
193
+ def numeric_to_key(numeric)
194
+ map_invert[numeric]
195
+ end
196
+
197
+ def name_to_value(name)
198
+ numeric_to_value map[name.intern]
199
+ end
200
+
201
+ def name_to_key(name)
202
+ name.intern
203
+ end
204
+ end
205
+ end
206
+ end
data/lib/rlyeh/runner.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'rlyeh/utils'
2
+
1
3
  module Rlyeh
2
4
  module Runner
3
5
  def self.included(base)
@@ -5,9 +7,20 @@ module Rlyeh
5
7
  end
6
8
 
7
9
  module ClassMethods
10
+ def servers
11
+ @servers ||= []
12
+ end
13
+
8
14
  def run(*args, &block)
15
+ default_options = {:signal_trap => true}.freeze
16
+ options = default_options.merge(Rlyeh::Utils.extract_options args)
17
+ signal_trap = options.delete(:signal_trap)
18
+
19
+ trap(:INT) { stop } if signal_trap
20
+
9
21
  starter = proc do
10
- Server.start *args, &block
22
+ server = Server.start *args, &block
23
+ servers << server
11
24
  end
12
25
 
13
26
  if EventMachine.reactor_running?
@@ -16,8 +29,12 @@ module Rlyeh
16
29
  EventMachine.run &starter
17
30
  end
18
31
  end
32
+ alias_method :emerge, :run
19
33
 
20
34
  def stop
35
+ servers.each { |server| server.stop }
36
+ servers.clear
37
+
21
38
  EventMachine.stop if EventMachine.reactor_running?
22
39
  end
23
40
  end
@@ -0,0 +1,11 @@
1
+ require 'ircp'
2
+ require 'rlyeh/numeric_reply'
3
+
4
+ module Rlyeh
5
+ module Sendable
6
+ def send_numeric_reply(numeric, target, *args)
7
+ numeric = Rlyeh::NumericReply.to_value numeric
8
+ send_data Ircp::Message.new(target, *args, :command => numeric)
9
+ end
10
+ end
11
+ end
data/lib/rlyeh/server.rb CHANGED
@@ -1,13 +1,11 @@
1
1
  require 'rlyeh/connection'
2
2
  require 'rlyeh/utils'
3
- require 'rlyeh/filter'
3
+ require 'rlyeh/filters'
4
4
 
5
5
  module Rlyeh
6
6
  class Server
7
- include Rlyeh::Filter
8
-
9
7
  attr_reader :options, :host, :port
10
- attr_reader :app_class, :signature, :connections, :sessions
8
+ attr_reader :app_class, :signature, :sessions
11
9
 
12
10
  def initialize(*args)
13
11
  @options = Rlyeh::Utils.extract_options! args
@@ -15,7 +13,6 @@ module Rlyeh
15
13
  @port = @options.delete(:port) || 46667
16
14
  @app_class = args.shift
17
15
  @signature = nil
18
- @connections = []
19
16
  @sessions = {}
20
17
  end
21
18
 
@@ -28,6 +25,7 @@ module Rlyeh
28
25
  @signature = EventMachine.start_server @host, @port, Rlyeh::Connection, *args do |connection|
29
26
  bind connection
30
27
  end
28
+ self
31
29
  end
32
30
 
33
31
  def stop
@@ -36,7 +34,6 @@ module Rlyeh
36
34
  end
37
35
 
38
36
  def bind(connection)
39
- @connections.push connection
40
37
  puts 'bind'
41
38
  end
42
39
 
@@ -47,14 +44,14 @@ module Rlyeh
47
44
 
48
45
  if session.empty?
49
46
  session.close
50
- @sessions.delete session
47
+ @sessions.delete session.id
51
48
  end
52
49
  end
53
50
 
54
- @connections.delete connection
55
51
  puts 'unbind'
56
52
  end
57
53
 
58
- define_filter :start, :stop, :bind, :unbind
54
+ include Rlyeh::Filters
55
+ define_filters :start, :stop, :bind, :unbind
59
56
  end
60
57
  end
data/lib/rlyeh/session.rb CHANGED
@@ -1,29 +1,28 @@
1
- require 'rlyeh/filter'
1
+ require 'rlyeh/filters'
2
2
 
3
3
  module Rlyeh
4
4
  class Session
5
- include Rlyeh::Filter
5
+ attr_reader :id, :channel, :connections
6
6
 
7
- attr_accessor :channel, :connections
8
-
9
- def initialize
7
+ def initialize(id)
8
+ @id = id
10
9
  @channel = EventMachine::Channel.new
11
- @subscribers = {}
10
+ @connections = {}
12
11
  end
13
12
 
14
- def attach(conn)
15
- conn.attached self
13
+ def attach(connection)
14
+ connection.attached self
16
15
 
17
- @subscribers[conn] = @channel.subscribe do |msg|
18
- conn.send_data msg
16
+ @connections[connection] = @channel.subscribe do |msg|
17
+ connection.send_data msg
19
18
  end
20
19
  end
21
20
 
22
- def detach(conn)
23
- id = @subscribers.delete conn
21
+ def detach(connection)
22
+ id = @connections.delete connection
24
23
  @channel.unsubscribe id if id
25
24
 
26
- conn.detached self
25
+ connection.detached self
27
26
  end
28
27
 
29
28
  def close
@@ -34,9 +33,10 @@ module Rlyeh
34
33
  end
35
34
 
36
35
  def empty?
37
- @subscribes.empty?
36
+ @connections.empty?
38
37
  end
39
38
 
40
- define_filter :attach, :detach, :close, :send_data
39
+ include Rlyeh::Filters
40
+ define_filters :attach, :detach, :close, :send_data
41
41
  end
42
42
  end
@@ -0,0 +1,35 @@
1
+ module Rlyeh
2
+ module Settings
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def settings
9
+ self
10
+ end
11
+
12
+ def set(option, value = nil, &block)
13
+ if option.respond_to?(:each)
14
+ option.each { |k, v| set k, v }
15
+ return self
16
+ end
17
+
18
+ setter = proc { |v| set option, v }
19
+ getter = block ? block : proc { value }
20
+
21
+ Rlyeh::Utils.singleton_class(self).class_eval do
22
+ define_method "#{option}=", &setter if setter
23
+ define_method "#{option}", &getter if getter
24
+ class_eval "def #{option}?; !!#{option}; end" unless method_defined?("#{option}?")
25
+ end
26
+ end
27
+
28
+ self
29
+ end
30
+
31
+ def settings
32
+ self.class.settings
33
+ end
34
+ end
35
+ end
data/lib/rlyeh/utils.rb CHANGED
@@ -1,9 +1,34 @@
1
1
  module Rlyeh
2
2
  module Utils
3
3
  class << self
4
+ def singleton_class(obj)
5
+ if obj.respond_to?(:singleton_class)
6
+ obj.singleton_class
7
+ else
8
+ class << obj
9
+ self
10
+ end
11
+ end
12
+ end
13
+
14
+ def extract_options(args)
15
+ args.last.is_a?(::Hash) ? args.last : {}
16
+ end
17
+
4
18
  def extract_options!(args)
5
19
  args.last.is_a?(::Hash) ? args.pop : {}
6
20
  end
21
+
22
+ def generate_method(obj, name, method = nil, &block)
23
+ name = name.to_s
24
+ method ||= block
25
+ obj.instance_eval do
26
+ define_method name, &method
27
+ method = instance_method name
28
+ remove_method name
29
+ method
30
+ end
31
+ end
7
32
  end
8
33
  end
9
34
  end
data/lib/rlyeh/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rlyeh
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/rlyeh.rb CHANGED
@@ -1,16 +1,20 @@
1
1
  require 'eventmachine'
2
2
 
3
3
  module Rlyeh
4
- autoload :VERSION, 'rlyeh/version'
4
+ autoload :VERSION, 'rlyeh/version'
5
5
 
6
- autoload :Server, 'rlyeh/server'
7
- autoload :Connection, 'rlyeh/connection'
8
- autoload :Session, 'rlyeh/session'
9
- autoload :Environment, 'rlyeh/environment'
10
- autoload :Base, 'rlyeh/base'
6
+ autoload :Server, 'rlyeh/server'
7
+ autoload :Connection, 'rlyeh/connection'
8
+ autoload :Session, 'rlyeh/session'
9
+ autoload :Environment, 'rlyeh/environment'
10
+ autoload :NumericReply, 'rlyeh/numeric_reply'
11
+ autoload :Base, 'rlyeh/base'
11
12
 
12
- autoload :Dispatcher, 'rlyeh/dispatcher'
13
- autoload :Filter, 'rlyeh/filter'
13
+ autoload :Dispatcher, 'rlyeh/dispatcher'
14
+ autoload :Filter, 'rlyeh/filter'
15
+ autoload :Settings, 'rlyeh/settings'
16
+
17
+ require 'rlyeh/deep_ones'
14
18
 
15
19
  require 'rlyeh/runner'
16
20
  include Rlyeh::Runner
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rlyeh::NumericReply do
4
+ describe '#to_value' do
5
+ [1, '1', '01', '001', 'welcome', :welcome].each do |arg|
6
+ context "with argument #{arg.inspect}" do
7
+ subject { Rlyeh::NumericReply.to_value arg }
8
+ it { should eq '001' }
9
+ end
10
+ end
11
+ end
12
+
13
+ describe '#to_key' do
14
+ [1, '1', '01', '001', 'welcome', :welcome].each do |arg|
15
+ context "with argument #{arg.inspect}" do
16
+ subject { Rlyeh::NumericReply.to_key arg }
17
+ it { should eq :welcome }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rlyeh::Settings do
4
+ describe '#settings' do
5
+ class Test
6
+ include Rlyeh::Settings
7
+ end
8
+
9
+ context 'class' do
10
+ subject { Test }
11
+ its(:settings) { should eq Test }
12
+ end
13
+
14
+ context 'instance' do
15
+ subject { Test.new }
16
+ its(:settings) { should eq Test }
17
+ end
18
+ end
19
+
20
+ describe '#set' do
21
+ class Test
22
+ include Rlyeh::Settings
23
+ set :logging, false
24
+ set :default_encoding, 'utf-8'
25
+ end
26
+ subject { Test.settings }
27
+
28
+ context 'getter' do
29
+ its(:logging) { should eq false }
30
+ its(:default_encoding) { should eq 'utf-8' }
31
+ end
32
+
33
+ context 'setter' do
34
+ before { Test.settings.logging = true }
35
+ its(:logging) { should eq true }
36
+ end
37
+
38
+ context 'condition' do
39
+ before { Test.settings.logging = false }
40
+ it { should_not be_logging }
41
+ end
42
+
43
+ context 'no method' do
44
+ it { lambda { Test.settings.not_found }.should raise_error(NoMethodError) }
45
+ end
46
+
47
+ context 'multi set' do
48
+ before { Test.set :foo => 1, :bar => 2, :buzz => 'zzz' }
49
+ its(:foo) { should eq 1 }
50
+ its(:bar) { should eq 2 }
51
+ its(:buzz) { should eq 'zzz' }
52
+ end
53
+ end
54
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
  require 'rspec'
4
- require 'ircp'
4
+ require 'rlyeh'
5
5
 
6
6
  # Requires supporting files with custom matchers and macros, etc,
7
7
  # in ./support/ and its subdirectories.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rlyeh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-10 00:00:00.000000000Z
12
+ date: 2012-03-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ircp
16
- requirement: &14960720 !ruby/object:Gem::Requirement
16
+ requirement: &24772480 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *14960720
24
+ version_requirements: *24772480
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: eventmachine
27
- requirement: &14960300 !ruby/object:Gem::Requirement
27
+ requirement: &24772060 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *14960300
35
+ version_requirements: *24772060
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &14959880 !ruby/object:Gem::Requirement
38
+ requirement: &24771600 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *14959880
46
+ version_requirements: *24771600
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &15007960 !ruby/object:Gem::Requirement
49
+ requirement: &24771160 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *15007960
57
+ version_requirements: *24771160
58
58
  description: Welcome to the deep sea
59
59
  email:
60
60
  - mail@mashiro.org
@@ -68,23 +68,34 @@ files:
68
68
  - LICENSE
69
69
  - README.md
70
70
  - Rakefile
71
- - example/middleware.rb
72
- - example/simple.rb
71
+ - examples/echo.rb
72
+ - examples/middleware.rb
73
+ - examples/simple.rb
73
74
  - lib/rlyeh.rb
74
75
  - lib/rlyeh/base.rb
75
76
  - lib/rlyeh/connection.rb
77
+ - lib/rlyeh/deep_ones.rb
78
+ - lib/rlyeh/deep_ones/auth.rb
79
+ - lib/rlyeh/deep_ones/builder.rb
80
+ - lib/rlyeh/deep_ones/closer.rb
81
+ - lib/rlyeh/deep_ones/logger.rb
82
+ - lib/rlyeh/deep_ones/parser.rb
83
+ - lib/rlyeh/deep_ones/typablemap.rb
76
84
  - lib/rlyeh/dispatcher.rb
77
85
  - lib/rlyeh/environment.rb
78
- - lib/rlyeh/filter.rb
79
- - lib/rlyeh/middleware/builder.rb
80
- - lib/rlyeh/middleware/typablemap.rb
86
+ - lib/rlyeh/filters.rb
87
+ - lib/rlyeh/numeric_reply.rb
81
88
  - lib/rlyeh/runner.rb
89
+ - lib/rlyeh/sendable.rb
82
90
  - lib/rlyeh/server.rb
83
91
  - lib/rlyeh/session.rb
92
+ - lib/rlyeh/settings.rb
84
93
  - lib/rlyeh/utils.rb
85
94
  - lib/rlyeh/version.rb
86
95
  - rlyeh.gemspec
96
+ - spec/rlyeh/numeric_reply_spec.rb
87
97
  - spec/rlyeh/server_spec.rb
98
+ - spec/rlyeh/settings_spec.rb
88
99
  - spec/spec_helper.rb
89
100
  homepage: ''
90
101
  licenses: []
@@ -98,15 +109,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
109
  - - ! '>='
99
110
  - !ruby/object:Gem::Version
100
111
  version: '0'
112
+ segments:
113
+ - 0
114
+ hash: -3713533615144336693
101
115
  required_rubygems_version: !ruby/object:Gem::Requirement
102
116
  none: false
103
117
  requirements:
104
118
  - - ! '>='
105
119
  - !ruby/object:Gem::Version
106
120
  version: '0'
121
+ segments:
122
+ - 0
123
+ hash: -3713533615144336693
107
124
  requirements: []
108
125
  rubyforge_project:
109
- rubygems_version: 1.8.10
126
+ rubygems_version: 1.8.17
110
127
  signing_key:
111
128
  specification_version: 3
112
129
  summary: IRC gateway server framework