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