calagator 0.0.1.pre1
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +23 -0
- data/README.md +75 -0
- data/Rakefile +12 -0
- data/app/assets/images/confused-alligator-sm.png +0 -0
- data/app/assets/images/disk.png +0 -0
- data/app/assets/images/edit.png +0 -0
- data/app/assets/images/external_sites/epdx.png +0 -0
- data/app/assets/images/external_sites/external.gif +0 -0
- data/app/assets/images/external_sites/facebook.png +0 -0
- data/app/assets/images/external_sites/foursquare.png +0 -0
- data/app/assets/images/external_sites/gowalla.png +0 -0
- data/app/assets/images/external_sites/lanyrd.png +0 -0
- data/app/assets/images/external_sites/meetup.png +0 -0
- data/app/assets/images/external_sites/plancast.png +0 -0
- data/app/assets/images/external_sites/shizzow.png +0 -0
- data/app/assets/images/external_sites/upcoming.png +0 -0
- data/app/assets/images/external_sites/yelp.png +0 -0
- data/app/assets/images/feed.png +0 -0
- data/app/assets/images/heart.png +0 -0
- data/app/assets/images/icon_ical.gif +0 -0
- data/app/assets/images/information.png +0 -0
- data/app/assets/images/nav_marker.gif +0 -0
- data/app/assets/images/nav_marker.png +0 -0
- data/app/assets/images/plus.png +0 -0
- data/app/assets/images/redx.png +0 -0
- data/app/assets/images/site-icon.png +0 -0
- data/app/assets/images/spinner.gif +0 -0
- data/app/assets/images/star.png +0 -0
- data/app/assets/images/subnav_marker.gif +0 -0
- data/app/assets/images/subnav_marker.png +0 -0
- data/app/assets/images/tag_blue.png +0 -0
- data/app/assets/images/tag_icons/angular.png +0 -0
- data/app/assets/images/tag_icons/beer.png +0 -0
- data/app/assets/images/tag_icons/bitcoin.png +0 -0
- data/app/assets/images/tag_icons/free.png +0 -0
- data/app/assets/images/tag_icons/golang.png +0 -0
- data/app/assets/images/tag_icons/html.png +0 -0
- data/app/assets/images/tag_icons/javascript.png +0 -0
- data/app/assets/images/tag_icons/linux.png +0 -0
- data/app/assets/images/tag_icons/php.png +0 -0
- data/app/assets/images/tag_icons/pizza.png +0 -0
- data/app/assets/images/tag_icons/python.png +0 -0
- data/app/assets/images/tag_icons/rails.png +0 -0
- data/app/assets/images/tag_icons/ruby.png +0 -0
- data/app/assets/images/tag_icons/sass.png +0 -0
- data/app/assets/images/tag_icons/swift.png +0 -0
- data/app/assets/images/transmit_blue.png +0 -0
- data/app/assets/images/weekday_background.gif +0 -0
- data/app/assets/javascripts/calagator.js +18 -0
- data/app/assets/javascripts/calagator/forms.js +60 -0
- data/app/assets/stylesheets/calagator.scss +8 -0
- data/app/assets/stylesheets/calagator/common.scss +14 -0
- data/app/assets/stylesheets/calagator/datepicker.scss +177 -0
- data/app/assets/stylesheets/calagator/errors.css +110 -0
- data/app/assets/stylesheets/calagator/forms.scss +4 -0
- data/app/assets/stylesheets/calagator/reset.css +40 -0
- data/app/assets/stylesheets/calagator/theme.css +0 -0
- data/app/controllers/calagator/admin_controller.rb +27 -0
- data/app/controllers/calagator/application_controller.rb +82 -0
- data/app/controllers/calagator/events_controller.rb +171 -0
- data/app/controllers/calagator/site_controller.rb +35 -0
- data/app/controllers/calagator/sources_controller.rb +94 -0
- data/app/controllers/calagator/venues_controller.rb +133 -0
- data/app/controllers/calagator/versions_controller.rb +20 -0
- data/app/helpers/calagator/application_helper.rb +128 -0
- data/app/helpers/calagator/events_helper.rb +184 -0
- data/app/helpers/calagator/google_event_export_helper.rb +67 -0
- data/app/helpers/calagator/mapping_helper.rb +103 -0
- data/app/helpers/calagator/sources_helper.rb +10 -0
- data/app/helpers/calagator/tags_helper.rb +42 -0
- data/app/helpers/calagator/time_range_helper.rb +166 -0
- data/app/models/calagator/event.rb +246 -0
- data/app/models/calagator/event/cloner.rb +39 -0
- data/app/models/calagator/event/ical_renderer.rb +155 -0
- data/app/models/calagator/event/overview.rb +45 -0
- data/app/models/calagator/event/saver.rb +58 -0
- data/app/models/calagator/event/search.rb +72 -0
- data/app/models/calagator/event/search_engine.rb +28 -0
- data/app/models/calagator/event/search_engine/apache_sunspot.rb +106 -0
- data/app/models/calagator/event/search_engine/sql.rb +107 -0
- data/app/models/calagator/source.rb +115 -0
- data/app/models/calagator/source/importer.rb +46 -0
- data/app/models/calagator/source/parser.rb +128 -0
- data/app/models/calagator/source/parser/facebook.rb +67 -0
- data/app/models/calagator/source/parser/hcal.rb +108 -0
- data/app/models/calagator/source/parser/http_authentication_required_error.rb +6 -0
- data/app/models/calagator/source/parser/ical.rb +186 -0
- data/app/models/calagator/source/parser/meetup.rb +72 -0
- data/app/models/calagator/source/parser/not_found.rb +9 -0
- data/app/models/calagator/source/parser/plancast.rb +59 -0
- data/app/models/calagator/venue.rb +161 -0
- data/app/models/calagator/venue/geocoder.rb +51 -0
- data/app/models/calagator/venue/search.rb +63 -0
- data/app/models/calagator/venue/search_engine.rb +24 -0
- data/app/models/calagator/venue/search_engine/apache_sunspot.rb +85 -0
- data/app/models/calagator/venue/search_engine/sql.rb +68 -0
- data/app/models/event/search_engine/base.rb +0 -0
- data/app/observers/calagator/cache_observer.rb +37 -0
- data/app/views/calagator/admin/events.html.erb +28 -0
- data/app/views/calagator/admin/index.html.erb +8 -0
- data/app/views/calagator/events/_feed_item.html.erb +62 -0
- data/app/views/calagator/events/_form.html.erb +63 -0
- data/app/views/calagator/events/_gcal_reminder.html.erb +1 -0
- data/app/views/calagator/events/_hcal.html.erb +41 -0
- data/app/views/calagator/events/_item.html.erb +120 -0
- data/app/views/calagator/events/_list.html.erb +30 -0
- data/app/views/calagator/events/_list_item.html.erb +37 -0
- data/app/views/calagator/events/_search_section.html.erb +15 -0
- data/app/views/calagator/events/_subnav.html.erb +13 -0
- data/app/views/calagator/events/_table.html.erb +74 -0
- data/app/views/calagator/events/duplicates.html.erb +58 -0
- data/app/views/calagator/events/edit.html.erb +3 -0
- data/app/views/calagator/events/index.atom.builder +32 -0
- data/app/views/calagator/events/index.html.erb +51 -0
- data/app/views/calagator/events/index.kml.erb +20 -0
- data/app/views/calagator/events/new.html.erb +7 -0
- data/app/views/calagator/events/search.html.erb +25 -0
- data/app/views/calagator/events/show.html.erb +81 -0
- data/app/views/calagator/site/_appropriateness_message.html.erb +15 -0
- data/app/views/calagator/site/_description.html.erb +3 -0
- data/app/views/calagator/site/about.html.erb +7 -0
- data/app/views/calagator/site/defunct.html.erb +15 -0
- data/app/views/calagator/site/export.html.erb +4 -0
- data/app/views/calagator/site/index.html.erb +40 -0
- data/app/views/calagator/site/opensearch.xml.builder +8 -0
- data/app/views/calagator/sources/_subnav.html.erb +0 -0
- data/app/views/calagator/sources/edit.html.erb +12 -0
- data/app/views/calagator/sources/import.html.erb +10 -0
- data/app/views/calagator/sources/index.html.erb +22 -0
- data/app/views/calagator/sources/new.html.erb +32 -0
- data/app/views/calagator/sources/show.html.erb +16 -0
- data/app/views/calagator/venues/_form.html.erb +57 -0
- data/app/views/calagator/venues/_subnav.html.erb +10 -0
- data/app/views/calagator/venues/duplicates.html.erb +65 -0
- data/app/views/calagator/venues/edit.html.erb +3 -0
- data/app/views/calagator/venues/index.html.erb +93 -0
- data/app/views/calagator/venues/index.kml.erb +15 -0
- data/app/views/calagator/venues/map.html.erb +4 -0
- data/app/views/calagator/venues/new.html.erb +5 -0
- data/app/views/calagator/venues/show.html.erb +113 -0
- data/app/views/calagator/versions/_chooser.html.erb +28 -0
- data/app/views/calagator/versions/_edit_with_chooser.html.erb +16 -0
- data/app/views/layouts/calagator/application.html.erb +110 -0
- data/config/deploy/local.rb +37 -0
- data/config/deploy/lucca.rb +33 -0
- data/config/initializers/dates.rb +7 -0
- data/config/initializers/formtastic.rb +82 -0
- data/config/initializers/geokit.rb +74 -0
- data/config/initializers/ics_renderer.rb +6 -0
- data/config/initializers/load_tag_model_extensions.rb +3 -0
- data/config/initializers/mime_types.rb +9 -0
- data/config/initializers/observers.rb +1 -0
- data/config/initializers/search_engine.rb +4 -0
- data/config/initializers/set_default_url_host.rb +5 -0
- data/config/initializers/time_get_zone.rb +8 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +55 -0
- data/config/secrets.yml.blag +75 -0
- data/config/sunspot.yml +23 -0
- data/db/development.sqlite3 +0 -0
- data/db/development.sqlite3.bak +0 -0
- data/db/development.sqlite3.old +0 -0
- data/db/development~20111112@110950.sqlite3 +0 -0
- data/db/migrate/001_create_events.rb +17 -0
- data/db/migrate/002_create_venues.rb +17 -0
- data/db/migrate/003_create_sources.rb +16 -0
- data/db/migrate/004_add_detailed_fields_to_venue.rb +19 -0
- data/db/migrate/005_add_end_time_to_events.rb +9 -0
- data/db/migrate/006_add_source_id_to_events.rb +9 -0
- data/db/migrate/008_add_source_id_to_venues.rb +10 -0
- data/db/migrate/009_add_duplicate_of_column_to_venues.rb +9 -0
- data/db/migrate/010_add_duplicate_of_column_to_events.rb +9 -0
- data/db/migrate/011_change_lat_long_type.rb +12 -0
- data/db/migrate/012_add_source_reimport.rb +9 -0
- data/db/migrate/013_change_end_time_to_duration.rb +11 -0
- data/db/migrate/014_remove_format_type_from_source.rb +9 -0
- data/db/migrate/015_create_updates.rb +15 -0
- data/db/migrate/016_remove_next_update_from_source.rb +9 -0
- data/db/migrate/20080705163959_change_duration_to_end_time.rb +11 -0
- data/db/migrate/20080705164959_create_tags_and_taggings.rb +28 -0
- data/db/migrate/20081011181519_create_versioned_events.rb +25 -0
- data/db/migrate/20081011193124_create_versioned_venues.rb +32 -0
- data/db/migrate/20081115190515_add_rrule_to_events.rb +15 -0
- data/db/migrate/20090912082129_create_versions.rb +18 -0
- data/db/migrate/20110219205156_add_closed_flag_to_venues.rb +9 -0
- data/db/migrate/20110220001008_add_wifi_flag_to_venues.rb +9 -0
- data/db/migrate/20110220011427_add_access_notes_to_venues.rb +9 -0
- data/db/migrate/20110220031117_add_events_count_to_venues.rb +8 -0
- data/db/migrate/20110604174521_add_venue_details_to_events.rb +9 -0
- data/db/migrate/20110717231316_acts_as_taggable_on_migration.rb +50 -0
- data/db/migrate/20120709092821_cleanup.rb +14 -0
- data/db/migrate/20120831234448_specify_venues_latitude_and_longitude_precision.rb +11 -0
- data/db/migrate/20150206085809_remove_updates.rb +13 -0
- data/db/migrate/20150207231355_add_locked_status_to_events.rb +5 -0
- data/db/production.sqlite3 +0 -0
- data/db/schema.rb +102 -0
- data/db/seeds.rb +16 -0
- data/db/test.sqlite3 +0 -0
- data/db/test2.sqlite3 +0 -0
- data/lib/calagator.rb +30 -0
- data/lib/calagator/blacklist_validator.rb +69 -0
- data/lib/calagator/decode_html_entities_hack.rb +33 -0
- data/lib/calagator/duplicate_checking.rb +133 -0
- data/lib/calagator/duplicate_checking/controller_actions.rb +38 -0
- data/lib/calagator/duplicate_checking/duplicate_finder.rb +83 -0
- data/lib/calagator/duplicate_checking/duplicate_squasher.rb +74 -0
- data/lib/calagator/engine.rb +30 -0
- data/lib/calagator/strip_whitespace.rb +19 -0
- data/lib/calagator/tag_model_extensions.rb +104 -0
- data/lib/calagator/url_prefixer.rb +9 -0
- data/lib/calagator/version.rb +3 -0
- data/lib/generators/calagator/install_generator.rb +39 -0
- data/lib/generators/calagator/templates/config/calagator.rb +26 -0
- data/lib/generators/calagator/templates/config/secrets.yml.sample +83 -0
- data/lib/secrets_reader.rb +76 -0
- data/lib/tasks/spec_db.rake +53 -0
- data/lib/tasks/sunspot_reindex_calagator.rake +6 -0
- data/lib/tasks/sunspot_solr_restart_enhancements.rake +19 -0
- data/lib/tasks/update_counter_caches.rake +13 -0
- data/lib/templates/erb/scaffold/_form.html.erb +11 -0
- data/lib/theme_reader.rb +17 -0
- data/lib/wait_for_solr.rb +25 -0
- data/spec/controllers/calagator/application_controller_spec.rb +47 -0
- data/spec/controllers/calagator/events_controller_spec.rb +794 -0
- data/spec/controllers/calagator/site_controller_spec.rb +59 -0
- data/spec/controllers/calagator/sources_controller_spec.rb +439 -0
- data/spec/controllers/calagator/venues_controller_spec.rb +319 -0
- data/spec/controllers/calagator/versions_controller_spec.rb +82 -0
- data/spec/controllers/squash_many_duplicates_examples.rb +49 -0
- data/spec/dummy/Gemfile +39 -0
- data/spec/dummy/Gemfile.lock +195 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/images/rails.png +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/stylesheets/application.css +14 -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 +62 -0
- data/spec/dummy/config/boot.rb +6 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/calagator.rb +26 -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 +5 -0
- data/spec/dummy/config/routes.rb +59 -0
- data/spec/dummy/config/secrets.yml +83 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20150309023304_create_events.calagator.rb +18 -0
- data/spec/dummy/db/migrate/20150309023305_create_venues.calagator.rb +18 -0
- data/spec/dummy/db/migrate/20150309023306_create_sources.calagator.rb +17 -0
- data/spec/dummy/db/migrate/20150309023307_add_detailed_fields_to_venue.calagator.rb +20 -0
- data/spec/dummy/db/migrate/20150309023308_add_end_time_to_events.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023309_add_source_id_to_events.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023310_add_source_id_to_venues.calagator.rb +11 -0
- data/spec/dummy/db/migrate/20150309023311_add_duplicate_of_column_to_venues.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023312_add_duplicate_of_column_to_events.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023313_change_lat_long_type.calagator.rb +13 -0
- data/spec/dummy/db/migrate/20150309023314_add_source_reimport.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023315_change_end_time_to_duration.calagator.rb +12 -0
- data/spec/dummy/db/migrate/20150309023316_remove_format_type_from_source.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023317_create_updates.calagator.rb +16 -0
- data/spec/dummy/db/migrate/20150309023318_remove_next_update_from_source.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023319_change_duration_to_end_time.calagator.rb +12 -0
- data/spec/dummy/db/migrate/20150309023320_create_tags_and_taggings.calagator.rb +29 -0
- data/spec/dummy/db/migrate/20150309023321_create_versioned_events.calagator.rb +26 -0
- data/spec/dummy/db/migrate/20150309023322_create_versioned_venues.calagator.rb +33 -0
- data/spec/dummy/db/migrate/20150309023323_add_rrule_to_events.calagator.rb +16 -0
- data/spec/dummy/db/migrate/20150309023324_create_versions.calagator.rb +19 -0
- data/spec/dummy/db/migrate/20150309023325_add_closed_flag_to_venues.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023326_add_wifi_flag_to_venues.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023327_add_access_notes_to_venues.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023328_add_events_count_to_venues.calagator.rb +9 -0
- data/spec/dummy/db/migrate/20150309023329_add_venue_details_to_events.calagator.rb +10 -0
- data/spec/dummy/db/migrate/20150309023330_acts_as_taggable_on_migration.calagator.rb +51 -0
- data/spec/dummy/db/migrate/20150309023331_cleanup.calagator.rb +15 -0
- data/spec/dummy/db/migrate/20150309023332_specify_venues_latitude_and_longitude_precision.calagator.rb +12 -0
- data/spec/dummy/db/migrate/20150309023333_remove_updates.calagator.rb +14 -0
- data/spec/dummy/db/migrate/20150309023334_add_locked_status_to_events.calagator.rb +6 -0
- data/spec/dummy/db/schema.rb +95 -0
- data/spec/dummy/db/seeds.rb +7 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/doc/README_FOR_APP +2 -0
- data/spec/dummy/log/development.log +273 -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/robots.txt +5 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/test/performance/browsing_test.rb +12 -0
- data/spec/dummy/test/test_helper.rb +13 -0
- data/spec/factories.rb +93 -0
- data/spec/features/add_event_spec.rb +99 -0
- data/spec/features/add_venue_spec.rb +34 -0
- data/spec/features/admin_auth_spec.rb +22 -0
- data/spec/features/admin_lock_event_spec.rb +41 -0
- data/spec/features/import_events_from_feed_spec.rb +43 -0
- data/spec/features/managing_event_spec.rb +111 -0
- data/spec/features/managing_venue_spec.rb +71 -0
- data/spec/features/search_event_spec.rb +27 -0
- data/spec/helpers/calagator/application_helper_spec.rb +82 -0
- data/spec/helpers/calagator/events_helper_spec.rb +172 -0
- data/spec/helpers/calagator/google_event_export_helper_spec.rb +70 -0
- data/spec/helpers/calagator/sources_helper_spec.rb +12 -0
- data/spec/helpers/calagator/tags_helper_spec.rb +85 -0
- data/spec/helpers/calagator/time_range_helper_spec.rb +59 -0
- data/spec/lib/calagator/blacklist_validator_spec.rb +65 -0
- data/spec/lib/calagator/decode_html_entities_hack_spec.rb +54 -0
- data/spec/lib/calagator/settings_spec.rb +20 -0
- data/spec/lib/calagator/url_prefixer_spec.rb +33 -0
- data/spec/lib/secrets_reader_spec.rb +65 -0
- data/spec/models/calagator/event/cloner_spec.rb +43 -0
- data/spec/models/calagator/event/overview_spec.rb +79 -0
- data/spec/models/calagator/event/search_spec.rb +103 -0
- data/spec/models/calagator/event_search_spec.rb +149 -0
- data/spec/models/calagator/event_spec.rb +859 -0
- data/spec/models/calagator/source/parser_facebook_spec.rb +73 -0
- data/spec/models/calagator/source/parser_hcal_spec.rb +69 -0
- data/spec/models/calagator/source/parser_ical_non_standard_spec.rb +91 -0
- data/spec/models/calagator/source/parser_ical_spec.rb +322 -0
- data/spec/models/calagator/source/parser_meetup_spec.rb +69 -0
- data/spec/models/calagator/source/parser_plancast_spec.rb +53 -0
- data/spec/models/calagator/source/parser_spec.rb +238 -0
- data/spec/models/calagator/source_spec.rb +135 -0
- data/spec/models/calagator/venue/search_spec.rb +92 -0
- data/spec/models/calagator/venue_search_spec.rb +124 -0
- data/spec/models/calagator/venue_spec.rb +346 -0
- data/spec/models/tag_spec.rb +35 -0
- data/spec/rails_helper.rb +39 -0
- data/spec/spec_helper.rb +140 -0
- data/spec/support/disable_geocoding.rb +1 -0
- data/spec/support/http_samples.rb +5 -0
- data/spec/support/samples/facebook.json +23 -0
- data/spec/support/samples/hcal_basic.xml +6 -0
- data/spec/support/samples/hcal_dup_event_dup_venue.xml +13 -0
- data/spec/support/samples/hcal_event_duplicates_fixture.xml +13 -0
- data/spec/support/samples/hcal_event_wo_lat_and_long.xml +14 -0
- data/spec/support/samples/hcal_multiple.xml +16 -0
- data/spec/support/samples/hcal_same_event_twice_with_different_venues.xml +12 -0
- data/spec/support/samples/hcal_single.xml +8 -0
- data/spec/support/samples/hcal_two_identical_events.xml +14 -0
- data/spec/support/samples/hcal_upcoming_v1.html +412 -0
- data/spec/support/samples/hcal_upcoming_v2.html +749 -0
- data/spec/support/samples/hcal_upcoming_v3.html +685 -0
- data/spec/support/samples/hcal_upcoming_v4.html +761 -0
- data/spec/support/samples/ical_apple.ics +22 -0
- data/spec/support/samples/ical_apple_v3.ics +37 -0
- data/spec/support/samples/ical_basic.ics +15 -0
- data/spec/support/samples/ical_basic_with_duration.ics +16 -0
- data/spec/support/samples/ical_event_with_squashed_venue.ics +12 -0
- data/spec/support/samples/ical_eventful_many.ics +504 -0
- data/spec/support/samples/ical_gmt.ics +12 -0
- data/spec/support/samples/ical_google.ics +786 -0
- data/spec/support/samples/ical_multiple_calendars.ics +111 -0
- data/spec/support/samples/ical_upcoming.ics +36 -0
- data/spec/support/samples/ical_upcoming_many.ics +682 -0
- data/spec/support/samples/ical_upcoming_v2.ics +43 -0
- data/spec/support/samples/ical_z.ics +10 -0
- data/spec/support/samples/meetup.ics +16 -0
- data/spec/support/samples/meetup.json +31 -0
- data/spec/support/samples/plancast.ics +59 -0
- data/spec/support/samples/plancast.json +51 -0
- data/spec/support/samples/plancast_with_missing_venue.json +39 -0
- data/spec/support/samples/upcoming_v1.xml +8 -0
- data/spec/support/samples/upcoming_v2_with_invalid_utc_dates.xml +8 -0
- data/spec/support/time_convenience_methods.rb +8 -0
- data/spec/support/time_zones.rb +12 -0
- data/spec/support/url_helpers.rb +5 -0
- data/spec/support/wait_for_ajax.rb +15 -0
- data/spec/support/webmock.rb +8 -0
- data/spec/travis_spec.rb +7 -0
- metadata +1194 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Calagator
|
|
2
|
+
class Engine < ::Rails::Engine
|
|
3
|
+
isolate_namespace Calagator
|
|
4
|
+
|
|
5
|
+
config.before_initialize do
|
|
6
|
+
# Read secrets
|
|
7
|
+
require 'secrets_reader'
|
|
8
|
+
::SECRETS = SecretsReader.read
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# settings with defaults
|
|
13
|
+
class << self
|
|
14
|
+
mattr_accessor :title, :tagline, :url, :venues_map_options, :blacklist_patterns
|
|
15
|
+
|
|
16
|
+
self.title = 'Calagator'
|
|
17
|
+
self.tagline = 'A Tech Calendar'
|
|
18
|
+
self.url = 'http://my-calagator.org/'
|
|
19
|
+
self.venues_map_options = {}
|
|
20
|
+
self.blacklist_patterns = [
|
|
21
|
+
/\b(online|overseas).+(drugstore|pharmacy)\b/,
|
|
22
|
+
/\bcialis\b/,
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
# map the attrs from initializer
|
|
26
|
+
def setup(&block)
|
|
27
|
+
yield self
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module StripWhitespace
|
|
2
|
+
def self.included(base)
|
|
3
|
+
base.extend(ClassMethods)
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
module ClassMethods
|
|
7
|
+
def strip_whitespace!(*fields)
|
|
8
|
+
before_validation do |record|
|
|
9
|
+
fields.each do |field|
|
|
10
|
+
setter = "#{field}=".to_sym
|
|
11
|
+
value = record.send(field.to_sym)
|
|
12
|
+
if value.respond_to?(:strip) and record.respond_to?(setter)
|
|
13
|
+
record.send(setter, value.strip)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# We're extending ActsAsTaggableOn's Tag model to include support for machine tags and such.
|
|
2
|
+
module Calagator
|
|
3
|
+
|
|
4
|
+
module TagModelExtensions
|
|
5
|
+
def self.included(base)
|
|
6
|
+
base.class_eval do
|
|
7
|
+
scope :machine_tags, where("name LIKE '%:%=%'")
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
#---[ Machine tags ]----------------------------------------------------
|
|
12
|
+
|
|
13
|
+
# Structure of machine tag namespaces and predicates to their URLs. See
|
|
14
|
+
# #machine_tag for details.
|
|
15
|
+
MACHINE_TAG_URLS = {
|
|
16
|
+
'epdx' => {
|
|
17
|
+
'company' => 'http://epdx.org/companies/%s',
|
|
18
|
+
'group' => 'http://epdx.org/groups/%s',
|
|
19
|
+
'person' => 'http://epdx.org/people/%s',
|
|
20
|
+
'project' => 'http://epdx.org/projects/%s',
|
|
21
|
+
},
|
|
22
|
+
'upcoming' => {
|
|
23
|
+
'event' => "http://upcoming.yahoo.com/event/%s",
|
|
24
|
+
'venue' => "http://upcoming.yahoo.com/venue/%s"
|
|
25
|
+
},
|
|
26
|
+
'plancast' => {
|
|
27
|
+
'activity' => "http://plancast.com/a/%s",
|
|
28
|
+
'plan' => "http://plancast.com/p/%s"
|
|
29
|
+
},
|
|
30
|
+
'yelp' => {
|
|
31
|
+
'biz' => "http://www.yelp.com/biz/%s"
|
|
32
|
+
},
|
|
33
|
+
'foursquare' => {
|
|
34
|
+
'venue' => "http://foursquare.com/venue/%s"
|
|
35
|
+
},
|
|
36
|
+
'gowalla' => {
|
|
37
|
+
'spot' => "http://gowalla.com/spots/%s"
|
|
38
|
+
},
|
|
39
|
+
'shizzow' => {
|
|
40
|
+
'place' => "http://www.shizzow.com/places/%s"
|
|
41
|
+
},
|
|
42
|
+
'meetup' => {
|
|
43
|
+
'group' => "http://www.meetup.com/%s"
|
|
44
|
+
},
|
|
45
|
+
'facebook' => {
|
|
46
|
+
'event' => "http://www.facebook.com/event.php?eid=%s"
|
|
47
|
+
},
|
|
48
|
+
'lanyrd' => {
|
|
49
|
+
'event' => "http://lanyrd.com/%s"
|
|
50
|
+
}
|
|
51
|
+
} unless defined?(MACHINE_TAG_URLS)
|
|
52
|
+
|
|
53
|
+
# Regular expression for parsing machine tags
|
|
54
|
+
MACHINE_TAG_PATTERN = /([^:]+):([^=]+)=(.+)/ unless defined?(MACHINE_TAG_PATTERN)
|
|
55
|
+
|
|
56
|
+
# Machine tag predicates that refer to place entries
|
|
57
|
+
VENUE_PREDICATES = %w(venue place spot biz) unless defined?(VENUE_PREDICATES)
|
|
58
|
+
|
|
59
|
+
# Return a machine tag hash for this tag, or an empty hash if this isn't a
|
|
60
|
+
# machine tag. The hash will always contain :namespace, :predicate and :value
|
|
61
|
+
# key-value pairs. It may also contain an :url if one is known.
|
|
62
|
+
#
|
|
63
|
+
# Machine tags describe references to remote resources. For example, a
|
|
64
|
+
# Calagator event imported from an Meetup event may have a machine
|
|
65
|
+
# linking it back to the Meetup event.
|
|
66
|
+
#
|
|
67
|
+
# Example:
|
|
68
|
+
# # A tag named "meetup:group=1234" will produce this machine tag:
|
|
69
|
+
# tag.machine_tag == {
|
|
70
|
+
# :namespace => "meetup",
|
|
71
|
+
# :predicate => "group",
|
|
72
|
+
# :value => "1234",
|
|
73
|
+
# :url => "http://www.meetup.com/1234",
|
|
74
|
+
def machine_tag
|
|
75
|
+
if components = self.name.match(MACHINE_TAG_PATTERN)
|
|
76
|
+
namespace, predicate, value = components.captures
|
|
77
|
+
|
|
78
|
+
result = {
|
|
79
|
+
:namespace => namespace,
|
|
80
|
+
:predicate => predicate,
|
|
81
|
+
:value => value,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if machine_tag = MACHINE_TAG_URLS[namespace]
|
|
85
|
+
if url_template = machine_tag[predicate]
|
|
86
|
+
result[:url] = sprintf(url_template, value)
|
|
87
|
+
if namespace =~ /\A(upcoming|gowalla|shizzow)\Z/
|
|
88
|
+
domain = "http://localhost:3000" if Rails.env.development? || Rails.env.test?
|
|
89
|
+
domain = "http://calagator.org" if Rails.env.production?
|
|
90
|
+
archive_date = Event.tagged_with(self).first.start_time.strftime("%Y%m%d") if Event.tagged_with(self).first
|
|
91
|
+
archive_date = Venue.tagged_with(self).first.created_at.strftime("%Y%m%d") if Venue.tagged_with(self).first
|
|
92
|
+
result[:url] = "#{domain}/defunct?url=https://web.archive.org/web/#{archive_date}/#{result[:url]}"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
return result
|
|
98
|
+
else
|
|
99
|
+
return {}
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Calagator
|
|
2
|
+
class InstallGenerator < Rails::Generators::Base
|
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
4
|
+
|
|
5
|
+
def install
|
|
6
|
+
add_route
|
|
7
|
+
add_secrets
|
|
8
|
+
add_initializer
|
|
9
|
+
add_javascripts
|
|
10
|
+
add_stylesheets
|
|
11
|
+
rake 'calagator:install:migrations'
|
|
12
|
+
rake 'db:migrate'
|
|
13
|
+
rake 'db:test:prepare'
|
|
14
|
+
run 'rm -f public/index.html'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def add_route
|
|
20
|
+
inject_into_file 'config/routes.rb', "\s\smount Calagator::Engine => '/'\n", after: "Application.routes.draw do\n"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def add_secrets
|
|
24
|
+
copy_file File.expand_path(File.join(__FILE__, '../templates/config/secrets.yml.sample')), 'config/secrets.yml'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def add_initializer
|
|
28
|
+
copy_file File.expand_path(File.join(__FILE__, '../templates/config/calagator.rb')), 'config/initializers/calagator.rb'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def add_javascripts
|
|
32
|
+
append_file 'app/assets/javascripts/application.js', '//= require calagator'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def add_stylesheets
|
|
36
|
+
append_file 'app/assets/stylesheets/application.css', '//= require calagator'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Calagator.setup do |config|
|
|
2
|
+
|
|
3
|
+
# # Site's name
|
|
4
|
+
# config.title = 'Calagator'
|
|
5
|
+
|
|
6
|
+
# # Site's tagline
|
|
7
|
+
# config.tagline = 'A Tech Calendar'
|
|
8
|
+
|
|
9
|
+
# # Site's URL with trailing slash
|
|
10
|
+
# config.url = 'http://my-calagator.org/'
|
|
11
|
+
|
|
12
|
+
# # Map to display on /venues page:
|
|
13
|
+
# config.venues_map_options = {
|
|
14
|
+
# # Zoom magnification level:
|
|
15
|
+
# zoom: 12,
|
|
16
|
+
# # Center of the map, in latitude and longitude.
|
|
17
|
+
# # If no center is specified, the map will zoom to fit all markers.
|
|
18
|
+
# center: [45.518493, -122.660737]
|
|
19
|
+
# }
|
|
20
|
+
|
|
21
|
+
# # Patterns for detecting spam events and venues
|
|
22
|
+
# config.blacklist_patterns = [
|
|
23
|
+
# /\b(online|overseas).+(drugstore|pharmacy)\b/,
|
|
24
|
+
# /\bcialis\b/,
|
|
25
|
+
# ]
|
|
26
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#===[ Secrets ]=========================================================
|
|
2
|
+
#
|
|
3
|
+
# This file is meant for storing secret information that is never
|
|
4
|
+
# published or committed to a revision control system.
|
|
5
|
+
#
|
|
6
|
+
# Do not modify this "config/secrets.yml.sample" file directly -- you
|
|
7
|
+
# should copy it to "config/secrets.yml" and customize it there.
|
|
8
|
+
#
|
|
9
|
+
#---[ Values ]----------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
# Email address of administrator that will get exception notifications
|
|
12
|
+
# and requests for assistance from users:
|
|
13
|
+
administrator_email: 'your@email.addr'
|
|
14
|
+
|
|
15
|
+
# Admin username and password to use when accessing /admin pages
|
|
16
|
+
admin_username: 'admin'
|
|
17
|
+
admin_password: 'kitties!'
|
|
18
|
+
|
|
19
|
+
# Secret code for verifying cookie session data integrity. If you change it,
|
|
20
|
+
# all old sessions will become invalid! Make sure the secret is at least 30
|
|
21
|
+
# characters and all random, no regular words or you'll be exposed to
|
|
22
|
+
# dictionary attacks.
|
|
23
|
+
session_secret: '1290832312281326461234712c347134618233441234513341132032545424856956711678856985f0575586671765c678659e7855bd58c6978856178b56e8f6'
|
|
24
|
+
|
|
25
|
+
# Name to use for storing application's session cookies, this is often a
|
|
26
|
+
# shortened form of your organization and application name, e.g.,
|
|
27
|
+
# "igniteportlandproposals", "igniteproposals", "openproposals", etc:
|
|
28
|
+
session_name: 'calagator'
|
|
29
|
+
|
|
30
|
+
# API key for Meetup.com, get your own from: http://www.meetup.com/meetup_api/key/
|
|
31
|
+
# meetup_api_key: registerNow
|
|
32
|
+
|
|
33
|
+
# Search engine to use for searching events, uncomment the line to specify that
|
|
34
|
+
# search engine. Defaults to 'sql'. For further information, see `INSTALL.md`.
|
|
35
|
+
### search_engine: sql
|
|
36
|
+
### search_engine: sunspot
|
|
37
|
+
|
|
38
|
+
# Configure a mapping provider
|
|
39
|
+
# Stamen's terrain tiles will be used by default.
|
|
40
|
+
mapping:
|
|
41
|
+
# Map marker color
|
|
42
|
+
# Values: red, darkred, orange, green, darkgreen, blue, purple, darkpuple, cadetblue
|
|
43
|
+
marker_color: green
|
|
44
|
+
|
|
45
|
+
# A Google Maps API key is required to use Google's geocoding service
|
|
46
|
+
# as well as to display maps using their API.
|
|
47
|
+
#
|
|
48
|
+
# Get one at: https://developers.google.com/maps/documentation/javascript/tutorial#api_key
|
|
49
|
+
google_maps_api_key: <your google maps v3 API key>
|
|
50
|
+
|
|
51
|
+
# The tile provider to use when rendering maps with Leaflet.
|
|
52
|
+
# One of: leaflet, stamen, mapbox, google
|
|
53
|
+
# provider: stamen
|
|
54
|
+
#
|
|
55
|
+
# The tiles to use for the map, see the docs for individual Leaflet plugins.
|
|
56
|
+
# For stamen, this can be one of: terrain, toner, watercolor
|
|
57
|
+
# tiles: terrain
|
|
58
|
+
#
|
|
59
|
+
#== Examples ==
|
|
60
|
+
# Stamen
|
|
61
|
+
# (available tiles: terrain, toner, watercolor)
|
|
62
|
+
# provider: stamen
|
|
63
|
+
# tiles: watercolor
|
|
64
|
+
#
|
|
65
|
+
# MapBox Streets (use a map from your own account)
|
|
66
|
+
# provider: mapbox
|
|
67
|
+
# tiles: examples.map-9ijuk24y
|
|
68
|
+
#
|
|
69
|
+
# Google Maps
|
|
70
|
+
# provider: google
|
|
71
|
+
# tiles: ROADMAP
|
|
72
|
+
# google_maps_api_key: <your google maps v3 API key>
|
|
73
|
+
#
|
|
74
|
+
# OpenStreetMap
|
|
75
|
+
# provider: leaflet
|
|
76
|
+
# tiles: http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
|
|
77
|
+
#
|
|
78
|
+
# Esri
|
|
79
|
+
# (available tiles: Gray, Streets, Oceans, Topographic)
|
|
80
|
+
# provider: esri
|
|
81
|
+
# tiles: Gray
|
|
82
|
+
|
|
83
|
+
#===[ fin ]=============================================================
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require 'erb'
|
|
3
|
+
require 'ostruct'
|
|
4
|
+
require 'set'
|
|
5
|
+
|
|
6
|
+
# = SecretsReader
|
|
7
|
+
#
|
|
8
|
+
# Reads secrets from an ERB-parsed YAML file and returns an OpenStruct object.
|
|
9
|
+
#
|
|
10
|
+
# Examples:
|
|
11
|
+
# # Read from default "config/secrets.yml" and "config/secrets.yml.sample" files:
|
|
12
|
+
# Secrets = SecretsReader.read
|
|
13
|
+
#
|
|
14
|
+
# # Read a specific file:
|
|
15
|
+
# Secrets = SecretsReader.read("myfile.yml") #
|
|
16
|
+
#
|
|
17
|
+
class SecretsReader
|
|
18
|
+
# Return an OpenStruct object with secret information. The secrets are read
|
|
19
|
+
# from an ERB-parsed YAML file.
|
|
20
|
+
#
|
|
21
|
+
# Arguments:
|
|
22
|
+
# * Filename to read secrets from. Optional, if not given will try
|
|
23
|
+
# "config/secret.yml" and "config/secret.yml.sample".
|
|
24
|
+
#
|
|
25
|
+
# Options:
|
|
26
|
+
# * :verbose => Print status to screen on error. Defaults to true.
|
|
27
|
+
# * :silent => Display nothing, not even errors. Defaults to false.
|
|
28
|
+
def self.read(*args)
|
|
29
|
+
given_file = args.first.kind_of?(String) ? args.first : nil
|
|
30
|
+
opts = args.last.kind_of?(Hash) ? args.last : {}
|
|
31
|
+
verbose = opts[:verbose] != false
|
|
32
|
+
silent = opts[:silent] == true
|
|
33
|
+
|
|
34
|
+
normal_file = "config/secrets.yml"
|
|
35
|
+
sample_file = "config/secrets.yml.sample"
|
|
36
|
+
rails_root = defined?(Rails) ? ::Rails.root : File.dirname(File.dirname(__FILE__))
|
|
37
|
+
|
|
38
|
+
message = ""
|
|
39
|
+
error = false
|
|
40
|
+
|
|
41
|
+
if object = self.filename_to_ostruct(given_file)
|
|
42
|
+
message << "loaded '#{given_file}'"
|
|
43
|
+
elsif object = self.filename_to_ostruct(File.join(rails_root, normal_file))
|
|
44
|
+
message << "loaded '#{normal_file}'"
|
|
45
|
+
elsif object = self.filename_to_ostruct(File.join(rails_root, sample_file))
|
|
46
|
+
message << "WARNING! Using insecure '#{sample_file}' settings, see 'Security' in INSTALL.md" unless defined?($INSECURE_SECRETS)
|
|
47
|
+
$INSECURE_SECRETS = true
|
|
48
|
+
error = true
|
|
49
|
+
else
|
|
50
|
+
object = OpenStruct.new
|
|
51
|
+
message << "Couldn't find '#{normal_file}'"
|
|
52
|
+
error = true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
unless silent
|
|
56
|
+
if message.present?
|
|
57
|
+
message = "** SecretsReader - #{message}"
|
|
58
|
+
puts message if error
|
|
59
|
+
if message.present? && defined?(Rails)
|
|
60
|
+
Rails.logger.info(message)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
return object
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Return an OpenStruct object by reading the +filename+ and parsing it with ERB and YAML.
|
|
69
|
+
def self.filename_to_ostruct(filename)
|
|
70
|
+
if filename.nil? or not File.exist?(filename)
|
|
71
|
+
return nil
|
|
72
|
+
else
|
|
73
|
+
return OpenStruct.new(YAML.load(ERB.new(File.read(filename)).result))
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
namespace :spec do
|
|
2
|
+
namespace :db do
|
|
3
|
+
databases = [:postgresql, :mysql, :sqlite3]
|
|
4
|
+
|
|
5
|
+
desc "Run specs against all databases"
|
|
6
|
+
task :all do
|
|
7
|
+
failed = false
|
|
8
|
+
|
|
9
|
+
databases.each do |database|
|
|
10
|
+
test_against database
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
databases.each do |database|
|
|
15
|
+
desc "Run specs against '#{database}' database"
|
|
16
|
+
task database do
|
|
17
|
+
return test_against database
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_against(kind)
|
|
22
|
+
sample = Rails.root + "config/database~#{kind}.sample.yml"
|
|
23
|
+
custom = Rails.root + "config/database~custom.yml"
|
|
24
|
+
backup = Rails.root + "config/database~custom.yml.backup"
|
|
25
|
+
|
|
26
|
+
if custom.exist?
|
|
27
|
+
mv custom, backup
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
cp sample, custom
|
|
31
|
+
|
|
32
|
+
succeeded = nil
|
|
33
|
+
|
|
34
|
+
begin
|
|
35
|
+
Dir.chdir(Rails.root) do
|
|
36
|
+
puts
|
|
37
|
+
puts "## Database: #{kind}"
|
|
38
|
+
succeeded = system "unset BUNDLE_GEMFILE BUNDLE_BIN_PATH RUBYOPT; bundle --quiet && rake db:create:all db:migrate db:test:prepare spec"
|
|
39
|
+
end
|
|
40
|
+
ensure
|
|
41
|
+
rm custom
|
|
42
|
+
|
|
43
|
+
if backup.exist?
|
|
44
|
+
mv backup, custom
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
unless succeeded
|
|
49
|
+
raise "Tests failed against database '#{kind}'"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|