droom 0.0.1 → 0.2.1
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/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
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Droom
|
|
2
|
+
class PersonalFolder < ActiveRecord::Base
|
|
3
|
+
belongs_to :person
|
|
4
|
+
belongs_to :folder
|
|
5
|
+
|
|
6
|
+
def copy_to_dropbox
|
|
7
|
+
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def copy_to_dav
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#todo: lifted from Person and awaiting translation
|
|
15
|
+
#
|
|
16
|
+
# def create_and_update_dav_directories
|
|
17
|
+
# document_links.each do |dl|
|
|
18
|
+
# p "-> creating DAV directory #{dl.slug}"
|
|
19
|
+
# create_dav_directory(dl.slug)
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# def create_dav_directory(name)
|
|
24
|
+
# FileUtils.mkdir_p(Rails.root + "#{Droom.dav_root}/#{self.id}/#{name}")
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
|
|
28
|
+
# association helpers give us more readable logic elsewhere.
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Preferences...
|
|
2
|
+
|
|
3
|
+
module Droom
|
|
4
|
+
class Preference < ActiveRecord::Base
|
|
5
|
+
attr_accessible :key, :value, :uuid
|
|
6
|
+
belongs_to :created_by, :class_name => "Droom::User"
|
|
7
|
+
validates :key, :presence => true, :uniqueness => true
|
|
8
|
+
|
|
9
|
+
def set(value)
|
|
10
|
+
if boolean?
|
|
11
|
+
self.value = value ? 1 : 0
|
|
12
|
+
else
|
|
13
|
+
self.value = value
|
|
14
|
+
end
|
|
15
|
+
self.save if changed?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get
|
|
19
|
+
if boolean?
|
|
20
|
+
value.to_i == 1
|
|
21
|
+
else
|
|
22
|
+
value
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def boolean?
|
|
27
|
+
key.last == "?"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def uuid
|
|
31
|
+
self[:uuid] ||= SecureRandom.uuid
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
module Droom
|
|
2
|
+
class Scrap < ActiveRecord::Base
|
|
3
|
+
belongs_to :created_by, :class_name => "Droom::User"
|
|
4
|
+
belongs_to :event, :class_name => "Droom::Event"
|
|
5
|
+
accepts_nested_attributes_for :event
|
|
6
|
+
|
|
7
|
+
belongs_to :document, :class_name => "Droom::Document", :dependent => :destroy
|
|
8
|
+
accepts_nested_attributes_for :document
|
|
9
|
+
|
|
10
|
+
has_upload :image,
|
|
11
|
+
:geometry => "580x326#",
|
|
12
|
+
:styles => {
|
|
13
|
+
:icon => "32x18#",
|
|
14
|
+
:thumb => "160x90#",
|
|
15
|
+
:precrop => "1200x1200^"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
searchable do
|
|
19
|
+
text :name, :boost => 10, :stored => true
|
|
20
|
+
text :body, :stored => true
|
|
21
|
+
text :note
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.highlight_fields
|
|
25
|
+
[:name, :body]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
attr_accessible :name, :body, :image, :description, :scraptype, :note, :created_by, :event, :event_attributes, :document, :document_attributes
|
|
29
|
+
before_save :get_youtube_thumbnail
|
|
30
|
+
|
|
31
|
+
scope :by_date, order("droom_scraps.created_at DESC")
|
|
32
|
+
|
|
33
|
+
scope :later_than, lambda { |scrap|
|
|
34
|
+
where(["created_at > ?", scrap.created_at]).order("droom_scraps.created_at ASC")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
scope :earlier_than, lambda { |scrap|
|
|
38
|
+
where(["created_at < ?", scrap.created_at]).order("droom_scraps.created_at DESC")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
scope :matching, lambda { |fragment|
|
|
42
|
+
fragment = "%#{fragment}%"
|
|
43
|
+
where('droom_scraps.name LIKE :f OR droom_scraps.body LIKE :f OR droom_scraps.note LIKE :f', :f => fragment)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
scope :visible_to, lambda { |person|
|
|
47
|
+
where("1=1")
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
Droom.scrap_types.each do |t|
|
|
51
|
+
define_method(:"#{t}?") { scraptype == t.to_s }
|
|
52
|
+
scope t.pluralize.to_sym, where(["scraptype == ?", t])
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def wordiness
|
|
56
|
+
if body.length < 48
|
|
57
|
+
'word'
|
|
58
|
+
elsif body.length < 320
|
|
59
|
+
'phrase'
|
|
60
|
+
elsif body.length < 800
|
|
61
|
+
'paragraph'
|
|
62
|
+
else
|
|
63
|
+
'text'
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def text_size
|
|
68
|
+
if l = body.length
|
|
69
|
+
((560.0/(1.4 * l+150.0)) + 0.25) / 1.5
|
|
70
|
+
else
|
|
71
|
+
1
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def url_with_protocol
|
|
76
|
+
body =~ /^https?:\/\// ? body : "http://#{body}"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def url_without_protocol
|
|
80
|
+
body.sub(/^https?:\/\//, '')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def as_search_result
|
|
84
|
+
{
|
|
85
|
+
:type => 'scrap',
|
|
86
|
+
:prompt => name,
|
|
87
|
+
:value => name,
|
|
88
|
+
:id => id
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def next_younger
|
|
93
|
+
Droom::Scrap.later_than(self).first
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def next_older
|
|
97
|
+
Droom::Scrap.earlier_than(self).first
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
protected
|
|
101
|
+
|
|
102
|
+
def get_youtube_thumbnail
|
|
103
|
+
# youtube id is held in the 'note' column.
|
|
104
|
+
if scraptype == "video" && body?
|
|
105
|
+
self.image = URI.parse("http://img.youtube.com/vi/#{body}/0.jpg")
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Tags are simple one-word descriptors. There is no hierarchy or other structure among them.
|
|
2
|
+
# They are strictly catalogue data, used to locate people but not treated as part of the person record.
|
|
3
|
+
|
|
4
|
+
module Droom
|
|
5
|
+
class Tag < ActiveRecord::Base
|
|
6
|
+
# They are attached to people through many-to-many taggings.
|
|
7
|
+
#
|
|
8
|
+
has_many :taggings
|
|
9
|
+
has_many :taggees, :through => :taggings
|
|
10
|
+
before_save :downcase
|
|
11
|
+
|
|
12
|
+
## Suggestions
|
|
13
|
+
#
|
|
14
|
+
# There is a tag-suggesting mechanism in the front end to encourage tag reuse and consistency.
|
|
15
|
+
# It rests on this simple scope, which returns all tags matching a given string fragment.
|
|
16
|
+
#
|
|
17
|
+
scope :matching, lambda { |fragment|
|
|
18
|
+
fragment = "%#{fragment}%"
|
|
19
|
+
where('tags.name like ?', fragment)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# The public-facing search engine is faceted and relies on a similar but broader suggestion mechanism
|
|
23
|
+
# that offers both tags and institutions. In that situation we only want to display tags that will give
|
|
24
|
+
# give results, so we limit the suggestions to only those tags that have been applied to a person.
|
|
25
|
+
#
|
|
26
|
+
scope :in_use,
|
|
27
|
+
joins("INNER JOIN taggings ON taggings.tag_id = tags.id")
|
|
28
|
+
.group('tags.id')
|
|
29
|
+
.having('count(taggings.tag_id) > 0')
|
|
30
|
+
|
|
31
|
+
# This returns a list of all the tags attached to any of a given set of objects.
|
|
32
|
+
# In future it will support cloud-weighting.
|
|
33
|
+
#
|
|
34
|
+
scope :attached_to_any_of, lambda {|these|
|
|
35
|
+
these = [these].flatten
|
|
36
|
+
type = these.first.class.to_s
|
|
37
|
+
placeholders = these.map{"?"}.join(',')
|
|
38
|
+
select("droom_tags.*, count(droom_taggings.id) as use_count")
|
|
39
|
+
.joins("INNER JOIN droom_taggings ON droom_taggings.tag_id = droom_tags.id")
|
|
40
|
+
.where(["droom_taggings.taggee_type = ? and droom_taggings.taggee_id IN (#{placeholders})", *these.map(&:id).unshift(type)])
|
|
41
|
+
.group('droom_tags.id')
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Suggestions are returned in a minimal format and need only contain name and (for the public search
|
|
45
|
+
# where there are more possibilities) the type of suggestion.
|
|
46
|
+
#
|
|
47
|
+
def as_json(options={})
|
|
48
|
+
{
|
|
49
|
+
:id => id,
|
|
50
|
+
:name => name,
|
|
51
|
+
:type => 'tag'
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
## Keyword lists
|
|
56
|
+
#
|
|
57
|
+
# Sometimes we want the interface to present a simple comma-separated list.
|
|
58
|
+
# These methods help to move to and from that form.
|
|
59
|
+
#
|
|
60
|
+
def self.from_list(list=[], or_create=true)
|
|
61
|
+
list = list.split(/[,;]\s*/) if String === list
|
|
62
|
+
list.uniq.map{|t| self.for(t, or_create) }.compact if list && list.any?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Renders a set of tags as a comma-separated list.
|
|
66
|
+
#
|
|
67
|
+
def self.to_list(tags=[])
|
|
68
|
+
tags.uniq.map(&:name).join(', ')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Finds or creates a tag with the supplied title
|
|
72
|
+
#
|
|
73
|
+
def self.for(name, or_create=true)
|
|
74
|
+
if or_create
|
|
75
|
+
find_or_create_by_name(name)
|
|
76
|
+
else
|
|
77
|
+
find_by_name(name)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## Clouds
|
|
83
|
+
#
|
|
84
|
+
# The administrative interface offers a big tag cloud and drag and drop tag-merging. Tag size in the
|
|
85
|
+
# cloud is based on a usage count that is retrieved here in a join with the taggings table. The cloud
|
|
86
|
+
# display logic can be found in the [application_helper](../controllers/application_helper.html).
|
|
87
|
+
#
|
|
88
|
+
attr_accessor :cloud_size
|
|
89
|
+
scope :with_usage_count, lambda { |limit|
|
|
90
|
+
select("tags.*, count(tt.id) AS weight").joins("INNER JOIN taggings as tt ON tt.tag_id = tags.id").group("tt.tag_id").order("weight DESC").limit(limit)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# *self.for_cloud* uses that scope to return a list of the most popular tags, weighted for display as a tag cloud
|
|
94
|
+
# and re-sorted into alphabetical order (since to select the most popular we originally had to sort by weighting).
|
|
95
|
+
#
|
|
96
|
+
def self.for_cloud(limit=100)
|
|
97
|
+
with_usage_count(limit).sort_by(&:name)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# This is here just to make tag interpolation a bit more readable.
|
|
101
|
+
#
|
|
102
|
+
def to_s
|
|
103
|
+
name
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
## Admin
|
|
107
|
+
#
|
|
108
|
+
def assimilate(tag)
|
|
109
|
+
self.taggees << tag.taggees
|
|
110
|
+
tag.destroy
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
protected
|
|
114
|
+
|
|
115
|
+
def downcase
|
|
116
|
+
self.name = self.name.downcase
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Taggings are the many to many links that associated tags with people. There isn't much to see here.
|
|
2
|
+
|
|
3
|
+
module Droom
|
|
4
|
+
class Tagging < ActiveRecord::Base
|
|
5
|
+
belongs_to :tag
|
|
6
|
+
belongs_to :taggee, :polymorphic => true
|
|
7
|
+
|
|
8
|
+
# The tagging interface allows the creation of new tags on save but in normal use this would never be hit:
|
|
9
|
+
# the ajax-based tag-adder creates tags in the background so the form needs only the nested tagging fields.
|
|
10
|
+
#
|
|
11
|
+
accepts_nested_attributes_for :tag, :reject_if => :all_blank
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
module Droom
|
|
2
|
+
class User < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
attr_accessible :name, :forename, :email, :password, :password_confirmation, :admin, :newly_activated, :update_person_email, :preferences_attributes, :confirm, :old_id, :remove_person
|
|
5
|
+
has_one :person
|
|
6
|
+
has_many :dropbox_tokens, :foreign_key => "created_by_id"
|
|
7
|
+
has_many :preferences, :foreign_key => "created_by_id"
|
|
8
|
+
accepts_nested_attributes_for :preferences, :allow_destroy => true
|
|
9
|
+
|
|
10
|
+
receives_messages# :groups => [:unconfirmed, :personed, :administrative]
|
|
11
|
+
|
|
12
|
+
devise :database_authenticatable,
|
|
13
|
+
:encryptable,
|
|
14
|
+
:recoverable,
|
|
15
|
+
:rememberable,
|
|
16
|
+
:trackable,
|
|
17
|
+
:confirmable,
|
|
18
|
+
:token_authenticatable,
|
|
19
|
+
:encryptor => :sha512
|
|
20
|
+
|
|
21
|
+
before_create :ensure_authentication_token
|
|
22
|
+
|
|
23
|
+
attr_accessor :newly_activated, :update_person_email, :confirm, :remove_person
|
|
24
|
+
|
|
25
|
+
# validates :password, :length => { :minimum => 6 }, :if => :password_required?
|
|
26
|
+
|
|
27
|
+
scope :unconfirmed, where("confirmed_at IS NULL")
|
|
28
|
+
scope :administrative, where(:admin => true)
|
|
29
|
+
|
|
30
|
+
scope :personed, select("droom_users.*")
|
|
31
|
+
.joins("INNER JOIN droom_people as dp ON dp.user_id = droom_users.id")
|
|
32
|
+
|
|
33
|
+
scope :unpersoned, select("droom_users.*")
|
|
34
|
+
.joins("LEFT OUTER JOIN droom_people as dp ON dp.user_id = droom_users.id")
|
|
35
|
+
.having("count(dp.id) = 0")
|
|
36
|
+
|
|
37
|
+
scope :with_person_in_group, lambda { |group|
|
|
38
|
+
group = group.id if group.is_a? Droom::Group
|
|
39
|
+
select("droom_users.*")
|
|
40
|
+
.joins("INNER JOIN droom_people as dp ON dp.user_id = droom_users.id")
|
|
41
|
+
.joins("INNER JOIN droom_memberships as dm ON dp.id = dm.person_id")
|
|
42
|
+
.where("dm.group_id" => group)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Messaging groups are normally scopes passed through when receives_messages is called,
|
|
46
|
+
# but anything will work that can be called on the class and return a set of instances.
|
|
47
|
+
# Here we're overriding the getter so as to offer sending by group membership as well as
|
|
48
|
+
# the usual scoping.
|
|
49
|
+
#
|
|
50
|
+
def self.messaging_groups
|
|
51
|
+
unless @messaging_groups
|
|
52
|
+
@messaging_groups = {
|
|
53
|
+
:unconfirmed => lambda { Droom::User.unconfirmed},
|
|
54
|
+
:personed => lambda { Droom::User.personed },
|
|
55
|
+
:administrative => lambda { Droom::User.administrative }
|
|
56
|
+
}
|
|
57
|
+
Droom::Group.all.each do |group|
|
|
58
|
+
@messaging_groups[group.slug.to_sym] = lambda { Droom::User.with_person_in_group(group.id) }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
@messaging_groups
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def confirm=(confirmed)
|
|
65
|
+
confirm! if confirmed
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def remove_person=(boolean)
|
|
69
|
+
if boolean
|
|
70
|
+
p = Droom::Person.find(person.id)
|
|
71
|
+
p.user = nil
|
|
72
|
+
p.save!
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Password is not required on creation, contrary to the devise defaults.
|
|
77
|
+
def password_required?
|
|
78
|
+
confirmed? && (!password.blank?)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def password_match?
|
|
82
|
+
Rails.logger.warn ">>> password_match? '#{password}' == '#{password_confirmation}'"
|
|
83
|
+
self.errors[:password] << "can't be blank" if password.blank?
|
|
84
|
+
self.errors[:password_confirmation] << "can't be blank" if password_confirmation.blank?
|
|
85
|
+
self.errors[:password_confirmation] << "does not match password" if password != password_confirmation
|
|
86
|
+
password == password_confirmation && !password.blank?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def is_person?(person)
|
|
90
|
+
person == self.person
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def organisation
|
|
94
|
+
person.organisation if person
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Current user is pushed into here to make it available in models
|
|
98
|
+
# such as the UserActionObserver that sets ownership before save.
|
|
99
|
+
#
|
|
100
|
+
def self.current
|
|
101
|
+
Thread.current[:user]
|
|
102
|
+
end
|
|
103
|
+
def self.current=(user)
|
|
104
|
+
Thread.current[:user] = user
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Personal DAV repository is accessed via a DAV4rack endpoint but we have to take care of its creation and population.
|
|
108
|
+
#
|
|
109
|
+
def dav_root
|
|
110
|
+
dav_path = Rails.root + "webdav/#{id}"
|
|
111
|
+
Dir.mkdir(dav_path, 0600) unless File.exist?(dav_path)
|
|
112
|
+
dav_path
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def full_name
|
|
116
|
+
[forename, name].compact.join(' ').strip
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def formal_name
|
|
120
|
+
[title, forename, name].compact.join(' ').strip
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def informal_name
|
|
124
|
+
if Droom.use_forenames
|
|
125
|
+
forename
|
|
126
|
+
else
|
|
127
|
+
name
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def dropbox_token
|
|
132
|
+
unless @dropbox_token
|
|
133
|
+
@dropbox_token = dropbox_tokens.by_date.last || 'nope'
|
|
134
|
+
end
|
|
135
|
+
@dropbox_token unless @dropbox_token == 'nope'
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def dropbox_client
|
|
139
|
+
dropbox_token.dropbox_client if dropbox_token
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def privileged?
|
|
143
|
+
admin? || person && person.privileged?
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
## Preferences
|
|
148
|
+
#
|
|
149
|
+
# User settings are held as an association with Preference objects, which are simple key:value pairs.
|
|
150
|
+
# The keys are usually colon:separated for namespacing purposes, eg:
|
|
151
|
+
#
|
|
152
|
+
# current_user.pref("email:enabled?")
|
|
153
|
+
# current_user.pref("dropbox:enabled?")
|
|
154
|
+
#
|
|
155
|
+
# Default settings are defined in Droom.user_defaults and can be defined in an initializer if the default droom
|
|
156
|
+
# defaults are not right for your application.
|
|
157
|
+
#
|
|
158
|
+
# `User#pref(key)` returns the **value** of the preference (whether set or default) for the given key. It is intended
|
|
159
|
+
# for use in views:
|
|
160
|
+
#
|
|
161
|
+
# - if current_user.pref("dropbox:enabled?")
|
|
162
|
+
# = link_to "copy to dropbox", dropbox_folder_url(folder)
|
|
163
|
+
#
|
|
164
|
+
def pref(key)
|
|
165
|
+
if pref = preferences.find_by_key(key)
|
|
166
|
+
pref.value
|
|
167
|
+
else
|
|
168
|
+
Droom.user_default(key)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# `User#preference(key)` always returns a preference object and is used to build control panels. If no preference
|
|
173
|
+
# is saved for the given key, we return a new (unsaved) one with that key and the default value.
|
|
174
|
+
#
|
|
175
|
+
def preference(key)
|
|
176
|
+
pref = preferences.find_or_initialize_by_key(key)
|
|
177
|
+
pref.value = Droom.user_default(key) unless pref.persisted?
|
|
178
|
+
pref
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Setting preferences is normally handled either by the PreferencesController or by nesting preferences
|
|
182
|
+
# in a user form. `User#set_pref` is a convenient console method but not otherwise used much.
|
|
183
|
+
#
|
|
184
|
+
# Preferences are set in a simple key:value way, where key usually includes some namespacing prefixes:
|
|
185
|
+
#
|
|
186
|
+
# user.set_pref("email:enabled", true)
|
|
187
|
+
#
|
|
188
|
+
def set_pref(key, value)
|
|
189
|
+
preferences.find_or_create_by_key(key).set(value)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
## Email
|
|
193
|
+
#
|
|
194
|
+
# If using `msg`, this defines the variables available in message templates.
|
|
195
|
+
#
|
|
196
|
+
def for_email
|
|
197
|
+
{
|
|
198
|
+
:informal_name => informal_name,
|
|
199
|
+
:formal_name => formal_name,
|
|
200
|
+
:forename => forename,
|
|
201
|
+
:name => name,
|
|
202
|
+
:email => email,
|
|
203
|
+
:confirmation_url => Droom::Engine.routes.url_helpers.new_user_confirmation_url(self, :confirmation_token => self.confirmation_token, :host => ActionMailer::Base.default_url_options[:host]),
|
|
204
|
+
:sign_in_url => Droom::Engine.routes.url_helpers.new_user_session_path(:host => ActionMailer::Base.default_url_options[:host]),
|
|
205
|
+
:password_reset_url => Droom::Engine.routes.url_helpers.new_user_password_path(self, :host => ActionMailer::Base.default_url_options[:host])
|
|
206
|
+
}
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
end
|
|
211
|
+
end
|