spontaneous 0.2.0.alpha2 → 0.2.0.alpha3
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.
- data/Gemfile +3 -40
- data/Rakefile +29 -41
- data/Readme.markdown +21 -8
- data/application/css/add_alias_dialogue.css.scss +79 -0
- data/application/css/{v2.scss → core.css.scss} +537 -550
- data/application/css/{definitions.scss → definitions.css.scss} +121 -33
- data/application/css/dialogue.css.scss +409 -0
- data/application/css/{editing.scss → editing.css.scss} +25 -262
- data/application/css/font.css.scss +8 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_222222_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_228ef1_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ef8c08_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffd27a_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffffff_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/ui-lightness.css.scss +565 -0
- data/application/css/{login.scss → login.css.scss} +4 -4
- data/application/css/meta.css.scss +331 -0
- data/application/css/{popover.scss → popover.css.scss} +9 -8
- data/application/css/{schema_error.scss → schema_error.css.scss} +4 -4
- data/application/css/spontaneous.css +5 -0
- data/application/css/unsupported.css.scss +42 -0
- data/application/js/add_alias_dialogue.js +72 -10
- data/application/js/ajax.js +50 -16
- data/application/js/compatibility.js +19 -15
- data/application/js/content.js +39 -36
- data/application/js/content_area.js +53 -5
- data/application/js/dialogue.js +17 -0
- data/application/js/dom.js +1 -1
- data/application/js/edit_panel.js +23 -8
- data/application/js/extensions.js +7 -2
- data/application/js/field_preview.js +2 -1
- data/application/js/field_types/date_field.js +11 -8
- data/application/js/field_types/file_field.js +188 -9
- data/application/js/field_types/image_field.js +46 -29
- data/application/js/field_types/markdown_field.js +57 -14
- data/application/js/field_types/select_field.js +72 -0
- data/application/js/field_types/string_field.js +8 -0
- data/application/js/field_types/webvideo_field.js +8 -0
- data/application/js/init.js +1 -7
- data/application/js/location.js +41 -13
- data/application/js/login.js +3 -0
- data/application/js/meta_view/user_admin.js +543 -0
- data/application/js/meta_view.js +1 -0
- data/application/js/metadata.js +20 -0
- data/application/js/page.js +17 -3
- data/application/js/page_browser.js +40 -30
- data/application/js/page_entry.js +4 -0
- data/application/js/panel/root_menu.js +66 -0
- data/application/js/popover.js +2 -2
- data/application/js/preview.js +1 -1
- data/application/js/publish.js +138 -30
- data/application/js/services.js +43 -0
- data/application/js/sharded_upload.js +2 -2
- data/application/js/spontaneous.js +64 -5
- data/application/js/state.js +20 -9
- data/application/js/top_bar.js +273 -150
- data/application/js/types.js +20 -15
- data/application/js/upload.js +1 -2
- data/application/js/user.js +18 -4
- data/application/js/vendor/date.js +104 -0
- data/application/js/vendor/jquery-ui-1.8.18.custom.min.js +356 -0
- data/application/js/views/box_view.js +15 -8
- data/application/js/views/page_piece_view.js +11 -8
- data/application/js/views/page_view.js +21 -3
- data/application/js/views/piece_view.js +19 -10
- data/application/js/views.js +3 -0
- data/application/static/chromelogo-200x52-45c7cbc93be080bea342df5fcda2ef8b.png +0 -0
- data/application/static/dot-texture-9eea29e4ac7ad9a772285252078ec127.png +0 -0
- data/application/static/editing-textarea-resize-s-b5af62365eb7e19ea4beccf7242d508e.png +0 -0
- data/application/static/editing-texture-1-42b06a3439752490988f30f2a06d5e7c.png +0 -0
- data/application/static/font/fontawesome-webfont-5c5c21100a346972a82c34c5e96ffcfe.ttf +0 -0
- data/application/static/loop_alt1-white-7894b458528e92216196cae26b4c2c96.svg +12 -0
- data/application/static/spontaneous-states-e91ec89db525c62da0105b97cdd781ce.png +0 -0
- data/application/views/index.erb +2 -2
- data/application/views/login.erb +4 -8
- data/application/views/schema_modification_error.html.erb +1 -4
- data/application/views/unsupported.erb +9 -7
- data/bin/spot +1 -1
- data/db/migrations/20110209152710_users_and_groups.rb +10 -10
- data/db/migrations/20120305112647_site_modification_time.rb +11 -0
- data/db/migrations/20120418153903_add_ownership_of_content.rb +14 -0
- data/db/migrations/20120423175416_add_pending_modifications.rb +21 -0
- data/db/migrations/20120525164947_add_field_versions.rb +27 -0
- data/lib/sequel/plugins/scoped_table_name.rb +10 -1
- data/lib/spontaneous/asset/file.rb +25 -0
- data/lib/spontaneous/asset/source.rb +28 -0
- data/lib/spontaneous/asset.rb +75 -0
- data/lib/spontaneous/box.rb +6 -4
- data/lib/spontaneous/capistrano/deploy.rb +47 -0
- data/lib/spontaneous/capistrano/sync.rb +81 -0
- data/lib/spontaneous/capistrano.rb +13 -0
- data/lib/spontaneous/change.rb +60 -68
- data/lib/spontaneous/cli/assets.rb +29 -0
- data/lib/spontaneous/cli/base.rb +0 -48
- data/lib/spontaneous/cli/console.rb +1 -1
- data/lib/spontaneous/cli/server.rb +6 -4
- data/lib/spontaneous/cli/site.rb +28 -17
- data/lib/spontaneous/cli/user.rb +107 -0
- data/lib/spontaneous/cli.rb +100 -4
- data/lib/spontaneous/collections/entry_set.rb +2 -2
- data/lib/spontaneous/collections/field_set.rb +48 -22
- data/lib/spontaneous/collections/prototype_set.rb +20 -13
- data/lib/spontaneous/constants.rb +3 -0
- data/lib/spontaneous/content.rb +22 -5
- data/lib/spontaneous/errors.rb +3 -3
- data/lib/spontaneous/extensions/array.rb +12 -0
- data/lib/spontaneous/extensions/enumerable.rb +30 -0
- data/lib/spontaneous/extensions/nil.rb +3 -1
- data/lib/spontaneous/extensions/string.rb +16 -0
- data/lib/spontaneous/field_types/date_field.rb +45 -2
- data/lib/spontaneous/field_types/field.rb +42 -9
- data/lib/spontaneous/field_types/file_field.rb +68 -0
- data/lib/spontaneous/field_types/image_field.rb +63 -0
- data/lib/spontaneous/field_types/select_field.rb +109 -0
- data/lib/spontaneous/field_types/string_field.rb +6 -1
- data/lib/spontaneous/field_types/webvideo_field.rb +85 -27
- data/lib/spontaneous/field_types.rb +1 -1
- data/lib/spontaneous/field_version.rb +8 -0
- data/lib/spontaneous/generators/page.rb +1 -1
- data/lib/spontaneous/generators/site/Capfile.tt +1 -4
- data/lib/spontaneous/generators/site/Gemfile.tt +13 -6
- data/lib/spontaneous/generators/site/config/deploy.rb.tt +28 -0
- data/lib/spontaneous/generators/site/config/environments/production.rb.tt +7 -2
- data/lib/spontaneous/generators/site.rb +1 -0
- data/lib/spontaneous/json.rb +34 -11
- data/lib/spontaneous/layout.rb +22 -0
- data/lib/spontaneous/media/file.rb +4 -0
- data/lib/spontaneous/output/assets/compression.rb +58 -0
- data/lib/spontaneous/output/assets.rb +32 -0
- data/lib/spontaneous/output/context.rb +179 -0
- data/lib/spontaneous/output/format/html.rb +5 -0
- data/lib/spontaneous/output/format/plain.rb +5 -0
- data/lib/spontaneous/output/format.rb +180 -0
- data/lib/spontaneous/output/helpers/classes_helper.rb +18 -0
- data/lib/spontaneous/{render/helpers/html_helper.rb → output/helpers/conditional_comment_helper.rb} +3 -12
- data/lib/spontaneous/output/helpers/script_helper.rb +73 -0
- data/lib/spontaneous/output/helpers/stylesheet_helper.rb +61 -0
- data/lib/spontaneous/output/helpers.rb +28 -0
- data/lib/spontaneous/output/template/engine.rb +59 -0
- data/lib/spontaneous/output/template/renderer.rb +153 -0
- data/lib/spontaneous/output/template.rb +21 -0
- data/lib/spontaneous/output.rb +163 -0
- data/lib/spontaneous/page.rb +2 -1
- data/lib/spontaneous/paths.rb +6 -1
- data/lib/spontaneous/permissions/access_key.rb +5 -5
- data/lib/spontaneous/permissions/user.rb +81 -35
- data/lib/spontaneous/permissions/user_level.rb +26 -22
- data/lib/spontaneous/plugins/aliases.rb +76 -12
- data/lib/spontaneous/plugins/allowed_types.rb +60 -18
- data/lib/spontaneous/plugins/application/paths.rb +0 -28
- data/lib/spontaneous/plugins/application/system.rb +35 -0
- data/lib/spontaneous/plugins/boxes.rb +4 -0
- data/lib/spontaneous/plugins/content_groups.rb +16 -0
- data/lib/spontaneous/plugins/entries.rb +50 -30
- data/lib/spontaneous/plugins/fields.rb +15 -0
- data/lib/spontaneous/plugins/layouts.rb +8 -2
- data/lib/spontaneous/plugins/modifications.rb +228 -0
- data/lib/spontaneous/plugins/page/formats.rb +67 -42
- data/lib/spontaneous/plugins/page/request.rb +10 -0
- data/lib/spontaneous/plugins/page/site_timestamps.rb +28 -0
- data/lib/spontaneous/plugins/paths.rb +15 -3
- data/lib/spontaneous/plugins/publishing.rb +124 -45
- data/lib/spontaneous/plugins/render.rb +13 -8
- data/lib/spontaneous/plugins/schema_hierarchy.rb +18 -6
- data/lib/spontaneous/plugins/site/helpers.rb +53 -0
- data/lib/spontaneous/plugins/site/hooks.rb +50 -0
- data/lib/spontaneous/plugins/site/map.rb +1 -1
- data/lib/spontaneous/plugins/site/paths.rb +13 -0
- data/lib/spontaneous/plugins/site/publishing.rb +6 -2
- data/lib/spontaneous/plugins/site/{revisions.rb → state.rb} +5 -1
- data/lib/spontaneous/plugins/site/storage.rb +4 -0
- data/lib/spontaneous/plugins/site/url.rb +15 -0
- data/lib/spontaneous/plugins/site_map.rb +13 -3
- data/lib/spontaneous/plugins/styles.rb +5 -1
- data/lib/spontaneous/plugins/visibility.rb +39 -12
- data/lib/spontaneous/prototypes/box_prototype.rb +4 -0
- data/lib/spontaneous/prototypes/field_prototype.rb +15 -10
- data/lib/spontaneous/publishing/event_client.rb +46 -0
- data/lib/spontaneous/publishing/immediate.rb +81 -44
- data/lib/spontaneous/publishing/simultaneous.rb +23 -6
- data/lib/spontaneous/publishing.rb +4 -3
- data/lib/spontaneous/rack/around_back.rb +1 -5
- data/lib/spontaneous/rack/around_front.rb +4 -4
- data/lib/spontaneous/rack/around_preview.rb +4 -3
- data/lib/spontaneous/rack/assets.rb +81 -54
- data/lib/spontaneous/rack/authentication.rb +0 -1
- data/lib/spontaneous/rack/back.rb +160 -72
- data/lib/spontaneous/rack/cookie_authentication.rb +2 -2
- data/lib/spontaneous/rack/css.rb +18 -15
- data/lib/spontaneous/rack/event_source.rb +9 -21
- data/lib/spontaneous/rack/fiber_pool.rb +26 -0
- data/lib/spontaneous/rack/front.rb +12 -4
- data/lib/spontaneous/rack/helpers.rb +35 -13
- data/lib/spontaneous/rack/js.rb +41 -0
- data/lib/spontaneous/rack/public.rb +34 -44
- data/lib/spontaneous/rack/sse.rb +18 -0
- data/lib/spontaneous/rack/static.rb +3 -0
- data/lib/spontaneous/rack/user_admin.rb +100 -0
- data/lib/spontaneous/rack/user_helpers.rb +1 -1
- data/lib/spontaneous/rack.rb +6 -2
- data/lib/spontaneous/schema.rb +31 -4
- data/lib/spontaneous/search/index.rb +19 -3
- data/lib/spontaneous/search/results.rb +1 -1
- data/lib/spontaneous/sequel.rb +17 -0
- data/lib/spontaneous/site.rb +11 -4
- data/lib/spontaneous/state.rb +11 -0
- data/lib/spontaneous/storage/cloud.rb +4 -0
- data/lib/spontaneous/storage/local.rb +11 -0
- data/lib/spontaneous/style.rb +2 -2
- data/lib/spontaneous/tasks/database.rake +21 -22
- data/lib/spontaneous/utils/database/mysql_dumper.rb +4 -0
- data/lib/spontaneous/utils/database/postgres_dumper.rb +78 -0
- data/lib/spontaneous/utils/database.rb +6 -3
- data/lib/spontaneous/utils/smart_quotes.rb +499 -0
- data/lib/spontaneous/utils/smush_it.rb +66 -0
- data/lib/spontaneous/utils.rb +3 -1
- data/lib/spontaneous/version.rb +2 -2
- data/lib/spontaneous.rb +25 -29
- data/spontaneous.gemspec +186 -106
- data/test/experimental/test_features.rb +1 -1
- data/test/fixtures/asset_pipeline/application/css/basic.css.scss +4 -0
- data/test/fixtures/asset_pipeline/application/css/complex.css.scss.erb +6 -0
- data/test/fixtures/asset_pipeline/application/css/simple.css +3 -0
- data/test/fixtures/asset_pipeline/application/css/spontaneous.css +7 -0
- data/test/fixtures/asset_pipeline/application/css/subdir/complex.css.scss.erb +6 -0
- data/test/fixtures/asset_pipeline/application/css/subdir/library.css.scss +1 -0
- data/test/fixtures/asset_pipeline/application/css/subdir/simple.css +3 -0
- data/test/fixtures/asset_pipeline/application/js/basic.js.coffee +1 -0
- data/test/fixtures/asset_pipeline/application/js/complex.js.coffee.erb +1 -0
- data/test/fixtures/asset_pipeline/application/js/login.js +1 -0
- data/test/fixtures/asset_pipeline/application/js/require.js +1 -0
- data/test/fixtures/asset_pipeline/application/js/simple.js +1 -0
- data/test/fixtures/asset_pipeline/application/js/spontaneous.js +5 -0
- data/test/fixtures/asset_pipeline/application/js/subdir/complex.js.coffee.erb +1 -0
- data/test/fixtures/asset_pipeline/application/js/subdir/library.js.coffee +1 -0
- data/test/fixtures/asset_pipeline/application/js/subdir/simple.js +1 -0
- data/test/fixtures/asset_pipeline/application/js/vendor/jquery.js +1 -0
- data/test/fixtures/asset_pipeline/application/static/dot-texture.png +0 -0
- data/test/fixtures/asset_pipeline/application/static/subdir/px.gif +0 -0
- data/test/fixtures/assets/public1/css/a.scss +1 -0
- data/test/fixtures/assets/public1/js/a.js +1 -0
- data/test/fixtures/assets/public1/js/m.coffee +1 -0
- data/test/fixtures/assets/public2/css/b.scss +1 -0
- data/test/fixtures/assets/public2/css/c.css +1 -0
- data/test/fixtures/assets/public2/js/b.js +1 -0
- data/test/fixtures/assets/public2/js/c.js +1 -0
- data/test/fixtures/assets/public2/js/n.coffee +1 -0
- data/test/fixtures/back/config/user_levels.yml +3 -0
- data/test/fixtures/back/public/js/coffeescript.coffee +1 -0
- data/test/fixtures/back/templates/layouts/standard.css.cut +1 -0
- data/test/fixtures/back/templates/layouts/standard.js.cut +1 -0
- data/test/fixtures/example_application/config/database.yml +4 -4
- data/test/fixtures/helpers/templates/layouts/standard.html.cut +1 -0
- data/test/fixtures/helpers/templates/layouts/standard.mobile.cut +1 -0
- data/test/fixtures/images/vimlogo.pdf +0 -0
- data/test/fixtures/outputs/templates/layouts/standard.atom.cut +1 -0
- data/test/fixtures/permissions/config/user_levels.yml +6 -3
- data/test/fixtures/serialisation/class_hash.yaml.erb +1 -0
- data/test/fixtures/serialisation/root_hash.yaml.erb +2 -2
- data/test/fixtures/templates/extended/grandparent.html.cut +7 -7
- data/test/fixtures/templates/extended/main.html.cut +5 -5
- data/test/fixtures/templates/extended/parent.html.cut +8 -8
- data/test/fixtures/templates/extended/partial_with_locals.html.cut +1 -1
- data/test/fixtures/templates/extended/with_includes.html.cut +6 -6
- data/test/fixtures/templates/extended/with_includes_and_locals.html.cut +6 -7
- data/test/fixtures/templates/layouts/entries.html.cut +4 -4
- data/test/fixtures/templates/layouts/standard.html.cut +1 -0
- data/test/fixtures/templates/layouts/variables.html.cut +1 -1
- data/test/fixtures/templates/publishing/templates/layouts/static.html.cut +1 -1
- data/test/fixtures/templates/publishing/templates/layouts/static.rtf.cut +1 -0
- data/test/fixtures/templates/template_class/complex_template.html.cut +2 -2
- data/test/fixtures/templates/template_class/complex_template.pdf.cut +2 -2
- data/test/fixtures/templates/template_class/default_template_style.html.cut +1 -1
- data/test/fixtures/templates/template_class/images_with_template.html.cut +2 -2
- data/test/fixtures/templates/template_class/slots_template.html.cut +2 -2
- data/test/fixtures/templates/template_class/slots_template.pdf.cut +2 -2
- data/test/fixtures/user_manager/config/user_levels.yml +9 -0
- data/test/functional/test_application.rb +7 -7
- data/test/functional/test_back.rb +352 -97
- data/test/functional/test_front.rb +71 -20
- data/test/functional/test_user_manager.rb +284 -0
- data/test/javascript/env.js +13505 -0
- data/test/javascript/test_markdown.rb +43 -3
- data/test/support/custom_matchers.rb +3 -2
- data/test/test_helper.rb +50 -9
- data/test/test_javascript.rb +13 -13
- data/test/ui_helper.rb +1 -1
- data/test/unit/test_alias.rb +79 -8
- data/test/unit/test_asset_bundler.rb +220 -0
- data/test/unit/test_assets.rb +213 -0
- data/test/unit/test_async.rb +55 -0
- data/test/unit/test_authentication.rb +52 -39
- data/test/unit/test_boxes.rb +20 -15
- data/test/unit/test_changesets.rb +261 -0
- data/test/unit/test_content.rb +73 -33
- data/test/unit/test_content_inheritance.rb +18 -18
- data/test/unit/test_extensions.rb +26 -0
- data/test/unit/test_fields.rb +303 -16
- data/test/unit/test_formats.rb +267 -34
- data/test/unit/test_helpers.rb +79 -2
- data/test/unit/test_images.rb +10 -0
- data/test/unit/test_layouts.rb +21 -13
- data/test/unit/test_modifications.rb +648 -0
- data/test/unit/test_page.rb +6 -2
- data/test/unit/test_permissions.rb +101 -27
- data/test/unit/test_piece.rb +4 -4
- data/test/unit/test_plugins.rb +3 -2
- data/test/unit/test_publishing.rb +332 -0
- data/test/unit/test_render.rb +118 -67
- data/test/unit/test_revisions.rb +546 -0
- data/test/unit/test_schema.rb +83 -1
- data/test/unit/test_search.rb +59 -0
- data/test/unit/test_serialisation.rb +2 -47
- data/test/unit/test_site.rb +217 -108
- data/test/unit/test_storage.rb +26 -0
- data/test/unit/test_structure.rb +2 -2
- data/test/unit/test_styles.rb +90 -75
- data/test/unit/test_table_scoping.rb +21 -17
- data/test/unit/test_templates.rb +75 -69
- data/test/{slow → unit}/test_visibility.rb +78 -22
- metadata +528 -221
- data/application/css/add_alias_dialogue.scss +0 -27
- data/application/css/min/14c2a35812c443001b15d8b12a4780f88c678035.css +0 -1
- data/application/css/min/565d4c25e82148acb01c45c8d675b37a08676d77.css +0 -1
- data/application/css/min/84dbe894ea96eafd321c30823d630817bfc4b03b.css +0 -1
- data/application/css/spontaneous.scss +0 -111
- data/application/css/unsupported.scss +0 -16
- data/application/css/variables.scss +0 -80
- data/application/js/min/2a0c2962537a3181fedfff5c92596ba6d3122dc9.js +0 -3
- data/application/js/min/4cf1c493d3379ecba5287758c61238034c0893f9.js +0 -2
- data/application/js/min/78ac6b99d96750bb6b9f9aad4cb9cd91cd03f391.js +0 -3
- data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +0 -2
- data/application/js/min/c8efb9b9f7c3f6613fcebc6be60f605b6570a382.js +0 -90
- data/application/static/diagonal-texture.png +0 -0
- data/application/static/editing-0-noise.png +0 -0
- data/application/static/editing-1-noise.png +0 -0
- data/application/static/editing-texture-1.png +0 -0
- data/application/static/editing-texture.png +0 -0
- data/application/static/editing-toolbar-shadow-bottom.png +0 -0
- data/application/static/editing-toolbar-shadow-top.png +0 -0
- data/application/static/inner-glow.png +0 -0
- data/application/static/item-buttons-highlight.png +0 -0
- data/application/static/item-buttons.png +0 -0
- data/application/static/paper-texture-dark.png +0 -0
- data/application/static/plus_alt.svg +0 -8
- data/application/static/select-arrow-root.png +0 -0
- data/application/static/slot-up-arrow.png +0 -0
- data/application/static/spontaneous.png +0 -0
- data/lib/cutaneous/context_helper.rb +0 -187
- data/lib/cutaneous/preview_context.rb +0 -32
- data/lib/cutaneous/preview_renderer.rb +0 -10
- data/lib/cutaneous/publish_context.rb +0 -10
- data/lib/cutaneous/publish_renderer.rb +0 -14
- data/lib/cutaneous/publish_template.rb +0 -62
- data/lib/cutaneous/publish_token_parser.rb +0 -8
- data/lib/cutaneous/renderer.rb +0 -124
- data/lib/cutaneous/request_context.rb +0 -9
- data/lib/cutaneous/request_renderer.rb +0 -15
- data/lib/cutaneous/request_template.rb +0 -11
- data/lib/cutaneous/request_token_parser.rb +0 -9
- data/lib/cutaneous/token_parser.rb +0 -125
- data/lib/cutaneous.rb +0 -48
- data/lib/spontaneous/render/context_base.rb +0 -143
- data/lib/spontaneous/render/development_renderer.rb +0 -14
- data/lib/spontaneous/render/engine.rb +0 -19
- data/lib/spontaneous/render/format/html.rb +0 -5
- data/lib/spontaneous/render/format.rb +0 -75
- data/lib/spontaneous/render/helpers/script_helper.rb +0 -17
- data/lib/spontaneous/render/helpers/stylesheet_helper.rb +0 -16
- data/lib/spontaneous/render/helpers.rb +0 -14
- data/lib/spontaneous/render/preview_context.rb +0 -8
- data/lib/spontaneous/render/preview_renderer.rb +0 -24
- data/lib/spontaneous/render/publish_context.rb +0 -22
- data/lib/spontaneous/render/published_renderer.rb +0 -53
- data/lib/spontaneous/render/publishing_renderer.rb +0 -16
- data/lib/spontaneous/render/render_cache.rb +0 -26
- data/lib/spontaneous/render/renderer.rb +0 -50
- data/lib/spontaneous/render/request_context.rb +0 -8
- data/lib/spontaneous/render.rb +0 -214
- data/test/experimental/test_cutaneous.rb +0 -309
- data/test/fixtures/application/css/test.less +0 -5
- data/test/slow/test_publishing.rb +0 -1006
- /data/application/css/{developer.scss → developer.css.scss} +0 -0
- /data/application/js/vendor/{jquery-1.7.1.min.js → jquery.js} +0 -0
- /data/application/static/{location-arrow.png → location-arrow-c1c1d3ca472481c61a0a5f8cb289d743.png} +0 -0
- /data/application/static/{missing.png → missing-911ce6dbd9f4602e0f3fbcd7e78846a2.png} +0 -0
- /data/application/static/{orange-down-arrow.png → orange-down-arrow-395ae1929e8662b2ff0977daf12c35bb.png} +0 -0
- /data/application/static/{page-browser-next.png → page-browser-next-ce781a242c23b980b99b9db7abc20b05.png} +0 -0
- /data/application/static/{plus-box.png → plus-box-dcde74a1e496f68298c9b443caa1c5d5.png} +0 -0
- /data/application/static/{select-arrow.png → select-arrow-6e7dd3745b00e934b0d7a3250c46558b.png} +0 -0
- /data/application/static/{slot-down-arrow.png → slot-down-arrow-59ad5f5ee5b52a7ebd00bca4b3104194.png} +0 -0
- /data/application/static/{splash.png → splash-65b493a714df9b8b3ab170103401b53d.png} +0 -0
- /data/application/static/{spot.png → spot-71fab1d2f065034f5fc15e7bea2ad36c.png} +0 -0
- /data/application/static/{spot.svg → spot-8505041082d8d3bbe8d34c29dddb3b7d.svg} +0 -0
- /data/application/static/{texture.png → texture-03f7627e8264b1d607113ab32c593a58.png} +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
3
|
require 'sass'
|
|
4
|
-
require '
|
|
4
|
+
require 'sinatra/streaming'
|
|
5
|
+
require 'sprockets'
|
|
5
6
|
|
|
6
7
|
module Spontaneous
|
|
7
8
|
module Rack
|
|
@@ -19,6 +20,54 @@ module Spontaneous
|
|
|
19
20
|
@messenger
|
|
20
21
|
end
|
|
21
22
|
|
|
23
|
+
class EventSource < ServerBase
|
|
24
|
+
helpers Sinatra::Streaming
|
|
25
|
+
|
|
26
|
+
get "/", :provides => "text/event-stream" do
|
|
27
|
+
headers "X-Accel-Buffering" => "no"
|
|
28
|
+
stream(:keep_open) do |out|
|
|
29
|
+
messenger = Spontaneous::Rack::Back.messenger
|
|
30
|
+
out.errback { messenger.delete(out) }
|
|
31
|
+
out.callback { messenger.delete(out) }
|
|
32
|
+
messenger << out
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.editing_app
|
|
38
|
+
::Rack::Builder.app do
|
|
39
|
+
use Spontaneous::Rack::FiberPool, :size => 15
|
|
40
|
+
use ::Rack::Lint
|
|
41
|
+
use Spontaneous::Rack::Static, :root => Spontaneous.application_dir, :urls => %W(/static)
|
|
42
|
+
use Spontaneous::Rack::Static, :root => Spontaneous.root / "public/@spontaneous", :urls => %W(/assets)
|
|
43
|
+
use AssetsHandler
|
|
44
|
+
use UnsupportedBrowserHandler
|
|
45
|
+
use SchemaModification
|
|
46
|
+
map "/users" do
|
|
47
|
+
run UserAdmin
|
|
48
|
+
end
|
|
49
|
+
run EditingInterface
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.preview_app
|
|
54
|
+
::Rack::Builder.app do
|
|
55
|
+
use ::Rack::Lint
|
|
56
|
+
use Spontaneous::Rack::Static, :root => Spontaneous.root / "public",
|
|
57
|
+
:urls => %w[/],
|
|
58
|
+
:try => ['.html', 'index.html', '/index.html']
|
|
59
|
+
use Spontaneous::Rack::CSS, :root => Spontaneous.instance.paths.expanded(:public)
|
|
60
|
+
use Spontaneous::Rack::JS, :root => Spontaneous.instance.paths.expanded(:public)
|
|
61
|
+
run Preview
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.assets_app(dir)
|
|
66
|
+
::Sprockets::Environment.new(Spontaneous.application_dir) do |environment|
|
|
67
|
+
environment.append_path("#{dir}")
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
22
71
|
def self.application
|
|
23
72
|
messenger = self.messenger
|
|
24
73
|
app = ::Rack::Builder.new do
|
|
@@ -45,9 +94,6 @@ module Spontaneous
|
|
|
45
94
|
# Needs testing...
|
|
46
95
|
# ###################
|
|
47
96
|
|
|
48
|
-
use Spontaneous::Rack::Static, :root => Spontaneous.root / "public",
|
|
49
|
-
:urls => %w[/],
|
|
50
|
-
:try => ['.html', 'index.html', '/index.html']
|
|
51
97
|
|
|
52
98
|
################### REMOVE THIS
|
|
53
99
|
# map "#{NAMESPACE}/lock" do
|
|
@@ -84,16 +130,23 @@ module Spontaneous
|
|
|
84
130
|
map "#{NAMESPACE}/events" do
|
|
85
131
|
use CookieAuthentication
|
|
86
132
|
use QueryAuthentication
|
|
87
|
-
run
|
|
133
|
+
run EventSource
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
map "#{NAMESPACE}/event" do
|
|
137
|
+
run EventListener
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
map "#{NAMESPACE}/css" do
|
|
141
|
+
run Spontaneous::Rack::Back.assets_app("css")
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
map "#{NAMESPACE}/js" do
|
|
145
|
+
run Spontaneous::Rack::Back.assets_app("js")
|
|
88
146
|
end
|
|
89
147
|
|
|
90
148
|
map NAMESPACE do
|
|
91
|
-
|
|
92
|
-
use Spontaneous::Rack::Static, :root => Spontaneous.application_dir, :urls => %W(/static /js)
|
|
93
|
-
use AssetsHandler
|
|
94
|
-
use UnsupportedBrowserHandler
|
|
95
|
-
use SchemaModification
|
|
96
|
-
run EditingInterface
|
|
149
|
+
run Spontaneous::Rack::Back.editing_app
|
|
97
150
|
end
|
|
98
151
|
|
|
99
152
|
map "/media" do
|
|
@@ -102,13 +155,19 @@ module Spontaneous
|
|
|
102
155
|
end
|
|
103
156
|
|
|
104
157
|
map "/" do
|
|
105
|
-
|
|
106
|
-
use Spontaneous::Rack::CSS, :root => Spontaneous.instance.paths.expanded(:public)
|
|
107
|
-
run Preview
|
|
158
|
+
run Spontaneous::Rack::Back.preview_app
|
|
108
159
|
end
|
|
109
160
|
end
|
|
110
161
|
end
|
|
111
162
|
|
|
163
|
+
class EventListener < ServerBase
|
|
164
|
+
put "/" do
|
|
165
|
+
Back.messenger.deliver_event(SSE.new(params))
|
|
166
|
+
200
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
|
|
112
171
|
class EditingBase < ServerBase
|
|
113
172
|
set :views, Proc.new { Spontaneous.application_dir + '/views' }
|
|
114
173
|
set :environment, Proc.new { Spontaneous.env }
|
|
@@ -117,10 +176,6 @@ module Spontaneous
|
|
|
117
176
|
helpers Spontaneous::Rack::UserHelpers
|
|
118
177
|
helpers Spontaneous::Rack::Helpers
|
|
119
178
|
|
|
120
|
-
def json(response)
|
|
121
|
-
content_type 'application/json', :charset => 'utf-8'
|
|
122
|
-
response.serialise_http(user)
|
|
123
|
-
end
|
|
124
179
|
end
|
|
125
180
|
|
|
126
181
|
class UnsupportedBrowserHandler < EditingBase
|
|
@@ -199,6 +254,7 @@ module Spontaneous
|
|
|
199
254
|
Content.db.transaction {
|
|
200
255
|
dataset = lock ? Content.for_update : Content
|
|
201
256
|
content = dataset.first(:id => params[:id])
|
|
257
|
+
content.current_editor = user
|
|
202
258
|
halt 404 if content.nil?
|
|
203
259
|
if box_id = Spontaneous.schema.uids[params[:box_id]]
|
|
204
260
|
box = content.boxes.detect { |b| b.schema_id == box_id }
|
|
@@ -209,16 +265,30 @@ module Spontaneous
|
|
|
209
265
|
}
|
|
210
266
|
end
|
|
211
267
|
|
|
268
|
+
def set_authentication_cookie(key)
|
|
269
|
+
response.set_cookie(AUTH_COOKIE, {
|
|
270
|
+
:value => key.key_id,
|
|
271
|
+
:path => '/',
|
|
272
|
+
:secure => request.ssl?,
|
|
273
|
+
:httponly => true
|
|
274
|
+
})
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def unset_authentication_cookie
|
|
278
|
+
response.delete_cookie(AUTH_COOKIE, {
|
|
279
|
+
:path => '/',
|
|
280
|
+
:secure => request.ssl?,
|
|
281
|
+
:httponly => true
|
|
282
|
+
})
|
|
283
|
+
end
|
|
284
|
+
|
|
212
285
|
post "/reauthenticate" do
|
|
286
|
+
origin = "#{NAMESPACE}#{(params[:origin] || "").gsub(%r[^#{NAMESPACE}], "")}"
|
|
213
287
|
if key = Spot::Permissions::AccessKey.authenticate(params[:api_key])
|
|
214
|
-
|
|
215
|
-
:value => key.key_id,
|
|
216
|
-
:path => '/'
|
|
217
|
-
})
|
|
218
|
-
origin = "#{NAMESPACE}#{params[:origin]}"
|
|
288
|
+
set_authentication_cookie(key)
|
|
219
289
|
redirect origin, 302
|
|
220
290
|
else
|
|
221
|
-
show_login_page( :invalid_key => true )
|
|
291
|
+
show_login_page( :invalid_key => true, :origin => origin )
|
|
222
292
|
end
|
|
223
293
|
end
|
|
224
294
|
|
|
@@ -226,11 +296,8 @@ module Spontaneous
|
|
|
226
296
|
login = params[:user][:login]
|
|
227
297
|
password = params[:user][:password]
|
|
228
298
|
origin = "#{NAMESPACE}#{params[:origin]}"
|
|
229
|
-
if key = Spontaneous::Permissions::User.authenticate(login, password)
|
|
230
|
-
|
|
231
|
-
:value => key.key_id,
|
|
232
|
-
:path => '/'
|
|
233
|
-
})
|
|
299
|
+
if key = Spontaneous::Permissions::User.authenticate(login, password, env["REMOTE_ADDR"])
|
|
300
|
+
set_authentication_cookie(key)
|
|
234
301
|
if request.xhr?
|
|
235
302
|
json({
|
|
236
303
|
:key => key.key_id,
|
|
@@ -244,6 +311,11 @@ module Spontaneous
|
|
|
244
311
|
end
|
|
245
312
|
end
|
|
246
313
|
|
|
314
|
+
post "/logout" do
|
|
315
|
+
unset_authentication_cookie
|
|
316
|
+
401
|
|
317
|
+
end
|
|
318
|
+
|
|
247
319
|
get '/?' do
|
|
248
320
|
erb :index
|
|
249
321
|
end
|
|
@@ -256,29 +328,20 @@ module Spontaneous
|
|
|
256
328
|
json Site.root
|
|
257
329
|
end
|
|
258
330
|
|
|
259
|
-
get '/user' do
|
|
260
|
-
json(user)
|
|
261
|
-
end
|
|
262
|
-
# TODO: check for perms on the particular bit of content
|
|
263
|
-
# and pass user level into returned JSON
|
|
264
331
|
get '/page/:id' do
|
|
265
332
|
content_for_request { |content| json(content)}
|
|
266
333
|
end
|
|
267
334
|
|
|
268
|
-
get '/
|
|
269
|
-
json
|
|
335
|
+
get '/metadata' do
|
|
336
|
+
json({
|
|
337
|
+
:types => Site.schema.export(user),
|
|
338
|
+
:user => user.export,
|
|
339
|
+
:services => (Site.config.services || [])
|
|
340
|
+
})
|
|
270
341
|
end
|
|
271
342
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
# json klass
|
|
275
|
-
# end
|
|
276
|
-
|
|
277
|
-
get '/map' do
|
|
278
|
-
json Site.map
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
get '/map/:id' do
|
|
343
|
+
get '/map/?:id?' do
|
|
344
|
+
last_modified(Site.modified_at)
|
|
282
345
|
map = Site.map(params[:id])
|
|
283
346
|
if map
|
|
284
347
|
json(map)
|
|
@@ -288,6 +351,7 @@ module Spontaneous
|
|
|
288
351
|
end
|
|
289
352
|
|
|
290
353
|
get '/location*' do
|
|
354
|
+
last_modified(Site.modified_at)
|
|
291
355
|
if Page.count == 0
|
|
292
356
|
406
|
|
293
357
|
else
|
|
@@ -301,7 +365,6 @@ module Spontaneous
|
|
|
301
365
|
if Site.root.nil?
|
|
302
366
|
type = Spontaneous.schema[params[:type]]
|
|
303
367
|
root = type.create(:title => "Home")
|
|
304
|
-
Spontaneous::Change.push(root)
|
|
305
368
|
json({:id => root.id})
|
|
306
369
|
else
|
|
307
370
|
403
|
|
@@ -314,6 +377,13 @@ module Spontaneous
|
|
|
314
377
|
end
|
|
315
378
|
end
|
|
316
379
|
|
|
380
|
+
get '/options/:field_sid/:id/?:box_id?' do
|
|
381
|
+
content_for_request do |content, box|
|
|
382
|
+
field = (box || content).fields.sid(params[:field_sid])
|
|
383
|
+
json(field.option_list)
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
317
387
|
def generate_conflict_list(content)
|
|
318
388
|
field_versions = params[:fields]
|
|
319
389
|
conflicts = []
|
|
@@ -380,7 +450,7 @@ module Spontaneous
|
|
|
380
450
|
if target.field_writable?(user, field.name)
|
|
381
451
|
# version = params[:version].to_i
|
|
382
452
|
# if version == field.version
|
|
383
|
-
field.
|
|
453
|
+
field.value = file
|
|
384
454
|
content.save
|
|
385
455
|
json(field.export(user))
|
|
386
456
|
# else
|
|
@@ -404,7 +474,7 @@ module Spontaneous
|
|
|
404
474
|
instance = type.new
|
|
405
475
|
box.insert(position, instance)
|
|
406
476
|
field = instance.field_for_mime_type(file[:type])
|
|
407
|
-
field.
|
|
477
|
+
field.value = file
|
|
408
478
|
instance.save
|
|
409
479
|
content.save
|
|
410
480
|
json({
|
|
@@ -422,8 +492,9 @@ module Spontaneous
|
|
|
422
492
|
content_for_request(true) do |content, box|
|
|
423
493
|
position = (params[:position] || 0).to_i
|
|
424
494
|
type = Spontaneous.schema[params[:type_name]]#.constantize
|
|
495
|
+
|
|
425
496
|
if box.writable?(user, type)
|
|
426
|
-
instance = type.new
|
|
497
|
+
instance = type.new(:created_by => user)
|
|
427
498
|
box.insert(position, instance)
|
|
428
499
|
content.save
|
|
429
500
|
json({
|
|
@@ -469,6 +540,14 @@ module Spontaneous
|
|
|
469
540
|
end
|
|
470
541
|
end
|
|
471
542
|
|
|
543
|
+
post '/slug/:id/titlesync' do
|
|
544
|
+
content_for_request do |page|
|
|
545
|
+
page.slug = page.title.unprocessed_value
|
|
546
|
+
page.save
|
|
547
|
+
json({:path => page.path, :slug => page.slug })
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
|
|
472
551
|
post '/uid/:id' do
|
|
473
552
|
if user.developer?
|
|
474
553
|
content_for_request(true) do |content|
|
|
@@ -485,14 +564,21 @@ module Spontaneous
|
|
|
485
564
|
klass = Spontaneous.schema[params[:schema_id]]
|
|
486
565
|
if klass.alias?
|
|
487
566
|
content_for_request do |content, box|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
567
|
+
options = {}
|
|
568
|
+
if (query = params[:query])
|
|
569
|
+
options[:search] = Regexp.new(query, Regexp::IGNORECASE)
|
|
570
|
+
end
|
|
571
|
+
targets = klass.targets(content, box, options).map do |t|
|
|
572
|
+
{ :id => t.id,
|
|
491
573
|
:title => t.alias_title,
|
|
492
|
-
:icon => t.exported_alias_icon
|
|
493
|
-
}
|
|
574
|
+
:icon => t.exported_alias_icon }
|
|
494
575
|
end
|
|
495
|
-
json(
|
|
576
|
+
json({
|
|
577
|
+
:pages => 1,
|
|
578
|
+
:total => targets.length,
|
|
579
|
+
:page => 1,
|
|
580
|
+
:targets => targets
|
|
581
|
+
})
|
|
496
582
|
end
|
|
497
583
|
end
|
|
498
584
|
end
|
|
@@ -502,9 +588,8 @@ module Spontaneous
|
|
|
502
588
|
type = Spontaneous.schema[params[:alias_id]]
|
|
503
589
|
position = (params[:position] || 0).to_i
|
|
504
590
|
if box.writable?(user, type)
|
|
505
|
-
|
|
506
|
-
if
|
|
507
|
-
instance = type.create(:target => target)
|
|
591
|
+
instance = type.for_target(params[:target_id])
|
|
592
|
+
if instance
|
|
508
593
|
box.insert(position, instance)
|
|
509
594
|
content.save
|
|
510
595
|
json({
|
|
@@ -527,14 +612,14 @@ module Spontaneous
|
|
|
527
612
|
end
|
|
528
613
|
|
|
529
614
|
post '/publish/publish' do
|
|
530
|
-
ids = params[:
|
|
615
|
+
ids = params[:page_ids]
|
|
531
616
|
ids = ids.blank? ? [] : ids
|
|
532
|
-
|
|
533
|
-
if
|
|
617
|
+
pages = ids.map(&:to_i)
|
|
618
|
+
if pages.empty?
|
|
534
619
|
400
|
|
535
620
|
else
|
|
536
621
|
if user.level.can_publish?
|
|
537
|
-
Site.
|
|
622
|
+
Site.publish_pages(pages)
|
|
538
623
|
json({})
|
|
539
624
|
else
|
|
540
625
|
unauthorised!
|
|
@@ -579,7 +664,7 @@ module Spontaneous
|
|
|
579
664
|
# version = params[:version].to_i
|
|
580
665
|
# if version == field.version
|
|
581
666
|
Spontaneous::Media.combine_shards(params[:shards]) do |combined|
|
|
582
|
-
field.
|
|
667
|
+
field.value = {
|
|
583
668
|
:filename => params[:filename],
|
|
584
669
|
:tempfile => combined
|
|
585
670
|
}
|
|
@@ -606,7 +691,7 @@ module Spontaneous
|
|
|
606
691
|
box.insert(position, instance)
|
|
607
692
|
field = instance.field_for_mime_type(params[:mime_type])
|
|
608
693
|
Spontaneous::Media.combine_shards(params[:shards]) do |combined|
|
|
609
|
-
field.
|
|
694
|
+
field.value = {
|
|
610
695
|
:filename => params[:filename],
|
|
611
696
|
:tempfile => combined
|
|
612
697
|
}
|
|
@@ -657,11 +742,8 @@ module Spontaneous
|
|
|
657
742
|
else
|
|
658
743
|
content_type :css
|
|
659
744
|
sass_template = Spontaneous.css_dir / File.basename(file, ".css") + ".scss"
|
|
660
|
-
less_template = Spontaneous.css_dir / File.basename(file, ".css") + ".less"
|
|
661
745
|
if File.exists?(sass_template)
|
|
662
746
|
Sass::Engine.for_file(sass_template, :load_paths => [Spontaneous.css_dir], :filename => sass_template, :cache => false).render
|
|
663
|
-
elsif File.exists?(less_template)
|
|
664
|
-
Less::Engine.new(File.new(less_template)).to_css
|
|
665
747
|
else
|
|
666
748
|
raise Sinatra::NotFound
|
|
667
749
|
end
|
|
@@ -673,12 +755,12 @@ module Spontaneous
|
|
|
673
755
|
end
|
|
674
756
|
|
|
675
757
|
class Preview < Sinatra::Base
|
|
758
|
+
use CookieAuthentication
|
|
759
|
+
use AroundPreview
|
|
676
760
|
use Reloader if Site.config.reload_classes
|
|
677
761
|
include Spontaneous::Rack::Public
|
|
678
762
|
helpers Spontaneous::Rack::UserHelpers
|
|
679
763
|
|
|
680
|
-
use CookieAuthentication
|
|
681
|
-
use AroundPreview
|
|
682
764
|
|
|
683
765
|
set :views, Proc.new { Spontaneous.application_dir + '/views' }
|
|
684
766
|
|
|
@@ -688,12 +770,17 @@ module Spontaneous
|
|
|
688
770
|
}
|
|
689
771
|
|
|
690
772
|
|
|
773
|
+
# Forward all GETs to the page resolution method
|
|
691
774
|
get '*' do
|
|
692
|
-
|
|
775
|
+
render_path(params[:splat][0])
|
|
776
|
+
end
|
|
693
777
|
|
|
694
|
-
|
|
778
|
+
# Forward all POSTs to the page resolution method
|
|
779
|
+
post '*' do
|
|
780
|
+
render_path(params[:splat][0])
|
|
695
781
|
end
|
|
696
782
|
|
|
783
|
+
# Override the S::Rack::Public method to add in some cache-busting headers
|
|
697
784
|
def render_page(page, format = :html, local_params = {})
|
|
698
785
|
now = Time.now.to_formatted_s(:rfc822)
|
|
699
786
|
response.headers[HTTP_EXPIRES] = now
|
|
@@ -706,3 +793,4 @@ module Spontaneous
|
|
|
706
793
|
end
|
|
707
794
|
end
|
|
708
795
|
end
|
|
796
|
+
|
|
@@ -11,14 +11,14 @@ module Spontaneous
|
|
|
11
11
|
if login = Site.config.auto_login
|
|
12
12
|
user = Spontaneous::Permissions::User[:login => login]
|
|
13
13
|
if user.access_keys.empty?
|
|
14
|
-
user.generate_access_key
|
|
14
|
+
user.generate_access_key(env["REMOTE_ADDR"])
|
|
15
15
|
else
|
|
16
16
|
user.access_keys.first
|
|
17
17
|
end
|
|
18
18
|
else
|
|
19
19
|
request = ::Rack::Request.new(env)
|
|
20
20
|
api_key = request.cookies[Spontaneous::Rack::AUTH_COOKIE]
|
|
21
|
-
if api_key && key = Spontaneous::Permissions::AccessKey.authenticate(api_key)
|
|
21
|
+
if api_key && key = Spontaneous::Permissions::AccessKey.authenticate(api_key, env["REMOTE_ADDR"])
|
|
22
22
|
key
|
|
23
23
|
else
|
|
24
24
|
nil
|
data/lib/spontaneous/rack/css.rb
CHANGED
|
@@ -4,24 +4,28 @@ require 'sass'
|
|
|
4
4
|
|
|
5
5
|
module Spontaneous::Rack
|
|
6
6
|
class CSS
|
|
7
|
+
CSS_EXTENSION = /\.css$/o
|
|
8
|
+
|
|
7
9
|
def initialize(app, options = {})
|
|
8
|
-
@
|
|
9
|
-
@root = options.delete(:root)
|
|
10
|
+
@roots = options[:root]
|
|
10
11
|
@app = app
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def call(env)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
try_sass(env[S::PATH_INFO]) or @app.call(env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def try_sass(request_path)
|
|
19
|
+
return nil unless request_path =~ CSS_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_sass_template(template) if File.exists?(template)
|
|
24
27
|
end
|
|
28
|
+
nil
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
def render_sass_template(template)
|
|
@@ -35,9 +39,8 @@ module Spontaneous::Rack
|
|
|
35
39
|
[200, {'Content-type' => 'text/css'}, [engine.render]]
|
|
36
40
|
end
|
|
37
41
|
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
File.join(@root, File.dirname(path), basename)
|
|
42
|
+
def template_path(path)
|
|
43
|
+
path.gsub(CSS_EXTENSION, ".scss")
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
46
|
end
|
|
@@ -1,31 +1,19 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
|
+
require 'simultaneous'
|
|
4
|
+
|
|
3
5
|
module Spontaneous
|
|
4
6
|
module Rack
|
|
5
7
|
class EventSource < ::Simultaneous::Rack::EventSource
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# end
|
|
8
|
+
def push(client)
|
|
9
|
+
@lock.synchronize { @clients << client }
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
# user = env[S::Rack::ACTIVE_USER]
|
|
13
|
-
# if user.nil?
|
|
14
|
-
# unauthorized!
|
|
15
|
-
# else
|
|
16
|
-
# request = ::Rack::Request.new(env)
|
|
17
|
-
# key = request[S::Rack::KEY_PARAM]
|
|
18
|
-
# if ::S::Permissions::AccessKey.valid?(key, user)
|
|
19
|
-
# @app.call(env)
|
|
20
|
-
# else
|
|
21
|
-
# unauthorized!
|
|
22
|
-
# end
|
|
23
|
-
# end
|
|
24
|
-
# end
|
|
12
|
+
alias_method :<<, :push
|
|
25
13
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
def delete(client)
|
|
15
|
+
@lock.synchronize { removed = @clients.delete(client) }
|
|
16
|
+
end
|
|
29
17
|
end
|
|
30
18
|
end
|
|
31
19
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'rack/fiber_pool'
|
|
2
|
+
|
|
3
|
+
module Spontaneous::Rack
|
|
4
|
+
class FiberPool
|
|
5
|
+
def initialize(app, options = {})
|
|
6
|
+
@target_app = app
|
|
7
|
+
@options = options
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call(env)
|
|
11
|
+
app.call(env)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def app
|
|
15
|
+
@app ||= wrap_target_app
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def wrap_target_app
|
|
19
|
+
if Spontaneous.async?
|
|
20
|
+
::Rack::FiberPool.new(@target_app, @options)
|
|
21
|
+
else
|
|
22
|
+
@target_app
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -5,6 +5,13 @@ require 'sinatra/base'
|
|
|
5
5
|
module Spontaneous
|
|
6
6
|
module Rack
|
|
7
7
|
module Front
|
|
8
|
+
def self.front_app
|
|
9
|
+
::Rack::Builder.app do
|
|
10
|
+
use AroundFront
|
|
11
|
+
use Reloader if Site.config.reload_classes
|
|
12
|
+
run Server.new
|
|
13
|
+
end
|
|
14
|
+
end
|
|
8
15
|
def self.application
|
|
9
16
|
app = ::Rack::Builder.new do
|
|
10
17
|
# use ::Rack::CommonLogger, STDERR #unless server.name =~ /CGI/
|
|
@@ -42,19 +49,20 @@ module Spontaneous
|
|
|
42
49
|
end
|
|
43
50
|
|
|
44
51
|
map "/" do
|
|
45
|
-
|
|
46
|
-
use Reloader if Site.config.reload_classes
|
|
47
|
-
run Server.new
|
|
52
|
+
run Spontaneous::Rack::Front.front_app
|
|
48
53
|
end
|
|
49
54
|
end
|
|
50
55
|
end
|
|
56
|
+
|
|
51
57
|
class Server < Sinatra::Base
|
|
52
58
|
include Spontaneous::Rack::Public
|
|
53
59
|
|
|
54
60
|
def call!(env)
|
|
55
61
|
@env = env
|
|
56
62
|
@response = ::Sinatra::Response.new
|
|
57
|
-
@request
|
|
63
|
+
@request = ::Sinatra::Request.new(env)
|
|
64
|
+
@params = indifferent_params(@request.params)
|
|
65
|
+
|
|
58
66
|
render_path(@request.path_info)
|
|
59
67
|
end
|
|
60
68
|
end
|
|
@@ -1,31 +1,53 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
|
+
require 'sprockets'
|
|
4
|
+
|
|
3
5
|
module Spontaneous
|
|
4
6
|
module Rack
|
|
5
7
|
module Helpers
|
|
8
|
+
def json(response)
|
|
9
|
+
content_type 'application/json', :charset => 'utf-8'
|
|
10
|
+
response.serialise_http(user)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def application_assets
|
|
14
|
+
@application_assets_compiler ||= Spontaneous::Asset::AppCompiler.new(Spontaneous.gem_dir, Spontaneous.root)
|
|
15
|
+
end
|
|
6
16
|
|
|
7
17
|
def style_url(style)
|
|
8
|
-
"#{
|
|
18
|
+
style = "#{style}.css" unless style =~ /\.css$/
|
|
19
|
+
if (compiled_asset = application_assets.manifest.assets[style])
|
|
20
|
+
return "#{NAMESPACE}/assets/#{compiled_asset}"
|
|
21
|
+
end
|
|
22
|
+
# TODO: use the sprockets environment to append a modification time to the non-compiled URL
|
|
23
|
+
"#{NAMESPACE}/css/#{style}"
|
|
9
24
|
end
|
|
10
25
|
|
|
11
26
|
def script_url(script)
|
|
12
|
-
"#{
|
|
27
|
+
script = "#{script}.js" unless script =~ /\.js$/
|
|
28
|
+
|
|
29
|
+
if (compiled_asset = application_assets.manifest.assets[script])
|
|
30
|
+
return "#{NAMESPACE}/assets/#{compiled_asset}"
|
|
31
|
+
end
|
|
32
|
+
# TODO: use the sprockets environment to append a modification time to the non-compiled URL
|
|
33
|
+
"#{NAMESPACE}/js/#{script}"
|
|
13
34
|
end
|
|
14
35
|
|
|
15
36
|
def script_list(scripts)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
37
|
+
scripts.map do |script|
|
|
38
|
+
script = "#{script}.js" unless script =~ /\.js$/
|
|
39
|
+
src = script_url(script)
|
|
40
|
+
size = 0
|
|
41
|
+
if (asset = application_assets.manifest.files[File.basename(src)])
|
|
42
|
+
size = asset["size"]
|
|
43
|
+
else
|
|
44
|
+
src = "#{NAMESPACE}/js/#{script}"
|
|
45
|
+
path = Spontaneous.application_dir("/js/#{script}")
|
|
20
46
|
size = File.size(path)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
else
|
|
25
|
-
# script bundling + compression
|
|
26
|
-
end
|
|
47
|
+
end
|
|
48
|
+
[src, size]
|
|
49
|
+
end.to_json
|
|
27
50
|
end
|
|
28
51
|
end
|
|
29
52
|
end
|
|
30
53
|
end
|
|
31
|
-
|