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.
- data/.gitignore +1 -0
- data/examples/echo.rb +13 -0
- data/{example → examples}/middleware.rb +3 -1
- data/examples/simple.rb +20 -0
- data/lib/rlyeh/base.rb +14 -11
- data/lib/rlyeh/connection.rb +15 -15
- data/lib/rlyeh/deep_ones/auth.rb +72 -0
- data/lib/rlyeh/deep_ones/builder.rb +37 -0
- data/lib/rlyeh/deep_ones/closer.rb +18 -0
- data/lib/rlyeh/deep_ones/logger.rb +22 -0
- data/lib/rlyeh/deep_ones/parser.rb +21 -0
- data/lib/rlyeh/{middleware → deep_ones}/typablemap.rb +1 -1
- data/lib/rlyeh/deep_ones.rb +9 -0
- data/lib/rlyeh/dispatcher.rb +18 -10
- data/lib/rlyeh/environment.rb +16 -13
- data/lib/rlyeh/filters.rb +91 -0
- data/lib/rlyeh/numeric_reply.rb +206 -0
- data/lib/rlyeh/runner.rb +18 -1
- data/lib/rlyeh/sendable.rb +11 -0
- data/lib/rlyeh/server.rb +6 -9
- data/lib/rlyeh/session.rb +15 -15
- data/lib/rlyeh/settings.rb +35 -0
- data/lib/rlyeh/utils.rb +25 -0
- data/lib/rlyeh/version.rb +1 -1
- data/lib/rlyeh.rb +12 -8
- data/spec/rlyeh/numeric_reply_spec.rb +21 -0
- data/spec/rlyeh/settings_spec.rb +54 -0
- data/spec/spec_helper.rb +1 -1
- metadata +33 -16
- data/example/simple.rb +0 -16
- data/lib/rlyeh/filter.rb +0 -77
- data/lib/rlyeh/middleware/builder.rb +0 -31
data/.gitignore
CHANGED
data/examples/echo.rb
ADDED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# -*- coding: utf-8 -*-
|
3
|
-
$LOAD_PATH.unshift 'lib'
|
3
|
+
$LOAD_PATH.unshift 'lib', '../lib'
|
4
4
|
require 'rlyeh'
|
5
|
+
require 'logger'
|
5
6
|
|
6
7
|
class MyMiddleware
|
7
8
|
include Rlyeh::Dispatcher
|
@@ -21,6 +22,7 @@ class MyMiddleware
|
|
21
22
|
end
|
22
23
|
|
23
24
|
class MyApp < Rlyeh::Base
|
25
|
+
use Rlyeh::DeepOnes::Logger, :level => Logger::DEBUG
|
24
26
|
use MyMiddleware
|
25
27
|
|
26
28
|
on :privmsg do |env|
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
$LOAD_PATH.unshift 'lib', '../lib'
|
4
|
+
require 'rlyeh'
|
5
|
+
|
6
|
+
class MyApp < Rlyeh::Base
|
7
|
+
use Rlyeh::DeepOnes::Logger, :level => 0
|
8
|
+
use Rlyeh::DeepOnes::Auth do |auth|
|
9
|
+
auth.nick if [auth.nick, auth.pass] == ['dankogai', 'kogaidan']
|
10
|
+
end
|
11
|
+
|
12
|
+
set :server_name, 'MyApp'
|
13
|
+
set :server_version, '1.0.0'
|
14
|
+
|
15
|
+
on :privmsg do |env|
|
16
|
+
puts "RECV: #{env.message}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Rlyeh.emerge MyApp, :host => '0.0.0.0'
|
data/lib/rlyeh/base.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
require 'rlyeh/dispatcher'
|
2
|
-
require 'rlyeh/
|
2
|
+
require 'rlyeh/settings'
|
3
|
+
require 'rlyeh/deep_ones/builder'
|
4
|
+
require 'rlyeh/deep_ones/parser'
|
3
5
|
|
4
6
|
module Rlyeh
|
5
7
|
class Base
|
6
8
|
include Rlyeh::Dispatcher
|
9
|
+
include Rlyeh::Settings
|
10
|
+
|
11
|
+
set :server_name, 'Rlyeh'
|
12
|
+
set :server_version, Rlyeh::VERSION
|
7
13
|
|
8
14
|
class << self
|
9
15
|
def middlewares
|
@@ -23,11 +29,9 @@ module Rlyeh
|
|
23
29
|
|
24
30
|
alias new! new unless method_defined? :new!
|
25
31
|
def new(*args, &block)
|
26
|
-
build(Rlyeh::
|
32
|
+
build(Rlyeh::DeepOnes::Builder.new, *args, &block).to_app
|
27
33
|
end
|
28
34
|
|
29
|
-
private
|
30
|
-
|
31
35
|
def build(builder, *args, &block)
|
32
36
|
setup_default_middlewares builder
|
33
37
|
setup_middlewares builder
|
@@ -36,6 +40,8 @@ module Rlyeh
|
|
36
40
|
end
|
37
41
|
|
38
42
|
def setup_default_middlewares(builder)
|
43
|
+
builder.use! Rlyeh::DeepOnes::Closer
|
44
|
+
builder.use! Rlyeh::DeepOnes::Parser
|
39
45
|
end
|
40
46
|
|
41
47
|
def setup_middlewares(builder)
|
@@ -45,23 +51,20 @@ module Rlyeh
|
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
48
|
-
def initialize(app = nil)
|
54
|
+
def initialize(app = nil, options = {})
|
49
55
|
@app = app
|
56
|
+
@options = options
|
50
57
|
yield self if block_given?
|
51
58
|
end
|
52
59
|
|
53
60
|
def call(env)
|
54
61
|
name = env.message.command.to_s.downcase
|
55
62
|
trigger name, env
|
56
|
-
|
57
63
|
@app.call env if @app
|
58
64
|
end
|
59
65
|
|
60
|
-
def
|
61
|
-
|
62
|
-
callbacks.each do |callback|
|
63
|
-
callback.bind(self).call *args, &block
|
64
|
-
end
|
66
|
+
def halt
|
67
|
+
throw :halt
|
65
68
|
end
|
66
69
|
end
|
67
70
|
end
|
data/lib/rlyeh/connection.rb
CHANGED
@@ -1,23 +1,24 @@
|
|
1
|
-
require 'ircp'
|
2
1
|
require 'rlyeh/environment'
|
2
|
+
require 'rlyeh/filters'
|
3
|
+
require 'rlyeh/sendable'
|
3
4
|
|
4
5
|
module Rlyeh
|
5
6
|
class Connection < EventMachine::Connection
|
6
7
|
include EventMachine::Protocols::LineText2
|
8
|
+
include Rlyeh::Sendable
|
7
9
|
|
8
|
-
attr_reader :server, :
|
10
|
+
attr_reader :server, :app_class, :options
|
9
11
|
attr_reader :app, :session
|
10
12
|
|
11
|
-
def initialize(server,
|
13
|
+
def initialize(server, app_class, options)
|
12
14
|
@server = server
|
13
|
-
@
|
15
|
+
@app_class = app_class
|
14
16
|
@options = options
|
15
17
|
set_delimiter "\r\n"
|
16
18
|
end
|
17
19
|
|
18
20
|
def post_init
|
19
|
-
@app =
|
20
|
-
#@app = @app_class.new self, options
|
21
|
+
@app = app_class.new nil, @options
|
21
22
|
end
|
22
23
|
|
23
24
|
def unbind
|
@@ -26,30 +27,29 @@ module Rlyeh
|
|
26
27
|
|
27
28
|
def receive_line(data)
|
28
29
|
env = Rlyeh::Environment.new
|
30
|
+
env.data = data
|
31
|
+
env.server = @server
|
29
32
|
env.connection = self
|
30
|
-
env.
|
33
|
+
env.settings = @app_class.settings
|
31
34
|
|
32
|
-
|
33
|
-
env.message = Ircp.parse data
|
34
|
-
rescue Ircp::ParseError => e
|
35
|
-
p e
|
36
|
-
else
|
35
|
+
catch :halt do
|
37
36
|
@app.call env
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
41
40
|
def attached(session)
|
42
41
|
@session = session
|
43
|
-
#@app.attached session
|
44
42
|
end
|
45
43
|
|
46
|
-
def
|
47
|
-
#@app.detached session
|
44
|
+
def detached(session)
|
48
45
|
@session = nil
|
49
46
|
end
|
50
47
|
|
51
48
|
def attached?
|
52
49
|
!!@session
|
53
50
|
end
|
51
|
+
|
52
|
+
include Rlyeh::Filters
|
53
|
+
define_filters :attached, :detached
|
54
54
|
end
|
55
55
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'rlyeh/dispatcher'
|
3
|
+
|
4
|
+
module Rlyeh
|
5
|
+
module DeepOnes
|
6
|
+
class Auth
|
7
|
+
include Rlyeh::Dispatcher
|
8
|
+
|
9
|
+
attr_reader :nick, :pass, :user, :real, :host
|
10
|
+
|
11
|
+
def initialize(app, &authenticator)
|
12
|
+
@app = app
|
13
|
+
@authenticator = authenticator
|
14
|
+
@authorized = false
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
dispatch env
|
19
|
+
|
20
|
+
if authorized?
|
21
|
+
env.auth = self
|
22
|
+
@app.call env
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_session(env, id)
|
27
|
+
env.server.sessions[id] ||= Rlyeh::Session.new(id)
|
28
|
+
end
|
29
|
+
|
30
|
+
def authorized?
|
31
|
+
@authorized
|
32
|
+
end
|
33
|
+
|
34
|
+
def authorized(env)
|
35
|
+
name = env.settings.server_name
|
36
|
+
version = env.settings.server_version
|
37
|
+
|
38
|
+
env.connection.tap do |conn|
|
39
|
+
conn.send_numeric_reply :welcome, @host, "Welcome to the Internet Relay Network #{@nick}!#{@user}@#{@host}"
|
40
|
+
conn.send_numeric_reply :yourhost, @host, "Your host is #{name}, running version #{version}"
|
41
|
+
conn.send_numeric_reply :created, @host, "This server was created #{Time.now}"
|
42
|
+
conn.send_numeric_reply :myinfo, @host, "#{name} #{version} #{""} #{""}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
on :pass do |env|
|
47
|
+
@pass = env.message.params[0]
|
48
|
+
end
|
49
|
+
|
50
|
+
on :nick do |env|
|
51
|
+
@nick = env.message.params[0]
|
52
|
+
end
|
53
|
+
|
54
|
+
on :user do |env|
|
55
|
+
@user = env.message.params[0]
|
56
|
+
@real = env.message.params[3]
|
57
|
+
port, @host = Socket.unpack_sockaddr_in(env.connection.get_peername)
|
58
|
+
|
59
|
+
session_id = @authenticator.call(self)
|
60
|
+
if session_id.nil?
|
61
|
+
p "Auth error"
|
62
|
+
else
|
63
|
+
@authorized = true
|
64
|
+
session = load_session env, session_id
|
65
|
+
session.attach env.connection
|
66
|
+
authorized env
|
67
|
+
p 'Session attached.'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Rlyeh
|
2
|
+
module DeepOnes
|
3
|
+
class Builder
|
4
|
+
def initialize(app = nil, &block)
|
5
|
+
@stack = []
|
6
|
+
@runner = app
|
7
|
+
instance_eval(&block) if block_given?
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.app(app = nil, &block)
|
11
|
+
self.new(app, &block).to_app
|
12
|
+
end
|
13
|
+
|
14
|
+
def use(middleware, *args, &block)
|
15
|
+
@stack << proc { |app| middleware.new(app, *args, &block) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def use!(middleware, *args, &block)
|
19
|
+
@stack.unshift lambda { |app| middleware.new(app, *args, &block) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(app)
|
23
|
+
@runner = app
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_app
|
27
|
+
@stack.reverse.inject(@runner) do |inner, outer|
|
28
|
+
outer.call inner
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(env)
|
33
|
+
to_app.call(env)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rlyeh/dispatcher'
|
2
|
+
|
3
|
+
module Rlyeh
|
4
|
+
module DeepOnes
|
5
|
+
class Closer
|
6
|
+
include Rlyeh::Dispatcher
|
7
|
+
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
on :quit do |env|
|
13
|
+
env.connection.close_connection_after_writing
|
14
|
+
throw :halt
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Rlyeh
|
4
|
+
module DeepOnes
|
5
|
+
class Logger
|
6
|
+
def initialize(app, options = {})
|
7
|
+
@app = app
|
8
|
+
@logger = options[:logger] || ::Logger.new(STDOUT)
|
9
|
+
@logger.level = options[:level] || ::Logger::INFO
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
write env
|
14
|
+
@app.call env
|
15
|
+
end
|
16
|
+
|
17
|
+
def write(env)
|
18
|
+
@logger.debug env.data
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'ircp'
|
2
|
+
|
3
|
+
module Rlyeh
|
4
|
+
module DeepOnes
|
5
|
+
class Parser
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
begin
|
12
|
+
message = Ircp.parse env.data
|
13
|
+
env.message = message
|
14
|
+
@app.call env
|
15
|
+
rescue Ircp::ParseError => e
|
16
|
+
p e
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Rlyeh
|
2
|
+
module DeepOnes
|
3
|
+
autoload :Parser, 'rlyeh/deep_ones/parser'
|
4
|
+
autoload :Builder, 'rlyeh/deep_ones/builder'
|
5
|
+
autoload :Closer, 'rlyeh/deep_ones/closer'
|
6
|
+
autoload :Logger, 'rlyeh/deep_ones/logger'
|
7
|
+
autoload :Auth, 'rlyeh/deep_ones/auth'
|
8
|
+
end
|
9
|
+
end
|
data/lib/rlyeh/dispatcher.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rlyeh/utils'
|
2
|
+
|
1
3
|
module Rlyeh
|
2
4
|
module Dispatcher
|
3
5
|
def self.included(base)
|
@@ -7,7 +9,15 @@ module Rlyeh
|
|
7
9
|
module ClassMethods
|
8
10
|
def callbacks(name)
|
9
11
|
@dispatchers ||= {}
|
10
|
-
|
12
|
+
|
13
|
+
callbacks = @dispatchers.select do |key, value|
|
14
|
+
if key.is_a?(Regexp)
|
15
|
+
key =~ name
|
16
|
+
else
|
17
|
+
key == name
|
18
|
+
end
|
19
|
+
end.values.flatten
|
20
|
+
|
11
21
|
if superclass.respond_to?(:callbacks)
|
12
22
|
superclass.callbacks(name) + callbacks
|
13
23
|
else
|
@@ -17,18 +27,16 @@ module Rlyeh
|
|
17
27
|
|
18
28
|
def on(name, &block)
|
19
29
|
@dispatchers ||= {}
|
20
|
-
name = name.to_s
|
30
|
+
name = name.to_s if name.is_a?(Symbol)
|
21
31
|
callbacks = (@dispatchers[name] ||= [])
|
22
|
-
callbacks << generate_method(name,
|
32
|
+
callbacks << Rlyeh::Utils.generate_method(self, "__on_#{name}", block)
|
23
33
|
callbacks.uniq!
|
24
34
|
end
|
35
|
+
end
|
25
36
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
remove_method method_name
|
30
|
-
method
|
31
|
-
end
|
37
|
+
def call(env)
|
38
|
+
dispatch env
|
39
|
+
@app.call env if @app
|
32
40
|
end
|
33
41
|
|
34
42
|
def dispatch(env)
|
@@ -39,7 +47,7 @@ module Rlyeh
|
|
39
47
|
def trigger(name, *args, &block)
|
40
48
|
callbacks = self.class.callbacks name
|
41
49
|
callbacks.each do |callback|
|
42
|
-
callback.bind(self).call
|
50
|
+
break if callback.bind(self).call(*args, &block) == false
|
43
51
|
end
|
44
52
|
end
|
45
53
|
end
|
data/lib/rlyeh/environment.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
module Rlyeh
|
2
2
|
class Environment < ::Hash
|
3
|
-
def
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
def respond_to?(method_id, include_private = false)
|
4
|
+
super || respond_to_missing?(method_id, include_private)
|
5
|
+
end
|
6
|
+
|
7
|
+
def respond_to_missing?(method_name, include_private)
|
8
|
+
method_name = method_id.to_s
|
9
|
+
return true if method_name =~ /^(.+)=$/
|
10
|
+
return true if self.key? method_name
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method_id, *args, &block)
|
15
|
+
method_name = method_id.to_s
|
16
|
+
return self[$1] = args.first if method_name =~ /^(.+)=$/
|
17
|
+
return self[method_name] if self.key? method_name
|
18
|
+
super method_id, *args, &block
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'rlyeh/utils'
|
2
|
+
|
3
|
+
module Rlyeh
|
4
|
+
module Filters
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def define_filters(*names, &block)
|
11
|
+
names.each do |name|
|
12
|
+
unless method_defined?("#{name}_with_filters")
|
13
|
+
define_method(:"#{name}_with_filters") do |*args, &block|
|
14
|
+
run_filters name, *args do
|
15
|
+
send(:"#{name}_without_filters", *args, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
alias_method :"#{name}_without_filters", :"#{name}"
|
19
|
+
alias_method :"#{name}", :"#{name}_with_filters"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_filters(name, *args, &block)
|
26
|
+
catch :halt do
|
27
|
+
_run_filters name, [:before, :arround], *args
|
28
|
+
result = block.call *args if block
|
29
|
+
_run_filters name, [:arround, :after], *args
|
30
|
+
result
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
[:before, :after, :around].each do |type|
|
35
|
+
define_method(:"#{type}_filter") do |*names, &block|
|
36
|
+
_insert_filter(names, type, block)
|
37
|
+
end
|
38
|
+
alias_method :"append_#{type}_filter", :"#{type}_filter"
|
39
|
+
|
40
|
+
define_method(:"prepend_#{type}_filter") do |*names, &block|
|
41
|
+
_insert_filter(names, type, block, :prepend => true)
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method(:"remove_#{type}_filter") do |*names, &block|
|
45
|
+
_remove_filter(names, type, block)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def _filters
|
52
|
+
@_filters ||= {}
|
53
|
+
end
|
54
|
+
|
55
|
+
def _run_filters(name, types, *args, &block)
|
56
|
+
named_filters = _filters[name.to_s] || {}
|
57
|
+
types.each do |type|
|
58
|
+
(named_filters[type.to_s] || []).each do |filter|
|
59
|
+
throw :halt if filter.bind(self).call(*args, &block) == false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def _generate_filter_method(name, type, block)
|
65
|
+
method_name = "__filter_#{type}_#{name}"
|
66
|
+
Rlyeh::Utils.generate_method(Rlyeh::Utils.singleton_class(self), method_name, block)
|
67
|
+
end
|
68
|
+
|
69
|
+
def _insert_filter(names, type, block, options = {})
|
70
|
+
prepend = options[:prepend]
|
71
|
+
names.each do |name|
|
72
|
+
filter = _generate_filter_method name, type, block
|
73
|
+
named_filters = (_filters[name.to_s] ||= {})
|
74
|
+
filters = (named_filters[type.to_s] ||= [])
|
75
|
+
if prepend
|
76
|
+
filters.unshift filter
|
77
|
+
else
|
78
|
+
filters.push filter
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def _remove_filter(names, type, block)
|
84
|
+
names.each do |name|
|
85
|
+
named_filters = (_filters[name.to_s] ||= {})
|
86
|
+
filters = (named_filters[type.to_s] ||= [])
|
87
|
+
filters.delete block
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|