rad_core 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (258) hide show
  1. data/Rakefile +10 -0
  2. data/lib/rad/controller/abstract_controller/micelaneous.rb +31 -0
  3. data/lib/rad/controller/abstract_controller/render.rb +160 -0
  4. data/lib/rad/controller/abstract_controller/responder.rb +17 -0
  5. data/lib/rad/controller/abstract_controller.rb +64 -0
  6. data/lib/rad/controller/controller_context.rb +15 -0
  7. data/lib/rad/controller/http_controller.rb +48 -0
  8. data/lib/rad/controller/processors/controller_caller.rb +28 -0
  9. data/lib/rad/controller/processors/controller_error_handling.rb +51 -0
  10. data/lib/rad/controller/processors/controller_logger.rb +12 -0
  11. data/lib/rad/controller.rb +28 -0
  12. data/lib/rad/conveyor/conveyor.rb +74 -0
  13. data/lib/rad/conveyor/conveyors.rb +20 -0
  14. data/lib/rad/conveyor/params.rb +14 -0
  15. data/lib/rad/conveyor/processor.rb +68 -0
  16. data/lib/rad/conveyor/processors/conveyor_logger.rb +25 -0
  17. data/lib/rad/conveyor/workspace.rb +36 -0
  18. data/lib/rad/conveyor.rb +29 -0
  19. data/lib/rad/environment/config.rb +111 -0
  20. data/lib/rad/environment/dependency_resolver.rb +107 -0
  21. data/lib/rad/environment/environment.rb +29 -0
  22. data/lib/rad/environment/files_helper.rb +55 -0
  23. data/lib/rad/environment/logger.rb +21 -0
  24. data/lib/rad/environment.rb +55 -0
  25. data/lib/rad/html/flash.rb +42 -0
  26. data/lib/rad/html/helpers/basic_html_helper.rb +83 -0
  27. data/lib/rad/html/helpers/flash_helper.rb +5 -0
  28. data/lib/rad/html/helpers/form_helper.rb +115 -0
  29. data/lib/rad/html/helpers/html_helper.rb +5 -0
  30. data/lib/rad/html/helpers/javascript_helper.rb +18 -0
  31. data/lib/rad/html/helpers/model_helper.rb +135 -0
  32. data/lib/rad/html/include_into_controller.rb +0 -0
  33. data/lib/rad/html/processors/prepare_flash.rb +26 -0
  34. data/lib/rad/html/processors/scoped_params.rb +26 -0
  35. data/lib/rad/html.rb +26 -0
  36. data/lib/rad/http/http.rb +21 -0
  37. data/lib/rad/http/http_adapter.rb +36 -0
  38. data/lib/rad/http/middleware/static_files.rb +21 -0
  39. data/lib/rad/http/processors/evaluate_format.rb +22 -0
  40. data/lib/rad/http/processors/http_logger.rb +15 -0
  41. data/lib/rad/http/processors/http_writer.rb +30 -0
  42. data/lib/rad/http/processors/prepare_params.rb +22 -0
  43. data/lib/rad/http/support/rack/fixes.rb +36 -0
  44. data/lib/rad/http/support/rack/rack_adapter.rb +67 -0
  45. data/lib/rad/http/support/rack/request.rb +42 -0
  46. data/lib/rad/http/support/rack/response.rb +86 -0
  47. data/lib/rad/http.rb +48 -0
  48. data/lib/rad/integration/controller_micelaneous_helper.rb +19 -0
  49. data/lib/rad/integration/router/abstract_routing_helper.rb +22 -0
  50. data/lib/rad/integration/router/controller_routing_helper.rb +58 -0
  51. data/lib/rad/integration/router/view_routing_helper.rb +104 -0
  52. data/lib/rad/integration.rb +30 -0
  53. data/lib/rad/mail/letter.rb +30 -0
  54. data/lib/rad/mail/mail_controller.rb +31 -0
  55. data/lib/rad/mail/mailer.rb +23 -0
  56. data/lib/rad/mail/processors/letter_builder.rb +36 -0
  57. data/lib/rad/mail.rb +15 -0
  58. data/lib/rad/profiles/mail.rb +16 -0
  59. data/lib/rad/profiles/web.rb +68 -0
  60. data/lib/rad/profiles/web_require.rb +5 -0
  61. data/lib/rad/remote/processors/remote_caller.rb +54 -0
  62. data/lib/rad/remote/processors/remote_logger.rb +13 -0
  63. data/lib/rad/remote/remote.rb +15 -0
  64. data/lib/rad/remote.rb +9 -0
  65. data/lib/rad/router/core/configurator.rb +25 -0
  66. data/lib/rad/router/core/core_routing_helper.rb +41 -0
  67. data/lib/rad/router/core/default_format_processor.rb +12 -0
  68. data/lib/rad/router/core/processors/router.rb +29 -0
  69. data/lib/rad/router/core/router.rb +271 -0
  70. data/lib/rad/router/core/simple_router.rb +23 -0
  71. data/lib/rad/router/routers/abstract_router.rb +62 -0
  72. data/lib/rad/router/routers/alias_router.rb +113 -0
  73. data/lib/rad/router/routers/restful_router.rb +113 -0
  74. data/lib/rad/router.rb +29 -0
  75. data/lib/rad/spec/controller.rb +41 -0
  76. data/lib/rad/spec/environment.rb +51 -0
  77. data/lib/rad/spec/http.rb +93 -0
  78. data/lib/rad/spec/mail.rb +31 -0
  79. data/lib/rad/spec/remote.rb +9 -0
  80. data/lib/rad/spec/router.rb +18 -0
  81. data/lib/rad/spec/template.rb +12 -0
  82. data/lib/rad/spec/view.rb +10 -0
  83. data/lib/rad/spec/xhtml.rb +33 -0
  84. data/lib/rad/spec.rb +11 -0
  85. data/lib/rad/support/active_support/locales/en/actionpack.yml +154 -0
  86. data/lib/rad/support/active_support/locales/en/activesupport.yml +36 -0
  87. data/lib/rad/support/active_support/micelaneous.rb +2 -0
  88. data/lib/rad/support/active_support/time.rb +105 -0
  89. data/lib/rad/support/active_support.rb +49 -0
  90. data/lib/rad/support/addressable.rb +45 -0
  91. data/lib/rad/support/buffered_logger.rb +44 -0
  92. data/lib/rad/support/callbacks.rb +168 -0
  93. data/lib/rad/support/exception.rb +31 -0
  94. data/lib/rad/support/filters.rb +34 -0
  95. data/lib/rad/support/format.rb +17 -0
  96. data/lib/rad/support/hacks_and_fixes.rb +23 -0
  97. data/lib/rad/support/micon.rb +13 -0
  98. data/lib/rad/support/mime.rb +13 -0
  99. data/lib/rad/support/module.rb +48 -0
  100. data/lib/rad/support/rson.rb +53 -0
  101. data/lib/rad/support/ruby_ext_with_active_support.rb +4 -0
  102. data/lib/rad/support/string.rb +26 -0
  103. data/lib/rad/support.rb +63 -0
  104. data/lib/rad/template/support/tilt.rb +68 -0
  105. data/lib/rad/template/support/tilt_fixes.rb +17 -0
  106. data/lib/rad/template/template.rb +250 -0
  107. data/lib/rad/template/template_context.rb +62 -0
  108. data/lib/rad/template.rb +25 -0
  109. data/lib/rad_core/gems.rb +31 -0
  110. data/readme.md +33 -0
  111. data/spec/controller/abstract_controller_spec/views/OperationsOrderSpec/action.erb +1 -0
  112. data/spec/controller/abstract_controller_spec/views/ViewVariablesSpec/action.erb +11 -0
  113. data/spec/controller/abstract_controller_spec.rb +132 -0
  114. data/spec/controller/controller_context_spec/views/ItemSpec/actions.erb +4 -0
  115. data/spec/controller/controller_context_spec/views/ItemSpec/show.erb +0 -0
  116. data/spec/controller/controller_context_spec/views/ItemSpec/update.erb +0 -0
  117. data/spec/controller/controller_context_spec/views/NamespaceSpec/ClassSpec/show.erb +0 -0
  118. data/spec/controller/controller_context_spec/views/PageSpec/actions.erb +3 -0
  119. data/spec/controller/controller_context_spec/views/PageSpec/show.erb +0 -0
  120. data/spec/controller/controller_context_spec/views/namespace_spec/class_spec/update.erb +0 -0
  121. data/spec/controller/controller_context_spec.rb +123 -0
  122. data/spec/controller/controller_helper_spec/views/HelperMethodSpec/action.erb +1 -0
  123. data/spec/controller/controller_helper_spec/views/HelperSpec/action.erb +1 -0
  124. data/spec/controller/controller_helper_spec.rb +53 -0
  125. data/spec/controller/controller_render_spec/views/AlreadyRenderedSpec/action.erb +1 -0
  126. data/spec/controller/controller_render_spec/views/AlreadyRenderedSpec/custom_template.erb +1 -0
  127. data/spec/controller/controller_render_spec/views/AnotherActionSpec/another_action.erb +1 -0
  128. data/spec/controller/controller_render_spec/views/AnotherLayout/action.erb +1 -0
  129. data/spec/controller/controller_render_spec/views/ForbidPartialAsActionSpec/_action.erb +1 -0
  130. data/spec/controller/controller_render_spec/views/FormatSpec/action.html.erb +1 -0
  131. data/spec/controller/controller_render_spec/views/FormatSpec/action.js.erb +1 -0
  132. data/spec/controller/controller_render_spec/views/LayoutFiltersSpec/action_with_layout.erb +1 -0
  133. data/spec/controller/controller_render_spec/views/LayoutFiltersSpec/action_without_layout.erb +1 -0
  134. data/spec/controller/controller_render_spec/views/LayoutSpec/action.erb +1 -0
  135. data/spec/controller/controller_render_spec/views/MultipleActions/actions.haml +7 -0
  136. data/spec/controller/controller_render_spec/views/layouts/admin.erb +1 -0
  137. data/spec/controller/controller_render_spec/views/layouts/app.html.erb +1 -0
  138. data/spec/controller/controller_render_spec/views/layouts/app.js.erb +1 -0
  139. data/spec/controller/controller_render_spec/views/rem ExplicitRenderSpec/action.erb +1 -0
  140. data/spec/controller/controller_render_spec/views/rem ExplicitRenderSpec/another_action.erb +1 -0
  141. data/spec/controller/controller_render_spec/views/some_template.erb +1 -0
  142. data/spec/controller/controller_render_spec/views/standalone.html.erb +1 -0
  143. data/spec/controller/controller_render_spec.rb +217 -0
  144. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/a.erb +1 -0
  145. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/b.erb +1 -0
  146. data/spec/controller/error_handling_spec/views/diferrent_error_handling_spec/c.erb +1 -0
  147. data/spec/controller/error_handling_spec.rb +117 -0
  148. data/spec/controller/http_controller_spec.rb +130 -0
  149. data/spec/controller/spec_helper.rb +19 -0
  150. data/spec/conveyor/conveyor_spec.rb +124 -0
  151. data/spec/conveyor/spec_helper.rb +3 -0
  152. data/spec/environment/config_spec/config.default.yml +3 -0
  153. data/spec/environment/config_spec/config.development.yml +3 -0
  154. data/spec/environment/config_spec/config.yml +5 -0
  155. data/spec/environment/config_spec.rb +30 -0
  156. data/spec/environment/environment_spec/path1/file1 +0 -0
  157. data/spec/environment/environment_spec/path1/some_folder/some_file +0 -0
  158. data/spec/environment/environment_spec/path2/file2 +0 -0
  159. data/spec/environment/environment_spec/path2/some_folder/some_file +0 -0
  160. data/spec/environment/environment_spec.rb +65 -0
  161. data/spec/environment/logger_spec.rb +19 -0
  162. data/spec/environment/minimal_app_spec/app.rb +1 -0
  163. data/spec/environment/minimal_app_spec.rb +25 -0
  164. data/spec/environment/spec_helper.rb +1 -0
  165. data/spec/environment/standard_app_spec/app/lib/app/init.rb +3 -0
  166. data/spec/environment/standard_app_spec/plugin_a/lib/plugin_a/init.rb +1 -0
  167. data/spec/environment/standard_app_spec/plugin_b/lib/emptygit +0 -0
  168. data/spec/environment/standard_app_spec.rb +48 -0
  169. data/spec/html/basic_html_helper_spec.rb +29 -0
  170. data/spec/html/form_helper_spec.rb +63 -0
  171. data/spec/html/javascript_helper_spec.rb +15 -0
  172. data/spec/html/model_helper_spec.rb +81 -0
  173. data/spec/html/scoped_params_spec.rb +15 -0
  174. data/spec/html/spec_helper.rb +28 -0
  175. data/spec/http/http_spec/app/lib/app/init.rb +10 -0
  176. data/spec/http/http_spec/app/runtime/public/emptygit +0 -0
  177. data/spec/http/http_spec/plugin_a/lib/plugin_a/init.rb +0 -0
  178. data/spec/http/http_spec/plugin_b/lib/plugin_b/init.rb +5 -0
  179. data/spec/http/http_spec/plugin_b/static/emptygit +0 -0
  180. data/spec/http/http_spec.rb +51 -0
  181. data/spec/http/micelaneous_spec.rb +13 -0
  182. data/spec/http/spec_helper.rb +5 -0
  183. data/spec/integration/basic_spec/views/smoke_test_spec/action.erb +1 -0
  184. data/spec/integration/basic_spec.rb +79 -0
  185. data/spec/integration/controller_routing_helper_spec.rb +84 -0
  186. data/spec/integration/flash_spec.rb +206 -0
  187. data/spec/integration/spec_helper.rb +5 -0
  188. data/spec/integration/spec_helper_spec.rb +63 -0
  189. data/spec/integration/view_routing_helper_spec.rb +134 -0
  190. data/spec/mail/mail_controller_spec/views/body_template_spec/signup.erb +1 -0
  191. data/spec/mail/mail_controller_spec.rb +61 -0
  192. data/spec/mail/spec_helper.rb +7 -0
  193. data/spec/remote/remote_spec.rb +75 -0
  194. data/spec/remote/spec_helper.rb +17 -0
  195. data/spec/router/alias_router_spec.rb +98 -0
  196. data/spec/router/basic_spec.rb +111 -0
  197. data/spec/router/configurator_spec.rb +18 -0
  198. data/spec/router/integration_spec.rb +42 -0
  199. data/spec/router/persistent_params_spec.rb +65 -0
  200. data/spec/router/restful_router_spec.rb +120 -0
  201. data/spec/router/routing_helper_spec.rb +55 -0
  202. data/spec/router/spec_helper.rb +20 -0
  203. data/spec/support/callbacks_spec.rb +157 -0
  204. data/spec/support/filters_spec.rb +60 -0
  205. data/spec/support/spec_helper.rb +4 -0
  206. data/spec/template/spec_helper.rb +6 -0
  207. data/spec/template/template_spec/file.erb +1 -0
  208. data/spec/template/template_spec/views/basic/custom_context.erb +1 -0
  209. data/spec/template/template_spec/views/basic/extension.erb +1 -0
  210. data/spec/template/template_spec/views/basic/general.html.erb +5 -0
  211. data/spec/template/template_spec/views/basic/non_existing_format.html.erb +0 -0
  212. data/spec/template/template_spec/views/format/format.erb +1 -0
  213. data/spec/template/template_spec/views/format/format.html.erb +1 -0
  214. data/spec/template/template_spec/views/format/format.js.erb +1 -0
  215. data/spec/template/template_spec/views/format_for_partials/_form.html.erb +1 -0
  216. data/spec/template/template_spec/views/format_for_partials/dialog.js.erb +1 -0
  217. data/spec/template/template_spec/views/layout/basic/content.erb +1 -0
  218. data/spec/template/template_spec/views/layout/basic/layout.erb +1 -0
  219. data/spec/template/template_spec/views/layout/content_for/content.erb +3 -0
  220. data/spec/template/template_spec/views/layout/content_for/layout.erb +3 -0
  221. data/spec/template/template_spec/views/layout/format/content.html.erb +1 -0
  222. data/spec/template/template_spec/views/layout/format/content.js.erb +1 -0
  223. data/spec/template/template_spec/views/layout/format/layout.html.erb +1 -0
  224. data/spec/template/template_spec/views/layout/format/layout.js.erb +1 -0
  225. data/spec/template/template_spec/views/layout/nested_yield/a.erb +1 -0
  226. data/spec/template/template_spec/views/layout/nested_yield/layout.erb +1 -0
  227. data/spec/template/template_spec/views/layout/nested_yield/layout_b.erb +1 -0
  228. data/spec/template/template_spec/views/layout/same_context/a.erb +1 -0
  229. data/spec/template/template_spec/views/layout/same_context/b.erb +1 -0
  230. data/spec/template/template_spec/views/layout/same_context/layout.erb +1 -0
  231. data/spec/template/template_spec/views/nested/format/a.erb +1 -0
  232. data/spec/template/template_spec/views/nested/format/b.erb +1 -0
  233. data/spec/template/template_spec/views/nested/relative/a.erb +1 -0
  234. data/spec/template/template_spec/views/nested/relative/b.erb +1 -0
  235. data/spec/template/template_spec/views/nested/relative/c.erb +1 -0
  236. data/spec/template/template_spec/views/nested/shared/c.erb +1 -0
  237. data/spec/template/template_spec/views/nesting_format/_edit.html.erb +1 -0
  238. data/spec/template/template_spec/views/nesting_format/_form.html.erb +1 -0
  239. data/spec/template/template_spec/views/nesting_format/dialog.js.erb +1 -0
  240. data/spec/template/template_spec/views/other/template.erb +1 -0
  241. data/spec/template/template_spec/views/prefixes/_underscored.erb +1 -0
  242. data/spec/template/template_spec/views/prefixes/without_prefix.erb +1 -0
  243. data/spec/template/template_spec.rb +204 -0
  244. data/spec/template/tilt_spec/views/concat_and_capture.erb +1 -0
  245. data/spec/template/tilt_spec/views/concat_and_capture.haml +3 -0
  246. data/spec/template/tilt_spec/views/encoding/erb.erb +1 -0
  247. data/spec/template/tilt_spec/views/encoding/haml.haml +1 -0
  248. data/spec/template/tilt_spec/views/errors.erb +3 -0
  249. data/spec/template/tilt_spec/views/errors.haml +3 -0
  250. data/spec/template/tilt_spec/views/mixed_templates/broken_erb_concat_erb.erb +4 -0
  251. data/spec/template/tilt_spec/views/mixed_templates/broken_erb_concat_haml.haml +1 -0
  252. data/spec/template/tilt_spec/views/mixed_templates/broken_haml_concat_erb.erb +1 -0
  253. data/spec/template/tilt_spec/views/mixed_templates/broken_haml_concat_haml.haml +2 -0
  254. data/spec/template/tilt_spec/views/nested_capture_and_concat.haml +3 -0
  255. data/spec/template/tilt_spec/views/ugly.haml +3 -0
  256. data/spec/template/tilt_spec/views/yield.erb +1 -0
  257. data/spec/template/tilt_spec.rb +98 -0
  258. metadata +531 -0
@@ -0,0 +1,18 @@
1
+ module Rad
2
+ module JavascriptHelper
3
+ def javascript_include_tag *scripts
4
+ Array(scripts).collect{|script|
5
+ tag :script, '', src: "#{config && config.url_root!}#{script}", type: "text/javascript"
6
+ }.join("\n")
7
+ end
8
+
9
+ def javascript_tag value = nil, &block
10
+ args = [{type: "text/javascript"}]
11
+ args.unshift value if value
12
+ tag :script, *args, &block
13
+ end
14
+
15
+ # Escape
16
+ def js obj; obj.to_s.js_escape end
17
+ end
18
+ end
@@ -0,0 +1,135 @@
1
+ module Rad
2
+ class ModelHelper
3
+ attr_accessor :template, :model_name, :model, :options, :form_helper
4
+
5
+ def initialize template, form_helper, model_name, model, options
6
+ self.template, self.form_helper, self.model_name, self.model, self.options = template, form_helper, model_name, model, options
7
+ end
8
+
9
+
10
+ #
11
+ # Helpers
12
+ #
13
+ def check_box name, options = {}
14
+ render_attribute name, options do |fname, value, o|
15
+ form_helper.check_box_tag fname, !!value, o
16
+ end
17
+ end
18
+
19
+ def file_field name, options = {}
20
+ render_attribute name, options do |fname, value, o|
21
+ form_helper.file_field_tag fname, o
22
+ end
23
+ end
24
+
25
+ def hidden_field name, options = {}
26
+ render_attribute name, options do |fname, value, o|
27
+ form_helper.hidden_field_tag fname, value, o
28
+ end
29
+ end
30
+
31
+ def password_field name, options = {}
32
+ render_attribute name, options do |fname, value, o|
33
+ form_helper.password_field_tag fname, nil, o
34
+ end
35
+ end
36
+
37
+ def radio_button name, options = {}
38
+ render_attribute name, options do |fname, value, o|
39
+ form_helper.radio_button_tag fname, !!value, o
40
+ end
41
+ end
42
+
43
+ def submit value, options = {}
44
+ form_helper.submit_tag value, options
45
+ end
46
+
47
+ def text_field name, options = {}
48
+ render_attribute name, options do |fname, value, o|
49
+ form_helper.text_field_tag fname, value, o
50
+ end
51
+ end
52
+
53
+ def text_area name, options = {}
54
+ render_attribute name, options do |fname, value, o|
55
+ form_helper.text_area_tag fname, value, o
56
+ end
57
+ end
58
+
59
+ def select name, values, options = {}
60
+ render_attribute name, options do |fname, value, o|
61
+ form_helper.select_tag fname, value, values, o
62
+ end
63
+ end
64
+
65
+ def error_messages
66
+ merrors = errors[:base]
67
+ form_helper.error_messages merrors.to_a unless merrors.blank?
68
+ end
69
+
70
+
71
+ protected
72
+ def method_missing m, *args, &b
73
+ form_helper.send m, *args, &b
74
+ end
75
+
76
+ def render_attribute name, options, &block
77
+ name.must_be.a Symbol
78
+ ferrors = errors_for(name)
79
+
80
+ options = insert_human_readable_label name, options
81
+
82
+ if form_helper.respond_to? :field_with_errors
83
+ field_html = block.call field_name_for(name), value_of(name), options
84
+ unless ferrors.blank?
85
+ form_helper.field_with_errors name, ferrors, options, field_html
86
+ else
87
+ field_html
88
+ end
89
+ else
90
+ options[:errors] = ferrors
91
+ block.call field_name_for(name), value_of(name), options
92
+ end
93
+ end
94
+
95
+ def errors
96
+ unless @errors
97
+ @errors = {}
98
+ (
99
+ (model.respond_to?(:errors) && model.errors) ||
100
+ (model.respond_to?(:[]) && (model['errors'] || model[:errors])) ||
101
+ {}
102
+ ).each do |k, v|
103
+ @errors[k.to_sym] = Array.wrap(v)
104
+ end
105
+ end
106
+ @errors
107
+ end
108
+
109
+ def errors_for name
110
+ name.must_be.a Symbol
111
+ errors[name]
112
+ end
113
+
114
+ def field_name_for name
115
+ "#{model_name}[#{name}]"
116
+ end
117
+
118
+ def value_of name
119
+ if model.respond_to? name
120
+ model.send name
121
+ elsif model.respond_to? :[]
122
+ model[name.to_sym] || model[name.to_s]
123
+ else
124
+ raise "Model not respond to :#{name} nor to :[]!"
125
+ end
126
+ end
127
+
128
+ def insert_human_readable_label name, options
129
+ unless options.include?(:label) or options.include?(:label)
130
+ options[:label] = model.t(name) if model.respond_to? :t
131
+ end
132
+ options
133
+ end
134
+ end
135
+ end
File without changes
@@ -0,0 +1,26 @@
1
+ module Rad
2
+ module Processors
3
+ class PrepareFlash < Processor
4
+
5
+ def call
6
+ workspace.request.must_be.present
7
+ workspace.params.must_be.defined
8
+
9
+ previous_messages = workspace.request.session.delete 'flash'
10
+ if previous_messages.present?
11
+ previous_messages = JSON.load previous_messages
12
+ rad[:flash] = Rad::Flash.new workspace.params.format, previous_messages
13
+ end
14
+
15
+ next_processor.call
16
+
17
+ if rad.include? :flash
18
+ flash = rad[:flash]
19
+ messages = flash.messages_for_next_request
20
+ workspace.request.must_be.present
21
+ workspace.request.session['flash'] = messages.to_json unless messages.empty?
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # Converts {'model[attribute]' => value} into {'model' => {'attribute' => value}}
2
+ module Rad
3
+ module Processors
4
+ class ScopedParams < Processor
5
+ def call
6
+ if workspace.params?
7
+ to_delete = []
8
+ to_add = {}
9
+ workspace.params.each do |name, value|
10
+ name.to_s.scan /(.+)\[(.+)\]/ do |scope_name, name_in_scope|
11
+ logger.warn "Owerriding :#{scope} param!" if workspace.params.include? scope_name
12
+ scope = to_add[scope_name.to_sym] ||= {}
13
+ scope[name_in_scope] = value
14
+ to_delete << name
15
+ end
16
+ end
17
+ workspace.params.merge! to_add
18
+ to_delete.each{|n| workspace.params.delete n}
19
+ end
20
+
21
+ next_processor.call
22
+ end
23
+ end
24
+ end
25
+ end
26
+
data/lib/rad/html.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'rad/http'
2
+ require 'rad/template'
3
+
4
+ [
5
+ 'flash',
6
+
7
+ 'helpers/basic_html_helper',
8
+ 'helpers/form_helper',
9
+ 'helpers/model_helper',
10
+ 'helpers/javascript_helper',
11
+ 'helpers/flash_helper',
12
+ 'helpers/html_helper',
13
+
14
+ 'processors/scoped_params',
15
+ 'processors/prepare_flash'
16
+ ].each{|f| require "rad/html/#{f}"}
17
+
18
+ # Flash
19
+ rad.register :flash, scope: :cycle, depends_on: :environment do
20
+ workspace = rad[:workspace]
21
+ workspace.params.must_be.defined
22
+ Rad::Flash.new workspace.params.format
23
+ end
24
+
25
+ # Initialization
26
+ Rad::Config::DEFAULTS[:remote_link_formats] = ['js', 'json']
@@ -0,0 +1,21 @@
1
+ module Rad
2
+ module HTTP
3
+ class << self
4
+ inject environment: :environment, config: :config
5
+
6
+ def ensure_public_symlink symlink_name, plugin_public_folder
7
+ plugin_public_folder = File.expand_path(plugin_public_folder)
8
+ File.must.exist(plugin_public_folder)
9
+
10
+ environment.must_be.defined
11
+ if environment.config.static? and !environment.config.test?
12
+ symlink_path = "#{config.public_dir!}/#{symlink_name}"
13
+ unless File.exist?(symlink_path) # and File.symlink?(symlink_path)
14
+ # File.delete(symlink_path) if File.symlink?(symlink_path)
15
+ File.symlink(plugin_public_folder, symlink_path)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ module Rad
2
+ module HTTPAdapter
3
+ class << self
4
+ inject conveyors: :conveyors, config: :config
5
+
6
+ def call env, workspace = {}, &block
7
+ # result, opt = nil, opt.to_openobject
8
+ workspace = conveyors.web.call(
9
+ {env: env, response: Rad::Response.new}.merge(workspace),
10
+ &block
11
+ )
12
+
13
+ response = workspace.response.must_be.defined
14
+ result = response.finish
15
+
16
+ result
17
+ end
18
+ # synchronize_method :call
19
+
20
+ # def mock_call env = {}, workspace = {}, &block
21
+ # env['PATH_INFO'] ||= '/'
22
+ # env['rack.input'] ||= StringIO.new
23
+ #
24
+ # call env, workspace, &block
25
+ # end
26
+
27
+ def mock_environment
28
+ {
29
+ 'rack.url_scheme' => 'http',
30
+ 'PATH_INFO' => '/',
31
+ 'rack.input' => StringIO.new
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ module Rad
2
+ class StaticFiles
3
+
4
+ def initialize(app, dir, filter = nil)
5
+ @app = app
6
+ @dir = File.expand_path(dir)
7
+ @file_server = Rack::File.new(@dir)
8
+ @filter = filter
9
+ end
10
+
11
+ def call(env)
12
+ path = env["PATH_INFO"]
13
+
14
+ if (!@filter or (@filter and @filter =~ path)) and File.exist?("#{@dir}#{path}")
15
+ @file_server.call(env)
16
+ else
17
+ @app.call(env)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ module Rad
2
+ module Processors
3
+ class EvaluateFormat < Processor
4
+ def call
5
+ path = workspace.path.must_be.defined
6
+ params = workspace.params.must_be.defined
7
+
8
+ parts = path.split('.')
9
+ if parts.size > 1
10
+ format = parts.last
11
+ logger.warn "Two :format parameters!" if params.include?(:format)
12
+ workspace.params = params.clone
13
+ workspace.params.format = format
14
+ else
15
+ params.format ||= config.default_format!
16
+ end
17
+
18
+ next_processor.call
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Rad
2
+ module Processors
3
+ class HTTPLogger < Processor
4
+ def call
5
+ if workspace.request? and workspace.params?
6
+ method, path, ip, time, format = workspace.request.request_method, workspace.path,
7
+ workspace.request.ip, (workspace.start_time || Time.now), workspace.params.format
8
+ logger.info " Started '#{path}' as '#{format}' (for #{ip} at #{time.to_s} with #{method})"
9
+ end
10
+
11
+ next_processor.call
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ module Rad
2
+ module Processors
3
+ class HttpWriter < Processor
4
+ def call
5
+ response = workspace.response.must_be.defined
6
+
7
+ begin
8
+ next_processor.call
9
+
10
+ response.body = workspace.content if response.body.blank? and workspace.content?
11
+ response.content_type ||= Mime[(workspace.params.format if workspace.params?) || config.default_format]
12
+ rescue StandardError => e
13
+ raise e if config.test?
14
+
15
+ response.clear
16
+ if workspace.params.format? and workspace.params.format == 'json'
17
+ response.body = {error: (config.production? ? "Internal error!" : e.message)}.to_json
18
+ response.content_type = Mime.json
19
+ else
20
+ response.body = (config.production? ? "Internal error!" : e.message)
21
+ response.content_type = Mime.text
22
+ end
23
+
24
+ logger.error e
25
+ logger.info "\n"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ module Rad
2
+ module Processors
3
+ class PrepareParams < Processor
4
+ def call
5
+ workspace.env.must_be.defined
6
+ workspace.request = Rad::Request.new(workspace.env)
7
+ workspace.path = workspace.request.path
8
+ params = workspace.params = Rad::Params.new(workspace.request.params)
9
+
10
+ if params.json?
11
+ json_params = JSON.load params['json']
12
+ json_params.must_be.a Hash
13
+ json_params.keys.each do |k|
14
+ logger.warn "Parameter :#{k} will be overwriden from JSON!" if params.include?(k)
15
+ end
16
+ params.merge! json_params
17
+ end
18
+ next_processor.call
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Rack doesn't works well with ruby 1.9.2
3
+ # there's no :each method in String anymore
4
+ #
5
+ class Rack::Response
6
+ def each(&callback)
7
+ if @body.is_a? String
8
+ @body.each_char(&callback)
9
+ else
10
+ @body.each(&callback)
11
+ end
12
+ @writer = callback
13
+ @block.call(self) if @block
14
+ end
15
+ end
16
+
17
+ class Rack::Request
18
+ alias_method :params_with_wrong_encoding, :params
19
+ def params
20
+ @params ||= encode_in_utf8(params_with_wrong_encoding)
21
+ end
22
+
23
+ protected
24
+ def encode_in_utf8 hash
25
+ r = {}
26
+ hash.each do |k, v|
27
+ r[k] = if v.is_a? String
28
+ v.force_encoding("UTF-8")
29
+ elsif v.is_a? Hash
30
+ encode_in_utf8(v)
31
+ else
32
+ v
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,67 @@
1
+ module Rad
2
+ class RackAdapter
3
+ SERVERS = %w{thin mongrel webrick}
4
+
5
+ # class Callback
6
+ # def initialize app; end
7
+ # def self.call env; Rad::Adapter.call env end
8
+ # end
9
+
10
+ class << self
11
+ inject(
12
+ logger: :logger,
13
+ config: :config
14
+ )
15
+
16
+ def initialize_rack builder = nil, &block
17
+ @rack_configurations ||= []
18
+ if block
19
+ raise "provide configuration block!" unless block
20
+ @rack_configurations << block
21
+ else
22
+ if @rack_configurations.empty?
23
+ raise "Common App not defined! Use profiles (like rad/profiles/web), define it by yourself or use your own configuration!"
24
+ end
25
+ @rack_configurations.each{|conf| conf.call builder}
26
+ end
27
+ end
28
+
29
+ def parse_config
30
+ app, options = Rack::Builder.parse_file 'config.ru'
31
+ app
32
+ end
33
+
34
+ def run app, host, port
35
+ handler = detect_rack_handler
36
+ handler_name = handler.name.gsub(/.*::/, '')
37
+ logger.info " HTTP server started on #{host}:#{port}" unless config.test?
38
+ # unless handler_name =~/cgi/i
39
+ handler.run app, Host: host, Port: port do |server|
40
+ [:INT, :TERM].each {|sig| trap(sig){quit!(server, handler_name)}}
41
+ end
42
+ rescue Errno::EADDRINUSE => e
43
+ logger.error "Port #{port} taken!"
44
+ end
45
+
46
+ def quit!(server, handler_name)
47
+ ## Use thins' hard #stop! if available, otherwise just #stop
48
+ server.respond_to?(:stop!) ? server.stop! : server.stop
49
+ puts "\nRad stopped" unless handler_name =~/cgi/i
50
+ end
51
+
52
+ protected
53
+ def detect_rack_handler
54
+ return Rack::Handler.get('thin')
55
+ SERVERS.each do |server_name|
56
+ begin
57
+ return Rack::Handler.get(server_name.downcase)
58
+ rescue LoadError
59
+ rescue NameError
60
+ end
61
+ end
62
+ fail " Server handler (#{SERVERS.join(', ')}) not found."
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,42 @@
1
+ module Rad
2
+ class Request < Rack::Request
3
+ # Returns an array of acceptable media types for the response
4
+ # def accept
5
+ # @env['HTTP_ACCEPT'].to_s.split(',').map { |a| a.split(';')[0].strip }
6
+ # end
7
+ #
8
+ # def secure?
9
+ # (@env['HTTP_X_FORWARDED_PROTO'] || @env['rack.url_scheme']) == 'https'
10
+ # end
11
+
12
+
13
+ # Returns all the \subdomains as an array, so <tt>["dev", "www"]</tt> would be
14
+ # returned for "dev.www.rubyonrails.org". You can specify a different <tt>tld_length</tt>,
15
+ # such as 2 to catch <tt>["www"]</tt> instead of <tt>["www", "rubyonrails"]</tt>
16
+ # in "www.rubyonrails.co.uk".
17
+ def subdomains(tld_length = 1)
18
+ return [] unless named_host?(host)
19
+ parts = host.split('.')
20
+ parts[0..-(tld_length+2)]
21
+ end
22
+
23
+
24
+ # Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify
25
+ # a different <tt>tld_length</tt>, such as 2 to catch rubyonrails.co.uk in "www.rubyonrails.co.uk".
26
+ def domain(tld_length = 1)
27
+ return nil unless named_host?(host)
28
+
29
+ host.split('.').last(1 + tld_length).join('.')
30
+ end
31
+
32
+ def cookies_with_memory
33
+ @cookies_with_memory ||= cookies_without_memory
34
+ end
35
+ alias_method_chain :cookies, :memory
36
+
37
+ protected
38
+ def named_host?(host)
39
+ !(host.nil? || /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.match(host))
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,86 @@
1
+ module Rad
2
+ class Response < Rack::Response
3
+ include ::OpenConstructor
4
+
5
+ STATUS_MESSAGES = {
6
+ ok: 200,
7
+ not_found: 404,
8
+ failed: 500,
9
+ error: 500,
10
+ redirect: 301
11
+ }
12
+
13
+ def initialize *args
14
+ super
15
+ clear
16
+ end
17
+
18
+ def content_type= type; self["Content-Type"] = type end
19
+ def content_type; self["Content-Type"] end
20
+ def content_type?; !!content_type end
21
+
22
+ def location; self['Location'] end
23
+ def location= location; self['Location'] = location end
24
+
25
+ # def to_a
26
+ # [status, headers, body]
27
+ # end
28
+
29
+ def body_as_string
30
+ if @body.is_a? String
31
+ @body
32
+ else
33
+ @body ? @body.join : ""
34
+ end
35
+ end
36
+
37
+ def inspect
38
+ to_a2.inspect
39
+ end
40
+
41
+ def == other
42
+ to_a2 == other
43
+ end
44
+
45
+ def cookies
46
+ self['Set-Cookie']
47
+ end
48
+
49
+ def clear
50
+ @status = 200
51
+ @header = Rack::Utils::HeaderHash.new("Content-Type" => nil)
52
+ @length = 0
53
+ @body = []
54
+ end
55
+
56
+ def status= code_or_message
57
+ @status = if code_or_message.is_a? Numeric
58
+ code_or_message
59
+ else
60
+ self.class.decode_status_message(code_or_message) || raise("unknown http status message '#{code_or_message}'!")
61
+ end
62
+ end
63
+
64
+ def self.decode_status_message message
65
+ STATUS_MESSAGES[message]
66
+ end
67
+
68
+
69
+ #
70
+ # Status helpers
71
+ #
72
+ STATUS_MESSAGES.each do |message, status_code|
73
+ define_method("#{message}?"){self.status == status_code}
74
+ end
75
+ alias_method :success?, :ok?
76
+
77
+ def redirect?
78
+ super or (body and body.include?('window.location'))
79
+ end
80
+
81
+ protected
82
+ def to_a2
83
+ [status, header, body_as_string]
84
+ end
85
+ end
86
+ end
data/lib/rad/http.rb ADDED
@@ -0,0 +1,48 @@
1
+ # WServer provides support for Web Servers (via Rack)
2
+
3
+ require 'rack'
4
+ require 'rack/builder'
5
+
6
+ require 'rad/conveyor'
7
+
8
+ # support
9
+ [
10
+ 'rack/request',
11
+ 'rack/response',
12
+ 'rack/rack_adapter',
13
+ 'rack/fixes'
14
+ ].each{|f| require "rad/http/support/#{f}"}
15
+
16
+ # http
17
+ [
18
+ # 'config',
19
+ 'http',
20
+ 'http_adapter',
21
+ 'processors/prepare_params',
22
+ 'processors/http_writer',
23
+ 'processors/http_logger',
24
+ 'processors/evaluate_format'
25
+ ].each{|f| require "rad/http/#{f}"}
26
+
27
+ module Rad
28
+ autoload :StaticFiles, 'rad/http/middleware/static_files'
29
+ end
30
+
31
+ Rad.metaclass_eval do
32
+ delegate :initialize_rack, to: Rad::RackAdapter
33
+ delegate :call, to: Rad::HTTPAdapter
34
+ delegate :ensure_public_symlink, to: Rad::HTTP
35
+ end
36
+
37
+
38
+ #
39
+ # Initialization
40
+ #
41
+ Rad::Config::DEFAULTS.merge!(
42
+ host: '0.0.0.0',
43
+ port: 4000,
44
+
45
+ static: true,
46
+ url_root: '',
47
+ default_format: 'html',
48
+ )