rjspotter-ramaze 2009.06.29

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 (503) hide show
  1. data/.gitignore +3 -0
  2. data/.mailmap +25 -0
  3. data/MANIFEST +502 -0
  4. data/README.md +457 -0
  5. data/Rakefile +88 -0
  6. data/benchmark/bench_templates/bench.rb +67 -0
  7. data/benchmark/bench_templates/view/large.erb +79 -0
  8. data/benchmark/bench_templates/view/large.haml +41 -0
  9. data/benchmark/bench_templates/view/large.xhtml +79 -0
  10. data/benchmark/bench_templates/view/small.erb +21 -0
  11. data/benchmark/bench_templates/view/small.haml +12 -0
  12. data/benchmark/bench_templates/view/small.xhtml +21 -0
  13. data/benchmark/results.txt +131 -0
  14. data/benchmark/run.rb +355 -0
  15. data/benchmark/suite/minimal.rb +11 -0
  16. data/benchmark/suite/no_informer.rb +7 -0
  17. data/benchmark/suite/no_sessions.rb +9 -0
  18. data/benchmark/suite/no_template.rb +7 -0
  19. data/benchmark/suite/simple.rb +5 -0
  20. data/benchmark/suite/template_erubis.rb +8 -0
  21. data/benchmark/suite/template_etanni.rb +8 -0
  22. data/benchmark/suite/template_ezamar.rb +8 -0
  23. data/benchmark/suite/template_haml.rb +13 -0
  24. data/benchmark/suite/template_liquid.rb +11 -0
  25. data/benchmark/suite/template_markaby.rb +9 -0
  26. data/benchmark/suite/template_nagoro.rb +8 -0
  27. data/benchmark/suite/template_redcloth.rb +13 -0
  28. data/benchmark/suite/template_tenjin.rb +8 -0
  29. data/benchmark/test.rb +35 -0
  30. data/bin/ramaze +15 -0
  31. data/doc/AUTHORS +44 -0
  32. data/doc/CHANGELOG +17362 -0
  33. data/doc/COPYING +56 -0
  34. data/doc/FAQ +92 -0
  35. data/doc/GPL +339 -0
  36. data/doc/INSTALL +92 -0
  37. data/doc/LEGAL +26 -0
  38. data/doc/TODO +29 -0
  39. data/doc/meta/announcement.txt +146 -0
  40. data/doc/meta/configuration.txt +163 -0
  41. data/doc/meta/internals.txt +278 -0
  42. data/doc/meta/users.kml +64 -0
  43. data/doc/tutorial/todolist.html +1379 -0
  44. data/doc/tutorial/todolist.txt +920 -0
  45. data/examples/app/auth/layout/auth.xhtml +25 -0
  46. data/examples/app/auth/start.rb +23 -0
  47. data/examples/app/auth/view/index.xhtml +4 -0
  48. data/examples/app/auth/view/login.xhtml +20 -0
  49. data/examples/app/auth/view/secret.xhtml +1 -0
  50. data/examples/app/blog/README +3 -0
  51. data/examples/app/blog/app.rb +69 -0
  52. data/examples/app/blog/config.ru +17 -0
  53. data/examples/app/blog/controller/comment.rb +45 -0
  54. data/examples/app/blog/controller/entry.rb +85 -0
  55. data/examples/app/blog/controller/init.rb +86 -0
  56. data/examples/app/blog/controller/main.rb +20 -0
  57. data/examples/app/blog/controller/tag.rb +9 -0
  58. data/examples/app/blog/layout/default.nag +31 -0
  59. data/examples/app/blog/model/comment.rb +58 -0
  60. data/examples/app/blog/model/entry.rb +89 -0
  61. data/examples/app/blog/model/init.rb +15 -0
  62. data/examples/app/blog/model/tag.rb +36 -0
  63. data/examples/app/blog/public/css/screen.css +273 -0
  64. data/examples/app/blog/spec/blog.rb +87 -0
  65. data/examples/app/blog/start.rb +5 -0
  66. data/examples/app/blog/view/comment/form.nag +10 -0
  67. data/examples/app/blog/view/comment/show.nag +16 -0
  68. data/examples/app/blog/view/entry/edit.nag +14 -0
  69. data/examples/app/blog/view/entry/feed.atom.nag +8 -0
  70. data/examples/app/blog/view/entry/feed.rss.nag +7 -0
  71. data/examples/app/blog/view/entry/index.nag +7 -0
  72. data/examples/app/blog/view/entry/new.nag +13 -0
  73. data/examples/app/blog/view/entry/show.nag +36 -0
  74. data/examples/app/blog/view/feed.atom.nag +18 -0
  75. data/examples/app/blog/view/feed.rss.nag +25 -0
  76. data/examples/app/blog/view/index.nag +6 -0
  77. data/examples/app/blog/view/tag/index.nag +5 -0
  78. data/examples/app/chat/layout/default.xhtml +13 -0
  79. data/examples/app/chat/model/history.rb +38 -0
  80. data/examples/app/chat/model/message.rb +7 -0
  81. data/examples/app/chat/public/css/chat.css +9 -0
  82. data/examples/app/chat/public/js/chat.js +28 -0
  83. data/examples/app/chat/public/js/jquery.js +3436 -0
  84. data/examples/app/chat/start.rb +39 -0
  85. data/examples/app/chat/view/chat.xhtml +9 -0
  86. data/examples/app/chat/view/index.xhtml +7 -0
  87. data/examples/app/localization/locale/de.yaml +5 -0
  88. data/examples/app/localization/locale/en.yaml +5 -0
  89. data/examples/app/localization/locale/ja.yaml +5 -0
  90. data/examples/app/localization/start.rb +48 -0
  91. data/examples/app/sourceview/public/coderay.css +104 -0
  92. data/examples/app/sourceview/public/images/file.gif +0 -0
  93. data/examples/app/sourceview/public/images/folder.gif +0 -0
  94. data/examples/app/sourceview/public/images/tv-collapsable-last.gif +0 -0
  95. data/examples/app/sourceview/public/images/tv-collapsable.gif +0 -0
  96. data/examples/app/sourceview/public/images/tv-expandable-last.gif +0 -0
  97. data/examples/app/sourceview/public/images/tv-expandable.gif +0 -0
  98. data/examples/app/sourceview/public/images/tv-item-last.gif +0 -0
  99. data/examples/app/sourceview/public/images/tv-item.gif +0 -0
  100. data/examples/app/sourceview/public/jquery.js +11 -0
  101. data/examples/app/sourceview/public/jquery.treeview.css +48 -0
  102. data/examples/app/sourceview/public/jquery.treeview.js +223 -0
  103. data/examples/app/sourceview/public/sourceview.js +52 -0
  104. data/examples/app/sourceview/start.rb +79 -0
  105. data/examples/app/sourceview/view/index.haml +59 -0
  106. data/examples/app/todolist/controller/init.rb +10 -0
  107. data/examples/app/todolist/controller/task.rb +39 -0
  108. data/examples/app/todolist/layout/default.xhtml +14 -0
  109. data/examples/app/todolist/model/init.rb +14 -0
  110. data/examples/app/todolist/model/task.rb +39 -0
  111. data/examples/app/todolist/public/css/screen.css +63 -0
  112. data/examples/app/todolist/public/favicon.ico +0 -0
  113. data/examples/app/todolist/start.rb +11 -0
  114. data/examples/app/todolist/view/index.xhtml +29 -0
  115. data/examples/app/upload/start.rb +19 -0
  116. data/examples/app/upload/view/index.xhtml +25 -0
  117. data/examples/app/whywiki/spec/whywiki.rb +58 -0
  118. data/examples/app/whywiki/start.rb +46 -0
  119. data/examples/app/whywiki/template/edit.xhtml +14 -0
  120. data/examples/app/whywiki/template/show.xhtml +18 -0
  121. data/examples/app/wikore/spec/wikore.rb +109 -0
  122. data/examples/app/wikore/src/controller.rb +78 -0
  123. data/examples/app/wikore/src/model.rb +56 -0
  124. data/examples/app/wikore/start.rb +9 -0
  125. data/examples/app/wikore/view/index.xhtml +8 -0
  126. data/examples/app/wiktacular/README +2 -0
  127. data/examples/app/wiktacular/mkd/link/2007-07-20_19-45-51.mkd +1 -0
  128. data/examples/app/wiktacular/mkd/link/current.mkd +1 -0
  129. data/examples/app/wiktacular/mkd/main/2007-07-20_16-31-33.mkd +1 -0
  130. data/examples/app/wiktacular/mkd/main/2007-07-20_19-21-12.mkd +1 -0
  131. data/examples/app/wiktacular/mkd/main/2007-07-20_19-23-10.mkd +2 -0
  132. data/examples/app/wiktacular/mkd/main/2007-07-20_19-45-07.mkd +2 -0
  133. data/examples/app/wiktacular/mkd/main/current.mkd +2 -0
  134. data/examples/app/wiktacular/mkd/markdown/current.mkd +3 -0
  135. data/examples/app/wiktacular/mkd/testing/2007-07-20_16-43-46.mkd +2 -0
  136. data/examples/app/wiktacular/mkd/testing/2007-07-20_19-43-50.mkd +3 -0
  137. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-46-01.mkd +11 -0
  138. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-46-32.mkd +13 -0
  139. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-08.mkd +17 -0
  140. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-54.mkd +17 -0
  141. data/examples/app/wiktacular/mkd/testing/current.mkd +17 -0
  142. data/examples/app/wiktacular/public/favicon.ico +0 -0
  143. data/examples/app/wiktacular/public/screen.css +72 -0
  144. data/examples/app/wiktacular/spec/wiktacular.rb +157 -0
  145. data/examples/app/wiktacular/src/controller.rb +55 -0
  146. data/examples/app/wiktacular/src/model.rb +102 -0
  147. data/examples/app/wiktacular/start.rb +8 -0
  148. data/examples/app/wiktacular/template/edit.xhtml +6 -0
  149. data/examples/app/wiktacular/template/html_layout.xhtml +27 -0
  150. data/examples/app/wiktacular/template/index.xhtml +9 -0
  151. data/examples/app/wiktacular/template/new.xhtml +6 -0
  152. data/examples/basic/element.rb +47 -0
  153. data/examples/basic/gestalt.rb +26 -0
  154. data/examples/basic/hello.rb +14 -0
  155. data/examples/basic/layout.rb +28 -0
  156. data/examples/basic/linking.rb +29 -0
  157. data/examples/basic/partial.rb +26 -0
  158. data/examples/basic/simple.rb +52 -0
  159. data/examples/helpers/cache.rb +33 -0
  160. data/examples/helpers/form_with_sequel.rb +24 -0
  161. data/examples/helpers/httpdigest.rb +107 -0
  162. data/examples/helpers/identity.rb +18 -0
  163. data/examples/helpers/nitro_form.rb +23 -0
  164. data/examples/helpers/paginate.rb +71 -0
  165. data/examples/helpers/rest.rb +28 -0
  166. data/examples/helpers/simple_captcha.rb +29 -0
  167. data/examples/misc/css.rb +37 -0
  168. data/examples/misc/facebook.rb +159 -0
  169. data/examples/misc/memleak_detector.rb +37 -0
  170. data/examples/misc/nagoro_element.rb +43 -0
  171. data/examples/misc/ramaise.rb +132 -0
  172. data/examples/misc/rapp.rb +56 -0
  173. data/examples/misc/sequel_scaffolding.rb +34 -0
  174. data/examples/misc/serve_directory.rb +6 -0
  175. data/examples/templates/template_erubis.rb +52 -0
  176. data/examples/templates/template_ezamar.rb +51 -0
  177. data/examples/templates/template_haml.rb +49 -0
  178. data/examples/templates/template_liquid.rb +66 -0
  179. data/examples/templates/template_markaby.rb +57 -0
  180. data/examples/templates/template_nagoro.rb +50 -0
  181. data/examples/templates/template_redcloth.rb +58 -0
  182. data/examples/templates/template_remarkably.rb +54 -0
  183. data/examples/templates/template_tenjin.rb +52 -0
  184. data/examples/templates/view/external.haml +22 -0
  185. data/examples/templates/view/external.liquid +28 -0
  186. data/examples/templates/view/external.mab +30 -0
  187. data/examples/templates/view/external.nag +28 -0
  188. data/examples/templates/view/external.redcloth +19 -0
  189. data/examples/templates/view/external.rem +30 -0
  190. data/examples/templates/view/external.rhtml +28 -0
  191. data/examples/templates/view/external.tenjin +28 -0
  192. data/examples/templates/view/external.zmr +28 -0
  193. data/lib/proto/app.rb +14 -0
  194. data/lib/proto/config.ru +20 -0
  195. data/lib/proto/controller/init.rb +11 -0
  196. data/lib/proto/controller/main.rb +20 -0
  197. data/lib/proto/layout/default.xhtml +24 -0
  198. data/lib/proto/model/init.rb +4 -0
  199. data/lib/proto/public/.htaccess +24 -0
  200. data/lib/proto/public/css/screen.css +30 -0
  201. data/lib/proto/public/dispatch.fcgi +11 -0
  202. data/lib/proto/public/favicon.ico +0 -0
  203. data/lib/proto/public/js/jquery.js +4376 -0
  204. data/lib/proto/public/ramaze.png +0 -0
  205. data/lib/proto/spec/main.rb +20 -0
  206. data/lib/proto/start.rb +8 -0
  207. data/lib/proto/view/index.xhtml +41 -0
  208. data/lib/ramaze.rb +87 -0
  209. data/lib/ramaze/app.rb +124 -0
  210. data/lib/ramaze/cache.rb +19 -0
  211. data/lib/ramaze/cache/localmemcache.rb +56 -0
  212. data/lib/ramaze/cache/memcache.rb +124 -0
  213. data/lib/ramaze/cache/sequel.rb +82 -0
  214. data/lib/ramaze/contrib/addressable_route.rb +55 -0
  215. data/lib/ramaze/contrib/app_graph.rb +64 -0
  216. data/lib/ramaze/contrib/email.rb +88 -0
  217. data/lib/ramaze/contrib/facebook.rb +23 -0
  218. data/lib/ramaze/contrib/facebook/facebook.rb +171 -0
  219. data/lib/ramaze/contrib/gettext.rb +113 -0
  220. data/lib/ramaze/contrib/gettext/mo.rb +155 -0
  221. data/lib/ramaze/contrib/gettext/parser.rb +46 -0
  222. data/lib/ramaze/contrib/gettext/po.rb +109 -0
  223. data/lib/ramaze/contrib/gzip_filter.rb +1 -0
  224. data/lib/ramaze/contrib/maruku_uv.rb +59 -0
  225. data/lib/ramaze/contrib/profiling.rb +36 -0
  226. data/lib/ramaze/contrib/rest.rb +22 -0
  227. data/lib/ramaze/contrib/sequel/create_join.rb +26 -0
  228. data/lib/ramaze/contrib/sequel/form_field.rb +129 -0
  229. data/lib/ramaze/contrib/sequel/image.rb +196 -0
  230. data/lib/ramaze/contrib/sequel/relation.rb +98 -0
  231. data/lib/ramaze/controller.rb +104 -0
  232. data/lib/ramaze/controller/default.rb +12 -0
  233. data/lib/ramaze/current.rb +7 -0
  234. data/lib/ramaze/files.rb +24 -0
  235. data/lib/ramaze/gestalt.rb +132 -0
  236. data/lib/ramaze/helper.rb +13 -0
  237. data/lib/ramaze/helper/auth.rb +84 -0
  238. data/lib/ramaze/helper/bench.rb +41 -0
  239. data/lib/ramaze/helper/cache.rb +117 -0
  240. data/lib/ramaze/helper/disqus.rb +26 -0
  241. data/lib/ramaze/helper/flash.rb +62 -0
  242. data/lib/ramaze/helper/form.rb +127 -0
  243. data/lib/ramaze/helper/formatting.rb +189 -0
  244. data/lib/ramaze/helper/gestalt.rb +47 -0
  245. data/lib/ramaze/helper/gravatar.rb +79 -0
  246. data/lib/ramaze/helper/httpdigest.rb +97 -0
  247. data/lib/ramaze/helper/identity.rb +119 -0
  248. data/lib/ramaze/helper/layout.rb +97 -0
  249. data/lib/ramaze/helper/link.rb +56 -0
  250. data/lib/ramaze/helper/localize.rb +138 -0
  251. data/lib/ramaze/helper/markaby.rb +31 -0
  252. data/lib/ramaze/helper/maruku.rb +16 -0
  253. data/lib/ramaze/helper/nitroform.rb +14 -0
  254. data/lib/ramaze/helper/pager.rb +367 -0
  255. data/lib/ramaze/helper/paginate.rb +242 -0
  256. data/lib/ramaze/helper/partial.rb +100 -0
  257. data/lib/ramaze/helper/remarkably.rb +14 -0
  258. data/lib/ramaze/helper/request_accessor.rb +16 -0
  259. data/lib/ramaze/helper/sequel.rb +55 -0
  260. data/lib/ramaze/helper/sequel_form.rb +284 -0
  261. data/lib/ramaze/helper/simple_captcha.rb +61 -0
  262. data/lib/ramaze/helper/stack.rb +75 -0
  263. data/lib/ramaze/helper/tagz.rb +19 -0
  264. data/lib/ramaze/helper/thread.rb +17 -0
  265. data/lib/ramaze/helper/ultraviolet.rb +46 -0
  266. data/lib/ramaze/helper/user.rb +229 -0
  267. data/lib/ramaze/helper/xhtml.rb +34 -0
  268. data/lib/ramaze/log.rb +39 -0
  269. data/lib/ramaze/log/analogger.rb +39 -0
  270. data/lib/ramaze/log/growl.rb +38 -0
  271. data/lib/ramaze/log/hub.rb +41 -0
  272. data/lib/ramaze/log/informer.rb +129 -0
  273. data/lib/ramaze/log/knotify.rb +28 -0
  274. data/lib/ramaze/log/logger.rb +26 -0
  275. data/lib/ramaze/log/logging.rb +83 -0
  276. data/lib/ramaze/log/rotatinginformer.rb +168 -0
  277. data/lib/ramaze/log/syslog.rb +51 -0
  278. data/lib/ramaze/log/xosd.rb +92 -0
  279. data/lib/ramaze/middleware_compiler.rb +13 -0
  280. data/lib/ramaze/plugin.rb +69 -0
  281. data/lib/ramaze/reloader.rb +172 -0
  282. data/lib/ramaze/reloader/watch_inotify.rb +85 -0
  283. data/lib/ramaze/reloader/watch_stat.rb +58 -0
  284. data/lib/ramaze/request.rb +115 -0
  285. data/lib/ramaze/response.rb +36 -0
  286. data/lib/ramaze/setup.rb +123 -0
  287. data/lib/ramaze/snippets.rb +22 -0
  288. data/lib/ramaze/snippets/array/put_within.rb +44 -0
  289. data/lib/ramaze/snippets/binding/locals.rb +25 -0
  290. data/lib/ramaze/snippets/blankslate.rb +7 -0
  291. data/lib/ramaze/snippets/fiber.rb +63 -0
  292. data/lib/ramaze/snippets/kernel/pretty_inspect.rb +21 -0
  293. data/lib/ramaze/snippets/metaid.rb +17 -0
  294. data/lib/ramaze/snippets/numeric/filesize_format.rb +32 -0
  295. data/lib/ramaze/snippets/numeric/time.rb +63 -0
  296. data/lib/ramaze/snippets/object/__dir__.rb +29 -0
  297. data/lib/ramaze/snippets/object/instance_variable_defined.rb +19 -0
  298. data/lib/ramaze/snippets/object/pretty.rb +16 -0
  299. data/lib/ramaze/snippets/object/scope.rb +18 -0
  300. data/lib/ramaze/snippets/ordered_set.rb +51 -0
  301. data/lib/ramaze/snippets/proc/locals.rb +19 -0
  302. data/lib/ramaze/snippets/ramaze/acquire.rb +31 -0
  303. data/lib/ramaze/snippets/ramaze/deprecated.rb +23 -0
  304. data/lib/ramaze/snippets/ramaze/dictionary.rb +400 -0
  305. data/lib/ramaze/snippets/ramaze/fiber.rb +24 -0
  306. data/lib/ramaze/snippets/ramaze/struct.rb +45 -0
  307. data/lib/ramaze/snippets/string/camel_case.rb +21 -0
  308. data/lib/ramaze/snippets/string/color.rb +31 -0
  309. data/lib/ramaze/snippets/string/end_with.rb +20 -0
  310. data/lib/ramaze/snippets/string/esc.rb +34 -0
  311. data/lib/ramaze/snippets/string/ord.rb +21 -0
  312. data/lib/ramaze/snippets/string/snake_case.rb +21 -0
  313. data/lib/ramaze/snippets/string/start_with.rb +19 -0
  314. data/lib/ramaze/snippets/string/unindent.rb +28 -0
  315. data/lib/ramaze/snippets/thread/into.rb +18 -0
  316. data/lib/ramaze/spec.rb +33 -0
  317. data/lib/ramaze/spec/bacon.rb +34 -0
  318. data/lib/ramaze/spec/helper/bacon.rb +8 -0
  319. data/lib/ramaze/spec/helper/pretty_output.rb +82 -0
  320. data/lib/ramaze/spec/helper/snippets.rb +16 -0
  321. data/lib/ramaze/spec/helper/template_examples.rb +19 -0
  322. data/lib/ramaze/tool/bin.rb +340 -0
  323. data/lib/ramaze/tool/create.rb +48 -0
  324. data/lib/ramaze/tool/project_creator.rb +111 -0
  325. data/lib/ramaze/version.rb +3 -0
  326. data/lib/ramaze/view.rb +39 -0
  327. data/lib/ramaze/view/erubis.rb +23 -0
  328. data/lib/ramaze/view/ezamar.rb +23 -0
  329. data/lib/ramaze/view/gestalt.rb +14 -0
  330. data/lib/ramaze/view/haml.rb +16 -0
  331. data/lib/ramaze/view/liquid.rb +100 -0
  332. data/lib/ramaze/view/maruku.rb +15 -0
  333. data/lib/ramaze/view/nagoro.rb +44 -0
  334. data/lib/ramaze/view/nagoro/render_partial.rb +32 -0
  335. data/lib/ramaze/view/redcloth.rb +21 -0
  336. data/lib/ramaze/view/remarkably.rb +21 -0
  337. data/lib/ramaze/view/sass.rb +21 -0
  338. data/lib/ramaze/view/tagz.rb +63 -0
  339. data/lib/ramaze/view/tenjin.rb +32 -0
  340. data/lib/vendor/etag.rb +22 -0
  341. data/lib/vendor/route_exceptions.rb +42 -0
  342. data/ramaze.gemspec +85 -0
  343. data/spec/contrib/addressable_route.rb +32 -0
  344. data/spec/contrib/rest.rb +28 -0
  345. data/spec/examples/caching.rb +16 -0
  346. data/spec/examples/css.rb +14 -0
  347. data/spec/examples/element.rb +15 -0
  348. data/spec/examples/hello.rb +10 -0
  349. data/spec/examples/helpers/httpdigest.rb +64 -0
  350. data/spec/examples/linking.rb +17 -0
  351. data/spec/examples/simple.rb +40 -0
  352. data/spec/examples/templates/template_erubis.rb +10 -0
  353. data/spec/examples/templates/template_ezamar.rb +10 -0
  354. data/spec/examples/templates/template_haml.rb +10 -0
  355. data/spec/examples/templates/template_liquid.rb +10 -0
  356. data/spec/examples/templates/template_markaby.rb +11 -0
  357. data/spec/examples/templates/template_nagoro.rb +10 -0
  358. data/spec/examples/templates/template_redcloth.rb +10 -0
  359. data/spec/examples/templates/template_remarkably.rb +10 -0
  360. data/spec/examples/templates/template_tenjin.rb +10 -0
  361. data/spec/helper.rb +9 -0
  362. data/spec/ramaze/action/render.rb +21 -0
  363. data/spec/ramaze/action/view/bar.xhtml +1 -0
  364. data/spec/ramaze/action/view/instancevars/layout.xhtml +1 -0
  365. data/spec/ramaze/action/view/other_wrapper.erb +1 -0
  366. data/spec/ramaze/action/view/other_wrapper.xhtml +1 -0
  367. data/spec/ramaze/action/view/single_wrapper.xhtml +1 -0
  368. data/spec/ramaze/action/view/sub/sub_wrapper.erb +1 -0
  369. data/spec/ramaze/action/view/sub/sub_wrapper.xhtml +1 -0
  370. data/spec/ramaze/app.rb +47 -0
  371. data/spec/ramaze/bin/ramaze.rb +91 -0
  372. data/spec/ramaze/cache/localmemcache.rb +49 -0
  373. data/spec/ramaze/cache/memcache.rb +60 -0
  374. data/spec/ramaze/cache/sequel.rb +51 -0
  375. data/spec/ramaze/controller/actionless_templates.rb +36 -0
  376. data/spec/ramaze/controller/lonely_mapping.rb +16 -0
  377. data/spec/ramaze/controller/mapping.rb +43 -0
  378. data/spec/ramaze/controller/provide_inheritance.rb +47 -0
  379. data/spec/ramaze/controller/resolve.rb +30 -0
  380. data/spec/ramaze/controller/subclass.rb +36 -0
  381. data/spec/ramaze/controller/template_resolving.rb +77 -0
  382. data/spec/ramaze/controller/view/bar.xhtml +1 -0
  383. data/spec/ramaze/controller/view/base/another.xhtml +1 -0
  384. data/spec/ramaze/controller/view/greet.xhtml +1 -0
  385. data/spec/ramaze/controller/view/list.xhtml +1 -0
  386. data/spec/ramaze/controller/view/other/greet/other.xhtml +1 -0
  387. data/spec/ramaze/controller/view/other_wrapper.xhtml +1 -0
  388. data/spec/ramaze/dispatcher/directory.rb +69 -0
  389. data/spec/ramaze/dispatcher/file.rb +71 -0
  390. data/spec/ramaze/dispatcher/public/favicon.ico +0 -0
  391. data/spec/ramaze/dispatcher/public/file name.txt +1 -0
  392. data/spec/ramaze/dispatcher/public/test_download.css +141 -0
  393. data/spec/ramaze/error.rb +88 -0
  394. data/spec/ramaze/files.rb +29 -0
  395. data/spec/ramaze/files/public_1/plain.txt +1 -0
  396. data/spec/ramaze/files/public_2/rich.txt +1 -0
  397. data/spec/ramaze/gestalt.rb +135 -0
  398. data/spec/ramaze/helper/auth.rb +83 -0
  399. data/spec/ramaze/helper/bench.rb +18 -0
  400. data/spec/ramaze/helper/cache.rb +124 -0
  401. data/spec/ramaze/helper/flash.rb +41 -0
  402. data/spec/ramaze/helper/form.rb +356 -0
  403. data/spec/ramaze/helper/formatting.rb +111 -0
  404. data/spec/ramaze/helper/gestalt.rb +15 -0
  405. data/spec/ramaze/helper/gravatar.rb +40 -0
  406. data/spec/ramaze/helper/httpdigest.rb +144 -0
  407. data/spec/ramaze/helper/layout.rb +79 -0
  408. data/spec/ramaze/helper/layout/default.xhtml +5 -0
  409. data/spec/ramaze/helper/link.rb +70 -0
  410. data/spec/ramaze/helper/localize.rb +62 -0
  411. data/spec/ramaze/helper/maruku.rb +19 -0
  412. data/spec/ramaze/helper/pager.rb +96 -0
  413. data/spec/ramaze/helper/paginate.rb +68 -0
  414. data/spec/ramaze/helper/request_accessor.rb +19 -0
  415. data/spec/ramaze/helper/sequel_form.rb +91 -0
  416. data/spec/ramaze/helper/simple_captcha.rb +45 -0
  417. data/spec/ramaze/helper/stack.rb +86 -0
  418. data/spec/ramaze/helper/user.rb +72 -0
  419. data/spec/ramaze/helper/view/locals.xhtml +1 -0
  420. data/spec/ramaze/helper/view/loop.xhtml +4 -0
  421. data/spec/ramaze/helper/view/num.xhtml +1 -0
  422. data/spec/ramaze/helper/view/partial.xhtml +1 -0
  423. data/spec/ramaze/helper/view/recursive.xhtml +8 -0
  424. data/spec/ramaze/helper/view/recursive_local_ivars.xhtml +7 -0
  425. data/spec/ramaze/helper/view/recursive_locals.xhtml +7 -0
  426. data/spec/ramaze/helper/view/test_template.xhtml +1 -0
  427. data/spec/ramaze/helper/xhtml.rb +32 -0
  428. data/spec/ramaze/log/informer.rb +73 -0
  429. data/spec/ramaze/log/logging.rb +63 -0
  430. data/spec/ramaze/log/syslog.rb +73 -0
  431. data/spec/ramaze/params.rb +153 -0
  432. data/spec/ramaze/public/favicon.ico +0 -0
  433. data/spec/ramaze/public/ramaze.png +0 -0
  434. data/spec/ramaze/public/test_download.css +141 -0
  435. data/spec/ramaze/request.rb +61 -0
  436. data/spec/ramaze/rewrite/file.css +1 -0
  437. data/spec/ramaze/session/memcache.rb +66 -0
  438. data/spec/ramaze/struct.rb +47 -0
  439. data/spec/ramaze/template/ramaze/external.test +1 -0
  440. data/spec/ramaze/view.rb +36 -0
  441. data/spec/ramaze/view/erubis.rb +73 -0
  442. data/spec/ramaze/view/erubis/external.rhtml +8 -0
  443. data/spec/ramaze/view/erubis/sum.rhtml +1 -0
  444. data/spec/ramaze/view/ezamar.rb +73 -0
  445. data/spec/ramaze/view/ezamar/external.zmr +8 -0
  446. data/spec/ramaze/view/ezamar/sum.zmr +1 -0
  447. data/spec/ramaze/view/gestalt.rb +94 -0
  448. data/spec/ramaze/view/gestalt/external.ges +8 -0
  449. data/spec/ramaze/view/haml.rb +86 -0
  450. data/spec/ramaze/view/haml/external.haml +5 -0
  451. data/spec/ramaze/view/haml/sum.haml +2 -0
  452. data/spec/ramaze/view/liquid.rb +73 -0
  453. data/spec/ramaze/view/liquid/external.liquid +8 -0
  454. data/spec/ramaze/view/liquid/sum.liquid +1 -0
  455. data/spec/ramaze/view/nagoro.rb +73 -0
  456. data/spec/ramaze/view/nagoro/external.nag +8 -0
  457. data/spec/ramaze/view/nagoro/sum.nag +1 -0
  458. data/spec/ramaze/view/redcloth.rb +66 -0
  459. data/spec/ramaze/view/redcloth/external.redcloth +8 -0
  460. data/spec/ramaze/view/remarkably.rb +49 -0
  461. data/spec/ramaze/view/remarkably/external.rem +8 -0
  462. data/spec/ramaze/view/remarkably/sum.rem +1 -0
  463. data/spec/ramaze/view/sass.rb +73 -0
  464. data/spec/ramaze/view/sass/file.css.sass +5 -0
  465. data/spec/ramaze/view/tagz.rb +51 -0
  466. data/spec/ramaze/view/tagz/external.tagz +8 -0
  467. data/spec/ramaze/view/tagz/sum.tagz +1 -0
  468. data/spec/ramaze/view/tenjin.rb +57 -0
  469. data/spec/ramaze/view/tenjin/external.rbhtml +8 -0
  470. data/spec/ramaze/view/tenjin/sum.rbhtml +1 -0
  471. data/spec/snippets/array/put_within.rb +33 -0
  472. data/spec/snippets/binding/locals.rb +9 -0
  473. data/spec/snippets/numeric/filesize_format.rb +12 -0
  474. data/spec/snippets/numeric/time.rb +12 -0
  475. data/spec/snippets/object/__dir__.rb +14 -0
  476. data/spec/snippets/ordered_set.rb +63 -0
  477. data/spec/snippets/ramaze/acquire.rb +77 -0
  478. data/spec/snippets/ramaze/dictionary.rb +110 -0
  479. data/spec/snippets/ramaze/struct.rb +12 -0
  480. data/spec/snippets/string/camel_case.rb +25 -0
  481. data/spec/snippets/string/color.rb +11 -0
  482. data/spec/snippets/string/snake_case.rb +24 -0
  483. data/spec/snippets/string/unindent.rb +43 -0
  484. data/spec/snippets/thread/into.rb +9 -0
  485. data/tasks/authors.rake +30 -0
  486. data/tasks/bacon.rake +66 -0
  487. data/tasks/changelog.rake +20 -0
  488. data/tasks/copyright.rake +21 -0
  489. data/tasks/gem.rake +22 -0
  490. data/tasks/gem_setup.rake +99 -0
  491. data/tasks/git.rake +46 -0
  492. data/tasks/grancher.rake +12 -0
  493. data/tasks/jquery.rake +15 -0
  494. data/tasks/manifest.rake +4 -0
  495. data/tasks/metric_changes.rake +24 -0
  496. data/tasks/rcov.rake +23 -0
  497. data/tasks/release.rake +54 -0
  498. data/tasks/reversion.rake +8 -0
  499. data/tasks/setup.rake +6 -0
  500. data/tasks/todo.rake +27 -0
  501. data/tasks/traits.rake +21 -0
  502. data/tasks/yard.rake +4 -0
  503. metadata +720 -0
@@ -0,0 +1,168 @@
1
+ module Ramaze
2
+
3
+ module Logger
4
+
5
+ # A customized logger (based on Informer) that creates multiple log files based on time
6
+
7
+ class RotatingInformer
8
+ include Innate::Traited
9
+ include Logging
10
+
11
+ attr_accessor :time_format, :log_levels
12
+ attr_reader :base_dir
13
+
14
+ # parameter for Time.now.strftime
15
+ trait :timestamp => "%Y-%m-%d %H:%M:%S"
16
+
17
+ # This is how the final output is arranged.
18
+ trait :format => "[%time] %prefix %text"
19
+
20
+ # Create a new instance of RotatingInformer.
21
+ #
22
+ # base_dir is the directory where all log files will be stored
23
+ #
24
+ # time_format is the time format used to name the log files.
25
+ # Possible formats are identical to those
26
+ # accepted by Time.strftime
27
+ #
28
+ # log_levelse is an array describing what kind of messages
29
+ # that the log receives. The array may contain
30
+ # any or all of the symbols :debug, :error, :info and/or :warn
31
+ #
32
+ # Examples:
33
+ # RotatingInformer.new('logs')
34
+ # #=> Creates logs in directory called logs.
35
+ # The generated filenames will be in the
36
+ # form YYYY-MM-DD.log
37
+ # RotatingInformer.new('logs', '%Y-%m.txt')
38
+ # #=> Creates logs in directory called logs.
39
+ # The generated filenames will be in the
40
+ # form YYYY-MM.txt
41
+ # RotatingInformer.new('logs', '%Y-%m.txt', [:error])
42
+ # #=> Creates logs in directory called logs.
43
+ # The generated filenames will be in the
44
+ # form YYYY-MM.txt. Only errors will be
45
+ # logged to the files.
46
+
47
+ def initialize(base_dir, time_format = '%Y-%m-%d.log', log_levels = [:debug, :error, :info, :warn])
48
+ # Verify and set base directory
49
+ send :base_dir=, base_dir, true
50
+
51
+ @time_format = time_format
52
+ @log_levels = log_levels
53
+
54
+ # Keep track of log shutdown (to prevent StackErrors due to recursion)
55
+ @in_shutdown = false
56
+ end
57
+
58
+ # Set the base directory for log files
59
+ #
60
+ # If this method is called with the raise_exception
61
+ # parameter set to true the method will raise an exception
62
+ # if the specified directory does not exist or is unwritable.
63
+ #
64
+ # If raise_exception is set to false, the method will just
65
+ # silently fail if the specified directory does not exist
66
+ # or is unwritable
67
+
68
+ def base_dir=(directory, raise_exception = false)
69
+ # Expand directory path
70
+ base_dir = File.expand_path(directory)
71
+ # Verify that directory path exists
72
+ if File.exist?(base_dir)
73
+ # Verify that directory path is a directory
74
+ if File.directory?(base_dir)
75
+ # Verify that directory path is writable
76
+ if File.writable?(base_dir)
77
+ @base_dir = base_dir
78
+ else
79
+ raise Exception.new("#{base_dir} is not writable") if raise_exception
80
+ end
81
+ else
82
+ raise Exception.new("#{base_dir} is not a directory") if raise_exception
83
+ end
84
+ else
85
+ raise Exception.new("#{base_dir} does not exist.") if raise_exception
86
+ end
87
+ end
88
+
89
+ # Close the file we log to if it isn't closed already.
90
+
91
+ def shutdown
92
+ if @out.respond_to?(:close)
93
+ unless @in_shutdown
94
+ @in_shutdown = true
95
+ Log.debug("close, #{@out.inspect}")
96
+ @in_shutdown = false
97
+ end
98
+ @out.close
99
+ end
100
+ end
101
+
102
+ # Integration to Logging.
103
+
104
+ def log tag, *messages
105
+
106
+ return unless @log_levels.include?(tag)
107
+
108
+ # Update current log
109
+ update_current_log
110
+
111
+ messages.flatten!
112
+
113
+ prefix = tag.to_s.upcase.ljust(5)
114
+
115
+ messages.each do |message|
116
+ @out.puts(log_interpolate(prefix, message))
117
+ end
118
+
119
+ @out.flush if @out.respond_to?(:flush)
120
+ end
121
+
122
+ # Takes the prefix (tag), text and timestamp and applies it to
123
+ # the :format trait.
124
+
125
+ def log_interpolate prefix, text, time = timestamp
126
+ message = class_trait[:format].dup
127
+
128
+ vars = { '%time' => time, '%prefix' => prefix, '%text' => text }
129
+ vars.each{|from, to| message.gsub!(from, to) }
130
+
131
+ message
132
+ end
133
+
134
+ # This uses Global.inform_timestamp or a date in the format of
135
+ # %Y-%m-%d %H:%M:%S
136
+ # # => "2007-01-19 21:09:32"
137
+
138
+ def timestamp
139
+ mask = class_trait[:timestamp]
140
+ Time.now.strftime(mask || "%Y-%m-%d %H:%M:%S")
141
+ end
142
+
143
+ # is @out closed?
144
+
145
+ def closed?
146
+ @out.respond_to?(:closed?) && @out.closed?
147
+ end
148
+
149
+ private
150
+
151
+ # Checks whether current filename is still valid.
152
+ # If not, update the current log to point at the new
153
+ # filename
154
+
155
+ def update_current_log
156
+ out = File.join(@base_dir, Time.now.strftime(@time_format))
157
+ if @out.nil? || @out.path != out
158
+ # Close old log if necessary
159
+ shutdown unless @out.nil? || closed?
160
+
161
+ # Start new log
162
+ @out = File.open(out, 'ab+')
163
+ end
164
+ end
165
+ end
166
+
167
+ end
168
+ end
@@ -0,0 +1,51 @@
1
+ # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
+ # Copyright (c) 2008 rob@rebeltechnologies.nl
3
+ # All files in this distribution are subject to the terms of the Ruby license.
4
+
5
+ require 'syslog'
6
+
7
+ # Add aliases for the levelnames used by Ramaze logging
8
+ module Syslog
9
+ alias dev debug
10
+ alias warn warning
11
+ alias error err
12
+ module_function :dev, :warn, :error
13
+ end
14
+
15
+ module Ramaze
16
+ module Logger
17
+ # Logger class for writing to syslog. It is a *very* thin wrapper
18
+ # around the Syslog library.
19
+ class Syslog
20
+ include Logging
21
+
22
+ # Open the syslog library, if it is allready open, we reopen it using the
23
+ # new argument list. The argument list is passed on to the Syslog library
24
+ # so please check that, and man syslog for detailed information.
25
+ # There are 3 parameters:
26
+ #
27
+ # ident: The identification used in the log file, defaults to $0
28
+ # options: defaults to Syslog::LOG_PID | Syslog::LOG_CONS
29
+ # facility: defaults to Syslog::LOG_USER
30
+ #
31
+ def initialize( *args )
32
+ ::Syslog.close if ::Syslog.opened?
33
+ ::Syslog.open( *args )
34
+ end
35
+
36
+ # just sends all messages received to ::Syslog
37
+ # We simply return if the log was closed for some reason, this behavior
38
+ # was copied from Informer. We do not handle levels here. This will
39
+ # be done by te syslog daemon based on it's configuration.
40
+ def log(tag, *messages)
41
+ return if !::Syslog.opened?
42
+ ::Syslog.send(tag, *messages)
43
+ end
44
+
45
+ # Has to call the modules singleton-method.
46
+ def inspect
47
+ ::Syslog.inspect
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,92 @@
1
+ # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ Ramaze::Log.log( :warn, "Both xosd gems are currently known to be broken" )
5
+ require 'xosd'
6
+ require 'thread'
7
+
8
+ module Ramaze
9
+ module Logger
10
+
11
+ # Informer for the XOSD notification system for X11.
12
+ #
13
+ # You can install the ruby-bindings with:
14
+ # gem install xosd.
15
+
16
+ class Xosd < ::Xosd
17
+ attr_accessor :options
18
+
19
+ include Logging
20
+
21
+ DEFAULT = {
22
+ :font_size => 20,
23
+ :font => "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*",
24
+ :align => 'center',
25
+ :color => '#FFFFFF',
26
+ :lines => 3,
27
+ :valign => 'top',
28
+ :timeout => 3,
29
+ :outline_color => "#000000",
30
+ :outline_width => 1,
31
+ :vertical_offset => 20,
32
+ :colors => {
33
+ :error => "#FF0000",
34
+ :info => "#00FF00",
35
+ :warn => "#EAA61E",
36
+ :debug => "#FFFF00"
37
+ },
38
+ }
39
+
40
+ # keys to ignore when setting the options to the instance.
41
+ IGNORE = [:colors, :font_size, :lines]
42
+
43
+ # Here new messages are pushed to eventually displaying them.
44
+ QUEUE = Queue.new
45
+
46
+ # Create a new instance, valid options are in DEFAULT.
47
+ # In the background a new thread will be running that checks the QUEUE
48
+ # and processes all messages that are being sent to it.
49
+ # This is done to make output nicer and readable.
50
+
51
+ def initialize(options = {})
52
+ @options = DEFAULT.merge(options)
53
+
54
+ super(@options[:lines])
55
+
56
+ @options.each do |key, value|
57
+ next if IGNORE.include?(key)
58
+ value %= @options[:font_size] if key == :font
59
+ send("#{key}=", value)
60
+ end
61
+
62
+ Thread.new(self) do |xosd|
63
+ loop do
64
+ items = []
65
+ lines = xosd.options[:lines]
66
+ items << QUEUE.shift until QUEUE.empty? or items.size >= lines
67
+
68
+ unless items.empty?
69
+ # pad up with empty lines to avoid dragging around old messages.
70
+ items << [:info, ' '] until items.size >= lines
71
+
72
+ items.each_with_index do |(tag, message), i|
73
+ xosd.color = xosd.options[:colors][tag.to_sym]
74
+ xosd.display(message, i)
75
+ end
76
+ end
77
+ sleep xosd.options[:timeout]
78
+ end
79
+ end
80
+ end
81
+
82
+ # pushes all messages it gets on the QUEUE for further processing.
83
+
84
+ def log(tag, *messages)
85
+ messages.each do |message|
86
+ QUEUE << [tag, message]
87
+ end
88
+ end
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,13 @@
1
+ module Ramaze
2
+ class MiddlewareCompiler < Innate::MiddlewareCompiler
3
+ def static(path)
4
+ require 'rack/contrib'
5
+ Rack::ETag.new(Rack::ConditionalGet.new(Rack::File.new(path)))
6
+ end
7
+
8
+ def directory(path)
9
+ require 'rack/contrib'
10
+ Rack::ETag.new(Rack::ConditionalGet.new(Rack::Directory.new(path)))
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,69 @@
1
+ # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ module Ramaze
5
+ def self.plugin(name, options = {})
6
+ Plugin.load(name, options)
7
+ end
8
+
9
+ module Plugin
10
+ PLUGIN_LIST = Set.new
11
+ EXTS = %w[rb so bundle]
12
+ PATH = []
13
+ POOL = []
14
+
15
+ module_function
16
+
17
+ Ramaze.options.setup << self
18
+
19
+ def setup
20
+ PLUGIN_LIST.each do |name, const, options|
21
+ const.setup(options) if const.respond_to?(:setup)
22
+ end
23
+ end
24
+
25
+ def teardown
26
+ PLUGIN_LIST.each do |name, const, options|
27
+ const.teardown if const.respond_to?(:teardown)
28
+ end
29
+ end
30
+
31
+ def add_pool(pool)
32
+ POOL.unshift(pool)
33
+ POOL.uniq!
34
+ end
35
+
36
+ add_pool(self)
37
+
38
+ def add_path(path)
39
+ PATH.unshift(File.expand_path(path))
40
+ PATH.uniq!
41
+ end
42
+
43
+ add_path(__DIR__)
44
+ add_path('')
45
+
46
+ def load(name, options)
47
+ name = name.to_s
48
+ try_require(name.snake_case)
49
+ PLUGIN_LIST << [name, const_get(name.camel_case), options]
50
+ rescue Exception => exception
51
+ Log.error(exception)
52
+ raise LoadError, "Plugin #{name} not found"
53
+ end
54
+
55
+ def try_require(name)
56
+ found = Dir[glob(name)].first
57
+ require(File.expand_path(found)) if found
58
+ rescue LoadError
59
+ end
60
+
61
+ def glob(name = '*')
62
+ "{#{paths.join(',')}}/plugin/#{name}.{#{EXTS.join(',')}}"
63
+ end
64
+
65
+ def paths
66
+ PATH
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,172 @@
1
+ # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ module Ramaze
5
+
6
+ # High performant source reloader
7
+ #
8
+ # This class acts as Rack middleware.
9
+ #
10
+ # It does not depend on Ramaze itself, but you might have to adjust the
11
+ # Reloader::Hooks module or include your own module to override the hooks.
12
+ # You also might have to set the Log constant.
13
+ #
14
+ # Currently, it uses RInotify if available and falls back to using File.stat.
15
+ #
16
+ # Please note that this will not reload files in the background, it does so
17
+ # only when actively called
18
+ # In case of Ramaze it is performing a check/reload cycle at the start of
19
+ # every request, but also respects a cool down time, during which nothing will
20
+ # be done.
21
+ #
22
+ # After every reload the OPTIONS hash will be checked for changed options and
23
+ # assigned to the instance, so you may change options during the lifetime of
24
+ # your application.
25
+ #
26
+ # A number of hooks will be executed during the reload cycle, see
27
+ # Ramaze::ReloaderHooks for more information.
28
+
29
+ class Reloader
30
+ OPTIONS = {
31
+ # At most check every n seconds
32
+ # nil/false will never trigger the reload cycle
33
+ # 0 will cycle on every call
34
+ :cooldown => 2,
35
+
36
+ # Compiled files cannot be reloaded during runtime
37
+ :ignore => /\.so$/,
38
+
39
+ # Run cycle in a Thread.exclusive, by default no threads are used.
40
+ :thread => false,
41
+
42
+ # If you assign a block here it will be instance_evaled instead of
43
+ # calling cycle. This allows you to use for example EventMachine for
44
+ # well performing asynchronous cycling.
45
+ :control => nil, # lambda{ cycle },
46
+ }
47
+
48
+ begin
49
+ begin
50
+ gem('RInotify', '>=0.9') # is older version ok?
51
+ rescue NoMethodError # Kernel::gem might simply be not available
52
+ end
53
+
54
+ require 'rinotify'
55
+ require 'ramaze/reloader/watch_inotify'
56
+ Watcher = WatchInotify
57
+ rescue LoadError
58
+ # stat always available
59
+ require 'ramaze/reloader/watch_stat'
60
+ Watcher = WatchStat
61
+ end
62
+
63
+ def initialize(app)
64
+ @app = app
65
+ @files = {}
66
+ @watcher = Watcher.new
67
+ options_reload
68
+ end
69
+
70
+ def options_reload
71
+ @cooldown, @ignore, @control, @thread =
72
+ OPTIONS.values_at(:cooldown, :ignore, :control, :thread)
73
+ end
74
+
75
+ def call(env)
76
+ options_reload
77
+
78
+ @watcher.call(@cooldown) do
79
+ if @control
80
+ instance_eval(&@control)
81
+ elsif @thread
82
+ Thread.exclusive{ cycle }
83
+ else
84
+ cycle
85
+ end
86
+ end
87
+
88
+ @app.call(env)
89
+ end
90
+
91
+ def cycle
92
+ before_cycle
93
+
94
+ rotation{|file| @watcher.watch(file) }
95
+ @watcher.changed_files{|f| safe_load(f) }
96
+
97
+ after_cycle
98
+ end
99
+
100
+ # A safe Kernel::load, issuing the hooks depending on the results
101
+ def safe_load(file)
102
+ before_safe_load(file)
103
+ load(file)
104
+ after_safe_load_succeed(file)
105
+ rescue Object => ex
106
+ Log.error(ex)
107
+ after_safe_load_failed(file, ex)
108
+ end
109
+
110
+ def rotation
111
+ files = [$0, __FILE__, *$LOADED_FEATURES].uniq
112
+ paths = ['./', *$LOAD_PATH].uniq
113
+
114
+ files.each do |file|
115
+ next if file =~ @ignore
116
+ if not @files.has_key?(file) and path = figure_path(file, paths)
117
+ @files[file] = path
118
+ yield path
119
+ end
120
+ end
121
+ end
122
+
123
+ def figure_path(file, paths)
124
+ if Pathname.new(file).absolute?
125
+ return File.exist?(file) ? file : nil
126
+ end
127
+
128
+ paths.each do |possible_path|
129
+ full_path = File.join(possible_path, file)
130
+ return full_path if File.exist?(full_path)
131
+ end
132
+ nil
133
+ end
134
+
135
+
136
+ # Holds hooks that are called before and after #cycle and #safe_load
137
+ module Hooks
138
+ # Overwrite to add actions before the reload rotation is started.
139
+ def before_cycle
140
+ end
141
+
142
+ # Overwrite to add actions after the reload rotation has ended.
143
+ def after_cycle
144
+ end
145
+
146
+ # Overwrite to add actions before a file is Kernel::load-ed
147
+ def before_safe_load(file)
148
+ Log.debug("reload #{file}")
149
+ end
150
+
151
+ # Overwrite to add actions after a file is Kernel::load-ed successfully,
152
+ # by default we clean the Cache for compiled templates and resolved actions.
153
+ def after_safe_load_succeed(file)
154
+ Cache.clear_after_reload
155
+ after_safe_load(file)
156
+ end
157
+
158
+ # Overwrite to add custom hook in addition to default Cache cleaning
159
+ def after_safe_load(file)
160
+ end
161
+
162
+ # Overwrite to add actions after a file is Kernel::load-ed unsuccessfully,
163
+ # by default we output an error-message with the exception.
164
+ def after_safe_load_failed(file, error)
165
+ Log.error(error)
166
+ end
167
+ end
168
+
169
+ include Hooks
170
+
171
+ end
172
+ end