rlyeh 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ vendor
data/examples/echo.rb ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ $LOAD_PATH.unshift 'lib', '../lib'
4
+ require 'rlyeh'
5
+
6
+ class Echo < Rlyeh::Base
7
+ def call(env)
8
+ conn = env.connection
9
+ conn.send_data env.message
10
+ end
11
+ end
12
+
13
+ Rlyeh.emerge Echo
@@ -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|
@@ -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/middleware/builder'
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::Middleware::Builder.new, *args, &block).to_app
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 trigger(name, *args, &block)
61
- callbacks = self.class.callbacks name
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
@@ -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, :klass, :options
10
+ attr_reader :server, :app_class, :options
9
11
  attr_reader :app, :session
10
12
 
11
- def initialize(server, klass, options)
13
+ def initialize(server, app_class, options)
12
14
  @server = server
13
- @klass = klass
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 = klass.new
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.raw = data
33
+ env.settings = @app_class.settings
31
34
 
32
- begin
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 deatched(session)
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
@@ -1,5 +1,5 @@
1
1
  module Rlyeh
2
- module Middleware
2
+ module DeepOnes
3
3
  class TypableMap
4
4
  def initialize(app)
5
5
  @app = app
@@ -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
@@ -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
- callbacks = @dispatchers[name] || []
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, &block)
32
+ callbacks << Rlyeh::Utils.generate_method(self, "__on_#{name}", block)
23
33
  callbacks.uniq!
24
34
  end
35
+ end
25
36
 
26
- def generate_method(method_name, &block)
27
- define_method method_name, &block
28
- method = instance_method method_name
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 *args, &block
50
+ break if callback.bind(self).call(*args, &block) == false
43
51
  end
44
52
  end
45
53
  end
@@ -1,18 +1,21 @@
1
1
  module Rlyeh
2
2
  class Environment < ::Hash
3
- def method_missing(method_id, *args)
4
- case method_id.to_s
5
- when /^(.+)=$/
6
- store $1.to_sym, args.first
7
- when /^(.+)\?$/
8
- key? $1.to_sym
9
- else
10
- unless key? method_id
11
- store method_id, Environment.new
12
- else
13
- fetch method_id
14
- end
15
- end
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