spontaneous 0.1.0.alpha1

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 (556) hide show
  1. data/Gemfile +49 -0
  2. data/Gemfile.lock +146 -0
  3. data/LICENSE +0 -0
  4. data/README +0 -0
  5. data/Rakefile +284 -0
  6. data/Readme.markdown +7 -0
  7. data/application/css/add_alias_dialogue.scss +27 -0
  8. data/application/css/definitions.scss +249 -0
  9. data/application/css/developer.scss +9 -0
  10. data/application/css/editing.scss +649 -0
  11. data/application/css/login.scss +91 -0
  12. data/application/css/min/54ee0ed3c7fac7632bd5c020d69e9a2503e0c88c.css +1 -0
  13. data/application/css/min/c256adc144e2bdd0b0539356b04eb62db01e1dc3.css +1 -0
  14. data/application/css/popover.scss +335 -0
  15. data/application/css/schema_error.scss +90 -0
  16. data/application/css/spontaneous.scss +111 -0
  17. data/application/css/unsupported.scss +16 -0
  18. data/application/css/v2.scss +1606 -0
  19. data/application/css/variables.scss +80 -0
  20. data/application/js/add_alias_dialogue.js +59 -0
  21. data/application/js/add_home_dialogue.js +59 -0
  22. data/application/js/ajax.js +99 -0
  23. data/application/js/authentication.js +22 -0
  24. data/application/js/box.js +104 -0
  25. data/application/js/box_container.js +82 -0
  26. data/application/js/compatibility.js +132 -0
  27. data/application/js/conflicted_field_dialogue.js +92 -0
  28. data/application/js/content.js +224 -0
  29. data/application/js/content_area.js +44 -0
  30. data/application/js/dialogue.js +196 -0
  31. data/application/js/dom.js +71 -0
  32. data/application/js/edit_dialogue.js +137 -0
  33. data/application/js/edit_panel.js +232 -0
  34. data/application/js/editing.js +42 -0
  35. data/application/js/entry.js +13 -0
  36. data/application/js/extensions.js +104 -0
  37. data/application/js/field.js +4 -0
  38. data/application/js/field_preview.js +55 -0
  39. data/application/js/field_types/date_field.js +16 -0
  40. data/application/js/field_types/file_field.js +71 -0
  41. data/application/js/field_types/image_field.js +358 -0
  42. data/application/js/field_types/markdown_field.js +656 -0
  43. data/application/js/field_types/string_field.js +185 -0
  44. data/application/js/image.js +72 -0
  45. data/application/js/init.js +34 -0
  46. data/application/js/load.js +4 -0
  47. data/application/js/location.js +157 -0
  48. data/application/js/login.js +53 -0
  49. data/application/js/min/492a209de8ee955fa9c729a765377495001e11b1.js +17 -0
  50. data/application/js/min/80f684d77c940887a1d4a63e3a96102e993baa98.js +88 -0
  51. data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +2 -0
  52. data/application/js/min/c7140ec9475e5bf868b901e0621338d7d162358b.js +3 -0
  53. data/application/js/min/f07f2bd6630ee31e1c2288ec223383d8f0658ba6.js +2 -0
  54. data/application/js/page.js +43 -0
  55. data/application/js/page_browser.js +147 -0
  56. data/application/js/page_entry.js +47 -0
  57. data/application/js/popover.js +99 -0
  58. data/application/js/popover_view.js +56 -0
  59. data/application/js/preview.js +64 -0
  60. data/application/js/progress.js +358 -0
  61. data/application/js/properties.js +90 -0
  62. data/application/js/publish.js +187 -0
  63. data/application/js/require.js +129 -0
  64. data/application/js/sharded_upload.js +206 -0
  65. data/application/js/side_bar.js +30 -0
  66. data/application/js/spontaneous.js +6 -0
  67. data/application/js/state.js +64 -0
  68. data/application/js/status_bar.js +47 -0
  69. data/application/js/top_bar.js +368 -0
  70. data/application/js/types.js +98 -0
  71. data/application/js/upload.js +88 -0
  72. data/application/js/upload_manager.js +319 -0
  73. data/application/js/user.js +37 -0
  74. data/application/js/vendor/.DS_Store +0 -0
  75. data/application/js/vendor/JS.Class-2.1.5/CHANGELOG +283 -0
  76. data/application/js/vendor/JS.Class-2.1.5/MIT-LICENSE +30 -0
  77. data/application/js/vendor/JS.Class-2.1.5/README +30 -0
  78. data/application/js/vendor/JS.Class-2.1.5/min/command.js +1 -0
  79. data/application/js/vendor/JS.Class-2.1.5/min/comparable.js +1 -0
  80. data/application/js/vendor/JS.Class-2.1.5/min/constant_scope.js +1 -0
  81. data/application/js/vendor/JS.Class-2.1.5/min/core.js +1 -0
  82. data/application/js/vendor/JS.Class-2.1.5/min/decorator.js +1 -0
  83. data/application/js/vendor/JS.Class-2.1.5/min/enumerable.js +1 -0
  84. data/application/js/vendor/JS.Class-2.1.5/min/forwardable.js +1 -0
  85. data/application/js/vendor/JS.Class-2.1.5/min/hash.js +1 -0
  86. data/application/js/vendor/JS.Class-2.1.5/min/linked_list.js +1 -0
  87. data/application/js/vendor/JS.Class-2.1.5/min/loader.js +1 -0
  88. data/application/js/vendor/JS.Class-2.1.5/min/method_chain.js +1 -0
  89. data/application/js/vendor/JS.Class-2.1.5/min/observable.js +1 -0
  90. data/application/js/vendor/JS.Class-2.1.5/min/package.js +1 -0
  91. data/application/js/vendor/JS.Class-2.1.5/min/proxy.js +1 -0
  92. data/application/js/vendor/JS.Class-2.1.5/min/ruby.js +1 -0
  93. data/application/js/vendor/JS.Class-2.1.5/min/set.js +1 -0
  94. data/application/js/vendor/JS.Class-2.1.5/min/stack_trace.js +1 -0
  95. data/application/js/vendor/JS.Class-2.1.5/min/state.js +1 -0
  96. data/application/js/vendor/JS.Class-2.1.5/min/stdlib.js +16 -0
  97. data/application/js/vendor/JS.Class-2.1.5/src/command.js +93 -0
  98. data/application/js/vendor/JS.Class-2.1.5/src/comparable.js +37 -0
  99. data/application/js/vendor/JS.Class-2.1.5/src/constant_scope.js +48 -0
  100. data/application/js/vendor/JS.Class-2.1.5/src/core.js +1060 -0
  101. data/application/js/vendor/JS.Class-2.1.5/src/decorator.js +50 -0
  102. data/application/js/vendor/JS.Class-2.1.5/src/enumerable.js +505 -0
  103. data/application/js/vendor/JS.Class-2.1.5/src/forwardable.js +22 -0
  104. data/application/js/vendor/JS.Class-2.1.5/src/hash.js +334 -0
  105. data/application/js/vendor/JS.Class-2.1.5/src/linked_list.js +114 -0
  106. data/application/js/vendor/JS.Class-2.1.5/src/loader.js +553 -0
  107. data/application/js/vendor/JS.Class-2.1.5/src/method_chain.js +172 -0
  108. data/application/js/vendor/JS.Class-2.1.5/src/observable.js +55 -0
  109. data/application/js/vendor/JS.Class-2.1.5/src/package.js +472 -0
  110. data/application/js/vendor/JS.Class-2.1.5/src/proxy.js +58 -0
  111. data/application/js/vendor/JS.Class-2.1.5/src/ruby.js +44 -0
  112. data/application/js/vendor/JS.Class-2.1.5/src/set.js +332 -0
  113. data/application/js/vendor/JS.Class-2.1.5/src/stack_trace.js +151 -0
  114. data/application/js/vendor/JS.Class-2.1.5/src/state.js +95 -0
  115. data/application/js/vendor/JS.Class-2.1.5/src/stdlib.js +2612 -0
  116. data/application/js/vendor/crypto-2.3.0-crypto.js +160 -0
  117. data/application/js/vendor/crypto-2.3.0-sha1.js +91 -0
  118. data/application/js/vendor/diff_match_patch.js +2153 -0
  119. data/application/js/vendor/jquery-1.4.2.min.js +154 -0
  120. data/application/js/vendor/jquery-1.4.3.min.js +166 -0
  121. data/application/js/vendor/jquery-1.5.1.min.js +16 -0
  122. data/application/js/vendor/jquery-1.5.1rc1.min.js +24 -0
  123. data/application/js/vendor/jquery-1.6.2.min.js +18 -0
  124. data/application/js/vendor/jquery-ui-1.8.6.custom.min.js +265 -0
  125. data/application/js/vendor/jquery-ui-1.8.9.custom.min.js +415 -0
  126. data/application/js/vendor/jquery-ui-1.8.custom.min.js +106 -0
  127. data/application/js/vendor/jquery.hotkeys-0.7.9.js +248 -0
  128. data/application/js/vendor/jquery.hotkeys-0.7.9.min.js +19 -0
  129. data/application/js/vendor/jsdiff.js +169 -0
  130. data/application/js/views/box_view.js +229 -0
  131. data/application/js/views/page_piece_view.js +45 -0
  132. data/application/js/views/page_view.js +238 -0
  133. data/application/js/views/piece_view.js +178 -0
  134. data/application/js/views.js +110 -0
  135. data/application/static/editing-0-noise.png +0 -0
  136. data/application/static/editing-1-noise.png +0 -0
  137. data/application/static/editing-texture-1.png +0 -0
  138. data/application/static/editing-texture.png +0 -0
  139. data/application/static/editing-toolbar-shadow-bottom.png +0 -0
  140. data/application/static/editing-toolbar-shadow-top.png +0 -0
  141. data/application/static/favicon.ico +0 -0
  142. data/application/static/inner-glow.png +0 -0
  143. data/application/static/item-buttons.png +0 -0
  144. data/application/static/location-arrow.png +0 -0
  145. data/application/static/logo-400px-transparent.png +0 -0
  146. data/application/static/missing.png +0 -0
  147. data/application/static/orange-down-arrow.png +0 -0
  148. data/application/static/page-browser-next.png +0 -0
  149. data/application/static/paper-texture-dark.png +0 -0
  150. data/application/static/px.gif +0 -0
  151. data/application/static/select-arrow-root.png +0 -0
  152. data/application/static/select-arrow.png +0 -0
  153. data/application/static/slot-down-arrow.png +0 -0
  154. data/application/static/splash.png +0 -0
  155. data/application/static/spontaneous.png +0 -0
  156. data/application/static/spot.png +0 -0
  157. data/application/static/spot.svg +40 -0
  158. data/application/static/texture.png +0 -0
  159. data/application/views/index.erubis +46 -0
  160. data/application/views/login.erubis +69 -0
  161. data/application/views/schema_modification_error.html.erb +61 -0
  162. data/application/views/unsupported.erubis +23 -0
  163. data/bin/limit-upload +5 -0
  164. data/bin/spot +10 -0
  165. data/bin/unlimit-upload +3 -0
  166. data/config/nginx.conf +60 -0
  167. data/db/migrations/20100610142136_init.rb +66 -0
  168. data/db/migrations/20101130104334_timestamps.rb +44 -0
  169. data/db/migrations/20101202113205_site_publishing_flags.rb +12 -0
  170. data/db/migrations/20101206124543_aliases.rb +16 -0
  171. data/db/migrations/20110201133550_visibility.rb +27 -0
  172. data/db/migrations/20110209152710_users_and_groups.rb +58 -0
  173. data/db/migrations/20110215133910_boxes.rb +25 -0
  174. data/db/migrations/20110521114145_remove_slots_and_entries.rb +21 -0
  175. data/db/migrations/20110604192145_rename_schema_id_columns.rb +22 -0
  176. data/db/migrations/20110805141925_rename_site_to_state.rb +11 -0
  177. data/lib/cutaneous/context_helper.rb +82 -0
  178. data/lib/cutaneous/first_pass_parser.rb +23 -0
  179. data/lib/cutaneous/first_pass_renderer.rb +18 -0
  180. data/lib/cutaneous/parser_core.rb +18 -0
  181. data/lib/cutaneous/preview_context.rb +31 -0
  182. data/lib/cutaneous/preview_renderer.rb +15 -0
  183. data/lib/cutaneous/publish_context.rb +9 -0
  184. data/lib/cutaneous/renderer.rb +122 -0
  185. data/lib/cutaneous/request_context.rb +8 -0
  186. data/lib/cutaneous/second_pass_parser.rb +23 -0
  187. data/lib/cutaneous/second_pass_renderer.rb +18 -0
  188. data/lib/cutaneous.rb +47 -0
  189. data/lib/sequel/plugins/content_table_inheritance.rb +196 -0
  190. data/lib/sequel/plugins/yajl_serialization.rb +154 -0
  191. data/lib/spontaneous/application/feature.rb +9 -0
  192. data/lib/spontaneous/application/plugin.rb +13 -0
  193. data/lib/spontaneous/application.rb +8 -0
  194. data/lib/spontaneous/box.rb +232 -0
  195. data/lib/spontaneous/box_style.rb +64 -0
  196. data/lib/spontaneous/change.rb +107 -0
  197. data/lib/spontaneous/cli/adapter.rb +13 -0
  198. data/lib/spontaneous/cli/base.rb +184 -0
  199. data/lib/spontaneous/cli/console.rb +0 -0
  200. data/lib/spontaneous/cli/media.rb +13 -0
  201. data/lib/spontaneous/cli/server.rb +50 -0
  202. data/lib/spontaneous/cli/site.rb +46 -0
  203. data/lib/spontaneous/cli/sync.rb +42 -0
  204. data/lib/spontaneous/cli/tasks.rb +9 -0
  205. data/lib/spontaneous/cli.rb +83 -0
  206. data/lib/spontaneous/collections/box_set.rb +56 -0
  207. data/lib/spontaneous/collections/change_set.rb +43 -0
  208. data/lib/spontaneous/collections/entry_set.rb +83 -0
  209. data/lib/spontaneous/collections/field_set.rb +53 -0
  210. data/lib/spontaneous/collections/prototype_set.rb +131 -0
  211. data/lib/spontaneous/collections/style_set.rb +13 -0
  212. data/lib/spontaneous/config.rb +156 -0
  213. data/lib/spontaneous/constants.rb +24 -0
  214. data/lib/spontaneous/content.rb +113 -0
  215. data/lib/spontaneous/content_query.rb +17 -0
  216. data/lib/spontaneous/errors.rb +48 -0
  217. data/lib/spontaneous/extensions/array.rb +18 -0
  218. data/lib/spontaneous/extensions/class.rb +17 -0
  219. data/lib/spontaneous/extensions/hash.rb +18 -0
  220. data/lib/spontaneous/extensions/json.rb +26 -0
  221. data/lib/spontaneous/extensions/kernel.rb +7 -0
  222. data/lib/spontaneous/extensions/object.rb +30 -0
  223. data/lib/spontaneous/extensions/object_space.rb +12 -0
  224. data/lib/spontaneous/extensions/string.rb +44 -0
  225. data/lib/spontaneous/facet.rb +47 -0
  226. data/lib/spontaneous/field_types/date_field.rb +12 -0
  227. data/lib/spontaneous/field_types/field.rb +252 -0
  228. data/lib/spontaneous/field_types/image_field.rb +329 -0
  229. data/lib/spontaneous/field_types/markdown_field.rb +37 -0
  230. data/lib/spontaneous/field_types/string_field.rb +14 -0
  231. data/lib/spontaneous/field_types.rb +40 -0
  232. data/lib/spontaneous/generators/page/inline.html.cut +1 -0
  233. data/lib/spontaneous/generators/page/page.html.cut.tt +4 -0
  234. data/lib/spontaneous/generators/page/page.rb.tt +9 -0
  235. data/lib/spontaneous/generators/page.rb +38 -0
  236. data/lib/spontaneous/generators/site/.gitignore +4 -0
  237. data/lib/spontaneous/generators/site/Gemfile.tt +31 -0
  238. data/lib/spontaneous/generators/site/Rakefile.tt +6 -0
  239. data/lib/spontaneous/generators/site/config/back.ru +7 -0
  240. data/lib/spontaneous/generators/site/config/boot.rb +19 -0
  241. data/lib/spontaneous/generators/site/config/database.yml.tt +21 -0
  242. data/lib/spontaneous/generators/site/config/deploy.rb.tt +0 -0
  243. data/lib/spontaneous/generators/site/config/environment.rb.tt +8 -0
  244. data/lib/spontaneous/generators/site/config/environments/development.rb.tt +15 -0
  245. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +5 -0
  246. data/lib/spontaneous/generators/site/config/front.ru +8 -0
  247. data/lib/spontaneous/generators/site/config/user_levels.yml +22 -0
  248. data/lib/spontaneous/generators/site/lib/site.rb.tt +4 -0
  249. data/lib/spontaneous/generators/site/lib/tasks/site.rake.tt +8 -0
  250. data/lib/spontaneous/generators/site/public/css/site.css +0 -0
  251. data/lib/spontaneous/generators/site/public/favicon.ico +0 -0
  252. data/lib/spontaneous/generators/site/public/js/.empty_directory +0 -0
  253. data/lib/spontaneous/generators/site/public/js/site.js +0 -0
  254. data/lib/spontaneous/generators/site/public/robots.txt +0 -0
  255. data/lib/spontaneous/generators/site/schema/.map +1 -0
  256. data/lib/spontaneous/generators/site/schema/page.rb.tt +8 -0
  257. data/lib/spontaneous/generators/site/schema/piece.rb.tt +4 -0
  258. data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +13 -0
  259. data/lib/spontaneous/generators/site.rb +77 -0
  260. data/lib/spontaneous/generators.rb +23 -0
  261. data/lib/spontaneous/image_size.rb +117 -0
  262. data/lib/spontaneous/json.rb +33 -0
  263. data/lib/spontaneous/layout.rb +15 -0
  264. data/lib/spontaneous/loader.rb +280 -0
  265. data/lib/spontaneous/logger.rb +369 -0
  266. data/lib/spontaneous/media.rb +84 -0
  267. data/lib/spontaneous/page.rb +92 -0
  268. data/lib/spontaneous/page_controller.rb +18 -0
  269. data/lib/spontaneous/page_piece.rb +77 -0
  270. data/lib/spontaneous/paths.rb +30 -0
  271. data/lib/spontaneous/permissions/access_group.rb +50 -0
  272. data/lib/spontaneous/permissions/access_key.rb +35 -0
  273. data/lib/spontaneous/permissions/user.rb +167 -0
  274. data/lib/spontaneous/permissions/user_level.rb +177 -0
  275. data/lib/spontaneous/permissions.rb +55 -0
  276. data/lib/spontaneous/piece.rb +30 -0
  277. data/lib/spontaneous/plugins/aliases.rb +128 -0
  278. data/lib/spontaneous/plugins/allowed_types.rb +173 -0
  279. data/lib/spontaneous/plugins/application/facets.rb +25 -0
  280. data/lib/spontaneous/plugins/application/paths.rb +137 -0
  281. data/lib/spontaneous/plugins/application/render.rb +29 -0
  282. data/lib/spontaneous/plugins/application/serialisation.rb +16 -0
  283. data/lib/spontaneous/plugins/application/state.rb +86 -0
  284. data/lib/spontaneous/plugins/boxes.rb +84 -0
  285. data/lib/spontaneous/plugins/controllers.rb +52 -0
  286. data/lib/spontaneous/plugins/entries.rb +193 -0
  287. data/lib/spontaneous/plugins/entry.rb +51 -0
  288. data/lib/spontaneous/plugins/fields.rb +103 -0
  289. data/lib/spontaneous/plugins/instance_code.rb +18 -0
  290. data/lib/spontaneous/plugins/layouts.rb +87 -0
  291. data/lib/spontaneous/plugins/media.rb +41 -0
  292. data/lib/spontaneous/plugins/page/formats.rb +67 -0
  293. data/lib/spontaneous/plugins/page/request.rb +89 -0
  294. data/lib/spontaneous/plugins/page_search.rb +64 -0
  295. data/lib/spontaneous/plugins/page_tree.rb +25 -0
  296. data/lib/spontaneous/plugins/paths.rb +125 -0
  297. data/lib/spontaneous/plugins/permissions.rb +63 -0
  298. data/lib/spontaneous/plugins/prototypes.rb +84 -0
  299. data/lib/spontaneous/plugins/publishing.rb +255 -0
  300. data/lib/spontaneous/plugins/render.rb +24 -0
  301. data/lib/spontaneous/plugins/schema_hierarchy.rb +76 -0
  302. data/lib/spontaneous/plugins/schema_id.rb +60 -0
  303. data/lib/spontaneous/plugins/schema_title.rb +33 -0
  304. data/lib/spontaneous/plugins/serialisation.rb +67 -0
  305. data/lib/spontaneous/plugins/site/instance.rb +22 -0
  306. data/lib/spontaneous/plugins/site/map.rb +19 -0
  307. data/lib/spontaneous/plugins/site/publishing.rb +74 -0
  308. data/lib/spontaneous/plugins/site/revisions.rb +28 -0
  309. data/lib/spontaneous/plugins/site/selectors.rb +41 -0
  310. data/lib/spontaneous/plugins/site_map.rb +34 -0
  311. data/lib/spontaneous/plugins/styles.rb +119 -0
  312. data/lib/spontaneous/plugins/supertype.rb +11 -0
  313. data/lib/spontaneous/plugins/visibility.rb +151 -0
  314. data/lib/spontaneous/plugins.rb +20 -0
  315. data/lib/spontaneous/prototypes/box_prototype.rb +168 -0
  316. data/lib/spontaneous/prototypes/field_prototype.rb +112 -0
  317. data/lib/spontaneous/prototypes/layout_prototype.rb +17 -0
  318. data/lib/spontaneous/prototypes/style_prototype.rb +42 -0
  319. data/lib/spontaneous/proxy_object.rb +12 -0
  320. data/lib/spontaneous/publishing/fire_and_forget.rb +57 -0
  321. data/lib/spontaneous/publishing/immediate.rb +197 -0
  322. data/lib/spontaneous/publishing/threaded.rb +25 -0
  323. data/lib/spontaneous/publishing.rb +10 -0
  324. data/lib/spontaneous/rack/around_back.rb +44 -0
  325. data/lib/spontaneous/rack/around_front.rb +29 -0
  326. data/lib/spontaneous/rack/around_preview.rb +26 -0
  327. data/lib/spontaneous/rack/assets.rb +98 -0
  328. data/lib/spontaneous/rack/back.rb +729 -0
  329. data/lib/spontaneous/rack/front.rb +41 -0
  330. data/lib/spontaneous/rack/http.rb +18 -0
  331. data/lib/spontaneous/rack/media.rb +29 -0
  332. data/lib/spontaneous/rack/public.rb +232 -0
  333. data/lib/spontaneous/rack/reloader.rb +42 -0
  334. data/lib/spontaneous/rack/static.rb +25 -0
  335. data/lib/spontaneous/rack.rb +55 -0
  336. data/lib/spontaneous/render/context.rb +100 -0
  337. data/lib/spontaneous/render/development_renderer.rb +14 -0
  338. data/lib/spontaneous/render/engine.rb +19 -0
  339. data/lib/spontaneous/render/format/html.rb +5 -0
  340. data/lib/spontaneous/render/format.rb +70 -0
  341. data/lib/spontaneous/render/preview_renderer.rb +18 -0
  342. data/lib/spontaneous/render/published_renderer.rb +54 -0
  343. data/lib/spontaneous/render/publishing_renderer.rb +13 -0
  344. data/lib/spontaneous/render/renderer.rb +46 -0
  345. data/lib/spontaneous/render.rb +173 -0
  346. data/lib/spontaneous/revision.rb +7 -0
  347. data/lib/spontaneous/schema/schema_modification.rb +260 -0
  348. data/lib/spontaneous/schema/uid.rb +221 -0
  349. data/lib/spontaneous/schema.rb +295 -0
  350. data/lib/spontaneous/server.rb +65 -0
  351. data/lib/spontaneous/site.rb +87 -0
  352. data/lib/spontaneous/state.rb +53 -0
  353. data/lib/spontaneous/style.rb +144 -0
  354. data/lib/spontaneous/tasks/database.rake +9 -0
  355. data/lib/spontaneous/tasks.rb +5 -0
  356. data/lib/spontaneous/version.rb +6 -0
  357. data/lib/spontaneous.rb +179 -0
  358. data/spontaneous.gemspec.tmpl +66 -0
  359. data/test/disabled/test_slots.rb +287 -0
  360. data/test/experimental/test_formats.rb +92 -0
  361. data/test/experimental/test_plugins.rb +64 -0
  362. data/test/fixtures/application/css/test.less +5 -0
  363. data/test/fixtures/application/js/test.js +1 -0
  364. data/test/fixtures/application/static/favicon.ico +1 -0
  365. data/test/fixtures/application/static/test.html +1 -0
  366. data/test/fixtures/application/views/index.erubis +1 -0
  367. data/test/fixtures/back/public/test.html +1 -0
  368. data/test/fixtures/back/templates/layouts/standard.html.cut +1 -0
  369. data/test/fixtures/config/config/environment.rb +4 -0
  370. data/test/fixtures/config/config/environments/development.rb +13 -0
  371. data/test/fixtures/config/config/environments/production.rb +22 -0
  372. data/test/fixtures/config/config/environments/staging.rb +2 -0
  373. data/test/fixtures/example_application/Gemfile +6 -0
  374. data/test/fixtures/example_application/Gemfile.lock +76 -0
  375. data/test/fixtures/example_application/Rakefile +6 -0
  376. data/test/fixtures/example_application/config/back.rb +15 -0
  377. data/test/fixtures/example_application/config/back.ru +8 -0
  378. data/test/fixtures/example_application/config/back.yml +8 -0
  379. data/test/fixtures/example_application/config/boot.rb +16 -0
  380. data/test/fixtures/example_application/config/database.yml +24 -0
  381. data/test/fixtures/example_application/config/environment.rb +4 -0
  382. data/test/fixtures/example_application/config/environments/development.rb +16 -0
  383. data/test/fixtures/example_application/config/environments/production.rb +21 -0
  384. data/test/fixtures/example_application/config/environments/staging.rb +1 -0
  385. data/test/fixtures/example_application/config/front.rb +8 -0
  386. data/test/fixtures/example_application/config/front.ru +8 -0
  387. data/test/fixtures/example_application/config/front.yml +8 -0
  388. data/test/fixtures/example_application/config/schema.yml +48 -0
  389. data/test/fixtures/example_application/config/unicorn.rb +1 -0
  390. data/test/fixtures/example_application/config/user_levels.yml +19 -0
  391. data/test/fixtures/example_application/public/css/test.css +0 -0
  392. data/test/fixtures/example_application/public/favicon.ico +1 -0
  393. data/test/fixtures/example_application/public/js/test.js +0 -0
  394. data/test/fixtures/example_application/public/test.html +1 -0
  395. data/test/fixtures/example_application/schema/client_project.rb +18 -0
  396. data/test/fixtures/example_application/schema/client_projects.rb +8 -0
  397. data/test/fixtures/example_application/schema/home_page.rb +22 -0
  398. data/test/fixtures/example_application/schema/info_page.rb +13 -0
  399. data/test/fixtures/example_application/schema/inline_image.rb +11 -0
  400. data/test/fixtures/example_application/schema/page.rb +4 -0
  401. data/test/fixtures/example_application/schema/piece.rb +3 -0
  402. data/test/fixtures/example_application/schema/project.rb +21 -0
  403. data/test/fixtures/example_application/schema/project_image.rb +18 -0
  404. data/test/fixtures/example_application/schema/projects_page.rb +12 -0
  405. data/test/fixtures/example_application/schema/text.rb +8 -0
  406. data/test/fixtures/example_application/templates/client_project/images.html.cut +1 -0
  407. data/test/fixtures/example_application/templates/client_project.html.cut +4 -0
  408. data/test/fixtures/example_application/templates/client_projects.html.cut +6 -0
  409. data/test/fixtures/example_application/templates/info_page/inline.html.cut +0 -0
  410. data/test/fixtures/example_application/templates/inline_image.html.cut +1 -0
  411. data/test/fixtures/example_application/templates/layouts/home.html.cut +15 -0
  412. data/test/fixtures/example_application/templates/layouts/info.html.cut +3 -0
  413. data/test/fixtures/example_application/templates/layouts/project.html.cut +13 -0
  414. data/test/fixtures/example_application/templates/layouts/projects.html.cut +11 -0
  415. data/test/fixtures/example_application/templates/layouts/standard.html.cut +0 -0
  416. data/test/fixtures/example_application/templates/project/inline.html.cut +5 -0
  417. data/test/fixtures/example_application/templates/project.html.cut +5 -0
  418. data/test/fixtures/example_application/templates/project_image.html.cut +1 -0
  419. data/test/fixtures/example_application/templates/text.html.cut +1 -0
  420. data/test/fixtures/images/rose.greyscale.jpg +0 -0
  421. data/test/fixtures/images/rose.jpg +0 -0
  422. data/test/fixtures/images/size.gif +0 -0
  423. data/test/fixtures/images/size.jpg +0 -0
  424. data/test/fixtures/images/size.png24 +0 -0
  425. data/test/fixtures/images/size.png8 +0 -0
  426. data/test/fixtures/layouts/layouts/custom1.html.cut +1 -0
  427. data/test/fixtures/layouts/layouts/custom1.pdf.cut +0 -0
  428. data/test/fixtures/layouts/layouts/custom1.xml.cut +0 -0
  429. data/test/fixtures/layouts/layouts/custom2.html.cut +1 -0
  430. data/test/fixtures/layouts/layouts/custom3.html.cut +0 -0
  431. data/test/fixtures/layouts/layouts/standard.html.cut +1 -0
  432. data/test/fixtures/media/101/003/rose.jpg +0 -0
  433. data/test/fixtures/permissions/config/user_levels.yml +9 -0
  434. data/test/fixtures/permissions/media/image.jpg +0 -0
  435. data/test/fixtures/plugins/schema_plugin/init.rb +1 -0
  436. data/test/fixtures/plugins/schema_plugin/schema/external.rb +5 -0
  437. data/test/fixtures/plugins/schema_plugin/templates/external.html.cut +1 -0
  438. data/test/fixtures/plugins/schema_plugin/templates/from_plugin.html.cut +0 -0
  439. data/test/fixtures/plugins/schema_plugin/templates/layouts/from_plugin.html.cut +0 -0
  440. data/test/fixtures/public/templates/layouts/default.html.cut +1 -0
  441. data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -0
  442. data/test/fixtures/public/templates/layouts/default.rss.cut +1 -0
  443. data/test/fixtures/public/templates/layouts/dynamic.html.cut +1 -0
  444. data/test/fixtures/public/templates/layouts/standard.html.cut +0 -0
  445. data/test/fixtures/schema/before.yml +24 -0
  446. data/test/fixtures/schema/resolvable.yml +12 -0
  447. data/test/fixtures/schema/schema.yml +7 -0
  448. data/test/fixtures/serialisation/class_hash.yaml.erb +53 -0
  449. data/test/fixtures/serialisation/root_hash.yaml.erb +184 -0
  450. data/test/fixtures/sharding/rose.jpg +0 -0
  451. data/test/fixtures/sharding/xaa +0 -0
  452. data/test/fixtures/sharding/xab +0 -0
  453. data/test/fixtures/sharding/xac +0 -0
  454. data/test/fixtures/sharding/xad +0 -0
  455. data/test/fixtures/sharding/xae +0 -0
  456. data/test/fixtures/sharding/xaf +0 -0
  457. data/test/fixtures/sharding/xag +0 -0
  458. data/test/fixtures/styles/box_a/runny.html.cut +0 -0
  459. data/test/fixtures/styles/box_a.html.cut +1 -0
  460. data/test/fixtures/styles/named2.html.cut +1 -0
  461. data/test/fixtures/styles/orange/apple.html.cut +1 -0
  462. data/test/fixtures/styles/template_class/named1.html.cut +1 -0
  463. data/test/fixtures/styles/template_class/results.html.cut +1 -0
  464. data/test/fixtures/styles/template_class/walky.html.cut +0 -0
  465. data/test/fixtures/styles/template_class.epub.cut +0 -0
  466. data/test/fixtures/styles/template_class.html.cut +1 -0
  467. data/test/fixtures/styles/template_class.pdf.cut +0 -0
  468. data/test/fixtures/styles/template_sub_class1.html.cut +1 -0
  469. data/test/fixtures/templates/aliases/a/a_style.html.cut +0 -0
  470. data/test/fixtures/templates/aliases/a/page.html.cut +0 -0
  471. data/test/fixtures/templates/aliases/a_alias/a_alias_style.html.cut +0 -0
  472. data/test/fixtures/templates/aliases/layouts/b.html.cut +1 -0
  473. data/test/fixtures/templates/aliases/layouts/b_alias.html.cut +1 -0
  474. data/test/fixtures/templates/aliases/layouts/c_alias.html.cut +1 -0
  475. data/test/fixtures/templates/boxes/blank_content/things.html.cut +1 -0
  476. data/test/fixtures/templates/boxes/my_box_class/christy.html.cut +1 -0
  477. data/test/fixtures/templates/boxes/thangs.html.cut +1 -0
  478. data/test/fixtures/templates/boxes/with_template_box.html.cut +1 -0
  479. data/test/fixtures/templates/content/include.html.cut +1 -0
  480. data/test/fixtures/templates/content/include_dir.html.cut +1 -0
  481. data/test/fixtures/templates/content/included.epub.cut +1 -0
  482. data/test/fixtures/templates/content/included.html.cut +1 -0
  483. data/test/fixtures/templates/content/partial/included.html.cut +1 -0
  484. data/test/fixtures/templates/content/preprocess.html.cut +1 -0
  485. data/test/fixtures/templates/content/second.html.cut +1 -0
  486. data/test/fixtures/templates/content/template.epub.cut +1 -0
  487. data/test/fixtures/templates/content/template.html.cut +1 -0
  488. data/test/fixtures/templates/default_style_class.html.cut +1 -0
  489. data/test/fixtures/templates/direct.html.cut +1 -0
  490. data/test/fixtures/templates/extended/grandparent.html.cut +10 -0
  491. data/test/fixtures/templates/extended/main.html.cut +6 -0
  492. data/test/fixtures/templates/extended/parent.html.cut +10 -0
  493. data/test/fixtures/templates/layouts/entries.html.cut +7 -0
  494. data/test/fixtures/templates/layouts/page_style.html.cut +1 -0
  495. data/test/fixtures/templates/layouts/params.html.cut +1 -0
  496. data/test/fixtures/templates/layouts/preview_render.html.cut +2 -0
  497. data/test/fixtures/templates/layouts/standard_page.html.cut +1 -0
  498. data/test/fixtures/templates/layouts/subdir_style.html.cut +1 -0
  499. data/test/fixtures/templates/layouts/template_params.html.cut +1 -0
  500. data/test/fixtures/templates/page_class/inline_style.html.cut +1 -0
  501. data/test/fixtures/templates/preview_render/inline.html.cut +0 -0
  502. data/test/fixtures/templates/publishing/layouts/dynamic.html.cut +1 -0
  503. data/test/fixtures/templates/publishing/layouts/static.html.cut +1 -0
  504. data/test/fixtures/templates/template_class/anonymous_style.html.cut +4 -0
  505. data/test/fixtures/templates/template_class/another_template.html.cut +0 -0
  506. data/test/fixtures/templates/template_class/complex_template.html.cut +6 -0
  507. data/test/fixtures/templates/template_class/complex_template.pdf.cut +6 -0
  508. data/test/fixtures/templates/template_class/default_template_style.html.cut +4 -0
  509. data/test/fixtures/templates/template_class/images_with_template.html.cut +5 -0
  510. data/test/fixtures/templates/template_class/slots_template.html.cut +5 -0
  511. data/test/fixtures/templates/template_class/slots_template.pdf.cut +5 -0
  512. data/test/fixtures/templates/template_class/this_template.epub.cut +1 -0
  513. data/test/fixtures/templates/template_class/this_template.html.cut +1 -0
  514. data/test/fixtures/templates/template_class/this_template.pdf.cut +1 -0
  515. data/test/fixtures/templates/with_default_style_class.html.cut +1 -0
  516. data/test/functional/test_application.rb +176 -0
  517. data/test/functional/test_back.rb +902 -0
  518. data/test/functional/test_front.rb +571 -0
  519. data/test/javascript/test_dom.rb +94 -0
  520. data/test/javascript/test_markdown.rb +97 -0
  521. data/test/slow/test_publishing.rb +987 -0
  522. data/test/slow/test_visibility.rb +250 -0
  523. data/test/support/custom_matchers.rb +77 -0
  524. data/test/support/timing.rb +23 -0
  525. data/test/test_helper.rb +164 -0
  526. data/test/test_javascript.rb +34 -0
  527. data/test/ui/test_page_editing.rb +167 -0
  528. data/test/ui_helper.rb +114 -0
  529. data/test/unit/test_alias.rb +254 -0
  530. data/test/unit/test_authentication.rb +510 -0
  531. data/test/unit/test_boxes.rb +497 -0
  532. data/test/unit/test_config.rb +156 -0
  533. data/test/unit/test_content.rb +221 -0
  534. data/test/unit/test_content_inheritance.rb +103 -0
  535. data/test/unit/test_extensions.rb +14 -0
  536. data/test/unit/test_fields.rb +392 -0
  537. data/test/unit/test_generators.rb +97 -0
  538. data/test/unit/test_image_size.rb +25 -0
  539. data/test/unit/test_images.rb +265 -0
  540. data/test/unit/test_layouts.rb +111 -0
  541. data/test/unit/test_logger.rb +80 -0
  542. data/test/unit/test_media.rb +70 -0
  543. data/test/unit/test_page.rb +244 -0
  544. data/test/unit/test_permissions.rb +834 -0
  545. data/test/unit/test_piece.rb +80 -0
  546. data/test/unit/test_prototype_set.rb +192 -0
  547. data/test/unit/test_prototypes.rb +102 -0
  548. data/test/unit/test_render.rb +359 -0
  549. data/test/unit/test_schema.rb +1009 -0
  550. data/test/unit/test_serialisation.rb +215 -0
  551. data/test/unit/test_site.rb +145 -0
  552. data/test/unit/test_structure.rb +85 -0
  553. data/test/unit/test_styles.rb +417 -0
  554. data/test/unit/test_templates.rb +224 -0
  555. data/test/unit/test_type_hierarchy.rb +28 -0
  556. metadata +1017 -0
@@ -0,0 +1,107 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ class Change < Sequel::Model(:changes)
5
+ class << self
6
+ alias_method :sequel_plugin, :plugin
7
+ end
8
+
9
+ sequel_plugin :yajl_serialization, :modified_list
10
+
11
+ @@instance = nil
12
+
13
+ class << self
14
+ def record
15
+ entry_point = @@instance.nil?
16
+ @@instance ||= self.new(:modified_list => [])
17
+ yield if block_given?
18
+ ensure
19
+ if entry_point and !@@instance.modified_list.empty?
20
+ @@instance.save
21
+ end
22
+ @@instance = nil if entry_point
23
+ end
24
+
25
+ def recording?
26
+ !@@instance.nil?
27
+ end
28
+
29
+ def push(page)
30
+ if @@instance
31
+ @@instance.push(page)
32
+ end
33
+ end
34
+
35
+ def outstanding
36
+ dependencies = dependency_map
37
+ dependencies.map { |d| Spontaneous::Collections::ChangeSet.new(d) }
38
+ end
39
+
40
+ def dependency_map
41
+ grouped_changes = self.valid.map { |c| [c] }
42
+ begin
43
+ modified = false
44
+ grouped_changes.each_with_index do |inner, i|
45
+ inner_ids = inner.map { |c| c.modified_list }.flatten
46
+ grouped_changes[(i+1)..-1].each_with_index do |outer, j|
47
+ outer_ids = outer.map { |c| c.modified_list }.flatten
48
+ unless (inner_ids & outer_ids).empty?
49
+ modified = true
50
+ grouped_changes.delete(outer)
51
+ grouped_changes[i] += outer
52
+ end
53
+ end
54
+ end
55
+ end while modified
56
+
57
+ grouped_changes
58
+ end
59
+
60
+ def valid
61
+ invalid, valid = self.all.partition { |change| change.modified.empty? }
62
+ self.filter(:id => invalid.map { |change| change.id }).delete
63
+ valid
64
+ end
65
+
66
+ def export
67
+ outstanding.map { |change_set| change_set.export }
68
+ end
69
+
70
+ def serialise_http
71
+ Spontaneous.serialise_http(export)
72
+ end
73
+ end
74
+
75
+
76
+ def after_initialize
77
+ super
78
+ self.modified_list ||= []
79
+ end
80
+
81
+ def push(page)
82
+ self.modified_list << page.id
83
+ end
84
+
85
+ def before_update
86
+ self.modified_list.uniq!
87
+ end
88
+
89
+ def modified
90
+ @modified ||= modified_list.map { |id| Content[id] }.compact
91
+ end
92
+
93
+ alias_method :pages, :modified
94
+
95
+ def &(change)
96
+ self.modified_list & change.modified_list
97
+ end
98
+
99
+ def export
100
+ {
101
+ :id => self.id,
102
+ :created_at => self.created_at.to_s,
103
+ :page_ids => modified_list
104
+ }
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Cli
5
+ module Adapter
6
+ class << self
7
+ def start(options)
8
+ ::Spontaneous::Server.run!(options)
9
+ end
10
+ end
11
+ end # Adapter
12
+ end # Cli
13
+ end # Spontaneous
@@ -0,0 +1,184 @@
1
+ require 'thor'
2
+
3
+ module Spontaneous
4
+ module Cli
5
+ class Base < ::Spontaneous::Cli::Thor
6
+ Spontaneous = ::Spontaneous
7
+ include Thor::Actions
8
+ namespace :default
9
+
10
+ class InvalidGenerator < Error
11
+ attr_reader :name
12
+ def initialize(name)
13
+ @name = name
14
+ super()
15
+ end
16
+ end
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+ desc :console, "Gives you console access to the current site"
25
+ def console
26
+ ENV["SPOT_MODE"] = "console"
27
+ prepare :console
28
+ ARGV.clear
29
+ require 'irb'
30
+ boot!
31
+ IRB.setup(nil)
32
+ irb = IRB::Irb.new
33
+ IRB.conf[:MAIN_CONTEXT] = irb.context
34
+ irb.context.evaluate("require 'irb/completion'", 0)
35
+ irb.context.evaluate("require '#{File.expand_path(File.dirname(__FILE__) + '/console')}'", 0)
36
+ # irb.context.evaluate("include Spontaneous", 0)
37
+ trap("SIGINT") do
38
+ irb.signal_handle
39
+ end
40
+ catch(:IRB_EXIT) do
41
+ irb.eval_input
42
+ end
43
+ end
44
+
45
+ desc :generate, "Executes the Spontaneous generator with given options."
46
+ def generate(*args)
47
+ require File.expand_path('../../../spontaneous', __FILE__)
48
+ ARGV.shift
49
+ generator_name = ARGV.shift
50
+ generator = nil
51
+ d = Spontaneous::Generators
52
+ case generator_name
53
+ when ''
54
+ raise InvalidGenerator.new(generator_name)
55
+ when 'site'
56
+ generator = d::Site
57
+ when 'page'
58
+ prepare(:generator)
59
+ boot!
60
+ generator = d::Page
61
+ when /[a-zA-Z0-9-]+(\.[a-z]+)+/
62
+ # generator called as 'spot generate domain.com'
63
+ ARGV.unshift(generator_name)
64
+ generator = d::Site
65
+ else
66
+ raise InvalidGenerator.new(generator_name)
67
+ end
68
+ generator.start(ARGV) if generator
69
+ rescue InvalidGenerator => e
70
+ say "Unrecognised generator '#{e.name}'. Available options are:\n\n #{available_generators.join("\n ")}\n"
71
+ end
72
+
73
+ desc :browse, "Launces a browser pointing to the current development CMS"
74
+ def browse
75
+ prepare :browse
76
+ require 'launchy'
77
+ boot!
78
+ ::Launchy::Browser.run("http://localhost:#{Site.config.port}/@spontaneous")
79
+ end
80
+
81
+
82
+ desc :init, "Creates databases and initialises a new Spontaneous site"
83
+ def init
84
+ prepare :init
85
+ require File.expand_path('../../../spontaneous', __FILE__)
86
+ Sequel.extension :migration
87
+ connection_params = Spontaneous.db_settings
88
+ connection_params[:user] = 'root'
89
+ database = connection_params.delete(:database)
90
+ password = connection_params.delete(:password)
91
+ catch(:error) do
92
+ Sequel.connect(connection_params) do |connection|
93
+ ["", "_test"].map { |ext| "#{database}#{ext}"}.each do |db|
94
+ begin
95
+ say " >> Creating database `#{db}`"
96
+ connection.run("CREATE DATABASE `#{db}` CHARACTER SET UTF8")
97
+ rescue => e
98
+ say " >>> Unable to create #{connection_params[:adapter]} database `#{db}`:\n > #{e}", :red
99
+ # throw :error
100
+ end
101
+ end
102
+ end
103
+ boot!
104
+ Spontaneous.database.logger = nil
105
+ say " >> Running migrations..."
106
+ Sequel::Migrator.apply(Spontaneous.database, Spontaneous.gem_dir('db/migrations'))
107
+ say " >> Done"
108
+ end
109
+ end
110
+
111
+ desc :migrate, "Runs migrations"
112
+ def migrate
113
+ prepare :init
114
+ boot!
115
+ Sequel.extension :migration
116
+ connection_params = Spontaneous.db_settings
117
+ say " >> Running migrations..."
118
+ Sequel::Migrator.apply(Spontaneous.database, Spontaneous.gem_dir('db/migrations'))
119
+ say " >> Done"
120
+ end
121
+
122
+ desc :adduser, "Add a user"
123
+ def adduser
124
+ prepare :adduser
125
+ boot!
126
+ users = Spontaneous::Permissions::User.count
127
+ attrs = {}
128
+ width = 12
129
+ valid_login = /^[a-z0-9_]{3,}$/
130
+ levels = Spontaneous::Permissions::UserLevel.all.map(&:to_s)
131
+ level = nil
132
+
133
+ say("\nAll fields are required:\n", :green)
134
+ begin
135
+ attrs[:login] = ask "Login : ".rjust(width, " ")
136
+ say("Login must consist of at least 3 letters, numbers and underscores", :red) unless valid_login === attrs[:login]
137
+ end while attrs[:login] !~ valid_login
138
+
139
+ attrs[:name] = ask "Name : ".rjust(width, " ")
140
+ attrs[:email] = ask "Email : ".rjust(width, " ")
141
+
142
+ begin
143
+ attrs[:password] = ask "Password : ".rjust(width, " ")
144
+ say("Password must be at least 6 characters long", :red) unless attrs[:password].length > 5
145
+ end while attrs[:password].length < 6
146
+
147
+ if users == 0
148
+ level = "root"
149
+ else
150
+ begin
151
+ level = ask("User level [#{levels.join(', ')}] : ")
152
+ say("Invalid level '#{level}'", :red) unless levels.include?(level)
153
+ end while !levels.include?(level)
154
+ end
155
+
156
+ attrs[:password_confirmation] = attrs[:password]
157
+ user = Spontaneous::Permissions::User.new(attrs)
158
+
159
+ if user.save
160
+ user.update(:level => level)
161
+ say("\nUser '#{user.login}' created with level '#{user.level}'", :green)
162
+ else
163
+ errors = user.errors.map do | a, e |
164
+ " - '#{a.to_s.capitalize}' #{e.first}"
165
+ end.join("\n")
166
+ say("\nInvalid user details:\n"+errors, :red)
167
+ end
168
+ end
169
+
170
+ private
171
+
172
+
173
+ def available_generators
174
+ Spontaneous::Generators.available.map do |g|
175
+ g.name.demodulize.underscore
176
+ end
177
+ end
178
+
179
+
180
+
181
+
182
+ end # Base
183
+ end # Cli
184
+ end # Spontaneous
File without changes
@@ -0,0 +1,13 @@
1
+
2
+ module Spontaneous
3
+ module Cli
4
+ class Media < ::Thor
5
+ namespace :media
6
+
7
+ desc "#{namespace}:cleanup", "Removes stale temp files"
8
+ def cleanup
9
+ puts "CLEANING UP!!"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,50 @@
1
+
2
+ module Spontaneous
3
+ module Cli
4
+ class Server < ::Spontaneous::Cli::Thor
5
+ namespace :server
6
+
7
+ default_task :back
8
+
9
+ # desc :start, "Starts Spontaneous"
10
+
11
+ # def both
12
+ # pids = []
13
+ # trap(:INT) { }
14
+ # pids << fork { front }
15
+ # pids << fork { back }
16
+ # Process.wait
17
+ # pids.each { | pid | Process.kill(:TERM, pid) rescue nil }
18
+ # end
19
+
20
+
21
+ desc "#{namespace}:front", "Starts Spontaneous in front/public mode"
22
+ # method_option :adapter, :type => :string, :aliases => "-a", :desc => "Rack Handler (default: autodetect)"
23
+ method_option :host, :type => :string, :aliases => "-h", :desc => "Bind to HOST address"
24
+ method_option :port, :type => :numeric, :aliases => "-p", :desc => "Use PORT"
25
+ def front
26
+ start_server(:front)
27
+ end
28
+
29
+ desc "#{namespace}:back", "Starts Spontaneous in back/CMS mode"
30
+ # method_option :adapter, :type => :string, :aliases => "-a", :desc => "Rack Handler (default: autodetect)"
31
+ method_option :host, :type => :string, :aliases => "-h", :desc => "Bind to HOST address"
32
+ method_option :port, :type => :numeric, :aliases => "-p", :desc => "Use PORT"
33
+ def back
34
+ start_server(:back)
35
+ end
36
+
37
+ private
38
+
39
+ def start_server(mode)
40
+ prepare mode.to_sym
41
+ ENV["SPOT_MODE"] = mode.to_s
42
+ require File.expand_path(File.dirname(__FILE__) + "/adapter")
43
+ boot!
44
+ Spontaneous::Cli::Adapter.start(options)
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,46 @@
1
+
2
+ module Spontaneous
3
+ module Cli
4
+ class Site < ::Spontaneous::Cli::Thor
5
+ Spontaneous = ::Spontaneous
6
+ namespace :site
7
+
8
+ default_task :browse
9
+
10
+ desc "#{namespace}:publish", "Publishes the site"
11
+ method_option :changes, :type => :array, :desc => "List of changesets to include"
12
+ method_option :logfile, :type => :string, :desc => "Location of logfile"
13
+
14
+ def publish
15
+ prepare :publish
16
+ # TODO: set up logging
17
+ boot!
18
+ ::Site.publishing_method = :immediate
19
+ Spontaneous::Logger.setup(:logfile => options.logfile) if options.logfile
20
+ say "Creating revision #{::Site.revision}", :green, true
21
+ if options.changes
22
+ say "> Publishing changes #{options.changes.inspect}", :green, true
23
+ ::Site.publish_changes(options.changes)
24
+ else
25
+ say "> Publishing all", :green, true
26
+ ::Site.publish_all
27
+ end
28
+ end
29
+
30
+ desc "#{namespace}:revision", "Shows the site status"
31
+ def revision
32
+ prepare :revision
33
+ boot!
34
+ say "Site is at revision #{::Site.revision}", :green
35
+ end
36
+
37
+ desc "#{namespace}:browse", "Launces a browser pointing to the current development CMS"
38
+ def browse
39
+ prepare :browse
40
+ require 'launchy'
41
+ boot!
42
+ ::Launchy::Browser.run("http://localhost:#{::Site.config.port}/@spontaneous")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+
2
+ module Spontaneous
3
+ module Cli
4
+ class Sync < ::Spontaneous::Cli::Thor
5
+ Spontaneous = ::Spontaneous
6
+ namespace :sync
7
+ default_task :down
8
+
9
+ class SyncTask < ::Thor::Group
10
+ protected
11
+
12
+ def arse(n)
13
+ puts 'arse '+n
14
+ end
15
+ end
16
+
17
+ class Down < SyncTask
18
+ desc "Syncs down"
19
+ def one
20
+ arse('one')
21
+ end
22
+ def two
23
+ arse('two')
24
+ end
25
+ end
26
+
27
+ class Up < SyncTask
28
+ desc "Syncs up"
29
+ end
30
+
31
+ desc "#{namespace}:down", "Makes the local copy a clone of the live server"
32
+ def down
33
+ Down.start
34
+ end
35
+
36
+ desc "#{namespace}:up", "Makes the local copy a clone of the live server"
37
+ def up
38
+ Down.start
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ require 'thor'
2
+
3
+ module Spontaneous
4
+ # class Cli
5
+ # module Tasks
6
+ # end
7
+ # end
8
+ end
9
+
@@ -0,0 +1,83 @@
1
+ require 'thor'
2
+ require 'thor/runner'
3
+
4
+ module Spontaneous
5
+ module Cli
6
+ class Thor < ::Thor
7
+
8
+ class_option :site, :type => :string, :aliases => ["-s", "--root"], :desc => "Site root dir"
9
+ class_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development, :desc => "Spontaneous Environment"
10
+ class_option :mode, :type => :string, :aliases => "-m", :default => :back, :desc => "Spontaneous mode ('front' or 'back')"
11
+ class_option :help, :type => :boolean, :desc => "Show help usage"
12
+ protected
13
+
14
+ def boot!
15
+ begin
16
+ require File.expand_path('config/boot.rb')
17
+ rescue Spontaneous::SchemaModificationError => error
18
+ fix_schema(error)
19
+ end
20
+ end
21
+
22
+ def fix_schema(error)
23
+ modification = error.modification
24
+ actions = modification.actions
25
+ say(actions.description, :red)
26
+ say("Please choose one of the solutions below", :yellow)
27
+ actions.each_with_index do |a, i|
28
+ say(" #{i+1}: #{a.description}")
29
+ end
30
+ choice = ( ask "Choose action : ").to_i rescue nil
31
+ if choice and choice <= actions.length and choice > 0
32
+ action = actions[choice - 1]
33
+ begin
34
+ Spontaneous::Schema.apply(action)
35
+ rescue Spontaneous::SchemaModificationError => error
36
+ fix_schema(error)
37
+ end
38
+ else
39
+ say("Invalid choice '#{choice.inspect}'\n", :red)
40
+ fix_schema(error)
41
+ end
42
+ end
43
+
44
+ def prepare(task)
45
+ if options.help?
46
+ help(task.to_s)
47
+ raise SystemExit
48
+ end
49
+ ENV["SPOT_ENV"] ||= options.environment.to_s
50
+ ENV["RACK_ENV"] = ENV["SPOT_ENV"] # Also set this for middleware
51
+ ENV["SPOT_MODE"] ||= options.mode.to_s
52
+ chdir(options.site)
53
+ unless File.exist?('config/boot.rb')
54
+ puts "=> Could not find boot file in: #{options.chdir}/config/boot.rb\n=> Are you sure this is a Spontaneous site?"
55
+ raise SystemExit
56
+ end
57
+ end
58
+
59
+ def chdir(dir)
60
+ return unless dir
61
+ begin
62
+ Dir.chdir(dir.to_s)
63
+ rescue Errno::ENOENT
64
+ puts "=> Specified site '#{dir}' does not appear to exist"
65
+ rescue Errno::EACCES
66
+ puts "=> Specified site '#{dir}' cannot be accessed by the current user"
67
+ end
68
+ end
69
+ end
70
+
71
+ class Runner < ::Thor::Runner
72
+ remove_task :install#, :undefine => true
73
+
74
+ private
75
+
76
+ def thorfiles(*args)
77
+ task_dir = File.expand_path('../cli', __FILE__)
78
+ Dir["#{task_dir}/*.rb"]
79
+ end
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,56 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous::Collections
5
+ class BoxSet < PrototypeSet
6
+
7
+ attr_reader :owner
8
+
9
+ def initialize(owner)
10
+ super()
11
+ @owner = owner
12
+ initialize_from_prototypes
13
+ end
14
+
15
+ def initialize_from_prototypes
16
+ owner.class.boxes.each do |box_prototype|
17
+ box = box_prototype.get_instance(owner)
18
+ add_box(box)
19
+ end
20
+ end
21
+
22
+ alias_method :get_without_ranges, :[]
23
+
24
+ def [](*args)
25
+ if args.length == 1
26
+ get_single(args[0])
27
+ else
28
+ args.map { |index| get_single(index) }.flatten
29
+ end
30
+ end
31
+
32
+ def export
33
+ self.map { |item| item.export }
34
+ end
35
+
36
+ protected
37
+
38
+ def get_single(index)
39
+ case index
40
+ when Range
41
+ order[index].map { | name | named(name) }
42
+ else
43
+ get_without_ranges(index)
44
+ end
45
+ end
46
+
47
+ def add_box(box)
48
+ self[box._prototype.name] = box
49
+ getter_name = box._prototype.name
50
+ singleton_class.class_eval do
51
+ define_method(getter_name) { |*args| box.tap { |b| b.template_params = args } }
52
+ end
53
+ end
54
+ end
55
+ end
56
+
@@ -0,0 +1,43 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Collections
4
+ class ChangeSet
5
+ attr_reader :changes
6
+
7
+ def initialize(changes)
8
+ @changes = changes.map do |change_or_id|
9
+ change_or_id.is_a?(Spontaneous::Change) ? change_or_id : Spontaneous::Change[change_or_id]
10
+ end
11
+ end
12
+
13
+ def pages
14
+ @pages ||= page_ids.map { |id| Spontaneous::Content[id] }
15
+ end
16
+
17
+ def page_ids
18
+ @page_ids ||= changes.inject([]) { |a, c| a += c.modified_list; a }.uniq.sort
19
+ end
20
+
21
+ def export
22
+ h = {
23
+ :changes => changes.map { |c| c.export },
24
+ }
25
+ # use compact because it's possible that some pages have been deleted since
26
+ # the change was created and the best way to deal with them is to silently
27
+ # ignore them and let the publishing mech delete them as usual
28
+ h[:pages] = pages.compact.map do |page|
29
+ {
30
+ :id => page.id,
31
+ :title => page.title.to_s,
32
+ :path => page.path,
33
+ :depth => page.depth
34
+ }
35
+ end
36
+ h
37
+ end
38
+ # def serialise_http
39
+ # Spontaneous.serialise_http(export)
40
+ # end
41
+ end
42
+ end
43
+