rango 0.2 → 0.2.1.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (261) hide show
  1. data/.gitignore +9 -0
  2. data/.gitmodules +3 -0
  3. data/CHANGELOG +5 -0
  4. data/CONTRIBUTORS +1 -0
  5. data/Gemfile +20 -0
  6. data/LICENSE +1 -1
  7. data/README.textile +5 -4
  8. data/benchmarks/ab.rb +6 -0
  9. data/benchmarks/bm/boot.rb +20 -0
  10. data/{spec/rango/version_spec.rb → benchmarks/bm/callbacks.rb} +0 -0
  11. data/benchmarks/bm/request.rb +4 -0
  12. data/benchmarks/bm/routers.rb +22 -0
  13. data/benchmarks/bm/stack.rb +19 -0
  14. data/{spec/stubs/acqs/dir/lib.rb → benchmarks/bm/templates.rb} +0 -0
  15. data/benchmarks/helper.rb +7 -0
  16. data/benchmarks/stubs/merb-app/.gitignore +21 -0
  17. data/benchmarks/stubs/merb-app/Rakefile +35 -0
  18. data/benchmarks/stubs/merb-app/app/controllers/application.rb +4 -0
  19. data/benchmarks/stubs/merb-app/app/controllers/exceptions.rb +15 -0
  20. data/benchmarks/stubs/merb-app/app/helpers/global_helpers.rb +7 -0
  21. data/benchmarks/stubs/merb-app/app/models/user.rb +19 -0
  22. data/benchmarks/stubs/merb-app/app/views/exceptions/not_acceptable.html.erb +63 -0
  23. data/benchmarks/stubs/merb-app/app/views/exceptions/not_found.html.erb +47 -0
  24. data/benchmarks/stubs/merb-app/app/views/layout/application.html.erb +12 -0
  25. data/benchmarks/stubs/merb-app/autotest/discover.rb +4 -0
  26. data/benchmarks/stubs/merb-app/autotest/merb.rb +154 -0
  27. data/benchmarks/stubs/merb-app/autotest/merb_rspec.rb +167 -0
  28. data/benchmarks/stubs/merb-app/config/database.yml +33 -0
  29. data/benchmarks/stubs/merb-app/config/dependencies.rb +36 -0
  30. data/benchmarks/stubs/merb-app/config/environments/development.rb +17 -0
  31. data/benchmarks/stubs/merb-app/config/environments/production.rb +12 -0
  32. data/benchmarks/stubs/merb-app/config/environments/rake.rb +13 -0
  33. data/benchmarks/stubs/merb-app/config/environments/staging.rb +12 -0
  34. data/benchmarks/stubs/merb-app/config/environments/test.rb +14 -0
  35. data/benchmarks/stubs/merb-app/config/init.rb +26 -0
  36. data/benchmarks/stubs/merb-app/config/rack.rb +13 -0
  37. data/benchmarks/stubs/merb-app/config/router.rb +46 -0
  38. data/benchmarks/stubs/merb-app/doc/rdoc/generators/merb_generator.rb +1364 -0
  39. data/benchmarks/stubs/merb-app/doc/rdoc/generators/template/merb/api_grease.js +640 -0
  40. data/benchmarks/stubs/merb-app/doc/rdoc/generators/template/merb/index.html.erb +37 -0
  41. data/benchmarks/stubs/merb-app/doc/rdoc/generators/template/merb/merb.css +252 -0
  42. data/benchmarks/stubs/merb-app/doc/rdoc/generators/template/merb/merb.rb +353 -0
  43. data/benchmarks/stubs/merb-app/doc/rdoc/generators/template/merb/merb_doc_styles.css +492 -0
  44. data/benchmarks/stubs/merb-app/doc/rdoc/generators/template/merb/prototype.js +2515 -0
  45. data/benchmarks/stubs/merb-app/merb/merb-auth/setup.rb +46 -0
  46. data/benchmarks/stubs/merb-app/merb/merb-auth/strategies.rb +13 -0
  47. data/benchmarks/stubs/merb-app/merb/session/session.rb +11 -0
  48. data/benchmarks/stubs/merb-app/public/.htaccess +17 -0
  49. data/benchmarks/stubs/merb-app/public/favicon.ico +0 -0
  50. data/benchmarks/stubs/merb-app/public/images/merb.jpg +0 -0
  51. data/benchmarks/stubs/merb-app/public/javascripts/application.js +1 -0
  52. data/benchmarks/stubs/merb-app/public/javascripts/jquery.js +19 -0
  53. data/benchmarks/stubs/merb-app/public/merb.fcgi +22 -0
  54. data/benchmarks/stubs/merb-app/public/robots.txt +5 -0
  55. data/benchmarks/stubs/merb-app/public/stylesheets/master.css +119 -0
  56. data/{spec/stubs/acqs/dir/lib_spec.rb → benchmarks/stubs/merb-app/spec/spec.opts} +0 -0
  57. data/benchmarks/stubs/merb-app/spec/spec_helper.rb +27 -0
  58. data/benchmarks/stubs/merb-app/tasks/doc.thor +151 -0
  59. data/benchmarks/stubs/merb-app/tasks/merb.thor/app_script.rb +33 -0
  60. data/benchmarks/stubs/merb-app/tasks/merb.thor/common.rb +70 -0
  61. data/benchmarks/stubs/merb-app/tasks/merb.thor/gem_ext.rb +127 -0
  62. data/benchmarks/stubs/merb-app/tasks/merb.thor/main.thor +152 -0
  63. data/benchmarks/stubs/merb-app/tasks/merb.thor/ops.rb +95 -0
  64. data/benchmarks/stubs/merb-app/tasks/merb.thor/utils.rb +42 -0
  65. data/benchmarks/stubs/merb-core/.gitignore +21 -0
  66. data/benchmarks/stubs/merb-core/Rakefile +35 -0
  67. data/benchmarks/stubs/merb-core/app/controllers/application.rb +4 -0
  68. data/benchmarks/stubs/merb-core/app/controllers/exceptions.rb +15 -0
  69. data/benchmarks/stubs/merb-core/app/helpers/global_helpers.rb +7 -0
  70. data/benchmarks/stubs/merb-core/app/views/exceptions/not_acceptable.html.erb +63 -0
  71. data/benchmarks/stubs/merb-core/app/views/exceptions/not_found.html.erb +47 -0
  72. data/benchmarks/stubs/merb-core/app/views/layout/application.html.erb +12 -0
  73. data/benchmarks/stubs/merb-core/autotest/discover.rb +1 -0
  74. data/benchmarks/stubs/merb-core/autotest/merb.rb +151 -0
  75. data/benchmarks/stubs/merb-core/autotest/merb_rspec.rb +167 -0
  76. data/benchmarks/stubs/merb-core/config/environments/development.rb +17 -0
  77. data/benchmarks/stubs/merb-core/config/environments/production.rb +12 -0
  78. data/benchmarks/stubs/merb-core/config/environments/rake.rb +13 -0
  79. data/benchmarks/stubs/merb-core/config/environments/staging.rb +12 -0
  80. data/benchmarks/stubs/merb-core/config/environments/test.rb +14 -0
  81. data/benchmarks/stubs/merb-core/config/init.rb +27 -0
  82. data/benchmarks/stubs/merb-core/config/rack.rb +13 -0
  83. data/benchmarks/stubs/merb-core/config/router.rb +43 -0
  84. data/benchmarks/stubs/merb-core/doc/rdoc/generators/merb_generator.rb +1364 -0
  85. data/benchmarks/stubs/merb-core/doc/rdoc/generators/template/merb/api_grease.js +640 -0
  86. data/benchmarks/stubs/merb-core/doc/rdoc/generators/template/merb/index.html.erb +37 -0
  87. data/benchmarks/stubs/merb-core/doc/rdoc/generators/template/merb/merb.css +252 -0
  88. data/benchmarks/stubs/merb-core/doc/rdoc/generators/template/merb/merb.rb +353 -0
  89. data/benchmarks/stubs/merb-core/doc/rdoc/generators/template/merb/merb_doc_styles.css +492 -0
  90. data/benchmarks/stubs/merb-core/doc/rdoc/generators/template/merb/prototype.js +2515 -0
  91. data/benchmarks/stubs/merb-core/public/.htaccess +17 -0
  92. data/benchmarks/stubs/merb-core/public/favicon.ico +0 -0
  93. data/benchmarks/stubs/merb-core/public/images/merb.jpg +0 -0
  94. data/benchmarks/stubs/merb-core/public/javascripts/application.js +1 -0
  95. data/benchmarks/stubs/merb-core/public/merb.fcgi +22 -0
  96. data/benchmarks/stubs/merb-core/public/robots.txt +5 -0
  97. data/benchmarks/stubs/merb-core/public/stylesheets/master.css +119 -0
  98. data/{spec/stubs/acqs/lib.rb → benchmarks/stubs/merb-core/spec/spec.opts} +0 -0
  99. data/benchmarks/stubs/merb-core/spec/spec_helper.rb +22 -0
  100. data/benchmarks/stubs/merb-core/tasks/merb.thor/app_script.rb +33 -0
  101. data/benchmarks/stubs/merb-core/tasks/merb.thor/common.rb +70 -0
  102. data/benchmarks/stubs/merb-core/tasks/merb.thor/gem_ext.rb +127 -0
  103. data/benchmarks/stubs/merb-core/tasks/merb.thor/main.thor +152 -0
  104. data/benchmarks/stubs/merb-core/tasks/merb.thor/ops.rb +95 -0
  105. data/benchmarks/stubs/merb-core/tasks/merb.thor/utils.rb +42 -0
  106. data/benchmarks/stubs/merb-flat/.gitignore +21 -0
  107. data/benchmarks/stubs/merb-flat/README.txt +10 -0
  108. data/benchmarks/stubs/merb-flat/Rakefile +35 -0
  109. data/benchmarks/stubs/merb-flat/application.rb +17 -0
  110. data/benchmarks/stubs/merb-flat/config/framework.rb +9 -0
  111. data/benchmarks/stubs/merb-flat/config/init.rb +42 -0
  112. data/benchmarks/stubs/merb-flat/spec/spec_helper.rb +26 -0
  113. data/benchmarks/stubs/merb-flat/tasks/merb.thor/app_script.rb +33 -0
  114. data/benchmarks/stubs/merb-flat/tasks/merb.thor/common.rb +70 -0
  115. data/benchmarks/stubs/merb-flat/tasks/merb.thor/gem_ext.rb +127 -0
  116. data/benchmarks/stubs/merb-flat/tasks/merb.thor/main.thor +152 -0
  117. data/benchmarks/stubs/merb-flat/tasks/merb.thor/ops.rb +95 -0
  118. data/benchmarks/stubs/merb-flat/tasks/merb.thor/utils.rb +42 -0
  119. data/benchmarks/stubs/merb-flat/views/foo.html.erb +3 -0
  120. data/benchmarks/stubs/merb-very-flat/.gitignore +21 -0
  121. data/benchmarks/stubs/merb-very-flat/Rakefile +35 -0
  122. data/benchmarks/stubs/merb-very-flat/merb-very-flat.rb +61 -0
  123. data/benchmarks/stubs/merb-very-flat/spec/spec_helper.rb +26 -0
  124. data/benchmarks/stubs/merb-very-flat/tasks/merb.thor/app_script.rb +33 -0
  125. data/benchmarks/stubs/merb-very-flat/tasks/merb.thor/common.rb +70 -0
  126. data/benchmarks/stubs/merb-very-flat/tasks/merb.thor/gem_ext.rb +127 -0
  127. data/benchmarks/stubs/merb-very-flat/tasks/merb.thor/main.thor +152 -0
  128. data/benchmarks/stubs/merb-very-flat/tasks/merb.thor/ops.rb +95 -0
  129. data/benchmarks/stubs/merb-very-flat/tasks/merb.thor/utils.rb +42 -0
  130. data/benchmarks/stubs/rails/README +243 -0
  131. data/benchmarks/stubs/rails/Rakefile +10 -0
  132. data/benchmarks/stubs/rails/app/controllers/application_controller.rb +12 -0
  133. data/benchmarks/stubs/rails/app/helpers/application_helper.rb +5 -0
  134. data/benchmarks/stubs/rails/config/boot.rb +112 -0
  135. data/benchmarks/stubs/rails/config/database.yml +22 -0
  136. data/benchmarks/stubs/rails/config/environment.rb +43 -0
  137. data/benchmarks/stubs/rails/config/environments/development.rb +19 -0
  138. data/benchmarks/stubs/rails/config/environments/production.rb +30 -0
  139. data/benchmarks/stubs/rails/config/environments/test.rb +30 -0
  140. data/benchmarks/stubs/rails/config/initializers/backtrace_silencers.rb +9 -0
  141. data/benchmarks/stubs/rails/config/initializers/inflections.rb +12 -0
  142. data/benchmarks/stubs/rails/config/initializers/mime_types.rb +7 -0
  143. data/benchmarks/stubs/rails/config/initializers/new_rails_defaults.rb +21 -0
  144. data/benchmarks/stubs/rails/config/initializers/session_store.rb +17 -0
  145. data/benchmarks/stubs/rails/config/locales/en.yml +5 -0
  146. data/benchmarks/stubs/rails/config/routes.rb +45 -0
  147. data/benchmarks/stubs/rails/doc/README_FOR_APP +2 -0
  148. data/{spec/stubs/acqs/tasks.thor → benchmarks/stubs/rails/log/development.log} +0 -0
  149. data/{stubs/stack/content/TODO.txt → benchmarks/stubs/rails/log/production.log} +0 -0
  150. data/benchmarks/stubs/rails/log/server.log +0 -0
  151. data/benchmarks/stubs/rails/log/test.log +0 -0
  152. data/benchmarks/stubs/rails/public/404.html +30 -0
  153. data/benchmarks/stubs/rails/public/422.html +30 -0
  154. data/benchmarks/stubs/rails/public/500.html +30 -0
  155. data/benchmarks/stubs/rails/public/favicon.ico +0 -0
  156. data/benchmarks/stubs/rails/public/images/rails.png +0 -0
  157. data/benchmarks/stubs/rails/public/index.html +275 -0
  158. data/benchmarks/stubs/rails/public/javascripts/application.js +2 -0
  159. data/benchmarks/stubs/rails/public/javascripts/controls.js +963 -0
  160. data/benchmarks/stubs/rails/public/javascripts/dragdrop.js +973 -0
  161. data/benchmarks/stubs/rails/public/javascripts/effects.js +1128 -0
  162. data/benchmarks/stubs/rails/public/javascripts/prototype.js +4320 -0
  163. data/benchmarks/stubs/rails/public/robots.txt +5 -0
  164. data/benchmarks/stubs/rails/script/about +4 -0
  165. data/benchmarks/stubs/rails/script/console +3 -0
  166. data/benchmarks/stubs/rails/script/dbconsole +3 -0
  167. data/benchmarks/stubs/rails/script/destroy +3 -0
  168. data/benchmarks/stubs/rails/script/generate +3 -0
  169. data/benchmarks/stubs/rails/script/performance/benchmarker +3 -0
  170. data/benchmarks/stubs/rails/script/performance/profiler +3 -0
  171. data/benchmarks/stubs/rails/script/plugin +3 -0
  172. data/benchmarks/stubs/rails/script/runner +3 -0
  173. data/benchmarks/stubs/rails/script/server +3 -0
  174. data/benchmarks/stubs/rails/test/performance/browsing_test.rb +11 -0
  175. data/benchmarks/stubs/rails/test/test_helper.rb +40 -0
  176. data/benchmarks/stubs/ramaze.rb +0 -0
  177. data/benchmarks/stubs/sinatra.rb +11 -0
  178. data/bin/rango +2 -2
  179. data/deps.rip +7 -0
  180. data/deps.rip.rbe +7 -0
  181. data/gems/cache/abstract-1.0.0.gem +0 -0
  182. data/gems/cache/code-cleaner-0.1.gem +0 -0
  183. data/gems/cache/code-cleaner-0.2.gem +0 -0
  184. data/gems/cache/code-cleaner-0.3.gem +0 -0
  185. data/gems/cache/code-cleaner-0.4.gem +0 -0
  186. data/gems/cache/code-cleaner-0.5.gem +0 -0
  187. data/gems/cache/code-cleaner-0.6.gem +0 -0
  188. data/gems/cache/code-cleaner-0.7.gem +0 -0
  189. data/gems/cache/code-cleaner-0.8.1.gem +0 -0
  190. data/gems/cache/code-cleaner-0.8.gem +0 -0
  191. data/gems/cache/erubis-2.6.5.gem +0 -0
  192. data/gems/cache/extlib-0.9.14.gem +0 -0
  193. data/gems/cache/haml-2.2.16.gem +0 -0
  194. data/gems/cache/haml-2.2.17.gem +0 -0
  195. data/gems/cache/nake-0.0.2.gem +0 -0
  196. data/gems/cache/nake-0.0.3.gem +0 -0
  197. data/gems/cache/nake-0.0.5.gem +0 -0
  198. data/gems/cache/nake-0.0.6.gem +0 -0
  199. data/gems/cache/nake-0.0.8.gem +0 -0
  200. data/gems/cache/rack-1.0.1.gem +0 -0
  201. data/gems/cache/rack-1.1.0.gem +0 -0
  202. data/gems/cache/rspec-1.2.9.gem +0 -0
  203. data/gems/cache/rspec-1.3.0.gem +0 -0
  204. data/gems/cache/term-ansicolor-1.0.4.gem +0 -0
  205. data/gems/cache/tilt-0.4.gem +0 -0
  206. data/gems/cache/tilt-0.5.gem +0 -0
  207. data/lib/rango.rb +28 -28
  208. data/lib/rango/cli.rb +34 -0
  209. data/lib/rango/contrib/pagination/adapters/datamapper.rb +21 -17
  210. data/lib/rango/controller.rb +36 -4
  211. data/lib/rango/environments.rb +1 -15
  212. data/lib/rango/exceptions.rb +144 -86
  213. data/lib/rango/helpers.rb +10 -2
  214. data/lib/rango/mailer.rb +48 -0
  215. data/lib/rango/mixins/action_args.rb +5 -7
  216. data/lib/rango/mixins/filters.rb +18 -14
  217. data/lib/rango/mixins/message.rb +30 -24
  218. data/lib/rango/mixins/rendering.rb +54 -0
  219. data/lib/rango/orm/tasks/datamapper.nake +81 -0
  220. data/lib/rango/orm/tasks/sequel.nake +43 -0
  221. data/lib/rango/router/adapters/usher.rb +2 -1
  222. data/lib/rango/stacks/controller.rb +12 -0
  223. data/lib/rango/tasks/spec.nake +9 -0
  224. data/lib/rango/templates/exts/haml.rb +1 -1
  225. data/lib/rango/templates/exts/tilt.rb +10 -0
  226. data/lib/rango/templates/helpers.rb +29 -25
  227. data/lib/rango/templates/template.rb +7 -6
  228. data/rango.gemspec +52 -0
  229. data/rango.pre.gemspec +8 -0
  230. data/spec/rango/environments_spec.rb +1 -1
  231. data/spec/rango/exceptions_spec.rb +8 -7
  232. data/spec/rango/mixins/render_spec.rb +1 -1
  233. data/spec/rango/templates/template_spec.rb +1 -1
  234. data/stubs/stack/content/%name%.gemspec.rbt +52 -0
  235. data/stubs/stack/content/%name%.pre.gemspec.rbt +8 -0
  236. data/stubs/stack/content/CHANGELOG +0 -0
  237. data/stubs/stack/content/Gemfile.rbt +22 -11
  238. data/stubs/stack/content/README.textile.rbt +7 -0
  239. data/stubs/stack/content/config.ru.rbt +33 -62
  240. data/stubs/stack/content/deps.rip +0 -0
  241. data/stubs/stack/content/init.rb.rbt +14 -39
  242. data/stubs/stack/content/lib/%name%.rb.rbt +8 -0
  243. data/stubs/stack/content/lib/%name%/config.rb.rbt +0 -0
  244. data/stubs/stack/content/{environments.rb.rbt → lib/%name%/environments/development.rb.rbt} +5 -0
  245. data/stubs/stack/content/lib/%name%/environments/production.rb.rbt +0 -0
  246. data/stubs/stack/content/lib/%name%/environments/stagging.rb.rbt +0 -0
  247. data/stubs/stack/content/lib/%name%/initializers/middlewares.rb.rbt +5 -0
  248. data/stubs/stack/content/lib/%name%/initializers/urls.rb.rbt +24 -0
  249. data/stubs/stack/content/{models.rb.rbt → lib/%name%/models.rb.rbt} +7 -0
  250. data/stubs/stack/content/{views.rb.rbt → lib/%name%/views.rb.rbt} +2 -8
  251. data/stubs/stack/content/rackup.rb.rbt +41 -0
  252. data/stubs/stack/content/tasks.rb.rbt +52 -0
  253. data/stubs/stack/setup.rb +7 -1
  254. data/support/hooks/pre-commit +12 -0
  255. data/tasks.rb +49 -0
  256. metadata +250 -54
  257. data/Rakefile +0 -33
  258. data/lib/rango/rack/middlewares/email_obfuscator.rb +0 -25
  259. data/lib/rango/version.rb +0 -7
  260. data/stubs/stack/content/.rvmrc.rbt +0 -2
  261. data/stubs/stack/content/Rakefile.rbt +0 -12
@@ -3,22 +3,12 @@
3
3
  # http://wiki.github.com/botanicus/rango/environments-support
4
4
 
5
5
  module Rango
6
- # @since 0.0.1
7
- # @return [String] Returns current environment name.
8
- def self.environment
9
- @@environment ||= "development"
10
- end
11
-
12
- def self.environment=(environment)
13
- @@environment = environment
14
- end
15
-
16
6
  # clever environments support
17
7
  def self.environments
18
8
  @@environments ||= {
19
9
  development: ["development"],
20
10
  testing: ["test", "spec", "cucumber"],
21
- production: ["stage", "production"]
11
+ production: ["stagging", "production"]
22
12
  }
23
13
  end
24
14
 
@@ -33,8 +23,4 @@ module Rango
33
23
  def self.production?
34
24
  self.environments[:production].include?(Rango.environment)
35
25
  end
36
-
37
- def self.environment?(environment)
38
- self.environment.eql?(environment.to_s)
39
- end
40
26
  end
@@ -2,102 +2,160 @@
2
2
 
3
3
  # http://wiki.github.com/botanicus/rango/errors-handling
4
4
 
5
+ require "uri"
6
+
5
7
  # superclass of all the controller exceptions
6
8
  module Rango
7
- class HttpError < StandardError
8
- CONTENT_TYPE ||= "text/html"
9
+ module Exceptions
10
+ class HttpError < StandardError
11
+ def self.name=(name)
12
+ @name = name
13
+ end
9
14
 
10
- attr_accessor :content_type, :headers
11
- def initialize(*args)
12
- @headers = Hash.new
13
- super(*args)
14
- end
15
+ def self.name
16
+ @name
17
+ end
15
18
 
16
- def inspect
17
- self.to_response.inspect
18
- end
19
+ def name
20
+ @name ||= self.class.name
21
+ end
19
22
 
20
- # @returns [String]
21
- # @example NotFound.new.to_snakecase # "not_found"
22
- def to_snakecase
23
- self.class.name.split("::").last.snake_case
24
- end
23
+ def self.message=(message)
24
+ @message = message
25
+ end
25
26
 
26
- def status() self.class::STATUS end
27
- def content_type
28
- @content_type || self.class::CONTENT_TYPE
29
- end
27
+ def self.message
28
+ @message ||= begin
29
+ self.superclass.message
30
+ rescue NoMethodError
31
+ end
32
+ end
33
+
34
+ attr_writer :message
35
+ def message
36
+ @message ||= self.class.message
37
+ end
38
+
39
+ def self.status=(status)
40
+ @status = status
41
+ end
42
+
43
+ def self.status
44
+ @status ||= begin
45
+ self.superclass.status
46
+ rescue NoMethodError
47
+ end
48
+ end
49
+
50
+ # If we have a redirection but we don't know the status yet,
51
+ # then rather than use raise Error301 we create a new instance
52
+ # of the Redirection class and set the status manualy
53
+ attr_writer :status
54
+
55
+ def status
56
+ @status ||= self.class.status
57
+ end
30
58
 
31
- def to_response
32
- headers = {"Content-Type" => self.content_type}.merge(self.headers)
33
- [self.status, headers, [self.message]]
59
+ def self.headers
60
+ @headers ||= {"Content-Type" => "text/html"}
61
+ end
62
+
63
+ def headers
64
+ @headers ||= self.class.headers.dup
65
+ end
66
+
67
+ # raise Redirection.new("/", 301)
68
+ def initialize(message = self.class.name, status = nil)
69
+ self.status = status unless status.nil?
70
+ self.message = message
71
+ end
72
+
73
+ def inspect
74
+ self.to_response.inspect
75
+ end
76
+
77
+ # @returns [String]
78
+ # @example NotFound.new.to_snakecase # "not_found"
79
+ def to_snakecase
80
+ self.class.name.split("::").last.snake_case
81
+ end
82
+
83
+ def to_response
84
+ [self.status, self.headers, [self.message].compact]
85
+ end
34
86
  end
35
87
 
36
- def self.const_missing(name)
37
- if [:STATUS, :CONTENT_TYPE].include?(name)
38
- raise NameError, "Every descendant of HttpError class has to have defined constant #{name}."
39
- else
40
- super(name)
88
+ # http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
89
+
90
+ # informational
91
+ Informational = Class.new(HttpError)
92
+ Error100 = Continue = Class.new(Informational) { self.status ||= 100; self.name ||= "Continue" }
93
+ Error101 = SwitchingProtocols = Class.new(Informational) { self.status ||= 101; self.name ||= "Switching Protocols" }
94
+
95
+ # successful
96
+ Successful = Class.new(HttpError)
97
+ Error200 = OK = Class.new(Successful) { self.status ||= 200; self.name ||= "OK" }
98
+ Error201 = Created = Class.new(Successful) { self.status ||= 201; self.name ||= "Created" }
99
+ Error202 = Accepted = Class.new(Successful) { self.status ||= 202; self.name ||= "Accepted" }
100
+ Error203 = NonAuthoritativeInformation = Class.new(Successful) { self.status ||= 203; self.name ||= "Non Authoritative Information" }
101
+ Error204 = NoContent = Class.new(Successful) { self.status ||= 204; self.name ||= "No Content" }
102
+ Error205 = ResetContent = Class.new(Successful) { self.status ||= 205; self.name ||= "Reset Content" }
103
+ Error206 = PartialContent = Class.new(Successful) { self.status ||= 206; self.name ||= "Partial Content" }
104
+
105
+ # redirection
106
+ class Redirection < HttpError
107
+ self.name ||= "Redirection"
108
+ alias_method :location, :message
109
+
110
+ # use raise MovedPermanently, "http://example.com"
111
+ # Yes, you can use just redirect method from the controller, but
112
+ # this will work even in filters or in environments without controllers
113
+ # raise Redirection.new("/", 301)
114
+ def initialize(location, status = nil)
115
+ super(location, status)
116
+ location = URI.escape(location)
117
+ headers["Location"] = location
41
118
  end
42
119
  end
43
- end
44
120
 
45
- # http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
46
-
47
- # informational
48
- Informational = Class.new(Rango::HttpError)
49
- Error100 = Continue = Class.new(Rango::Informational) { STATUS ||= 100 }
50
- Error101 = SwitchingProtocols = Class.new(Rango::Informational) { STATUS ||= 101 }
51
-
52
- # successful
53
- Successful = Class.new(Rango::HttpError)
54
- Error200 = OK = Class.new(Rango::Successful) { STATUS ||= 200 }
55
- Error201 = Created = Class.new(Rango::Successful) { STATUS ||= 201 }
56
- Error202 = Accepted = Class.new(Rango::Successful) { STATUS ||= 202 }
57
- Error203 = NonAuthoritativeInformation = Class.new(Rango::Successful) { STATUS ||= 203 }
58
- Error204 = NoContent = Class.new(Rango::Successful) { STATUS ||= 204 }
59
- Error205 = ResetContent = Class.new(Rango::Successful) { STATUS ||= 205 }
60
- Error206 = PartialContent = Class.new(Rango::Successful) { STATUS ||= 206 }
61
-
62
- # redirection
63
- Redirection = Class.new(Rango::HttpError)
64
- Error300 = MultipleChoices = Class.new(Rango::Redirection) { STATUS ||= 300 }
65
- Error301 = MovedPermanently = Class.new(Rango::Redirection) { STATUS ||= 301 }
66
- Error302 = MovedTemporarily = Class.new(Rango::Redirection) { STATUS ||= 302 }
67
- Error303 = SeeOther = Class.new(Rango::Redirection) { STATUS ||= 303 }
68
- Error304 = NotModified = Class.new(Rango::Redirection) { STATUS ||= 304 }
69
- Error305 = UseProxy = Class.new(Rango::Redirection) { STATUS ||= 305 }
70
- Error307 = TemporaryRedirect = Class.new(Rango::Redirection) { STATUS ||= 307 }
71
-
72
- # client error
73
- ClientError = Class.new(Rango::HttpError)
74
- Error400 = BadRequest = Class.new(Rango::ClientError) { STATUS ||= 400 }
75
- MultiPartParseError = Class.new(Rango::BadRequest)
76
- Error401 = Unauthorized = Class.new(Rango::ClientError) { STATUS ||= 401 }
77
- Error402 = PaymentRequired = Class.new(Rango::ClientError) { STATUS ||= 402 }
78
- Error403 = Forbidden = Class.new(Rango::ClientError) { STATUS ||= 403 }
79
- Error404 = NotFound = Class.new(Rango::ClientError) { STATUS ||= 404 }
80
- ActionNotFound = Class.new(Rango::NotFound)
81
- Error405 = MethodNotAllowed = Class.new(Rango::ClientError) { STATUS ||= 405 }
82
- Error406 = NotAcceptable = Class.new(Rango::ClientError) { STATUS ||= 406 }
83
- Error407 = ProxyAuthenticationRequired = Class.new(Rango::ClientError) { STATUS ||= 407 }
84
- Error408 = RequestTimeout = Class.new(Rango::ClientError) { STATUS ||= 408 }
85
- Error409 = Conflict = Class.new(Rango::ClientError) { STATUS ||= 409 }
86
- Error410 = Gone = Class.new(Rango::ClientError) { STATUS ||= 410 }
87
- Error411 = LengthRequired = Class.new(Rango::ClientError) { STATUS ||= 411 }
88
- Error412 = PreconditionFailed = Class.new(Rango::ClientError) { STATUS ||= 412 }
89
- Error413 = RequestEntityTooLarge = Class.new(Rango::ClientError) { STATUS ||= 413 }
90
- Error414 = RequestURITooLarge = Class.new(Rango::ClientError) { STATUS ||= 414 }
91
- Error415 = UnsupportedMediaType = Class.new(Rango::ClientError) { STATUS ||= 415 }
92
- Error416 = RequestRangeNotSatisfiable = Class.new(Rango::ClientError) { STATUS ||= 416 }
93
- Error417 = ExpectationFailed = Class.new(Rango::ClientError) { STATUS ||= 417 }
94
-
95
- # server error
96
- ServerError = Class.new(Rango::HttpError)
97
- Error500 = InternalServerError = Class.new(Rango::ServerError) { STATUS ||= 500 }
98
- Error501 = NotImplemented = Class.new(Rango::ServerError) { STATUS ||= 501 }
99
- Error502 = BadGateway = Class.new(Rango::ServerError) { STATUS ||= 502 }
100
- Error503 = ServiceUnavailable = Class.new(Rango::ServerError) { STATUS ||= 503 }
101
- Error504 = GatewayTimeout = Class.new(Rango::ServerError) { STATUS ||= 504 }
102
- Error505 = HTTPVersionNotSupported = Class.new(Rango::ServerError) { STATUS ||= 505 }
121
+ Error300 = MultipleChoices = Class.new(Redirection) { self.status ||= 300; self.name ||= "Multiple Choices" }
122
+ Error301 = MovedPermanently = Class.new(Redirection) { self.status ||= 301; self.name ||= "Moved Permanently" }
123
+ Error302 = MovedTemporarily = Class.new(Redirection) { self.status ||= 302; self.name ||= "Moved Temporarily" }
124
+ Error303 = SeeOther = Class.new(Redirection) { self.status ||= 303; self.name ||= "See Other" }
125
+ Error304 = NotModified = Class.new(Redirection) { self.status ||= 304; self.name ||= "Not Modified" }
126
+ Error305 = UseProxy = Class.new(Redirection) { self.status ||= 305; self.name ||= "Use Proxy" }
127
+ Error307 = TemporaryRedirect = Class.new(Redirection) { self.status ||= 307; self.name ||= "Temporary Redirect" }
128
+
129
+ # client error
130
+ ClientError = Class.new(HttpError)
131
+ Error400 = BadRequest = Class.new(ClientError) { self.status ||= 400; self.name ||= "Bad Request" }
132
+ MultiPartParseError = Class.new(BadRequest)
133
+ Error401 = Unauthorized = Class.new(ClientError) { self.status ||= 401; self.name ||= "Unauthorized" }
134
+ Error402 = PaymentRequired = Class.new(ClientError) { self.status ||= 402; self.name ||= "Payment Required" }
135
+ Error403 = Forbidden = Class.new(ClientError) { self.status ||= 403; self.name ||= "Forbidden" }
136
+ Error404 = NotFound = Class.new(ClientError) { self.status ||= 404; self.name ||= "Not Found" }
137
+ ActionNotFound = Class.new(NotFound)
138
+ Error405 = MethodNotAllowed = Class.new(ClientError) { self.status ||= 405; self.name ||= "Method Not Allowed" }
139
+ Error406 = NotAcceptable = Class.new(ClientError) { self.status ||= 406; self.name ||= "Not Acceptable" }
140
+ Error407 = ProxyAuthenticationRequired = Class.new(ClientError) { self.status ||= 407; self.name ||= "Proxy Authentication Required" }
141
+ Error408 = RequestTimeout = Class.new(ClientError) { self.status ||= 408; self.name ||= "Request Timeout" }
142
+ Error409 = Conflict = Class.new(ClientError) { self.status ||= 409; self.name ||= "Conflict" }
143
+ Error410 = Gone = Class.new(ClientError) { self.status ||= 410; self.name ||= "Gone" }
144
+ Error411 = LengthRequired = Class.new(ClientError) { self.status ||= 411; self.name ||= "Length Required" }
145
+ Error412 = PreconditionFailed = Class.new(ClientError) { self.status ||= 412; self.name ||= "Precondition Failed" }
146
+ Error413 = RequestEntityTooLarge = Class.new(ClientError) { self.status ||= 413; self.name ||= "Request Entity Too Large" }
147
+ Error414 = RequestURITooLarge = Class.new(ClientError) { self.status ||= 414; self.name ||= "Request URI Too Large" }
148
+ Error415 = UnsupportedMediaType = Class.new(ClientError) { self.status ||= 415; self.name ||= "Unsupported Media Type" }
149
+ Error416 = RequestRangeNotSatisfiable = Class.new(ClientError) { self.status ||= 416; self.name ||= "Request Range Not Satisfiable" }
150
+ Error417 = ExpectationFailed = Class.new(ClientError) { self.status ||= 417; self.name ||= "Expectation Failed" }
151
+
152
+ # server error
153
+ ServerError = Class.new(HttpError)
154
+ Error500 = InternalServerError = Class.new(ServerError) { self.status ||= 500; self.name ||= "Internal Server Error" }
155
+ Error501 = NotImplemented = Class.new(ServerError) { self.status ||= 501; self.name ||= "Not Implemented" }
156
+ Error502 = BadGateway = Class.new(ServerError) { self.status ||= 502; self.name ||= "Bad Gateway" }
157
+ Error503 = ServiceUnavailable = Class.new(ServerError) { self.status ||= 503; self.name ||= "Service Unavailable" }
158
+ Error504 = GatewayTimeout = Class.new(ServerError) { self.status ||= 504; self.name ||= "Gateway Timeout" }
159
+ Error505 = HTTPVersionNotSupported = Class.new(ServerError) { self.status ||= 505; self.name ||= "HTTP Version Not Supported" }
160
+ end
103
161
  end
data/lib/rango/helpers.rb CHANGED
@@ -8,12 +8,20 @@ module Rango
8
8
  def tag(tag, content, attrs = Hash.new, &block)
9
9
  attrs, content = content, String.new if attrs.empty? && content.is_a?(Hash)
10
10
  block.call if block
11
- %[<#{tag} #{attrs.to_html_attrs}>#{content}</#{tag}>]
11
+ %[<#{tag}#{attrs_to_html(attrs)}>#{content}</#{tag}>]
12
12
  end
13
13
 
14
14
  # @since 0.0.2
15
15
  def single_tag(tag, attrs = Hash.new)
16
- %[<#{tag} #{attrs.to_html_attrs} />]
16
+ %[<#{tag}#{attrs_to_html(attrs)} />]
17
+ end
18
+
19
+ private
20
+ def attrs_to_html(attrs)
21
+ attrs.inject(String.new) do |result, pair|
22
+ key, value = pair
23
+ result += " #{key}='#{value}'"
24
+ end
17
25
  end
18
26
  end
19
27
  end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ require "net/smtp"
4
+
5
+ # Mailer.new("noreply@rangoproject.org", "RangoProject.org")
6
+ # self.to = "tony@example.com"
7
+ # self.subject = "Just hey"
8
+ # self.body = "Hey Tony, what's up?"
9
+ # end
10
+ module Rango
11
+ class Mailer
12
+ @@config = {smtp: ["localhost", 25]}
13
+
14
+ def self.mail(options = Hash.new)
15
+ self.new(options[:from]).tap do |mailer|
16
+ mailer.body = options[:body]
17
+ end
18
+ end
19
+
20
+ attr_accessor :to, :to_alias
21
+ attr_accessor :from, :from_alias
22
+ attr_accessor :body, :subject
23
+
24
+ def initialize(from, from_alias = from, &block)
25
+ @from, @from_alias = from, from_alias
26
+ unless block.nil?
27
+ block.instance_eval(&block)
28
+ block.send
29
+ end
30
+ end
31
+
32
+ def raw
33
+ <<-EOF
34
+ From: #{from_alias} <#{from}>
35
+ To: #{to_alias} <#{to}>
36
+ Subject: #{subject}
37
+
38
+ #{body}
39
+ EOF
40
+ end
41
+
42
+ def send(to)
43
+ Net::SMTP.start(*@@config[:smtp]) do |smtp|
44
+ smtp.send_message(self.raw, @from, to)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -10,11 +10,9 @@
10
10
  # => [[:req, :name], [:opt, :params], [:rest, :args]]
11
11
 
12
12
  if RUBY_VERSION < "1.9.2"
13
- begin
14
- require "methopara"
15
- rescue LoadError
16
- raise LoadError, "Method#parameters is part of Ruby 1.9.2 and higher. If you want to use this feature with Ruby 1.9.1, you have to install methopara gem (http://github.com/genki/methopara)"
17
- end
13
+ raise <<-EOF
14
+ Method#parameters is a part of Ruby 1.9.2 and higher, you can't use it with Ruby #{RUBY_VERSION}.
15
+ EOF
18
16
  end
19
17
 
20
18
  module Rango
@@ -41,8 +39,8 @@ module Rango
41
39
  view.parameters.each do |type, name|
42
40
  args.push(self.params[name]) if type.eql?(:req) || (type.eql?(:opt) && !self.params[name].nil?) # this is a bit complex, but we have to do because of rewriting optional args by nil value if we use just map with params[name]
43
41
  end
44
- puts "Rendering #{self}##{action} with #{args.map(&:inspect).join(", ")}"
45
- self.send(action, *args)
42
+ puts "Rendering #{self.class}##{action} with #{args.map(&:inspect).join(", ")}"
43
+ self.response.body = self.send(action, *args)
46
44
  end
47
45
  end
48
46
  end
@@ -7,18 +7,18 @@ module Rango
7
7
  end
8
8
 
9
9
  # for Rango::Controller
10
- def process_action(method)
11
- self.run_filters(:before, method)
12
- super(method)
13
- self.run_filters(:after, method)
10
+ def invoke_action(action)
11
+ self.run_filters(:before, action)
12
+ super(action)
13
+ self.run_filters(:after, action)
14
14
  end
15
15
 
16
16
  # @since 0.0.2
17
- def run_filters(name, method)
17
+ def run_filters(name, action)
18
18
  # Rango.logger.debug(self.class.instance_variables)
19
- # #Rango.logger.inspect(name: name, method: method)
19
+ # Rango.logger.inspect(name: name, action: action)
20
20
  self.class.get_filters(name).each do |filter_method, options|
21
- unless options[:except] && options[:except].include?(method)
21
+ unless options[:except] && options[:except].include?(action)
22
22
  if filter_method.is_a?(Symbol) && self.respond_to?(filter_method)
23
23
  Rango.logger.info("Calling filter #{filter_method} for controller #{self}")
24
24
  self.send(filter_method)
@@ -33,23 +33,27 @@ module Rango
33
33
  end
34
34
 
35
35
  module ClassMethods
36
- #def inherited(subclass)
37
- # subclass.before_filters = self.before_filters.dup
38
- # subclass.after_filters = self.after_filters.dup
39
- #end
36
+ # If you are using your own inherited hook, you have
37
+ # to use super here, otherwise your filters won't work!
38
+ def inherited(subclass)
39
+ subclass.before_filters.replace(self.before_filters)
40
+ subclass.after_filters.replace(self.after_filters)
41
+ end
40
42
 
41
43
  # @since 0.2
44
+ # we can't use class variables because they
45
+ # are shared between parent and child classes
42
46
  def before_filters
43
- @@before_filters ||= Hash.new
47
+ @before_filters ||= Hash.new
44
48
  end
45
49
 
46
50
  # @since 0.2
47
51
  def after_filters
48
- @@after_filters ||= Hash.new
52
+ @after_filters ||= Hash.new
49
53
  end
50
54
 
51
55
  # before :login
52
- # before :login, actions: [:send]
56
+ # before :login, except: [:send]
53
57
  # @since 0.0.2
54
58
  def before(action = nil, options = Hash.new, &block)
55
59
  self.before_filters[action || block] = options
@@ -1,44 +1,50 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require "rango/mixins/chainable"
4
+
3
5
  module Rango
4
6
  module MessageMixin
5
7
  # The rails-style flash messages
6
8
  # @since 0.0.2
7
9
  # NOTE: it's important to include this mixin after ImplicitRendering mixin
8
10
  def self.included(controller)
11
+ unless controller.method_defined?(:request)
12
+ raise "Rango::MessageMixin requires method request to be defined"
13
+ end
9
14
  if controller.method_defined?(:context)
15
+ Rango.logger.debug("Extending context by message")
10
16
  controller.class_eval do
11
- def context
12
- @context ||= super.merge!(message: self.message)
17
+ extend Chainable
18
+ chainable do
19
+ def context
20
+ super.merge!(message: self.message)
21
+ end
22
+
23
+ def redirect(uri, status = 301, options = Hash.new)
24
+ status, options = 301, status if status.is_a?(Hash)
25
+ if options.respond_to?(:inject)
26
+ # redirect "/post", error: "Try again"
27
+ # ?msg[error]="Try again"
28
+ uri = options.inject(uri) do |uri, pair|
29
+ type, message = pair
30
+ uri + "?msg[#{type}]=#{message}"
31
+ end
32
+ else
33
+ # redirect "/post", "Try again"
34
+ # ?msg="Try again"
35
+ uri.concat("?msg=#{options}")
36
+ end
37
+ super(uri, status)
38
+ end
13
39
  end
14
40
  end
41
+ else
42
+ Rango.logger.warn("Context method isn't defined")
15
43
  end
16
44
  end
17
45
 
18
46
  def message
19
47
  @message ||= (request.GET[:msg] || Hash.new)
20
48
  end
21
-
22
- # @since 0.0.2
23
- def redirect(url, options = Hash.new)
24
- url = [self.request.base_url.chomp("/"), url].join("/").chomp("/") unless url.match(/^http/)
25
-
26
- if options.respond_to?(:inject)
27
- # redirect "/post", error: "Try again"
28
- # ?msg[error]="Try again"
29
- url = options.inject(url) do |url, pair|
30
- type, message = pair
31
- url + "?msg[#{type}]=#{message}"
32
- end
33
- else
34
- # redirect "/post", "Try again"
35
- # ?msg="Try again"
36
- url.concat("?msg=#{options}")
37
- end
38
-
39
- self.status = 302
40
- self.headers["Location"] = URI.escape(url)
41
- return String.new
42
- end
43
49
  end
44
50
  end