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,134 @@
|
|
|
1
|
+
require 'zip/zip'
|
|
2
|
+
require 'open-uri'
|
|
3
|
+
|
|
4
|
+
module Droom
|
|
5
|
+
class Folder < ActiveRecord::Base
|
|
6
|
+
attr_accessible :name, :parent, :parent_id
|
|
7
|
+
|
|
8
|
+
belongs_to :created_by, :class_name => "Droom::User"
|
|
9
|
+
belongs_to :holder, :polymorphic => true
|
|
10
|
+
has_many :documents, :dependent => :destroy
|
|
11
|
+
has_many :personal_folders, :dependent => :destroy
|
|
12
|
+
acts_as_tree :order => "name ASC"
|
|
13
|
+
|
|
14
|
+
validates :slug, :presence => true, :uniqueness => { :scope => :parent_id }
|
|
15
|
+
|
|
16
|
+
before_validation :set_properties
|
|
17
|
+
before_validation :ensure_slug
|
|
18
|
+
|
|
19
|
+
default_scope includes(:documents)
|
|
20
|
+
|
|
21
|
+
scope :all_private, where("#{table_name}.private = 1")
|
|
22
|
+
scope :not_private, where("#{table_name}.private <> 1 OR #{table_name}.private IS NULL")
|
|
23
|
+
scope :all_public, where("#{table_name}.public = 1 AND #{table_name}.private <> 1 OR #{table_name}.private IS NULL")
|
|
24
|
+
scope :not_public, where("#{table_name}.public <> 1 OR #{table_name}.private = 1)")
|
|
25
|
+
scope :by_name, order("#{table_name}.name ASC")
|
|
26
|
+
scope :visible_to, lambda { |person|
|
|
27
|
+
# if person
|
|
28
|
+
# select('droom_folders.*')
|
|
29
|
+
# .joins('LEFT OUTER JOIN droom_personal_folders AS dpf ON droom_folders.id = dpf.folder_id')
|
|
30
|
+
# .where(["(droom_folders.public = 1 OR dpf.person_id = ?)", person.id])
|
|
31
|
+
# .group('droom_folders.id')
|
|
32
|
+
# else
|
|
33
|
+
# all_public
|
|
34
|
+
# end
|
|
35
|
+
not_private
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def visible_to?(person)
|
|
39
|
+
true
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# A root folders is created automatically for each class that has_folder,
|
|
43
|
+
# the first time something in that class asks for its folder.
|
|
44
|
+
# scope :roots, where('droom_folders.holder_type IS NULL AND droom_folders.parent_id IS NULL')
|
|
45
|
+
|
|
46
|
+
scope :loose, where('parent_id IS NULL')
|
|
47
|
+
|
|
48
|
+
scope :populated, select('droom_folders.*')
|
|
49
|
+
.joins('LEFT OUTER JOIN droom_documents AS dd ON droom_folders.id = dd.folder_id LEFT OUTER JOIN droom_folders AS df ON droom_folders.id = df.parent_id')
|
|
50
|
+
.having('count(dd.id) > 0 OR count(df.id) > 0')
|
|
51
|
+
.group('droom_folders.id')
|
|
52
|
+
|
|
53
|
+
scope :latest, lambda {|limit|
|
|
54
|
+
order("updated_at DESC, created_at DESC").limit(limit)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
def path
|
|
58
|
+
"#{parent.path if parent}/#{slug}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def documents_zipped
|
|
62
|
+
if self.documents.any?
|
|
63
|
+
tempfile = Tempfile.new("droom-temp-#{slug}-#{Time.now}.zip")
|
|
64
|
+
Zip::ZipOutputStream.open(tempfile.path) do |z|
|
|
65
|
+
self.documents.each do |doc|
|
|
66
|
+
z.add(doc.file_file_name, doc.original_file)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
tempfile
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def populated?
|
|
74
|
+
children.any? || documents.any?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def empty?
|
|
78
|
+
!populated?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def simple?
|
|
82
|
+
children.empty? && documents.count <= 2
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# If we start to get deep folder trees we'll have to use ancestry instead of acts_as_tree.
|
|
86
|
+
def family
|
|
87
|
+
self_and_children
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def loose?
|
|
91
|
+
!parent
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def ancestor_of?(folder)
|
|
95
|
+
folder && folder.ancestors.include?(self)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def copy_to_dropbox(user)
|
|
99
|
+
Rails.logger.warn ">>> creating dropbox subfolder #{slug} for user #{user.name}"
|
|
100
|
+
documents.each { |doc| doc.copy_to_dropbox(user) }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def dropboxed_for?(user)
|
|
104
|
+
# user.person && dropbox_documents.for_person(person).any?
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def copy_to_dav
|
|
108
|
+
Rails.logger.warn ">>> copy folder #{@folder.inspect} to DAV"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def get_name_from_holder
|
|
112
|
+
send :set_properties
|
|
113
|
+
self.save if self.changed?
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
protected
|
|
117
|
+
|
|
118
|
+
def set_properties
|
|
119
|
+
if holder
|
|
120
|
+
self.name ||= holder.name
|
|
121
|
+
self.slug ||= holder.slug
|
|
122
|
+
end
|
|
123
|
+
# folders originally only had slugs, so this happens from time to time
|
|
124
|
+
self.name ||= self.slug
|
|
125
|
+
self.public = !holder && (!parent || parent.public?)
|
|
126
|
+
true
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def ensure_slug
|
|
130
|
+
ensure_presence_and_uniqueness_of(:slug, name.parameterize)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
end
|
|
134
|
+
end
|
data/app/models/droom/group.rb
CHANGED
|
@@ -2,53 +2,77 @@ module Droom
|
|
|
2
2
|
class Group < ActiveRecord::Base
|
|
3
3
|
attr_accessible :name, :leader_id, :description
|
|
4
4
|
|
|
5
|
-
belongs_to :created_by, :class_name =>
|
|
5
|
+
belongs_to :created_by, :class_name => "Droom::User"
|
|
6
6
|
belongs_to :leader, :class_name => 'Person'
|
|
7
7
|
|
|
8
|
+
has_folder
|
|
9
|
+
|
|
8
10
|
has_many :group_invitations, :dependent => :destroy, :uniq => true
|
|
9
11
|
has_many :events, :through => :group_invitations
|
|
10
12
|
|
|
11
13
|
has_many :memberships, :dependent => :destroy
|
|
12
14
|
has_many :people, :through => :memberships, :uniq => true
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
|
|
16
|
+
before_validation :ensure_slug
|
|
17
|
+
before_validation :ensure_mailing_list_name
|
|
18
|
+
|
|
19
|
+
validates :slug, :uniqueness => true, :presence => true
|
|
20
|
+
validates :mailing_list_name, :uniqueness => true, :presence => true
|
|
21
|
+
|
|
22
|
+
searchable do
|
|
23
|
+
text :name, :boost => 10, :stored => true
|
|
24
|
+
text :description, :stored => true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
handle_asynchronously :solr_index
|
|
28
|
+
|
|
29
|
+
def self.highlight_fields
|
|
30
|
+
[:name, :description]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
scope :all_private, where("private = 1")
|
|
34
|
+
scope :not_private, where("private <> 1 OR private IS NULL")
|
|
35
|
+
scope :all_public, where("public = 1 AND private <> 1 OR private IS NULL")
|
|
36
|
+
scope :not_public, where("public <> 1 OR private = 1)")
|
|
37
|
+
|
|
38
|
+
scope :visible_to, lambda { |person|
|
|
39
|
+
if person
|
|
40
|
+
if person.admin?
|
|
41
|
+
scoped({})
|
|
42
|
+
else
|
|
43
|
+
select('droom_groups.*')
|
|
44
|
+
.joins('INNER JOIN droom_memberships as dm on droom_groups.id = dm.group_id')
|
|
45
|
+
.where(['dm.person_id = ?', person.id])
|
|
46
|
+
.group('droom_groups.id')
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
where("1=0")
|
|
50
|
+
end
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
scope :matching, lambda { |fragment|
|
|
26
54
|
fragment = "%#{fragment}%"
|
|
27
55
|
where('droom_groups.name like ?', fragment)
|
|
28
56
|
}
|
|
29
|
-
|
|
57
|
+
|
|
30
58
|
default_scope order("droom_groups.created_at ASC")
|
|
31
|
-
|
|
32
|
-
def identifier
|
|
33
|
-
'group'
|
|
34
|
-
end
|
|
35
|
-
|
|
59
|
+
|
|
36
60
|
def admit(person)
|
|
37
61
|
self.people << person
|
|
38
62
|
end
|
|
39
|
-
|
|
63
|
+
|
|
40
64
|
def attach(doc)
|
|
41
|
-
self.documents << doc
|
|
65
|
+
# self.documents << doc
|
|
42
66
|
end
|
|
43
67
|
|
|
44
68
|
def membership_for(person)
|
|
45
69
|
self.memberships.for(person).first
|
|
46
70
|
end
|
|
47
|
-
|
|
71
|
+
|
|
48
72
|
def invite_to(event)
|
|
49
73
|
group_invitations.find_or_create_by_event_id(event.id)
|
|
50
74
|
end
|
|
51
|
-
|
|
75
|
+
|
|
52
76
|
def uninvite_from(event)
|
|
53
77
|
group_invitation = group_invitations.find_by_event_id(event.id)
|
|
54
78
|
group_invitation.invitations.to_event(event).each do |invitation|
|
|
@@ -57,10 +81,27 @@ module Droom
|
|
|
57
81
|
group_invitation.destroy!
|
|
58
82
|
end
|
|
59
83
|
|
|
84
|
+
def invited_to?(event)
|
|
85
|
+
group_invitations.to_event(event).any?
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def as_suggestion
|
|
89
|
+
{
|
|
90
|
+
:type => 'group',
|
|
91
|
+
:prompt => name,
|
|
92
|
+
:value => name,
|
|
93
|
+
:id => id
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
60
97
|
protected
|
|
61
|
-
|
|
62
|
-
def
|
|
98
|
+
|
|
99
|
+
def ensure_slug
|
|
63
100
|
ensure_presence_and_uniqueness_of(:slug, name.parameterize)
|
|
64
101
|
end
|
|
102
|
+
|
|
103
|
+
def ensure_mailing_list_name
|
|
104
|
+
ensure_presence_and_uniqueness_of(:mailing_list_name, slug)
|
|
105
|
+
end
|
|
65
106
|
end
|
|
66
|
-
end
|
|
107
|
+
end
|
|
@@ -6,18 +6,27 @@ module Droom
|
|
|
6
6
|
belongs_to :group
|
|
7
7
|
belongs_to :event
|
|
8
8
|
has_many :invitations, :dependent => :destroy
|
|
9
|
-
|
|
9
|
+
after_save :create_personal_invitations
|
|
10
10
|
validates_uniqueness_of :group_id, :scope => :event_id
|
|
11
11
|
|
|
12
12
|
scope :to_event, lambda { |event|
|
|
13
|
-
where("
|
|
13
|
+
where("droom_group_invitations.event_id = ?", event.id)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
scope :for_group, lambda { |group|
|
|
17
|
+
where("droom_group_invitations.group_id = ?", group.id)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
16
21
|
def create_personal_invitations
|
|
17
22
|
group.people.each do |person|
|
|
18
|
-
|
|
23
|
+
create_personal_invitation_for(person)
|
|
19
24
|
end
|
|
20
25
|
end
|
|
26
|
+
|
|
27
|
+
def create_personal_invitation_for(person)
|
|
28
|
+
event.invitations.find_or_create_by_person_id(person.id) if person.member_of?(group)
|
|
29
|
+
end
|
|
21
30
|
|
|
22
31
|
end
|
|
23
32
|
end
|
|
@@ -7,24 +7,66 @@ module Droom
|
|
|
7
7
|
belongs_to :group_invitation
|
|
8
8
|
belongs_to :created_by, :class_name => "User"
|
|
9
9
|
|
|
10
|
-
after_create :
|
|
11
|
-
after_destroy :
|
|
10
|
+
after_create :link_folder
|
|
11
|
+
after_destroy :unlink_folder
|
|
12
|
+
# after_destroy :delete_similar
|
|
12
13
|
|
|
13
14
|
validates_uniqueness_of :person_id, :scope => [:event_id, :group_invitation_id]
|
|
14
15
|
|
|
15
16
|
scope :to_event, lambda { |event|
|
|
16
17
|
where(["event_id = ?", event.id])
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
scope :for_person, lambda { |person|
|
|
21
|
+
where("droom_invitations.person_id = ?", person.id)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
scope :future, lambda {
|
|
25
|
+
select('droom_invitations.*')
|
|
26
|
+
.joins('inner join droom_events as de on droom_invitations.event_id = de.id')
|
|
27
|
+
.where(['de.start > :now', :now => Time.now])
|
|
28
|
+
.group('droom_invitations.id')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
scope :refused, where("response < 1")
|
|
32
|
+
scope :accepted, where("response > 1")
|
|
33
|
+
scope :not_refused, where("response > 0")
|
|
34
|
+
scope :not_accepted, where("response < 2")
|
|
35
|
+
scope :responded, where("response <> 1")
|
|
36
|
+
scope :not_responded, where("response == 1")
|
|
20
37
|
|
|
21
|
-
def
|
|
22
|
-
person.
|
|
38
|
+
def link_folder
|
|
39
|
+
person.add_personal_folders(event.folder)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def unlink_folder
|
|
43
|
+
person.remove_personal_folders(event.folder)
|
|
23
44
|
end
|
|
24
45
|
|
|
25
|
-
def
|
|
26
|
-
|
|
46
|
+
def status
|
|
47
|
+
if response < 1
|
|
48
|
+
"refused"
|
|
49
|
+
elsif response == 1
|
|
50
|
+
"maybe"
|
|
51
|
+
else
|
|
52
|
+
"accepted"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def accepted?
|
|
57
|
+
response && response > 1
|
|
27
58
|
end
|
|
28
59
|
|
|
60
|
+
def refused?
|
|
61
|
+
response && response < 1
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
protected
|
|
65
|
+
|
|
66
|
+
def delete_similar
|
|
67
|
+
Droom::Invitation.for_person(person).to_event(event).delete_all
|
|
68
|
+
end
|
|
69
|
+
|
|
29
70
|
end
|
|
71
|
+
|
|
30
72
|
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# This class has the awkward job of giving access to the mailing list membership records stored in
|
|
2
|
+
# legacy mailman mysql tables. They're likely to be held in another database, and they have an extremely
|
|
3
|
+
# un-rails-like schema, so our main job is to translate between their and our conventions.
|
|
4
|
+
#
|
|
5
|
+
# This whole mechanism and its configuration requirements can safely be ignored unless you want to
|
|
6
|
+
# use it, in which case you should set `Droom.enable_mailing_lists` to true in an initializer and read on.
|
|
7
|
+
#
|
|
8
|
+
# If you don't set `enable_mailing_lists` then some database activity will still go on, but with no
|
|
9
|
+
# consequence, and the mailing list interface controls will not appear.
|
|
10
|
+
#
|
|
11
|
+
## Requirements
|
|
12
|
+
#
|
|
13
|
+
# The MailingListMembership class is able to interface directly with your existing mailman data, with
|
|
14
|
+
# the addition of a couple of columns to support activerecord associations. It's mostly just a case of
|
|
15
|
+
# configuring access to the old data.
|
|
16
|
+
#
|
|
17
|
+
# ### Mailman data held in MySQL tables with the 'flat' data structure
|
|
18
|
+
#
|
|
19
|
+
# There are two options here. Either you can use the standard table that has already been created here,
|
|
20
|
+
# or you can define a `mailman_[env]` connection in database.yml that points to an external mailman
|
|
21
|
+
# database. In that case see the notes below about adding a couple of columns.
|
|
22
|
+
#
|
|
23
|
+
# ### Mailman configured to use MySQL
|
|
24
|
+
#
|
|
25
|
+
# If you don't have an existing mailmanmysql setup, it takes a few steps to point your mailman installation
|
|
26
|
+
# at this database and table. It can be done either globally or on a per-list basis, so it is possible
|
|
27
|
+
# to keep your existing mailman installation but add a new database-backed mailing list.
|
|
28
|
+
#
|
|
29
|
+
# Mysql storage is considered modern and a bit racy in the mailman community, having only been available
|
|
30
|
+
# since the early 2000s. It's not officially supported until mailman 3 coalesces out of the ether but if
|
|
31
|
+
# you speak any python it's easy to make it work with 2.x. Two sets of dusty patches are available here:
|
|
32
|
+
#
|
|
33
|
+
# http://wiki.list.org/pages/viewpage.action?pageId=15564884
|
|
34
|
+
#
|
|
35
|
+
# and I've found the slightly less ancient version from rezo.net works well:
|
|
36
|
+
#
|
|
37
|
+
# http://trac.rezo.net/trac/rezo/browser/Mailman
|
|
38
|
+
#
|
|
39
|
+
# In order that we can store membership of different lists in the same table, please make sure that
|
|
40
|
+
# mailman is using the 'flat' data structure. If you want to enable mysql just for selected lists,
|
|
41
|
+
# put an `extend.py` in each list directory and leave the rest of your configuration as it is.
|
|
42
|
+
#
|
|
43
|
+
# It is currently a good idea to avoid reserved words in your mailing list names. They'll work in rails
|
|
44
|
+
# but not in python, where the quoting of some database queries seems to be less than perfect.
|
|
45
|
+
#
|
|
46
|
+
# ### Minor changes to the mailman table
|
|
47
|
+
#
|
|
48
|
+
# The local table is already set up in a way that should work equally well with rails and mailman.
|
|
49
|
+
# If you're using a remote mailman table, it will need a couple of small changes:
|
|
50
|
+
#
|
|
51
|
+
# **An id column as primary key.** Strictly speaking we should define a composite primary key based
|
|
52
|
+
# on address & listname, but it's much easier just to add an auto_incrementing id column and make
|
|
53
|
+
# that the primary key. Mailman doesn't care as long as its columns are there. You probably also want
|
|
54
|
+
# to create a unique index on address+listname so that mailman gets the benefit and sees the expected
|
|
55
|
+
# behaviour.
|
|
56
|
+
#
|
|
57
|
+
# **A membership_id column** We could (and used to) twist Activerecord out of shape by defining
|
|
58
|
+
# associations with address and listname primary keys between mailing list memberships and people
|
|
59
|
+
# and groups, but again it's much easier just to belong_to a group membership. For that we need a
|
|
60
|
+
# membership_id column. Again, you will want an index on that column.
|
|
61
|
+
|
|
62
|
+
module Droom
|
|
63
|
+
class MailingListMembership < ActiveRecord::Base
|
|
64
|
+
attr_accessible :address, :listname, :digest, :not_metoo, :nomail, :plain, :ack
|
|
65
|
+
#
|
|
66
|
+
## Configuration
|
|
67
|
+
#
|
|
68
|
+
# A dedicated mailman database connection can be defined in the host app's config/database.yml as
|
|
69
|
+
# `mailman_development` or `mailman_production` if you want us to use an existing mailman database.
|
|
70
|
+
# We can only work with the 'flat' database structure, where all the list memberships are held in
|
|
71
|
+
# one table.
|
|
72
|
+
#
|
|
73
|
+
# If no such connection is defined, we will use the local `droom_mailing_list_memberships` table.
|
|
74
|
+
#
|
|
75
|
+
begin
|
|
76
|
+
establish_connection :"mailman_#{Rails.env}"
|
|
77
|
+
set_table_name Droom.mailman_table_name
|
|
78
|
+
rescue ActiveRecord::AdapterNotSpecified
|
|
79
|
+
Rails.logger.warn "Droom: No mailman connection configured. Using #{Rails.env} database."
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
## Associations
|
|
83
|
+
#
|
|
84
|
+
# Giving membership of a group will create a mailing list membership automatically.
|
|
85
|
+
# The activity status of the created mlm depends on the `Droom.mailing_lists_active_by_default`
|
|
86
|
+
# setting, and its effect depends of course on your mailman setup.
|
|
87
|
+
#
|
|
88
|
+
belongs_to :membership
|
|
89
|
+
before_create :set_defaults
|
|
90
|
+
|
|
91
|
+
validates :address, :uniqueness => {:scope => :listname}
|
|
92
|
+
|
|
93
|
+
## Translation
|
|
94
|
+
#
|
|
95
|
+
# Mailman's boolean columns are held as Y/N so we intervene to translate.
|
|
96
|
+
#
|
|
97
|
+
[:digest, :not_metoo, :nomail, :plain, :ack].each do |col|
|
|
98
|
+
define_method(col) do
|
|
99
|
+
read_attribute(col) == 'Y'
|
|
100
|
+
end
|
|
101
|
+
define_method("#{col}?") do
|
|
102
|
+
read_attribute(col) == 'Y'
|
|
103
|
+
end
|
|
104
|
+
define_method("#{col}=") do |value|
|
|
105
|
+
write_attribute(col, to_yesno(value))
|
|
106
|
+
end
|
|
107
|
+
define_method("#{col}_before_type_cast") do
|
|
108
|
+
read_attribute(col) == 'Y' ? 1 : 0
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
private
|
|
113
|
+
|
|
114
|
+
def set_defaults
|
|
115
|
+
self.bi_lastnotice = 0
|
|
116
|
+
self.bi_date = 0
|
|
117
|
+
self.ack = true
|
|
118
|
+
self.nomail = !Droom.mailing_lists_active_by_default?
|
|
119
|
+
self.digest = Droom.mailing_lists_digest_by_default?
|
|
120
|
+
true
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def to_yesno(value)
|
|
124
|
+
(value && value != 0 && value != "0" && value != "N") ? 'Y' : 'N'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|
|
128
|
+
end
|