junior 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/LICENSE +20 -0
- data/README +21 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/junior.gemspec +75 -0
- data/lib/junior/application.rb +121 -0
- data/lib/junior/controller.rb +55 -0
- data/lib/junior/dispatcher.rb +70 -0
- data/lib/junior/helpers.rb +111 -0
- data/lib/junior/request.rb +12 -0
- data/lib/junior/router.rb +36 -0
- data/lib/junior/support.rb +23 -0
- data/lib/junior.rb +16 -0
- data/spec/junior_spec.rb +7 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- data/tasks/spec.rake +16 -0
- data/tasks/yard.rake +9 -0
- metadata +124 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Michael Wood.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= Junior
|
2
|
+
|
3
|
+
An MVC Web Framework
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
sudo gem install junior
|
8
|
+
|
9
|
+
== Note on Patches/Pull Requests
|
10
|
+
|
11
|
+
* Fork the project.
|
12
|
+
* Make your feature addition or bug fix.
|
13
|
+
* Add tests for it. This is important so I don't break it in a
|
14
|
+
future version unintentionally.
|
15
|
+
* Commit, do not mess with rakefile, version, or history.
|
16
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
17
|
+
* Send me a pull request. Bonus points for topic branches.
|
18
|
+
|
19
|
+
== Copyright
|
20
|
+
|
21
|
+
Copyright (c) 2010 Michael Wood. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "junior"
|
8
|
+
gem.summary = 'An MVC Web Framework'
|
9
|
+
gem.description = 'A Mini MVC Web Framework for Ruby built on Rack and a lot of inspiration from Sinatra'
|
10
|
+
gem.email = 'mike@michaelwood.com'
|
11
|
+
gem.homepage = 'http://github.com/eddanger/junior'
|
12
|
+
gem.authors = ["Michael Wood"]
|
13
|
+
|
14
|
+
gem.add_dependency 'rack', "~> 1.0.1"
|
15
|
+
gem.add_dependency 'rack-mount', "~> 0.4.0"
|
16
|
+
gem.add_dependency 'tilt', "~> 0.4.0"
|
17
|
+
|
18
|
+
gem.add_development_dependency 'rspec', '~> 1.2.9'
|
19
|
+
gem.add_development_dependency 'yard', '~> 0.5.2'
|
20
|
+
end
|
21
|
+
Jeweler::GemcutterTasks.new
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
24
|
+
end
|
25
|
+
|
26
|
+
FileList['tasks/**/*.rake'].each { |task| load task }
|
27
|
+
|
28
|
+
task :spec => :check_dependencies
|
29
|
+
|
30
|
+
task :default => :spec
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/junior.gemspec
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{junior}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Michael Wood"]
|
12
|
+
s.date = %q{2009-12-31}
|
13
|
+
s.description = %q{A Mini MVC Web Framework for Ruby built on Rack and a lot of inspiration from Sinatra}
|
14
|
+
s.email = %q{mike@michaelwood.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE",
|
22
|
+
"README",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"junior.gemspec",
|
26
|
+
"lib/junior.rb",
|
27
|
+
"lib/junior/application.rb",
|
28
|
+
"lib/junior/controller.rb",
|
29
|
+
"lib/junior/dispatcher.rb",
|
30
|
+
"lib/junior/helpers.rb",
|
31
|
+
"lib/junior/request.rb",
|
32
|
+
"lib/junior/router.rb",
|
33
|
+
"lib/junior/support.rb",
|
34
|
+
"spec/junior_spec.rb",
|
35
|
+
"spec/spec.opts",
|
36
|
+
"spec/spec_helper.rb",
|
37
|
+
"tasks/spec.rake",
|
38
|
+
"tasks/yard.rake"
|
39
|
+
]
|
40
|
+
s.homepage = %q{http://github.com/eddanger/junior}
|
41
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = %q{1.3.5}
|
44
|
+
s.summary = %q{An MVC Web Framework}
|
45
|
+
s.test_files = [
|
46
|
+
"spec/junior_spec.rb",
|
47
|
+
"spec/spec_helper.rb"
|
48
|
+
]
|
49
|
+
|
50
|
+
if s.respond_to? :specification_version then
|
51
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
52
|
+
s.specification_version = 3
|
53
|
+
|
54
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_runtime_dependency(%q<rack>, ["~> 1.0.1"])
|
56
|
+
s.add_runtime_dependency(%q<rack-mount>, ["~> 0.4.0"])
|
57
|
+
s.add_runtime_dependency(%q<tilt>, ["~> 0.4.0"])
|
58
|
+
s.add_development_dependency(%q<rspec>, ["~> 1.2.9"])
|
59
|
+
s.add_development_dependency(%q<yard>, ["~> 0.5.2"])
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<rack>, ["~> 1.0.1"])
|
62
|
+
s.add_dependency(%q<rack-mount>, ["~> 0.4.0"])
|
63
|
+
s.add_dependency(%q<tilt>, ["~> 0.4.0"])
|
64
|
+
s.add_dependency(%q<rspec>, ["~> 1.2.9"])
|
65
|
+
s.add_dependency(%q<yard>, ["~> 0.5.2"])
|
66
|
+
end
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<rack>, ["~> 1.0.1"])
|
69
|
+
s.add_dependency(%q<rack-mount>, ["~> 0.4.0"])
|
70
|
+
s.add_dependency(%q<tilt>, ["~> 0.4.0"])
|
71
|
+
s.add_dependency(%q<rspec>, ["~> 1.2.9"])
|
72
|
+
s.add_dependency(%q<yard>, ["~> 0.5.2"])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Junior
|
2
|
+
|
3
|
+
class Application
|
4
|
+
|
5
|
+
attr_accessor :app, :env, :request, :response
|
6
|
+
|
7
|
+
def initialize(app = nil)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
dup.call!(env)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call!(env)
|
16
|
+
@env = env
|
17
|
+
#@request = Rack::Request.new(env)
|
18
|
+
@request = Junior::Request.new(env)
|
19
|
+
@response = Rack::Response.new
|
20
|
+
|
21
|
+
Dispatcher.dispatch!(self)
|
22
|
+
|
23
|
+
status, header, body = @response.finish
|
24
|
+
|
25
|
+
[status, header, body]
|
26
|
+
end
|
27
|
+
|
28
|
+
class << self
|
29
|
+
|
30
|
+
def reset!
|
31
|
+
@middleware = []
|
32
|
+
@resources = []
|
33
|
+
@routes = []
|
34
|
+
@prototype = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def router
|
38
|
+
Router.router(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
def prototype
|
42
|
+
@prototype ||= new
|
43
|
+
end
|
44
|
+
|
45
|
+
def new(*args, &bk)
|
46
|
+
builder = Rack::Builder.new
|
47
|
+
|
48
|
+
middleware.each { |middleware, args, block| builder.use(middleware, *args, &block) }
|
49
|
+
|
50
|
+
builder.run super
|
51
|
+
builder.to_app
|
52
|
+
end
|
53
|
+
|
54
|
+
def call(env)
|
55
|
+
prototype.call(env)
|
56
|
+
end
|
57
|
+
|
58
|
+
def development?; environment == :development end
|
59
|
+
def production?; environment == :production end
|
60
|
+
def test?; environment == :test end
|
61
|
+
|
62
|
+
def middleware
|
63
|
+
if superclass.respond_to?(:middleware)
|
64
|
+
superclass.middleware + ( @middleware || [] )
|
65
|
+
else
|
66
|
+
@middleware || []
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def resources
|
71
|
+
@resources || []
|
72
|
+
end
|
73
|
+
|
74
|
+
def routes
|
75
|
+
@routes || []
|
76
|
+
end
|
77
|
+
|
78
|
+
def use(middleware, *args, &block)
|
79
|
+
@middleware << [ middleware, args, block ]
|
80
|
+
end
|
81
|
+
|
82
|
+
def resource(resource)
|
83
|
+
@resources << resource
|
84
|
+
end
|
85
|
+
|
86
|
+
def route(path, to = {}, method = 'GET')
|
87
|
+
@routes << { :path => path, :to => to, :method => method }
|
88
|
+
end
|
89
|
+
|
90
|
+
def set(option, value=self)
|
91
|
+
if value.kind_of?(Proc)
|
92
|
+
metadef(option, &value)
|
93
|
+
metadef("#{option}?") { !!__send__(option) }
|
94
|
+
metadef("#{option}=") { |val| set(option, Proc.new{val}) }
|
95
|
+
elsif value == self && option.respond_to?(:to_hash)
|
96
|
+
option.to_hash.each { |k,v| set(k, v) }
|
97
|
+
elsif respond_to?("#{option}=")
|
98
|
+
__send__ "#{option}=", value
|
99
|
+
else
|
100
|
+
set option, Proc.new{value}
|
101
|
+
end
|
102
|
+
self
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def inherited(subclass)
|
108
|
+
subclass.reset!
|
109
|
+
super
|
110
|
+
end
|
111
|
+
|
112
|
+
def metadef(message, &block)
|
113
|
+
(class << self; self; end).
|
114
|
+
send :define_method, message, &block
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
set :environment, (ENV['RACK_ENV'] || :development).to_sym
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Junior
|
2
|
+
|
3
|
+
class Controller
|
4
|
+
|
5
|
+
include Junior::Helpers
|
6
|
+
|
7
|
+
attr_accessor :env, :response, :request, :params, :layout_path
|
8
|
+
|
9
|
+
def initialize(app = nil, id = nil)
|
10
|
+
@env = app.env
|
11
|
+
@response = app.response
|
12
|
+
@request = app.request
|
13
|
+
@params = @request.params
|
14
|
+
|
15
|
+
@resource_id = id
|
16
|
+
end
|
17
|
+
|
18
|
+
def render(path)
|
19
|
+
begin
|
20
|
+
template = Tilt.new(path)
|
21
|
+
|
22
|
+
output = template.render(self)
|
23
|
+
|
24
|
+
if self.class.layout_path
|
25
|
+
layout_template = Tilt.new(self.class.layout_path)
|
26
|
+
output = layout_template.render(self) { output }
|
27
|
+
end
|
28
|
+
|
29
|
+
response.body = output
|
30
|
+
response.status = 200
|
31
|
+
rescue Exception => exception
|
32
|
+
error(500, "#{exception}")
|
33
|
+
end
|
34
|
+
|
35
|
+
output
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
|
40
|
+
attr_reader :layout_path
|
41
|
+
|
42
|
+
def layout(layout_path = nil)
|
43
|
+
@layout_path = layout_path
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def inherited(subclass)
|
49
|
+
super
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Junior
|
2
|
+
|
3
|
+
class Dispatcher
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def dispatch!(app)
|
8
|
+
@env = app.env
|
9
|
+
@response = app.response
|
10
|
+
@request = app.request
|
11
|
+
|
12
|
+
invoke do
|
13
|
+
response = app.response
|
14
|
+
|
15
|
+
#puts app.env['rack.input'].read
|
16
|
+
|
17
|
+
controller = app.env[ 'rack.routing_args' ][ :controller ].to_s
|
18
|
+
action = app.env[ 'rack.routing_args' ][ :action ].to_s
|
19
|
+
id = app.env[ 'rack.routing_args' ][ :id ].to_s
|
20
|
+
|
21
|
+
controller_instance = controller.camelize.to_class.new(app, id)
|
22
|
+
|
23
|
+
if controller_instance.respond_to?(action)
|
24
|
+
controller_instance.send(action)
|
25
|
+
else
|
26
|
+
not_found('Not found')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# Run the block with 'throw :halt' support and apply result to the response.
|
33
|
+
def invoke(&block)
|
34
|
+
res = catch(:halt) { instance_eval(&block) }
|
35
|
+
return if res.nil?
|
36
|
+
|
37
|
+
case
|
38
|
+
when res.respond_to?(:to_str)
|
39
|
+
@response.body = [res]
|
40
|
+
when res.respond_to?(:to_ary)
|
41
|
+
res = res.to_ary
|
42
|
+
if Fixnum === res.first
|
43
|
+
if res.length == 3
|
44
|
+
@response.status, headers, body = res
|
45
|
+
@response.body = body if body
|
46
|
+
headers.each { |k, v| @response.headers[k] = v } if headers
|
47
|
+
elsif res.length == 2
|
48
|
+
@response.status = res.first
|
49
|
+
@response.body = res.last
|
50
|
+
else
|
51
|
+
raise TypeError, "#{res.inspect} not supported"
|
52
|
+
end
|
53
|
+
else
|
54
|
+
@response.body = res
|
55
|
+
end
|
56
|
+
when res.respond_to?(:each)
|
57
|
+
@response.body = res
|
58
|
+
when (100...599) === res
|
59
|
+
@response.status = res
|
60
|
+
end
|
61
|
+
|
62
|
+
res
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Junior
|
2
|
+
|
3
|
+
# Methods available to routes, before/after filters, and views.
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
# Exit the current block, halts any further processing
|
7
|
+
# of the request, and returns the specified response.
|
8
|
+
def halt(*response)
|
9
|
+
response = response.first if response.length == 1
|
10
|
+
throw :halt, response
|
11
|
+
end
|
12
|
+
|
13
|
+
# Set or retrieve the response status code.
|
14
|
+
def status(value=nil)
|
15
|
+
response.status = value if value
|
16
|
+
response.status
|
17
|
+
end
|
18
|
+
|
19
|
+
# Set or retrieve the response body. When a block is given,
|
20
|
+
# evaluation is deferred until the body is read with #each.
|
21
|
+
def body(value=nil, &block)
|
22
|
+
if block_given?
|
23
|
+
def block.each ; yield call ; end
|
24
|
+
response.body = block
|
25
|
+
else
|
26
|
+
response.body = value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Halt processing and redirect to the URI provided.
|
31
|
+
def redirect(uri, *args)
|
32
|
+
status 302
|
33
|
+
response['Location'] = uri
|
34
|
+
halt(*args)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Halt processing and return the error status provided.
|
38
|
+
def error(code, body=nil)
|
39
|
+
code, body = 500, code.to_str if code.respond_to? :to_str
|
40
|
+
response.body = body unless body.nil?
|
41
|
+
halt code
|
42
|
+
end
|
43
|
+
|
44
|
+
# Halt processing and return a 404 Not Found.
|
45
|
+
def not_found(body=nil)
|
46
|
+
error 404, body
|
47
|
+
end
|
48
|
+
|
49
|
+
# Set multiple response headers with Hash.
|
50
|
+
def headers(hash=nil)
|
51
|
+
response.headers.merge! hash if hash
|
52
|
+
response.headers
|
53
|
+
end
|
54
|
+
|
55
|
+
# Access the underlying Rack session.
|
56
|
+
def session
|
57
|
+
env['rack.session'] ||= {}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Look up a media type by file extension in Rack's mime registry.
|
61
|
+
def mime_type(type)
|
62
|
+
Rack::Mime.mime_type(type)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set the Content-Type of the response body given a media type or file
|
66
|
+
# extension.
|
67
|
+
def content_type(type, params={})
|
68
|
+
mime_type = self.mime_type(type)
|
69
|
+
fail "Unknown media type: %p" % type if mime_type.nil?
|
70
|
+
if params.any?
|
71
|
+
params = params.collect { |kv| "%s=%s" % kv }.join(', ')
|
72
|
+
response['Content-Type'] = [mime_type, params].join(";")
|
73
|
+
else
|
74
|
+
response['Content-Type'] = mime_type
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Set the Content-Disposition to "attachment" with the specified filename,
|
79
|
+
# instructing the user agents to prompt to save.
|
80
|
+
def attachment(filename=nil)
|
81
|
+
response['Content-Disposition'] = 'attachment'
|
82
|
+
if filename
|
83
|
+
params = '; filename="%s"' % File.basename(filename)
|
84
|
+
response['Content-Disposition'] << params
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Use the contents of the file at +path+ as the response body.
|
89
|
+
def send_file(path, opts={})
|
90
|
+
stat = File.stat(path)
|
91
|
+
last_modified stat.mtime
|
92
|
+
|
93
|
+
content_type mime_type(opts[:type]) ||
|
94
|
+
mime_type(File.extname(path)) ||
|
95
|
+
response['Content-Type'] ||
|
96
|
+
'application/octet-stream'
|
97
|
+
|
98
|
+
response['Content-Length'] ||= (opts[:length] || stat.size).to_s
|
99
|
+
|
100
|
+
if opts[:disposition] == 'attachment' || opts[:filename]
|
101
|
+
attachment opts[:filename] || path
|
102
|
+
elsif opts[:disposition] == 'inline'
|
103
|
+
response['Content-Disposition'] = 'inline'
|
104
|
+
end
|
105
|
+
|
106
|
+
halt StaticFile.open(path, 'rb')
|
107
|
+
rescue Errno::ENOENT
|
108
|
+
not_found
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Junior
|
2
|
+
|
3
|
+
class Router
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def router( app )
|
8
|
+
router = Rack::Mount::RouteSet.new do |set|
|
9
|
+
app.resources.each do |resource|
|
10
|
+
set.add_route app, { :path_info => %r{^/#{resource}(\.(?:<format>[a-z]+))?$}, :request_method => 'GET' }, { :controller => resource, :action => 'index' }
|
11
|
+
set.add_route app, { :path_info => %r{^/#{resource}(\.(?:<format>[a-z]+))?$}, :request_method => 'POST' }, { :controller => resource, :action => 'create' }
|
12
|
+
set.add_route app, { :path_info => %r{^/#{resource}/new(\.(?:<format>[a-z]+))?$}, :request_method => 'GET' }, { :controller => resource, :action => 'new' }
|
13
|
+
set.add_route app, { :path_info => %r{^/#{resource}/(?:<id>[^/]+)/edit(\.(?:<format>[a-z]+))?$}, :request_method => 'GET' }, { :controller => resource, :action => 'edit' }
|
14
|
+
set.add_route app, { :path_info => %r{^/#{resource}/(?:<id>[^/]+)/delete(\.(?:<format>[a-z]+))?$}, :request_method => 'GET' }, { :controller => resource, :action => 'delete' }
|
15
|
+
set.add_route app, { :path_info => %r{^/#{resource}/(?:<id>[^/]+)(\.(?:<format>[a-z]+))?$}, :request_method => 'GET' }, { :controller => resource, :action => 'show' }
|
16
|
+
set.add_route app, { :path_info => %r{^/#{resource}/(?:<id>[^/]+)(\.(?:<format>[a-z]+))?$}, :request_method => 'PUT' }, { :controller => resource, :action => 'update' }
|
17
|
+
set.add_route app, { :path_info => %r{^/#{resource}/(?:<id>[^/]+)(\.(?:<format>[a-z]+))?$}, :request_method => 'DELETE' }, { :controller => resource, :action => 'destroy' }
|
18
|
+
end
|
19
|
+
|
20
|
+
app.routes.each do |route|
|
21
|
+
set.add_route app, { :path_info => %r{^#{route[ :path ]}$}, :request_method => route[ :method ] }, route[ :to ]
|
22
|
+
end
|
23
|
+
|
24
|
+
# default
|
25
|
+
#set.add_route app, { :path_info => %r{^/$} }, { :controller => app.default_controller, :action => app.default_action }
|
26
|
+
#set.add_route app, { :path_info => %r{^/(?:<controller>[a-z0-9]+)(/(?:<action>[a-z0-9]+)(/(?:<id>[a-z0-9]+)(\.(?:<format>[a-z]+))?)?)?$} }, { :controller => app.default_controller, :action => app.default_action }
|
27
|
+
end
|
28
|
+
|
29
|
+
router
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class String
|
2
|
+
# http://stackoverflow.com/questions/1448293/cast-between-string-and-classname
|
3
|
+
def to_class
|
4
|
+
chain = self.split "::"
|
5
|
+
klass = Kernel
|
6
|
+
chain.each do |klass_string|
|
7
|
+
klass = klass.const_get klass_string
|
8
|
+
end
|
9
|
+
klass.is_a?(Class) ? klass : nil
|
10
|
+
rescue NameError
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
|
14
|
+
# http://rails.rubyonrails.org/classes/Inflector.html#M001629
|
15
|
+
def camelize(first_letter_in_uppercase = true)
|
16
|
+
if first_letter_in_uppercase
|
17
|
+
self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
18
|
+
else
|
19
|
+
self.first + camelize(self)[1..-1]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/lib/junior.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Junior
|
2
|
+
VERSION = '0.0.0'
|
3
|
+
|
4
|
+
require 'rack'
|
5
|
+
require 'rack/builder'
|
6
|
+
require 'rack/mount'
|
7
|
+
require 'tilt'
|
8
|
+
|
9
|
+
require 'junior/helpers'
|
10
|
+
require 'junior/router'
|
11
|
+
require 'junior/request'
|
12
|
+
require 'junior/dispatcher'
|
13
|
+
require 'junior/controller'
|
14
|
+
require 'junior/application'
|
15
|
+
require 'junior/support'
|
16
|
+
end
|
data/spec/junior_spec.rb
ADDED
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
data/tasks/spec.rake
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec/rake/spectask'
|
2
|
+
|
3
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
4
|
+
spec.libs << 'lib' << 'spec'
|
5
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
6
|
+
end
|
7
|
+
|
8
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
9
|
+
spec.libs << 'lib' << 'spec'
|
10
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
11
|
+
spec.rcov = true
|
12
|
+
end
|
13
|
+
|
14
|
+
task :spec => :check_dependencies
|
15
|
+
|
16
|
+
task :default => :spec
|
data/tasks/yard.rake
ADDED
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: junior
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Wood
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-31 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rack
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.0.1
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rack-mount
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.0
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: tilt
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.4.0
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: rspec
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.2.9
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
type: :development
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ~>
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 0.5.2
|
64
|
+
version:
|
65
|
+
description: A Mini MVC Web Framework for Ruby built on Rack and a lot of inspiration from Sinatra
|
66
|
+
email: mike@michaelwood.com
|
67
|
+
executables: []
|
68
|
+
|
69
|
+
extensions: []
|
70
|
+
|
71
|
+
extra_rdoc_files:
|
72
|
+
- LICENSE
|
73
|
+
- README
|
74
|
+
files:
|
75
|
+
- .gitignore
|
76
|
+
- LICENSE
|
77
|
+
- README
|
78
|
+
- Rakefile
|
79
|
+
- VERSION
|
80
|
+
- junior.gemspec
|
81
|
+
- lib/junior.rb
|
82
|
+
- lib/junior/application.rb
|
83
|
+
- lib/junior/controller.rb
|
84
|
+
- lib/junior/dispatcher.rb
|
85
|
+
- lib/junior/helpers.rb
|
86
|
+
- lib/junior/request.rb
|
87
|
+
- lib/junior/router.rb
|
88
|
+
- lib/junior/support.rb
|
89
|
+
- spec/junior_spec.rb
|
90
|
+
- spec/spec.opts
|
91
|
+
- spec/spec_helper.rb
|
92
|
+
- tasks/spec.rake
|
93
|
+
- tasks/yard.rake
|
94
|
+
has_rdoc: true
|
95
|
+
homepage: http://github.com/eddanger/junior
|
96
|
+
licenses: []
|
97
|
+
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options:
|
100
|
+
- --charset=UTF-8
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: "0"
|
108
|
+
version:
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: "0"
|
114
|
+
version:
|
115
|
+
requirements: []
|
116
|
+
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 1.3.5
|
119
|
+
signing_key:
|
120
|
+
specification_version: 3
|
121
|
+
summary: An MVC Web Framework
|
122
|
+
test_files:
|
123
|
+
- spec/junior_spec.rb
|
124
|
+
- spec/spec_helper.rb
|