grippy-doozer 0.1.3 → 0.1.4
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/VERSION +1 -1
- data/doozer.gemspec +40 -3
- data/lib/doozer.rb +6 -1
- data/lib/doozer/app.rb +28 -19
- data/lib/doozer/configs.rb +18 -12
- data/lib/doozer/controller.rb +2 -2
- data/lib/doozer/exceptions.rb +12 -0
- data/lib/doozer/initializer.rb +8 -6
- data/lib/doozer/logger.rb +2 -1
- data/lib/doozer/partial.rb +3 -3
- data/lib/doozer/rackup/test.rb +2 -1
- data/lib/doozer/redirect.rb +1 -1
- data/lib/doozer/route.rb +34 -6
- data/lib/doozer/scripts/cluster.rb +9 -10
- data/lib/doozer/version.rb +1 -1
- data/lib/doozer/view_helpers.rb +100 -12
- data/lib/generator/generator.rb +0 -2
- data/templates/skeleton/config/environment.rb +1 -1
- data/templates/skeleton/config/routes.rb +2 -2
- data/test/doozer_test.rb +1 -1
- data/test/project/Rakefile +3 -0
- data/test/project/app/controllers/application_controller.rb +2 -0
- data/test/project/app/controllers/index_controller.rb +7 -0
- data/test/project/app/helpers/application_helper.rb +17 -0
- data/test/project/app/views/global/_header.html.erb +7 -0
- data/test/project/app/views/global/_navigation.html.erb +6 -0
- data/test/project/app/views/index/index.html.erb +108 -0
- data/test/project/app/views/layouts/default.html.erb +23 -0
- data/test/project/config/app.yml +31 -0
- data/test/project/config/database.yml +25 -0
- data/test/project/config/environment.rb +11 -0
- data/test/project/config/rack.rb +30 -0
- data/test/project/config/routes.rb +72 -0
- data/test/project/script/cluster +6 -0
- data/test/project/script/console +15 -0
- data/test/project/script/migrate +6 -0
- data/test/project/script/task +6 -0
- data/test/project/script/test +6 -0
- data/test/project/static/404.html +16 -0
- data/test/project/static/500.html +16 -0
- data/test/project/static/css/style.css +32 -0
- data/test/project/static/favicon.ico +0 -0
- data/test/project/static/js/application.js +1 -0
- data/test/project/static/js/jquery-1.3.min.js +19 -0
- data/test/project/static/robots.txt +5 -0
- data/test/project/test/fixtures/setup.rb +6 -0
- data/test/project/test/setup.rb +33 -0
- data/test/routing_test.rb +66 -0
- data/test/test_helper.rb +18 -2
- metadata +40 -3
- data/lib/doozer/README.rb +0 -40
@@ -11,7 +11,6 @@
|
|
11
11
|
require 'optparse'
|
12
12
|
|
13
13
|
APP_PATH = Dir.pwd if APP_PATH.nil?
|
14
|
-
|
15
14
|
config = Doozer::Configs.symbolize_keys( YAML.load(File.read(File.join(APP_PATH,'config/app.yml'))) )
|
16
15
|
clusters = Doozer::Configs.symbolize_keys(config[:clusters])
|
17
16
|
|
@@ -32,7 +31,7 @@ end
|
|
32
31
|
# Automatically starts a test instance of your appserver on http://localhost:5000. (No -E flag is required for this command).
|
33
32
|
def test
|
34
33
|
cmd = "rackup #{@test_config}"
|
35
|
-
|
34
|
+
printf "Command: #{cmd} -p 5000 -E test -o 127.0.0.1\n"
|
36
35
|
system(cmd)
|
37
36
|
end
|
38
37
|
|
@@ -40,23 +39,23 @@ end
|
|
40
39
|
#
|
41
40
|
# <b>deployment</b>: Automatically starts a new instance of your appserver for each defined cluster address:port
|
42
41
|
def start
|
43
|
-
|
42
|
+
printf "Starting clusters...\n"
|
44
43
|
for app in @apps
|
45
44
|
if @env == :deployment
|
46
45
|
#need to check if application has a pid file so we don't start
|
47
46
|
pid_file = "#{APP_PATH}/log/doozer.#{app[:port]}.pid"
|
48
47
|
raise "pid file already exists for #{pid_file}" if File.exist?(pid_file)
|
49
48
|
cmd = "rackup #{@config} -p #{app[:port]} -E #{@env.to_s} -s #{@server} -o #{app[:ip]} #{@daemonize} -P #{pid_file}"
|
50
|
-
|
49
|
+
printf "Command: #{cmd}\n"
|
51
50
|
system(cmd)
|
52
51
|
else
|
53
52
|
cmd = "rackup #{@config} -p #{app[:port]} -E #{@env.to_s} -s #{@server} -o #{app[:ip]}"
|
54
|
-
|
53
|
+
printf "Command: #{cmd}\n"
|
55
54
|
system(cmd)
|
56
55
|
break
|
57
56
|
end
|
58
57
|
end
|
59
|
-
|
58
|
+
printf "Did they start?\n"
|
60
59
|
system("ps -aux | grep rackup")
|
61
60
|
end
|
62
61
|
|
@@ -71,21 +70,21 @@ end
|
|
71
70
|
# <b>deployment</b>: Automatically stops all instances of your appserver for each defined cluster address:port
|
72
71
|
def stop
|
73
72
|
system("ps -aux | grep rackup")
|
74
|
-
|
73
|
+
printf "Stoping clusters...\n"
|
75
74
|
for app in @apps
|
76
75
|
if @env == :deployment
|
77
76
|
pid_file = "#{APP_PATH}/log/doozer.#{app[:port]}.pid"
|
78
|
-
|
77
|
+
printf "Reading pid from #{pid_file}\n"
|
79
78
|
if File.exist?(pid_file)
|
80
79
|
File.open(pid_file, 'r'){ | f |
|
81
80
|
pid = f.gets.to_i
|
82
|
-
|
81
|
+
printf "Shutting down process #{pid}\n"
|
83
82
|
system("kill -9 #{pid}")
|
84
83
|
|
85
84
|
}
|
86
85
|
File.delete(pid_file)
|
87
86
|
else
|
88
|
-
|
87
|
+
printf "pid file doesn't exist\n"
|
89
88
|
end
|
90
89
|
end
|
91
90
|
end
|
data/lib/doozer/version.rb
CHANGED
data/lib/doozer/view_helpers.rb
CHANGED
@@ -1,8 +1,22 @@
|
|
1
1
|
require 'digest/sha1'
|
2
2
|
|
3
3
|
module Doozer
|
4
|
+
|
5
|
+
# ViewHelpers which are included in Controllers and Partials
|
4
6
|
module ViewHelpers
|
5
|
-
|
7
|
+
|
8
|
+
# Returns a url from a hash of options. Expects option keys as symbols.
|
9
|
+
#
|
10
|
+
# :name - the route.name to parse additional options with
|
11
|
+
#
|
12
|
+
# :base_url - the base url of the request
|
13
|
+
#
|
14
|
+
# => route tokens are replace the key/values pairs in the options. if a route token is found in the options it is replaced with a 'MISSING-key' string.
|
15
|
+
#
|
16
|
+
# => all remaining options are added as key=value query string parameters
|
17
|
+
#
|
18
|
+
# You can also pass a opt as a string which just passed it through.
|
19
|
+
#
|
6
20
|
def url(opt)
|
7
21
|
url = ''
|
8
22
|
if opt.kind_of? Hash
|
@@ -14,8 +28,10 @@ module Doozer
|
|
14
28
|
return "MISSING-ROUTE-for-name-#{name}" if route .nil?
|
15
29
|
url = "#{route.path}"
|
16
30
|
|
17
|
-
# we need to swap out the tokens here
|
18
|
-
route.tokens
|
31
|
+
# we need to swap out the tokens here and account for formats on the end of the path
|
32
|
+
tokens = route.tokens
|
33
|
+
tokens.last.gsub!(Regexp.compile("\.#{route.format.to_s}$"), '') if route.format != :html if not route.tokens.empty?
|
34
|
+
tokens.each { |token|
|
19
35
|
val = opt[token.to_sym]
|
20
36
|
if val
|
21
37
|
opt.delete(token.to_sym)
|
@@ -26,7 +42,7 @@ module Doozer
|
|
26
42
|
}
|
27
43
|
end
|
28
44
|
|
29
|
-
# set
|
45
|
+
# set base_url
|
30
46
|
host = ""
|
31
47
|
if opt[:base_url]
|
32
48
|
host = opt.delete(:base_url)
|
@@ -42,15 +58,34 @@ module Doozer
|
|
42
58
|
return url
|
43
59
|
end
|
44
60
|
|
61
|
+
# Creates an html anchor tag.
|
62
|
+
#
|
63
|
+
# text - the text of the anchor tag
|
64
|
+
#
|
65
|
+
# opt - a hash of options which are passed to url(opt)
|
66
|
+
#
|
67
|
+
# prop - a hash of anchor tag attributes to add to the link
|
45
68
|
def link(text='', opt={}, prop={})
|
46
69
|
"<a href=\"#{url(opt)}\"#{hash_to_props(prop)}>#{text}</a>"
|
47
70
|
end
|
48
|
-
|
71
|
+
|
72
|
+
# Creates an img tag.
|
73
|
+
#
|
74
|
+
# path - the src of the image tag
|
75
|
+
#
|
76
|
+
# prop - a hash of image tag attributes
|
49
77
|
def img(path, prop={})
|
50
78
|
path = timestamp_path(path)
|
51
79
|
"<img src=\"#{path}\"#{hash_to_props(prop)} />"
|
52
80
|
end
|
53
81
|
|
82
|
+
# Creates a stylesheet link tag.
|
83
|
+
#
|
84
|
+
# path - the href of the link tag
|
85
|
+
#
|
86
|
+
# prop - a hash of link tag attributes.
|
87
|
+
#
|
88
|
+
# => Defaults to :rel=>'stylesheet', :type=>'text/css', :media=>'all'
|
54
89
|
def stylesheet(path, prop={})
|
55
90
|
#<link rel="stylesheet" type="text/css" media="all" href="/css/style.css" />
|
56
91
|
path = timestamp_path(path)
|
@@ -60,12 +95,33 @@ module Doozer
|
|
60
95
|
"<link #{hash_to_props(prop)} href=\"#{path}\" />"
|
61
96
|
end
|
62
97
|
|
98
|
+
# Creates a link tag for feeds.
|
99
|
+
#
|
100
|
+
# opt - a hash of options which are passed to url(opt)
|
101
|
+
#
|
102
|
+
# prop - a hash of link tag attributes.
|
103
|
+
#
|
104
|
+
# => Example: :rel=>'alternate', :type=>'application/rss+', :media=>'all'
|
105
|
+
def feed(opt={}, prop={})
|
106
|
+
"<link #{hash_to_props(prop)} href=\"#{url(opt)}\" />"
|
107
|
+
end
|
108
|
+
|
109
|
+
# Creates a script tag.
|
110
|
+
#
|
111
|
+
# path - the src of the javascript tag
|
112
|
+
#
|
113
|
+
# prop - a hash of script tag attributes.
|
114
|
+
#
|
115
|
+
# => Defaults to: :type=>'text/javascript'
|
63
116
|
def javascript(path, prop={})
|
64
117
|
path = timestamp_path(path)
|
65
118
|
prop[:type] = 'text/javascript' if prop[:type].nil?
|
66
119
|
"<script #{hash_to_props(prop)} src=\"#{path}\"></script>"
|
67
120
|
end
|
68
121
|
|
122
|
+
# Creates metatags
|
123
|
+
#
|
124
|
+
# retuns a differnt metatag for each key/value added to @view[:meta] hash. See Doozer::Controller#meta for adding examples.
|
69
125
|
def metatags
|
70
126
|
#loop all metatags here...
|
71
127
|
out=[]
|
@@ -75,7 +131,20 @@ module Doozer
|
|
75
131
|
}
|
76
132
|
out.join("")
|
77
133
|
end
|
78
|
-
|
134
|
+
|
135
|
+
# Creates an authtoken form element
|
136
|
+
#
|
137
|
+
# By default, all post requests expect this value to be present unless overrided with Doozer::Controller#after_initialize
|
138
|
+
#
|
139
|
+
# You can customize the elemement id by passing arg[:id] to the method.
|
140
|
+
#
|
141
|
+
# The value contains an checksum of the app_name and cookie sid
|
142
|
+
def authtoken(args={})
|
143
|
+
id = args[:id] if args[:id]
|
144
|
+
"<input type=\"hidden\" id=\"#{id}_authtoken\" name=\"_authtoken\" value=\"#{generate_authtoken(@request.cookies['sid'])}\" />"
|
145
|
+
end
|
146
|
+
|
147
|
+
# Turns a hash of key/value pairs in to a key1="value1" key2="value2" key3="value3"
|
79
148
|
def hash_to_props(opt={})
|
80
149
|
props=[]
|
81
150
|
opt.each { | key, value |
|
@@ -85,6 +154,9 @@ module Doozer
|
|
85
154
|
return ""
|
86
155
|
end
|
87
156
|
|
157
|
+
# Turns a hash of key/value pairs in querystring like key1=value%201&key2=value2&key3=value3
|
158
|
+
#
|
159
|
+
# All values are CGI.escaped for output
|
88
160
|
def hash_to_qs(opt={})
|
89
161
|
props=[]
|
90
162
|
opt.each { | key, value |
|
@@ -93,24 +165,41 @@ module Doozer
|
|
93
165
|
props.join("&")
|
94
166
|
end
|
95
167
|
|
168
|
+
# Safe encodes a string by entity encodes all less then and greater then signs
|
169
|
+
#
|
96
170
|
def h(s)
|
97
171
|
s.gsub!(/</,'<')
|
98
172
|
s.gsub!(/>/,'>')
|
99
173
|
return s
|
100
174
|
end
|
101
175
|
|
176
|
+
# Returns the base url configured in app.yml
|
177
|
+
#
|
102
178
|
def base_url
|
103
179
|
Doozer::Configs.base_url
|
104
180
|
end
|
105
181
|
|
182
|
+
# Returns the env setting the application was loaded under (:development, :deployment, or :test)
|
183
|
+
#
|
106
184
|
def rack_env
|
107
185
|
Doozer::Configs.rack_env
|
108
186
|
end
|
109
187
|
|
188
|
+
# Returns the app name configured in app.yml
|
189
|
+
#
|
110
190
|
def app_name
|
111
191
|
Doozer::Configs.app_name
|
112
192
|
end
|
113
193
|
|
194
|
+
# Returns the app path the application was loaded in. This defaults to the path all scripts were executed from. In general, this is the root of your project directory unless specified otherwise.
|
195
|
+
#
|
196
|
+
def app_path
|
197
|
+
Doozer::Configs.app_path
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns the ip address of the server
|
201
|
+
#
|
202
|
+
# Automatically accounts for proxied requests and returns HTTP_X_FORWARDED_FOR if present.
|
114
203
|
def ip
|
115
204
|
if addr = @env['HTTP_X_FORWARDED_FOR']
|
116
205
|
addr.split(',').last.strip
|
@@ -119,20 +208,19 @@ module Doozer
|
|
119
208
|
end
|
120
209
|
end
|
121
210
|
|
211
|
+
# Returns the domain name of the request
|
212
|
+
#
|
122
213
|
def server_name
|
123
214
|
@env['SERVER_NAME']
|
124
215
|
end
|
125
216
|
|
217
|
+
# Returns the request path
|
218
|
+
#
|
126
219
|
def path
|
127
220
|
@env['REQUEST_PATH']
|
128
221
|
end
|
129
222
|
|
130
|
-
|
131
|
-
id = args[:id] if args[:id]
|
132
|
-
"<input type=\"hidden\" id=\"#{id}_authtoken\" name=\"_authtoken\" value=\"#{generate_authtoken(@request.cookies['sid'])}\" />"
|
133
|
-
end
|
134
|
-
|
135
|
-
# test if this person has a session with keys in it...
|
223
|
+
# Test if this person has a session with keys in it...
|
136
224
|
def session?
|
137
225
|
@session.empty?
|
138
226
|
end
|
data/lib/generator/generator.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This file is loaded right after orm is initialized and right before app, controllers and models
|
2
2
|
# place code here which is used throughout the application
|
3
|
-
printf "Loading Environment..."
|
3
|
+
printf "Loading Environment... \n"
|
4
4
|
|
5
5
|
Doozer::Initializer.after_orm do | config |
|
6
6
|
# require 'doozer/plugins/paginate/init'
|
@@ -19,7 +19,7 @@ Formats
|
|
19
19
|
Adding formats symbolzes automatically creates new routes for the formats symbols provided.
|
20
20
|
The appropriate content-type is returned with the response.
|
21
21
|
You can access the format with @format in your controllers.
|
22
|
-
Supported formats are: :json, :js, :xml, :rss
|
22
|
+
Supported formats are: :json, :js, :xml, :rss, :atom
|
23
23
|
All routes default to :html format
|
24
24
|
|
25
25
|
Example:
|
@@ -32,7 +32,7 @@ Example:
|
|
32
32
|
map.add :format_example, '/format_example', {:controller=>'index', :action=>'format_example', :status=>200}
|
33
33
|
:json format
|
34
34
|
map.add :format_example_json, '/format_example.json', {:controller=>'index', :action=>'format_example', :status=>200}
|
35
|
-
:xml
|
35
|
+
:xml format
|
36
36
|
map.add :format_example_xml, '/format_example.xml', {:controller=>'index', :action=>'format_example', :status=>200}
|
37
37
|
|
38
38
|
|
data/test/doozer_test.rb
CHANGED
@@ -2,6 +2,6 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class DoozerTest < Test::Unit::TestCase
|
4
4
|
should "probably rename this file and start testing for real" do
|
5
|
-
flunk "hey buddy, you should probably rename this file and start testing for real"
|
5
|
+
# flunk "hey buddy, you should probably rename this file and start testing for real"
|
6
6
|
end
|
7
7
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This is the default ApplicationHelper.
|
2
|
+
# Place methods here which are global to your application.
|
3
|
+
# By default all controllers include this file.
|
4
|
+
#
|
5
|
+
# To load a helper file into a controller:
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
#
|
9
|
+
# -files: app_root/app/helpers/helper1_helper.rb, app_root/app/helpers/helper2_helper.rb
|
10
|
+
#
|
11
|
+
# -declare inside controller: self.require_view_helpers=[:helper1, :helper2]
|
12
|
+
#
|
13
|
+
# By default all helpers are automatically included into the base partial class.
|
14
|
+
# Be care to avoid methods with the same names between helper modules.
|
15
|
+
# The helpers are included alphabetically by file name
|
16
|
+
module ApplicationHelper
|
17
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
<h2><span>Project Details</span></h2>
|
2
|
+
<p><span>Doozer is a <%=link('Rackup', 'http://rack.rubyforge.org/') %> application.</span></p>
|
3
|
+
|
4
|
+
<ul>
|
5
|
+
<li><span>Bare bones, lightweight, MVC framework.</span></li>
|
6
|
+
<li><span>Map routes to controller actions or completely separate applications.</span></li>
|
7
|
+
<li><span>ORM agnostic. use activerecord, data mapper, or sequel</span></li>
|
8
|
+
<li><span>Easy to define static directories</span></li>
|
9
|
+
<li><span>View Helpers for controllers</span></li>
|
10
|
+
<li><span>Layouts and Partials</span></li>
|
11
|
+
</ul>
|
12
|
+
|
13
|
+
<h3>Intro</h3>
|
14
|
+
<h4>Inspiration</h4>
|
15
|
+
|
16
|
+
<h3>Requirements</h3>
|
17
|
+
<h4>Rackup</h4>
|
18
|
+
<p>Rackup and its dependencies:</p>
|
19
|
+
|
20
|
+
<h3>File Structure</h3>
|
21
|
+
<p>This should look similar to rails</p>
|
22
|
+
<h4>Layout</h4>
|
23
|
+
|
24
|
+
<h3>Configs</h3>
|
25
|
+
<h4>Static</h4>
|
26
|
+
<h4>ORM</h4>
|
27
|
+
<h4>Clusters</h4>
|
28
|
+
<p>This needs to change names to something better. Maybe Server?</p>
|
29
|
+
<h3>Environment</h3>
|
30
|
+
<h4>Load Hooks</h4>
|
31
|
+
<h4>Settings</h4>
|
32
|
+
|
33
|
+
<h3>Load Order</h3>
|
34
|
+
|
35
|
+
<h3>Routes</h3>
|
36
|
+
<h4>Parameters</h4>
|
37
|
+
<h4>Magic</h4>
|
38
|
+
<p>A magic route is similar to "/:controller/:action" in rails.</p>
|
39
|
+
<p>Right now, these are tuned off in favor of explicitly having to declare them. Formats aren't extended to them yet. :()</p>
|
40
|
+
<h4>Bypassing Controllers</h4>
|
41
|
+
<p>You can declare a Rackup compatible app to call instead of a Doozer::Controller.</p>
|
42
|
+
<p>See config/routes.rb for more info.</p>
|
43
|
+
<h4>Layouts</h4>
|
44
|
+
<p>By default all html routes use the default.html.erb layout generated with the initial scaffolding.</p>
|
45
|
+
<p>Declare a route layout of :layout=>:view_name to override the default behavior.</p>
|
46
|
+
|
47
|
+
|
48
|
+
<h3>App</h3>
|
49
|
+
<h4>Security</h4>
|
50
|
+
<h5>Post Requests</h5>
|
51
|
+
<h6>Authenticity Token</h6>
|
52
|
+
|
53
|
+
<h4>Model</h4>
|
54
|
+
<h4>View</h4>
|
55
|
+
<h5>Route Tokens</h5>
|
56
|
+
<h4>Controller</h4>
|
57
|
+
<h5>Callbacks</h5>
|
58
|
+
As a controller is initialized, rendered, and finalized, you have the ability to influence the call stack.
|
59
|
+
|
60
|
+
<h6>after_initialize</h6>
|
61
|
+
<p>This is called after the controller is matched to the route and intialized.
|
62
|
+
<p>Use this hook to customize which actions shouldn't call before_filter and after_filter.</p>
|
63
|
+
<code>
|
64
|
+
@before_filter={:exclude=>[:action1, :action2]}
|
65
|
+
@after_filter={:exclude=>[:action1, :action2]}
|
66
|
+
</code>
|
67
|
+
<h6>before_filter</h6>
|
68
|
+
<p>By default all actions call this method. You can override it in your controller class by declaring:</p>
|
69
|
+
<code>
|
70
|
+
def before_filter
|
71
|
+
#code goes here....
|
72
|
+
end
|
73
|
+
</code>
|
74
|
+
<h6>after_filter</h6>
|
75
|
+
<p>By default all actions call this method. You can override it in your controller class by declaring:</p>
|
76
|
+
<code>
|
77
|
+
def after_filter
|
78
|
+
#code goes here....
|
79
|
+
end
|
80
|
+
</code>
|
81
|
+
<h5>Params</h5>
|
82
|
+
<h5>Route Tokens</h5>
|
83
|
+
<p>All route tokens are available as instance variables.</p>
|
84
|
+
<p>A route token of :id is available in an action and it's view as @id. You must pass this variable into a partial as a local variable.</p>
|
85
|
+
|
86
|
+
<h3>View Helpers</h3>
|
87
|
+
<h4>Redirects</h4>
|
88
|
+
<h4>Flash</h4>
|
89
|
+
<h4>Partial</h4>
|
90
|
+
<h4>Layout</h4>
|
91
|
+
<h4>Session</h4>
|
92
|
+
|
93
|
+
<h3>Generators</h3>
|
94
|
+
<h4>MVC Files</h4>
|
95
|
+
|
96
|
+
<h3>Scaffold</h3>
|
97
|
+
<h4>Building Project</h4>
|
98
|
+
|
99
|
+
<h3>Static</h3>
|
100
|
+
|
101
|
+
<h3>Testing</h3>
|
102
|
+
|
103
|
+
<h3>Tasks</h3>
|
104
|
+
|
105
|
+
<h3>App Start</h3>
|
106
|
+
<h4>Config</h4>
|
107
|
+
<h4>Start Command</h4>
|
108
|
+
<h5>Environments</h5>
|