doozer 0.4.0 → 0.4.1
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 +4 -2
- data/lib/doozer.rb +2 -1
- data/lib/doozer/app.rb +37 -3
- data/lib/doozer/controller.rb +6 -7
- data/lib/doozer/lib.rb +12 -0
- data/lib/doozer/mailer.rb +263 -0
- data/lib/doozer/mailer_partial.rb +74 -0
- data/lib/doozer/partial.rb +1 -0
- data/lib/doozer/route.rb +4 -1
- data/lib/doozer/scripts/task.rb +29 -5
- data/lib/doozer/version.rb +1 -1
- data/lib/doozer/view_helpers.rb +18 -0
- data/lib/generator/generator.rb +67 -2
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.1
|
data/doozer.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{doozer}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["grippy"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-03}
|
13
13
|
s.default_executable = %q{doozer}
|
14
14
|
s.description = %q{This GEM provides a small, barebones framework for creating MVC Rack applications.}
|
15
15
|
s.email = %q{gmelton@whorde.com}
|
@@ -41,6 +41,8 @@ Gem::Specification.new do |s|
|
|
41
41
|
"lib/doozer/initializer.rb",
|
42
42
|
"lib/doozer/lib.rb",
|
43
43
|
"lib/doozer/logger.rb",
|
44
|
+
"lib/doozer/mailer.rb",
|
45
|
+
"lib/doozer/mailer_partial.rb",
|
44
46
|
"lib/doozer/middleware.rb",
|
45
47
|
"lib/doozer/orm/active_record.rb",
|
46
48
|
"lib/doozer/orm/data_mapper.rb",
|
data/lib/doozer.rb
CHANGED
@@ -27,10 +27,11 @@ module Doozer
|
|
27
27
|
autoload :Route, "doozer/exceptions"
|
28
28
|
end
|
29
29
|
|
30
|
+
autoload :Mailer, "doozer/mailer"
|
31
|
+
autoload :MailerPartial, "doozer/mailer_partial"
|
30
32
|
autoload :Middleware, "doozer/middleware"
|
31
33
|
autoload :MiddlewareBeforeDozerApp, "doozer/middleware"
|
32
34
|
|
33
|
-
|
34
35
|
autoload :Task, "doozer/task"
|
35
36
|
autoload :ViewHelpers, "doozer/view_helpers"
|
36
37
|
autoload :Version, "doozer/version"
|
data/lib/doozer/app.rb
CHANGED
@@ -64,10 +64,8 @@ module Doozer
|
|
64
64
|
#execution_time(nil,:end)
|
65
65
|
r.set_cookie('flash',{:value=>nil, :path=>'/'})
|
66
66
|
r.set_cookie('session',{:value=>controller.session_to_cookie(), :path=>'/'})
|
67
|
-
|
68
67
|
r = controller.write_response_cookies(r)
|
69
68
|
|
70
|
-
|
71
69
|
# finalize the request
|
72
70
|
controller.finished!
|
73
71
|
controller = nil
|
@@ -133,6 +131,7 @@ module Doozer
|
|
133
131
|
load_models
|
134
132
|
puts "=> Caching files"
|
135
133
|
@@controllers = {}
|
134
|
+
@@mailers = {}
|
136
135
|
@@layouts={}
|
137
136
|
@@views={}
|
138
137
|
@@errors={}
|
@@ -224,6 +223,39 @@ module Doozer
|
|
224
223
|
end
|
225
224
|
}
|
226
225
|
}
|
226
|
+
|
227
|
+
mailer_files = Dir.glob(File.join(app_path,'app/mailers/*_mailer.rb'))
|
228
|
+
mailer_files.each { |f|
|
229
|
+
require f
|
230
|
+
key = f.split("mailers/")[1].split("_mailer.rb")[0]
|
231
|
+
if key.index("_")
|
232
|
+
value = key.split('_').each{ | k | k.capitalize! }.join('')
|
233
|
+
else
|
234
|
+
value = key.capitalize
|
235
|
+
end
|
236
|
+
klass_name = "#{value}Mailer"
|
237
|
+
@@mailers[key.to_sym] = klass_name
|
238
|
+
# puts "cache mailer: #{key.to_sym}"
|
239
|
+
# importing view helpers into controller
|
240
|
+
mailer_klass = Object.const_get(klass_name)
|
241
|
+
# automatically ads the application helper to the class
|
242
|
+
mailer_klass.include_view_helper('application_helper')
|
243
|
+
mailer_klass.include_view_helpers
|
244
|
+
}
|
245
|
+
|
246
|
+
mail_key = :mail
|
247
|
+
mailer_files = Dir.glob(File.join(app_path,"app/views/#{mail_key.to_s}/*.erb"))
|
248
|
+
mailer_files.each { | f |
|
249
|
+
#!!!don't cache partials here!!!
|
250
|
+
view = f.split("#{mail_key.to_s}/")[1].split(".erb")[0].gsub(/\./,'_')
|
251
|
+
if not /^_/.match( view )
|
252
|
+
# puts "cache view: #{view}"
|
253
|
+
results = []
|
254
|
+
File.new(f, "r").each { |line| results << line }
|
255
|
+
@@views[mail_key] = {} if @@views[mail_key].nil?
|
256
|
+
@@views[mail_key][view.to_sym] = ERB.new(results.join(""))
|
257
|
+
end
|
258
|
+
}
|
227
259
|
end
|
228
260
|
|
229
261
|
# Load application routes
|
@@ -256,22 +288,24 @@ module Doozer
|
|
256
288
|
watcher.addDirectory( app_path + '/static/', "*.*")
|
257
289
|
watcher.addDirectory( app_path + '/static/', "**/**/*")
|
258
290
|
|
259
|
-
|
260
291
|
watcher.sleepTime = 1
|
261
292
|
watcher.start { |status, file|
|
262
293
|
if(status == FileSystemWatcher::CREATED) then
|
263
294
|
puts "created: #{file}"
|
264
295
|
load_files
|
265
296
|
Doozer::Partial.clear_loaded_partials
|
297
|
+
Doozer::MailerPartial.clear_loaded_partials
|
266
298
|
elsif(status == FileSystemWatcher::MODIFIED) then
|
267
299
|
puts "modified: #{file}"
|
268
300
|
load_files
|
269
301
|
Doozer::Partial.clear_loaded_partials
|
302
|
+
Doozer::MailerPartial.clear_loaded_partials
|
270
303
|
Doozer::Configs.clear_static_files
|
271
304
|
elsif(status == FileSystemWatcher::DELETED) then
|
272
305
|
puts "deleted: #{file}"
|
273
306
|
load_files
|
274
307
|
Doozer::Partial.clear_loaded_partials
|
308
|
+
Doozer::MailerPartial.clear_loaded_partials
|
275
309
|
Doozer::Configs.clear_static_files
|
276
310
|
end
|
277
311
|
}
|
data/lib/doozer/controller.rb
CHANGED
@@ -28,17 +28,17 @@ module Doozer
|
|
28
28
|
#
|
29
29
|
# To save cookies: All hash keys must be symbols and value strings.
|
30
30
|
# Reserved hash keys per cookie:
|
31
|
-
#
|
32
|
-
#
|
31
|
+
# :expires - Time.now + some duration. This default to 30 days if not defined
|
32
|
+
# :path - The path for the cookie. This defaults to '/' if not defined
|
33
33
|
#
|
34
34
|
# Example:
|
35
|
-
#
|
35
|
+
# @cookies[:yum_yum]={:a=>'123',
|
36
36
|
# :b=>'abc',
|
37
37
|
# :expires=>Time.now + 3.day
|
38
38
|
# :path=>'/path'}
|
39
39
|
# To delete a cookie, set it to nil or delete it from @cookies
|
40
40
|
#
|
41
|
-
#
|
41
|
+
# @cookies[:testing]=nil
|
42
42
|
attr_accessor :cookies
|
43
43
|
# @session variable containing a hash of strings which are persisted in the session cookie until the browser session expires.
|
44
44
|
attr_accessor :session
|
@@ -124,8 +124,8 @@ module Doozer
|
|
124
124
|
|
125
125
|
#turn extra params into instance variables...
|
126
126
|
args[:extra_params].each { |key, value| self.instance_variable_set("@#{key}".to_sym, value)}
|
127
|
-
|
128
|
-
|
127
|
+
puts " Params: #{@request.params.inspect}" if not @request.params.nil?
|
128
|
+
puts " Extra params: #{args[:extra_params].inspect}" if not args[:extra_params].nil?
|
129
129
|
end
|
130
130
|
|
131
131
|
# Renders an action with any of the following overridable parameters:
|
@@ -169,7 +169,6 @@ module Doozer
|
|
169
169
|
change_layout(args[:layout]) if args[:layout]
|
170
170
|
change_view(args[:view]) if args[:view]
|
171
171
|
change_view(ERB.new(args[:text])) if args[:text]
|
172
|
-
|
173
172
|
end
|
174
173
|
|
175
174
|
# This method is called from the appserver controller handler.
|
data/lib/doozer/lib.rb
CHANGED
@@ -16,6 +16,17 @@ module Doozer
|
|
16
16
|
end
|
17
17
|
return klass
|
18
18
|
end
|
19
|
+
|
20
|
+
#Return an underscored string from a ClassName string.
|
21
|
+
# example: input "ExampleClass" > "example_class"
|
22
|
+
def self.underscore(s)
|
23
|
+
while true do
|
24
|
+
m = /[A-Z]/.match(s)
|
25
|
+
break if m.to_s == ''
|
26
|
+
s.gsub!(/#{m.to_s}/,"_#{m.to_s.downcase}")
|
27
|
+
end
|
28
|
+
s.gsub(/^_/,'') # move the first underscore
|
29
|
+
end
|
19
30
|
|
20
31
|
#Returns a one-level deep folder/file structure and preservers underscores for filename.
|
21
32
|
# example: input "folder_some_file_name" > "folder/some_file_name"
|
@@ -28,5 +39,6 @@ module Doozer
|
|
28
39
|
end
|
29
40
|
s
|
30
41
|
end
|
42
|
+
|
31
43
|
end
|
32
44
|
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
# load gems
|
2
|
+
%w(rack erb).each { |dep| require dep }
|
3
|
+
|
4
|
+
module Doozer
|
5
|
+
|
6
|
+
# The Mailer class operates in many ways like a Controller.
|
7
|
+
#
|
8
|
+
# Mailers have access to all ViewHelpers methods.
|
9
|
+
#
|
10
|
+
# Mailers can also load partials.
|
11
|
+
#
|
12
|
+
# Limitations:
|
13
|
+
# - The current send implemntation must be overridden by your application.
|
14
|
+
# - Create multipart messages but only handles html content types. No text or attachment capabilities.
|
15
|
+
#
|
16
|
+
class Mailer
|
17
|
+
|
18
|
+
# @controller variable containing the name of the mailer
|
19
|
+
attr_accessor :controller
|
20
|
+
# @action variable containing the name of the mailer action to deliver
|
21
|
+
attr_accessor :action
|
22
|
+
# @from variable which contains either a string or list of senders. Example: ['some@email.com', 'Some guy <some@guy.com>']
|
23
|
+
attr_accessor :from
|
24
|
+
# @to variable which contains either a string or list of recipients. Example: ['some@email.com', 'Some guy <some@guy.com>']
|
25
|
+
attr_accessor :to
|
26
|
+
# @cc variable which contains either a string or list of recipients which should be cc'd on the email. Example: ['some@email.com', 'Some guy <some@guy.com>']
|
27
|
+
attr_accessor :cc
|
28
|
+
# @bcc variable which contains either a string or list of recipients which should be bcc'd on the email. Example: ['some@email.com', 'Some guy <some@guy.com>']
|
29
|
+
attr_accessor :bcc
|
30
|
+
# @subject variable which contains the subject of the mail.
|
31
|
+
attr_accessor :subject
|
32
|
+
# @date variable which contains the date of the email. Must be a Time object. Defaults to Time.now.
|
33
|
+
attr_accessor :date
|
34
|
+
# @envelope variable which holds the TMail object for the mail.
|
35
|
+
attr_accessor :envelope
|
36
|
+
# @message_id variable which holds the unique message identifier of the mail.
|
37
|
+
attr_accessor :message_id
|
38
|
+
# @charset variable which holds the character set of the mail. Defaults to "ISO-8859-1"
|
39
|
+
attr_accessor :charset
|
40
|
+
# @render_args variable containing a hash of values to use while rendering the message
|
41
|
+
attr_accessor :render_args
|
42
|
+
|
43
|
+
include Doozer::Util::Logger
|
44
|
+
include Doozer::ViewHelpers
|
45
|
+
|
46
|
+
self.class_inheritable_accessor :require_view_helpers, :view_dir, :layout
|
47
|
+
|
48
|
+
# Array of helper methods to include inside the view.
|
49
|
+
#
|
50
|
+
# Example: self.require_view_helpers=[:application, :helper_1]
|
51
|
+
self.require_view_helpers=[]
|
52
|
+
|
53
|
+
# Default directory where the views should be looked up for the mail.
|
54
|
+
#
|
55
|
+
self.view_dir = 'mail'
|
56
|
+
|
57
|
+
# Default mail layout symbol to use for the mail.
|
58
|
+
#
|
59
|
+
self.layout = :default_mail
|
60
|
+
|
61
|
+
# Create a new Mailer object
|
62
|
+
# action: a symbol of the action to call
|
63
|
+
# args: optional list of arguments
|
64
|
+
#
|
65
|
+
def initialize(action, args={})
|
66
|
+
@controller = self.class.to_s
|
67
|
+
@action = action
|
68
|
+
|
69
|
+
#holds all variables for template binding
|
70
|
+
@view={}
|
71
|
+
@to = args[:to]
|
72
|
+
@from = args[:from]
|
73
|
+
@cc = args[:cc]
|
74
|
+
@bcc = args[:bcc]
|
75
|
+
@subject = args[:subject] || ''
|
76
|
+
@date = args[:date] || Time.now()
|
77
|
+
@charset = args[:charset] || "ISO-8859-1"
|
78
|
+
|
79
|
+
@message_id = "#{DateTime.now().strftime('%Y%m%d%H%M%S')}.#{(rand(1000) * 1024).to_s}"
|
80
|
+
@envelope = nil
|
81
|
+
@render_args = {:layout=>nil, :view=>nil, :text=>nil}
|
82
|
+
render({
|
83
|
+
:view=>args[:view] || action,
|
84
|
+
:layout=>args[:layout] || mailer_class.layout,
|
85
|
+
:text=>args[:text]
|
86
|
+
})
|
87
|
+
|
88
|
+
# turn the rest of the args into instance variables
|
89
|
+
args.delete(:view) if args[:view]
|
90
|
+
args.delete(:layout) if args[:delete]
|
91
|
+
args.delete(:text) if args[:text]
|
92
|
+
args.each { |key, value| self.instance_variable_set("@#{key}".to_sym, value)}
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
# Erb binding
|
97
|
+
def bind
|
98
|
+
@erb.result(binding)
|
99
|
+
end
|
100
|
+
|
101
|
+
# This method is called prior to #send and handles the creation of envelope.
|
102
|
+
def package
|
103
|
+
raise "Missing from address" if self.from.nil?
|
104
|
+
|
105
|
+
begin
|
106
|
+
@envelope = TMail::Mail.new()
|
107
|
+
rescue => e
|
108
|
+
begin
|
109
|
+
require 'tmail'
|
110
|
+
@envelope = TMail::Mail.new()
|
111
|
+
rescue MissingSourceFile, Gem::LoadError => e
|
112
|
+
logger.error("TMail Gem wasn't found. Please install if you want to send mail.")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# http://tmail.rubyforge.org/rdoc/index.html
|
117
|
+
@envelope.mime_version = "1.0"
|
118
|
+
@envelope.charset = self.charset
|
119
|
+
@envelope.message_id = self.message_id
|
120
|
+
@envelope.from = [self.from]
|
121
|
+
@envelope.to = [self.to] if self.to
|
122
|
+
@envelope.cc = [self.cc] if self.cc
|
123
|
+
@envelope.bcc = [self.bcc] if self.bcc
|
124
|
+
@envelope.date = self.date
|
125
|
+
@envelope.subject = self.subject
|
126
|
+
|
127
|
+
html = TMail::Mail.new()
|
128
|
+
html.body = self.render_result
|
129
|
+
html.set_content_type('text','html')
|
130
|
+
|
131
|
+
@envelope.parts << html
|
132
|
+
@envelope.set_content_type('multipart', 'mixed') # needs to be set last or throws an error
|
133
|
+
end
|
134
|
+
|
135
|
+
# Call this method to receive the list of only :to addresses. Use this when sending through SMTP.
|
136
|
+
def to_address
|
137
|
+
out = []; @envelope.to_addrs.each{|a| out.push(a.address)}
|
138
|
+
return out
|
139
|
+
end
|
140
|
+
|
141
|
+
# Call this method to receive the list of only :from addresses. Use this when sending through SMTP.
|
142
|
+
def from_address
|
143
|
+
out = []; @envelope.from_addrs.each{|a| out.push(a.address)}
|
144
|
+
return out
|
145
|
+
end
|
146
|
+
|
147
|
+
# Helper method for initializing partials from views.
|
148
|
+
def partial(file=nil, locals={})
|
149
|
+
locals[:view_dir] = mailer_class.view_dir
|
150
|
+
Doozer::MailerPartial.partial(file, locals)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Renders an action with any of the following overridable parameters:
|
154
|
+
#
|
155
|
+
# args={
|
156
|
+
# :view=>Symbol, String or ERB,
|
157
|
+
# :layout=>Symbol,
|
158
|
+
# :text=>'this is the text to render'
|
159
|
+
# }
|
160
|
+
#
|
161
|
+
def render(args={})
|
162
|
+
change_layout(args[:layout]) if args[:layout]
|
163
|
+
change_view(args[:view]) if args[:view]
|
164
|
+
change_view(ERB.new(args[:text])) if args[:text]
|
165
|
+
end
|
166
|
+
|
167
|
+
# This method creates the html part of the mail.
|
168
|
+
def render_result
|
169
|
+
layout = @render_args[:layout]
|
170
|
+
view = @render_args[:view]
|
171
|
+
if layout.kind_of? Symbol # this handles the layout(:none)
|
172
|
+
view.result(binding)
|
173
|
+
else
|
174
|
+
@view[:timestamp] = "<!-- rendered: #{Time.now()} / env: #{rack_env} -->"
|
175
|
+
@view[:body] = view.result(binding)
|
176
|
+
# layout = @layout if layout.nil? # this handles the layout(:some_other_layout) case for formats
|
177
|
+
layout.result(binding)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Sequel ORM db connection
|
182
|
+
def db
|
183
|
+
Doozer::Configs.db_conn
|
184
|
+
end
|
185
|
+
|
186
|
+
# Global teardown called at the end of every request. Hooks ORM.teardown
|
187
|
+
def finished!
|
188
|
+
Doozer::ORM.after_request if Doozer::Configs.orm_loaded
|
189
|
+
end
|
190
|
+
|
191
|
+
# Returns the Mailer object
|
192
|
+
def mailer_class
|
193
|
+
Object.const_get(self.class.to_s)
|
194
|
+
end
|
195
|
+
|
196
|
+
# Include additional view helpers declared for the class.
|
197
|
+
#
|
198
|
+
# This method automatically appends '_helper' to each required helper symbol
|
199
|
+
def self.include_view_helpers
|
200
|
+
# importing view helpers into controller
|
201
|
+
self.require_view_helpers.each { | sym |
|
202
|
+
self.include_view_helper("#{sym.to_s}_helper")
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
# Include the app/helpers file_name. Expects helper as a string.
|
207
|
+
#
|
208
|
+
# You must pass the full file name if you use this method.
|
209
|
+
#
|
210
|
+
# Example: self.include_view_helper('application_helper')
|
211
|
+
def self.include_view_helper(helper)
|
212
|
+
# importing view helpers into controller
|
213
|
+
include Object.const_get(Doozer::Lib.classify("#{helper}"))
|
214
|
+
end
|
215
|
+
|
216
|
+
# Call this method to deliver a Mailer#action
|
217
|
+
#
|
218
|
+
# Arguments
|
219
|
+
# - action: The action of the mailer to call passed as a symbol.
|
220
|
+
# - args: The mail arguments to initialize the email with.
|
221
|
+
# All remaining arguments are turned into instance variables and bound to the view.
|
222
|
+
|
223
|
+
# Note: The send mechanism is empty and must be overriden in the calling application.
|
224
|
+
def self.deliver(action, args={})
|
225
|
+
# puts "deliver.."
|
226
|
+
mailer = self.new(action, args)
|
227
|
+
mailer.method(action).call()
|
228
|
+
mailer.finished! #close the db connections
|
229
|
+
mailer.package
|
230
|
+
send(mailer)
|
231
|
+
end
|
232
|
+
|
233
|
+
# The send method must be overriden by the calling class.
|
234
|
+
#
|
235
|
+
# => The mailer object passed to this mehod of the instance of the mailer.
|
236
|
+
# => You can access the mailer.envelope.encoded (tmail) object which handles all the encoding.
|
237
|
+
def self.send(mailer); end
|
238
|
+
|
239
|
+
private
|
240
|
+
def change_layout(sym)
|
241
|
+
if sym == :none
|
242
|
+
layout=sym
|
243
|
+
else
|
244
|
+
#this needs to look up the layout and reset layout to this erb template
|
245
|
+
lay = Doozer::App.layouts[sym]
|
246
|
+
raise "Can't find layout for #{sym}" if lay.nil?
|
247
|
+
layout = lay
|
248
|
+
end
|
249
|
+
@render_args[:layout] = layout
|
250
|
+
end
|
251
|
+
|
252
|
+
def change_view(args)
|
253
|
+
if args.kind_of? Symbol
|
254
|
+
# implies we're using the same controller as the current controller with a view name of :view_name
|
255
|
+
view = Doozer::App.views[mailer_class.view_dir.to_sym]["#{args.to_s}_html".to_sym]
|
256
|
+
elsif args.kind_of? ERB
|
257
|
+
view = args
|
258
|
+
end
|
259
|
+
view = ERB.new("Missing view for goes here") if view.nil?
|
260
|
+
@render_args[:view] = view
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Doozer
|
2
|
+
# The MailerPartial is really similar to Doozer::Partial.
|
3
|
+
class MailerPartial
|
4
|
+
attr_accessor :erb
|
5
|
+
|
6
|
+
include ERB::Util
|
7
|
+
include Doozer::Util::Logger
|
8
|
+
include Doozer::ViewHelpers
|
9
|
+
|
10
|
+
@@partials={}
|
11
|
+
|
12
|
+
def initialize(erb, locals)
|
13
|
+
@erb = erb
|
14
|
+
if locals.kind_of? Hash
|
15
|
+
locals.each_pair {|key, value|
|
16
|
+
#p "#{key}:#{value}"
|
17
|
+
self.instance_variable_set("@#{key}".to_sym, value) # :@a, value
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def bind
|
23
|
+
@erb.result(binding)
|
24
|
+
end
|
25
|
+
|
26
|
+
# This class method lazy loads and caches the erb templates of the requested partials
|
27
|
+
def self.partial(file=nil, locals={})
|
28
|
+
#p "Class method: Doozer::Partial#partial"
|
29
|
+
dir = locals[:view_dir]
|
30
|
+
if file.index("/").nil?
|
31
|
+
name = "#{dir}/_#{file}"
|
32
|
+
else
|
33
|
+
name = "#{file.gsub(/\//,'/_')}"
|
34
|
+
end
|
35
|
+
load_partial(name) if @@partials[name].nil?
|
36
|
+
erb = @@partials[name]
|
37
|
+
if erb
|
38
|
+
partial = Doozer::MailerPartial.new(erb, locals)
|
39
|
+
partial.bind()
|
40
|
+
else
|
41
|
+
puts "ERROR => no partial exists for #{file}\n"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def partial(file=nil, locals={})
|
46
|
+
locals[:view_dir] = @view_dir if not @view_dir.nil?
|
47
|
+
Doozer::MailerPartial.partial(file, locals)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Load and cache partial ERB template with the given file_name.
|
51
|
+
def self.load_partial(name)
|
52
|
+
|
53
|
+
file = File.join(Doozer::Configs.app_path,"app/views/#{name}.html.erb")
|
54
|
+
results = []
|
55
|
+
begin
|
56
|
+
File.new(file, "r").each { |line| results << line }
|
57
|
+
@@partials[name] = ERB.new(results.join(""))
|
58
|
+
rescue
|
59
|
+
puts "ERROR => sorry couldn't load partial #{name} (#{file})"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Class methods for clearing all cached partials. Mainly a dispatcher for the file watcher to pick up new changes without having to restart the appserver in development mode.
|
64
|
+
def self.clear_loaded_partials
|
65
|
+
@@partials = {}
|
66
|
+
end
|
67
|
+
|
68
|
+
# Class method for including a view helper.
|
69
|
+
def self.include_view_helper(helper)
|
70
|
+
m = Doozer::Lib.classify(helper)
|
71
|
+
include Object.const_get(m)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/doozer/partial.rb
CHANGED
data/lib/doozer/route.rb
CHANGED
@@ -300,7 +300,9 @@ module Doozer
|
|
300
300
|
return hashish
|
301
301
|
end
|
302
302
|
|
303
|
-
# Parses route tokens and returns a helper method which evntually module_eval'd into Doozer::ViewHelpers
|
303
|
+
# Parses route tokens and returns a helper method which evntually is module_eval'd into Doozer::ViewHelpers
|
304
|
+
#
|
305
|
+
# => creates helper methods for route_name_url (relative) and route_name_aurl (absolute)
|
304
306
|
def url_helper_method
|
305
307
|
method_name=[@name]
|
306
308
|
# method_name.push(@format) if @format != :html
|
@@ -334,6 +336,7 @@ module Doozer
|
|
334
336
|
end
|
335
337
|
url_method.push("})")
|
336
338
|
method = """def #{method_name.join('_')}#{signature.join('')}; #{url_method} end"""
|
339
|
+
method += "\n#{method.gsub(/url\(/, 'aurl(')}"
|
337
340
|
return method
|
338
341
|
end
|
339
342
|
|
data/lib/doozer/scripts/task.rb
CHANGED
@@ -31,24 +31,29 @@ require 'optparse'
|
|
31
31
|
@task = nil
|
32
32
|
@args = nil
|
33
33
|
@help = false
|
34
|
+
@daemonize = false
|
34
35
|
|
35
36
|
opts = OptionParser.new("", 24, ' ') { |opts|
|
36
37
|
opts.banner = "Usage: script/task -T task_name -E (default: development || deployment || test)"
|
37
38
|
opts.separator ""
|
38
39
|
opts.separator "Command options:"
|
39
|
-
|
40
|
+
|
40
41
|
opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development || deployment || test)") { |e|
|
41
42
|
@env = e.to_sym
|
42
43
|
}
|
43
|
-
|
44
|
+
|
44
45
|
opts.on("-T", "--task TASK", "run task_name") { | t |
|
45
46
|
@task = t
|
46
47
|
}
|
47
|
-
|
48
|
+
|
48
49
|
opts.on("-A", "--args ARGS", "args") { |a|
|
49
50
|
@args = eval(a) if a and a.length
|
50
51
|
}
|
51
|
-
|
52
|
+
|
53
|
+
opts.on("-D", "--daemonize") {
|
54
|
+
@daemonize = true
|
55
|
+
}
|
56
|
+
|
52
57
|
opts.on("-h", "--help", "Show this message") do
|
53
58
|
@help = true
|
54
59
|
end
|
@@ -68,8 +73,27 @@ if @task
|
|
68
73
|
raise "Can't find this task file #{@task}" if file.nil?
|
69
74
|
task, file_name = file_to_task(file, @args)
|
70
75
|
if not @help
|
71
|
-
puts "Running #{@task}
|
76
|
+
puts "=> Running #{@task}"
|
72
77
|
Doozer::Initializer.boot(@env)
|
78
|
+
if @daemonize
|
79
|
+
puts "=> Daemonize"
|
80
|
+
log_file = "#{APP_PATH}/log/task/#{@task}.log"
|
81
|
+
error_file = "#{APP_PATH}/log/task/#{@task}_errors.log"
|
82
|
+
puts "=> Writing to log: #{log_file}"
|
83
|
+
exit if fork
|
84
|
+
Process.setsid
|
85
|
+
exit if fork
|
86
|
+
# Dir.chdir "/"
|
87
|
+
File.umask 0000
|
88
|
+
file = File.open(log_file, File::RDWR|File::APPEND|File::CREAT, 0600)
|
89
|
+
STDIN.reopen(file)
|
90
|
+
STDOUT.reopen(file)
|
91
|
+
file = File.open(error_file, File::RDWR|File::APPEND|File::CREAT, 0600)
|
92
|
+
STDERR.reopen(file)
|
93
|
+
# STDIN.reopen "/dev/null"
|
94
|
+
# STDOUT.reopen "/dev/null", "a"
|
95
|
+
# STDERR.reopen "/dev/null", "a"
|
96
|
+
end
|
73
97
|
task.run
|
74
98
|
else
|
75
99
|
puts ""
|
data/lib/doozer/version.rb
CHANGED
data/lib/doozer/view_helpers.rb
CHANGED
@@ -58,6 +58,13 @@ module Doozer
|
|
58
58
|
return url
|
59
59
|
end
|
60
60
|
|
61
|
+
# A wrapper method for #url which automatically sets the base_url to the one configured for the application
|
62
|
+
#
|
63
|
+
def aurl(opt)
|
64
|
+
opt[:base_url] = base_url if opt.kind_of? Hash
|
65
|
+
url(opt)
|
66
|
+
end
|
67
|
+
|
61
68
|
# Creates an html anchor tag.
|
62
69
|
#
|
63
70
|
# text - the text of the anchor tag
|
@@ -69,6 +76,17 @@ module Doozer
|
|
69
76
|
"<a href=\"#{url(opt)}\"#{hash_to_props(prop)}>#{text}</a>"
|
70
77
|
end
|
71
78
|
|
79
|
+
# Creates an html anchor tag with an absolute url.
|
80
|
+
#
|
81
|
+
# text - the text of the anchor tag
|
82
|
+
#
|
83
|
+
# opt - a hash of options which are passed to url(opt)
|
84
|
+
#
|
85
|
+
# prop - a hash of anchor tag attributes to add to the link
|
86
|
+
def alink(text='', opt={}, prop={})
|
87
|
+
"<a href=\"#{aurl(opt)}\"#{hash_to_props(prop)}>#{text}</a>"
|
88
|
+
end
|
89
|
+
|
72
90
|
# Creates an img tag.
|
73
91
|
#
|
74
92
|
# path - the src of the image tag
|
data/lib/generator/generator.rb
CHANGED
@@ -63,7 +63,14 @@ module Doozer
|
|
63
63
|
task(name.downcase)
|
64
64
|
else
|
65
65
|
help?(:help, :task)
|
66
|
-
end
|
66
|
+
end
|
67
|
+
when :mailer, :"-E"
|
68
|
+
if args.length == 3
|
69
|
+
name = args[2]
|
70
|
+
mailer(name.downcase)
|
71
|
+
else
|
72
|
+
help?(:help, :mailer)
|
73
|
+
end
|
67
74
|
else
|
68
75
|
help_all
|
69
76
|
end
|
@@ -85,6 +92,7 @@ module Doozer
|
|
85
92
|
help(:helper)
|
86
93
|
help(:migrate)
|
87
94
|
help(:task)
|
95
|
+
help(:mailer)
|
88
96
|
end
|
89
97
|
|
90
98
|
def self.controller(name)
|
@@ -308,6 +316,42 @@ end
|
|
308
316
|
end
|
309
317
|
end
|
310
318
|
|
319
|
+
def self.mailer(name)
|
320
|
+
return if help?(name, :mailer)
|
321
|
+
path = "#{APP_PATH}/app/mailers"
|
322
|
+
if not File.exist?(path)
|
323
|
+
puts "Creating directory for mailers..."
|
324
|
+
system("mkdir #{path}")
|
325
|
+
end
|
326
|
+
|
327
|
+
puts "Generating file..."
|
328
|
+
path = "#{path}/#{name}_mailer.rb"
|
329
|
+
if not File.exist?(path)
|
330
|
+
puts "=> Generating mailer: #{path}"
|
331
|
+
file = File.new(path, "w+")
|
332
|
+
if file
|
333
|
+
klass = Doozer::Lib.classify(name)
|
334
|
+
template = """
|
335
|
+
#= #{klass}Mailer
|
336
|
+
class #{klass}Mailer < Doozer::Mailer
|
337
|
+
\"\"\"Default configuration options for mailers
|
338
|
+
self.require_view_helpers=[]
|
339
|
+
self.view_dir = 'mail'
|
340
|
+
self.layout = :default_mail
|
341
|
+
\"\"\"
|
342
|
+
end
|
343
|
+
"""
|
344
|
+
file.syswrite(template)
|
345
|
+
else
|
346
|
+
puts "ERROR => Unable to open file!"
|
347
|
+
end
|
348
|
+
else
|
349
|
+
puts "Skipping: #{path} (already exists)"
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
|
311
355
|
def self.help?(name, action=nil)
|
312
356
|
if name.to_sym == :"-h" or name == :help
|
313
357
|
puts "Commands:"
|
@@ -355,10 +399,15 @@ Migration - Create a migration file in project/db with the next available versio
|
|
355
399
|
Task - Create a task file in project/tasks with the class name of TaskName.
|
356
400
|
Command: doozer generate (task or -T) task_name
|
357
401
|
Example: doozer generate task task_name\n"""
|
402
|
+
when :mailer, :mail :"-E"
|
403
|
+
h += """
|
404
|
+
Mailer - Create a mailer file in project/app/mailers with the class name of NameMailer. '_mailer' is automatically appended to the name.
|
405
|
+
Command: doozer generate (mailer or -E) mailer_name
|
406
|
+
Example: doozer generate mailer mailer_name\n"""
|
358
407
|
end
|
359
408
|
puts h
|
360
409
|
end
|
361
|
-
|
410
|
+
|
362
411
|
# TODO: Dry this up...
|
363
412
|
def self.skeleton(name)
|
364
413
|
|
@@ -387,6 +436,14 @@ Task - Create a task file in project/tasks with the class name of TaskName.
|
|
387
436
|
puts "Skipping #{name}/app/controllers directory (already exists)"
|
388
437
|
end
|
389
438
|
|
439
|
+
#copy mailers
|
440
|
+
if not File.exist?("#{name}/app/mailers")
|
441
|
+
puts "=> Creating #{name}/app/mailers directory"
|
442
|
+
system("mkdir #{name}/app/mailers")
|
443
|
+
else
|
444
|
+
puts "Skipping #{name}/app/mailers directory (already exists)"
|
445
|
+
end
|
446
|
+
|
390
447
|
#copy models
|
391
448
|
if not File.exist?("#{name}/app/models")
|
392
449
|
puts "=> Creating #{name}/app/models directory and files"
|
@@ -420,6 +477,14 @@ Task - Create a task file in project/tasks with the class name of TaskName.
|
|
420
477
|
else
|
421
478
|
puts "Skipping #{name}/app/views/index directory (already exists)"
|
422
479
|
end
|
480
|
+
|
481
|
+
#copy views/mail
|
482
|
+
if not File.exist?("#{name}/app/views/mail")
|
483
|
+
puts "=> Creating #{name}/app/views/mail directory"
|
484
|
+
system("mkdir #{name}/app/views/mail")
|
485
|
+
else
|
486
|
+
puts "Skipping #{name}/app/views/mail directory (already exists)"
|
487
|
+
end
|
423
488
|
|
424
489
|
#copy views/global
|
425
490
|
if not File.exist?("#{name}/app/views/global")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doozer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- grippy
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-03 00:00:00 -08:00
|
13
13
|
default_executable: doozer
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -45,6 +45,8 @@ files:
|
|
45
45
|
- lib/doozer/initializer.rb
|
46
46
|
- lib/doozer/lib.rb
|
47
47
|
- lib/doozer/logger.rb
|
48
|
+
- lib/doozer/mailer.rb
|
49
|
+
- lib/doozer/mailer_partial.rb
|
48
50
|
- lib/doozer/middleware.rb
|
49
51
|
- lib/doozer/orm/active_record.rb
|
50
52
|
- lib/doozer/orm/data_mapper.rb
|