droom 0.0.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -2
- data/app/assets/images/droom/Untitled-1.png +0 -0
- data/app/assets/images/droom/acceptance.png +0 -0
- data/app/assets/images/droom/add.png +0 -0
- data/app/assets/images/droom/asterisk.png +0 -0
- data/app/assets/images/droom/asterisk_up.png +0 -0
- data/app/assets/images/droom/checkboxes.png +0 -0
- data/app/assets/images/droom/clear.png +0 -0
- data/app/assets/images/droom/cog.png +0 -0
- data/app/assets/images/droom/copy.png +0 -0
- data/app/assets/images/droom/copy_to_dropbox.png +0 -0
- data/app/assets/images/droom/crosses.png +0 -0
- data/app/assets/images/droom/dark_scrap_icons.png +0 -0
- data/app/assets/images/droom/defilter.png +0 -0
- data/app/assets/images/droom/delete.png +0 -0
- data/app/assets/images/droom/dropbox.png +0 -0
- data/app/assets/images/droom/dropbox_button.png +0 -0
- data/app/assets/images/droom/dropbox_button_small.png +0 -0
- data/app/assets/images/droom/edit.png +0 -0
- data/app/assets/images/droom/expand.png +0 -0
- data/app/assets/images/droom/expander.png +0 -0
- data/app/assets/images/droom/folder.png +0 -0
- data/app/assets/images/droom/image_box.png +0 -0
- data/app/assets/images/droom/in_dropbox.png +0 -0
- data/app/assets/images/droom/integration_buttons.png +0 -0
- data/app/assets/images/droom/leftright.png +0 -0
- data/app/assets/images/droom/manage.png +0 -0
- data/app/assets/images/droom/medium_object_icons.png +0 -0
- data/app/assets/images/droom/object_icons.png +0 -0
- data/app/assets/images/droom/playable.png +0 -0
- data/app/assets/images/droom/revoke.png +0 -0
- data/app/assets/images/droom/scrap_icons.png +0 -0
- data/app/assets/images/droom/search.png +0 -0
- data/app/assets/images/droom/small_asterisk.png +0 -0
- data/app/assets/images/droom/small_cog.png +0 -0
- data/app/assets/images/droom/small_download.png +0 -0
- data/app/assets/images/droom/small_image_box.png +0 -0
- data/app/assets/images/droom/smalladd.png +0 -0
- data/app/assets/images/droom/smallarrows.png +0 -0
- data/app/assets/images/droom/smallcopy.png +0 -0
- data/app/assets/images/droom/smalldelete.png +0 -0
- data/app/assets/images/droom/smalldownload.png +0 -0
- data/app/assets/images/droom/smalledit.png +0 -0
- data/app/assets/images/droom/smallmanage.png +0 -0
- data/app/assets/images/droom/star.png +0 -0
- data/app/assets/images/droom/symbols.png +0 -0
- data/app/assets/images/droom/tinyarrows.png +0 -0
- data/app/assets/images/droom/to_dropbox.png +0 -0
- data/app/assets/images/droom/twisty.png +0 -0
- data/app/assets/images/droom/youtube_icon.png +0 -0
- data/app/assets/javascripts/droom.js.coffee +62 -65
- data/app/assets/javascripts/droom/actions.js.coffee +492 -0
- data/app/assets/javascripts/droom/ajax.js.coffee +84 -0
- data/app/assets/javascripts/droom/{lib/extensions.js.coffee → extensions.js.coffee} +22 -15
- data/app/assets/javascripts/droom/lib/ZeroClipboard.js +334 -0
- data/app/assets/javascripts/droom/lib/ZeroClipboard.swf +0 -0
- data/app/assets/javascripts/droom/lib/ZeroClipboard10.swf +0 -0
- data/app/assets/javascripts/droom/map.js.coffee +124 -86
- data/app/assets/javascripts/droom/popups.js.coffee +252 -0
- data/app/assets/javascripts/droom/stream.js.coffee +92 -0
- data/app/assets/javascripts/droom/utilities.js.coffee +120 -0
- data/app/assets/javascripts/droom/widgets.js.coffee +1209 -0
- data/app/assets/stylesheets/_definitions.css.sass +189 -0
- data/app/assets/stylesheets/droom.css.sass +1429 -376
- data/app/assets/stylesheets/lib/_kalendae.css.sass +2 -5
- data/app/assets/stylesheets/lib/_popups.css.sass +86 -0
- data/app/assets/stylesheets/lib/_toolbar.css.sass +17 -11
- data/app/controllers/droom/agenda_categories_controller.rb +24 -0
- data/app/controllers/droom/calendars_controller.rb +29 -0
- data/app/controllers/droom/confirmations_controller.rb +38 -0
- data/app/controllers/droom/dashboard_controller.rb +2 -0
- data/app/controllers/droom/documents_controller.rb +42 -51
- data/app/controllers/droom/dropbox_tokens_controller.rb +61 -0
- data/app/controllers/droom/engine_controller.rb +8 -23
- data/app/controllers/droom/events_controller.rb +39 -27
- data/app/controllers/droom/folders_controller.rb +106 -0
- data/app/controllers/droom/group_invitations_controller.rb +15 -7
- data/app/controllers/droom/groups_controller.rb +4 -4
- data/app/controllers/droom/invitations_controller.rb +37 -9
- data/app/controllers/droom/memberships_controller.rb +5 -3
- data/app/controllers/droom/organisations_controller.rb +53 -0
- data/app/controllers/droom/people_controller.rb +46 -27
- data/app/controllers/droom/preferences_controller.rb +34 -0
- data/app/controllers/droom/scraps_controller.rb +77 -0
- data/app/controllers/droom/search_controller.rb +66 -0
- data/app/controllers/droom/suggestions_controller.rb +22 -35
- data/app/controllers/droom/users_controller.rb +69 -0
- data/app/controllers/droom/venues_controller.rb +1 -2
- data/app/controllers/droom/youtube_controller.rb +22 -0
- data/app/helpers/droom/droom_helper.rb +93 -5
- data/app/models/droom/agenda_category.rb +8 -1
- data/app/models/droom/calendar.rb +19 -0
- data/app/models/droom/category.rb +4 -6
- data/app/models/droom/document.rb +103 -64
- data/app/models/droom/document_attachment.rb +13 -47
- data/app/models/droom/dropbox_document.rb +41 -0
- data/app/models/droom/dropbox_token.rb +29 -0
- data/app/models/droom/event.rb +125 -90
- data/app/models/droom/folder.rb +134 -0
- data/app/models/droom/group.rb +68 -27
- data/app/models/droom/group_invitation.rb +12 -3
- data/app/models/droom/invitation.rb +50 -8
- data/app/models/droom/mailing_list_membership.rb +128 -0
- data/app/models/droom/membership.rb +71 -9
- data/app/models/droom/organisation.rb +22 -0
- data/app/models/droom/page.rb +3 -3
- data/app/models/droom/person.rb +180 -166
- data/app/models/droom/personal_folder.rb +31 -0
- data/app/models/droom/preference.rb +35 -0
- data/app/models/droom/recurrence_rule.rb +1 -1
- data/app/models/droom/scrap.rb +110 -0
- data/app/models/droom/tag.rb +120 -0
- data/app/models/droom/tagging.rb +13 -0
- data/app/models/droom/user.rb +211 -0
- data/app/models/droom/user_action_observer.rb +12 -0
- data/app/models/droom/venue.rb +56 -39
- data/app/views/cropper/uploads/_crop.html.haml +46 -0
- data/app/views/devise/mailer/confirmation_instructions.en.html.haml +24 -0
- data/app/views/devise/mailer/reset_password_instructions.en.html.haml +21 -0
- data/app/views/devise/passwords/edit.html.haml +31 -0
- data/app/views/devise/passwords/new.html.haml +21 -0
- data/app/views/devise/sessions/new.html.haml +33 -0
- data/app/views/droom/agenda_categories/_form.html.haml +22 -0
- data/app/views/droom/agenda_categories/new.html.haml +6 -0
- data/app/views/droom/calendars/_action_menu.html.haml +6 -0
- data/app/views/droom/calendars/index.html.haml +12 -0
- data/app/views/droom/calendars/show.rss.builder +0 -0
- data/app/views/droom/confirmations/show.html.haml +40 -0
- data/app/views/droom/dashboard/_calendar.html.haml +1 -0
- data/app/views/droom/dashboard/_folders.html.haml +5 -0
- data/app/views/droom/dashboard/_future_events.html.haml +18 -0
- data/app/views/droom/dashboard/_invitations.html.haml +1 -0
- data/app/views/droom/dashboard/_past_events.haml +14 -0
- data/app/views/droom/dashboard/_quicksearch.html.haml +6 -0
- data/app/views/droom/dashboard/_stream.html.haml +9 -0
- data/app/views/droom/dashboard/index.html.haml +5 -3
- data/app/views/droom/documents/_action_menu.html.haml +7 -0
- data/app/views/droom/documents/_documents.html.haml +5 -0
- data/app/views/droom/documents/_documents_list.html.haml +6 -6
- data/app/views/droom/documents/_documents_table.html.haml +29 -10
- data/app/views/droom/documents/_form.html.haml +3 -7
- data/app/views/droom/documents/_listing.html.haml +5 -6
- data/app/views/droom/documents/_pagination.html.haml +8 -0
- data/app/views/droom/documents/_search_result.html.haml +14 -0
- data/app/views/droom/documents/_suggested.html.haml +0 -5
- data/app/views/droom/documents/_table_document.html.haml +2 -8
- data/app/views/droom/documents/edit.html.haml +7 -1
- data/app/views/droom/documents/index.html.haml +10 -27
- data/app/views/droom/documents/new.html.haml +10 -1
- data/app/views/droom/dropbox_tokens/new.html.haml +6 -0
- data/app/views/droom/events/_action_menu.html.haml +15 -0
- data/app/views/droom/events/_event.html.haml +67 -57
- data/app/views/droom/events/_form.html.haml +15 -4
- data/app/views/droom/events/_invitations.html.haml +4 -19
- data/app/views/droom/events/_search_result.html.haml +19 -0
- data/app/views/droom/events/_views.html.haml +2 -2
- data/app/views/droom/events/edit.html.haml +7 -1
- data/app/views/droom/events/index.html.haml +27 -10
- data/app/views/droom/events/index.rss.builder +1 -1
- data/app/views/droom/events/new.html.haml +6 -1
- data/app/views/droom/events/show.html.haml +5 -1
- data/app/views/droom/folders/_action_menu.html.haml +14 -0
- data/app/views/droom/folders/_attachments.html.haml +3 -0
- data/app/views/droom/folders/_contents.html.haml +6 -0
- data/app/views/droom/folders/_folder.html.haml +20 -0
- data/app/views/droom/folders/_folders.html.haml +2 -0
- data/app/views/droom/folders/_form.html.haml +18 -0
- data/app/views/droom/folders/edit.html.haml +6 -0
- data/app/views/droom/folders/index.html.haml +32 -0
- data/app/views/droom/folders/new.html.haml +6 -0
- data/app/views/droom/folders/show.html.haml +1 -0
- data/app/views/droom/group_invitations/_form.html.haml +15 -4
- data/app/views/droom/group_invitations/new.html.haml +6 -1
- data/app/views/droom/groups/_action_menu.haml +11 -0
- data/app/views/droom/groups/_form.html.haml +10 -11
- data/app/views/droom/groups/_group.html.haml +9 -10
- data/app/views/droom/groups/_groups.html.haml +2 -3
- data/app/views/droom/groups/_search_result.html.haml +16 -0
- data/app/views/droom/groups/_suggested.html.haml +7 -0
- data/app/views/droom/groups/edit.html.haml +7 -1
- data/app/views/droom/groups/index.html.haml +6 -3
- data/app/views/droom/groups/new.html.haml +7 -0
- data/app/views/droom/groups/show.html.haml +1 -1
- data/app/views/droom/invitations/_created.html.haml +1 -1
- data/app/views/droom/invitations/_form.html.haml +9 -5
- data/app/views/droom/invitations/_invitation.html.haml +9 -0
- data/app/views/droom/invitations/_invitations.html.haml +8 -0
- data/app/views/droom/invitations/new.html.haml +6 -1
- data/app/views/droom/memberships/_member.html.haml +1 -1
- data/app/views/droom/memberships/_membership_toggle.html.haml +10 -0
- data/app/views/droom/memberships/new.html.haml +10 -0
- data/app/views/droom/organisations/_action_menu.html.haml +7 -0
- data/app/views/droom/organisations/_form.html.haml +25 -0
- data/app/views/droom/organisations/_organisation.html.haml +23 -0
- data/app/views/droom/organisations/_organisations.html.haml +2 -0
- data/app/views/droom/organisations/_suggested.html.haml +7 -0
- data/app/views/droom/organisations/edit.html.haml +6 -0
- data/app/views/droom/organisations/index.html.haml +20 -0
- data/app/views/droom/organisations/new.html.haml +6 -0
- data/app/views/droom/organisations/show.html.haml +1 -0
- data/app/views/droom/pages/_full_page.html.haml +1 -1
- data/app/views/droom/pages/index.html.haml +1 -1
- data/app/views/droom/panels/_account.html.haml +16 -0
- data/app/views/droom/panels/_admin.html.haml +23 -0
- data/app/views/droom/panels/_devices.html.haml +19 -0
- data/app/views/droom/panels/_dropbox.html.haml +17 -0
- data/app/views/droom/panels/_email.html.haml +16 -0
- data/app/views/droom/panels/_keywords.html.haml +3 -0
- data/app/views/droom/panels/_networks.html.haml +3 -0
- data/app/views/droom/panels/_readers.html.haml +18 -0
- data/app/views/droom/panels/_rss.html.haml +10 -0
- data/app/views/droom/panels/_search.html.haml +16 -0
- data/app/views/droom/panels/_vcal.html.haml +3 -0
- data/app/views/droom/people/_action_menu.html.haml +22 -0
- data/app/views/droom/people/_form.html.haml +69 -39
- data/app/views/droom/people/_listing.html.haml +19 -0
- data/app/views/droom/people/_memberships.html.haml +24 -0
- data/app/views/droom/people/_people.html.haml +5 -29
- data/app/views/droom/people/_person.html.haml +30 -32
- data/app/views/droom/people/_search_result.html.haml +14 -0
- data/app/views/droom/people/_suggested.html.haml +10 -5
- data/app/views/droom/people/edit.html.haml +9 -1
- data/app/views/droom/people/index.html.haml +6 -9
- data/app/views/droom/people/new.html.haml +6 -1
- data/app/views/droom/people/show.html.haml +1 -1
- data/app/views/droom/preferences/_checkbox.html.haml +7 -0
- data/app/views/droom/preferences/_radio_set.html.haml +9 -0
- data/app/views/droom/scraps/_action_menu.html.haml +9 -0
- data/app/views/droom/scraps/_caption.html.haml +9 -0
- data/app/views/droom/scraps/_credit.html.haml +10 -0
- data/app/views/droom/scraps/_form.html.haml +77 -0
- data/app/views/droom/scraps/_heading.html.haml +16 -0
- data/app/views/droom/scraps/_scrap.html.haml +17 -0
- data/app/views/droom/scraps/_search_result.html.haml +5 -0
- data/app/views/droom/scraps/_stream.html.haml +4 -0
- data/app/views/droom/scraps/_suggested.html.haml +5 -0
- data/app/views/droom/scraps/_thumb.html.haml +5 -0
- data/app/views/droom/scraps/edit.html.haml +2 -0
- data/app/views/droom/scraps/full/_document.html.haml +6 -0
- data/app/views/droom/scraps/full/_event.html.haml +20 -0
- data/app/views/droom/scraps/full/_image.html.haml +4 -0
- data/app/views/droom/scraps/full/_link.html.haml +5 -0
- data/app/views/droom/scraps/full/_quote.html.haml +8 -0
- data/app/views/droom/scraps/full/_text.html.haml +4 -0
- data/app/views/droom/scraps/full/_video.html.haml +4 -0
- data/app/views/droom/scraps/index.atom.builder +26 -0
- data/app/views/droom/scraps/index.html.haml +15 -0
- data/app/views/droom/scraps/new.html.haml +2 -0
- data/app/views/droom/scraps/show.html.haml +4 -0
- data/app/views/droom/scraps/thumbs/_document.html.haml +9 -0
- data/app/views/droom/scraps/thumbs/_event.html.haml +17 -0
- data/app/views/droom/scraps/thumbs/_image.html.haml +6 -0
- data/app/views/droom/scraps/thumbs/_link.html.haml +10 -0
- data/app/views/droom/scraps/thumbs/_quote.html.haml +8 -0
- data/app/views/droom/scraps/thumbs/_text.html.haml +8 -0
- data/app/views/droom/scraps/thumbs/_video.html.haml +6 -0
- data/app/views/droom/shared/_controls.html.haml +5 -3
- data/app/views/droom/shared/_excerpt.html.haml +2 -0
- data/app/views/droom/shared/_navigation.html.haml +4 -4
- data/app/views/droom/shared/_panels.html.haml +4 -0
- data/app/views/droom/shared/_quicklinks.html.haml +5 -0
- data/app/views/droom/shared/_search_form.html.haml +2 -1
- data/app/views/droom/shared/_search_results.html.haml +9 -0
- data/app/views/droom/shared/_suggestions.html.haml +13 -9
- data/app/views/droom/shared/_title_excerpt.haml +2 -0
- data/app/views/droom/shared/search.html.haml +18 -0
- data/app/views/droom/users/_confirmation.html.haml +2 -0
- data/app/views/droom/users/_dropbox_status.html.haml +2 -0
- data/app/views/droom/users/_form.html.haml +34 -0
- data/app/views/droom/users/_user.html.haml +2 -0
- data/app/views/droom/users/_user_or_person.html.haml +63 -0
- data/app/views/droom/users/_users_table.html.haml +17 -0
- data/app/views/droom/users/edit.html.haml +10 -0
- data/app/views/droom/users/index.html.haml +42 -0
- data/app/views/droom/users/unwelcome.en.html.haml +17 -0
- data/app/views/droom/venues/_search_result.html.haml +17 -0
- data/app/views/droom/youtube/show.html.haml +12 -0
- data/app/views/kaminari/_paginator.html.haml +16 -0
- data/app/views/layouts/droom/application.html.haml +17 -17
- data/app/views/layouts/droom/email.html.haml +59 -0
- data/config/cucumber.yml +8 -0
- data/config/initializers/devise.rb +240 -0
- data/config/locales/devise.en.yml +58 -0
- data/config/locales/en.yml +203 -32
- data/config/routes.rb +55 -16
- data/config/sunspot.yml +17 -0
- data/db/migrate/20121120115447_tags.rb +18 -0
- data/db/migrate/20130116155331_dropbox_tokens.rb +9 -0
- data/db/migrate/20130118103540_folders.rb +47 -0
- data/db/migrate/20130124113715_preferences.rb +10 -0
- data/db/migrate/20130125132427_users_in_droom.rb +58 -0
- data/db/migrate/20130129142307_mobile_phones.rb +7 -0
- data/db/migrate/20130130120124_folder_ancestry_to_parents.rb +7 -0
- data/db/migrate/20130131161430_mailing_lists.rb +37 -0
- data/db/migrate/20130207091903_preference_uuids.rb +5 -0
- data/db/migrate/20130207123614_stream.rb +13 -0
- data/db/migrate/20130208035113_access_token_secret.rb +5 -0
- data/db/migrate/20130214145014_person_image.rb +9 -0
- data/db/migrate/20130217152644_devise_confirmable.rb +13 -0
- data/db/migrate/20130225095328_create_droom_calendars.rb +20 -0
- data/db/migrate/20130226092944_give_scraps_document.rb +5 -0
- data/db/migrate/20130228083509_privateness.rb +9 -0
- data/db/migrate/20130228134143_store_metadata.rb +5 -0
- data/db/migrate/20130305150648_folders_nicely.rb +6 -0
- data/db/migrate/20130305151936_niceties.rb +7 -0
- data/db/migrate/20130308103807_create_droom_dropbox_documents.rb +11 -0
- data/db/migrate/20130308154552_dropbox_documents_changed.rb +5 -0
- data/db/migrate/20130326135738_user_titles.rb +5 -0
- data/lib/droom.rb +189 -22
- data/lib/droom/engine.rb +6 -1
- data/lib/droom/folders.rb +106 -0
- data/lib/droom/lazy_hash.rb +73 -0
- data/lib/droom/{helpers.rb → model_helpers.rb} +1 -1
- data/lib/droom/monkeys.rb +21 -2
- data/lib/droom/routing.rb +13 -0
- data/lib/droom/searchability.rb +25 -0
- data/lib/droom/taggability.rb +60 -0
- data/lib/droom/title_case.rb +101 -0
- data/lib/droom/user_config.rb +67 -0
- data/lib/droom/validators.rb +6 -0
- data/lib/droom/version.rb +1 -1
- data/lib/generators/droom/install/templates/droom_initializer.rb +0 -1
- data/lib/tasks/cucumber.rake +65 -0
- data/spec/datasets/calendar_events_dataset.rb +44 -0
- data/spec/datasets/calendar_pages_dataset.rb +8 -0
- data/spec/datasets/calendar_sites_dataset.rb +6 -0
- data/spec/datasets/calendars_dataset.rb +34 -0
- data/spec/datasets/documents_dataset.rb +28 -0
- data/spec/datasets/recurrence_dataset.rb +7 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +65 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +21 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +38 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +38 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +7 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/sunspot.yml +17 -0
- data/spec/dummy/db/migrate/20120911070124_create_droom_data.droom.rb +135 -0
- data/spec/dummy/db/migrate/20120921094604_agenda_sections.droom.rb +14 -0
- data/spec/dummy/db/migrate/20120921094605_add_postal_address_to_people.droom.rb +11 -0
- data/spec/dummy/db/migrate/20121102064845_give_groups_descriptions.droom.rb +6 -0
- data/spec/dummy/db/migrate/20121102064846_more_names.droom.rb +6 -0
- data/spec/dummy/db/migrate/20121102064847_event_agenda_sections.droom.rb +14 -0
- data/spec/dummy/db/migrate/20121102064848_create_group_invitations.droom.rb +11 -0
- data/spec/dummy/db/migrate/20121102064849_give_people_positions.droom.rb +6 -0
- data/spec/dummy/db/migrate/20121102064850_help_pages.droom.rb +14 -0
- data/spec/dummy/db/migrate/20121102064851_category_slugs.droom.rb +6 -0
- data/spec/dummy/db/migrate/20121102064852_document_links.droom.rb +15 -0
- data/spec/dummy/db/migrate/20121102064853_people_visibility.droom.rb +8 -0
- data/spec/dummy/db/migrate/20121102094820_shy_people.droom.rb +6 -0
- data/spec/dummy/db/migrate/20121102095927_visibility_defaults.droom.rb +10 -0
- data/spec/dummy/db/migrate/20130121122352_tags.droom.rb +19 -0
- data/spec/dummy/db/migrate/20130121122353_dropbox.droom.rb +10 -0
- data/spec/dummy/db/migrate/20130121122354_folders.droom.rb +48 -0
- data/spec/dummy/db/migrate/20130128142902_memberships_expire.droom.rb +6 -0
- data/spec/dummy/db/migrate/20130128142903_give_documents_extracted_text.droom.rb +6 -0
- data/spec/dummy/db/migrate/20130128142904_preferences.droom.rb +11 -0
- data/spec/dummy/db/migrate/20130128142905_users_in_droom.droom.rb +59 -0
- data/spec/dummy/db/migrate/20130130120631_folder_ancestry_to_parents.droom.rb +8 -0
- data/spec/dummy/db/migrate/20130201103737_mobile_phones.droom.rb +8 -0
- data/spec/dummy/db/migrate/20130201103738_mailing_lists.droom.rb +38 -0
- data/spec/dummy/db/schema.rb +327 -0
- data/spec/dummy/log/sunspot-solr-test.log.1 +222 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/system/droom/documents/files/000/000/001/original/frog.png +0 -0
- data/spec/dummy/public/system/droom/documents/files/000/000/001/original/rat.png +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/solr/conf/admin-extra.html +31 -0
- data/spec/dummy/solr/conf/elevate.xml +36 -0
- data/spec/dummy/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
- data/spec/dummy/solr/conf/protwords.txt +21 -0
- data/spec/dummy/solr/conf/schema.xml +238 -0
- data/spec/dummy/solr/conf/scripts.conf +24 -0
- data/spec/dummy/solr/conf/solrconfig.xml +934 -0
- data/spec/dummy/solr/conf/spellings.txt +2 -0
- data/spec/dummy/solr/conf/stopwords.txt +58 -0
- data/spec/dummy/solr/conf/synonyms.txt +31 -0
- data/spec/dummy/solr/data/development/index/segments.gen +0 -0
- data/spec/dummy/solr/data/development/index/segments_1 +0 -0
- data/spec/dummy/solr/data/development/spellchecker/segments.gen +0 -0
- data/spec/dummy/solr/data/development/spellchecker/segments_1 +0 -0
- data/spec/dummy/solr/data/test/index/segments.gen +0 -0
- data/spec/dummy/solr/data/test/index/segments_3nu +0 -0
- data/spec/dummy/solr/data/test/spellchecker/segments.gen +0 -0
- data/spec/dummy/solr/data/test/spellchecker/segments_1 +0 -0
- data/spec/dummy/webdav/1/group/rat.png +0 -0
- data/spec/dummy/webdav/1/unattached/rat.png +0 -0
- data/spec/dummy/webdav/group/rat.png +0 -0
- data/spec/dummy/webdav/unattached/rat.png +0 -0
- data/spec/dummy/webdav/unattached/rat_v1.png +0 -0
- data/spec/factories/agenda_categories.rb +5 -0
- data/spec/factories/categories.rb +5 -0
- data/spec/factories/documents.rb +16 -0
- data/spec/factories/events.rb +41 -0
- data/spec/factories/folders.rb +5 -0
- data/spec/factories/groups.rb +6 -0
- data/spec/factories/memberships.rb +5 -0
- data/spec/factories/people.rb +16 -0
- data/spec/factories/recurrence_rules.rb +25 -0
- data/spec/factories/user.rb +6 -0
- data/spec/fixtures/dummy.ics +59 -0
- data/spec/fixtures/images/frog.png +0 -0
- data/spec/fixtures/images/rat.png +0 -0
- data/spec/fixtures/ny.ics +36 -0
- data/spec/lib/droom/folders_spec.rb +46 -0
- data/spec/lib/droom/lazy_hash_spec.rb +33 -0
- data/spec/models/droom/agenda_category_spec.rb +15 -0
- data/spec/models/droom/document_spec.rb +76 -0
- data/spec/models/droom/event_spec.rb +154 -0
- data/spec/models/droom/folder_spec.rb +5 -0
- data/spec/models/droom/ical_spec.rb +62 -0
- data/spec/models/droom/mailing_list_membership_spec.rb +81 -0
- data/spec/models/droom/membership_spec.rb +22 -0
- data/spec/models/droom/person_spec.rb +72 -0
- data/spec/models/droom/recurrence_rule_spec.rb +81 -0
- data/spec/models/droom/user_spec.rb +27 -0
- data/spec/models/droom/visibility_spec.rb +6 -0
- data/spec/spec_helper.rb +119 -0
- data/spec/support/matchers/content_type_matcher.rb +17 -0
- metadata +591 -36
- data/app/assets/javascripts/droom/calendar.js.coffee +0 -121
- data/app/assets/javascripts/droom/drag_sort.js.coffee +0 -22
- data/app/assets/javascripts/droom/forms.js.coffee +0 -746
- data/app/assets/javascripts/droom/sort.js.coffee +0 -126
- data/app/assets/javascripts/droom/suggester.js.coffee +0 -230
- data/app/controllers/droom/document_attachments_controller.rb +0 -19
- data/app/models/droom/document_link.rb +0 -31
- data/app/models/droom/personal_document.rb +0 -98
- data/app/views/droom/dashboard/_marginalia.html.haml +0 -3
- data/app/views/droom/dashboard/_my_future_events.html.haml +0 -9
- data/app/views/droom/dashboard/_my_group_documents.html.haml +0 -6
- data/app/views/droom/dashboard/_my_past_events.haml +0 -6
- data/app/views/droom/documents/_event_document_form.html.haml +0 -15
- data/app/views/droom/errors/bang.html.haml +0 -12
- data/app/views/droom/errors/not_allowed.html.haml +0 -12
- data/app/views/droom/errors/not_found.html.haml +0 -12
- data/app/views/droom/events/_attachment.html.haml +0 -1
- data/app/views/droom/events/_attachment_list.html.haml +0 -4
- data/app/views/droom/invitations/_attending_people.html.haml +0 -8
- data/config/initializers/dav.rb +0 -2
data/lib/droom/engine.rb
CHANGED
@@ -2,7 +2,12 @@ module Droom
|
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
isolate_namespace Droom
|
4
4
|
initializer "droom.integration" do
|
5
|
-
ActiveRecord::Base.send :include, Droom::
|
5
|
+
ActiveRecord::Base.send :include, Droom::ModelHelpers
|
6
|
+
ActiveRecord::Base.send :include, Droom::Taggability
|
7
|
+
ActiveRecord::Base.send :include, Droom::Folders
|
8
|
+
ActiveSupport.on_load :action_controller do
|
9
|
+
helper Droom::DroomHelper
|
10
|
+
end
|
6
11
|
end
|
7
12
|
end
|
8
13
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# Documents in droom are never attached directly to an object. Instead they are always attached to a folder,
|
2
|
+
# and the folder is usually attached to an object. The folder itself is a normal ActiveRecord object with a
|
3
|
+
# name and some tree behaviours that allow us to present a filing system.
|
4
|
+
#
|
5
|
+
# This file defines the interface by which we declare that an object has a folder and would like to receive documents.
|
6
|
+
#
|
7
|
+
# It is also possible to have a loose folder: in that case it is considered public and available to everyone.
|
8
|
+
#
|
9
|
+
module Droom
|
10
|
+
module Folders
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend FolderClassMethods
|
14
|
+
end
|
15
|
+
|
16
|
+
module FolderClassMethods
|
17
|
+
def has_folder?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
# In most cases all you need is a `has_folder` line in the model class definition.
|
22
|
+
#
|
23
|
+
# class Thing < ActiveRecord::Base
|
24
|
+
# has_folder
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# This will bring in the folder and document associations and all the instance methods
|
28
|
+
# involved in adding and removing documents. The folder itself is lazy-loaded: the first
|
29
|
+
# time it is requested, it will be created.
|
30
|
+
#
|
31
|
+
# You can specify that the folder should be created inside another folder. For example, the
|
32
|
+
# document folder associated with an agenda_category is always created within the folder of
|
33
|
+
# its event, so that the filing system reflects the organisation of the event. To achieve this,
|
34
|
+
# pass in the name of an associate as the `:within` option:
|
35
|
+
#
|
36
|
+
# class Subthing < ActiveRecord::Base
|
37
|
+
# belongs_to :thing
|
38
|
+
# has_folder :within => :thing
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
def has_folder( options={} )
|
42
|
+
return if has_folder?
|
43
|
+
has_one :folder, :as => :holder, :class_name => "Droom::Folder"
|
44
|
+
has_many :documents, :through => :folder, :class_name => "Droom::Document"
|
45
|
+
# The :within option is stored as a class variable that will be consulted when the folder is created.
|
46
|
+
class_variable_set(:"@@parent_folder_holder", options[:within])
|
47
|
+
|
48
|
+
class_eval {
|
49
|
+
extend Droom::Folders::FolderedClassMethods
|
50
|
+
include Droom::Folders::FolderedInstanceMethods
|
51
|
+
alias_method_chain :folder, :lazy_load
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module FolderedClassMethods
|
57
|
+
# The has_folder? method is used to prevent multiple calls to has_folder, but might possibly be useful elsewhere.
|
58
|
+
def has_folder?
|
59
|
+
true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module FolderedInstanceMethods
|
64
|
+
#
|
65
|
+
# Folders are lazy-created. That is, when we need it, we make it. This is achieved by chaining the `:folder`
|
66
|
+
# association method and creating a folder if none exists. This method definition must occur after the association
|
67
|
+
# has been defined.
|
68
|
+
#
|
69
|
+
def folder_with_lazy_load
|
70
|
+
folder_without_lazy_load || self.create_folder(:parent => get_parent_folder)
|
71
|
+
end
|
72
|
+
|
73
|
+
def all_documents
|
74
|
+
Droom::Document.in_folders(folder.family)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Here we refer to the class variable defined during `has_folder` configuration. If it exists, we will put our folder
|
79
|
+
# inside that of the named associate. The containing folder might be created as a side effect.
|
80
|
+
#
|
81
|
+
def get_parent_folder
|
82
|
+
pfh = self.class.class_variable_get(:"@@parent_folder_holder")
|
83
|
+
if pfh && holder = send(pfh.to_sym)
|
84
|
+
holder.folder
|
85
|
+
else
|
86
|
+
# otherwise we want a root folder like /Events
|
87
|
+
Droom::Folder.find_or_create_by_slug_and_parent_id(self.class.to_s.titlecase.split('/').last.pluralize, nil)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Create a new document in our folder, with the supplied properties.
|
92
|
+
#
|
93
|
+
def add_document(attributes)
|
94
|
+
folder.documents.create(attributes)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Move an existing document into our folder.
|
98
|
+
#
|
99
|
+
def receive_document(doc)
|
100
|
+
folder.documents << doc
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# This is the mechanism by which droom's preferences system is bolted onto the host app's user class.
|
2
|
+
#
|
3
|
+
module Droom
|
4
|
+
# LazyHash is a recursive hash descendant that accepts keys in the form `key:subkey:subsubkey` and populates
|
5
|
+
# nested hashes accordingly.
|
6
|
+
#
|
7
|
+
# In droom this mechanism is used to manage the default values that sit behind user preferences. The motive
|
8
|
+
# is to match the `User#pref(key)` interface, with concatenated keys designating namespaced values:
|
9
|
+
#
|
10
|
+
# LazyHash.set("key:subkey:otherkey:something", "hippopotamus")
|
11
|
+
# => {:key => {:subkey => {:otherkey => {:something => "hippopotamus"}}}}
|
12
|
+
#
|
13
|
+
# LazyHash.get("key:subkey:otherkey") => {:something => "hippopotamus"}
|
14
|
+
# LazyHash.get("key:subkey:otherkey:something") => "hippopotamus"
|
15
|
+
#
|
16
|
+
# An unset value will always return nil. A set value may be false. You may want to test for the difference.
|
17
|
+
#
|
18
|
+
# NB. keys are always symbolized.
|
19
|
+
#
|
20
|
+
class LazyHash < Hash
|
21
|
+
|
22
|
+
def initialize(*args)
|
23
|
+
hash = args.extract_options!
|
24
|
+
super
|
25
|
+
hash.each_pair do |k,v|
|
26
|
+
self[k] = v.is_a?(Hash) ? Droom::LazyHash.new(v) : v
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def inspect
|
31
|
+
"lazyhash: #{super}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# *get* will return the value in the named bucket. The bucket is designated
|
35
|
+
# by a key that can either be simple or the dot.separated path to a nested hash.
|
36
|
+
#
|
37
|
+
def get(path)
|
38
|
+
key, subkeys = split_path(path)
|
39
|
+
if subkeys.any?
|
40
|
+
if self[key].is_a?(Droom::LazyHash)
|
41
|
+
self[key].get(subkeys)
|
42
|
+
else
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
elsif self.key?(key)
|
46
|
+
self[key]
|
47
|
+
else
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# *set* will set the value at the named bucket. Note that you should only ever do this from an
|
53
|
+
# initializer or some other thread-global event that can be relied upon always to have run. Never call
|
54
|
+
# LazyHash#set at runtime unless what you want is a local, non-thread-global nested hash construction.
|
55
|
+
#
|
56
|
+
def set(path, value)
|
57
|
+
key, subkeys = split_path(path)
|
58
|
+
if subkeys.any?
|
59
|
+
self[key] ||= Droom::LazyHash.new({})
|
60
|
+
self[key].set(subkeys, value)
|
61
|
+
else
|
62
|
+
self[key] = value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
def split_path(key)
|
68
|
+
keys = key.is_a?(Array) ? key : key.to_s.split('.')
|
69
|
+
keys.any? ? [keys.shift.to_sym, keys] : [nil, []]
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/lib/droom/monkeys.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class Array
|
2
|
-
|
3
2
|
def to_ics
|
4
3
|
to_rical.to_s
|
5
4
|
end
|
@@ -11,5 +10,25 @@ class Array
|
|
11
10
|
end
|
12
11
|
end
|
13
12
|
end
|
14
|
-
|
15
13
|
end
|
14
|
+
|
15
|
+
class Time
|
16
|
+
def ceil(seconds = 60)
|
17
|
+
Time.at((self.to_f / seconds).ceil * seconds)
|
18
|
+
end
|
19
|
+
|
20
|
+
def floor(seconds = 60)
|
21
|
+
Time.at((self.to_f / seconds).floor * seconds)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class DateTime
|
26
|
+
def ceil(seconds = 60)
|
27
|
+
Time.at(self.to_f).ceil(seconds).to_datetime
|
28
|
+
end
|
29
|
+
|
30
|
+
def floor(seconds = 60)
|
31
|
+
Time.at(self.to_f).floor(seconds).to_datetime
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'droom/title_case'
|
2
|
+
|
3
|
+
STOPWORDS = %w{ a about above after again against all am and any are aren't as at be because been before being below between both by can't cannot could couldn't did didn't do does doesn't doing don't down during each few for from further had hadn't has hasn't have haven't having he he'd he'll he's her here here's hers herself himself his how how's i i'd i'll i'm i've if in into is isn't it it's its itself let's me more most mustn't my myself no nor not of off once only other ought our ours ourselves out over own same shan't she she'd she'll she's should shouldn't some such than that that's the their theirs them themselves then there there's these they they'd they'll they're they've this those through too under until up very was wasn't we we'd we'll we're we've were weren't what what's when when's where where's which while who who's whom why why's with won't would wouldn't you you'd you'll you're you've your yours yourself yourselves }
|
4
|
+
STOPWORD_RE = %r{\b(#{STOPWORDS.join('|')})\b\s* }
|
5
|
+
SMALL_WORDS = %w( is a an and as at but by en for if in of on or the to v[.]? via vs[.]? )
|
6
|
+
SMALL_RE = %r{\b(#{SMALL_WORDS.join('|')})\b}io
|
7
|
+
|
8
|
+
SMALL_WORDS.join('|')
|
9
|
+
|
10
|
+
class String
|
11
|
+
include TitleCase
|
12
|
+
|
13
|
+
def searchable
|
14
|
+
downcase.remove_stopwords.flatten
|
15
|
+
end
|
16
|
+
|
17
|
+
def flatten
|
18
|
+
split(/[^\w\d\']{1,}/).join(' ')
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove_stopwords
|
22
|
+
gsub(STOPWORD_RE, '')
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Droom
|
2
|
+
module Taggability
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend TaggableClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module TaggableClassMethods
|
9
|
+
def has_tags?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_tags
|
14
|
+
return if has_tags?
|
15
|
+
has_many :taggings, :as => :taggee, :class_name => "Droom::Tagging"
|
16
|
+
has_many :tags, :through => :taggings, :class_name => "Droom::Tag"
|
17
|
+
|
18
|
+
class_eval {
|
19
|
+
extend Droom::Taggability::TaggedClassMethods
|
20
|
+
include Droom::Taggability::TaggedInstanceMethods
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module TaggedClassMethods
|
26
|
+
def has_tags?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module TaggedInstanceMethods
|
32
|
+
def add_tag(word=nil)
|
33
|
+
self.tags << Tag.for(word) if word && !word.blank?
|
34
|
+
end
|
35
|
+
|
36
|
+
def remove_tag(word=nil)
|
37
|
+
tag = Tag.find_by_title(word) if word && !word.blank?
|
38
|
+
self.tags.delete(tag) if tag
|
39
|
+
end
|
40
|
+
|
41
|
+
def keywords
|
42
|
+
self.tags.map {|t| t.name}.join(', ')
|
43
|
+
end
|
44
|
+
|
45
|
+
def keywords_before_type_cast # for form_helper
|
46
|
+
keywords
|
47
|
+
end
|
48
|
+
|
49
|
+
def keywords=(somewords="")
|
50
|
+
if somewords.blank?
|
51
|
+
self.tags.clear
|
52
|
+
else
|
53
|
+
self.tags = Tag.from_list(somewords)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Ruby Title Case
|
4
|
+
# A Ruby implementation of John Gruber's Title Case
|
5
|
+
# http://daringfireball.net/2008/05/title_case
|
6
|
+
#
|
7
|
+
# Copyright (c) Paul Mucur (http://mucur.name), 2008.
|
8
|
+
# Dual-licensed under the BSD (BSD-LICENSE.txt) and GPL (GPL-LICENSE.txt)
|
9
|
+
# licenses.
|
10
|
+
#
|
11
|
+
# This program is free software; you can redistribute it and/or modify
|
12
|
+
# it under the terms of the GNU General Public License as published by
|
13
|
+
# the Free Software Foundation; either version 2 of the License, or
|
14
|
+
# (at your option) any later version.
|
15
|
+
#
|
16
|
+
# This program is distributed in the hope that it will be useful,
|
17
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
# GNU General Public License for more details.
|
20
|
+
|
21
|
+
module TitleCase
|
22
|
+
|
23
|
+
# A regular expression to match small words that should not be
|
24
|
+
# titleized.
|
25
|
+
SMALL_WORDS_RE = /^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v\.?|via|vs\.?)$/
|
26
|
+
|
27
|
+
def titleize_if_appropriate(word)
|
28
|
+
if word
|
29
|
+
# If a word does not contain a full-stop within itself and it doesn't
|
30
|
+
# contain any capital letters apart from its first letter, titleize it.
|
31
|
+
if !word[/\w\.\w/] && !word[/^.+[A-Z]/]
|
32
|
+
|
33
|
+
# Capitalise the first *word* character (therefore avoiding problems
|
34
|
+
# where the first character is some punctuation).
|
35
|
+
word[/^\W*\w/] &&= word[/^\W*\w/].upcase
|
36
|
+
end
|
37
|
+
|
38
|
+
word
|
39
|
+
else
|
40
|
+
""
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def title_case
|
45
|
+
|
46
|
+
# Keep track when a colon has been used at the end of a word.
|
47
|
+
colon_preceding = false
|
48
|
+
|
49
|
+
# Split the string by any whitespace and then inspect each word
|
50
|
+
# at a time.
|
51
|
+
words = split(/\s+/).map do |word|
|
52
|
+
title_cased_word = if colon_preceding
|
53
|
+
|
54
|
+
# If there was a colon preceding this word then titleize
|
55
|
+
# it even if it is a small word.
|
56
|
+
colon_preceding = false
|
57
|
+
titleize_if_appropriate(word)
|
58
|
+
elsif word.downcase[SMALL_WORDS_RE]
|
59
|
+
|
60
|
+
# If this is a small word, make it lowercase.
|
61
|
+
word.downcase
|
62
|
+
else
|
63
|
+
|
64
|
+
# In all other cases, titleize the word.
|
65
|
+
titleize_if_appropriate(word)
|
66
|
+
end
|
67
|
+
|
68
|
+
# If this word ends in a colon, set the flag so that the
|
69
|
+
# following word can be titleized.
|
70
|
+
colon_preceding = true if word[/:$/]
|
71
|
+
|
72
|
+
title_cased_word
|
73
|
+
end
|
74
|
+
|
75
|
+
# Always capitalise the first and last words.
|
76
|
+
words[0] = titleize_if_appropriate(words[0])
|
77
|
+
words[-1] = titleize_if_appropriate(words[-1])
|
78
|
+
|
79
|
+
words.join(" ")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if $0 == __FILE__
|
84
|
+
|
85
|
+
# If this file is being executed, read in from the command line
|
86
|
+
# and STDIN.
|
87
|
+
input = ARGV.first || STDIN.read
|
88
|
+
|
89
|
+
# ARGV.first is frozen and so cannot be extended by default.
|
90
|
+
input = input.dup if input.frozen?
|
91
|
+
|
92
|
+
if input.empty?
|
93
|
+
|
94
|
+
# If no input was given, print simple usage instructions
|
95
|
+
puts "usage: ruby title_case.rb [TEXT_TO_TITLE_CASE]"
|
96
|
+
else
|
97
|
+
input.extend(TitleCase)
|
98
|
+
|
99
|
+
puts input.title_case
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# This is a recursive hash that accepst keys in the form `key:subkey:subsubkey` and
|
2
|
+
# populates nested hash objects accordingly. It allows both the standard []= and a more
|
3
|
+
# convenient method-call notation.
|
4
|
+
#
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# Call new with an existing hash to populate the LazyHash with defaults.
|
8
|
+
|
9
|
+
module Droom
|
10
|
+
|
11
|
+
class PreferencesHash < Hash
|
12
|
+
def get(path)
|
13
|
+
key, subkeys = split_path(path)
|
14
|
+
if subkeys.any?
|
15
|
+
self[key.to_sym].get(subkeys)
|
16
|
+
else
|
17
|
+
if self[key].is_a? Droom::Preference
|
18
|
+
self[key].value
|
19
|
+
else
|
20
|
+
self[key]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def set(path, value)
|
26
|
+
key, subkeys = split_path(path)
|
27
|
+
if subkeys.any?
|
28
|
+
self[key] ||= LazyHash.new({})
|
29
|
+
self[key].set(subkeys, value)
|
30
|
+
else
|
31
|
+
if self[key].is_a? Droom::Preference
|
32
|
+
self[key].set(value)
|
33
|
+
else
|
34
|
+
self[key] = value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_path?(path)
|
40
|
+
key, subkeys = split_path(path)
|
41
|
+
if subkeys.any?
|
42
|
+
self[key.to_sym].has_path?(subkeys)
|
43
|
+
else
|
44
|
+
self.has_key?(key.to_sym)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def split_path(key)
|
49
|
+
keys = path.is_a?(Array) ? path : path.to_s.split(':')
|
50
|
+
[keys.shift, keys]
|
51
|
+
end
|
52
|
+
|
53
|
+
def method_missing(method_name, *args, &blk)
|
54
|
+
return self.get(method_name, &blk) if has_path?(method_name)
|
55
|
+
match = method_name.to_s.match(/(.*?)([?=]?)$/)
|
56
|
+
case match[2]
|
57
|
+
when "="
|
58
|
+
self.set(match[1], args.first)
|
59
|
+
when "?"
|
60
|
+
!!self[match[1]]
|
61
|
+
else
|
62
|
+
default(method_name, *args, &blk)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|