rlyeh 0.0.1 → 0.0.2

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,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