spontaneous 0.2.0.alpha2 → 0.2.0.alpha3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (404) hide show
  1. data/Gemfile +3 -40
  2. data/Rakefile +29 -41
  3. data/Readme.markdown +21 -8
  4. data/application/css/add_alias_dialogue.css.scss +79 -0
  5. data/application/css/{v2.scss → core.css.scss} +537 -550
  6. data/application/css/{definitions.scss → definitions.css.scss} +121 -33
  7. data/application/css/dialogue.css.scss +409 -0
  8. data/application/css/{editing.scss → editing.css.scss} +25 -262
  9. data/application/css/font.css.scss +8 -0
  10. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  11. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  12. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_flat_10_000000_40x100.png +0 -0
  13. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  14. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  15. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  16. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  17. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  18. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  19. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_222222_256x240.png +0 -0
  20. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_228ef1_256x240.png +0 -0
  21. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ef8c08_256x240.png +0 -0
  22. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffd27a_256x240.png +0 -0
  23. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffffff_256x240.png +0 -0
  24. data/application/css/jquery-ui-1.8.21.custom/ui-lightness.css.scss +565 -0
  25. data/application/css/{login.scss → login.css.scss} +4 -4
  26. data/application/css/meta.css.scss +331 -0
  27. data/application/css/{popover.scss → popover.css.scss} +9 -8
  28. data/application/css/{schema_error.scss → schema_error.css.scss} +4 -4
  29. data/application/css/spontaneous.css +5 -0
  30. data/application/css/unsupported.css.scss +42 -0
  31. data/application/js/add_alias_dialogue.js +72 -10
  32. data/application/js/ajax.js +50 -16
  33. data/application/js/compatibility.js +19 -15
  34. data/application/js/content.js +39 -36
  35. data/application/js/content_area.js +53 -5
  36. data/application/js/dialogue.js +17 -0
  37. data/application/js/dom.js +1 -1
  38. data/application/js/edit_panel.js +23 -8
  39. data/application/js/extensions.js +7 -2
  40. data/application/js/field_preview.js +2 -1
  41. data/application/js/field_types/date_field.js +11 -8
  42. data/application/js/field_types/file_field.js +188 -9
  43. data/application/js/field_types/image_field.js +46 -29
  44. data/application/js/field_types/markdown_field.js +57 -14
  45. data/application/js/field_types/select_field.js +72 -0
  46. data/application/js/field_types/string_field.js +8 -0
  47. data/application/js/field_types/webvideo_field.js +8 -0
  48. data/application/js/init.js +1 -7
  49. data/application/js/location.js +41 -13
  50. data/application/js/login.js +3 -0
  51. data/application/js/meta_view/user_admin.js +543 -0
  52. data/application/js/meta_view.js +1 -0
  53. data/application/js/metadata.js +20 -0
  54. data/application/js/page.js +17 -3
  55. data/application/js/page_browser.js +40 -30
  56. data/application/js/page_entry.js +4 -0
  57. data/application/js/panel/root_menu.js +66 -0
  58. data/application/js/popover.js +2 -2
  59. data/application/js/preview.js +1 -1
  60. data/application/js/publish.js +138 -30
  61. data/application/js/services.js +43 -0
  62. data/application/js/sharded_upload.js +2 -2
  63. data/application/js/spontaneous.js +64 -5
  64. data/application/js/state.js +20 -9
  65. data/application/js/top_bar.js +273 -150
  66. data/application/js/types.js +20 -15
  67. data/application/js/upload.js +1 -2
  68. data/application/js/user.js +18 -4
  69. data/application/js/vendor/date.js +104 -0
  70. data/application/js/vendor/jquery-ui-1.8.18.custom.min.js +356 -0
  71. data/application/js/views/box_view.js +15 -8
  72. data/application/js/views/page_piece_view.js +11 -8
  73. data/application/js/views/page_view.js +21 -3
  74. data/application/js/views/piece_view.js +19 -10
  75. data/application/js/views.js +3 -0
  76. data/application/static/chromelogo-200x52-45c7cbc93be080bea342df5fcda2ef8b.png +0 -0
  77. data/application/static/dot-texture-9eea29e4ac7ad9a772285252078ec127.png +0 -0
  78. data/application/static/editing-textarea-resize-s-b5af62365eb7e19ea4beccf7242d508e.png +0 -0
  79. data/application/static/editing-texture-1-42b06a3439752490988f30f2a06d5e7c.png +0 -0
  80. data/application/static/font/fontawesome-webfont-5c5c21100a346972a82c34c5e96ffcfe.ttf +0 -0
  81. data/application/static/loop_alt1-white-7894b458528e92216196cae26b4c2c96.svg +12 -0
  82. data/application/static/spontaneous-states-e91ec89db525c62da0105b97cdd781ce.png +0 -0
  83. data/application/views/index.erb +2 -2
  84. data/application/views/login.erb +4 -8
  85. data/application/views/schema_modification_error.html.erb +1 -4
  86. data/application/views/unsupported.erb +9 -7
  87. data/bin/spot +1 -1
  88. data/db/migrations/20110209152710_users_and_groups.rb +10 -10
  89. data/db/migrations/20120305112647_site_modification_time.rb +11 -0
  90. data/db/migrations/20120418153903_add_ownership_of_content.rb +14 -0
  91. data/db/migrations/20120423175416_add_pending_modifications.rb +21 -0
  92. data/db/migrations/20120525164947_add_field_versions.rb +27 -0
  93. data/lib/sequel/plugins/scoped_table_name.rb +10 -1
  94. data/lib/spontaneous/asset/file.rb +25 -0
  95. data/lib/spontaneous/asset/source.rb +28 -0
  96. data/lib/spontaneous/asset.rb +75 -0
  97. data/lib/spontaneous/box.rb +6 -4
  98. data/lib/spontaneous/capistrano/deploy.rb +47 -0
  99. data/lib/spontaneous/capistrano/sync.rb +81 -0
  100. data/lib/spontaneous/capistrano.rb +13 -0
  101. data/lib/spontaneous/change.rb +60 -68
  102. data/lib/spontaneous/cli/assets.rb +29 -0
  103. data/lib/spontaneous/cli/base.rb +0 -48
  104. data/lib/spontaneous/cli/console.rb +1 -1
  105. data/lib/spontaneous/cli/server.rb +6 -4
  106. data/lib/spontaneous/cli/site.rb +28 -17
  107. data/lib/spontaneous/cli/user.rb +107 -0
  108. data/lib/spontaneous/cli.rb +100 -4
  109. data/lib/spontaneous/collections/entry_set.rb +2 -2
  110. data/lib/spontaneous/collections/field_set.rb +48 -22
  111. data/lib/spontaneous/collections/prototype_set.rb +20 -13
  112. data/lib/spontaneous/constants.rb +3 -0
  113. data/lib/spontaneous/content.rb +22 -5
  114. data/lib/spontaneous/errors.rb +3 -3
  115. data/lib/spontaneous/extensions/array.rb +12 -0
  116. data/lib/spontaneous/extensions/enumerable.rb +30 -0
  117. data/lib/spontaneous/extensions/nil.rb +3 -1
  118. data/lib/spontaneous/extensions/string.rb +16 -0
  119. data/lib/spontaneous/field_types/date_field.rb +45 -2
  120. data/lib/spontaneous/field_types/field.rb +42 -9
  121. data/lib/spontaneous/field_types/file_field.rb +68 -0
  122. data/lib/spontaneous/field_types/image_field.rb +63 -0
  123. data/lib/spontaneous/field_types/select_field.rb +109 -0
  124. data/lib/spontaneous/field_types/string_field.rb +6 -1
  125. data/lib/spontaneous/field_types/webvideo_field.rb +85 -27
  126. data/lib/spontaneous/field_types.rb +1 -1
  127. data/lib/spontaneous/field_version.rb +8 -0
  128. data/lib/spontaneous/generators/page.rb +1 -1
  129. data/lib/spontaneous/generators/site/Capfile.tt +1 -4
  130. data/lib/spontaneous/generators/site/Gemfile.tt +13 -6
  131. data/lib/spontaneous/generators/site/config/deploy.rb.tt +28 -0
  132. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +7 -2
  133. data/lib/spontaneous/generators/site.rb +1 -0
  134. data/lib/spontaneous/json.rb +34 -11
  135. data/lib/spontaneous/layout.rb +22 -0
  136. data/lib/spontaneous/media/file.rb +4 -0
  137. data/lib/spontaneous/output/assets/compression.rb +58 -0
  138. data/lib/spontaneous/output/assets.rb +32 -0
  139. data/lib/spontaneous/output/context.rb +179 -0
  140. data/lib/spontaneous/output/format/html.rb +5 -0
  141. data/lib/spontaneous/output/format/plain.rb +5 -0
  142. data/lib/spontaneous/output/format.rb +180 -0
  143. data/lib/spontaneous/output/helpers/classes_helper.rb +18 -0
  144. data/lib/spontaneous/{render/helpers/html_helper.rb → output/helpers/conditional_comment_helper.rb} +3 -12
  145. data/lib/spontaneous/output/helpers/script_helper.rb +73 -0
  146. data/lib/spontaneous/output/helpers/stylesheet_helper.rb +61 -0
  147. data/lib/spontaneous/output/helpers.rb +28 -0
  148. data/lib/spontaneous/output/template/engine.rb +59 -0
  149. data/lib/spontaneous/output/template/renderer.rb +153 -0
  150. data/lib/spontaneous/output/template.rb +21 -0
  151. data/lib/spontaneous/output.rb +163 -0
  152. data/lib/spontaneous/page.rb +2 -1
  153. data/lib/spontaneous/paths.rb +6 -1
  154. data/lib/spontaneous/permissions/access_key.rb +5 -5
  155. data/lib/spontaneous/permissions/user.rb +81 -35
  156. data/lib/spontaneous/permissions/user_level.rb +26 -22
  157. data/lib/spontaneous/plugins/aliases.rb +76 -12
  158. data/lib/spontaneous/plugins/allowed_types.rb +60 -18
  159. data/lib/spontaneous/plugins/application/paths.rb +0 -28
  160. data/lib/spontaneous/plugins/application/system.rb +35 -0
  161. data/lib/spontaneous/plugins/boxes.rb +4 -0
  162. data/lib/spontaneous/plugins/content_groups.rb +16 -0
  163. data/lib/spontaneous/plugins/entries.rb +50 -30
  164. data/lib/spontaneous/plugins/fields.rb +15 -0
  165. data/lib/spontaneous/plugins/layouts.rb +8 -2
  166. data/lib/spontaneous/plugins/modifications.rb +228 -0
  167. data/lib/spontaneous/plugins/page/formats.rb +67 -42
  168. data/lib/spontaneous/plugins/page/request.rb +10 -0
  169. data/lib/spontaneous/plugins/page/site_timestamps.rb +28 -0
  170. data/lib/spontaneous/plugins/paths.rb +15 -3
  171. data/lib/spontaneous/plugins/publishing.rb +124 -45
  172. data/lib/spontaneous/plugins/render.rb +13 -8
  173. data/lib/spontaneous/plugins/schema_hierarchy.rb +18 -6
  174. data/lib/spontaneous/plugins/site/helpers.rb +53 -0
  175. data/lib/spontaneous/plugins/site/hooks.rb +50 -0
  176. data/lib/spontaneous/plugins/site/map.rb +1 -1
  177. data/lib/spontaneous/plugins/site/paths.rb +13 -0
  178. data/lib/spontaneous/plugins/site/publishing.rb +6 -2
  179. data/lib/spontaneous/plugins/site/{revisions.rb → state.rb} +5 -1
  180. data/lib/spontaneous/plugins/site/storage.rb +4 -0
  181. data/lib/spontaneous/plugins/site/url.rb +15 -0
  182. data/lib/spontaneous/plugins/site_map.rb +13 -3
  183. data/lib/spontaneous/plugins/styles.rb +5 -1
  184. data/lib/spontaneous/plugins/visibility.rb +39 -12
  185. data/lib/spontaneous/prototypes/box_prototype.rb +4 -0
  186. data/lib/spontaneous/prototypes/field_prototype.rb +15 -10
  187. data/lib/spontaneous/publishing/event_client.rb +46 -0
  188. data/lib/spontaneous/publishing/immediate.rb +81 -44
  189. data/lib/spontaneous/publishing/simultaneous.rb +23 -6
  190. data/lib/spontaneous/publishing.rb +4 -3
  191. data/lib/spontaneous/rack/around_back.rb +1 -5
  192. data/lib/spontaneous/rack/around_front.rb +4 -4
  193. data/lib/spontaneous/rack/around_preview.rb +4 -3
  194. data/lib/spontaneous/rack/assets.rb +81 -54
  195. data/lib/spontaneous/rack/authentication.rb +0 -1
  196. data/lib/spontaneous/rack/back.rb +160 -72
  197. data/lib/spontaneous/rack/cookie_authentication.rb +2 -2
  198. data/lib/spontaneous/rack/css.rb +18 -15
  199. data/lib/spontaneous/rack/event_source.rb +9 -21
  200. data/lib/spontaneous/rack/fiber_pool.rb +26 -0
  201. data/lib/spontaneous/rack/front.rb +12 -4
  202. data/lib/spontaneous/rack/helpers.rb +35 -13
  203. data/lib/spontaneous/rack/js.rb +41 -0
  204. data/lib/spontaneous/rack/public.rb +34 -44
  205. data/lib/spontaneous/rack/sse.rb +18 -0
  206. data/lib/spontaneous/rack/static.rb +3 -0
  207. data/lib/spontaneous/rack/user_admin.rb +100 -0
  208. data/lib/spontaneous/rack/user_helpers.rb +1 -1
  209. data/lib/spontaneous/rack.rb +6 -2
  210. data/lib/spontaneous/schema.rb +31 -4
  211. data/lib/spontaneous/search/index.rb +19 -3
  212. data/lib/spontaneous/search/results.rb +1 -1
  213. data/lib/spontaneous/sequel.rb +17 -0
  214. data/lib/spontaneous/site.rb +11 -4
  215. data/lib/spontaneous/state.rb +11 -0
  216. data/lib/spontaneous/storage/cloud.rb +4 -0
  217. data/lib/spontaneous/storage/local.rb +11 -0
  218. data/lib/spontaneous/style.rb +2 -2
  219. data/lib/spontaneous/tasks/database.rake +21 -22
  220. data/lib/spontaneous/utils/database/mysql_dumper.rb +4 -0
  221. data/lib/spontaneous/utils/database/postgres_dumper.rb +78 -0
  222. data/lib/spontaneous/utils/database.rb +6 -3
  223. data/lib/spontaneous/utils/smart_quotes.rb +499 -0
  224. data/lib/spontaneous/utils/smush_it.rb +66 -0
  225. data/lib/spontaneous/utils.rb +3 -1
  226. data/lib/spontaneous/version.rb +2 -2
  227. data/lib/spontaneous.rb +25 -29
  228. data/spontaneous.gemspec +186 -106
  229. data/test/experimental/test_features.rb +1 -1
  230. data/test/fixtures/asset_pipeline/application/css/basic.css.scss +4 -0
  231. data/test/fixtures/asset_pipeline/application/css/complex.css.scss.erb +6 -0
  232. data/test/fixtures/asset_pipeline/application/css/simple.css +3 -0
  233. data/test/fixtures/asset_pipeline/application/css/spontaneous.css +7 -0
  234. data/test/fixtures/asset_pipeline/application/css/subdir/complex.css.scss.erb +6 -0
  235. data/test/fixtures/asset_pipeline/application/css/subdir/library.css.scss +1 -0
  236. data/test/fixtures/asset_pipeline/application/css/subdir/simple.css +3 -0
  237. data/test/fixtures/asset_pipeline/application/js/basic.js.coffee +1 -0
  238. data/test/fixtures/asset_pipeline/application/js/complex.js.coffee.erb +1 -0
  239. data/test/fixtures/asset_pipeline/application/js/login.js +1 -0
  240. data/test/fixtures/asset_pipeline/application/js/require.js +1 -0
  241. data/test/fixtures/asset_pipeline/application/js/simple.js +1 -0
  242. data/test/fixtures/asset_pipeline/application/js/spontaneous.js +5 -0
  243. data/test/fixtures/asset_pipeline/application/js/subdir/complex.js.coffee.erb +1 -0
  244. data/test/fixtures/asset_pipeline/application/js/subdir/library.js.coffee +1 -0
  245. data/test/fixtures/asset_pipeline/application/js/subdir/simple.js +1 -0
  246. data/test/fixtures/asset_pipeline/application/js/vendor/jquery.js +1 -0
  247. data/test/fixtures/asset_pipeline/application/static/dot-texture.png +0 -0
  248. data/test/fixtures/asset_pipeline/application/static/subdir/px.gif +0 -0
  249. data/test/fixtures/assets/public1/css/a.scss +1 -0
  250. data/test/fixtures/assets/public1/js/a.js +1 -0
  251. data/test/fixtures/assets/public1/js/m.coffee +1 -0
  252. data/test/fixtures/assets/public2/css/b.scss +1 -0
  253. data/test/fixtures/assets/public2/css/c.css +1 -0
  254. data/test/fixtures/assets/public2/js/b.js +1 -0
  255. data/test/fixtures/assets/public2/js/c.js +1 -0
  256. data/test/fixtures/assets/public2/js/n.coffee +1 -0
  257. data/test/fixtures/back/config/user_levels.yml +3 -0
  258. data/test/fixtures/back/public/js/coffeescript.coffee +1 -0
  259. data/test/fixtures/back/templates/layouts/standard.css.cut +1 -0
  260. data/test/fixtures/back/templates/layouts/standard.js.cut +1 -0
  261. data/test/fixtures/example_application/config/database.yml +4 -4
  262. data/test/fixtures/helpers/templates/layouts/standard.html.cut +1 -0
  263. data/test/fixtures/helpers/templates/layouts/standard.mobile.cut +1 -0
  264. data/test/fixtures/images/vimlogo.pdf +0 -0
  265. data/test/fixtures/outputs/templates/layouts/standard.atom.cut +1 -0
  266. data/test/fixtures/permissions/config/user_levels.yml +6 -3
  267. data/test/fixtures/serialisation/class_hash.yaml.erb +1 -0
  268. data/test/fixtures/serialisation/root_hash.yaml.erb +2 -2
  269. data/test/fixtures/templates/extended/grandparent.html.cut +7 -7
  270. data/test/fixtures/templates/extended/main.html.cut +5 -5
  271. data/test/fixtures/templates/extended/parent.html.cut +8 -8
  272. data/test/fixtures/templates/extended/partial_with_locals.html.cut +1 -1
  273. data/test/fixtures/templates/extended/with_includes.html.cut +6 -6
  274. data/test/fixtures/templates/extended/with_includes_and_locals.html.cut +6 -7
  275. data/test/fixtures/templates/layouts/entries.html.cut +4 -4
  276. data/test/fixtures/templates/layouts/standard.html.cut +1 -0
  277. data/test/fixtures/templates/layouts/variables.html.cut +1 -1
  278. data/test/fixtures/templates/publishing/templates/layouts/static.html.cut +1 -1
  279. data/test/fixtures/templates/publishing/templates/layouts/static.rtf.cut +1 -0
  280. data/test/fixtures/templates/template_class/complex_template.html.cut +2 -2
  281. data/test/fixtures/templates/template_class/complex_template.pdf.cut +2 -2
  282. data/test/fixtures/templates/template_class/default_template_style.html.cut +1 -1
  283. data/test/fixtures/templates/template_class/images_with_template.html.cut +2 -2
  284. data/test/fixtures/templates/template_class/slots_template.html.cut +2 -2
  285. data/test/fixtures/templates/template_class/slots_template.pdf.cut +2 -2
  286. data/test/fixtures/user_manager/config/user_levels.yml +9 -0
  287. data/test/functional/test_application.rb +7 -7
  288. data/test/functional/test_back.rb +352 -97
  289. data/test/functional/test_front.rb +71 -20
  290. data/test/functional/test_user_manager.rb +284 -0
  291. data/test/javascript/env.js +13505 -0
  292. data/test/javascript/test_markdown.rb +43 -3
  293. data/test/support/custom_matchers.rb +3 -2
  294. data/test/test_helper.rb +50 -9
  295. data/test/test_javascript.rb +13 -13
  296. data/test/ui_helper.rb +1 -1
  297. data/test/unit/test_alias.rb +79 -8
  298. data/test/unit/test_asset_bundler.rb +220 -0
  299. data/test/unit/test_assets.rb +213 -0
  300. data/test/unit/test_async.rb +55 -0
  301. data/test/unit/test_authentication.rb +52 -39
  302. data/test/unit/test_boxes.rb +20 -15
  303. data/test/unit/test_changesets.rb +261 -0
  304. data/test/unit/test_content.rb +73 -33
  305. data/test/unit/test_content_inheritance.rb +18 -18
  306. data/test/unit/test_extensions.rb +26 -0
  307. data/test/unit/test_fields.rb +303 -16
  308. data/test/unit/test_formats.rb +267 -34
  309. data/test/unit/test_helpers.rb +79 -2
  310. data/test/unit/test_images.rb +10 -0
  311. data/test/unit/test_layouts.rb +21 -13
  312. data/test/unit/test_modifications.rb +648 -0
  313. data/test/unit/test_page.rb +6 -2
  314. data/test/unit/test_permissions.rb +101 -27
  315. data/test/unit/test_piece.rb +4 -4
  316. data/test/unit/test_plugins.rb +3 -2
  317. data/test/unit/test_publishing.rb +332 -0
  318. data/test/unit/test_render.rb +118 -67
  319. data/test/unit/test_revisions.rb +546 -0
  320. data/test/unit/test_schema.rb +83 -1
  321. data/test/unit/test_search.rb +59 -0
  322. data/test/unit/test_serialisation.rb +2 -47
  323. data/test/unit/test_site.rb +217 -108
  324. data/test/unit/test_storage.rb +26 -0
  325. data/test/unit/test_structure.rb +2 -2
  326. data/test/unit/test_styles.rb +90 -75
  327. data/test/unit/test_table_scoping.rb +21 -17
  328. data/test/unit/test_templates.rb +75 -69
  329. data/test/{slow → unit}/test_visibility.rb +78 -22
  330. metadata +528 -221
  331. data/application/css/add_alias_dialogue.scss +0 -27
  332. data/application/css/min/14c2a35812c443001b15d8b12a4780f88c678035.css +0 -1
  333. data/application/css/min/565d4c25e82148acb01c45c8d675b37a08676d77.css +0 -1
  334. data/application/css/min/84dbe894ea96eafd321c30823d630817bfc4b03b.css +0 -1
  335. data/application/css/spontaneous.scss +0 -111
  336. data/application/css/unsupported.scss +0 -16
  337. data/application/css/variables.scss +0 -80
  338. data/application/js/min/2a0c2962537a3181fedfff5c92596ba6d3122dc9.js +0 -3
  339. data/application/js/min/4cf1c493d3379ecba5287758c61238034c0893f9.js +0 -2
  340. data/application/js/min/78ac6b99d96750bb6b9f9aad4cb9cd91cd03f391.js +0 -3
  341. data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +0 -2
  342. data/application/js/min/c8efb9b9f7c3f6613fcebc6be60f605b6570a382.js +0 -90
  343. data/application/static/diagonal-texture.png +0 -0
  344. data/application/static/editing-0-noise.png +0 -0
  345. data/application/static/editing-1-noise.png +0 -0
  346. data/application/static/editing-texture-1.png +0 -0
  347. data/application/static/editing-texture.png +0 -0
  348. data/application/static/editing-toolbar-shadow-bottom.png +0 -0
  349. data/application/static/editing-toolbar-shadow-top.png +0 -0
  350. data/application/static/inner-glow.png +0 -0
  351. data/application/static/item-buttons-highlight.png +0 -0
  352. data/application/static/item-buttons.png +0 -0
  353. data/application/static/paper-texture-dark.png +0 -0
  354. data/application/static/plus_alt.svg +0 -8
  355. data/application/static/select-arrow-root.png +0 -0
  356. data/application/static/slot-up-arrow.png +0 -0
  357. data/application/static/spontaneous.png +0 -0
  358. data/lib/cutaneous/context_helper.rb +0 -187
  359. data/lib/cutaneous/preview_context.rb +0 -32
  360. data/lib/cutaneous/preview_renderer.rb +0 -10
  361. data/lib/cutaneous/publish_context.rb +0 -10
  362. data/lib/cutaneous/publish_renderer.rb +0 -14
  363. data/lib/cutaneous/publish_template.rb +0 -62
  364. data/lib/cutaneous/publish_token_parser.rb +0 -8
  365. data/lib/cutaneous/renderer.rb +0 -124
  366. data/lib/cutaneous/request_context.rb +0 -9
  367. data/lib/cutaneous/request_renderer.rb +0 -15
  368. data/lib/cutaneous/request_template.rb +0 -11
  369. data/lib/cutaneous/request_token_parser.rb +0 -9
  370. data/lib/cutaneous/token_parser.rb +0 -125
  371. data/lib/cutaneous.rb +0 -48
  372. data/lib/spontaneous/render/context_base.rb +0 -143
  373. data/lib/spontaneous/render/development_renderer.rb +0 -14
  374. data/lib/spontaneous/render/engine.rb +0 -19
  375. data/lib/spontaneous/render/format/html.rb +0 -5
  376. data/lib/spontaneous/render/format.rb +0 -75
  377. data/lib/spontaneous/render/helpers/script_helper.rb +0 -17
  378. data/lib/spontaneous/render/helpers/stylesheet_helper.rb +0 -16
  379. data/lib/spontaneous/render/helpers.rb +0 -14
  380. data/lib/spontaneous/render/preview_context.rb +0 -8
  381. data/lib/spontaneous/render/preview_renderer.rb +0 -24
  382. data/lib/spontaneous/render/publish_context.rb +0 -22
  383. data/lib/spontaneous/render/published_renderer.rb +0 -53
  384. data/lib/spontaneous/render/publishing_renderer.rb +0 -16
  385. data/lib/spontaneous/render/render_cache.rb +0 -26
  386. data/lib/spontaneous/render/renderer.rb +0 -50
  387. data/lib/spontaneous/render/request_context.rb +0 -8
  388. data/lib/spontaneous/render.rb +0 -214
  389. data/test/experimental/test_cutaneous.rb +0 -309
  390. data/test/fixtures/application/css/test.less +0 -5
  391. data/test/slow/test_publishing.rb +0 -1006
  392. /data/application/css/{developer.scss → developer.css.scss} +0 -0
  393. /data/application/js/vendor/{jquery-1.7.1.min.js → jquery.js} +0 -0
  394. /data/application/static/{location-arrow.png → location-arrow-c1c1d3ca472481c61a0a5f8cb289d743.png} +0 -0
  395. /data/application/static/{missing.png → missing-911ce6dbd9f4602e0f3fbcd7e78846a2.png} +0 -0
  396. /data/application/static/{orange-down-arrow.png → orange-down-arrow-395ae1929e8662b2ff0977daf12c35bb.png} +0 -0
  397. /data/application/static/{page-browser-next.png → page-browser-next-ce781a242c23b980b99b9db7abc20b05.png} +0 -0
  398. /data/application/static/{plus-box.png → plus-box-dcde74a1e496f68298c9b443caa1c5d5.png} +0 -0
  399. /data/application/static/{select-arrow.png → select-arrow-6e7dd3745b00e934b0d7a3250c46558b.png} +0 -0
  400. /data/application/static/{slot-down-arrow.png → slot-down-arrow-59ad5f5ee5b52a7ebd00bca4b3104194.png} +0 -0
  401. /data/application/static/{splash.png → splash-65b493a714df9b8b3ab170103401b53d.png} +0 -0
  402. /data/application/static/{spot.png → spot-71fab1d2f065034f5fc15e7bea2ad36c.png} +0 -0
  403. /data/application/static/{spot.svg → spot-8505041082d8d3bbe8d34c29dddb3b7d.svg} +0 -0
  404. /data/application/static/{texture.png → texture-03f7627e8264b1d607113ab32c593a58.png} +0 -0
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'coffee-script'
4
+
5
+ module Spontaneous::Rack
6
+ class JS
7
+ JS_EXTENSION = /\.js$/o
8
+
9
+ def initialize(app, options = {})
10
+ @roots = options[:root]
11
+ @app = app
12
+ end
13
+
14
+ def call(env)
15
+ try_coffeescript(env[S::PATH_INFO]) or @app.call(env)
16
+ end
17
+
18
+ def try_coffeescript(request_path)
19
+ return nil unless request_path =~ JS_EXTENSION
20
+ try_paths = @roots.map { |root| File.join(root, request_path) }
21
+ # if the css file itself exists then we want to use that
22
+ return nil if try_paths.detect { |file| ::File.exists?(file) }
23
+
24
+ try_paths.each do |path|
25
+ template = template_path(path)
26
+ return render_coffeescript(template) if File.exists?(template)
27
+ end
28
+ nil
29
+ end
30
+
31
+ def render_coffeescript(template)
32
+ script = CoffeeScript.compile(File.read(template))
33
+ [200, {'Content-type' => 'application/javascript;charset=utf-8'}, StringIO.new(script)]
34
+ end
35
+
36
+ def template_path(path)
37
+ path.gsub(JS_EXTENSION, ".coffee")
38
+ end
39
+ end
40
+ end
41
+
@@ -13,6 +13,7 @@ module Spontaneous
13
13
  attr_accessor :page
14
14
 
15
15
  def render_path(path)
16
+ @template_params = {}
16
17
  find_page!(path)
17
18
 
18
19
  response = catch(:halt) do
@@ -52,7 +53,7 @@ module Spontaneous
52
53
  # stolen from Sinatra
53
54
  def parse_response(response)
54
55
  case
55
- when response.respond_to?(:spontaneous_content?)
56
+ when response.is_a?(Spontaneous::Content)
56
57
  @page = response
57
58
  when response.respond_to?(:to_str)
58
59
  @response.body = [response]
@@ -88,6 +89,11 @@ module Spontaneous
88
89
  status(status)
89
90
  end
90
91
 
92
+ def render(page, template_params = {})
93
+ @template_params = template_params
94
+ show(page)
95
+ end
96
+
91
97
  REDIRECTS = {
92
98
  :permanent => 301,
93
99
  :temporary => 302
@@ -122,12 +128,12 @@ module Spontaneous
122
128
  end
123
129
 
124
130
  def find_page!(path)
125
- @path, @format, @action = parse_path(path)
131
+ @path, @output, @action = parse_path(path)
126
132
  @page = Site[@path]
127
133
  end
128
134
 
129
- def format
130
- @format
135
+ def output
136
+ @output
131
137
  end
132
138
 
133
139
  def action
@@ -135,25 +141,17 @@ module Spontaneous
135
141
  end
136
142
 
137
143
  def render_get
138
- # return not_found! unless @page
139
-
140
- @format = (@format || @page.default_format).to_sym if @page
141
-
142
144
  if @action
143
145
  call_action!
144
146
  else
145
147
  block = page.request_block(request)
146
148
  parse_response(instance_eval(&block)) if (block)
147
-
148
- @format = (@format || @page.default_format).to_sym if @page
149
- render_page_with_format(@page, @format)
149
+ render_page_with_output
150
150
  end
151
151
  end
152
152
 
153
153
  # non-action urls shouldn't respond to post requests
154
154
  def render_post
155
- # return not_found! unless @page
156
-
157
155
  block = page.request_block(request)
158
156
  return not_found! unless (block or @action)
159
157
 
@@ -161,21 +159,18 @@ module Spontaneous
161
159
  call_action!
162
160
  else
163
161
  parse_response(instance_eval(&block)) if (block)
164
-
165
- @format = (@format || @page.default_format).to_sym if @page
166
- render_page_with_format(@page, @format)
162
+ render_page_with_output
167
163
  end
168
164
  end
169
165
 
170
166
  def call_action!
171
- # get
172
- status, headers, result = @page.process_action(action, request.env, format)
173
- # our 404 page should come from the CMS
167
+ status, headers, result = @page.process_action(action, request.env, output)
174
168
  if status == 404
175
169
  not_found!
176
170
  else
177
- if result.respond_to?(:spontaneous_content?)
178
- render_page_with_format(result, format)
171
+ if result.is_a?(Spontaneous::Content)
172
+ @page = result
173
+ render_page_with_output
179
174
  else
180
175
  [status, headers, result]
181
176
  end
@@ -185,46 +180,41 @@ module Spontaneous
185
180
  def parse_path(path)
186
181
  if path =~ %r(#{ACTION})
187
182
  path, action = path.split(ACTION)
183
+ path = "/" if path.empty?
188
184
  action, format = action.split(DOT)
189
185
  else
190
186
  path, format = path.split(DOT)
191
187
  end
192
- # format = (format || :html).to_sym
193
188
  [path, format, action]
194
189
  end
195
190
 
196
- def render_page_with_format(page, format)
197
- if page && page.provides_format?(format)
198
- content_type(page.mime_type(format))
199
- render_page(page, format)
191
+ def render_page_with_output
192
+ return not_found! if @page.nil?
193
+ return not_found! unless @page.provides_output?(@output)
194
+
195
+ output = @page.output(@output)
196
+
197
+ if output.public?
198
+ content_type(output.mime_type)
199
+ render_page(@page, output, @template_params)
200
200
  else
201
- # perhaps we should return the html version if the page exists but
202
- # doesn't respond to the requested format?
203
- # or even redirect to the html?
204
201
  not_found!
205
202
  end
206
203
  end
207
204
 
208
- def render_page(page, format = :html, local_params = {})
209
- response.body = page.render(format, local_params.merge({
210
- :params => request.params,
205
+ def renderer
206
+ env[Rack::RENDERER]
207
+ end
208
+
209
+ def render_page(page, output, local_params = {})
210
+ response.body = output.render_using(renderer, local_params.merge({
211
+ :params => params, # use sinatras indifferent params
211
212
  :request => request,
212
213
  :session => request.session
213
214
  }))
214
215
  end
215
216
 
216
- # def redirect?(page)
217
- # redirection, redirect_code = page.request_redirect(request.params, request, request.session)
218
- # if redirection
219
- # redirection = redirection.path if redirection.respond_to?(:path)
220
- # redirect_code = REDIRECTS[redirect_code] if Symbol === redirect_code
221
- # redirect_code ||= REDIRECTS[:temporary]
222
- # [redirection.to_s, redirect_code]
223
- # else
224
- # nil
225
- # end
226
- # end
227
-
217
+ # our 404 page should come from the CMS
228
218
  def not_found!
229
219
  404
230
220
  end
@@ -0,0 +1,18 @@
1
+
2
+ module Spontaneous
3
+ module Rack
4
+ class SSE
5
+ attr_reader :event, :data
6
+
7
+ def initialize(params)
8
+ @event = params[:event]
9
+ @data = params[:data]
10
+ end
11
+
12
+ def to_sse
13
+ lines = ["event: #{event}", "data: #{data}", "\n"]
14
+ lines.join("\n")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,6 +2,8 @@
2
2
  module Spontaneous
3
3
  module Rack
4
4
  class Static
5
+ ALLOWED_METHODS = %w(GET HEAD).freeze
6
+
5
7
  def initialize(app, options)
6
8
  @app = app
7
9
  @try = ['', *options.delete(:try)].compact
@@ -11,6 +13,7 @@ module Spontaneous
11
13
  end
12
14
 
13
15
  def call(env)
16
+ return @app.call(env) unless ALLOWED_METHODS.include?(env[S::REQUEST_METHOD])
14
17
  orig_path = env['PATH_INFO']
15
18
  found = nil
16
19
  @try.each do |path|
@@ -0,0 +1,100 @@
1
+ module Spontaneous::Rack
2
+ class UserAdmin < ServerBase
3
+ helpers UserHelpers
4
+ helpers Helpers
5
+
6
+ User = Spontaneous::Permissions::User unless defined?(User)
7
+
8
+ def with_account
9
+ User.db.transaction do
10
+ account = User.for_update.first(:id => params[:user_id])
11
+ halt 403 unless user.level >= account.level
12
+ yield account
13
+ end
14
+ end
15
+
16
+ def load_level
17
+ attr = params[:user]
18
+ level_name = attr.delete(:level) || attr.delete("level")
19
+ return nil if level_name.blank?
20
+ level = Spontaneous::Permissions[level_name]
21
+ halt 403 unless user.level >= level
22
+ level
23
+ end
24
+
25
+ before {
26
+ halt 403 unless user.admin?
27
+ }
28
+
29
+ get "/" do
30
+ json User.export(user)
31
+ end
32
+
33
+ post "/" do
34
+ level = load_level
35
+ account = User.new params[:user]
36
+ if account.save
37
+ account.update(:level => level)
38
+ json User.export_user(account)
39
+ else
40
+ status 422
41
+ json account.errors#.full_messages
42
+ end
43
+ end
44
+
45
+ put "/:user_id" do
46
+ with_account do |account|
47
+ level = load_level
48
+ account.update_fields(params[:user], [:login, :name, :email])
49
+ if account.save
50
+ account.update(:level => level) if level
51
+ json User.export_user(account)
52
+ else
53
+ status 422
54
+ json account.errors#.full_messages
55
+ end
56
+ end
57
+ end
58
+
59
+ delete "/:user_id" do
60
+ with_account do |account|
61
+ account.destroy
62
+ 200
63
+ end
64
+ end
65
+
66
+ put "/password/:user_id" do
67
+ with_account do |account|
68
+ account.password = params[:password]
69
+ if account.save
70
+ # TODO: changing the password should log the user out?
71
+ 200
72
+ else
73
+ status 422
74
+ json account.errors#.full_messages
75
+ end
76
+ end
77
+ end
78
+
79
+ delete "/keys/:user_id" do
80
+ with_account do |account|
81
+ account.clear_access_keys!
82
+ 200
83
+ end
84
+ end
85
+
86
+ put "/disable/:user_id" do
87
+ with_account do |account|
88
+ account.disable!
89
+ 200
90
+ end
91
+ end
92
+
93
+ put "/enable/:user_id" do
94
+ with_account do |account|
95
+ account.enable!
96
+ 200
97
+ end
98
+ end
99
+ end
100
+ end
@@ -5,7 +5,7 @@ module Spontaneous
5
5
  module UserHelpers
6
6
 
7
7
  def unauthorised!
8
- halt 401#, "You do not have the necessary permissions to update the '#{name}' field"
8
+ halt 403#, "You do not have the necessary permissions to update the '#{name}' field"
9
9
  end
10
10
 
11
11
  def api_key
@@ -1,8 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  require "rack"
4
- # require "sinatra"
5
- require 'sinatra/base'
4
+ require "sinatra/base"
6
5
 
7
6
  module Spontaneous
8
7
  module Rack
@@ -11,6 +10,7 @@ module Spontaneous
11
10
  ACTIVE_KEY = "SPONTANEOUS_KEY".freeze
12
11
  AUTH_COOKIE = "spontaneous_api_key".freeze
13
12
  KEY_PARAM = "__key".freeze
13
+ RENDERER = "spot.renderer".freeze
14
14
 
15
15
  EXPIRES_MAX = DateTime.parse("Thu, 31 Dec 2037 23:55:55 GMT").httpdate
16
16
 
@@ -54,6 +54,7 @@ module Spontaneous
54
54
  autoload :CacheableFile, 'spontaneous/rack/cacheable_file'
55
55
  autoload :Static, 'spontaneous/rack/static'
56
56
  autoload :UserHelpers, 'spontaneous/rack/user_helpers'
57
+ autoload :UserAdmin, 'spontaneous/rack/user_admin'
57
58
  autoload :Helpers, 'spontaneous/rack/helpers'
58
59
  autoload :CookieAuthentication, 'spontaneous/rack/cookie_authentication'
59
60
  autoload :QueryAuthentication, 'spontaneous/rack/query_authentication'
@@ -63,5 +64,8 @@ module Spontaneous
63
64
  autoload :Reloader, 'spontaneous/rack/reloader'
64
65
  autoload :EventSource, 'spontaneous/rack/event_source'
65
66
  autoload :CSS, 'spontaneous/rack/css'
67
+ autoload :JS, 'spontaneous/rack/js'
68
+ autoload :SSE, 'spontaneous/rack/sse'
69
+ autoload :FiberPool, 'spontaneous/rack/fiber_pool'
66
70
  end
67
71
  end
@@ -208,7 +208,7 @@ module Spontaneous
208
208
  # will check that each of the classes in the schema has a
209
209
  # corresponding id
210
210
  self.classes.each do | schema_class |
211
- schema_class.schema_validate
211
+ schema_class.schema_validate(self)
212
212
  end
213
213
 
214
214
  # now check that each of the ids in the map has a
@@ -227,15 +227,15 @@ module Spontaneous
227
227
  end
228
228
 
229
229
 
230
- def export
230
+ def export(user = nil)
231
231
  self.content_classes.inject({}) do |hash, klass|
232
- hash[klass.ui_class] = klass.export
232
+ hash[klass.ui_class] = klass.export(user)
233
233
  hash
234
234
  end
235
235
  end
236
236
 
237
237
  def serialise_http(user = nil)
238
- Spontaneous.serialise_http(export)
238
+ Spontaneous.serialise_http(export(user))
239
239
  end
240
240
 
241
241
  # all classes including boxes
@@ -321,6 +321,33 @@ module Spontaneous
321
321
  def [](schema_id)
322
322
  map[schema_id]
323
323
  end
324
+
325
+ def groups
326
+ @groups ||= Hash.new { |h, k| h[k] = [] }
327
+ end
328
+
329
+ def add_group_member(schema_class, group_names)
330
+ group_names.each do |name|
331
+ group = groups[name.to_sym]
332
+ group << schema_class.to_s unless group.include?(schema_class.to_s)
333
+ end
334
+ end
335
+
336
+ def is_group?(group_name)
337
+ groups.key?(group_name.to_sym)
338
+ end
339
+
340
+ def group_memberships(klass)
341
+ classname = klass.to_s
342
+ groups.select { |group, members| members.include?(classname) }.keys
343
+ end
344
+
345
+ def remove_group_members(klass)
346
+ type = klass.to_s
347
+ groups.each do |group, members|
348
+ members.delete(type)
349
+ end
350
+ end
324
351
  end
325
352
  end
326
353
  end
@@ -67,19 +67,35 @@ module Spontaneous::Search
67
67
  values = Hash.new { |h, k| h[k] = [] }
68
68
  # not sure that I need the include? test here as page.content only returns Pieces
69
69
  # and I'm not sure that there is a particular need to exclude Pieces from indexes
70
- pieces = [page].concat(page.content).select { |content| include?(content) }
71
- pieces += page.boxes.select { |box| include?(box) }
72
- pieces.each do |content|
70
+ indexable = [page]
71
+ indexable.concat(page.pieces.select { |content| include?(content) })
72
+ indexable += page.boxes.select { |box| include?(box) }
73
+ indexable.each do |content|
73
74
  content.fields.each do |field|
74
75
  prototype = field.prototype
75
76
  values[prototype.index_id(self)] << field.indexable_value if prototype.in_index?(self)
76
77
  end
78
+ insert_additional_indexable_values(content, values)
77
79
  end
78
80
  result = Hash[ values.map { |id, values| [id, values.join("\n")] } ]
79
81
  result[:id] = page.id
80
82
  result
81
83
  end
82
84
 
85
+ def insert_additional_indexable_values(content, values)
86
+ if content.respond_to?(:additional_search_values)
87
+ add = content.additional_search_values
88
+ case add
89
+ when Array
90
+ add.each do |row|
91
+ row.each { |k, v| values[k.to_s] << v }
92
+ end
93
+ when Hash
94
+ add.each { |k, v| values[k.to_s] << v }
95
+ end
96
+ end
97
+ end
98
+
83
99
  def fields
84
100
  field_lists = Hash.new { |h, k| h[k] = [] }
85
101
  # collect all the definitions for a particular field or group
@@ -28,7 +28,7 @@ module Spontaneous::Search
28
28
  end
29
29
 
30
30
  def pages
31
- @page_list ||= Spontaneous::Content.filter(:id => @results.map { |doc| doc.id })
31
+ @page_list ||= @results.map { |doc| Spontaneous::Content.first(:id => doc.id) }
32
32
  end
33
33
  end # Results
34
34
  end
@@ -0,0 +1,17 @@
1
+ require "sequel"
2
+
3
+ Sequel.extension :inflector
4
+
5
+ require 'sequel/plugins/serialization'
6
+
7
+ # Sequel::Plugins::Serialization.register_format(
8
+ # :yajl,
9
+ # lambda { |v| Yajl::Encoder.new.encode(v) },
10
+ # lambda { |v| Yajl::Parser.new(:symbolize_keys => true).parse(v) }
11
+ # )
12
+ Sequel::Plugins::Serialization.register_format(
13
+ :ojson,
14
+ lambda { |v| Oj.dump(v) },
15
+ lambda { |v| Oj.load(v) }
16
+ )
17
+
@@ -4,7 +4,7 @@ module Spontaneous
4
4
  class Site < Spontaneous::Facet
5
5
  include Plugins::Site::Instance
6
6
  include Plugins::Site::Publishing
7
- include Plugins::Site::Revisions
7
+ include Plugins::Site::State
8
8
  include Plugins::Site::Selectors
9
9
  include Plugins::Site::Map
10
10
  include Plugins::Site::Search
@@ -12,6 +12,10 @@ module Spontaneous
12
12
  include Plugins::Site::Schema
13
13
  include Plugins::Site::Level
14
14
  include Plugins::Site::Storage
15
+ include Plugins::Site::URL
16
+ include Plugins::Site::Hooks
17
+ include Plugins::Site::Paths
18
+ include Plugins::Site::Helpers
15
19
 
16
20
  attr_accessor :database
17
21
  attr_reader :environment, :mode
@@ -102,14 +106,17 @@ module Spontaneous
102
106
  end
103
107
 
104
108
  def revision_root
105
- @revision_dir ||= File.expand_path(@root / 'cache/revisions')
106
- # Spontaneous.relative_dir(@revision_dir, *path)
109
+ @revision_dir ||= begin
110
+ path = Pathname.new(@root / 'cache/revisions')
111
+ path.mkpath unless path.exist?
112
+ path.realpath.to_s
113
+ end
107
114
  end
108
115
 
109
116
  def revision_dir(revision=nil, root = revision_root)
110
117
  root ||= revision_root
111
118
  return root / 'current' if revision.nil?
112
- root / revision.to_s.rjust(5, "0")
119
+ root / Spontaneous::Paths.pad_revision_number(revision)
113
120
  end
114
121
 
115
122
  def media_dir(*path)
@@ -48,6 +48,17 @@ module Spontaneous
48
48
  instance.pending_revision
49
49
  end
50
50
 
51
+ # Returns the last date at which a Page was added or removed from the site
52
+ # Used to avoid un-necessary loading of the navigation map during editing
53
+ def modified_at
54
+ instance.modified_at || Time.now
55
+ end
56
+
57
+ # Called by Page.after_create and Page.after_destroy in order to update
58
+ # the Site's modification time
59
+ def site_modified!
60
+ instance.update :modified_at => Time.now
61
+ end
51
62
  end
52
63
  end
53
64
  end
@@ -35,6 +35,9 @@ module Spontaneous::Storage
35
35
  #
36
36
  attr_reader :bucket_name
37
37
 
38
+ # Don't verify my ssl certs when uploading images
39
+ ::Excon.defaults[:ssl_verify_peer] = false
40
+
38
41
  def initialize(config, bucket_name, accepts = nil)
39
42
  @config, @bucket_name, @accepts = config, bucket_name, accepts
40
43
  @public_host = @config.delete(:public_host)
@@ -55,6 +58,7 @@ module Spontaneous::Storage
55
58
  :idempotent => false,
56
59
  :body => existing_file,
57
60
  :public => true,
61
+ :expires => (DateTime.now + 20.years).to_s(:rfc822),
58
62
  :content_type => mimetype
59
63
  }
60
64
  params[:body] = File.open(existing_file) if existing_file.is_a?(String)
@@ -10,6 +10,12 @@ module Spontaneous::Storage
10
10
 
11
11
  def copy(existing_file, media_path, mimetype)
12
12
  dest_path = create_absolute_path(media_path)
13
+ copy_file(existing_file, dest_path)
14
+ set_permissions(dest_path)
15
+ dest_path
16
+ end
17
+
18
+ def copy_file(existing_file, dest_path)
13
19
  if existing_file.respond_to?(:read)
14
20
  File.open(dest_path, "wb") do |f|
15
21
  f.binmode
@@ -28,6 +34,7 @@ module Spontaneous::Storage
28
34
  f.binmode
29
35
  block.call(f)
30
36
  end
37
+ set_permissions(dest_path)
31
38
  end
32
39
 
33
40
  def create_absolute_path(relative_path)
@@ -48,5 +55,9 @@ module Spontaneous::Storage
48
55
  def local?
49
56
  true
50
57
  end
58
+
59
+ def set_permissions(filepath)
60
+ File.chmod(0644, filepath)
61
+ end
51
62
  end
52
63
  end
@@ -40,9 +40,9 @@ module Spontaneous
40
40
 
41
41
  def local_template(format)
42
42
  template_path = nil
43
- Spontaneous.template_paths.each do |template_root|
43
+ Site.paths(:templates).each do |template_root|
44
44
  template_path = try_template_paths.detect do |path|
45
- Spontaneous::Render.exists?(template_root, path, format)
45
+ Spontaneous::Output.template_exists?(template_root, path, format)
46
46
  end
47
47
  return (template_root / template_path) if template_path
48
48
  end