grippy-doozer 0.1.0

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.
Files changed (72) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +57 -0
  5. data/Rakefile +59 -0
  6. data/VERSION +1 -0
  7. data/bin/doozer +8 -0
  8. data/doozer.gemspec +114 -0
  9. data/lib/doozer/README.rb +40 -0
  10. data/lib/doozer/active_support/array.rb +14 -0
  11. data/lib/doozer/active_support/class.rb +221 -0
  12. data/lib/doozer/active_support/date_time.rb +23 -0
  13. data/lib/doozer/active_support/object.rb +43 -0
  14. data/lib/doozer/active_support/time.rb +32 -0
  15. data/lib/doozer/app.rb +265 -0
  16. data/lib/doozer/configs.rb +131 -0
  17. data/lib/doozer/controller.rb +335 -0
  18. data/lib/doozer/extend.rb +10 -0
  19. data/lib/doozer/initializer.rb +95 -0
  20. data/lib/doozer/lib.rb +32 -0
  21. data/lib/doozer/logger.rb +11 -0
  22. data/lib/doozer/orm/active_record.rb +19 -0
  23. data/lib/doozer/orm/data_mapper.rb +19 -0
  24. data/lib/doozer/orm/sequel.rb +18 -0
  25. data/lib/doozer/partial.rb +99 -0
  26. data/lib/doozer/plugins/paginate/init.rb +2 -0
  27. data/lib/doozer/plugins/paginate/lib/paginate/collection.rb +60 -0
  28. data/lib/doozer/plugins/paginate/lib/paginate/finder.rb +116 -0
  29. data/lib/doozer/plugins/paginate/lib/paginate/view_helpers.rb +37 -0
  30. data/lib/doozer/plugins/paginate/lib/paginate.rb +32 -0
  31. data/lib/doozer/rackup/server.ru +37 -0
  32. data/lib/doozer/rackup/test.rb +19 -0
  33. data/lib/doozer/redirect.rb +12 -0
  34. data/lib/doozer/route.rb +264 -0
  35. data/lib/doozer/scripts/cluster.rb +132 -0
  36. data/lib/doozer/scripts/migrate.rb +108 -0
  37. data/lib/doozer/scripts/task.rb +60 -0
  38. data/lib/doozer/scripts/test.rb +23 -0
  39. data/lib/doozer/version.rb +8 -0
  40. data/lib/doozer/view_helpers.rb +163 -0
  41. data/lib/doozer/watcher.rb +375 -0
  42. data/lib/doozer.rb +30 -0
  43. data/lib/generator/generator.rb +547 -0
  44. data/templates/skeleton/Rakefile +3 -0
  45. data/templates/skeleton/app/controllers/application_controller.rb +2 -0
  46. data/templates/skeleton/app/controllers/index_controller.rb +7 -0
  47. data/templates/skeleton/app/helpers/application_helper.rb +17 -0
  48. data/templates/skeleton/app/views/global/_header.html.erb +7 -0
  49. data/templates/skeleton/app/views/global/_navigation.html.erb +6 -0
  50. data/templates/skeleton/app/views/index/index.html.erb +108 -0
  51. data/templates/skeleton/app/views/layouts/default.html.erb +23 -0
  52. data/templates/skeleton/config/app.yml +31 -0
  53. data/templates/skeleton/config/database.yml +25 -0
  54. data/templates/skeleton/config/environment.rb +13 -0
  55. data/templates/skeleton/config/rack.rb +30 -0
  56. data/templates/skeleton/config/routes.rb +69 -0
  57. data/templates/skeleton/script/cluster +5 -0
  58. data/templates/skeleton/script/migrate +5 -0
  59. data/templates/skeleton/script/task +5 -0
  60. data/templates/skeleton/script/test +4 -0
  61. data/templates/skeleton/static/404.html +16 -0
  62. data/templates/skeleton/static/500.html +16 -0
  63. data/templates/skeleton/static/css/style.css +32 -0
  64. data/templates/skeleton/static/favicon.ico +0 -0
  65. data/templates/skeleton/static/js/application.js +1 -0
  66. data/templates/skeleton/static/js/jquery-1.3.min.js +19 -0
  67. data/templates/skeleton/static/robots.txt +5 -0
  68. data/templates/skeleton/test/fixtures/setup.rb +6 -0
  69. data/templates/skeleton/test/setup.rb +33 -0
  70. data/test/doozer_test.rb +7 -0
  71. data/test/test_helper.rb +10 -0
  72. metadata +126 -0
data/lib/doozer/app.rb ADDED
@@ -0,0 +1,265 @@
1
+ module Doozer
2
+ class App
3
+ APP_PATH = Dir.pwd
4
+ include Doozer::Util::Logger
5
+ attr_accessor :options
6
+
7
+ def initialize(args={})
8
+ @options=args
9
+
10
+ # load routes
11
+ load_routes
12
+
13
+ # load the application coontrollers, views, and helpers
14
+ load_files
15
+
16
+ # load models
17
+ load_models
18
+
19
+ # attach the file watcher for the mvc/lib/etc in development mode
20
+ require 'doozer/watcher'; load_watcher if Doozer::Configs.rack_env != :deployment
21
+
22
+ p "Doozer racked up..."
23
+ end
24
+
25
+ # This method is called along the rackup chain and maps the request path to the route, controller, and view for the format type.
26
+ def call(env)
27
+ # p env.inspect
28
+ # [200, {"Content-Type" => "text/html"}, "DOH!!!"]
29
+ path = env["PATH_INFO"]
30
+ # match env.path_info against the route compile
31
+ #p env.inspect
32
+ route = Doozer::Routing::Routes::match(path)
33
+ # p "path: #{path}"
34
+ # p "route: #{route.inspect}"
35
+ if not route.nil?
36
+ if route.app.nil?
37
+ extra_params = route.extra_params(path)
38
+ controller_klass = handler(route.controller.to_sym)
39
+ controller = controller_klass.new({:env=>env, :route=>route, :extra_params=>extra_params, :port=>@options[:Port]})
40
+
41
+ # call after_initialize test for excludes
42
+ #execution_time('controller.after_initialize',:start)
43
+ controller.after_initialize if not controller_klass.after_initialize_exclude.include?(route.action.to_sym)
44
+ #execution_time(nil, :end)
45
+
46
+ begin
47
+
48
+ # call before_filter test for excludes
49
+ #execution_time('controller.before_filter',:start)
50
+ controller.before_filter if not controller_klass.before_filter_exclude.include?(route.action.to_sym)
51
+ #execution_time(nil,:end)
52
+
53
+ # call the action method
54
+ #execution_time('controller.method(route.action).call',:start)
55
+ controller.method(route.action).call()
56
+ #execution_time(nil,:end)
57
+
58
+ # call after_filter test for excludes
59
+ #execution_time('controller.after_filter',:start)
60
+ controller.after_filter if not controller_klass.after_filter_exclude.include?(route.action.to_sym)
61
+ #execution_time(nil, :end)
62
+
63
+ # render controller...
64
+ #execution_time('controller.render_result',:start)
65
+ # r = Rack::Response.new(controller.render_controller(view, layout), route.status, {"Content-Type" => route.content_type})
66
+ r = Rack::Response.new(controller.render_result, route.status, {"Content-Type" => route.content_type})
67
+ #execution_time(nil,:end)
68
+ r.set_cookie('flash',{:value=>nil, :path=>'/'})
69
+ r.set_cookie('session',{:value=>controller.session_to_cookie(), :path=>'/'})
70
+ controller = nil
71
+ return r.to_a
72
+
73
+ rescue Doozer::Redirect => redirect
74
+ # set the status to the one defined in the route which type of redirect do we need to handle?
75
+ status = (route.status==301) ? 301 : 302
76
+ # check to make sure the status wasn't manually changed in the controller
77
+ status = redirect.status if not redirect.status.nil?
78
+
79
+ r = Rack::Response.new("redirect...", status, {"Content-Type" => "text/html", "Location"=>redirect.url})
80
+ # if we get a redirect we need to do something with the flash messages...
81
+ r.set_cookie('flash',{:value=>controller.flash_to_cookie(), :path=>'/'}) # might need to set the domain from config app_name value
82
+ r.set_cookie('session',{:value=>controller.session_to_cookie(), :path=>'/'})
83
+ return r.to_a
84
+ rescue => e
85
+ if Doozer::Configs.rack_env == :deployment
86
+ logger.error("RuntimeError: #{e.to_s}")
87
+ for line in e.backtrace
88
+ logger.error(" #{line}")
89
+ end
90
+ logger.error("Printing env variables:")
91
+ logger.error(env.inspect)
92
+ return [500, {"Content-Type" => "text/html"}, @@errors[500]]
93
+ else
94
+ raise e
95
+ end
96
+ end
97
+ else
98
+ return route.app.call(env)
99
+ end
100
+ else
101
+ return [404, {"Content-Type" => "text/html"}, @@errors[404]]
102
+ end
103
+ end
104
+
105
+ def execution_time(name = nil, point = :start)
106
+ if Doozer::Configs.rack_env == :development
107
+ @execution_time_name = name if name
108
+ @execution_time_start = Time.now().to_f if point == :start
109
+ @execution_time_end = Time.now().to_f if point == :end
110
+ logger.info("Excecution Time: #{@execution_time_name}: #{("%0.2f" % ( (@execution_time_end - @execution_time_start) * 1000).to_f)}ms") if point == :end
111
+ end
112
+ end
113
+
114
+ def load_files
115
+ p "Caching files..."
116
+ @@controllers = {}
117
+ @@layouts={}
118
+ @@views={}
119
+ @@errors={}
120
+
121
+ # require helper files and include into Doozer::Partial
122
+ helper_files = Dir.glob(File.join(APP_PATH,'/app/helpers/*_helper.rb'))
123
+ helper_files.each {|f|
124
+ require f
125
+ key = f.split("helpers/")[1].gsub(/.rb/,'')
126
+ Doozer::Partial.include_view_helper(key)
127
+ }
128
+
129
+ # cache contoller classes
130
+ controller_files = Dir.glob(File.join(APP_PATH,'/app/controllers/*_controller.rb'))
131
+ # we need to load the application_controller first since this might not be the first in the list...
132
+ if controller_files.length > 0
133
+ i=0
134
+ for f in controller_files
135
+ break if i==0 and f.index('application_controller.rb')
136
+ if f.index('application_controller.rb')
137
+ controller_files.insert(0, controller_files.delete(f))
138
+ break
139
+ end
140
+ i+=1
141
+ end
142
+ end
143
+
144
+ controller_files.each { |f|
145
+ require f
146
+ key = f.split("controllers/")[1].split("_controller.rb")[0]
147
+ if key.index("_")
148
+ value = key.split('_').each{ | k | k.capitalize! }.join('')
149
+ else
150
+ value = key.capitalize
151
+ end
152
+ klass_name = "#{value}Controller"
153
+ @@controllers[key.to_sym] = klass_name
154
+ # p "cache controller: #{key.to_sym}"
155
+
156
+ # importing view helpers into controller
157
+ controller_klass = Object.const_get(klass_name)
158
+ # automatically ads the application helper to the class
159
+ controller_klass.include_view_helper('application_helper')
160
+ controller_klass.include_view_helpers
161
+ }
162
+
163
+ # cache layout erb's
164
+ layout_files = Dir.glob(File.join(APP_PATH,'/app/views/layouts/*.erb'))
165
+ layout_files.each {|f|
166
+ key = f.split("layouts/")[1].split(".html.erb")[0].gsub(/.xml.erb/, '_xml').gsub(/.json.erb/, '_json')
167
+ results = []
168
+ File.new(f, "r").each { |line| results << line }
169
+ @@layouts[key.to_sym] = ERB.new(results.join(""))
170
+ }
171
+
172
+ #lood 404 and 500 pages if they exist
173
+ pnf = Doozer::Configs.page_not_found_url
174
+ if pnf
175
+ file = File.join(APP_PATH,"/#{pnf}")
176
+ results = []
177
+ File.new(file, "r").each { |line| results << line }
178
+ @@errors[404] = results.join("")
179
+ else
180
+ @@errors[404] = "<html><body>Sorry, this page can't be found.</body></html>"
181
+ end
182
+ ise = Doozer::Configs.internal_server_error_url
183
+ if ise
184
+ file = File.join(APP_PATH,"/#{ise}")
185
+ results = []
186
+ File.new(file, "r").each { |line| results << line }
187
+ @@errors[500] = results.join("")
188
+ else
189
+ @@errors[500] = "<html><body>There was an internal server error which borked this request.</body></html>"
190
+ end
191
+
192
+ @@controllers.each_key { | key |
193
+ # p key.inspect
194
+ files = Dir.glob(File.join(APP_PATH,"/app/views/#{key.to_s}/*.erb"))
195
+ files.each { | f |
196
+ #!!!don't cache partials here!!!
197
+ view = f.split("#{key.to_s}/")[1].split(".erb")[0].gsub(/\./,'_')
198
+ # p "check view: #{view}"
199
+ if not /^_/.match( view )
200
+ # p "cache view: #{view}"
201
+ results = []
202
+ File.new(f, "r").each { |line| results << line }
203
+ @@views[key] = {} if @@views[key].nil?
204
+ @@views[key][view.to_sym] = ERB.new(results.join(""))
205
+ end
206
+ }
207
+ }
208
+ end
209
+
210
+ def load_routes
211
+ require File.join(APP_PATH, 'config/routes')
212
+ end
213
+
214
+ def load_models
215
+ Dir.glob(File.join(APP_PATH,'/app/models/*.rb')).each { | model | require model }
216
+ end
217
+
218
+ def load_watcher
219
+ p "All along the watchtower..."
220
+ watcher = FileSystemWatcher.new()
221
+ # watcher.addDirectory(File.join(File.dirname(__FILE__),'../doozer/'), "*.rb")
222
+ watcher.addDirectory(File.join(APP_PATH,'/app/'), "**/*")
223
+ watcher.addDirectory(File.join(APP_PATH,'/app/'), "**/**/*")
224
+ watcher.addDirectory(File.join(APP_PATH,'/config/'), "*.*")
225
+ watcher.addDirectory(File.join(APP_PATH,'/lib/'), "*.*")
226
+ watcher.addDirectory(File.join(APP_PATH,'/static/'), "*.*")
227
+ watcher.addDirectory(File.join(APP_PATH,'/static/'), "**/**/*")
228
+
229
+ watcher.sleepTime = 1
230
+ watcher.start { |status,file|
231
+ if(status == FileSystemWatcher::CREATED) then
232
+ puts "created: #{file}"
233
+ load_files
234
+ Doozer::Partial.clear_loaded_partials
235
+ elsif(status == FileSystemWatcher::MODIFIED) then
236
+ puts "modified: #{file}"
237
+ load_files
238
+ Doozer::Partial.clear_loaded_partials
239
+ elsif(status == FileSystemWatcher::DELETED) then
240
+ puts "deleted: #{file}"
241
+ load_files
242
+ Doozer::Partial.clear_loaded_partials
243
+ end
244
+ }
245
+ #don't join the thread it messes up rackup threading watcher.join()
246
+ end
247
+
248
+ def handler(key)
249
+ return Object.const_get(@@controllers[key])
250
+ end
251
+
252
+ def self.controllers
253
+ @@controllers
254
+ end
255
+
256
+ def self.layouts
257
+ @@layouts
258
+ end
259
+
260
+ def self.views
261
+ @@views
262
+ end
263
+
264
+ end #App
265
+ end #Doozer
@@ -0,0 +1,131 @@
1
+ require 'rbconfig'
2
+ require 'logger'
3
+
4
+ module Doozer
5
+
6
+ # This is the main Configs class which loads root/config/app.yml and root/config/database.yml
7
+ #
8
+ # It also provides a few helper methods like logger, env_path, base_url and app_name
9
+ class Configs
10
+ APP_PATH = Dir.pwd
11
+ @@possible_orm = [:active_record, :data_mapper, :sequel]
12
+
13
+ # Rack refers to production as deployment.
14
+ def self.load(rack_env)
15
+ p "APP_ROOT: #{APP_PATH}"
16
+ p "Loading configs for #{rack_env}"
17
+
18
+ # TODO: remove this and replace with APP_PATH
19
+ @@env_path = Dir.pwd
20
+ @@config = Config::CONFIG
21
+ rack_env = (rack_env.kind_of? String) ? rack_env.to_sym : rack_env
22
+ case rack_env
23
+ when :development
24
+ when :deployment
25
+ rack_env = :deployment
26
+ when :test, :none
27
+ rack_env = :test
28
+ else
29
+ raise ":development, :deployment, or :test are only environments allowed"
30
+ end
31
+
32
+ # set logging for environment
33
+ if [:development, :test].include?(rack_env)
34
+ @@logger = Logger.new(STDOUT)
35
+ else
36
+ @@logger = Logger.new("#{APP_PATH}/log/#{rack_env}.log")
37
+ end
38
+
39
+ @@config[:rack_env] = rack_env
40
+ # p ":rack_env set to #{@@config[:rack_env]}"
41
+
42
+ begin
43
+ @@config[:database] = Configs.symbolize_keys( YAML.load(File.read(File.join(APP_PATH,'config/database.yml'))) )
44
+ rescue
45
+ p "Failed to load config/database.yml"
46
+ end
47
+
48
+ begin
49
+ @@config[:app] = Configs.symbolize_keys( YAML.load(File.read(File.join(APP_PATH,'config/app.yml'))) )
50
+ rescue
51
+ p "Failed to load config/app.yml"
52
+ end
53
+ end
54
+
55
+ # We initialize the application logger in this Configs. This is then extended through to the ActiveRecord and is also available in ViewHelpers.
56
+ def self.logger
57
+ @@logger
58
+ end
59
+
60
+ # This is the file path the app was loaded under. Dir.pwd moves to root in daemon mode so we cache this.
61
+ def self.env_path
62
+ @@env_path
63
+ end
64
+
65
+ # Take a hash and turn all the keys into symbols
66
+ def self.symbolize_keys(hash=nil)
67
+ out = {}; hash.each { | k, val | out[k.to_sym] = val}
68
+ return out
69
+ end
70
+
71
+ # Return the rack environment this application was loaded with.
72
+ def self.rack_env
73
+ return @@config[:rack_env] if not @@config[:rack_env].nil?
74
+ end
75
+
76
+ # Input a symbol and return the config for this sym
77
+ def self.get(sym=nil)
78
+ @@config[sym]
79
+ end
80
+
81
+ # Return the orm mapping gem name to load
82
+ def self.orm
83
+ begin
84
+ return @@config[:database][:orm]
85
+ rescue
86
+ end
87
+ return nil
88
+ end
89
+
90
+ # Return the database configuration setting for the loaded environment
91
+ def self.db
92
+ return @@config[:database][@@config[:rack_env]] if not @@config[:database].nil?
93
+ end
94
+
95
+ # Only used for Sequel ORM for getting the db connection after connecting
96
+ def self.db_conn
97
+ @@db_conn
98
+ end
99
+
100
+ # Only used for Sequel ORM to set the db connection
101
+ def self.db_conn=(conn)
102
+ @@db_conn = conn
103
+ end
104
+
105
+ # Return the app configuration setting for the loaded environment
106
+ def self.app
107
+ return @@config[:app][@@config[:rack_env]]
108
+ end
109
+
110
+ # Return the app base url
111
+ def self.base_url
112
+ self.app["base_url"] || ""
113
+ end
114
+
115
+ # Return the app name
116
+ def self.app_name
117
+ self.app["name"] || ""
118
+ end
119
+
120
+ # Return the app 404 url
121
+ def self.page_not_found_url
122
+ self.app[404] || nil
123
+ end
124
+
125
+ # Return the app 404 url
126
+ def self.internal_server_error_url
127
+ self.app[500] || nil
128
+ end
129
+
130
+ end
131
+ end