luca 0.9.8 → 0.9.9

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 (310) hide show
  1. data/CHANGELOG +49 -0
  2. data/Gemfile +8 -1
  3. data/Gemfile.lock +97 -53
  4. data/Guardfile +3 -25
  5. data/README.md +5 -16
  6. data/ROADMAP +15 -9
  7. data/Rakefile +24 -75
  8. data/app.rb +10 -42
  9. data/app/assets/javascripts/luca/basic.coffee +1 -1
  10. data/app/assets/javascripts/luca/components/application.coffee +187 -104
  11. data/app/assets/javascripts/luca/components/collection_view.coffee +115 -51
  12. data/app/assets/javascripts/luca/components/controller.coffee +87 -10
  13. data/app/assets/javascripts/luca/components/fields/base.coffee +74 -13
  14. data/app/assets/javascripts/luca/components/fields/button_field.coffee +60 -13
  15. data/app/assets/javascripts/luca/components/fields/checkbox_array.coffee +12 -7
  16. data/app/assets/javascripts/luca/components/fields/select_field.coffee +82 -23
  17. data/app/assets/javascripts/luca/components/fields/text_area_field.coffee +25 -10
  18. data/app/assets/javascripts/luca/components/fields/text_field.coffee +9 -3
  19. data/app/assets/javascripts/luca/components/form_view.coffee +105 -33
  20. data/app/assets/javascripts/luca/components/grid_layout_view.coffee +42 -0
  21. data/app/assets/javascripts/luca/components/index.coffee +6 -0
  22. data/app/assets/javascripts/luca/components/nav_bar.coffee +60 -6
  23. data/app/assets/javascripts/luca/components/page.coffee +70 -0
  24. data/app/assets/javascripts/luca/components/simple_collection_view.coffee +10 -0
  25. data/app/assets/javascripts/luca/components/table_view.coffee +7 -3
  26. data/app/assets/javascripts/luca/components/table_view_scrollable.coffee +23 -0
  27. data/app/assets/javascripts/luca/concerns/collection_event_bindings.coffee +4 -1
  28. data/app/assets/javascripts/luca/concerns/development_tool_helpers.coffee +23 -14
  29. data/app/assets/javascripts/luca/concerns/dom_helpers.coffee +2 -2
  30. data/app/assets/javascripts/luca/concerns/filterable.coffee +8 -11
  31. data/app/assets/javascripts/luca/concerns/form_model_bindings.coffee +20 -0
  32. data/app/assets/javascripts/luca/concerns/modal_view.coffee +40 -15
  33. data/app/assets/javascripts/luca/concerns/query_collection_bindings.coffee +7 -1
  34. data/app/assets/javascripts/luca/concerns/state_model.coffee +40 -26
  35. data/app/assets/javascripts/luca/concerns/templating.coffee +3 -1
  36. data/app/assets/javascripts/luca/config.coffee +5 -0
  37. data/app/assets/javascripts/luca/containers/card_view.coffee +87 -52
  38. data/app/assets/javascripts/luca/containers/container.coffee +305 -108
  39. data/app/assets/javascripts/luca/containers/modal_view.coffee +9 -9
  40. data/app/assets/javascripts/luca/containers/page_controller.coffee +25 -0
  41. data/app/assets/javascripts/luca/containers/panel_toolbar.coffee +5 -6
  42. data/app/assets/javascripts/luca/containers/tab_view.coffee +19 -10
  43. data/app/assets/javascripts/luca/containers/viewport.coffee +12 -16
  44. data/app/assets/javascripts/luca/core/collection.coffee +19 -5
  45. data/app/assets/javascripts/luca/core/events.coffee +5 -5
  46. data/app/assets/javascripts/luca/core/model.coffee +1 -1
  47. data/app/assets/javascripts/luca/core/panel.coffee +18 -6
  48. data/app/assets/javascripts/luca/core/registry/component_definition.coffee +2 -1
  49. data/app/assets/javascripts/luca/core/registry/meta_data.coffee +2 -0
  50. data/app/assets/javascripts/luca/core/registry/registry.coffee +14 -11
  51. data/app/assets/javascripts/luca/core/templates.coffee +5 -1
  52. data/app/assets/javascripts/luca/core/view.coffee +200 -47
  53. data/app/assets/javascripts/luca/dependencies.coffee +2 -0
  54. data/app/assets/javascripts/luca/development/code_sync_manager.coffee +173 -0
  55. data/app/assets/javascripts/luca/development/component.coffee +76 -0
  56. data/app/assets/javascripts/luca/development/components.coffee +57 -0
  57. data/app/assets/javascripts/luca/development/console.coffee +1 -1
  58. data/app/assets/javascripts/luca/development/index.coffee +4 -1
  59. data/app/assets/javascripts/luca/framework.coffee +7 -3
  60. data/app/assets/javascripts/luca/index.coffee +2 -1
  61. data/app/assets/javascripts/luca/managers/collection_manager.coffee +2 -3
  62. data/app/assets/javascripts/luca/managers/index.coffee +1 -1
  63. data/app/assets/javascripts/luca/managers/socket_manager.coffee +31 -8
  64. data/app/assets/javascripts/luca/templates/components/nav_bar.jst.ejs +16 -1
  65. data/app/assets/javascripts/luca/templates/containers/tab_view.jst.ejs +1 -1
  66. data/app/assets/javascripts/luca/util/index.coffee +1 -0
  67. data/app/assets/javascripts/luca/util/keybindings.coffee +24 -0
  68. data/app/assets/javascripts/luca/util/logging.coffee +15 -0
  69. data/app/assets/javascripts/luca/util/luca.coffee +9 -1
  70. data/app/assets/stylesheets/luca/components/table_view.scss +85 -0
  71. data/app/assets/stylesheets/luca/components/viewport.scss +0 -4
  72. data/app/assets/stylesheets/luca/containers/container.scss +8 -0
  73. data/app/assets/stylesheets/luca/index.css +2 -2
  74. data/bin/luca +14 -0
  75. data/config.ru +1 -2
  76. data/docs/framework.json +1 -0
  77. data/docs/luca-framework-documentation.js +1 -0
  78. data/docs/{application.md → old/application.md} +0 -0
  79. data/docs/{collection.md → old/collection.md} +0 -0
  80. data/docs/{collection_manager.md → old/collection_manager.md} +0 -0
  81. data/docs/{container_philosophy.md → old/container_philosophy.md} +0 -0
  82. data/docs/{event_binding_helpers.md → old/event_binding_helpers.md} +0 -0
  83. data/docs/{method_caching_and_computed_properties.md → old/method_caching_and_computed_properties.md} +0 -0
  84. data/docs/{view.md → old/view.md} +0 -0
  85. data/lib/generators/luca/application/templates/javascripts/dependencies.coffee +2 -5
  86. data/lib/guard/luca.rb +84 -0
  87. data/lib/luca.rb +25 -1
  88. data/lib/luca/asset_compiler.rb +117 -0
  89. data/lib/luca/cli.rb +68 -0
  90. data/lib/luca/cli/generate.rb +37 -0
  91. data/lib/luca/cli/server.rb +20 -0
  92. data/lib/luca/cli/sync.rb +40 -0
  93. data/lib/luca/cli/watch.rb +16 -0
  94. data/lib/luca/collection.rb +64 -0
  95. data/lib/luca/collection/endpoint.rb +38 -0
  96. data/lib/luca/collection/file_backend.rb +121 -0
  97. data/lib/luca/collection/redis_backend.rb +153 -0
  98. data/lib/luca/compiled_asset.rb +61 -0
  99. data/lib/luca/component_definition.rb +356 -0
  100. data/lib/luca/luca_application.rb +258 -0
  101. data/lib/luca/project.rb +73 -0
  102. data/lib/luca/project_harness.rb +96 -0
  103. data/lib/luca/rails.rb +5 -3
  104. data/lib/luca/rails/engine.rb +8 -0
  105. data/lib/luca/rails/version.rb +1 -2
  106. data/lib/luca/server.rb +7 -0
  107. data/lib/luca/stylesheet.rb +35 -0
  108. data/lib/luca/template.rb +2 -0
  109. data/lib/luca/template_asset.rb +64 -0
  110. data/lib/luca/version.rb +3 -0
  111. data/lib/luca/watcher.rb +72 -0
  112. data/lib/railties/luca/tasks.rake +7 -0
  113. data/site/.bundle/config +2 -0
  114. data/site/.gitignore +5 -0
  115. data/site/.rvmrc +1 -0
  116. data/site/CHANGELOG.md +41 -0
  117. data/site/DOCS.md +41 -0
  118. data/site/Gemfile +8 -0
  119. data/site/Gemfile.lock +134 -0
  120. data/site/LICENSE.md +19 -0
  121. data/site/config.rb +84 -0
  122. data/site/helpers/site_helpers.rb +20 -0
  123. data/site/html5bp-docs/README.md +38 -0
  124. data/site/html5bp-docs/contribute.md +104 -0
  125. data/site/html5bp-docs/crossdomain.md +21 -0
  126. data/site/html5bp-docs/css.md +135 -0
  127. data/site/html5bp-docs/extend.md +507 -0
  128. data/site/html5bp-docs/faq.md +77 -0
  129. data/site/html5bp-docs/htaccess.md +323 -0
  130. data/site/html5bp-docs/html.md +170 -0
  131. data/site/html5bp-docs/js.md +31 -0
  132. data/site/html5bp-docs/misc.md +25 -0
  133. data/site/html5bp-docs/usage.md +109 -0
  134. data/site/readme.md +47 -0
  135. data/site/source/.htaccess +540 -0
  136. data/site/source/404.html +157 -0
  137. data/site/source/app/assets/javascripts/dependencies.js.coffee +6 -0
  138. data/site/source/app/assets/javascripts/docs-docs.js +1 -0
  139. data/site/source/app/assets/javascripts/docs/application.coffee +64 -0
  140. data/site/source/app/assets/javascripts/docs/collections/docs_documentation.coffee +17 -0
  141. data/site/source/app/assets/javascripts/docs/collections/github_repositories.coffee +7 -0
  142. data/site/source/app/assets/javascripts/docs/collections/index.coffee +1 -0
  143. data/site/source/app/assets/javascripts/docs/collections/luca_documentation.coffee +17 -0
  144. data/site/source/app/assets/javascripts/docs/collections/public_gists.coffee +4 -0
  145. data/site/source/app/assets/javascripts/docs/config.coffee +5 -0
  146. data/site/source/app/assets/javascripts/docs/index.coffee +12 -0
  147. data/site/source/app/assets/javascripts/docs/lib/router.coffee +3 -0
  148. data/{spec/components/application_spec.coffee → site/source/app/assets/javascripts/docs/lib/util.coffee} +0 -0
  149. data/site/source/app/assets/javascripts/docs/models/component.coffee +99 -0
  150. data/site/source/app/assets/javascripts/docs/models/github_repository.coffee +3 -0
  151. data/site/source/app/assets/javascripts/docs/models/index.coffee +1 -0
  152. data/site/source/app/assets/javascripts/docs/templates/component_documentation.jst.ejs +55 -0
  153. data/site/source/app/assets/javascripts/docs/templates/examples_browser/overview.jst.ejs +4 -0
  154. data/site/source/app/assets/javascripts/docs/templates/examples_browser/selector.jst.ejs +11 -0
  155. data/site/source/app/assets/javascripts/docs/templates/github_repository.jst.ejs +4 -0
  156. data/site/source/app/assets/javascripts/docs/templates/layouts/main.jst.ejs +4 -0
  157. data/site/source/app/assets/javascripts/docs/templates/left_navigation.jst.ejs +5 -0
  158. data/site/source/app/assets/javascripts/docs/templates/pages/getting_started.jst.ejs +78 -0
  159. data/site/source/app/assets/javascripts/docs/templates/pages/home.jst.ejs +57 -0
  160. data/site/source/app/assets/javascripts/docs/views/components/code_editor.coffee +45 -0
  161. data/{spec/components/collection_loader_view_spec.coffee → site/source/app/assets/javascripts/docs/views/components/code_editor/index.coffee} +0 -0
  162. data/site/source/app/assets/javascripts/docs/views/components/component_documentation.coffee +72 -0
  163. data/site/source/app/assets/javascripts/docs/views/index.coffee +3 -0
  164. data/site/source/app/assets/javascripts/docs/views/pages/browse_source.coffee +46 -0
  165. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/details.coffee +37 -0
  166. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/list.coffee +31 -0
  167. data/site/source/app/assets/javascripts/docs/views/pages/component_editor.coffee +10 -0
  168. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser.coffee +102 -0
  169. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/docs.coffee +12 -0
  170. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/source.coffee +13 -0
  171. data/site/source/app/assets/javascripts/docs/views/pages/home.coffee +10 -0
  172. data/site/source/app/assets/javascripts/docs/views/views/api_browser/index.coffee +43 -0
  173. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/grid_layout_view_example.coffee +14 -0
  174. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/table_view_example.coffee +39 -0
  175. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/basic_example.coffee +38 -0
  176. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/complex_layout.coffee +110 -0
  177. data/site/source/app/assets/javascripts/docs/views/views/top_navigation.coffee +6 -0
  178. data/site/source/app/assets/javascripts/luca-docs.js +1 -0
  179. data/site/source/app/assets/javascripts/luca-framework-documentation.js +1 -0
  180. data/site/source/app/assets/javascripts/site.js.coffee +4 -0
  181. data/site/source/app/assets/javascripts/vendor/codemirror.js +4786 -0
  182. data/site/source/app/assets/javascripts/vendor/coffeescript.js +346 -0
  183. data/site/source/app/assets/javascripts/vendor/css.js +465 -0
  184. data/site/source/app/assets/javascripts/vendor/htmlmixed.js +84 -0
  185. data/site/source/app/assets/javascripts/vendor/javascript.js +422 -0
  186. data/site/source/app/assets/javascripts/vendor/js-beautify.js +1353 -0
  187. data/site/source/app/assets/javascripts/vendor/modernizr-2.6.1.min.js +4 -0
  188. data/site/source/app/assets/javascripts/vendor/vim.js +2511 -0
  189. data/site/source/app/assets/stylesheets/docs/api-browser.css.scss +5 -0
  190. data/site/source/app/assets/stylesheets/docs/application.css.scss +35 -0
  191. data/site/source/app/assets/stylesheets/docs/browse-source.css.scss +5 -0
  192. data/site/source/app/assets/stylesheets/docs/scrollable-table.css.scss +5 -0
  193. data/site/source/app/assets/stylesheets/site.css.scss +2 -0
  194. data/site/source/app/assets/stylesheets/vendor/codemirror.css +240 -0
  195. data/site/source/app/assets/stylesheets/vendor/prettify-tomorrow-night-bright.css +160 -0
  196. data/site/source/app/assets/stylesheets/vendor/twilight.css +26 -0
  197. data/site/source/crossdomain.xml +15 -0
  198. data/site/source/documentation.html.haml +1 -0
  199. data/site/source/favicon_base.png +0 -0
  200. data/site/source/humans.txt +15 -0
  201. data/site/source/images/background.png +0 -0
  202. data/site/source/images/middleman.png +0 -0
  203. data/site/source/index.html.haml +1 -0
  204. data/site/source/layouts/layout.haml +55 -0
  205. data/site/source/readme.md +63 -0
  206. data/site/source/robots.txt +3 -0
  207. data/spec/{components/grid_view_spec.coffee → javascripts/components/application_spec.coffee} +0 -0
  208. data/spec/{components/pagination_control_spec.coffee → javascripts/components/collection_loader_view_spec.coffee} +0 -0
  209. data/spec/{components → javascripts/components}/collection_view_spec.coffee +1 -1
  210. data/spec/{components → javascripts/components}/controller_spec.coffee +0 -0
  211. data/spec/{components → javascripts/components}/fields/checkbox_array_spec.coffee +0 -0
  212. data/spec/javascripts/components/form_view_spec.coffee +162 -0
  213. data/spec/{components/record_manager_spec.coffee → javascripts/components/grid_view_spec.coffee} +0 -0
  214. data/spec/{components → javascripts/components}/multi_collection_view_spec.coffee +0 -0
  215. data/spec/{components/template_spec.coffee → javascripts/components/pagination_control_spec.coffee} +0 -0
  216. data/spec/{concerns/paginatable_spec.coffee → javascripts/components/record_manager_spec.coffee} +0 -0
  217. data/spec/{components → javascripts/components}/table_view_spec.coffee +0 -0
  218. data/spec/{containers/modal_view_spec.coffee → javascripts/components/template_spec.coffee} +0 -0
  219. data/spec/{concerns → javascripts/concerns}/collection_event_bindings_spec.coffee +0 -0
  220. data/spec/{concerns → javascripts/concerns}/dom_helpers_spec.coffee +0 -0
  221. data/spec/{concerns → javascripts/concerns}/filterable_spec.coffee +0 -0
  222. data/spec/{concerns → javascripts/concerns}/model_presenter_spec.coffee +0 -0
  223. data/spec/{containers/panel_view_spec.coffee → javascripts/concerns/paginatable_spec.coffee} +0 -0
  224. data/spec/{concerns → javascripts/concerns}/state_model_spec.coffee +5 -0
  225. data/spec/javascripts/containers/card_view_spec.coffee +108 -0
  226. data/spec/{containers/tab_view_spec.coffee → javascripts/containers/modal_view_spec.coffee} +0 -0
  227. data/spec/{containers/viewport_spec.coffee → javascripts/containers/panel_view_spec.coffee} +0 -0
  228. data/spec/{core/observer_spec.coffee → javascripts/containers/tab_view_spec.coffee} +0 -0
  229. data/spec/{managers/socket_manager_spec.coffee → javascripts/containers/viewport_spec.coffee} +0 -0
  230. data/spec/{core → javascripts/core}/collection_spec.coffee +1 -1
  231. data/spec/{core → javascripts/core}/concerns_spec.coffee +0 -0
  232. data/spec/{core → javascripts/core}/container_spec.coffee +0 -0
  233. data/spec/{core → javascripts/core}/define_spec.coffee +0 -0
  234. data/spec/{core → javascripts/core}/events_spec.coffee +0 -0
  235. data/spec/{core → javascripts/core}/field_spec.coffee +0 -0
  236. data/spec/{core → javascripts/core}/framework_spec.coffee +0 -0
  237. data/spec/{core → javascripts/core}/model_spec.coffee +0 -0
  238. data/spec/javascripts/core/observer_spec.coffee +0 -0
  239. data/spec/{core → javascripts/core}/util_spec.coffee +0 -0
  240. data/spec/{core → javascripts/core}/view_spec.coffee +51 -39
  241. data/spec/{dependencies → javascripts/dependencies}/index.coffee +0 -0
  242. data/spec/{dependencies → javascripts/dependencies}/jasmine-html.js +0 -0
  243. data/spec/{dependencies → javascripts/dependencies}/jasmine.js +0 -0
  244. data/spec/{dependencies → javascripts/dependencies}/sinon.js +0 -0
  245. data/spec/{helper.coffee → javascripts/helper.coffee} +0 -0
  246. data/spec/{managers → javascripts/managers}/collection_manager_spec.coffee +0 -0
  247. data/spec/javascripts/managers/socket_manager_spec.coffee +0 -0
  248. data/spec/lib/component_definition_spec.rb +63 -0
  249. data/spec/lib/input_compiler_spec.rb +9 -0
  250. data/spec/lib/luca_application_spec.rb +30 -0
  251. data/spec/support/fixtures/application.coffee +45 -0
  252. data/spec/support/fixtures/component.coffee +34 -0
  253. data/tutorials/component-definitions.md +0 -0
  254. data/tutorials/component-definitions/01_intro.md +0 -0
  255. data/tutorials/component-driven-design.md +140 -0
  256. data/tutorials/structure-of-a-project.md +63 -0
  257. data/vendor/assets/javascripts/backbone-min.js +37 -33
  258. data/vendor/assets/javascripts/backbone-query.min.js +1 -1
  259. data/vendor/assets/javascripts/hogan.js +707 -0
  260. data/vendor/assets/javascripts/jquery.js +5 -4
  261. data/vendor/assets/javascripts/keymaster.min.js +4 -0
  262. data/vendor/assets/javascripts/luca-dependencies.min.js +8 -0
  263. data/vendor/assets/javascripts/luca-development.min.js +1 -0
  264. data/vendor/assets/javascripts/luca-spec.js +6 -6
  265. data/vendor/assets/javascripts/luca-ui.js +7386 -0
  266. data/vendor/assets/javascripts/luca-ui.min.js +5 -0
  267. data/vendor/assets/javascripts/luca.full.min.js +12 -0
  268. data/vendor/assets/javascripts/luca.min.js +5 -0
  269. data/vendor/assets/javascripts/underscore-min.js +1 -5
  270. data/vendor/assets/javascripts/underscore-string.min.js +1 -1
  271. data/vendor/assets/stylesheets/luca-components.css +202 -0
  272. data/vendor/assets/stylesheets/luca-development.css +23 -0
  273. data/vendor/assets/stylesheets/luca-ui.css +198 -0
  274. metadata +324 -94
  275. data/app/assets/javascripts/luca/components/base_toolbar.coffee +0 -17
  276. data/app/assets/javascripts/luca/components/form_button_toolbar.coffee +0 -28
  277. data/app/assets/javascripts/luca/components/grid_view.coffee +0 -269
  278. data/app/assets/javascripts/luca/components/page_controller.coffee +0 -7
  279. data/app/assets/javascripts/luca/components/template.coffee +0 -5
  280. data/app/assets/javascripts/luca/components/toolbar_dialog.coffee +0 -25
  281. data/lib/luca/code_browser.rb +0 -55
  282. data/lib/luca/command_line.rb +0 -69
  283. data/lib/luca/component_documentation.rb +0 -72
  284. data/site/assets/bootstrap.min.js +0 -7
  285. data/site/assets/dependencies.js +0 -94
  286. data/site/assets/glyphicons-halflings-white.png +0 -0
  287. data/site/assets/glyphicons-halflings.png +0 -0
  288. data/site/assets/luca-ui-bootstrap.css +0 -1331
  289. data/site/assets/luca-ui-bootstrap.js +0 -9
  290. data/site/assets/luca-ui-development-tools.css +0 -234
  291. data/site/assets/luca-ui-development-tools.js +0 -18561
  292. data/site/assets/luca-ui-development-tools.min.js +0 -15
  293. data/site/assets/luca-ui-full.min.js +0 -8
  294. data/site/assets/luca-ui.min.js +0 -4
  295. data/site/assets/sandbox.css +0 -62
  296. data/site/assets/sandbox.js +0 -469
  297. data/site/docs/application.html +0 -41
  298. data/site/docs/caching.html +0 -43
  299. data/site/docs/collection.html +0 -75
  300. data/site/docs/collection_manager.html +0 -71
  301. data/site/docs/containers.html +0 -118
  302. data/site/docs/events.html +0 -153
  303. data/site/docs/view.html +0 -128
  304. data/site/img/glyphicons-halflings-white.png +0 -0
  305. data/site/img/glyphicons-halflings.png +0 -0
  306. data/site/index.html +0 -20
  307. data/site/source-map.js +0 -1
  308. data/spec/components/form_view_spec.coffee +0 -84
  309. data/spec/containers/card_view_spec.coffee +0 -50
  310. data/spec/luca-spec.coffee +0 -9
@@ -0,0 +1,40 @@
1
+ module Luca
2
+ module Cli
3
+ class Sync < Thor
4
+ namespace :sync
5
+
6
+ method_options :namespace => :string
7
+ method_option :port, :default => 9292
8
+ method_option :timeout, :default => 25
9
+ method_option :channel, :default => "faye"
10
+ method_option :root, :default => Dir.pwd()
11
+
12
+ desc "sync", "sync APPLICATION_NAME [options]"
13
+ def sync application_name
14
+ fork do
15
+ watch(application_name)
16
+ end
17
+
18
+ fork do
19
+ server(application_name)
20
+ end
21
+
22
+ Process.waitpid
23
+ end
24
+
25
+ no_tasks do
26
+ def watch application_name
27
+ puts "Watching application assets for changes..."
28
+ watcher = Luca::Watcher.new(application_name, options)
29
+ watcher.start
30
+ end
31
+
32
+ def server application_name
33
+ puts "Running code sync faye process on channel #{ options[:channel] } port #{ options[:port] }"
34
+ process = Luca::Server.new(:mount=>"/#{ options[:channel] }",:timeout=>options[:timeout])
35
+ process.listen(options[:port])
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,16 @@
1
+ module Luca
2
+ module Cli
3
+ class Watch < Thor
4
+ namespace :watch
5
+
6
+ desc "watch", "watch APPLICATION_NAME [options]"
7
+ method_options :name => :string
8
+ method_option :root, :default => Dir.pwd()
9
+
10
+ def watch application_name
11
+ watcher = Luca::Watcher.new(application_name, options)
12
+ watcher.start
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,64 @@
1
+ # The Luca::Collection can be exposed via a Rack based Luca::Collection::Endpoint.
2
+ # It allows for a cheap persistence mechanism to support front end Luca.Collection objects.
3
+ module Luca
4
+ class Collection
5
+ require 'luca/collection/redis_backend'
6
+ require 'luca/collection/file_backend'
7
+ require 'luca/collection/endpoint'
8
+
9
+ attr_accessor :backend,
10
+ :options,
11
+ :namespace
12
+
13
+ def initialize options={}
14
+ @options = options.dup
15
+ @backend = options[:backend]
16
+ @namespace = options[:namespace]
17
+
18
+ setup_backend
19
+ end
20
+
21
+ def sync method, hash={}, options={}
22
+ backend.sync(method, hash, options)
23
+ end
24
+
25
+ def index
26
+ backend.index
27
+ end
28
+
29
+ def create hash={}
30
+ backend.create(hash)
31
+ end
32
+
33
+ def update hash={}
34
+ backend.update(hash)
35
+ end
36
+
37
+ def show id
38
+ backend.show(id)
39
+ end
40
+
41
+ def destroy id
42
+ backend.destroy(id)
43
+ end
44
+
45
+ protected
46
+ def setup_backend
47
+ if backend.nil?
48
+ if options[:backend] == "file"
49
+ self.backend = Luca::Collection::FileBackend.new(namespace: namespace)
50
+ end
51
+
52
+ if options[:backend] == "redis"
53
+ self.backend = Luca::Collection::RedisBackend.new(namespace: namespace)
54
+ end
55
+
56
+ if backend.nil? and defined?(Redis)
57
+ self.backend = Luca::Collection::RedisBackend.new(namespace: namespace)
58
+ else
59
+ self.backend = Luca::Collection::FileBackend.new(namespace: namespace)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,38 @@
1
+ require 'sinatra/base'
2
+ module Luca
3
+ class Collection
4
+ class Endpoint < Sinatra::Base
5
+ # Index
6
+ get "/collections/:namespace" do
7
+ @collection = Luca::Collection.new(namespace: params[:namespace])
8
+ @collection.index.to_json
9
+ end
10
+
11
+ # Show
12
+ get "/collections/:namespace/:id" do
13
+ @collection = Luca::Collection.new(namespace: params[:namespace])
14
+ @collection.show( params[:id] ).to_json
15
+ end
16
+
17
+ # Create
18
+ post "/collections/:namespace" do
19
+ @collection = Luca::Collection.new(namespace: params[:namespace])
20
+ payload = JSON.parse( request.body.read.to_s )
21
+ @collection.create(payload).to_json
22
+ end
23
+
24
+ # Update
25
+ put "/collections/:namespace/:id" do
26
+ @collection = Luca::Collection.new(namespace: params[:namespace])
27
+ payload = JSON.parse( request.body.read.to_s )
28
+ @collection.update(payload).to_json
29
+ end
30
+
31
+ # Destroy
32
+ delete "/collections/:namespace/:id" do
33
+ @collection = Luca::Collection.new(namespace: params[:namespace])
34
+ @collection.destroy(params).to_json
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,121 @@
1
+ module Luca
2
+ class Collection
3
+ class FileBackend
4
+
5
+ attr_accessor :namespace,
6
+ :required_attributes,
7
+ :file_storage,
8
+ :record_storage,
9
+ :data_dir
10
+
11
+ def initialize options={}
12
+ @options = options.dup
13
+ @namespace = options[:namespace]
14
+ @required_attributes = options[:required_attributes]
15
+ @data_dir = options[:data_dir] || File.join(::Rails.root, "db", "collections")
16
+
17
+ unless File.exists?( file_storage_location )
18
+ FileUtils.mkdir_p(data_dir)
19
+
20
+ flush_storage_to_disk
21
+ end
22
+
23
+ read_storage_from_disk
24
+ end
25
+
26
+ def flush_storage_to_disk
27
+ File.open(file_storage_location, 'w+') do |fh|
28
+ payload = JSON.generate(record_storage)
29
+ fh.puts(payload)
30
+ end
31
+ end
32
+
33
+ def read_storage_from_disk
34
+ data = IO.read( file_storage_location )
35
+ @record_storage = JSON.parse(data)
36
+ end
37
+
38
+ def file_storage_location
39
+ File.join(data_dir, "#{ namespace }.json")
40
+ end
41
+
42
+ def sync method, hash={}, options={}
43
+ if method == "read" and hash[:id].nil?
44
+ return index()
45
+ end
46
+
47
+ if method == "read" and !hash[:id].nil?
48
+ return show( hash[:id] )
49
+ end
50
+
51
+ if method == "create"
52
+ return create( hash )
53
+ end
54
+
55
+ if method == "update"
56
+ return update( hash )
57
+ end
58
+
59
+ if method == "delete"
60
+ return destroy( hash )
61
+ end
62
+ end
63
+
64
+ alias_method :backbone_sync, :sync
65
+
66
+ def record_storage
67
+ @record_storage ||= {
68
+ :namespace => namespace,
69
+ :id_counter => 0,
70
+ :records => []
71
+ }
72
+
73
+ @record_storage.symbolize_keys!
74
+ @record_storage
75
+ end
76
+
77
+ def records
78
+ Array(record_storage[:records])
79
+ end
80
+
81
+ def index
82
+ records
83
+ end
84
+
85
+ def show id
86
+ record = records.detect {|r| r[:id].to_s == id.to_s }
87
+ record.symbolize_keys!
88
+ record
89
+ end
90
+
91
+ def allocate_id
92
+ record_storage[:id_counter] += 1
93
+ end
94
+
95
+ def create attributes={}
96
+ attributes.symbolize_keys!
97
+ attributes[:id] ||= allocate_id
98
+ records << attributes
99
+ flush_storage_to_disk
100
+ {success:true,id:attributes[:id],record:attributes}
101
+ end
102
+
103
+ def update attributes={}
104
+ attributes.symbolize_keys!
105
+ record = show(attributes[:id])
106
+ record.merge! attributes
107
+ flush_storage_to_disk
108
+ {success:true,record:record}
109
+ end
110
+
111
+ def destroy id
112
+ records.reject! do |record|
113
+ record[:id] == id
114
+ end
115
+ flush_storage_to_disk
116
+ {success:true}
117
+ end
118
+
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,153 @@
1
+ # This is intended to provide a cheap, throw-away persistence solution
2
+ # for luca collections. Based on redis.
3
+ #
4
+ # it provides a Backbone.sync adapter and API endpoint for accessing it.
5
+ #
6
+ # It is used to make luca.collections persistent for
7
+ # multiple users. Not intended to be used in production or for any apps
8
+ # which require data integrity.
9
+
10
+ require 'json'
11
+
12
+ module Luca
13
+ class Collection
14
+ class RedisBackend
15
+
16
+ def self.default_redis
17
+ require 'redis'
18
+ @default_redis ||= Redis.new host: "localhost", port: 6379, db: 5
19
+ end
20
+
21
+ attr_accessor :namespace,
22
+ :redis,
23
+ :id_storage,
24
+ :required_attributes,
25
+ :redis_database
26
+
27
+ def initialize options={}
28
+ @namespace = options[:namespace].to_s
29
+ @redis = options[:redis] || Luca::Collection::RedisBackend.default_redis
30
+ @id_storage = options[:id_storage] ||= "#{ @namespace }:ids"
31
+ @required_attributes = options[:required_attributes] || []
32
+
33
+ validate_redis_connection
34
+ end
35
+
36
+ def sync method, hash={}, options={}
37
+ if method == "read" and !hash[:id].nil?
38
+ return index()
39
+ end
40
+
41
+ if method == "read" and !hash[:id].nil?
42
+ return show( hash[:id] )
43
+ end
44
+
45
+ if method == "create"
46
+ return create( hash )
47
+ end
48
+
49
+ if method == "update"
50
+ return update( hash )
51
+ end
52
+
53
+ if method == "delete"
54
+ return destroy( hash )
55
+ end
56
+ end
57
+
58
+ alias_method :backbone_sync, :sync
59
+
60
+ def validate_redis_connection
61
+ unless @redis
62
+
63
+ end
64
+
65
+ unless @redis.respond_to?(:get) and @redis.respond_to?(:incr) and @redis.respond_to?(:mget)
66
+ throw "Must specify a valid redis instance."
67
+ end
68
+ end
69
+
70
+ def record_ids
71
+ Array(redis.smembers( id_storage )).map {|id| "#{ namespace }/#{ id }"}
72
+ end
73
+
74
+ def clear!
75
+ return unless record_ids.length > 0
76
+ redis.del( *record_ids )
77
+ redis.del( id_storage )
78
+ end
79
+
80
+ def generate_id id_base=nil
81
+ id_base ||= id_storage
82
+ redis.incr("next:#{ id_base }:id")
83
+ end
84
+
85
+ def index search=nil
86
+ return [] unless record_ids.length > 0
87
+
88
+ redis.mget( *record_ids ).map {|serialized| JSON.parse(serialized) rescue nil }.compact
89
+ end
90
+
91
+ def show id
92
+ record = redis.get("#{ namespace }/#{ id }")
93
+ JSON.parse( record ) if record
94
+ end
95
+
96
+ def create hash
97
+ hash.symbolize_keys!
98
+
99
+ if required_attributes.any? {|attribute| hash[attribute].nil?}
100
+ return {success: false, error:"Missing required attributes."}
101
+ end
102
+
103
+ next_id = hash[:id] ||= generate_id
104
+
105
+ serialized = JSON.generate(hash)
106
+ response = redis.set "#{ namespace }/#{ next_id }", serialized
107
+
108
+ if response == "OK"
109
+ redis.sadd id_storage, hash[:id]
110
+ return {success: true, id: hash[:id], record: hash}
111
+ else
112
+ return {success: false, error:"Error adding record in data store."}
113
+ end
114
+ end
115
+
116
+ def destroy hash
117
+ hash.symbolize_keys!
118
+
119
+ stored = redis.get("#{ namespace }/#{ hash[:id] }")
120
+
121
+ if stored
122
+ redis.del "#{ namespace }/#{ hash[:id] }"
123
+ return {success: true}
124
+ else
125
+ return {success: false, error:"Could not find record with #{ hash[:id] }"}
126
+ end
127
+ end
128
+
129
+ def update hash
130
+ hash.symbolize_keys!
131
+
132
+ if required_attributes.any? {|attribute| hash[attribute].nil?}
133
+ return {success: false, error:"Missing required attributes."}
134
+ end
135
+
136
+ stored = redis.get("#{ namespace }/#{ hash[:id] }")
137
+
138
+ if stored.nil?
139
+ return {success: false, error:"Could not find record with #{ hash[:id] }"}
140
+ end
141
+
142
+ serialized = JSON.generate(hash)
143
+ result = redis.set "#{ namespace }/#{ hash[:id] }", serialized
144
+
145
+ if result == "OK"
146
+ return {success: true}
147
+ else
148
+ return {success: false, error:"Error adding record in data store."}
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,61 @@
1
+ module Luca
2
+ class CompiledAsset
3
+ class << self
4
+ attr_accessor :coffeescript_assets,
5
+ :sass_assets,
6
+ :scss_assets,
7
+ :less_assets,
8
+ :markdown_assets,
9
+ :asset_stores_setup
10
+ end
11
+
12
+ self.asset_stores_setup = false
13
+
14
+ def self.setup_asset_stores
15
+ return if self.asset_stores_setup == true
16
+
17
+ self.coffeescript_assets = Luca::Collection.new(namespace:"coffeescripts",backend:"file")
18
+ self.sass_assets = Luca::Collection.new(namespace:"sass_stylesheets",backend:"file")
19
+ self.scss_assets = Luca::Collection.new(namespace:"scss_stylesheets",backend:"file")
20
+ self.less_assets = Luca::Collection.new(namespace:"less_stylesheets",backend:"file")
21
+ self.markdown_assets = Luca::Collection.new(namespace:"markdown_assets",backend:"file")
22
+ self.asset_stores_setup = true
23
+ end
24
+
25
+ attr_accessor :type, :asset
26
+
27
+ def initialize type, asset
28
+ CompiledAsset.setup_asset_stores
29
+ @type = type
30
+ @asset = asset
31
+ end
32
+
33
+ def compiler
34
+ @compiler ||= AssetCompiler.new(input: asset['input'], type: type)
35
+ end
36
+
37
+ def output
38
+ compiler.output
39
+ end
40
+
41
+ def mime_type
42
+ if type == "coffeescript" || type == "haml" || type == "mustache"
43
+ "text/javascript"
44
+ elsif type == "markdown"
45
+ "text/html"
46
+ else
47
+ "text/css"
48
+ end
49
+ end
50
+
51
+ def self.find_by_type_and_id type, id
52
+ if ["markdown", "haml","coffeescript","sass","scss","less"].include?(type)
53
+ asset = self.send("#{ type }_assets".to_sym)
54
+ asset = asset && asset.show(:id)
55
+ if !asset.nil?
56
+ new(type, asset)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end