rack-golem 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ >Made of consonants and vowels,
2
+ >there is a terrible Name,
3
+ >that in its essence encodes God’s all,
4
+ >power, guarded in letters, in hidden syllables. -- Jorge Luis Borges
5
+
6
+ GOLEM
7
+ =====
8
+
9
+ I would describe Golem as a Ramaze for kids.
10
+ Golem is not a framework though, just a controller, but you know... the kind of controller that leaves you in the train
11
+ even if you did not buy a ticket.
12
+ It leaves you on the rails if you will (incredibly good pun intended).
13
+
14
+ Install with:
15
+
16
+ sudo gem install rack-golem
17
+
18
+ Config.ru is one of his names, so say it in a Rackup file.
19
+
20
+ require 'db' # Loads ORM models and all
21
+ require 'go' # Our controller (I don not like that word really)
22
+ use Rack::ContentLength
23
+ use Rack::Session::Cookies
24
+ run Go
25
+
26
+ And the winner is:
27
+
28
+ require 'rack/golem'
29
+
30
+ class Go
31
+ include Rack::Golem # To hell with sub-classes !!!
32
+
33
+ before do
34
+ # Here you can do many things
35
+ # In order to help you here are some variables you can read and override:
36
+ # @r => the Rack::Request object
37
+ # @res => the Rack::Response object
38
+ # @action => Name of the public method that will handle the request
39
+ # @action_arguments => Arguments for the action (really?)
40
+ end
41
+
42
+ def index(*args)
43
+ # When no public method is found
44
+ # Of course you don't have to declare one and it is gonna use Controller#not_found instead
45
+ # But if it is declared, keep in mind it's a catch-all so make it deal with args
46
+ @articles = Post.all
47
+ erb :index
48
+ end
49
+
50
+ def post(id=nil)
51
+ @post = Post[id]
52
+ if @post.nil?
53
+ not_found
54
+ else
55
+ erb :post
56
+ end
57
+ end
58
+
59
+ def say(listener='me', *words)
60
+ "Hey #{listener} I don't need ERB to tell you that #{words.join(' ')}"
61
+ end
62
+
63
+ def not_found(*args)
64
+ # This one is defined by Golem but here we decided to override it
65
+ # Like :index this method receives the arguments in order to make something with it
66
+ Email.alert('Too many people are looking for porn here') if args.includes?("porn")
67
+ super(args)
68
+ end
69
+
70
+ after do
71
+ Spy.analyse.send_info_to([:government, :facebook, :google, :james_bond])
72
+ end
73
+
74
+ end
75
+
76
+ Hopefully no headache.
77
+
78
+ WHAT GOLEM DOES NOT
79
+ ===================
80
+
81
+ - Support templates other than ERB (I plan to use Tilt more cleverly though in order to achieve that without selling my soul)
82
+ - Session/Cookies administration (Like for many things, use a middleware instead ex: Rack::Session::Cookies)
83
+ - Prepare the coffee (Emacs does but Ed is the standard text editor)
84
+ - So many things, why bother...
data/lib/rack/golem.rb ADDED
@@ -0,0 +1,65 @@
1
+ module Rack::Golem
2
+
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+ extend ClassMethods
6
+ include InstanceMethods
7
+ end
8
+ end
9
+
10
+ module ClassMethods
11
+ attr_reader :before_block, :after_block
12
+ def before(&block); @before_block = block; end
13
+ def after(&block); @after_block = block; end
14
+ def dispatcher(&block); @dispatcher_block = block; end
15
+ def dispatcher_block
16
+ @dispatcher_block || proc{
17
+ @path_atoms = @r.path_info.split('/').find_all{|s| s!=''}
18
+ @action, *@action_arguments = @path_atoms
19
+ unless public_methods.include?(@action)
20
+ if public_methods.include?('index')
21
+ @action, @action_arguments = 'index', @path_atoms
22
+ else
23
+ @action, @action_arguments = 'not_found', @path_atoms
24
+ end
25
+ end
26
+
27
+ instance_eval(&self.class.before_block) unless self.class.before_block.nil?
28
+
29
+ @res.write(self.__send__(@action,*@action_arguments))
30
+
31
+ instance_eval(&self.class.after_block) unless self.class.after_block.nil?
32
+ }
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ def initialize(app=nil); @app = app; end
38
+ def call(env); dup.call!(env); end
39
+ def call!(env)
40
+ @r = ::Rack::Request.new(env)
41
+ @res = ::Rack::Response.new
42
+ instance_eval(&self.class.dispatcher_block)
43
+ @res.status==404&&!@app.nil? ? @app.call(env) : @res.finish
44
+ end
45
+ def not_found(*args)
46
+ @res.status = 404
47
+ @res.headers['X-Cascade']='pass'
48
+ "Not Found: #{@r.path_info}"
49
+ end
50
+ def erb(template)
51
+ @@tilt_cache ||= {}
52
+ if @@tilt_cache.has_key?(template)
53
+ template_obj = @@tilt_cache[template]
54
+ else
55
+ erb_extention = @r.env['erb.extention'] || ".erb"
56
+ views_location = @r.env['erb.location'] || ::Dir.pwd+'/views/'
57
+ views_location << '/' unless views_location[-1]==?/
58
+ template_obj = Tilt.new("#{views_location}#{template}#{erb_extention}")
59
+ @@tilt_cache.store(template,template_obj) if ENV['RACK_ENV']=='production'
60
+ end
61
+ template_obj.render(self)
62
+ end
63
+ end
64
+
65
+ end
data/lib/rack_golem.rb ADDED
@@ -0,0 +1 @@
1
+ require 'rack/golem'
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'rack-golem'
3
+ s.version = "0.0.1"
4
+ s.platform = Gem::Platform::RUBY
5
+ s.summary = "A Controller middleware that is euh... basic"
6
+ s.description = "A Controller middleware that is euh... basic. I would say it is a sort of Ramaze for kids"
7
+ s.files = `git ls-files`.split("\n").sort
8
+ s.require_path = './lib'
9
+ s.author = "Mickael Riga"
10
+ s.email = "mig@campbellhay.com"
11
+ s.homepage = "http://www.campbellhay.com"
12
+ end
@@ -0,0 +1,95 @@
1
+ require 'rubygems'
2
+ require 'bacon'
3
+ require 'rack'
4
+ require 'rack/lobster'
5
+ require 'fileutils' # fix Rack missing
6
+
7
+ Bacon.summary_on_exit
8
+
9
+ # Helpers
10
+ F = ::File
11
+ D = ::Dir
12
+ ROOT = F.dirname(__FILE__)+'/..'
13
+ $:.unshift ROOT+'/lib'
14
+ require 'rack/golem'
15
+
16
+ # =========
17
+ # = Basic =
18
+ # =========
19
+
20
+ class Basic
21
+ include Rack::Golem
22
+ def no_arg; 'nothing'; end
23
+ def with_args(a,b); '%s+%s' % [a,b]; end
24
+ def splat_arg(*a); a.join('+'); end
25
+ private
26
+ def no_way; 'This is private'; end
27
+ end
28
+ BasicR = ::Rack::MockRequest.new(::Rack::Lint.new(Basic.new))
29
+ BasicLobsterR = ::Rack::MockRequest.new(::Rack::Lint.new(Basic.new(::Rack::Lobster.new)))
30
+
31
+ # ==========
32
+ # = Filter =
33
+ # ==========
34
+
35
+ class Filter
36
+ include Rack::Golem
37
+ before{@res.write @action=='not_found' ? @action_arguments.join('+') : 'before+'}
38
+ after{@res.write '+after'}
39
+ def wrapped; 'wrapped'; end
40
+ end
41
+ FilterR = ::Rack::MockRequest.new(::Rack::Lint.new(Filter.new))
42
+
43
+ # ===========
44
+ # = Indexed =
45
+ # ===========
46
+
47
+ class Indexed
48
+ include Rack::Golem
49
+ before{ @res.write("action=#{@action} args=#{@action_arguments.join(',')} ") if @r['switch']=='true' }
50
+ def index(*a); a.join('+'); end
51
+ def exist(*a); a.join('+'); end
52
+ end
53
+ IndexedR = ::Rack::MockRequest.new(::Rack::Lint.new(Indexed.new))
54
+
55
+ # =========
56
+ # = Specs =
57
+ # =========
58
+
59
+ describe "Golem" do
60
+ it "Should dispatch on a method with no arguments" do
61
+ BasicR.get('/no_arg').body.should=='nothing'
62
+ end
63
+ it "Should dispatch on a method with arguments" do
64
+ BasicR.get('/with_args/a/b').body.should=='a+b'
65
+ end
66
+ it "Should dispatch on a method with splat argument" do
67
+ BasicR.get('/splat_arg/a/b/c/d').body.should=='a+b+c+d'
68
+ end
69
+ it "Should not dispatch if the method is private or does not exist" do
70
+ r = BasicR.get('/no_way')
71
+ r.status.should==404
72
+ r.body.should=='Not Found: /no_way'
73
+ r = BasicR.get('/no')
74
+ r.status.should==404
75
+ r.body.should=='Not Found: /no'
76
+ end
77
+ it "Should follow the rack stack if response is 404 and there are middlewares below" do
78
+ r = BasicLobsterR.get("/no_way")
79
+ r.status.should==200
80
+ end
81
+ it "Should provide filters" do
82
+ FilterR.get('/wrapped').body.should=="before+wrapped+after"
83
+ end
84
+ it "Should provide arguments in filter when page is not_found" do
85
+ FilterR.get('/a/b/c/d').body.should=="a+b+c+dNot Found: /a/b/c/d+after"
86
+ end
87
+ it "Should send everything to :index if it exists and there is no matching method for first arg" do
88
+ IndexedR.get('/exist/a/b/c/d').body.should=='a+b+c+d'
89
+ Indexed.new.public_methods.include?(:index)
90
+ IndexedR.get('/a/b/c/d').body.should=='a+b+c+d'
91
+ end
92
+ it "Should set dispatch-specific variables correctly when defaulting to :index" do
93
+ IndexedR.get('/a/b/c/d?switch=true').body.should=="action=index args=a,b,c,d a+b+c+d"
94
+ end
95
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-golem
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Mickael Riga
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-09-22 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: A Controller middleware that is euh... basic. I would say it is a sort of Ramaze for kids
23
+ email: mig@campbellhay.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - README.md
32
+ - lib/rack/golem.rb
33
+ - lib/rack_golem.rb
34
+ - rack-golem.gemspec
35
+ - test/spec_golem.rb
36
+ has_rdoc: true
37
+ homepage: http://www.campbellhay.com
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - ./lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.4.2
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: A Controller middleware that is euh... basic
70
+ test_files: []
71
+