├── .gitignore ├── .hgignore ├── .rspec ├── .travis.yml ├── CONTRIBUTORS.md ├── Gemfile ├── Gemfile.lock ├── INSTALL.md ├── LICENSE.txt ├── Procfile ├── README.md ├── README_Activate.md ├── Rakefile ├── app ├── assets │ ├── images │ │ ├── disk.png │ │ ├── edit.png │ │ ├── external_sites │ │ │ ├── epdx.png │ │ │ ├── external.gif │ │ │ ├── facebook.png │ │ │ ├── foursquare.png │ │ │ ├── gowalla.png │ │ │ ├── lanyrd.png │ │ │ ├── meetup.png │ │ │ ├── plancast.png │ │ │ ├── shizzow.png │ │ │ ├── upcoming.png │ │ │ └── yelp.png │ │ ├── feed.png │ │ ├── head_calagator.gif │ │ ├── heart.png │ │ ├── icon_ical.gif │ │ ├── information.png │ │ ├── nav_marker.gif │ │ ├── nav_marker.png │ │ ├── navbar-logo.png │ │ ├── oaklandmakers-logo.png │ │ ├── og-image.png │ │ ├── og-oaklandmakers.png │ │ ├── plus.png │ │ ├── public_wifi-16x16.png │ │ ├── redx.png │ │ ├── site-icon.png │ │ ├── spinner.gif │ │ ├── star.png │ │ ├── subnav_marker.gif │ │ ├── subnav_marker.png │ │ ├── tag_blue.png │ │ └── weekday_background.gif │ ├── javascripts │ │ ├── admin.coffee │ │ ├── application.coffee │ │ ├── date-functions.js │ │ ├── events.coffee │ │ ├── forms.js │ │ ├── jquery.cookie.js │ │ ├── jquery.timePicker.js │ │ ├── mustache.js │ │ ├── organizations.coffee │ │ ├── sources.coffee │ │ ├── theme.coffee │ │ ├── venues.coffee │ │ └── widget.coffee │ └── stylesheets │ │ ├── _variables.scss │ │ ├── admin.scss │ │ ├── application.scss │ │ ├── common.scss │ │ ├── events.scss │ │ ├── forms.scss │ │ ├── layout.scss │ │ ├── markdown.scss │ │ ├── mobile.scss │ │ ├── organizations.scss │ │ ├── reset.css │ │ ├── sources.scss │ │ ├── theme.scss │ │ ├── venues.scss │ │ └── widget.scss ├── controllers │ ├── admin │ │ ├── events_controller.rb │ │ ├── topics_controller.rb │ │ ├── types_controller.rb │ │ └── venues_controller.rb │ ├── admin_controller.rb │ ├── application_controller.rb │ ├── events_controller.rb │ ├── organizations_controller.rb │ ├── site_controller.rb │ ├── sources_controller.rb │ ├── venues_controller.rb │ └── versions_controller.rb ├── helpers │ ├── application_helper.rb │ ├── events_helper.rb │ └── time_range_helper.rb ├── mixins │ ├── decode_html_entities_hack.rb │ ├── dirty_attr_accessor.rb │ ├── duplicate_checking.rb │ ├── rebaseable.rb │ ├── squash_many_duplicates_mixin.rb │ ├── strip_whitespace.rb │ ├── validates_blacklist_on_mixin.rb │ └── version_diff.rb ├── models │ ├── abstract_event.rb │ ├── abstract_location.rb │ ├── application_record.rb │ ├── event.rb │ ├── organization.rb │ ├── site.rb │ ├── site_domain.rb │ ├── source.rb │ ├── topic.rb │ ├── type.rb │ ├── update_updated_at_mixin.rb │ ├── user.rb │ ├── venue.rb │ └── version.rb └── views │ ├── admin │ ├── events │ │ ├── duplicates.html.haml │ │ └── index.html.haml │ ├── index.html.haml │ ├── topics │ │ ├── _form.html.haml │ │ ├── edit.html.haml │ │ ├── index.html.haml │ │ ├── new.html.haml │ │ └── show.html.haml │ ├── types │ │ ├── _form.html.haml │ │ ├── edit.html.haml │ │ ├── index.html.haml │ │ ├── new.html.haml │ │ └── show.html.haml │ └── venues │ │ ├── duplicates.html.haml │ │ └── index.html.haml │ ├── devise │ ├── confirmations │ │ └── new.html.erb │ ├── mailer │ │ ├── confirmation_instructions.html.erb │ │ ├── reset_password_instructions.html.erb │ │ └── unlock_instructions.html.erb │ ├── menu │ │ └── _login_links.html.erb │ ├── passwords │ │ ├── edit.html.erb │ │ └── new.html.erb │ ├── registrations │ │ ├── edit.html.erb │ │ └── new.html.erb │ ├── sessions │ │ └── new.html.erb │ ├── shared │ │ └── _links.erb │ └── unlocks │ │ └── new.html.erb │ ├── events │ ├── _calendar.html.haml │ ├── _comments.html.haml │ ├── _exports.html.haml │ ├── _feed_item.html.erb │ ├── _filters.html.haml │ ├── _form.html.haml │ ├── _hcal.html.erb │ ├── _index_item.html.haml │ ├── _item.html.haml │ ├── _item_exports.html.haml │ ├── _list.html.haml │ ├── _manage_overlay.html.haml │ ├── _share_buttons.html.haml │ ├── duplicates.html.erb │ ├── edit.html.haml │ ├── index.atom.builder │ ├── index.html.haml │ ├── index.kml.erb │ ├── new.html.haml │ ├── show.html.haml │ └── widget_builder.html.haml │ ├── filters │ ├── _date.html.haml │ ├── _topic.html.haml │ └── _type.html.haml │ ├── layouts │ ├── admin.html.haml │ ├── application.html.haml │ └── widget.html.haml │ ├── organizations │ ├── _filters.html.haml │ ├── _form.html.haml │ ├── _item.html.haml │ ├── edit.html.haml │ ├── index.html.haml │ ├── new.html.haml │ └── show.html.haml │ ├── site │ ├── _change.html.erb │ ├── _description.html.erb │ ├── _footer.html.haml │ ├── _head.html.haml │ ├── _navbar.html.haml │ ├── _sidebar.html.haml │ ├── _tracking.html.haml │ ├── _welcome.html.haml │ ├── _wiki_props.html.haml │ ├── _wiki_props_index.html.haml │ ├── about.html.erb │ └── opensearch.xml.builder │ ├── sources │ ├── _form.html.haml │ ├── _index_item.html.haml │ ├── _item.html.haml │ ├── edit.html.haml │ ├── new.html.haml │ └── show.html.haml │ ├── users │ └── show.html.haml │ ├── venues │ ├── _card.html.haml │ ├── _exports.html.haml │ ├── _filters.html.haml │ ├── _form.html.haml │ ├── _item.html.haml │ ├── _subnav.html.erb │ ├── duplicates.html.erb │ ├── edit.html.haml │ ├── index.html.haml │ ├── index.kml.erb │ ├── map.html.erb │ ├── new.html.haml │ └── show.html.haml │ └── versions │ ├── _chooser.html.erb │ └── _edit_with_chooser.html.erb ├── bin ├── rails ├── rake └── spring ├── ci ├── copy_database_config.rb ├── database.mysql.yml ├── database.postgresql.yml └── database.sqlite.yml ├── config.ru ├── config ├── application.rb ├── blacklist.txt ├── boot.rb ├── cable.yml ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── preview.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── application_controller_renderer.rb │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── cookies_serializer.rb │ ├── dates.rb │ ├── default_headers.rb │ ├── devise.rb │ ├── filter_parameter_logging.rb │ ├── formtastic.rb │ ├── geokit.rb │ ├── i18n.rb │ ├── inflections.rb │ ├── load_tag_model_extensions.rb │ ├── mime_types.rb │ ├── new_framework_defaults.rb │ ├── new_rails_defaults.rb │ ├── paper_trail.rb │ ├── rails_admin.rb │ ├── rollbar.rb │ ├── session_store.rb │ ├── timezone.rb │ └── wrap_parameters.rb ├── locales │ ├── README │ ├── activate │ │ ├── en-x-activate-arts.yml │ │ ├── en-x-activate-hub-detroit.yml │ │ ├── en-x-activate-hub.yml │ │ ├── en-x-activate-oakmaker.yml │ │ └── en-x-activate.yml │ ├── devise.en.yml │ ├── en.formats.yml │ └── en.yml ├── puma.rb ├── routes.rb ├── secrets.yml ├── spring.rb └── sunspot~sample.yml ├── db ├── migrate │ ├── 001_create_events.rb │ ├── 002_create_venues.rb │ ├── 003_create_sources.rb │ ├── 004_add_detailed_fields_to_venue.rb │ ├── 005_add_end_time_to_events.rb │ ├── 006_add_source_id_to_events.rb │ ├── 008_add_source_id_to_venues.rb │ ├── 009_add_duplicate_of_column_to_venues.rb │ ├── 010_add_duplicate_of_column_to_events.rb │ ├── 011_change_lat_long_type.rb │ ├── 012_add_source_reimport.rb │ ├── 013_change_end_time_to_duration.rb │ ├── 014_remove_format_type_from_source.rb │ ├── 015_create_updates.rb │ ├── 016_remove_next_update_from_source.rb │ ├── 20080604210521_convert_times_to_utc.rb │ ├── 20080705163959_change_duration_to_end_time.rb │ ├── 20080705164959_create_tags_and_taggings.rb │ ├── 20081011181519_create_versioned_events.rb │ ├── 20081011193124_create_versioned_venues.rb │ ├── 20081115190515_add_rrule_to_events.rb │ ├── 20090912082129_create_versions.rb │ ├── 20110219205156_add_closed_flag_to_venues.rb │ ├── 20110220001008_add_wifi_flag_to_venues.rb │ ├── 20110220011427_add_access_notes_to_venues.rb │ ├── 20110220031117_add_events_count_to_venues.rb │ ├── 20110604174521_add_venue_details_to_events.rb │ ├── 20110717231316_acts_as_taggable_on_migration.rb │ ├── 20111109034553_create_organizations.rb │ ├── 20111110144520_add_organization_id_to_events.rb │ ├── 20111213021451_create_types.rb │ ├── 20111213023932_add_organization_id_to_sources.rb │ ├── 20111224014835_create_topics.rb │ ├── 20120709092821_cleanup.rb │ ├── 20120831234448_specify_venues_latitude_and_longitude_precision.rb │ ├── 20130506062649_create_sites.rb │ ├── 20130506063000_add_site_id_to_models.rb │ ├── 20130601190557_add_contact_to_organizations.rb │ ├── 20130601201436_remove_users_and_rails_admin_table.rb │ ├── 20130601225529_devise_create_users.rb │ ├── 20130601225531_create_rails_admin_histories_table.rb │ ├── 20130630184240_add_description_to_organization.rb │ ├── 20130707033958_add_settings_to_sites.rb │ ├── 20130707094725_add_non_affiliated_event_org.rb │ ├── 20130707104341_add_topics_to_source.rb │ ├── 20130712205256_add_path_prefix_to_sites.rb │ ├── 20130720021739_add_enabled_to_sources.rb │ ├── 20130727043249_add_site_id_to_versions.rb │ ├── 20130818060649_create_abstract_locations.rb │ ├── 20130818074448_create_abstract_events.rb │ ├── 20130910081243_add_locale_to_sites.rb │ ├── 20130910114730_remove_path_prefix_from_sites.rb │ ├── 20130930234907_add_ga_account_id_to_sites.rb │ ├── 20131001031403_add_sharethis_key_to_sites.rb │ ├── 20140212051512_add_disqus_shortname_to_sites.rb │ ├── 20140309144618_add_updated_at_indexes.rb │ ├── 20140309152321_add_indexes_to_topics_types.rb │ ├── 20140517001901_add_admin_to_users.rb │ ├── 20140529191701_add_default_venue_id_to_organizations.rb │ ├── 20140603005652_rename_default_venue_to_venue.rb │ ├── 20161201160616_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb │ ├── 20161201160618_change_collation_for_tag_names.acts_as_taggable_on_engine.rb │ ├── 20161204144535_drop_updates.rb │ ├── 20170111075150_add_geo_precision_too_venues.rb │ ├── 20170113215729_add_enabled_to_topics_types.rb │ ├── 20170129122904_create_site_domains.rb │ └── 20170130081642_downcase_site_domains.rb ├── schema.rb └── seeds.rb ├── lib ├── associated_venues.rb ├── ext │ └── nil_strip_html.rb ├── metaclass.rb ├── search_engine.rb ├── search_engine │ ├── base.rb │ ├── sql.rb │ └── sunspot.rb ├── settings_reader.rb ├── source_importer.rb ├── source_parser.rb ├── source_parser │ ├── base.rb │ ├── facebook.rb │ ├── hcal.rb │ ├── http_authentication_required_error.rb │ ├── ical.rb │ ├── meetup.rb │ ├── not_found.rb │ └── plancast.rb ├── tag_model_extensions.rb ├── task_helpers.rb ├── tasks │ ├── db_raw.rake │ ├── sources │ │ └── import.rake │ ├── spec_rcov_with_save_and_diff.rake │ ├── sunspot_extras.rake │ └── update_counter_caches.rake ├── time_range.rb └── url_validator.rb ├── log └── .do_not_delete ├── public ├── .htaccess.disabled ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── favicon.png └── robots.txt ├── script └── seed-abstracts.rb ├── solr └── conf │ ├── elevate.xml │ ├── schema.xml │ ├── solrconfig.xml │ ├── spellings.txt │ ├── stopwords.txt │ └── synonyms.txt ├── spec ├── controllers │ ├── admin_controller_spec.rb │ ├── application_controller_spec.rb │ ├── events_controller_spec.rb │ ├── organizations_controller_spec.rb │ ├── paper_trail_manager_spec.rb │ ├── site_controller_spec.rb │ ├── sources_controller_spec.rb │ ├── venues_controller_spec.rb │ └── versions_controller_spec.rb ├── factories │ ├── abstract_event.rb │ ├── abstract_location.rb │ ├── event.rb │ ├── organization.rb │ ├── site.rb │ ├── site_domain.rb │ ├── source.rb │ ├── topic.rb │ ├── types.rb │ ├── users.rb │ └── venue.rb ├── fixtures │ └── locales │ │ ├── en-locale-loco.yml │ │ └── foo │ │ ├── en-x-foo-bar.yml │ │ └── en-x-foo.yml ├── helpers │ ├── application_helper_spec.rb │ ├── events_helper_spec.rb │ └── time_range_helper_spec.rb ├── lib │ ├── source_importer_spec.rb │ ├── source_parser_facebook_spec.rb │ ├── source_parser_hcal_spec.rb │ ├── source_parser_ical_non_standard_spec.rb │ ├── source_parser_ical_spec.rb │ ├── source_parser_meetup_spec.rb │ ├── source_parser_plancast_spec.rb │ ├── source_parser_spec.rb │ └── task_helpers_spec.rb ├── mixins │ ├── dirty_attr_accessor_examples.rb │ ├── dirty_attr_accessor_spec.rb │ ├── rebaseable_examples.rb │ └── rebaseable_spec.rb ├── models │ ├── abstract_event_spec.rb │ ├── abstract_location_spec.rb │ ├── decode_html_entities_hack_spec.rb │ ├── event_spec.rb │ ├── organization_spec.rb │ ├── site_domain_spec.rb │ ├── site_scoping_examples.rb │ ├── site_spec.rb │ ├── source_spec.rb │ ├── tag_spec.rb │ ├── type_spec.rb │ ├── user_spec.rb │ ├── validates_blacklist_on_spec.rb │ ├── venue_spec.rb │ └── version_spec.rb ├── rails_helper.rb ├── requests │ ├── admin │ │ ├── topics_spec.rb │ │ └── types_spec.rb │ ├── rails_admin_spec.rb │ └── site_tenancy_spec.rb ├── samples │ ├── facebook.json │ ├── hcal_basic.xml │ ├── hcal_dup_event_dup_venue.xml │ ├── hcal_event_duplicates_fixture.xml │ ├── hcal_event_wo_lat_and_long.xml │ ├── hcal_multiple.xml │ ├── hcal_same_event_twice_with_different_venues.xml │ ├── hcal_single.xml │ ├── hcal_two_identical_events.xml │ ├── hcal_upcoming_v1.html │ ├── ical_apple.ics │ ├── ical_apple_v3.ics │ ├── ical_basic.ics │ ├── ical_basic_with_duration.ics │ ├── ical_event_with_squashed_venue.ics │ ├── ical_eventful_many.ics │ ├── ical_gmt.ics │ ├── ical_google.ics │ ├── ical_multiple_calendars.ics │ ├── ical_z.ics │ ├── meetup.json │ ├── plancast.ics │ └── plancast.json ├── spec_helper.rb ├── spec_helper_extensions.rb └── support │ ├── auth_test_helpers.rb │ ├── controller_helper.rb │ ├── shared_context.rb │ └── test_classes │ └── dirty_model.rb ├── tmp ├── .do_not_delete ├── cache │ └── .do_not_delete ├── pids │ └── .do_not_delete ├── sessions │ └── .do_not_delete └── sockets │ └── .do_not_delete └── vendor └── gems └── mofo-0.2.8 ├── CHANGELOG ├── LICENSE ├── Manifest.txt ├── README ├── Rakefile ├── init.rb ├── lib ├── microformat.rb ├── microformat │ ├── array.rb │ ├── simple.rb │ ├── string.rb │ └── time.rb ├── mofo.rb └── mofo │ ├── adr.rb │ ├── geo.rb │ ├── hcalendar.rb │ ├── hcard.rb │ ├── hentry.rb │ ├── hfeed.rb │ ├── hresume.rb │ ├── hreview.rb │ ├── rel_bookmark.rb │ ├── rel_tag.rb │ ├── xfn.rb │ └── xoxo.rb ├── site ├── index.html ├── mofo-logo.png ├── mootools.v1.00.js └── style.css └── test ├── base_url_test.rb ├── ext_test.rb ├── fixtures ├── bob.html ├── chowhound.html ├── corkd.html ├── event_addr.html ├── events.html ├── fake.html ├── fauxtank.html ├── hatom.html ├── hresume.html ├── include_pattern_single_attribute.html ├── simple.html ├── stoneship.html ├── upcoming.html ├── upcoming_single.html └── xfn.html ├── hatom_test.rb ├── hcalendar_test.rb ├── hcard_test.rb ├── hresume_test.rb ├── hreview_test.rb ├── include_pattern_test.rb ├── reltag_test.rb ├── subclass_test.rb ├── test_helper.rb ├── xfn_test.rb └── xoxo_test.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.data 2 | *.diff 3 | *.solr 4 | *.sql 5 | *.swp 6 | *.tmp 7 | *~ 8 | .dev 9 | .dtach 10 | .rvmrc 11 | .sass-cache 12 | /.rbenv-vars 13 | Makefile 14 | config/sunspot.yml 15 | coverage.info* 16 | coverage/* 17 | db/*.sqlite3 18 | db/*.sqlite3.* 19 | index/* 20 | log/* 21 | solr/data/* 22 | tags 23 | tmp/* 24 | tmp/cache/* 25 | tmp/pids/* 26 | tmp/sessions/* 27 | tmp/sockets/* 28 | .ruby-gemset 29 | .ruby-version 30 | /spec/examples.txt 31 | 32 | # OS or Editor folders 33 | .DS_Store 34 | Thumbs.db 35 | .cache 36 | .project 37 | .settings 38 | .tmproj 39 | *.esproj 40 | nbproject 41 | *.sublime-project 42 | *.sublime-workspace 43 | 44 | # Komodo 45 | *.komodoproject 46 | .komodotools 47 | 48 | # Folders to ignore 49 | .hg 50 | .svn 51 | .CVS 52 | .idea 53 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | 3 | tags 4 | *.data 5 | *.diff 6 | *.solr 7 | *.sql 8 | *.swp 9 | *.tmp 10 | .dtach 11 | config/thin.yml 12 | config/mongrel_cluster.yml 13 | config/geocoder_api_keys.yml 14 | coverage/* 15 | db/schema.rb 16 | db/*.sqlite3 17 | db/*.sqlite3.* 18 | index/* 19 | log/* 20 | public/images/active_scaffold 21 | public/images/record_select 22 | public/javascripts/active_scaffold 23 | public/javascripts/record_select 24 | public/javascripts/all.js 25 | public/stylesheets/active_scaffold 26 | public/stylesheets/record_select 27 | public/stylesheets/all.css 28 | vendor/plugins/acts_as_solr/solr/logs/* 29 | vendor/plugins/acts_as_solr/solr/tmp/* 30 | vendor/plugins/acts_as_solr/solr/solr/data/* 31 | tmp/* 32 | tmp/cache/* 33 | tmp/pids/* 34 | tmp/sessions/* 35 | tmp/sockets/* 36 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 1.8.7 4 | - 1.9.3 5 | - 2.0.0 6 | - rbx-2.1.1 7 | 8 | ## Don't test 1.9.2 because people shouldn't be using it. 9 | # - 1.9.2 10 | 11 | ## Don't test REE because it's compatible enough with 1.8.7. 12 | # - ree 13 | 14 | ## JRuby is not compatible, see Gemfile for details. 15 | # - jruby-18mode 16 | # - jruby-19mode 17 | # - jruby-head 18 | env: 19 | - DB=mysql 20 | - DB=postgresql 21 | - DB=sqlite 22 | before_install: 23 | - ruby ci/copy_database_config.rb 24 | before_script: 25 | - mysql -e 'create database calagator_test;' 26 | - psql -c 'create database calagator_test;' -U postgres 27 | - bundle exec rake db:migrate 28 | - cp "config/secrets.yml.sample" "config/secrets.yml" 29 | script: 30 | - bundle exec rake spec --trace 31 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | http://www.opensource.org/licenses/mit-license.php 2 | 3 | The MIT License 4 | 5 | Original work Copyright (c) 2007-2011 Calagator 6 | Modified work Copyright (c) 2011-2013 Social Action Network LLC, ActivateHub.org 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/images/disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/disk.png -------------------------------------------------------------------------------- /app/assets/images/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/edit.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/epdx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/epdx.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/external.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/external.gif -------------------------------------------------------------------------------- /app/assets/images/external_sites/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/facebook.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/foursquare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/foursquare.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/gowalla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/gowalla.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/lanyrd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/lanyrd.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/meetup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/meetup.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/plancast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/plancast.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/shizzow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/shizzow.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/upcoming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/upcoming.png -------------------------------------------------------------------------------- /app/assets/images/external_sites/yelp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/external_sites/yelp.png -------------------------------------------------------------------------------- /app/assets/images/feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/feed.png -------------------------------------------------------------------------------- /app/assets/images/head_calagator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/head_calagator.gif -------------------------------------------------------------------------------- /app/assets/images/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/heart.png -------------------------------------------------------------------------------- /app/assets/images/icon_ical.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/icon_ical.gif -------------------------------------------------------------------------------- /app/assets/images/information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/information.png -------------------------------------------------------------------------------- /app/assets/images/nav_marker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/nav_marker.gif -------------------------------------------------------------------------------- /app/assets/images/nav_marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/nav_marker.png -------------------------------------------------------------------------------- /app/assets/images/navbar-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/navbar-logo.png -------------------------------------------------------------------------------- /app/assets/images/oaklandmakers-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/oaklandmakers-logo.png -------------------------------------------------------------------------------- /app/assets/images/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/og-image.png -------------------------------------------------------------------------------- /app/assets/images/og-oaklandmakers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/og-oaklandmakers.png -------------------------------------------------------------------------------- /app/assets/images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/plus.png -------------------------------------------------------------------------------- /app/assets/images/public_wifi-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/public_wifi-16x16.png -------------------------------------------------------------------------------- /app/assets/images/redx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/redx.png -------------------------------------------------------------------------------- /app/assets/images/site-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/site-icon.png -------------------------------------------------------------------------------- /app/assets/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/spinner.gif -------------------------------------------------------------------------------- /app/assets/images/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/star.png -------------------------------------------------------------------------------- /app/assets/images/subnav_marker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/subnav_marker.gif -------------------------------------------------------------------------------- /app/assets/images/subnav_marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/subnav_marker.png -------------------------------------------------------------------------------- /app/assets/images/tag_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/tag_blue.png -------------------------------------------------------------------------------- /app/assets/images/weekday_background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/images/weekday_background.gif -------------------------------------------------------------------------------- /app/assets/javascripts/admin.coffee: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/javascripts/admin.coffee -------------------------------------------------------------------------------- /app/assets/javascripts/application.coffee: -------------------------------------------------------------------------------- 1 | #= require jquery 2 | #= require jquery_ujs 3 | #= require jquery.cookie 4 | #= require events 5 | #= require organizations 6 | #= require venues 7 | #= require sources 8 | #= require_self 9 | 10 | $ -> 11 | # mobile-specific behaviour 12 | if $(window).width() <= 820 13 | # move sidebar to bottom of page so it's still accessible 14 | $('#sidebar-welcome, #sidebar-event-details').hide() 15 | $('#sidebar').insertAfter('#main').show() 16 | 17 | # force user to list view if resolution not acceptable for calendar view 18 | $('.events-index .switch-list').click() 19 | 20 | $('#navbar-toggle').click -> 21 | if $('#navbar-menu').is(':visible') 22 | $('#navbar-menu').slideUp('fast') 23 | else 24 | $('#navbar-menu').slideDown('fast') 25 | false 26 | -------------------------------------------------------------------------------- /app/assets/javascripts/forms.js: -------------------------------------------------------------------------------- 1 | //= require jquery-ui 2 | //= require date-functions 3 | //= require jquery.timePicker 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/organizations.coffee: -------------------------------------------------------------------------------- 1 | $ -> 2 | if $('.organizations-show')[0] # only enable on organization show page 3 | $('.show-sources a').click -> 4 | $container = $('.organization-sources-container').show() 5 | $('html, body').animate 6 | scrollTop: $container.offset().top - $('#navbar').outerHeight() 7 | 2000 8 | false 9 | -------------------------------------------------------------------------------- /app/assets/javascripts/sources.coffee: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/javascripts/sources.coffee -------------------------------------------------------------------------------- /app/assets/javascripts/theme.coffee: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/javascripts/theme.coffee -------------------------------------------------------------------------------- /app/assets/javascripts/venues.coffee: -------------------------------------------------------------------------------- 1 | $ -> 2 | if $('.venues-index')[0] # only enable on venue index page 3 | $('.show-all-venues a').click -> 4 | $('.venues-view').addClass('all') 5 | false 6 | 7 | $('.view-switcher a').click -> 8 | $('.view-switcher a').removeClass('selected') 9 | $(this).addClass('selected') 10 | $container = $('.venues-view') 11 | $container.removeClass('list map') 12 | $container.addClass($(this).data('view')); 13 | $.cookie('venues_view', $(this).data('view'), expires: 14, path: '/') 14 | $(window).resize() 15 | false 16 | 17 | $(window).resize -> 18 | if $('.venues-view').hasClass('map') 19 | $card = $('.venues-map') 20 | $card.height($(window).innerHeight() - $card.position().top - 30) 21 | $card.width($(window).innerWidth() - $card.position().left - 30) 22 | $('#google_map').height($card.innerHeight()) 23 | true 24 | 25 | $(window).resize() 26 | -------------------------------------------------------------------------------- /app/assets/stylesheets/common.scss: -------------------------------------------------------------------------------- 1 | .replace-this-text { 2 | margin: 0.25em 0; 3 | padding: 0.15em; 4 | border: 2px solid red; 5 | background: #F5DBD7; 6 | } 7 | 8 | #homepage_sidebar { 9 | display: none; 10 | } 11 | 12 | 13 | .nowrap { 14 | white-space: nowrap; 15 | } 16 | -------------------------------------------------------------------------------- /app/assets/stylesheets/markdown.scss: -------------------------------------------------------------------------------- 1 | // Contains css for HTML elemexts generated by markdown. 2 | .event-description.description, 3 | .description.e-description, 4 | .description { 5 | em { 6 | font-style: italic; 7 | } 8 | 9 | strong { 10 | font-weight:bold; 11 | } 12 | 13 | h1 { 14 | font-size: 2em; 15 | } 16 | 17 | h2 { 18 | font-size: 22px; 19 | } 20 | 21 | h3 { 22 | font-size: 18px; 23 | } 24 | 25 | h4 { 26 | font-size: 16px; 27 | } 28 | 29 | h5 { 30 | font-size: 12px; 31 | } 32 | 33 | h6 { 34 | font-size: 10px; 35 | } 36 | 37 | // These elements do not need any additional styling 38 | // since they look as intended after markdown conversion. 39 | a { 40 | 41 | } 42 | 43 | ol { 44 | 45 | } 46 | 47 | li { 48 | 49 | } 50 | 51 | blockquote { 52 | 53 | } 54 | 55 | code { 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/assets/stylesheets/reset.css: -------------------------------------------------------------------------------- 1 | /* ############################################################## 2 | 3 | reset.css 4 | * Resets default browser CSS. 5 | 6 | Originally from blueprint-css v0.7.1 7 | 8 | ############################################################## */ 9 | 10 | html, body, div, span, object, iframe, 11 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 12 | a, abbr, acronym, address, code, 13 | del, dfn, em, img, q, dl, dt, dd, ol, ul, li, 14 | fieldset, form, label, legend, 15 | table, caption, tbody, tfoot, thead, tr, th, td { 16 | margin: 0; 17 | padding: 0; 18 | border: 0; 19 | font-weight: inherit; 20 | font-style: inherit; 21 | font-size: 100%; 22 | font-family: inherit; 23 | vertical-align: baseline; 24 | } 25 | 26 | body { 27 | line-height: 1.5; 28 | } 29 | 30 | /* Tables still need 'cellspacing="0"' in the markup. */ 31 | table { border-collapse: separate; border-spacing: 0; } 32 | caption, th, td { text-align: left; font-weight: normal; } 33 | table, td, th { vertical-align: middle; } 34 | 35 | /* Remove possible quote marks (") from ,
. */ 36 | blockquote:before, blockquote:after, q:before, q:after { content: ""; } 37 | blockquote, q { quotes: "" ""; } 38 | 39 | /* Remove annoying border on linked images. */ 40 | a img { border: none; } 41 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sources.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | 4 | /*---[ sources show ]-------------------------------------------------------*/ 5 | 6 | .sources-show { 7 | .source-item { 8 | margin-bottom: 20px; 9 | } 10 | 11 | .source-title { 12 | line-height: 32px; 13 | font-size: 24px; 14 | font-weight: normal; 15 | } 16 | 17 | .source-url { 18 | max-width: $main-width; 19 | white-space: nowrap; 20 | overflow: hidden; 21 | text-overflow: ellipsis; 22 | } 23 | 24 | .source-url-title, .source-organization-title, .future-events-title, .past-events-title { 25 | margin: 20px 0px 0px 0px; 26 | line-height: 20px; 27 | font-size: 16px; 28 | font-weight: bold; 29 | } 30 | 31 | .source-topics-types { 32 | margin-top: 10px; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/assets/stylesheets/theme.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/app/assets/stylesheets/theme.scss -------------------------------------------------------------------------------- /app/assets/stylesheets/widget.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | 3 | #main { 4 | margin: 20px; 5 | } 6 | 7 | #widget-event-details { 8 | position: fixed; 9 | top: 10px; 10 | z-index: 100; 11 | background-color: rgba(255, 255, 255, 0.9); 12 | min-height: 80%; 13 | max-height: 500px; 14 | padding: 10px; 15 | 16 | border: 1px solid $link-color; 17 | border-left-width: 5px; 18 | -webkit-border-radius: 5px; 19 | -moz-border-radius: 5px; 20 | border-radius: 5px; 21 | 22 | -webkit-box-shadow: 2px 2px 8px 0px rgba(0, 136, 180, 0.25); 23 | -moz-box-shadow: 2px 2px 8px 0px rgba(0, 136, 180, 0.25); 24 | box-shadow: 2px 2px 8px 0px rgba(0, 136, 180, 0.25); 25 | } 26 | 27 | #widget-event-details.pos-left { 28 | left: 10px; 29 | } 30 | 31 | #widget-event-details.pos-right { 32 | right: 10px; 33 | } 34 | -------------------------------------------------------------------------------- /app/controllers/admin/venues_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::VenuesController < AdminController 2 | respond_to :html, :json 3 | 4 | include SquashManyDuplicatesMixin # provides squash_many_duplicates 5 | 6 | def index 7 | @venues = Venue.non_duplicates 8 | 9 | # ransack-compatible param-based search (might use real gem later if enough uses) 10 | if params[:type] == 'missing_lat_long' 11 | @venues = @venues.where('latitude is null or longitude is null') 12 | end 13 | 14 | @venues = @venues.order(:title) 15 | 16 | respond_with [:admin, @venues] 17 | end 18 | 19 | def duplicates 20 | @venues = Venue.non_duplicates.order(:title) 21 | @groupings = [] 22 | 23 | if params[:type] == 'matching_title' 24 | @groupings = @venues.group_by(&:title) 25 | 26 | elsif params[:type] == 'matching_lat_long' 27 | @venues = @venues.where('latitude is not null and longitude is not null') 28 | @groupings = @venues.group_by {|v| [v.latitude.to_s, v.longitude.to_s] } 29 | end 30 | 31 | @groupings = @groupings.reject {|k,v| v.size < 2 } 32 | 33 | respond_with @groupings 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /app/controllers/admin_controller.rb: -------------------------------------------------------------------------------- 1 | class AdminController < ApplicationController 2 | layout 'admin' 3 | 4 | before_action :authenticate_admin 5 | 6 | def index; end 7 | 8 | end 9 | -------------------------------------------------------------------------------- /app/controllers/site_controller.rb: -------------------------------------------------------------------------------- 1 | class SiteController < ApplicationController 2 | 3 | def params 4 | @params ||= UntaintedParams.new(super).for(action_name) 5 | end 6 | 7 | # Raise exception, mostly for confirming that exception_notification works 8 | def omfg 9 | raise ArgumentError, "OMFG" 10 | end 11 | 12 | # Render something to help benchmark stack without the views 13 | def hello 14 | render :plain => "hello" 15 | end 16 | 17 | def index 18 | redirect_to(events_path(:format => params[:format])) 19 | end 20 | 21 | # Displays the about page. 22 | def about; end 23 | 24 | def opensearch 25 | respond_to do |format| 26 | format.xml { render :content_type => 'application/opensearchdescription+xml' } 27 | end 28 | end 29 | 30 | class UntaintedParams < SimpleDelegator 31 | def for(action) 32 | respond_to?("for_#{action}") ? send("for_#{action}") : __getobj__ 33 | end 34 | 35 | def for_index 36 | permit(:format) 37 | end 38 | end 39 | 40 | end 41 | -------------------------------------------------------------------------------- /app/controllers/versions_controller.rb: -------------------------------------------------------------------------------- 1 | class VersionsController < ApplicationController 2 | 3 | def params 4 | @params ||= UntaintedParams.new(super).for(action_name) 5 | end 6 | 7 | def edit 8 | @version = Version.find(params[:id]) 9 | @record = @version.next.try(:reify) || @version.item || @version.reify 10 | 11 | singular = @record.class.name.singularize.underscore 12 | plural = @record.class.name.pluralize.underscore 13 | self.instance_variable_set("@#{singular}", @record) 14 | 15 | if request.xhr? 16 | render :partial => "/#{plural}/form", :locals => { singular.to_sym => @record } 17 | else 18 | render "#{plural}/edit", :locals => { singular.to_sym => @record } 19 | end 20 | end 21 | 22 | class UntaintedParams < SimpleDelegator 23 | def for(action) 24 | respond_to?("for_#{action}") ? send("for_#{action}") : __getobj__ 25 | end 26 | 27 | def for_edit 28 | permit(:id) 29 | end 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /app/helpers/time_range_helper.rb: -------------------------------------------------------------------------------- 1 | require 'time_range' 2 | 3 | module TimeRangeHelper 4 | def normalize_time(start_time, end_time=nil, opts=nil) 5 | TimeRange.new(start_time, end_time, opts).to_s.html_safe 6 | # datetime_format(time,time.min == 0 ? '%I%p' : '%I:%M%p').downcase 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/mixins/decode_html_entities_hack.rb: -------------------------------------------------------------------------------- 1 | # = DecodeHtmlEntitiesHack 2 | # 3 | # Loofah encodes HTML entities in every string that gets passed through it. 4 | # This includes things like the friendly ampersand which we don't want to be HTML 5 | # encoded in our database, so we need to decode the things that it changes. 6 | # 7 | # This should be included in models that use xss_foliate somewhere _after_ the xss_folidate call. 8 | # 9 | # This is, as the name of the module suggests, a giant hack. At some point, it should 10 | # be removed after the issue is resolved in the underlying library: 11 | # https://github.com/flavorjones/loofah/issues/20#issuecomment-1751538 12 | # 13 | # Warning: this effectively renders loofah's "escape" scrubbing mode useless by 14 | # undoing everything it does. Don't use that mode. 15 | # 16 | module DecodeHtmlEntitiesHack 17 | def self.included(base) 18 | base.set_callback(:validate, :before, :decode_html_entities) 19 | end 20 | 21 | def decode_html_entities 22 | self.attributes.each do |field, value| 23 | decoded_content = HTMLEntities.new.decode(value) 24 | if decoded_content.present? && !(decoded_content == value) 25 | self.send("#{field}=", decoded_content) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /app/mixins/strip_whitespace.rb: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /app/mixins/version_diff.rb: -------------------------------------------------------------------------------- 1 | module VersionDiff 2 | 3 | # provides basic diff services between two given versions. 4 | # 5 | # Examples: 6 | # @event.version_diff(1) # diff between 1 and head 7 | # @event.version_diff(1,2) # diff between 1 and 2 8 | # @event.version_diff(:head, 4) #diff between head and 4 9 | # @event.version_diff(3,:prev) # diff between 3 and 2 10 | # @event.version(:prev) # diff between head and prev 11 | # 12 | def version_diff(n1, n2=:head) 13 | if n1 == :prev && n2.nil? 14 | n1 = :head 15 | n2 = :prev 16 | end 17 | 18 | n1 = self.version if n1 == :head 19 | n2 = self.version if n2 == :head 20 | 21 | if n2 == :prev 22 | n2 = n1 23 | n1 = n1-1 24 | end 25 | 26 | raise(ArgumentError, "version cannot be 0") if n1 == 0 || n2 == 0 27 | v1 = self.versions.where({:version => n1}).first 28 | v2 = self.versions.where({:version => n2}).first 29 | 30 | v1.attributes = v2.attributes 31 | changed_fields = v1.changes 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | 4 | def self.current_site 5 | Thread.current[:current_site] 6 | end 7 | 8 | def self.current_site=(site) 9 | Thread.current[:current_site] = site 10 | end 11 | 12 | def self.scope_to_current_site 13 | default_scope -> { current_site ? where(:site_id => current_site.id) : all } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/models/organization.rb: -------------------------------------------------------------------------------- 1 | class Organization < ApplicationRecord 2 | include AssociatedVenues 3 | include UrlValidator 4 | 5 | scope_to_current_site 6 | belongs_to :site 7 | has_many :events 8 | has_many :sources 9 | has_and_belongs_to_many :topics 10 | belongs_to :venue 11 | 12 | # Validations 13 | validates :name, presence: true 14 | 15 | include ValidatesBlacklistOnMixin 16 | validates_blacklist_on :name, :url 17 | 18 | before_validation :normalize_url! 19 | validates_format_of :url, 20 | :with => WEBSITE_FORMAT, 21 | :allow_blank => true, 22 | :allow_nil => true 23 | 24 | validates_format_of :email, 25 | :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/, 26 | :allow_blank => true, 27 | :allow_nil => true, 28 | :message => "is invalid (did you include the @ part?)" 29 | 30 | before_save :check_touch_events 31 | after_save :touch_events 32 | 33 | default_scope -> { order('LOWER(organizations.name) ASC') } 34 | 35 | def title 36 | @name 37 | end 38 | 39 | private 40 | 41 | def check_touch_events 42 | @touch_events = name_changed? 43 | true 44 | end 45 | 46 | def touch_events 47 | return unless @touch_events 48 | events.update_all(:updated_at => Time.zone.now) 49 | sources.update_all(:updated_at => Time.zone.now) 50 | end 51 | 52 | end 53 | -------------------------------------------------------------------------------- /app/models/site_domain.rb: -------------------------------------------------------------------------------- 1 | class SiteDomain < ApplicationRecord 2 | 3 | belongs_to :site 4 | 5 | validates :domain, 6 | presence: true, 7 | uniqueness: { allow_blank: true, case_sensitive: false } 8 | 9 | validates :redirect, 10 | inclusion: { in: [ true, false ], message: :blank } # presence: true 11 | 12 | validates :site, 13 | presence: true 14 | 15 | def domain=(value) 16 | super(value.try(:downcase)) 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /app/models/topic.rb: -------------------------------------------------------------------------------- 1 | class Topic < ApplicationRecord 2 | has_and_belongs_to_many :events 3 | has_and_belongs_to_many :organizations 4 | has_and_belongs_to_many :sources 5 | 6 | belongs_to :site 7 | scope_to_current_site 8 | 9 | # Validations 10 | validates :name, :presence => true 11 | validates :name, :uniqueness => { :scope => :site_id, :case_sensitive => false } 12 | 13 | scope :enabled, -> { where(enabled: true) } 14 | scope :disabled, -> { where(enabled: false) } 15 | 16 | default_scope -> { order('LOWER(topics.name) ASC') } 17 | 18 | 19 | def any_items? 20 | events.any? || organizations.any? || sources.any? 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /app/models/type.rb: -------------------------------------------------------------------------------- 1 | class Type < ApplicationRecord 2 | has_and_belongs_to_many :events 3 | has_and_belongs_to_many :sources 4 | belongs_to :site 5 | scope_to_current_site 6 | 7 | # Validations 8 | validates :name, :presence => true 9 | validates :name, :uniqueness => { :scope => :site_id, :case_sensitive => false } 10 | 11 | scope :enabled, -> { where(enabled: true) } 12 | scope :disabled, -> { where(enabled: false) } 13 | 14 | default_scope -> { order('LOWER(types.name) ASC') } 15 | 16 | 17 | def any_items? 18 | events.any? || sources.any? 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /app/models/update_updated_at_mixin.rb: -------------------------------------------------------------------------------- 1 | # WTF: Rails 3 no longer updates the #updated_at on #save, only on create or through #update_attributes. That's really stupid. 2 | module UpdateUpdatedAtMixin 3 | def self.included(base) 4 | base.send:before_save, lambda { |record| record.updated_at = Time.zone.now } 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ApplicationRecord 2 | # Include default devise modules. Others available are: 3 | # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable 4 | devise :database_authenticatable, :trackable, :validatable, :timeoutable, :registerable 5 | end 6 | -------------------------------------------------------------------------------- /app/models/version.rb: -------------------------------------------------------------------------------- 1 | class Version < ApplicationRecord 2 | include PaperTrail::VersionConcern 3 | 4 | default_scope -> { current_site ? where(:site_id => current_site.id) : all } 5 | 6 | end 7 | -------------------------------------------------------------------------------- /app/views/admin/events/index.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Events 2 | 3 | #admin-content 4 | %table.index-table 5 | %thead 6 | %tr 7 | %th.title Title 8 | %th.start-date Start Date 9 | %th.end-date End Date 10 | %th.venue Venue 11 | %tbody 12 | - @events.each do |event| 13 | %tr 14 | %td.title= link_to event.title, event_path(event), :target => '_blank' 15 | %td.start-date= event.start_time.to_date 16 | %td.end-date= event.end_time.to_date 17 | %td.venue 18 | - if venue = event.venue 19 | = link_to event.venue.title, venue_path(venue), :target => '_blank' 20 | -------------------------------------------------------------------------------- /app/views/admin/index.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Admin Section 2 | 3 | #admin-content 4 | -------------------------------------------------------------------------------- /app/views/admin/topics/_form.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | topic ||= raise ArgumentError, "topic is required in view partial #{__FILE__}" 3 | 4 | 5 | - content_for :css_insert do 6 | = stylesheet_link_tag 'forms' 7 | 8 | - content_for :javascript_insert do 9 | = javascript_include_tag 'forms' 10 | 11 | 12 | .topic-form 13 | = semantic_form_for [:admin, topic], :as => :topic, :html => { :id => 'topic-form' } do |f| 14 | = f.inputs do 15 | = f.input :name 16 | 17 | - if f.object.persisted? 18 | = f.input :enabled 19 | 20 | %li.trap 21 | = label 'trap', 'field', "Leave this field blank or we'll think you're a robot." 22 | = text_field_tag 'trap_field', params[:trap_field] 23 | 24 | = f.actions do 25 | = f.action :submit 26 | 27 | 28 | :javascript 29 | // FIXME: shouldn't have to work around 'topic' class css rule, should be scoped better 30 | $('form').removeClass('topic'); 31 | -------------------------------------------------------------------------------- /app/views/admin/topics/edit.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Edit a Topic 2 | 3 | #admin-content 4 | = render 'form', :topic => @topic 5 | -------------------------------------------------------------------------------- /app/views/admin/topics/index.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Topics 2 | 3 | #admin-content 4 | %table.index-table 5 | %thead 6 | %tr 7 | %th Name 8 | %th Enabled 9 | %th # Events 10 | %th # Organizations 11 | %th # Sources 12 | %tbody 13 | - @topics.each do |topic| 14 | %tr 15 | %td= link_to topic.name, admin_topic_path(topic) 16 | %td= topic.enabled? ? '✔'.html_safe : '' 17 | %td= topic.events.size 18 | %td= topic.organizations.size 19 | %td= topic.sources.size 20 | -------------------------------------------------------------------------------- /app/views/admin/topics/new.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Create a Topic 2 | 3 | #admin-content 4 | = render 'form', :topic => @topic 5 | -------------------------------------------------------------------------------- /app/views/admin/topics/show.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Topic: #{@topic.name} 2 | 3 | #admin-content 4 | - unless @topic.any_items? 5 | = link_to 'Delete this topic', admin_topic_path(@topic), :method => :delete, :data => { :confirm => 'Are you sure?' } 6 | 7 | = render 'form', :topic => @topic 8 | 9 | %h3 Most Recently Created Events 10 | - if @events.any? 11 | %ul 12 | - @events.each do |event| 13 | %li= link_to "#{event.title} (#{event.start_time.to_date})", event_path(event) 14 | - else 15 | No events. 16 | 17 | %h3 Organizations 18 | - if @organizations.any? 19 | %ul 20 | - @organizations.each do |organization| 21 | %li= link_to organization.name, organization_path(organization) 22 | - else 23 | No organizations. 24 | 25 | %h3 Sources 26 | - if @sources.any? 27 | %ul 28 | - @sources.each do |source| 29 | %li= link_to source.title, organization_source_path(source.organization, source) 30 | - else 31 | No sources. 32 | -------------------------------------------------------------------------------- /app/views/admin/types/_form.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | type ||= raise ArgumentError, "type is required in view partial #{__FILE__}" 3 | 4 | 5 | - content_for :css_insert do 6 | = stylesheet_link_tag 'forms' 7 | 8 | - content_for :javascript_insert do 9 | = javascript_include_tag 'forms' 10 | 11 | 12 | .type-form 13 | = semantic_form_for [:admin, type], :as => :type, :html => { :id => 'type-form' } do |f| 14 | = f.inputs do 15 | = f.input :name 16 | 17 | - if f.object.persisted? 18 | = f.input :enabled 19 | 20 | %li.trap 21 | = label 'trap', 'field', "Leave this field blank or we'll think you're a robot." 22 | = text_field_tag 'trap_field', params[:trap_field] 23 | 24 | = f.actions do 25 | = f.action :submit 26 | 27 | 28 | :javascript 29 | // FIXME: shouldn't have to work around 'type' class css rule, should be scoped better 30 | $('form').removeClass('type'); 31 | -------------------------------------------------------------------------------- /app/views/admin/types/edit.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Edit a Type 2 | 3 | #admin-content 4 | = render 'form', :type => @type 5 | -------------------------------------------------------------------------------- /app/views/admin/types/index.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Types 2 | 3 | #admin-content 4 | %table.index-table 5 | %thead 6 | %tr 7 | %th Name 8 | %th Enabled 9 | %th # Events 10 | %th # Sources 11 | %tbody 12 | - @types.each do |type| 13 | %tr 14 | %td= link_to type.name, admin_type_path(type) 15 | %td= type.enabled? ? '✔'.html_safe : '' 16 | %td= type.events.size 17 | %td= type.sources.size 18 | -------------------------------------------------------------------------------- /app/views/admin/types/new.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Create a Type 2 | 3 | #admin-content 4 | = render 'form', :type => @type 5 | -------------------------------------------------------------------------------- /app/views/admin/types/show.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Type: #{@type.name} 2 | 3 | #admin-content 4 | - unless @type.any_items? 5 | = link_to 'Delete this type', admin_type_path(@type), :method => :delete, :data => { :confirm => 'Are you sure?' } 6 | 7 | = render 'form', :type => @type 8 | 9 | %h3 Most Recently Created Events 10 | - if @events.any? 11 | %ul 12 | - @events.each do |event| 13 | %li= link_to "#{event.title} (#{event.start_time.to_date})", event_path(event) 14 | - else 15 | No events. 16 | 17 | %h3 Sources 18 | - if @sources.any? 19 | %ul 20 | - @sources.each do |source| 21 | %li= link_to source.title, organization_source_path(source.organization, source) 22 | - else 23 | No sources. 24 | -------------------------------------------------------------------------------- /app/views/admin/venues/duplicates.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Duplicate Venue Detector 2 | 3 | #admin-content 4 | - @groupings.each do |title,grouping| 5 | = form_for duplicates_admin_venues_path, :html => { :class => 'grouped-duplicates-form' } do |f| 6 | %h3= title 7 | %table.index-table 8 | %thead 9 | %tr 10 | %th.master Master? 11 | %th.duplicate Duplicate? 12 | %th.title Title 13 | %th.num-events # Events 14 | %tbody 15 | - grouping.each do |venue| 16 | %tr 17 | %td.master= radio_button_tag 'master_id', venue.id 18 | %td.duplicate= check_box_tag "duplicate_id_#{venue.id}", venue.id 19 | %td.title= link_to venue.title, venue_path(venue), :target => '_blank' 20 | %td.num-events= venue.events_count || '-' 21 | 22 | = hidden_field_tag 'type', params[:type] 23 | = button_tag 'Squash Duplicates', :style => 'display:none' 24 | 25 | :javascript 26 | $(document).ready(function() { 27 | var $forms = $('.grouped-duplicates-form'); 28 | $forms.find('input[type=radio]').click(function(e) { 29 | $(e.target).closest('form').find('button').show(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /app/views/admin/venues/index.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title Venues 2 | 3 | #admin-content 4 | %table.index-table.venue-duplicates 5 | %thead 6 | %tr 7 | %th Title 8 | %th # Events 9 | %th Address 10 | %tbody 11 | - @venues.each do |venue| 12 | %tr 13 | %td= link_to venue.title, venue_path(venue), :target => '_blank' 14 | %td= venue.events_count || '-' 15 | %td= venue.full_address || venue.address 16 | -------------------------------------------------------------------------------- /app/views/devise/confirmations/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend confirmation instructions

2 | 3 | <%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
<%= f.label :email %>
7 | <%= f.email_field :email %>
8 | 9 |
<%= f.submit "Resend confirmation instructions" %>
10 | <% end %> 11 | 12 | <%= render :partial => "devise/shared/links" %> -------------------------------------------------------------------------------- /app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @resource.email %>!

2 | 3 |

You can confirm your account through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %>

6 | -------------------------------------------------------------------------------- /app/views/devise/mailer/reset_password_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Someone has requested a link to change your password, and you can do this through the link below.

4 | 5 |

<%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %>

6 | 7 |

If you didn't request this, please ignore this email.

8 |

Your password won't change until you access the link above and create a new one.

9 | -------------------------------------------------------------------------------- /app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive amount of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %>

8 | -------------------------------------------------------------------------------- /app/views/devise/menu/_login_links.html.erb: -------------------------------------------------------------------------------- 1 | <% if user_signed_in? %> 2 | <%= link_to('Logout', destroy_user_session_path, :method => :delete) %> 3 | <% else %> 4 | <%= link_to('Login', new_user_session_path) %> 5 | <% end %> -------------------------------------------------------------------------------- /app/views/devise/passwords/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Change your password

2 | 3 | <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %> 4 | <%= devise_error_messages! %> 5 | <%= f.hidden_field :reset_password_token %> 6 | 7 |
<%= f.label :password, "New password" %>
8 | <%= f.password_field :password %>
9 | 10 |
<%= f.label :password_confirmation, "Confirm new password" %>
11 | <%= f.password_field :password_confirmation %>
12 | 13 |
<%= f.submit "Change my password" %>
14 | <% end %> 15 | 16 | <%= render :partial => "devise/shared/links" %> -------------------------------------------------------------------------------- /app/views/devise/passwords/new.html.erb: -------------------------------------------------------------------------------- 1 |

Forgot your password?

2 | 3 | <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
<%= f.label :email %>
7 | <%= f.email_field :email %>
8 | 9 |
<%= f.submit "Send me reset password instructions" %>
10 | <% end %> 11 | 12 | <%= render :partial => "devise/shared/links" %> -------------------------------------------------------------------------------- /app/views/devise/registrations/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Edit <%= resource_name.to_s.humanize %>

2 | 3 | <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
<%= f.label :email %>
7 | <%= f.email_field :email %>
8 | 9 |
<%= f.label :password %> (leave blank if you don't want to change it)
10 | <%= f.password_field :password %>
11 | 12 |
<%= f.label :password_confirmation %>
13 | <%= f.password_field :password_confirmation %>
14 | 15 |
<%= f.label :current_password %> (we need your current password to confirm your changes)
16 | <%= f.password_field :current_password %>
17 | 18 |
<%= f.submit "Update" %>
19 | <% end %> 20 | 21 |

Cancel my account

22 | 23 |

Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :method => :delete, :data => { :confirm => "Are you sure?" } %>.

24 | 25 | <%= link_to "Back", :back %> 26 | -------------------------------------------------------------------------------- /app/views/devise/registrations/new.html.erb: -------------------------------------------------------------------------------- 1 |

Sign up

2 | 3 | <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
<%= f.label :email %>
7 | <%= f.email_field :email %>
8 | 9 |
<%= f.label :password %>
10 | <%= f.password_field :password %>
11 | 12 |
<%= f.label :password_confirmation %>
13 | <%= f.password_field :password_confirmation %>
14 | 15 |
<%= f.submit "Sign up" %>
16 | <% end %> 17 | 18 | <%= render :partial => "devise/shared/links" %> 19 | -------------------------------------------------------------------------------- /app/views/devise/sessions/new.html.erb: -------------------------------------------------------------------------------- 1 |

Sign in

2 | 3 | <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %> 4 |
<%= f.label :email %>
5 | <%= f.email_field :email %>
6 | 7 |
<%= f.label :password %>
8 | <%= f.password_field :password %>
9 | 10 | <% if devise_mapping.rememberable? -%> 11 |
<%= f.check_box :remember_me %> <%= f.label :remember_me %>
12 | <% end -%> 13 | 14 |
<%= f.submit "Sign in" %>
15 | <% end %> 16 | 17 | <%= render :partial => "devise/shared/links" %> -------------------------------------------------------------------------------- /app/views/devise/shared/_links.erb: -------------------------------------------------------------------------------- 1 | <%- if controller_name != 'sessions' %> 2 | <%= link_to "Sign in", new_session_path(resource_name) %>
3 | <% end -%> 4 | 5 | <%- if devise_mapping.registerable? && controller_name != 'registrations' %> 6 | <%= link_to "Sign up", new_registration_path(resource_name) %>
7 | <% end -%> 8 | 9 | <%- if devise_mapping.recoverable? && controller_name != 'passwords' %> 10 | <%= link_to "Forgot your password?", new_password_path(resource_name) %>
11 | <% end -%> 12 | 13 | <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> 14 | <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
15 | <% end -%> 16 | 17 | <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> 18 | <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
19 | <% end -%> 20 | 21 | <%- if devise_mapping.omniauthable? %> 22 | <%- resource_class.omniauth_providers.each do |provider| %> 23 | <%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %>
24 | <% end -%> 25 | <% end -%> -------------------------------------------------------------------------------- /app/views/devise/unlocks/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend unlock instructions

2 | 3 | <%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
<%= f.label :email %>
7 | <%= f.email_field :email %>
8 | 9 |
<%= f.submit "Resend unlock instructions" %>
10 | <% end %> 11 | 12 | <%= render :partial => "devise/shared/links" %> -------------------------------------------------------------------------------- /app/views/events/_comments.html.haml: -------------------------------------------------------------------------------- 1 | - if disqus_shortname = @current_site.disqus_shortname.presence 2 | .event-comments 3 | #disqus_thread 4 | 5 | :javascript 6 | var disqus_shortname = #{disqus_shortname.to_json.html_safe}; 7 | 8 | (function() { 9 | var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; 10 | dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; 11 | (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); 12 | })(); 13 | -------------------------------------------------------------------------------- /app/views/events/_exports.html.haml: -------------------------------------------------------------------------------- 1 | %h3.subscriptions-title= t('.subscriptions.title') 2 | %ul.subscriptions-list 3 | %li= link_to t('.subscriptions.ical'), icalendar_feed_link 4 | %li= link_to t('.subscriptions.atom'), atom_feed_link 5 | %li= link_to t('.subscriptions.gcal'), google_events_subscription_link 6 | 7 | %h3.downloads-title= t('.downloads.title') 8 | %ul.downloads-list 9 | %li= link_to t('.downloads.ical'), icalendar_export_link 10 | -------------------------------------------------------------------------------- /app/views/events/_filters.html.haml: -------------------------------------------------------------------------------- 1 | = render 'filters/topic', :topics => @topics, :selected => @selected_topics 2 | = render 'filters/type', :types => @types, :selected => @selected_types 3 | = render 'filters/date' 4 | -------------------------------------------------------------------------------- /app/views/events/_item_exports.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | event ||= raise ArgumentError, "event is required in view partial #{__FILE__}" 3 | 4 | 5 | %h3.downloads-title= t('.downloads.title') 6 | %ul.downloads-list 7 | %li.download-gcal= link_to t('.downloads.gcal'), google_event_export_link(event), :target => '_blank' 8 | %li.download-ical= link_to t('.downloads.ical'), url_for(:format => :ics) 9 | -------------------------------------------------------------------------------- /app/views/events/_list.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | events ||= raise ArgumentError, "event is required in view partial #{__FILE__}" 3 | events_by_date = events.group_by {|e| e.start_time.to_date } 4 | 5 | 6 | - events_by_date.each do |date,events| 7 | .date 8 | .wday= t('date.day_names')[date.wday] 9 | .month= t('date.abbr_month_names')[date.month] 10 | .dom= date.day 11 | .year= date.year 12 | - events.each do |event| 13 | = render 'events/index_item', :event => event 14 | -------------------------------------------------------------------------------- /app/views/events/_share_buttons.html.haml: -------------------------------------------------------------------------------- 1 | - if sharethis_key = @current_site.sharethis_key.presence 2 | - content_for :javascript_insert do 3 | = javascript_include_tag 'http://w.sharethis.com/button/buttons.js' 4 | :javascript 5 | stLight.options({ 6 | publisher: #{sharethis_key.to_json.html_safe}, 7 | doNotHash: true, 8 | doNotCopy: true, 9 | hashAddressBar: false 10 | }); 11 | 12 | .event-share-buttons 13 | .st-widget.st_plusone_hcount{:displayText => 'Google +1'} 14 | .st-widget.st_twitter_hcount{:displayText => 'Tweet'} 15 | .st-widget.st_facebook_hcount{:displayText => 'Facebook'} 16 | .st-widget.st_reddit_hcount{:displayText => 'Reddit'} 17 | -------------------------------------------------------------------------------- /app/views/events/edit.html.haml: -------------------------------------------------------------------------------- 1 | - if params[:preview] && @event.valid? 2 | %h2.preview-title Preview 3 | .event-preview.events-show= render 'events/item', :event => @event 4 | .preview-separator 5 | 6 | %h2.main-title= t('.title') 7 | 8 | #main-content 9 | .appropriateness= t('events.appropriateness') 10 | = render 'form', :event => @event 11 | -------------------------------------------------------------------------------- /app/views/events/index.atom.builder: -------------------------------------------------------------------------------- 1 | collection_cache @events, [@start_date, @end_date, Time.zone.today] do 2 | atom_feed("xmlns:georss".to_sym => "http://www.georss.org/georss") do |feed| 3 | feed.title("#{@current_site.name}#{': ' + @page_title if @page_title}") 4 | unless @events.size == 0 5 | feed.updated(@events.present? ? @events.sort_by(&:updated_at).last.updated_at : Time.zone.now) 6 | 7 | for event in @events 8 | feed.entry(event) do |entry| 9 | summary = "#{normalize_time(event.start_time, event.end_time, :format => :text)}" 10 | summary += " at #{event.venue.title}" if event.venue && !event.venue.title.blank? 11 | 12 | entry.title(event.title) 13 | entry.summary(summary) 14 | entry.url(event_url(event)) 15 | entry.link({:rel => 'enclosure', :type => 'text/calendar', :href => event_url(event, :format => 'ics') }) 16 | entry.start_time(event.start_time.xmlschema) 17 | entry.end_time(event.end_time.xmlschema) if event.end_time 18 | entry.content(render(:partial => 'events/feed_item', :locals => {:event => event}, :formats => [:html]), :type => 'html') 19 | if event.venue && event.venue.latitude && event.venue.longitude 20 | entry.georss :point, "#{event.venue.latitude} #{event.venue.longitude}" 21 | end 22 | end 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /app/views/events/index.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | events_view ||= params[:view] || cookies[:events_view] || 'calendar' 3 | 4 | # widget overridable view elements 5 | page_title = params[:title] || t('.title') # "?title=" should hide title 6 | event_views = params[:views] ? params[:views].split(',') : %w( calendar list ) 7 | 8 | - content_for :sidebar do 9 | #sidebar-welcome.sidebar-box= render 'site/welcome' 10 | #sidebar-event-details.sidebar-box 11 | #sidebar-filters.sidebar-box= render 'events/filters' 12 | #sidebar-exports.sidebar-box= render 'events/exports' 13 | 14 | - if event_views.any? 15 | .view-switcher 16 | %ul 17 | - if event_views.include?('calendar') 18 | %li= link_to t('.switcher.calendar'), params.merge(:view => 'calendar'), :class => "switch-calendar #{(events_view == 'calendar' ? 'selected' : '')}", :data => { :view => 'calendar' } 19 | - if event_views.include?('list') 20 | %li= link_to t('.switcher.list'), params.merge(:view => 'list'), :class => "switch-list #{(events_view == 'list' ? 'selected' : '')}", :data => { :view => 'list' } 21 | 22 | %h2.main-title= page_title 23 | 24 | .events-list{:class => events_view} 25 | = render 'events/calendar', :events => @events, :start_date => @start_date, :end_date => @end_date 26 | 27 | - if params[:manage] 28 | = render 'manage_overlay' 29 | -------------------------------------------------------------------------------- /app/views/events/index.kml.erb: -------------------------------------------------------------------------------- 1 | <% collection_cache @events, [@start_date, @end_date, Time.zone.today] do %> 2 | 3 | 4 | 5 | <% for event in @events %> 6 | <% next if event.venue.nil? %> 7 | <% next if event.venue.latitude.nil? %> 8 | 9 | <%= escape_once(event.title) %> 10 | <%= cdata_section("#{event.description}

Venue: #{event.venue.title}

") %>
11 | 12 | <%= event.venue.longitude %>,<%= event.venue.latitude %> 13 | 14 | 15 | <%= event.start_time.xmlschema %> 16 | <%= event.end_time.nil? ? (event.start_time+1.hours).xmlschema : event.end_time.xmlschema %> 17 | 18 |
19 | <% end %> 20 |
21 |
22 | <% end %> 23 | -------------------------------------------------------------------------------- /app/views/events/new.html.haml: -------------------------------------------------------------------------------- 1 | - if params[:preview] && @event.valid? 2 | %h2.preview-title Preview 3 | .event-preview.events-show= render 'events/item', :event => @event 4 | .preview-separator 5 | 6 | %h2.main-title= t('.title') 7 | 8 | #main-content 9 | .appropriateness= t('events.appropriateness') 10 | = render 'form', :event => @event 11 | -------------------------------------------------------------------------------- /app/views/events/show.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :discovery_insert do 2 | %link{:rel => 'alternative', :type => 'application/x-wiki', :href => edit_event_path, :title => t('.discovery_edit_title')} 3 | 4 | - content_for :sidebar do 5 | #sidebar-welcome.sidebar-box= render 'site/welcome' 6 | #sidebar-wiki-props.sidebar-box= render 'site/wiki_props', :object => @event 7 | #sidebar-event-export.sidebar-box= render 'events/item_exports', :event => @event 8 | 9 | 10 | = render 'events/item', :event => @event 11 | -------------------------------------------------------------------------------- /app/views/filters/_date.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | # an explicitly passed in nil title means to skip, so check if defined 3 | unless defined?(title) then title = t('.title') end 4 | 5 | 6 | - if title 7 | %h3.date-filter-title= title 8 | 9 | = form_for :date, :method => :get, :html => { :class => 'date-filter-form' } do |f| 10 | .field 11 | .label= f.label :start, t('.start') 12 | .value= f.text_field :start, :value => @start_date.strftime('%Y-%m-%d') 13 | .field 14 | .label= f.label :end, t('.end') 15 | .value= f.text_field :end, :value => @end_date.strftime('%Y-%m-%d') 16 | 17 | - [:topic, :type].select {|n| params[n].present? }.each do |n| 18 | = hidden_field_tag n, params[n] 19 | 20 | .buttons 21 | = f.submit t('.submit') 22 | = link_to t('.reset'), params.merge(:date => nil, :commit => nil, :utf8 => nil) 23 | -------------------------------------------------------------------------------- /app/views/filters/_topic.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | topics ||= raise ArgumentError, "topics is required in view partial #{__FILE__}" 3 | selected = selected ? [*selected] : nil # force into array if just a single value 4 | 5 | # an explicitly passed in nil title means to skip, so check if defined 6 | unless defined?(title) then title = t('.title') end 7 | 8 | 9 | - if title 10 | %h3.topics-title= title 11 | 12 | .topics-list< 13 | - topics.each do |topic| 14 | - if !selected || selected.include?(topic.name) 15 | = link_to topic[:name], params.merge(:topic => topic[:name]), :class => 'topic' 16 | - else 17 | = link_to topic[:name], params.merge(:topic => topic[:name]), :class => 'topic empty' 18 | 19 | - if selected 20 | = link_to t('.reset'), params.merge(:topic => nil), :class => 'clear-topic' 21 | -------------------------------------------------------------------------------- /app/views/filters/_type.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | types ||= raise ArgumentError, "types is required in view partial #{__FILE__}" 3 | selected = selected ? [*selected] : nil # force into array if just a single value 4 | 5 | # an explicitly passed in nil title means to skip, so check if defined 6 | unless defined?(title) then title = t('.title') end 7 | 8 | 9 | - if title 10 | %h3.types-title= title 11 | 12 | .types-list< 13 | - types.each do |type| 14 | - if !selected || selected.include?(type.name) 15 | = link_to type[:name], params.merge(:type => type[:name]), :class => 'type' 16 | - else 17 | = link_to type[:name], params.merge(:type => type[:name]), :class => 'type empty' 18 | 19 | - if selected 20 | = link_to t('.reset'), params.merge(:type => nil), :class => 'clear-type' 21 | -------------------------------------------------------------------------------- /app/views/layouts/admin.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :sidebar do 2 | #sidebar-nav.sidebar-box 3 | %h3 Topics 4 | %ul 5 | %li= link_to 'Create a new topic', new_admin_topic_path 6 | %li= link_to 'View all topics', admin_topics_path 7 | 8 | %h3 Types 9 | %ul 10 | %li= link_to 'Create a new type', new_admin_type_path 11 | %li= link_to 'View all types', admin_types_path 12 | 13 | %h3 Possible Issues 14 | %ul 15 | %li= link_to 'Venues without map coordinates', admin_venues_path(:type => 'missing_lat_long') 16 | %li= link_to 'Events without an end time', admin_events_path(:type => 'missing_end_time') 17 | %li= link_to 'Events without topics', admin_events_path(:type => 'missing_topic') 18 | %li= link_to 'Events without types', admin_events_path(:type => 'missing_type') 19 | 20 | %h3 Duplicate Management 21 | %ul 22 | %li= link_to 'Venues with a matching title', duplicates_admin_venues_path(:type => 'matching_title') 23 | %li= link_to 'Venues at same map coordinates', duplicates_admin_venues_path(:type => 'matching_lat_long') 24 | %li= link_to 'Events with overlapping time and venue', duplicates_admin_events_path(:type => 'overlapping_venue_and_time') 25 | %li= link_to 'Drag & Drop Event Cleanup', events_path(:manage => 1) 26 | 27 | - content_for :content do 28 | = yield 29 | 30 | = render :file => 'layouts/application' 31 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.haml: -------------------------------------------------------------------------------- 1 | !!! XML 2 | !!! 3 | 4 | %html 5 | %head 6 | = render 'site/head' 7 | 8 | %body{:class => "#{controller.controller_path.parameterize}-#{action_name} application"} 9 | #navbar= render 'site/navbar' 10 | #sidebar= render 'site/sidebar' 11 | 12 | #main 13 | - flash.each do |klass,msg| 14 | .flash-msg{:class => klass}!= msg 15 | = content_for?(:content) ? yield(:content) : yield 16 | 17 | #footer= render 'site/footer' 18 | -------------------------------------------------------------------------------- /app/views/layouts/widget.html.haml: -------------------------------------------------------------------------------- 1 | !!! XML 2 | !!! 3 | 4 | %html 5 | %head 6 | = stylesheet_link_tag 'application', 'theme', 'widget', :media => :all 7 | = javascript_include_tag 'widget', 'theme' 8 | 9 | %body{:class => "#{controller.controller_name}-#{action_name} widget"} 10 | #main 11 | #widget-event-details 12 | = yield 13 | 14 | - # force all links to open in a new tab or window 15 | :javascript 16 | $('.event a').attr('target', '_blank'); 17 | -------------------------------------------------------------------------------- /app/views/organizations/_filters.html.haml: -------------------------------------------------------------------------------- 1 | = render 'filters/topic', :topics => @topics, :selected => @topic 2 | -------------------------------------------------------------------------------- /app/views/organizations/edit.html.haml: -------------------------------------------------------------------------------- 1 | - if params[:preview] && @organization.valid? 2 | %h2.preview-title Preview 3 | .organization-preview.organizations-show= render 'organizations/item', :organization => @organization 4 | .preview-separator 5 | 6 | %h2.main-title= t('.title') 7 | 8 | #main-content 9 | = render 'form', :organization => @organization 10 | -------------------------------------------------------------------------------- /app/views/organizations/index.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :sidebar do 2 | #sidebar-welcome.sidebar-box= render 'site/welcome' 3 | #sidebar-wiki-props.sidebar-box= render 'site/wiki_props_index', :collection => Organization.all 4 | #sidebar-filters.sidebar-box= render 'organizations/filters' 5 | 6 | 7 | - collection_cache @organizations do 8 | %h2.main-title= t('.title') 9 | 10 | %ul.organizations-view 11 | - for organization in @organizations 12 | %li.organization 13 | .organization-name= link_to organization.name, organization_path(organization) 14 | 15 | - if organization.url? 16 | .organization-url 17 | .organization-url-label= t('.url_label') 18 | = link_to organization.url, organization.url, :target => '_blank' 19 | 20 | .organization-description= organization.description 21 | 22 | .organization-topics< 23 | - organization.topics.each do |topic| 24 | = link_to topic.name, '#', :class => 'topic' 25 | -------------------------------------------------------------------------------- /app/views/organizations/new.html.haml: -------------------------------------------------------------------------------- 1 | - if params[:preview] && @organization.valid? 2 | %h2.preview-title Preview 3 | .organization-preview.organizations-show= render 'organizations/item', :organization => @organization 4 | .preview-separator 5 | 6 | %h2.main-title= t('.title') 7 | 8 | #main-content 9 | = render 'form', :organization => @organization 10 | -------------------------------------------------------------------------------- /app/views/organizations/show.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :sidebar do 2 | #sidebar-welcome.sidebar-box= render 'site/welcome' 3 | #sidebar-event-details.sidebar-box 4 | #sidebar-wiki-props.sidebar-box= render 'site/wiki_props', :object => @organization, :clone => false 5 | 6 | 7 | = render 'organizations/item', :organization => @organization 8 | 9 | - collection_cache @future_events, [:future, @organization.cache_key] do 10 | %h2.future-events-title= t('.future_events.title') 11 | .future-events.events-list.list 12 | - if @future_events.any? 13 | = render 'events/list', :events => @future_events 14 | - else 15 | .no-events= t('.future_events.none') 16 | 17 | - collection_cache @past_events, [:past, @organization.cache_key] do 18 | %h2.past-events-title= t('.past_events.title') 19 | .past-events.events-list.list 20 | - if @past_events.any? 21 | = render 'events/list', :events => @past_events 22 | - else 23 | .no-events= t('.past_events.none') 24 | -------------------------------------------------------------------------------- /app/views/site/_change.html.erb: -------------------------------------------------------------------------------- 1 | <%= link_to item.title, object %> : Version <%= item.version %>; 2 | <%= item.updated_at.strftime('%B %d, %Y at %I:%M %p') %> 3 | 4 | <% unless item.version==1 %> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | <% 13 | object.version_diff(item.version, :prev).each do |field_name, values| 14 | next if %w(updated_at).include?(field_name) 15 | %> 16 | 17 | <% end %> 18 | 19 |
FieldOldNew
<%= field_name %><%= values[0] %><%= values[1] %>
20 | <% end %> 21 | -------------------------------------------------------------------------------- /app/views/site/_description.html.erb: -------------------------------------------------------------------------------- 1 |

2 | Describe your site in: themes/YOUR_THEME/views/site/_description.html.erb 3 |

4 | -------------------------------------------------------------------------------- /app/views/site/_footer.html.haml: -------------------------------------------------------------------------------- 1 | %p= t('.').html_safe 2 | -------------------------------------------------------------------------------- /app/views/site/_navbar.html.haml: -------------------------------------------------------------------------------- 1 | #navbar-logo 2 | = link_to t('.logo_link', :default => '/') do 3 | - if logo_src = t('.logo_src', :default => '').presence 4 | = image_tag logo_src, :title => @current_site.name 5 | - else 6 | = @current_site.name 7 | 8 | #navbar-toggle 9 | %a 10 | %span.icon-bar 11 | %span.icon-bar 12 | %span.icon-bar 13 | 14 | #login_links= render 'devise/menu/login_links' 15 | 16 | #navbar-menu 17 | %ul 18 | %li{:class => link_class[:events]}= link_to t('.menu.events'), events_path 19 | %li{:class => link_class[:organizations]}= link_to t('.menu.organizations'), organizations_path 20 | %li{:class => link_class[:venues]}= link_to t('.menu.venues'), venues_path 21 | %li= link_to t('.menu.new_event'), new_event_path 22 | 23 | #navbar-search 24 | = form_tag search_events_path, :method => :get do 25 | = text_field_tag 'query', @query, :placeholder => t('.search.placeholder') 26 | -------------------------------------------------------------------------------- /app/views/site/_sidebar.html.haml: -------------------------------------------------------------------------------- 1 | = yield :sidebar 2 | -------------------------------------------------------------------------------- /app/views/site/_tracking.html.haml: -------------------------------------------------------------------------------- 1 | - if Rails.env.production? && @current_site.ga_account_id.present? 2 | :javascript 3 | var _gaq = _gaq || []; 4 | _gaq.push(['_setAccount', #{@current_site.ga_account_id.to_json.html_safe}]); 5 | _gaq.push(['_setDomainName', #{@current_site.domain.to_json.html_safe}]); 6 | _gaq.push(['_trackPageview']); 7 | 8 | (function() { 9 | var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; 10 | ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 11 | var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); 12 | })(); 13 | -------------------------------------------------------------------------------- /app/views/site/_welcome.html.haml: -------------------------------------------------------------------------------- 1 | %h4.welcome-title= t('.title').html_safe 2 | %p.welcome-text= t('.text').html_safe 3 | -------------------------------------------------------------------------------- /app/views/site/_wiki_props.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | object ||= raise ArgumentError, "object is required in view partial #{__FILE__}" 3 | ns ||= [] 4 | clone = clone.nil? ? true : clone 5 | 6 | ns << object # ns is just the object w/ namespace object(s) - [organization, source] 7 | object_name = object.class.name.downcase 8 | 9 | %h3.wiki-props-title= t('.title', :obj => object_name) 10 | 11 | .wiki-actions 12 | - edit_link = link_to t('.edit'), edit_polymorphic_path(ns) 13 | - if current_user 14 | - delete_link = link_to t('.delete'), polymorphic_path(ns), :method => :delete, :data => { :confirm => t('.delete_confirm', :obj => object_name) } 15 | 16 | - if clone 17 | - clone_link = link_to t('.clone'), polymorphic_path([:clone, *ns]) 18 | = t('.actions', :edit => edit_link, :clone => clone_link, :delete => delete_link, :obj => object_name).html_safe 19 | - else 20 | = t('.actions_no_clone', :edit => edit_link, :delete => delete_link, :obj => object_name).html_safe 21 | 22 | .wiki-metadata= datestamp(object) 23 | -------------------------------------------------------------------------------- /app/views/site/_wiki_props_index.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | collection ||= raise ArgumentError, "collection is required in view partial #{__FILE__}" 3 | object_name = collection.klass.name.downcase 4 | collection_name = object_name.pluralize 5 | 6 | %h3.wiki-index-title= t('.title', :obj => collection_name) 7 | 8 | .wiki-actions 9 | - add_link = link_to t('.add'), new_polymorphic_path(collection.klass) 10 | = t('.actions', :add => add_link, :obj => object_name, :collection => collection_name).html_safe 11 | -------------------------------------------------------------------------------- /app/views/site/about.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

About us

3 | 4 |

5 | Describe your project in: themes/YOUR_THEME/views/site/about.html.erb 6 |

7 |
8 | -------------------------------------------------------------------------------- /app/views/site/opensearch.xml.builder: -------------------------------------------------------------------------------- 1 | xml.instruct! 2 | xml.OpenSearchDescription('xmlns' => 'http://a9.com/-/spec/opensearch/1.1/', 'xmlns:moz' => 'http://www.mozilla.org/2006/browser/search/') do 3 | xml.ShortName @current_site.name 4 | xml.Description "Search #{@current_site.name}" 5 | xml.InputEncoding "UTF-8" 6 | # The sub call at the end of this line is because we want to use the rails URL helper, but don't want to urlencode the curly braces. 7 | xml.Url('type' => 'text/html', 'method' => 'get', 'template' => search_events_url(:query => "searchTerms").sub('searchTerms', '{searchTerms}') ) 8 | end 9 | -------------------------------------------------------------------------------- /app/views/sources/_index_item.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | source ||= raise ArgumentError, "source is required in view partial #{__FILE__}" 3 | 4 | .source{:class => (source.enabled? ? 'enabled' : 'disabled')} 5 | .source-title= link_to source.name, organization_source_path(:organization_id => source.organization_id, :id => source.id) 6 | .source-url 7 | .source-url-label= t('.url_label') 8 | = link_to source.url, source.url, :target => '_blank' 9 | 10 | .source-topics-types< 11 | - source.topics.each do |topic| 12 | = link_to topic.name, '#', :class => 'topic' 13 | - source.types.each do |type| 14 | = link_to type.name, '#', :class => 'type' 15 | -------------------------------------------------------------------------------- /app/views/sources/_item.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | source ||= raise ArgumentError, "source is required in view partial #{__FILE__}" 3 | 4 | 5 | - cache source do 6 | .source-item 7 | .source 8 | .source-title= source.title 9 | 10 | %h2.source-url-title= t('.url.title') 11 | .source-url= link_to source.url, source.url, :target => '_blank' 12 | 13 | - if organization = source.organization 14 | %h2.source-organization-title= t('.organization.title') 15 | .source-organization= link_to organization.name, organization_path(organization) 16 | 17 | .source-topics-types< 18 | - source.topics.each do |topic| 19 | = link_to topic.name, '#', :class => 'topic' 20 | - source.types.each do |type| 21 | = link_to type.name, '#', :class => 'type' 22 | -------------------------------------------------------------------------------- /app/views/sources/edit.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title= t('.title') 2 | 3 | #main-content 4 | .appropriateness= t('events.appropriateness') 5 | = render 'form', :source => @source 6 | -------------------------------------------------------------------------------- /app/views/sources/new.html.haml: -------------------------------------------------------------------------------- 1 | %h2.main-title= t('.title') 2 | 3 | #main-content 4 | .appropriateness= t('events.appropriateness') 5 | = render 'form', :source => @source 6 | -------------------------------------------------------------------------------- /app/views/sources/show.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :sidebar do 2 | #sidebar-welcome.sidebar-box= render 'site/welcome' 3 | #sidebar-event-details.sidebar-box 4 | #sidebar-wiki-props.sidebar-box= render 'site/wiki_props', :object => @source, :ns => [@source.organization], :clone => false 5 | 6 | 7 | = render 'sources/item', :source => @source 8 | 9 | - collection_cache @future_events, [:future, @source.cache_key] do 10 | %h2.future-events-title= t('.future_events.title') 11 | .future-events.events-list.list 12 | - if @future_events.any? 13 | = render 'events/list', :events => @future_events 14 | - else 15 | .no-events= t('.future_events.none') 16 | 17 | - collection_cache @past_events, [:past, @source.cache_key] do 18 | %h2.past-events-title= t('.past_events.title') 19 | .past-events.events-list.list 20 | - if @past_events.any? 21 | = render 'events/list', :events => @past_events 22 | - else 23 | .no-events= t('.past_events.none') 24 | -------------------------------------------------------------------------------- /app/views/users/show.html.haml: -------------------------------------------------------------------------------- 1 | %h1= @user.email -------------------------------------------------------------------------------- /app/views/venues/_exports.html.haml: -------------------------------------------------------------------------------- 1 | %h3.downloads-title= t('.downloads.title') 2 | %ul.downloads-list 3 | %li= link_to t('.downloads.kml'), url_for(:format => :kml) 4 | %li= link_to t('.downloads.json'), url_for(:format => :json) 5 | -------------------------------------------------------------------------------- /app/views/venues/_filters.html.haml: -------------------------------------------------------------------------------- 1 | = render 'filters/type', :types => @types, :selected => @selected_types 2 | -------------------------------------------------------------------------------- /app/views/venues/_item.html.haml: -------------------------------------------------------------------------------- 1 | :ruby 2 | venue ||= raise ArgumentError, "venue is required in view partial #{__FILE__}" 3 | 4 | - cache venue do 5 | .venue-item 6 | .venue{:class => (venue.closed? ? 'closed' : '')} 7 | .venue-title= venue.title 8 | 9 | %h2.venue-location-title= t('.location.title') 10 | .venue-location{:class => (venue.location ? 'has-location' : '')} 11 | = render 'venues/card', :venue => venue 12 | 13 | - if venue.access_notes? 14 | .venue-access-notes-container 15 | %h3.venue-access-notes-title= t('.access_notes.title') 16 | .venue-access-notes= venue.access_notes.presence 17 | 18 | - if venue.url? 19 | %h2.venue-url-title= t('.url.title') 20 | .venue-url= link_to venue.url, venue.url, :target => '_blank' 21 | 22 | %h2.venue-description-title= t('.description.title') 23 | .venue-description{:class => (venue.description? ? '' : 'no-content')} 24 | = venue.description.presence || t('.description.none') 25 | 26 | :javascript 27 | $('.event-description a').attr('target', '_blank'); 28 | -------------------------------------------------------------------------------- /app/views/venues/_subnav.html.erb: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /app/views/venues/edit.html.haml: -------------------------------------------------------------------------------- 1 | - if params[:preview] && @venue.valid? 2 | %h2.preview-title Preview 3 | .venue-preview.venues-show= render 'venues/item', :venue => @venue 4 | .preview-separator 5 | 6 | %h2.main-title= t('.title') 7 | 8 | #main-content 9 | .appropriateness= t('venues.appropriateness') 10 | = render 'form', :venue => @venue 11 | -------------------------------------------------------------------------------- /app/views/venues/index.kml.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <% for venue in @venues -%> 5 | <% next if venue.latitude.nil? -%> 6 | 7 | <%= escape_once(venue.title) %> 8 | <%= cdata_section(venue.description) %> 9 | 10 | <%= venue.longitude %>,<%= venue.latitude %> 11 | 12 | 13 | <% end -%> 14 | 15 | -------------------------------------------------------------------------------- /app/views/venues/map.html.erb: -------------------------------------------------------------------------------- 1 |

Big Map of Venues

2 |
3 | <%= map @venues, @current_site.venues_google_map_options %> 4 |
5 | -------------------------------------------------------------------------------- /app/views/venues/new.html.haml: -------------------------------------------------------------------------------- 1 | - if params[:preview] && @venue.valid? 2 | %h2.preview-title Preview 3 | .venue-preview.venues-show= render 'venues/item', :venue => @venue 4 | .preview-separator 5 | 6 | %h2.main-title= t('.title') 7 | 8 | #main-content 9 | .appropriateness= t('venues.appropriateness') 10 | = render 'form', :venue => @venue 11 | -------------------------------------------------------------------------------- /app/views/venues/show.html.haml: -------------------------------------------------------------------------------- 1 | - content_for :sidebar do 2 | #sidebar-welcome.sidebar-box= render 'site/welcome' 3 | #sidebar-event-details.sidebar-box 4 | #sidebar-wiki-props.sidebar-box= render 'site/wiki_props', :object => @venue, :clone => false 5 | 6 | 7 | = render 'venues/item', :venue => @venue 8 | 9 | - collection_cache @future_events, [:past, @venue.cache_key] do 10 | %h2.future-events-title= t('.future_events.title') 11 | .future-events.events-list.list 12 | - if @future_events.any? 13 | = render 'events/list', :events => @future_events 14 | - else 15 | .no-events= t('.future_events.none') 16 | 17 | - collection_cache @past_events, [:future, @venue.cache_key] do 18 | %h2.past-events-title= t('.past_events.title') 19 | .past-events.events-list.list 20 | - if @past_events.any? 21 | = render 'events/list', :events => @past_events 22 | - else 23 | .no-events= t('.past_events.none') 24 | -------------------------------------------------------------------------------- /app/views/versions/_chooser.html.erb: -------------------------------------------------------------------------------- 1 | <% 2 | # USAGE: Displays a version picker for the given object. 3 | # 4 | # VARIABLES: 5 | # * record: The record to show a version picker for. 6 | # * target: The DOM id to update when refreshing the version. 7 | %> 8 | 9 | <% if record.versions.present? %> 10 |
11 |
12 | Version <%= select_tag("version", options_for_select(record.versions.reverse.map { |version| ["#{version.created_at.strftime('%B %d, %Y at %I:%M %p')}", version.id]})) %><%= image_tag "spinner.gif", :alt => "Spinner", :id => "version_loading", :style => "display: none; margin-left: 0.5em;" %> 13 |
14 |
15 | <% content_for :javascript_insert do %> 16 | 27 | <% end %> 28 | <% end %> 29 | -------------------------------------------------------------------------------- /app/views/versions/_edit_with_chooser.html.erb: -------------------------------------------------------------------------------- 1 | <% 2 | # USAGE: Renders an edit form for an ActiveRecord model. 3 | # 4 | # VARIABLES: 5 | # * record: The record to render this form for. 6 | 7 | target = "edit_#{record.class.name.underscore}_form" 8 | name = record.class.name.underscore.to_sym 9 | template = "/#{record.class.name.pluralize.underscore}/form" 10 | %> 11 | 12 | <%= render :partial => '/versions/chooser', :locals => {:record => record, :target => target} %> 13 | 14 |
15 | <%= render template, name => record %> 16 |
17 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 8 | 9 | APP_PATH = File.expand_path('../../config/application', __FILE__) 10 | require File.expand_path('../../config/boot', __FILE__) 11 | require 'rails/commands' 12 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require 'bundler/setup' 8 | load Gem.bin_path('rake', 'rake') 9 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require 'rubygems' 8 | require 'bundler' 9 | 10 | if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)) 11 | Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq.join(Gem.path_separator) } 12 | gem 'spring', match[1] 13 | require 'spring/binstub' 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /ci/copy_database_config.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | which_config = "ci/database.#{ENV['DB'] || 'sqlite'}.yml" 4 | 5 | puts "Copying database configuration for CI: #{which_config}" 6 | FileUtils.cp which_config, 'config/database~custom.yml' 7 | -------------------------------------------------------------------------------- /ci/database.mysql.yml: -------------------------------------------------------------------------------- 1 | test: 2 | adapter: mysql2 3 | database: calagator_test 4 | username: travis 5 | encoding: utf8 6 | -------------------------------------------------------------------------------- /ci/database.postgresql.yml: -------------------------------------------------------------------------------- 1 | test: 2 | adapter: postgresql 3 | database: calagator_test 4 | username: postgres 5 | -------------------------------------------------------------------------------- /ci/database.sqlite.yml: -------------------------------------------------------------------------------- 1 | test: 2 | adapter: sqlite3 3 | database: db/test.sqlite3 4 | timeout: 500 5 | 6 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Calagator::Application 5 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boot' 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Calagator 10 | class Application < Rails::Application 11 | # Settings in config/environments/* take precedence over those specified here. 12 | # Application configuration should go into files in config/initializers 13 | # -- all .rb files in that directory are automatically loaded. 14 | 15 | config.eager_load_paths += [Rails.root.join('lib')] 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /config/blacklist.txt: -------------------------------------------------------------------------------- 1 | \b(online|overseas).+(drugstore|pharmacy)\b 2 | \bAloha!\s+" 5 | password: "<%= ENV['PGPASSWORD'] %>" 6 | 7 | # Connect on a TCP socket. Omitted by default since the client uses a 8 | # domain socket that doesn't need configuration. Windows does not have 9 | # domain sockets, so uncomment these lines. 10 | host: localhost 11 | port: 5432 12 | # 13 | # Schema search path. The server defaults to $user,public 14 | #schema_search_path: myapp,sharedapp,public 15 | 16 | # Minimum log levels, in increasing order: 17 | # debug5, debug4, debug3, debug2, debug1, 18 | # log, notice, warning, error, fatal, and panic 19 | # The server defaults to notice. 20 | #min_messages: warning 21 | 22 | development: &development 23 | database: calagator_dev 24 | <<: *common 25 | 26 | test: 27 | database: calagator_test 28 | <<: *common 29 | 30 | preview: 31 | <<: *development 32 | 33 | production: 34 | database: calagator_prod 35 | <<: *common 36 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/preview.rb: -------------------------------------------------------------------------------- 1 | # Preview environment is the Production environment but using the Development database. Great for local manual testing and debugging Production-only bugs. 2 | 3 | eval File.read(Rails.root.join('config','environments','production.rb')) 4 | 5 | Rails.application.configure do 6 | config.public_file_server.enabled = true 7 | config.action_dispatch.x_sendfile_header = nil 8 | end 9 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ApplicationController.renderer.defaults.merge!( 4 | # http_host: 'example.org', 5 | # https: false 6 | # ) 7 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | 13 | Rails.application.config.assets.precompile += %w( 14 | *.gif 15 | *.jpg 16 | *.png 17 | 18 | forms.css 19 | mobile.css 20 | theme.css 21 | widget.css 22 | 23 | forms.js 24 | mobile.js 25 | theme.js 26 | widget.js 27 | 28 | jquery-ui.js 29 | ) 30 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /config/initializers/dates.rb: -------------------------------------------------------------------------------- 1 | my_formats = { 2 | :yyyymmdd => '%Y-%m-%d', 3 | :long_date => '%A, %B %d, %Y', 4 | } 5 | 6 | Time::DATE_FORMATS.merge!(my_formats) 7 | Date::DATE_FORMATS.merge!(my_formats) 8 | 9 | # Keep milliseconds from being included in JSON responses 10 | ActiveSupport::JSON::Encoding.time_precision = 0 11 | -------------------------------------------------------------------------------- /config/initializers/default_headers.rb: -------------------------------------------------------------------------------- 1 | # Default headers to include in HTTP responses 2 | Rails.application.config.action_dispatch.default_headers.delete('X-Frame-Options') 3 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/i18n.rb: -------------------------------------------------------------------------------- 1 | # Enable traversing up the locale hierarchy until we find a match, 2 | # specifically: en-x-foo-bar -> en-x-foo -> en (not translation path) 3 | Rails.application.config.i18n.fallbacks = true 4 | 5 | # Include subdirectories when searching for locales 6 | i18n_path = Rails.root.join('config', 'locales', '**', '*.{rb,yml}') 7 | Rails.application.config.i18n.load_path += Dir[i18n_path] 8 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/load_tag_model_extensions.rb: -------------------------------------------------------------------------------- 1 | require 'tag_model_extensions' 2 | 3 | ActsAsTaggableOn::Tag.send(:include, TagModelExtensions) 4 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | 6 | Mime::Type.register "application/vnd.google-earth.kml+xml", :kml 7 | Mime::Type.register "application/sqlite3", :sqlite3 8 | Mime::Type.register "application/data", :data 9 | -------------------------------------------------------------------------------- /config/initializers/new_framework_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains migration options to ease your Rails 5.0 upgrade. 4 | # 5 | # Read the Rails 5.0 release notes for more info on each option. 6 | 7 | # Enable per-form CSRF tokens. Previous versions had false. 8 | Rails.application.config.action_controller.per_form_csrf_tokens = true 9 | 10 | # Enable origin-checking CSRF mitigation. Previous versions had false. 11 | Rails.application.config.action_controller.forgery_protection_origin_check = true 12 | 13 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. 14 | # Previous versions had false. 15 | ActiveSupport.to_time_preserves_timezone = true 16 | 17 | # Require `belongs_to` associations by default. Previous versions had false. 18 | Rails.application.config.active_record.belongs_to_required_by_default = true 19 | 20 | # Do not halt callback chains when a callback returns false. Previous versions had true. 21 | ActiveSupport.halt_callback_chains_on_return_false = false 22 | 23 | # Configure SSL options to enable HSTS with subdomains. Previous versions had false. 24 | Rails.application.config.ssl_options = { hsts: { subdomains: true } } 25 | -------------------------------------------------------------------------------- /config/initializers/new_rails_defaults.rb: -------------------------------------------------------------------------------- 1 | # These settings change the behavior of Rails 2 apps and will be defaults 2 | # for Rails 3. You can remove this initializer when Rails 3 is released. 3 | 4 | if defined?(ActiveRecord) 5 | # Include Active Record class name as root for JSON serialized output. 6 | ActiveRecord::Base.include_root_in_json = false 7 | 8 | # Store the full class name (including module namespace) in STI type column. 9 | ActiveRecord::Base.store_full_sti_class = true 10 | end 11 | 12 | # Use ISO 8601 format for JSON serialized times and dates. 13 | ActiveSupport.use_standard_json_time_format = true 14 | 15 | # Don't escape HTML entities in JSON, leave that for the #json_escape helper. 16 | # if you're including raw json in an HTML page. 17 | ActiveSupport.escape_html_entities_in_json = false 18 | -------------------------------------------------------------------------------- /config/initializers/paper_trail.rb: -------------------------------------------------------------------------------- 1 | PaperTrailManager.version_model = '::Version' 2 | 3 | PaperTrailManager.whodunnit_class = User 4 | PaperTrailManager.whodunnit_name_method = :email 5 | PaperTrailManager.user_path_method = nil # Suppress link to user profile page 6 | 7 | PaperTrailManager.allow_index_when do |controller, version| 8 | controller.current_user and controller.current_user.admin? 9 | end 10 | 11 | PaperTrail.config.track_associations = false 12 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_activate_session', expire_after: 1.week 4 | -------------------------------------------------------------------------------- /config/initializers/timezone.rb: -------------------------------------------------------------------------------- 1 | # When an ambiguous time is encountered, treat time as non daylight-savings. 2 | # 3 | # This works around some code in RiCal that converts UTC dates to local time 4 | # in order to find the UTC offset of a date. This is normally not a problem 5 | # as events don't start or end durinng an ambiguous window (i.e. 1-2am when 6 | # a daylight savings transition takes place). Background workers that create 7 | # events can run during this time window, and the created_at or updated_at 8 | # timestamps are also have this calculation applied. 9 | TZInfo::Timezone.default_dst = false 10 | 11 | # A more accurate solution would be to check if the offset results in a time 12 | # that matches the original UTC time or using an activesupport way of 13 | # calculating the time offset; implementing this solution, however, would 14 | # require monkey-patching private/un-documented code in the ri_cal gem. 15 | # 16 | # The code in the ri_cal gem that causes an issue is in 17 | # lib/ri_cal/component/calendar.rb:142-144: 18 | # 19 | # def rational_utc_offset(local) 20 | # RiCal.RationalOffset[tzinfo.period_for_local(local, true).utc_total_offset] 21 | # end 22 | # 23 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/locales/README: -------------------------------------------------------------------------------- 1 | # The "-x-foo-bar" at the end of some locales are "private use subtags"; 2 | # they are part of the official BCP 47 ("Tags for Identifying Languages") 3 | # and RFC 4647 ("Matching of Language Tags") specifications for naming 4 | # and matching locales, see the following relevant sections for more info: 5 | # 6 | # BCP 47 - 2.2.7. Private Use Subtags 7 | # http://tools.ietf.org/html/bcp47#section-2.2.7 8 | # 9 | # BCP 47 - 4.6. Considerations for Private Use Subtags 10 | # http://tools.ietf.org/html/bcp47#section-4.6 11 | # 12 | # RFC 4647 - 3.4. Lookup 13 | # http://tools.ietf.org/html/rfc4647#section-3.4 14 | # 15 | # Private use subtags allow us to define a default set of translations for 16 | # a language (ie. "en"), override or complement them on a per-theme basis 17 | # and then further override them on a per-site basis. 18 | # 19 | # **IMPORTANT:** the maximum length of each private use subtag cannot 20 | # exceed eight characters and must contain only letters and numbers 21 | # (see: http://tools.ietf.org/html/bcp47#section-2.1). While the i18n gem 22 | # does not enforce this by default, you should try to follow this 23 | # convention and remain within the specification. 24 | -------------------------------------------------------------------------------- /config/locales/activate/en-x-activate-arts.yml: -------------------------------------------------------------------------------- 1 | en-x-activate-arts: 2 | 3 | -------------------------------------------------------------------------------- /config/locales/activate/en-x-activate-hub-detroit.yml: -------------------------------------------------------------------------------- 1 | en-x-activate-hub-detroit: 2 | events: 3 | index: 4 | title: "Activate! 313 Progressive Community Calendar" 5 | -------------------------------------------------------------------------------- /config/locales/activate/en-x-activate-hub.yml: -------------------------------------------------------------------------------- 1 | en-x-activate-hub: 2 | site: 3 | welcome: 4 | title: "Change Your Calendar,\nChange Your World" 5 | text: > 6 | Search for events and organizations in your community. Get educated, 7 | get involved, and start making a difference! 8 |
9 | 10 | 11 | 12 |
13 | events: 14 | index: 15 | title: "Your Community is Calling" 16 | -------------------------------------------------------------------------------- /config/locales/activate/en-x-activate-oakmaker.yml: -------------------------------------------------------------------------------- 1 | en-x-activate-oakmaker: 2 | assets: 3 | og_logo: "og-oaklandmakers.png" # "open graph (ogp.me) image, needed for facebook sharing 4 | 5 | site: 6 | navbar: 7 | logo_link: "http://oaklandmakers.org/" 8 | logo_src: "oaklandmakers-logo.png" 9 | 10 | footer: > 11 | Powered by Activate! Hub 12 | 13 | events: 14 | index: 15 | title: "You are here. Go somewhere!" 16 | -------------------------------------------------------------------------------- /config/locales/activate/en-x-activate.yml: -------------------------------------------------------------------------------- 1 | en-x-activate: 2 | assets: 3 | og_logo: "og-image.png" # "open graph (ogp.me) image, needed for facebook sharing 4 | 5 | site: 6 | navbar: 7 | logo_link: "http://activatehub.org/" 8 | logo_src: "navbar-logo.png" 9 | 10 | welcome: 11 | title: "Your Community is Calling" 12 | text: "Search for events and organizations in your community." 13 | footer: > 14 | © 2011-2013 Social Action Network LLC 15 | Branding by Alicia Nagel Creative, LLC 16 | 17 | events: 18 | index: 19 | title: "You are here. Go somewhere!" 20 | -------------------------------------------------------------------------------- /config/locales/en.formats.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml 2 | 3 | en: 4 | date: 5 | formats: 6 | # Use the strftime parameters for formats. 7 | # When no format has been given, it uses default. 8 | # You can provide other formats here if you like! 9 | default: "%Y-%m-%d" 10 | short: "%b %d" 11 | long: "%B %d, %Y" 12 | 13 | day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday] 14 | abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat] 15 | 16 | # Don't forget the nil at the beginning; there's no such thing as a 0th month 17 | month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December] 18 | abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec] 19 | # Used in date_select and datetime_select. 20 | order: 21 | - :year 22 | - :month 23 | - :day 24 | 25 | time: 26 | formats: 27 | default: "%a, %d %b %Y %H:%M:%S %z" 28 | short: "%d %b %H:%M" 29 | long: "%B %d, %Y %H:%M" 30 | am: "am" 31 | pm: "pm" 32 | 33 | # Used in array.to_sentence. 34 | support: 35 | array: 36 | words_connector: ", " 37 | two_words_connector: " and " 38 | last_word_connector: ", and " 39 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rails secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: &development 14 | secret_key_base: "ec3dbc2851fab74304d9b7b1af37cb8e2e403cb76a3c99c16ca16f53141258ab8168729d7a217c84d68cd219d6cee976af5457e38c41f260d1dcd372d0ccdcf3" 15 | google_api_key: <%= ENV["GOOGLE_API_KEY"].presence %> 16 | meetup_api_key: <%= ENV["MEETUP_API_KEY"].presence %> 17 | 18 | test: 19 | secret_key_base: "08baa26c5ee015110778cc9863fce2c87cd9a5187ef047a3743e33190d875555d33d350f57edf30972908d14364c5b311e374a4ec75a701427dcf11d433135f9" 20 | google_api_key: ~ 21 | meetup_api_key: "foo" 22 | 23 | preview: 24 | <<: *development 25 | 26 | # Do not keep production secrets in the repository, 27 | # instead read values from the environment. 28 | production: 29 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 30 | google_api_key: <%= ENV["GOOGLE_API_KEY"] %> 31 | meetup_api_key: <%= ENV["MEETUP_API_KEY"] %> 32 | -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | %w( 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ).each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /config/sunspot~sample.yml: -------------------------------------------------------------------------------- 1 | common: &common 2 | pid_dir: "tmp/pids" 3 | 4 | production: 5 | solr: 6 | hostname: localhost 7 | port: 8983 8 | log_level: WARNING 9 | << : *common 10 | 11 | development: 12 | solr: 13 | hostname: localhost 14 | port: 8982 15 | log_level: INFO 16 | << : *common 17 | 18 | test: 19 | solr: 20 | hostname: localhost 21 | port: 8981 22 | log_level: WARNING 23 | << : *common 24 | -------------------------------------------------------------------------------- /db/migrate/001_create_events.rb: -------------------------------------------------------------------------------- 1 | class CreateEvents < ActiveRecord::Migration 2 | def self.up 3 | create_table :events do |t| 4 | t.string :title 5 | t.text :description 6 | t.timestamp :start_time 7 | t.integer :venue_id 8 | t.string :url 9 | 10 | t.timestamps 11 | end 12 | end 13 | 14 | def self.down 15 | drop_table :events 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /db/migrate/002_create_venues.rb: -------------------------------------------------------------------------------- 1 | class CreateVenues < ActiveRecord::Migration 2 | def self.up 3 | create_table :venues do |t| 4 | t.string :title 5 | t.text :description 6 | t.string :address 7 | t.string :url 8 | 9 | t.timestamps 10 | end 11 | 12 | end 13 | 14 | def self.down 15 | drop_table :venues 16 | 17 | remove_column :events, :venue_id 18 | add_column :events, :location 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /db/migrate/003_create_sources.rb: -------------------------------------------------------------------------------- 1 | class CreateSources < ActiveRecord::Migration 2 | def self.up 3 | create_table :sources do |t| 4 | t.string :title 5 | t.string :url 6 | t.string :format_type 7 | t.timestamp :imported_at 8 | 9 | t.timestamps 10 | end 11 | end 12 | 13 | def self.down 14 | drop_table :sources 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /db/migrate/004_add_detailed_fields_to_venue.rb: -------------------------------------------------------------------------------- 1 | class AddDetailedFieldsToVenue < ActiveRecord::Migration 2 | def self.up 3 | add_column :venues, :street_address, :string 4 | add_column :venues, :locality, :string 5 | add_column :venues, :region, :string 6 | add_column :venues, :postal_code, :string 7 | add_column :venues, :country, :string 8 | 9 | add_column :venues, :latitude, :float 10 | add_column :venues, :longitude, :float 11 | 12 | add_column :venues, :email, :string 13 | add_column :venues, :telephone, :string 14 | end 15 | 16 | def self.down 17 | for field in %w(street_address locality region postal_code country latitude longitude email telephone) 18 | remove_column :venues, field 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /db/migrate/005_add_end_time_to_events.rb: -------------------------------------------------------------------------------- 1 | class AddEndTimeToEvents < ActiveRecord::Migration 2 | def self.up 3 | add_column :events, :end_time, :timestamp 4 | end 5 | 6 | def self.down 7 | remove_column :events, :end_time 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/006_add_source_id_to_events.rb: -------------------------------------------------------------------------------- 1 | class AddSourceIdToEvents < ActiveRecord::Migration 2 | def self.up 3 | add_column :events, :source_id, :integer 4 | end 5 | 6 | def self.down 7 | remove_column :events, :source_id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/008_add_source_id_to_venues.rb: -------------------------------------------------------------------------------- 1 | class AddSourceIdToVenues < ActiveRecord::Migration 2 | def self.up 3 | add_column :venues, :source_id, :integer 4 | end 5 | 6 | def self.down 7 | remove_column :venues, :source_id 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /db/migrate/009_add_duplicate_of_column_to_venues.rb: -------------------------------------------------------------------------------- 1 | class AddDuplicateOfColumnToVenues < ActiveRecord::Migration 2 | def self.up 3 | add_column :venues, :duplicate_of_id, :integer 4 | end 5 | 6 | def self.down 7 | remove_column :venues, :duplicate_of_id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/010_add_duplicate_of_column_to_events.rb: -------------------------------------------------------------------------------- 1 | class AddDuplicateOfColumnToEvents < ActiveRecord::Migration 2 | def self.up 3 | add_column :events, :duplicate_of_id, :integer 4 | end 5 | 6 | def self.down 7 | remove_column :events, :duplicate_of_id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/011_change_lat_long_type.rb: -------------------------------------------------------------------------------- 1 | class ChangeLatLongType < ActiveRecord::Migration 2 | def self.up 3 | # :decimal is more precise than :float, and we need that for lat/long. 4 | change_column :venues, :latitude, :decimal, :precision => 15, :scale => 10 5 | change_column :venues, :longitude, :decimal, :precision => 15, :scale => 10 6 | end 7 | 8 | def self.down 9 | change_column :venues, :latitude, :float 10 | change_column :venues, :longitude, :float 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/012_add_source_reimport.rb: -------------------------------------------------------------------------------- 1 | class AddSourceReimport < ActiveRecord::Migration 2 | def self.up 3 | add_column :sources, :reimport, :boolean 4 | end 5 | 6 | def self.down 7 | remove_column :sources, :reimport 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/013_change_end_time_to_duration.rb: -------------------------------------------------------------------------------- 1 | class ChangeEndTimeToDuration < ActiveRecord::Migration 2 | def self.up 3 | add_column :events, :duration, :integer 4 | 5 | # convert events that have an end time 6 | events = Event.where("end_time IS NOT NULL") 7 | for event in events 8 | raise "Events ends before it starts" if (event.read_attribute(:end_time) < event.start_time) 9 | event.duration = ((event.read_attribute(:end_time) - event.start_time) / 60).ceil 10 | event.save! 11 | puts "#{event.title}, Duration => #{event.duration}" 12 | end 13 | 14 | remove_column :events, :end_time 15 | end 16 | 17 | def self.down 18 | add_column :events, :end_time, :datetime 19 | 20 | # convert events that have a duration 21 | events = Event.where("duration IS NOT NULL") 22 | for event in events 23 | event.set_attribute(:end_time, event.start_time + (event.duration * 60)) 24 | event.save! 25 | end 26 | 27 | remove_column :events, :duration 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /db/migrate/014_remove_format_type_from_source.rb: -------------------------------------------------------------------------------- 1 | class RemoveFormatTypeFromSource < ActiveRecord::Migration 2 | def self.up 3 | remove_column :sources, :format_type 4 | end 5 | 6 | def self.down 7 | add_column :sources, :format_type, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/015_create_updates.rb: -------------------------------------------------------------------------------- 1 | class CreateUpdates < ActiveRecord::Migration 2 | def self.up 3 | create_table :updates do |t| 4 | t.integer "source_id" 5 | t.text "status" 6 | t.timestamps 7 | end 8 | add_column :sources, :next_update, :datetime 9 | end 10 | 11 | def self.down 12 | remove_column :sources, :next_update 13 | drop_table :updates 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/016_remove_next_update_from_source.rb: -------------------------------------------------------------------------------- 1 | class RemoveNextUpdateFromSource < ActiveRecord::Migration 2 | def self.up 3 | remove_column :sources, :next_update 4 | end 5 | 6 | def self.down 7 | add_column :sources, :next_update, :datetime 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20080604210521_convert_times_to_utc.rb: -------------------------------------------------------------------------------- 1 | class ConvertTimesToUtc < ActiveRecord::Migration 2 | def self.up 3 | Event.find(:all).each do |e| 4 | e.start_time = Time.parse(e.start_time_before_type_cast) 5 | e.save 6 | end 7 | end 8 | 9 | def self.down 10 | raise ActiveRecord::IrreversibleMigration, "Cannot migrate down." 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20080705164959_create_tags_and_taggings.rb: -------------------------------------------------------------------------------- 1 | 2 | # A migration to add tables for Tag and Tagging. This file is automatically generated and added to your app if you run the tagging generator included with has_many_polymorphs. 3 | 4 | class CreateTagsAndTaggings < ActiveRecord::Migration 5 | 6 | # Add the new tables. 7 | def self.up 8 | create_table :tags do |t| 9 | t.column :name, :string, :null => false 10 | end 11 | add_index :tags, :name, :unique => true 12 | 13 | create_table :taggings do |t| 14 | t.column :tag_id, :integer, :null => false 15 | t.column :taggable_id, :integer, :null => false 16 | t.column :taggable_type, :string, :null => false 17 | # t.column :position, :integer # Uncomment this if you need to use acts_as_list. 18 | end 19 | add_index :taggings, [:tag_id, :taggable_id, :taggable_type], :unique => true 20 | end 21 | 22 | # Remove the tables. 23 | def self.down 24 | drop_table :tags 25 | drop_table :taggings 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /db/migrate/20081011181519_create_versioned_events.rb: -------------------------------------------------------------------------------- 1 | class CreateVersionedEvents < ActiveRecord::Migration 2 | # NOTE: This migration's contents have been commented-out because they relied 3 | # on the old +acts_as_versioned+ plugin that has since replaced with the 4 | # +papertrail+ plugin. 5 | 6 | def self.up 7 | ### Event.create_versioned_table do |t| 8 | ### t.string "title" 9 | ### t.text "description" 10 | ### t.datetime "start_time" 11 | ### t.string "url" 12 | ### t.datetime "created_at" 13 | ### t.datetime "updated_at" 14 | ### t.integer "venue_id" 15 | ### t.integer "source_id" 16 | ### t.integer "duplicate_of_id" 17 | ### t.datetime "end_time" 18 | ### t.integer "version" 19 | ### end 20 | end 21 | 22 | def self.down 23 | ### Event.drop_versioned_table 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /db/migrate/20081011193124_create_versioned_venues.rb: -------------------------------------------------------------------------------- 1 | class CreateVersionedVenues < ActiveRecord::Migration 2 | # NOTE: This migration's contents have been commented-out because they relied 3 | # on the old +acts_as_versioned+ plugin that we've since replaced with the 4 | # +papertrail+ plugin. 5 | # 6 | def self.up 7 | ### Venue.create_versioned_table do |t| 8 | ### t.string "title" 9 | ### t.text "description" 10 | ### t.string "address" 11 | ### t.string "url" 12 | ### t.datetime "created_at" 13 | ### t.datetime "updated_at" 14 | ### t.string "street_address" 15 | ### t.string "locality" 16 | ### t.string "region" 17 | ### t.string "postal_code" 18 | ### t.string "country" 19 | ### t.decimal "latitude" 20 | ### t.decimal "longitude" 21 | ### t.string "email" 22 | ### t.string "telephone" 23 | ### t.integer "source_id" 24 | ### t.integer "duplicate_of_id" 25 | ### t.integer "version" 26 | ### end 27 | end 28 | 29 | def self.down 30 | ### Venue.drop_versioned_table 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /db/migrate/20081115190515_add_rrule_to_events.rb: -------------------------------------------------------------------------------- 1 | class AddRruleToEvents < ActiveRecord::Migration 2 | # NOTE: Some of this migration's contents have been commented-out because 3 | # they used tables created for the old +acts_as_versioned+ plugin that has 4 | # since replaced with the +papertrail+ plugin. 5 | 6 | def self.up 7 | add_column :events, :rrule, :string 8 | ### add_column :event_versions, :rrule, :string 9 | end 10 | 11 | def self.down 12 | remove_column :events, :rrule 13 | ### remove_column :event_versions, :rrule 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20090912082129_create_versions.rb: -------------------------------------------------------------------------------- 1 | class CreateVersions < ActiveRecord::Migration 2 | def self.up 3 | create_table :versions do |t| 4 | t.string :item_type, :null => false 5 | t.integer :item_id, :null => false 6 | t.string :event, :null => false 7 | t.string :whodunnit 8 | t.text :object 9 | t.datetime :created_at 10 | end 11 | add_index :versions, [:item_type, :item_id] 12 | end 13 | 14 | def self.down 15 | remove_index :versions, [:item_type, :item_id] 16 | drop_table :versions 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /db/migrate/20110219205156_add_closed_flag_to_venues.rb: -------------------------------------------------------------------------------- 1 | class AddClosedFlagToVenues < ActiveRecord::Migration 2 | def self.up 3 | add_column :venues, :closed, :boolean, :default => false 4 | end 5 | 6 | def self.down 7 | remove_column :venues, :closed 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20110220001008_add_wifi_flag_to_venues.rb: -------------------------------------------------------------------------------- 1 | class AddWifiFlagToVenues < ActiveRecord::Migration 2 | def self.up 3 | add_column :venues, :wifi, :boolean, :default => false 4 | end 5 | 6 | def self.down 7 | remove_column :venues, :wifi 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20110220011427_add_access_notes_to_venues.rb: -------------------------------------------------------------------------------- 1 | class AddAccessNotesToVenues < ActiveRecord::Migration 2 | def self.up 3 | add_column :venues, :access_notes, :text 4 | end 5 | 6 | def self.down 7 | remove_column :venues, :access_notes 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20110220031117_add_events_count_to_venues.rb: -------------------------------------------------------------------------------- 1 | class AddEventsCountToVenues < ActiveRecord::Migration 2 | def self.up 3 | add_column :venues, :events_count, :integer 4 | 5 | Venue.reset_column_information 6 | Venue.all.each do |p| 7 | Venue.update_counters p.id, :events_count => p.events.length 8 | end 9 | end 10 | 11 | def self.down 12 | remove_column :venues, :events_count 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20110604174521_add_venue_details_to_events.rb: -------------------------------------------------------------------------------- 1 | class AddVenueDetailsToEvents < ActiveRecord::Migration 2 | def self.up 3 | add_column :events, :venue_details, :text 4 | end 5 | 6 | def self.down 7 | remove_column :events, :venue_details 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20111109034553_create_organizations.rb: -------------------------------------------------------------------------------- 1 | class CreateOrganizations < ActiveRecord::Migration 2 | def self.up 3 | create_table :organizations do |t| 4 | t.primary_key :id 5 | t.string :name 6 | t.string :url 7 | t.datetime :created_at 8 | t.datetime :updated_at 9 | 10 | t.timestamps 11 | end 12 | end 13 | 14 | def self.down 15 | drop_table :organizations 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /db/migrate/20111110144520_add_organization_id_to_events.rb: -------------------------------------------------------------------------------- 1 | class AddOrganizationIdToEvents < ActiveRecord::Migration 2 | def self.up 3 | add_column :events, :organization_id, :integer 4 | end 5 | 6 | def self.down 7 | remove_column :events, :organization_id 8 | end 9 | end -------------------------------------------------------------------------------- /db/migrate/20111213021451_create_types.rb: -------------------------------------------------------------------------------- 1 | class CreateTypes < ActiveRecord::Migration 2 | def self.up 3 | create_table :types do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | 9 | # Create join tables necessary for many-many relation. 10 | # See http://guides.rubyonrails.org/association_basics.html#creating-join-tables-for-has_and_belongs_to_many-associations 11 | 12 | create_table :events_types, :id => false do |t| 13 | t.references :event 14 | t.references :type 15 | end 16 | 17 | create_table :sources_types, :id => false do |t| 18 | t.references :source 19 | t.references :type 20 | end 21 | 22 | end 23 | 24 | def self.down 25 | drop_table :types 26 | drop_table :events_types 27 | drop_table :sources_types 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /db/migrate/20111213023932_add_organization_id_to_sources.rb: -------------------------------------------------------------------------------- 1 | class AddOrganizationIdToSources < ActiveRecord::Migration 2 | def self.up 3 | add_column :sources, :organization_id, :integer 4 | end 5 | 6 | def self.down 7 | remove_column :sources, :organization_id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20111224014835_create_topics.rb: -------------------------------------------------------------------------------- 1 | class CreateTopics < ActiveRecord::Migration 2 | def self.up 3 | create_table :topics do |t| 4 | t.string :name 5 | t.timestamps 6 | end 7 | 8 | # Create join tables necessary for many-many relation. 9 | # See http://guides.rubyonrails.org/association_basics.html#creating-join-tables-for-has_and_belongs_to_many-associations 10 | 11 | create_table :events_topics, :id => false do |t| 12 | t.references :event 13 | t.references :topic 14 | end 15 | 16 | create_table :organizations_topics, :id => false do |t| 17 | t.references :organization 18 | t.references :topic 19 | end 20 | end 21 | 22 | def self.down 23 | drop_table :topics 24 | drop_table :events_topics 25 | drop_table :organizations_topics 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /db/migrate/20120709092821_cleanup.rb: -------------------------------------------------------------------------------- 1 | class Cleanup < ActiveRecord::Migration 2 | # Remove obsolete tables and columns that may have been left behind by other migrations. 3 | def self.up 4 | if ActiveRecord::Base.connection.columns('venues').map(&:name).include?("version") 5 | remove_column :venues, :version 6 | end 7 | 8 | %w[event_versions venue_versions].each do |table| 9 | if ActiveRecord::Base.connection.tables.include?(table) 10 | drop_table table 11 | end 12 | end 13 | end 14 | 15 | def self.down 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /db/migrate/20120831234448_specify_venues_latitude_and_longitude_precision.rb: -------------------------------------------------------------------------------- 1 | class SpecifyVenuesLatitudeAndLongitudePrecision < ActiveRecord::Migration 2 | FIELDS = %w[latitude longitude].map(&:to_sym) 3 | 4 | def up 5 | for field in FIELDS 6 | change_column :venues, field, :decimal, :precision => 7, :scale => 4 7 | end 8 | end 9 | 10 | def down 11 | for field in FIELDS 12 | change_column :venues, field, :decimal 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20130506062649_create_sites.rb: -------------------------------------------------------------------------------- 1 | class CreateSites < ActiveRecord::Migration 2 | def self.up 3 | create_table :sites do |t| 4 | t.string :name 5 | t.string :domain 6 | 7 | t.timestamps 8 | end 9 | end 10 | 11 | def self.down 12 | drop_table :sites 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20130506063000_add_site_id_to_models.rb: -------------------------------------------------------------------------------- 1 | class AddSiteIdToModels < ActiveRecord::Migration 2 | class Site < ActiveRecord::Base ; end 3 | 4 | def self.tables 5 | [:events, :organizations, :sources, :topics, :types, :venues] 6 | end 7 | 8 | def self.up 9 | default_site = Site.find_or_create_by(id: 1) 10 | if !default_site.domain 11 | default_site.domain = "localhost" 12 | default_site.name = "localhost" 13 | default_site.save 14 | end 15 | 16 | tables.each do |table| 17 | add_column table, :site_id, :integer 18 | 19 | model = table.to_s.classify.constantize 20 | model.reset_column_information 21 | 22 | model.update_all "site_id = 1", "site_id IS NULL" 23 | end 24 | end 25 | 26 | def self.down 27 | tables.each do |table| 28 | remove_column table, :site_id 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /db/migrate/20130601190557_add_contact_to_organizations.rb: -------------------------------------------------------------------------------- 1 | class AddContactToOrganizations < ActiveRecord::Migration 2 | def change 3 | add_column :organizations, :contact_name, :string 4 | add_column :organizations, :email, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20130601201436_remove_users_and_rails_admin_table.rb: -------------------------------------------------------------------------------- 1 | class RemoveUsersAndRailsAdminTable < ActiveRecord::Migration 2 | def up 3 | if ActiveRecord::Base.connection.table_exists? 'users' 4 | drop_table 'users' 5 | end 6 | if ActiveRecord::Base.connection.table_exists? 'rails_admin_histories' 7 | drop_table 'rails_admin_histories' 8 | end 9 | end 10 | 11 | def down 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20130601225529_devise_create_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateUsers < ActiveRecord::Migration 2 | def change 3 | create_table(:users) do |t| 4 | t.database_authenticatable :null => false 5 | t.recoverable 6 | t.rememberable 7 | t.trackable 8 | 9 | # t.encryptable 10 | # t.confirmable 11 | # t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both 12 | # t.token_authenticatable 13 | 14 | 15 | t.timestamps 16 | end 17 | 18 | add_index :users, :email, :unique => true 19 | add_index :users, :reset_password_token, :unique => true 20 | # add_index :users, :confirmation_token, :unique => true 21 | # add_index :users, :unlock_token, :unique => true 22 | # add_index :users, :authentication_token, :unique => true 23 | end 24 | 25 | end 26 | -------------------------------------------------------------------------------- /db/migrate/20130601225531_create_rails_admin_histories_table.rb: -------------------------------------------------------------------------------- 1 | class CreateRailsAdminHistoriesTable < ActiveRecord::Migration 2 | def self.up 3 | create_table :rails_admin_histories do |t| 4 | t.text :message # title, name, or object_id 5 | t.string :username 6 | t.integer :item 7 | t.string :table 8 | t.integer :month, :limit => 2 9 | t.integer :year, :limit => 5 10 | t.timestamps 11 | end 12 | add_index(:rails_admin_histories, [:item, :table, :month, :year], :name => 'index_rails_admin_histories' ) 13 | end 14 | 15 | def self.down 16 | drop_table :rails_admin_histories 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /db/migrate/20130630184240_add_description_to_organization.rb: -------------------------------------------------------------------------------- 1 | class AddDescriptionToOrganization < ActiveRecord::Migration 2 | def up 3 | add_column :organizations, :description, :string 4 | end 5 | 6 | def down 7 | remove_column :organizations, :description 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130707033958_add_settings_to_sites.rb: -------------------------------------------------------------------------------- 1 | class AddSettingsToSites < ActiveRecord::Migration 2 | def change 3 | add_column :sites, :tagline, :string 4 | add_column :sites, :timezone, :string 5 | add_column :sites, :map_latitude, :float 6 | add_column :sites, :map_longitude, :float 7 | add_column :sites, :map_zoom, :integer 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130707094725_add_non_affiliated_event_org.rb: -------------------------------------------------------------------------------- 1 | class AddNonAffiliatedEventOrg < ActiveRecord::Migration 2 | class Organization < ActiveRecord::Base 3 | self.table_name = 'organizations' 4 | end 5 | 6 | class Site < ActiveRecord::Base 7 | self.table_name = 'sites' 8 | end 9 | 10 | def up 11 | Site.pluck(:id).each do |site_id| 12 | Organization.create!(:name => 'A Non-Affiliated Event', :site_id => site_id) 13 | end 14 | end 15 | 16 | def down 17 | Site.pluck(:id).each do |site_id| 18 | Organization.where(:name => 'A Non-Affiliated Event').each(&:destroy) 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /db/migrate/20130707104341_add_topics_to_source.rb: -------------------------------------------------------------------------------- 1 | class AddTopicsToSource < ActiveRecord::Migration 2 | def up 3 | create_table :sources_topics, :id => false do |t| 4 | t.references :source 5 | t.references :topic 6 | end 7 | 8 | add_index :sources_topics, :source_id 9 | add_index :sources_topics, :topic_id 10 | 11 | Source.reset_column_information 12 | Source.all.each do |source| 13 | next unless source.organization 14 | 15 | source.topic_ids = source.organization.topic_ids 16 | source.save! 17 | end 18 | end 19 | 20 | def down 21 | drop_table :sources_topics, :id => false do |t| 22 | t.references :source 23 | t.references :topic 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /db/migrate/20130712205256_add_path_prefix_to_sites.rb: -------------------------------------------------------------------------------- 1 | class AddPathPrefixToSites < ActiveRecord::Migration 2 | def change 3 | add_column :sites, :path_prefix, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130720021739_add_enabled_to_sources.rb: -------------------------------------------------------------------------------- 1 | class AddEnabledToSources < ActiveRecord::Migration 2 | def change 3 | add_column :sources, :enabled, :boolean, :default => true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130818060649_create_abstract_locations.rb: -------------------------------------------------------------------------------- 1 | class CreateAbstractLocations < ActiveRecord::Migration 2 | def change 3 | create_table :abstract_locations do |t| 4 | t.references :site 5 | t.references :source 6 | t.references :venue 7 | 8 | t.string :external_id 9 | t.string :url 10 | t.string :title 11 | t.text :description 12 | 13 | t.string :address 14 | t.string :street_address 15 | t.string :locality 16 | t.string :region 17 | t.string :postal_code 18 | t.string :country 19 | 20 | t.decimal :latitude, :precision => 7, :scale => 4 21 | t.decimal :longitude, :precision => 7, :scale => 4 22 | 23 | t.string :email 24 | t.string :telephone 25 | t.text :tags 26 | 27 | t.string :result 28 | t.text :error_msg 29 | t.text :raw_venue 30 | 31 | t.timestamps 32 | end 33 | 34 | add_index :abstract_locations, [:site_id, :source_id, :external_id], :name => 'index_abstract_locations_by_external_id' 35 | add_index :abstract_locations, :venue_id 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /db/migrate/20130818074448_create_abstract_events.rb: -------------------------------------------------------------------------------- 1 | class CreateAbstractEvents < ActiveRecord::Migration 2 | def change 3 | create_table :abstract_events do |t| 4 | t.references :site 5 | t.references :source 6 | t.references :event 7 | 8 | t.string :external_id 9 | t.string :url 10 | t.string :title 11 | t.datetime :start_time 12 | t.datetime :end_time 13 | t.text :description 14 | 15 | t.string :venue_title 16 | t.references :abstract_location 17 | 18 | t.text :tags 19 | 20 | t.string :result 21 | t.text :error_msg 22 | t.text :raw_event 23 | 24 | t.timestamps 25 | end 26 | 27 | add_index :abstract_events, [:site_id, :source_id, :start_time], :name => 'abstract_events_by_start_time' 28 | add_index :abstract_events, [:site_id, :source_id, :external_id], :name => 'abstract_events_by_external_id' 29 | add_index :abstract_events, :event_id 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /db/migrate/20130910081243_add_locale_to_sites.rb: -------------------------------------------------------------------------------- 1 | class AddLocaleToSites < ActiveRecord::Migration 2 | def up 3 | add_column :sites, :locale, :string 4 | 5 | ActiveRecord::Base.connection.execute <<-SQL 6 | UPDATE sites SET locale = 'en-x-activate-hub'; 7 | SQL 8 | end 9 | 10 | def down 11 | remove_column :sites, :locale 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20130910114730_remove_path_prefix_from_sites.rb: -------------------------------------------------------------------------------- 1 | class RemovePathPrefixFromSites < ActiveRecord::Migration 2 | class Site < ActiveRecord::Base 3 | self.table_name = 'sites' 4 | end 5 | 6 | def up 7 | # this doesn't allow sub-calendars to still work, it's just so we can 8 | # identify the calendars later to change their domains to something else, 9 | # and also so they don't conflict with the primary calendar associated 10 | # with the domain 11 | 12 | sites = Site.where("path_prefix IS NOT NULL AND path_prefix != ''") 13 | sites.each do |site| 14 | site.domain += "/#{site.path_prefix}" 15 | site.save! 16 | end 17 | 18 | remove_column :sites, :path_prefix 19 | end 20 | 21 | def down 22 | add_column :sites, :path_prefix, :string 23 | 24 | Site.where("domain LIKE %/%").each do |site| 25 | domain, path_prefix = site.domain.partition('/')[0,2] 26 | 27 | site.domain = domain 28 | site.path_prefix = path_prefix 29 | site.save! 30 | end 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /db/migrate/20130930234907_add_ga_account_id_to_sites.rb: -------------------------------------------------------------------------------- 1 | class AddGaAccountIdToSites < ActiveRecord::Migration 2 | def change 3 | add_column :sites, :ga_account_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20131001031403_add_sharethis_key_to_sites.rb: -------------------------------------------------------------------------------- 1 | class AddSharethisKeyToSites < ActiveRecord::Migration 2 | def change 3 | add_column :sites, :sharethis_key, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140212051512_add_disqus_shortname_to_sites.rb: -------------------------------------------------------------------------------- 1 | class AddDisqusShortnameToSites < ActiveRecord::Migration 2 | def change 3 | add_column :sites, :disqus_shortname, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140309144618_add_updated_at_indexes.rb: -------------------------------------------------------------------------------- 1 | class AddUpdatedAtIndexes < ActiveRecord::Migration 2 | def change 3 | # add_timestamps :events_topics 4 | # add_timestamps :events_types 5 | # add_timestamps :organizations_topics 6 | # add_timestamps :sources_topics 7 | # add_timestamps :sources_types 8 | 9 | add_index :abstract_events, :updated_at 10 | add_index :abstract_locations, :updated_at 11 | add_index :events, :updated_at 12 | add_index :organizations, :updated_at 13 | add_index :sites, :updated_at 14 | add_index :sources, :updated_at 15 | add_index :topics, :updated_at 16 | add_index :types, :updated_at 17 | add_index :users, :updated_at 18 | add_index :venues, :updated_at 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /db/migrate/20140309152321_add_indexes_to_topics_types.rb: -------------------------------------------------------------------------------- 1 | class AddIndexesToTopicsTypes < ActiveRecord::Migration 2 | def change 3 | add_index :topics, [:site_id, :name] 4 | add_index :types, [:site_id, :name] 5 | 6 | add_index :events_topics, :event_id 7 | add_index :events_topics, :topic_id 8 | add_index :events_types, :event_id 9 | add_index :events_types, :type_id 10 | 11 | add_index :organizations_topics, :organization_id 12 | add_index :organizations_topics, :topic_id 13 | 14 | add_index :sources_types, :source_id 15 | add_index :sources_types, :type_id 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /db/migrate/20140517001901_add_admin_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddAdminToUsers < ActiveRecord::Migration 2 | class User < ActiveRecord::Base ; end 3 | 4 | def change 5 | add_column :users, :admin, :boolean, default: false 6 | 7 | # all pre-existing users were admins, so we're flagging them here 8 | User.all.each do |user| 9 | user.update_attributes(admin: true) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20140529191701_add_default_venue_id_to_organizations.rb: -------------------------------------------------------------------------------- 1 | class AddDefaultVenueIdToOrganizations < ActiveRecord::Migration 2 | def change 3 | add_column :organizations, :default_venue_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140603005652_rename_default_venue_to_venue.rb: -------------------------------------------------------------------------------- 1 | class RenameDefaultVenueToVenue < ActiveRecord::Migration 2 | def change 3 | rename_column :organizations, :default_venue_id, :venue_id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20161201160616_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from acts_as_taggable_on_engine (originally 3) 2 | class AddTaggingsCounterCacheToTags < ActiveRecord::Migration 3 | def self.up 4 | add_column :tags, :taggings_count, :integer, default: 0 5 | 6 | ActsAsTaggableOn::Tag.reset_column_information 7 | ActsAsTaggableOn::Tag.find_each do |tag| 8 | ActsAsTaggableOn::Tag.reset_counters(tag.id, :taggings) 9 | end 10 | end 11 | 12 | def self.down 13 | remove_column :tags, :taggings_count 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20161201160618_change_collation_for_tag_names.acts_as_taggable_on_engine.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from acts_as_taggable_on_engine (originally 5) 2 | # This migration is added to circumvent issue #623 and have special characters 3 | # work properly 4 | class ChangeCollationForTagNames < ActiveRecord::Migration 5 | def up 6 | if ActsAsTaggableOn::Utils.using_mysql? 7 | execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;") 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20161204144535_drop_updates.rb: -------------------------------------------------------------------------------- 1 | class DropUpdates < ActiveRecord::Migration[5.0] 2 | def change 3 | drop_table :updates 4 | end 5 | 6 | def down 7 | raise ActiveRecord::IrreversibleMigration 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20170111075150_add_geo_precision_too_venues.rb: -------------------------------------------------------------------------------- 1 | class AddGeoPrecisionTooVenues < ActiveRecord::Migration[5.0] 2 | def change 3 | add_column :venues, :geo_precision, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20170113215729_add_enabled_to_topics_types.rb: -------------------------------------------------------------------------------- 1 | class AddEnabledToTopicsTypes < ActiveRecord::Migration[5.0] 2 | def change 3 | add_column :topics, :enabled, :boolean, :default => true 4 | add_column :types, :enabled, :boolean, :default => true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20170129122904_create_site_domains.rb: -------------------------------------------------------------------------------- 1 | class CreateSiteDomains < ActiveRecord::Migration[5.0] 2 | def up 3 | create_table :site_domains do |t| 4 | t.references :site, foreign_key: true, null: false 5 | t.string :domain, null: false 6 | t.boolean :redirect, null: false, default: true 7 | 8 | t.timestamps null: false 9 | end 10 | 11 | execute <<-SQL 12 | INSERT INTO site_domains 13 | (site_id, domain, redirect, created_at, updated_at) 14 | SELECT id, domain, false, NOW(), NOW() FROM sites; 15 | SQL 16 | 17 | add_index :site_domains, :domain, unique: true 18 | end 19 | 20 | def down 21 | drop_table :site_domains 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /db/migrate/20170130081642_downcase_site_domains.rb: -------------------------------------------------------------------------------- 1 | class DowncaseSiteDomains < ActiveRecord::Migration[5.0] 2 | def up 3 | execute <<-SQL 4 | UPDATE sites SET domain = lower(domain); 5 | UPDATE site_domains SET domain = lower(domain); 6 | SQL 7 | end 8 | 9 | def down 10 | # Nothing to do 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /lib/associated_venues.rb: -------------------------------------------------------------------------------- 1 | module AssociatedVenues 2 | def associate_with_venue(venue) 3 | venue = \ 4 | case venue 5 | when Venue then venue 6 | when NilClass then nil 7 | when String then Venue.find_or_initialize_by(title: venue) 8 | when Fixnum then Venue.find(venue) 9 | else raise TypeError, "Unknown type: #{venue.class}" 10 | end 11 | 12 | if venue && ((self.venue && self.venue != venue) || (!self.venue)) 13 | self.venue = venue.progenitor 14 | elsif !venue && self.venue 15 | self.venue = nil 16 | end 17 | 18 | return self.venue 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/ext/nil_strip_html.rb: -------------------------------------------------------------------------------- 1 | # Helps Mofo users by providing a strip_html on NilClass, saving developers 2 | # from having to write code like: 3 | # event.title.strip_html if event.title 4 | # 5 | # And instead writing simpler code like: 6 | # event.title.strip_html 7 | class NilClass 8 | def strip_html 9 | nil 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/metaclass.rb: -------------------------------------------------------------------------------- 1 | # http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html 2 | 3 | class Object 4 | # The hidden singleton lurks behind everyone 5 | def metaclass; class << self; self; end; end 6 | def meta_eval(&blk); metaclass.instance_eval(&blk); end 7 | end 8 | -------------------------------------------------------------------------------- /lib/search_engine/base.rb: -------------------------------------------------------------------------------- 1 | require 'search_engine' 2 | 3 | # = SearchEngine::Base 4 | # 5 | # This class describes common behavior for search engine implementations, e.g. 6 | # the Sunspot search engine implementation would subclass this. 7 | # 8 | # == Usage 9 | # 10 | # Create a subclass to describe your search engine, indicate whether the search 11 | # engine provides a ::score to rank the relevance of matches, and 12 | # ::add_searching_to method for adding this search engine's logic to the model. 13 | # 14 | # class SearchEngine::Foo < SearchEngine::Base 15 | # score true 16 | # 17 | # def self.add_searching_to(model) 18 | # ... 19 | # end 20 | # end 21 | class SearchEngine::Base 22 | def self.inherited(subclass) 23 | subclass.class_eval do 24 | cattr_accessor :_score 25 | end 26 | end 27 | 28 | # Does this search engine provide a score? 29 | def self.score? 30 | return self._score != false 31 | end 32 | 33 | # Set whether this search engine provides a score. 34 | def self.score(value) 35 | self._score = value 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/settings_reader.rb: -------------------------------------------------------------------------------- 1 | require 'erb' 2 | require 'yaml' 3 | require 'ostruct' 4 | require 'socket' 5 | 6 | # = SettingsReader 7 | # 8 | # Returns an OpenStruct object representing settings read from an ERB-parsed 9 | # YAML file. 10 | class SettingsReader 11 | def self.read(filename, defaults={}) 12 | return OpenStruct.new(defaults.merge(YAML.load(ERB.new(File.read(filename)).result))) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/source_parser/http_authentication_required_error.rb: -------------------------------------------------------------------------------- 1 | # Exception raised if user requests parsing of a URL that requires 2 | # authentication but none was provided. 3 | class SourceParser 4 | class HttpAuthenticationRequiredError < Exception 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/source_parser/not_found.rb: -------------------------------------------------------------------------------- 1 | class SourceParser 2 | # == SourceParser::NotFound 3 | # 4 | # Exception thrown to indicate that the source isn't found and no other parsers should be tried. 5 | # 6 | # This exception should only be thrown by the canonical handler that can definitively tell if the source doesn't exist. For example, the SourceParser::Facebook parser can throw this exception when given a http://facebook.com/ URLs because it can be sure whether these exist. 7 | class NotFound < StandardError 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/task_helpers.rb: -------------------------------------------------------------------------------- 1 | module TaskHelpers 2 | def self.parse_var_args(args) 3 | args.inject({}) do |options,(key,val)| 4 | if key =~ /\Aargv/ 5 | # unnamed arg (key name defined in variable value, x=1 or x:1) 6 | if !val.present? || val[0] == ':' || val[0] == '=' 7 | # unnamed arg doesn't have a key/name, ignore 8 | elsif val =~ /\A([^:=]+)[:=](.*)\Z/ 9 | options[$1.to_sym] = $2 10 | elsif val =~ /\A!(.+?)\Z/ 11 | options[$1.to_sym] = false 12 | else 13 | options[val.to_sym] = true 14 | end 15 | else 16 | # standard task-defined arg (hard-coded in task definition) 17 | options[key] = val 18 | end 19 | 20 | options 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/tasks/update_counter_caches.rake: -------------------------------------------------------------------------------- 1 | desc "Update counter caches" 2 | task :update_counter_caches => :environment do 3 | # Update the Venue#events_count 4 | total = Venue.count 5 | Venue.all.each do |venue| 6 | cached = venue.events_count 7 | actual = venue.events.count 8 | if actual != cached 9 | puts "Updating Venue ##{venue.id} from #{cached} cached to #{actual} actual -- #{venue.title}" 10 | Venue.connection.update("UPDATE venues SET events_count = #{actual} WHERE id = #{venue.id}") 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/url_validator.rb: -------------------------------------------------------------------------------- 1 | module UrlValidator 2 | WEBSITE_FORMAT = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 3 | 4 | def normalize_url! 5 | unless self.url.blank? || self.url.match(/^[\d\D]+:\/\//) 6 | self.url = 'http://' + self.url 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /log/.do_not_delete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/log/.do_not_delete -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The page you were looking for doesn't exist (404) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The page you were looking for doesn't exist.

27 |

You may have mistyped the address or the page may have moved.

28 |
29 | 30 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The change you wanted was rejected (422) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The change you wanted was rejected.

27 |

Maybe you tried to change something you didn't have access to.

28 |
29 | 30 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | We're sorry, but something went wrong (500) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

We're sorry, but something went wrong.

27 |

We've been notified about this issue and we'll take a look at it shortly.

28 |
29 | 30 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/public/favicon.ico -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/public/favicon.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | 3 | # Allow visits to all pages, except the edit forms 4 | User-Agent: * 5 | Disallow: /omfg 6 | Disallow: /recent_changes 7 | Disallow: /sources 8 | Disallow: /sources/import 9 | Disallow: /sources/new 10 | Disallow: /events/new 11 | Disallow: /venues/new 12 | Disallow: /events/duplicates 13 | Disallow: /venues/duplicates 14 | Disallow: /events/*/edit 15 | Disallow: /venues/*/edit 16 | Disallow: /sources/*/edit 17 | -------------------------------------------------------------------------------- /solr/conf/spellings.txt: -------------------------------------------------------------------------------- 1 | pizza 2 | history -------------------------------------------------------------------------------- /solr/conf/synonyms.txt: -------------------------------------------------------------------------------- 1 | # The ASF licenses this file to You under the Apache License, Version 2.0 2 | # (the "License"); you may not use this file except in compliance with 3 | # the License. You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | 13 | #----------------------------------------------------------------------- 14 | #some test synonym mappings unlikely to appear in real input text 15 | aaa => aaaa 16 | bbb => bbbb1 bbbb2 17 | ccc => cccc1,cccc2 18 | a\=>a => b\=>b 19 | a\,a => b\,b 20 | fooaaa,baraaa,bazaaa 21 | 22 | # Some synonym groups specific to this example 23 | GB,gib,gigabyte,gigabytes 24 | MB,mib,megabyte,megabytes 25 | Television, Televisions, TV, TVs 26 | #notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming 27 | #after us won't split it into two words. 28 | 29 | # Synonym mappings can be used for spelling correction too 30 | pixima => pixma 31 | 32 | -------------------------------------------------------------------------------- /spec/controllers/admin_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe AdminController, type: :controller do 4 | describe "#index" do 5 | context "when the user is an admin" do 6 | before do 7 | sign_in create(:user, admin: true) 8 | end 9 | 10 | it "should load the admin pages" do 11 | get :index 12 | expect(response).to be_success 13 | end 14 | end 15 | 16 | context "when the user is not an admin" do 17 | before do 18 | sign_in create(:user, admin: false) 19 | end 20 | 21 | it "should not load the admin pages" do 22 | get :index 23 | expect(response).to be_redirect 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/controllers/paper_trail_manager_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe PaperTrailManager::ChangesController, type: :controller do 4 | describe "#index" do 5 | context "when the user is an admin" do 6 | before do 7 | sign_in create(:user, admin: true) 8 | end 9 | 10 | it "should load the admin pages" do 11 | get :index 12 | expect(response).to be_success 13 | end 14 | end 15 | 16 | context "when the user is not an admin" do 17 | before do 18 | sign_in create(:user, admin: false) 19 | end 20 | 21 | it "should not load the admin pages" do 22 | get :index 23 | expect(response).to be_redirect 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/controllers/site_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe SiteController, type: :controller do 4 | 5 | describe "#index" do 6 | it "should render requests for HTML successfully" do 7 | get :index 8 | expect(response).to redirect_to(events_path) 9 | end 10 | 11 | it "should redirect requests for non-HTML to events" do 12 | get :index, :params => { :format => "json" } 13 | expect(response).to redirect_to(events_path(:format => "json")) 14 | end 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /spec/factories/abstract_event.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :abstract_event do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | 7 | sequence(:title) {|n| "'Theory of Insanity' Attempt ##{n}" } 8 | start_time { Time.zone.now + 29.hours } 9 | end_time { Time.zone.now + 32.hours } 10 | 11 | source 12 | 13 | trait :invalid do 14 | title nil 15 | end 16 | 17 | trait :future do 18 | start_time { Time.zone.now + 7.days } 19 | end 20 | 21 | trait :w_location do 22 | abstract_location 23 | end 24 | 25 | trait :w_event_attributes do 26 | sequence(:url) {|n| "http://my.event-#{n}.url.test/" } 27 | 28 | description do 29 | "After careful examination, we have concluded that our universe " + 30 | "is really a multiverse that is being decompressed from a single " + 31 | "giant zip file. Compression levels before the Big Bang suggest " + 32 | "we are not as random as we would like ourselves to believe." 33 | end 34 | 35 | tags { %w(universe everything nothing the-sysadmin-drives-a-jalopy) } 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /spec/factories/abstract_location.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :abstract_location do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | 7 | sequence(:title) {|n| "Underground Strawberry-Turnip Cross-Breeding Facility ##{n}" } 8 | 9 | source 10 | 11 | trait :invalid do 12 | title ' ' 13 | end 14 | 15 | trait :w_address do 16 | address 'Unlabelled' 17 | street_address 'Not enough houses' 18 | locality "You're getting colder" 19 | region 'Likely Hell' 20 | postal_code '99762' 21 | country 'US' 22 | end 23 | 24 | trait :w_venue_attributes do 25 | w_address 26 | 27 | sequence(:url) {|n| "http://my.venue-#{n}.url.test/" } 28 | description { "For that glow-in-your-mouth goodness!" } 29 | latitude { (64.503889).to_d } 30 | longitude { (-165.399444).to_d } 31 | email { "iceman@extreme-tourguides.test" } 32 | telephone { "000-000-0000" } 33 | tags { %w(food farming gmo underground radium) } 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/factories/event.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :event do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | 7 | # TODO: reduce to minimum required to pass validation (drop sequences unless uniq) 8 | sequence(:title) { |n| "Event #{n}" } 9 | sequence(:description) { |n| "Description of Event #{n}." } 10 | start_time { Time.zone.now + 1.hour } 11 | end_time { self.start_time + 1.hours } 12 | 13 | trait :future do 14 | start_time { Time.zone.now + 7.days } 15 | end 16 | end 17 | 18 | factory :event_with_venue, :parent => :event do 19 | venue 20 | end 21 | 22 | factory :duplicate_event, :parent => :event do 23 | association :duplicate_of, :factory => :event 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/factories/organization.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :organization do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | 7 | name 'My Org' 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/factories/site.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :site do 5 | name 'My Site' 6 | sequence(:domain) {|n| "my.site#{n}" } 7 | timezone 'Asia/Tokyo' 8 | locale 'en-x-foo-bar' 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/factories/site_domain.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :site_domain do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | sequence(:domain) {|n| "my.site.domain#{n}" } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/factories/source.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :source do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | 7 | url 'http://a.valid.url.test' 8 | title 'My Source' 9 | 10 | transient do 11 | topics_count 0 12 | types_count 0 13 | end 14 | 15 | before(:create) do |source, evaluator| 16 | source.topics << create_list(:topic, evaluator.topics_count) 17 | source.types << create_list(:type, evaluator.types_count) 18 | end 19 | 20 | trait :w_organization do 21 | organization 22 | end 23 | 24 | trait :w_topics_types do 25 | topics_count 3 26 | types_count 2 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/factories/topic.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :topic do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | 7 | sequence(:name) {|n| "topic #{n}" } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/factories/types.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :type do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | 7 | sequence(:name) {|n| "type #{n}" } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/factories/users.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :user do 5 | sequence(:email) {|n| "foo-#{n}@example.com" } 6 | password "asdfasdf" 7 | password_confirmation "asdfasdf" 8 | 9 | factory :admin, traits: [:admin] 10 | end 11 | 12 | trait :admin do 13 | admin true 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /spec/factories/venue.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :venue do 5 | site { Site.find_by_domain(ENV['TEST_REQ_HOST']) } 6 | 7 | # TODO: reduce to minimum required to pass validation (drop sequences unless uniq) 8 | sequence(:title) { |n| "Venue #{n}" } 9 | sequence(:description) { |n| "Description of Venue #{n}." } 10 | sequence(:address) { |n| "Address #{n}" } 11 | sequence(:street_address) { |n| "Street #{n}" } 12 | sequence(:locality) { |n| "City #{n}" } 13 | sequence(:region) { |n| "Region #{n}" } 14 | sequence(:postal_code) { |n| "#{n}-#{n}-#{n}" } 15 | sequence(:country) { |n| "Country #{n}" } 16 | sequence(:latitude) { |n| "45.#{n}".to_f } 17 | sequence(:longitude) { |n| "122.#{n}".to_f } 18 | sequence(:email) { |n| "info@venue#{n}.test" } 19 | sequence(:telephone) { |n| "(#{n}#{n}#{n}) #{n}#{n}#{n}-#{n}#{n}#{n}#{n}" } 20 | sequence(:url) { |n| "http://#{n}.test" } 21 | closed false 22 | wifi true 23 | access_notes "Access permitted." 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/fixtures/locales/en-locale-loco.yml: -------------------------------------------------------------------------------- 1 | en-locale-loco: 2 | some: "translation" 3 | -------------------------------------------------------------------------------- /spec/fixtures/locales/foo/en-x-foo-bar.yml: -------------------------------------------------------------------------------- 1 | en-x-foo-bar: 2 | some: "translation" 3 | -------------------------------------------------------------------------------- /spec/fixtures/locales/foo/en-x-foo.yml: -------------------------------------------------------------------------------- 1 | en-x-foo: 2 | some: "translation" 3 | -------------------------------------------------------------------------------- /spec/lib/source_parser_meetup_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe SourceParser::Meetup do 4 | describe "with a meetup.com API key in secrets.yml" do 5 | before(:each) do 6 | content = read_sample('meetup.json') 7 | expect(HTTParty).to receive(:get).and_return(JSON.parse(content)) 8 | @events = SourceParser::Meetup.to_abstract_events(:url => 'http://www.meetup.com/pdxpython/events/ldhnqyplbnb/') 9 | @event = @events.first 10 | end 11 | 12 | it "should find one event" do 13 | expect(@events.size).to eq 1 14 | end 15 | 16 | it "should set event details" do 17 | expect(@event.title).to eq "eLearning Network Meetup" 18 | expect(@event.start_time).to eq Time.zone.parse("Thu Aug 11 00:00:00 UTC 2011") 19 | end 20 | 21 | it "should tag Meetup events with automagic machine tags" do 22 | expect(@event.tags).to eq ["meetup:event=ldhnqyplbnb", "meetup:group=eLearningNetwork"] 23 | end 24 | 25 | it "should populate a venue when structured data is provided" do 26 | expect(@event.abstract_location).to be_a AbstractLocation 27 | expect(@event.abstract_location.title).to eq "Green Dragon Bistro and Brewpub" 28 | expect(@event.abstract_location.street_address).to eq "928 SE 9th Ave" 29 | expect(@event.abstract_location.tags).to eq ["meetup:venue=774133"] 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /spec/lib/source_parser_plancast_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe SourceParser::Plancast do 4 | 5 | before(:each) do 6 | content = read_sample('plancast.json') 7 | expect(HTTParty).to receive(:get).and_return(JSON.parse(content)) 8 | @events = SourceParser::Plancast.to_abstract_events(:url => 'http://plancast.com/p/3cos/indiewebcamp') 9 | @event = @events.first 10 | end 11 | 12 | it "should find one event" do 13 | expect(@events.size).to eq 1 14 | end 15 | 16 | it "should set event details" do 17 | expect(@event.title).to eq "IndieWebCamp" 18 | expect(@event.start_time).to eq Time.zone.parse("Sat, 25 Jun 2011 00:00:00 PDT -07:00") 19 | end 20 | 21 | it "should tag Plancast events with automagic machine tags" do 22 | expect(@event.tags).to eq ["plancast:plan=3cos"] 23 | end 24 | 25 | it "should populate a venue when structured data is provided" do 26 | expect(@event.abstract_location.title).to eq "Urban Airship" 27 | expect(@event.abstract_location.address).to eq "334 Northwest 11th Avenue, Portland, Oregon, United States" 28 | expect(@event.abstract_location.tags).to eq ["plancast:place=1520153"] 29 | end 30 | 31 | end 32 | -------------------------------------------------------------------------------- /spec/mixins/dirty_attr_accessor_examples.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | # Tests defined in mix-in examples should only verify that the mix-in 4 | # was included in the +described_class+ and that it was properly set up. 5 | # 6 | # If you want to add tests for the mix-in's behavior itself, see the 7 | # *_spec.rb version of this file instead. 8 | # 9 | RSpec.shared_examples_for DirtyAttrAccessor do 10 | describe "mixing class methods into model" do 11 | subject { described_class } 12 | it { should respond_to :dirty_attr_accessor } 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /spec/mixins/rebaseable_examples.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | # Tests defined in mix-in examples should only verify that the mix-in 4 | # was included in the +described_class+ and that it was properly set up. 5 | # 6 | # If you want to add tests for the mix-in's behavior itself, see the 7 | # *_spec.rb version of this file instead. 8 | # 9 | RSpec.shared_examples_for Rebaseable do 10 | describe "mixing instance methods into model" do 11 | subject { described_class.new } 12 | it { should respond_to :rebase_changed_attributes! } 13 | end 14 | 15 | describe "rebasing two objects" do 16 | it "should not raise an error" do 17 | # just want to exercise the method once for anything catastrophic 18 | obj1, obj2 = 2.times.map { described_class.new } 19 | expect { obj1.rebase_changed_attributes!(obj2) }.to_not raise_error 20 | end 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /spec/models/site_domain_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe SiteDomain, type: :model do 4 | subject(:site_domain) { build(:site_domain) } 5 | 6 | it { should be_valid } 7 | 8 | it { should validate_presence_of(:site) } 9 | it { should validate_presence_of(:domain) } 10 | it { should validate_presence_of(:redirect) } 11 | 12 | it { should validate_uniqueness_of(:domain).case_insensitive } 13 | 14 | describe "#domain=" do 15 | it "downcases the domain on assignment" do 16 | expect { site_domain.domain = "FooBar.TEST" } 17 | .to change { site_domain.domain }.to("foobar.test") 18 | end 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /spec/models/site_scoping_examples.rb: -------------------------------------------------------------------------------- 1 | RSpec.shared_examples_for "site-scoped model" do |factory: described_class.downcase| 2 | 3 | before do 4 | [site, create(:site)].each do |site| 5 | factory.respond_to?(:call) \ 6 | ? factory.call(site) # Proc/Lambda 7 | : create(factory, site: site) # FactoryGirl 8 | end 9 | end 10 | 11 | context "when current site is not set" do 12 | around {|ex| Site.without_site { ex.run } } 13 | 14 | it "includes all sites in query" do 15 | site_ids = Version.all.pluck(:site_id).uniq 16 | expect(site_ids.size).to be > 1 17 | end 18 | end 19 | 20 | context "when current site is set" do 21 | around {|ex| site.with_site { ex.run } } 22 | 23 | it "limits queries to the current site" do 24 | site_ids = Version.all.pluck(:site_id).uniq 25 | expect(site_ids.size).to eq 1 26 | expect(site_ids.first).to eq site.id 27 | end 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /spec/models/tag_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe ActsAsTaggableOn::Tag, type: :model do 4 | describe "handling machine tags" do 5 | before do 6 | @valid_machine_tag = ActsAsTaggableOn::Tag.new(:name => 'lanyrd:event=1234') 7 | end 8 | 9 | it "should return an empty hash when the tag is not a machine tag" do 10 | expect(ActsAsTaggableOn::Tag.new(:name => 'not a machine tag').machine_tag).to eq({}) 11 | end 12 | 13 | it "should parse a machine tag into components" do 14 | expect(@valid_machine_tag.machine_tag[:namespace]).to eq 'lanyrd' 15 | expect(@valid_machine_tag.machine_tag[:predicate]).to eq 'event' 16 | expect(@valid_machine_tag.machine_tag[:value]).to eq '1234' 17 | end 18 | 19 | it "should generate a url for supported namespaces/predicates" do 20 | expect(@valid_machine_tag.machine_tag[:url]).to eq "http://lanyrd.com/1234" 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/models/type_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe Type, type: :model do 4 | describe "in general" do 5 | before(:each) do 6 | @type = Type.new(:name => "My Type") 7 | end 8 | specify {expect(@type).to be_valid} 9 | end 10 | 11 | # describe "when relating types and events" do 12 | # before(:each) do 13 | # @type = Type.new(:name => "protest") 14 | # @event = Event.new(:title => "Event title") 15 | # end 16 | 17 | # it "should find " 18 | 19 | 20 | describe "when creating nameless types" do 21 | before(:each) do 22 | @type = Type.new() 23 | end 24 | specify {expect(@type).to_not be_valid} 25 | end 26 | end 27 | 28 | 29 | -------------------------------------------------------------------------------- /spec/models/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe User, type: :model do 4 | it "should be registerable" do 5 | user = create(:user) 6 | expect(user.devise_modules).to include :registerable 7 | end 8 | 9 | it "can be an admin" do 10 | user = create(:user) 11 | user.update_attributes(admin: true) 12 | 13 | expect(user.admin).to be true 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/models/version_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | require_relative "site_scoping_examples" 3 | 4 | RSpec.describe Version do 5 | 6 | it_behaves_like "site-scoped model", 7 | factory: ->(site) { FactoryGirl.create(:event, site: site).versions.first } 8 | 9 | end 10 | -------------------------------------------------------------------------------- /spec/requests/rails_admin_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe RailsAdmin::MainController, type: :request do 4 | describe "#dashboard" do 5 | context "when the user is an admin" do 6 | before do 7 | sign_in create(:user, admin: true) 8 | end 9 | 10 | it "should load the admin pages" do 11 | get '/rails_admin' 12 | expect(response).to be_success 13 | end 14 | end 15 | 16 | context "when the user is not an admin" do 17 | before do 18 | sign_in create(:user, admin: false) 19 | end 20 | 21 | it "should not load the admin pages" do 22 | get '/rails_admin' 23 | expect(response).to be_redirect 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/samples/facebook.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "247619485255249", 3 | "owner": { 4 | "name": "Open Source Bridge", 5 | "category": "Community", 6 | "id": "228805830479541" 7 | }, 8 | "name": "Open Source Bridge 2012", 9 | "description": "Open Source Bridge is an open source developers conference, focused on bringing people from a range of technology backgrounds together to share their knowledge and explore what it means to be an open source citizen.\n\nFind out more at http://opensourcebridge.org/\nRegister today at http://osbridge.eventbrite.com/", 10 | "start_time": "2012-06-26T09:00:00", 11 | "end_time": "2012-06-29T21:00:00", 12 | "location": "Eliot Center", 13 | "venue": { 14 | "street": "1226 SW Salmon Street", 15 | "city": "Portland", 16 | "state": "Oregon", 17 | "country": "United States", 18 | "latitude": 45.5236, 19 | "longitude": -122.675 20 | }, 21 | "privacy": "OPEN", 22 | "updated_time": "2011-06-29T18:36:49+0000" 23 | } -------------------------------------------------------------------------------- /spec/samples/hcal_basic.xml: -------------------------------------------------------------------------------- 1 |
2 | http://www.web2con.com/ 3 | Web 2.0 Conference: 4 | Friday, April 5, 2013, 5 | at the Argent Hotel, San Francisco, CA 6 |
7 | -------------------------------------------------------------------------------- /spec/samples/hcal_dup_event_dup_venue.xml: -------------------------------------------------------------------------------- 1 |
2 | http://www.web2con.com/ 3 | Web 2.0 Conference: 4 | Friday, October 5, 2007, 5 | at the 6 |
7 | CubeSpace2
8 |
9 | 622 SE Grand Ave.
10 | Portland, OR 97204 11 |
12 |
13 |
-------------------------------------------------------------------------------- /spec/samples/hcal_event_duplicates_fixture.xml: -------------------------------------------------------------------------------- 1 |
2 | http://www.web2con.com/ 3 | Web 2.0 Conference: 4 | Friday, October 5, 2007, 5 | at the 6 |
7 | CubeSpace2
8 |
9 | 622 SE Grand Ave.
10 | Portland, OR 97204 11 |
12 |
13 |
-------------------------------------------------------------------------------- /spec/samples/hcal_event_wo_lat_and_long.xml: -------------------------------------------------------------------------------- 1 |
2 | Ignite Portland 2010 3 | June 18, 2010 4 | 9:00 PM 5 |
6 | Bagdad Theater and Pub
7 |
8 | 3702 S.E. Hawthorne Blvd
9 | Portland, 10 | OR 11 | 97214 12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /spec/samples/hcal_multiple.xml: -------------------------------------------------------------------------------- 1 | 9 | 17 | -------------------------------------------------------------------------------- /spec/samples/hcal_same_event_twice_with_different_venues.xml: -------------------------------------------------------------------------------- 1 | 7 | 13 | -------------------------------------------------------------------------------- /spec/samples/hcal_single.xml: -------------------------------------------------------------------------------- 1 | ` 9 | -------------------------------------------------------------------------------- /spec/samples/hcal_two_identical_events.xml: -------------------------------------------------------------------------------- 1 | ` 8 | ` 15 | -------------------------------------------------------------------------------- /spec/samples/ical_apple.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | CALSCALE:GREGORIAN 3 | X-WR-TIMEZONE;VALUE=TEXT:US/Pacific 4 | METHOD:PUBLISH 5 | PRODID:-//Apple Computer\, Inc//iCal 1.0//EN 6 | X-WR-CALNAME;VALUE=TEXT:Example 7 | VERSION:2.0 8 | BEGIN:VEVENT 9 | SEQUENCE:5 10 | DTSTART;TZID=US/Pacific:20021128T140000 11 | DTSTAMP:20021028T011706Z 12 | SUMMARY:Coffee with Jason 13 | UID:EC9439B1-FF65-11D6-9973-003065F99D04 14 | DTEND;TZID=US/Pacific:20021128T150000 15 | BEGIN:VALARM 16 | TRIGGER;VALUE=DURATION:-P1D 17 | ACTION:DISPLAY 18 | DESCRIPTION:Event reminder 19 | END:VALARM 20 | END:VEVENT 21 | END:VCALENDAR 22 | 23 | -------------------------------------------------------------------------------- /spec/samples/ical_apple_v3.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | METHOD:PUBLISH 3 | X-WR-TIMEZONE:US/Pacific 4 | PRODID:-//Apple Inc.//iCal 3.0//EN 5 | CALSCALE:GREGORIAN 6 | X-WR-CALNAME:Untitled 7 | VERSION:2.0 8 | X-WR-RELCALID:08075B83-5017-44B8-BB88-027F3F882762 9 | X-APPLE-CALENDAR-COLOR:#F57802 10 | BEGIN:VTIMEZONE 11 | TZID:US/Pacific 12 | BEGIN:DAYLIGHT 13 | TZOFFSETFROM:-0800 14 | TZOFFSETTO:-0700 15 | DTSTART:20070311T020000 16 | RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU 17 | TZNAME:PDT 18 | END:DAYLIGHT 19 | BEGIN:STANDARD 20 | TZOFFSETFROM:-0700 21 | TZOFFSETTO:-0800 22 | DTSTART:20071104T020000 23 | RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU 24 | TZNAME:PST 25 | END:STANDARD 26 | END:VTIMEZONE 27 | BEGIN:VEVENT 28 | SEQUENCE:3 29 | TRANSP:OPAQUE 30 | UID:654C6EC3-542C-469A-8267-12C35E5A6BCA 31 | DTSTART;TZID=US/Pacific:20100408T000000 32 | DTSTAMP:20100409T033746Z 33 | SUMMARY:Coffee with Jason 34 | CREATED:20100409T033734Z 35 | DTEND;TZID=US/Pacific:20100408T010000 36 | END:VEVENT 37 | END:VCALENDAR 38 | -------------------------------------------------------------------------------- /spec/samples/ical_basic.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | X-WR-CALNAME;VALUE=TEXT:Black cat 3 | VERSION:2.0 4 | CALSCALE:GREGORIAN 5 | PRODID:-//dclicio.us//iCal 1.0//EN 6 | X-WR-TIMEZONE;VALUE=TEXT:US/Eastern 7 | BEGIN:VEVENT 8 | UID:dclicio.us-243 9 | DESCRIPTION:with http://dclicio.us 10 | SUMMARY: 11 | DTSTART:20130117 12 | DTSTAMP:040425 13 | SEQ:0 14 | END:VEVENT 15 | END:VCALENDAR 16 | -------------------------------------------------------------------------------- /spec/samples/ical_basic_with_duration.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | X-WR-CALNAME;VALUE=TEXT:Black cat 3 | VERSION:2.0 4 | CALSCALE:GREGORIAN 5 | PRODID:-//dclicio.us//iCal 1.0//EN 6 | X-WR-TIMEZONE;VALUE=TEXT:US/Eastern 7 | BEGIN:VEVENT 8 | UID:dclicio.us-243 9 | DESCRIPTION:with http://dclicio.us 10 | SUMMARY: 11 | DTSTART:20100408T000000 12 | DTSTAMP:20100409T033746Z 13 | DURATION:PT1H0M0S 14 | SEQ:0 15 | END:VEVENT 16 | END:VCALENDAR 17 | -------------------------------------------------------------------------------- /spec/samples/ical_event_with_squashed_venue.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | X-WR-CALNAME;VALUE=TEXT:Black cat 3 | VERSION:2.0 4 | CALSCALE:GREGORIAN 5 | PRODID:-//dclicio.us//iCal 1.0//EN 6 | X-WR-TIMEZONE;VALUE=TEXT:US/Eastern 7 | BEGIN:VEVENT 8 | SUMMARY:Event with cloned venue 9 | DTSTART:20090117 10 | LOCATION:Squashed Duplicate Venue 11 | END:VEVENT 12 | END:VCALENDAR 13 | -------------------------------------------------------------------------------- /spec/samples/ical_gmt.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | X-WR-CALNAME;VALUE=TEXT:Black cat 3 | VERSION:2.0 4 | CALSCALE:GREGORIAN 5 | PRODID:-//dclicio.us//iCal 1.0//EN 6 | X-WR-TIMEZONE;VALUE=TEXT:US/Pacific 7 | BEGIN:VEVENT 8 | SUMMARY: Time 0800-0900 GMT 9 | DTSTART;TZID=GMT:20200507T080000 10 | DTEND;TZID=GMT:20200507T090000 11 | END:VEVENT 12 | END:VCALENDAR 13 | -------------------------------------------------------------------------------- /spec/samples/ical_z.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | VERSION:2.0 3 | CALSCALE:GREGORIAN 4 | X-WR-TIMEZONE;VALUE=TEXT:US/Pacific 5 | BEGIN:VEVENT 6 | SUMMARY:Time 0800-0900 GMT 7 | DTSTART:20100701T080000Z 8 | DTEND:20100701T090000Z 9 | END:VEVENT 10 | END:VCALENDAR 11 | -------------------------------------------------------------------------------- /spec/samples/meetup.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "ldhnqyplbnb", 3 | "utc_offset": -25200000, 4 | "time": 1313020800000, 5 | "status": "upcoming", 6 | "yes_rsvp_count": 1, 7 | "visibility": "public", 8 | "event_url": "http:\/\/www.meetup.com\/eLearningNetwork\/events\/23638211\/", 9 | "maybe_rsvp_count": 0, 10 | "name": "eLearning Network Meetup", 11 | "venue": { 12 | "id": 774133, 13 | "zip": "97214", 14 | "phone": "503 517 0606", 15 | "lon": -122.656696, 16 | "name": "Green Dragon Bistro and Brewpub", 17 | "state": "OR", 18 | "address_1": "928 SE 9th Ave", 19 | "lat": 45.516044, 20 | "city": "Portland", 21 | "country": "us" 22 | }, 23 | "group": { 24 | "id": 1758806, 25 | "group_lat": 45.5, 26 | "name": "eLearning Network", 27 | "group_lon": -122.69000244140625, 28 | "join_mode": "open", 29 | "urlname": "eLearningNetwork" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /spec/support/controller_helper.rb: -------------------------------------------------------------------------------- 1 | module ControllerHelper 2 | def default_url_options 3 | {} 4 | end 5 | 6 | def get(action, params: {}, **others) 7 | @request.host = ENV['TEST_REQ_HOST'] 8 | super(action, params: default_url_options.merge(params), **others) 9 | end 10 | 11 | def put(action, params: {}, **others) 12 | @request.host = ENV['TEST_REQ_HOST'] 13 | super(action, params: default_url_options.merge(params), **others) 14 | end 15 | 16 | def post(action, params: {}, **others) 17 | @request.host = ENV['TEST_REQ_HOST'] 18 | super(action, params: default_url_options.merge(params), **others) 19 | end 20 | 21 | def delete(action, params: {}, **others) 22 | @request.host = ENV['TEST_REQ_HOST'] 23 | super(action, params: default_url_options.merge(params), **others) 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /spec/support/shared_context.rb: -------------------------------------------------------------------------------- 1 | RSpec.shared_context "site" do 2 | let(:site) { Site.find_by_domain(ENV["TEST_REQ_HOST"]) } 3 | 4 | # Make sure the host used in requests matches our site 5 | before(:each, type: :request) do 6 | host! site.domain 7 | end 8 | 9 | end 10 | -------------------------------------------------------------------------------- /tmp/.do_not_delete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/tmp/.do_not_delete -------------------------------------------------------------------------------- /tmp/cache/.do_not_delete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/tmp/cache/.do_not_delete -------------------------------------------------------------------------------- /tmp/pids/.do_not_delete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/tmp/pids/.do_not_delete -------------------------------------------------------------------------------- /tmp/sessions/.do_not_delete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/tmp/sessions/.do_not_delete -------------------------------------------------------------------------------- /tmp/sockets/.do_not_delete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/tmp/sockets/.do_not_delete -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006 Chris Wanstrath 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'rake' 3 | 4 | version = '0.2.8' 5 | 6 | ENV['RUBY_FLAGS'] = "" 7 | 8 | begin 9 | require 'echoe' 10 | 11 | Echoe.new('mofo', version) do |p| 12 | p.rubyforge_name = 'mofo' 13 | p.summary = "mofo is a ruby microformat parser" 14 | p.description = "mofo is a ruby microformat parser" 15 | p.url = "http://mofo.rubyforge.org/" 16 | p.author = 'Chris Wanstrath' 17 | p.email = "chris@ozmm.org" 18 | p.extra_deps << ['hpricot', '>=0.4.59'] 19 | p.test_globs = 'test/*_test.rb' 20 | end 21 | 22 | rescue LoadError => boom 23 | puts "You are missing a dependency required for meta-operations on this gem." 24 | puts "#{boom.to_s.capitalize}." 25 | end 26 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/init.rb: -------------------------------------------------------------------------------- 1 | # Rails Plugin 2 | require 'mofo' 3 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/microformat/array.rb: -------------------------------------------------------------------------------- 1 | class Array 2 | def first_or_self 3 | size > 1 ? self : first 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/microformat/simple.rb: -------------------------------------------------------------------------------- 1 | require 'microformat' 2 | 3 | class Microformat 4 | class Simple < String 5 | extend Microformat::Base 6 | 7 | def self.find_first(doc) 8 | find_every(doc).first 9 | end 10 | 11 | def self.find_occurences(doc) 12 | @from ? doc/from_as_xpath : super(doc) 13 | end 14 | 15 | def self.build_class(tag) 16 | new(tag.text) 17 | end 18 | 19 | def self.from(options) 20 | @from ||= [] 21 | options.each do |tag, value| 22 | @from << "@#{tag}=#{value}" 23 | end 24 | end 25 | 26 | def self.from_as_xpath 27 | "[#{@from.to_a * "|"}]" 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/microformat/string.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/time' 2 | 3 | class String 4 | def coerce 5 | return true if self == 'true' 6 | return false if self == 'false' 7 | coerce_try { return Time.iso8601(self) } 8 | coerce_try { return Integer(self) } 9 | coerce_try { return Float(self) } 10 | self 11 | end 12 | 13 | def strip_html 14 | gsub(/<(?:[^>'"]*|(['"]).*?\1)*>/,'') 15 | end 16 | 17 | private 18 | 19 | def coerce_try 20 | yield 21 | rescue 22 | nil 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/microformat/time.rb: -------------------------------------------------------------------------------- 1 | require 'time' 2 | 3 | class Time 4 | ISO8601_REGEX = /^\d{4}-?\d{2}-?\d{2}(T\d{2}(:?\d{2}(:?\d{2}(\.?\d{2})?)?)?(Z|[+-]\d{2}(:?\d{2})?)?)?$/ 5 | 6 | def self.iso8601(a_string) 7 | raise ArgumentError unless a_string =~ ISO8601_REGEX 8 | 9 | Time.xmlschema(a_string) rescue Time.parse(a_string) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo.rb: -------------------------------------------------------------------------------- 1 | $:.unshift File.dirname(__FILE__) 2 | 3 | Dir["#{File.dirname(__FILE__)}/mofo/*.rb"].each { |format| require "mofo/#{File.basename format}" } 4 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/adr.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/adr 2 | require 'microformat' 3 | 4 | class Adr < Microformat 5 | one :post_office_box, :extended_address, :street_address, 6 | :locality, :region, :postal_code, :country_name, :value 7 | 8 | many :type 9 | end 10 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/geo.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/geo 2 | require 'microformat' 3 | 4 | class Geo < Microformat 5 | one :latitude, :longitude 6 | end 7 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/hcalendar.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/hcalendar 2 | require 'microformat' 3 | require 'mofo/hcard' 4 | require 'mofo/adr' 5 | require 'mofo/geo' 6 | 7 | class HCalendar < Microformat 8 | container :vevent 9 | 10 | one :class, :description, :dtend, :dtstamp, :dtstart, 11 | :duration, :status, :summary, :uid, :last_modified, 12 | :url => :url, :location => [ HCard, Adr, Geo, String ] 13 | 14 | many :category 15 | end 16 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/hcard.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/hcard 2 | require 'microformat' 3 | require 'mofo/geo' 4 | require 'mofo/adr' 5 | 6 | class HCard < Microformat 7 | container :vcard 8 | 9 | one :fn, :bday, :tz, :sort_string, :uid, :class, 10 | :geo => Geo 11 | 12 | many :label, :sound, :title, :role, :key, 13 | :mailer, :rev, :nickname, :category, :note, 14 | :logo => :url, :url => :url, :photo => :url, 15 | :adr => Adr 16 | 17 | one :n do 18 | one :family_name, :given_name, :additional_name 19 | many :honorific_prefix, :honorific_suffix 20 | end 21 | 22 | many :email do 23 | many :type 24 | many :value 25 | end 26 | 27 | many :tel do 28 | many :type 29 | many :value 30 | end 31 | 32 | many :org do 33 | one :organization_name, :organization_unit 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/hentry.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/hatom 2 | require 'microformat' 3 | require 'mofo/hcard' 4 | require 'mofo/rel_tag' 5 | 6 | class HEntry < Microformat 7 | one :entry_title, :entry_summary, :updated, :published, 8 | :author => HCard 9 | 10 | many :entry_content, :tags => RelTag 11 | 12 | after_find do 13 | @updated = @published unless @updated if @published 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/hfeed.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/hatom 2 | require 'mofo/hentry' 3 | 4 | class HFeed < Microformat 5 | many :hentry => HEntry 6 | end 7 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/hresume.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/hresume 2 | require 'microformat' 3 | require 'mofo/hcard' 4 | require 'mofo/hcalendar' 5 | require 'mofo/rel_tag' 6 | 7 | class HResume < Microformat 8 | container :hresume 9 | 10 | one :summary, :contact => HCard 11 | 12 | # TODO: linkedin uses a comma delimited skills list rather than the rel tags in the spec 13 | many :skills 14 | 15 | many :affiliation => HCard, :education => HCalendar, 16 | :experience => HCalendar 17 | end 18 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/hreview.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/hreview 2 | require 'microformat' 3 | require 'mofo/hcard' 4 | require 'mofo/rel_tag' 5 | 6 | class HReview < Microformat 7 | one :version, :summary, :type, :dtreviewed, :rating, :description 8 | 9 | one :reviewer => HCard 10 | 11 | one :item! do 12 | one :fn 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/rel_bookmark.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/rel-design-pattern 2 | require 'microformat/simple' 3 | 4 | class RelBookmark < Microformat::Simple 5 | from :rel => :bookmark 6 | end 7 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/lib/mofo/rel_tag.rb: -------------------------------------------------------------------------------- 1 | # => http://microformats.org/wiki/rel-design-pattern 2 | require 'microformat/simple' 3 | 4 | class RelTag < Microformat::Simple 5 | from :rel => :tag 6 | end 7 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/site/mofo-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/activate/ActivateHub/b165490bfe4e1ff81ca43363aee42943bef47e3b/vendor/gems/mofo-0.2.8/site/mofo-logo.png -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/base_url_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | require 'mofo/hreview' 3 | 4 | alias :real_open :open 5 | def open(input) 6 | input[/^http/] ? open(fixture(:corkd)) : real_open(input) 7 | end 8 | 9 | context "Grabbing an hReview from a URL" do 10 | setup do 11 | url = 'http://www.corkd.com/views/123' 12 | $url_hreview ||= HReview.find(:first => url) 13 | end 14 | 15 | specify "should add the base URL to all nested relative links" do 16 | $url_hreview.reviewer.url.should.equal 'http://www.corkd.com/people/simplebits' 17 | end 18 | 19 | specify "should not add the base URL to absolute links" do 20 | $url_hreview.reviewer.photo.should.equal 'http://flickr.com/img/icon-user-64.gif' 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/fixtures/event_addr.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

Bruce Cockburn

4 | 5 |
Tuesday, March 13, 2007
6 |
8:00 PM
7 | 8 |
9 |
Where
10 | 11 |
12 | 13 |
14 | 3210 Burton SE
15 | Grand Rapids, Michigan 16 |
17 | 18 | 22 | 23 |
24 | 25 |
Fine Arts Center
$8 w/ Calvin ID, $20 public
26 |
-------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/fixtures/fake.html: -------------------------------------------------------------------------------- 1 | fake. 2 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/fixtures/simple.html: -------------------------------------------------------------------------------- 1 |
2 | Chris Wanstrath 3 |
Err the Blog
4 | 5 |
6 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/hatom_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | require 'mofo/hentry' 3 | 4 | context "A parsed hEntry object" do 5 | setup do 6 | $hentry ||= HEntry.find(:first => fixture(:hatom)) 7 | end 8 | 9 | specify "should have a title" do 10 | $hentry.entry_title.should.equal "“A Rails Toolbox”" 11 | end 12 | 13 | specify "should have an author string " do 14 | $hentry.author.should.be.an.instance_of HCard 15 | $hentry.author.fn.should.equal "Chris" 16 | end 17 | 18 | specify "should have content" do 19 | $hentry.entry_content.should.be.an.instance_of String 20 | end 21 | 22 | specify "should have an attached published date object" do 23 | $hentry.published.should.be.an.instance_of Time 24 | end 25 | 26 | specify "should have an inferred updated attribute which references the published date object" do 27 | $hentry.updated.should.be.an.instance_of Time 28 | $hentry.updated.should.be $hentry.published 29 | end 30 | 31 | specify "should have a bookmark (permalink)" do 32 | $hentry.bookmark.should.equal "/post/13" 33 | end 34 | 35 | specify "should have an array of tags" do 36 | $hentry.tags.should.be.an.instance_of Array 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/hcalendar_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | require 'mofo/hcalendar' 3 | 4 | context "A parsed hCalendar object with an embedded hCard" do 5 | setup do 6 | $hcalendar_hcard ||= HCalendar.find(:first => fixture(:upcoming_single)) 7 | end 8 | 9 | specify "should have an HCard for its location" do 10 | $hcalendar_hcard.location.should.be.an.instance_of HCard 11 | end 12 | end 13 | 14 | context "A parsed hCalendar object with embedded adr" do 15 | setup do 16 | $hcalendar_addr ||= HCalendar.find(:first => fixture(:event_addr)) 17 | end 18 | 19 | specify "should have an Adr for its location" do 20 | $hcalendar_addr.location.should.be.an.instance_of Adr 21 | end 22 | end 23 | 24 | context "A parsed hCalendar object with string location" do 25 | setup do 26 | $hcalendar_string ||= HCalendar.find(:first => fixture(:upcoming)) 27 | end 28 | 29 | specify "should have a string for its location" do 30 | $hcalendar_string.location.should.be.an.instance_of String 31 | $hcalendar_string.location.should.not.be.empty 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/hresume_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | require 'mofo/hresume' 3 | 4 | context "A parsed hResume object" do 5 | setup do 6 | $hresume ||= HResume.find(:first => fixture(:hresume)) 7 | end 8 | 9 | fields = { 10 | :contact => HCard, 11 | :education => HCalendar, 12 | :experience => Array, 13 | :summary => String, 14 | :skills => String 15 | } 16 | 17 | fields.each do |field, klass| 18 | specify "should have an #{klass} for #{field}" do 19 | $hresume.send(field).should.not.be.nil 20 | $hresume.send(field).should.be.an.instance_of klass 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/include_pattern_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | require 'mofo/hcard' 3 | 4 | context "Multiple attributes within a container" do 5 | setup do 6 | $hcards ||= HCard.find(:all => fixture(:hresume)) 7 | $included ||= $hcards.first 8 | $including ||= $hcards[1] 9 | end 10 | 11 | specify "should be referenceable by a microformat using the include pattern" do 12 | %w(fn n).each do |att| 13 | $including.send(att).should.equal $included.send(att) 14 | end 15 | end 16 | end 17 | 18 | context "A single attribute" do 19 | setup do 20 | $horsed ||= HCard.find(:first => fixture(:include_pattern_single_attribute)) 21 | end 22 | 23 | specify "should be referenceable by a microformat using the include pattern" do 24 | $horsed.logo.should.not.be.nil 25 | $horsed.logo.should.equal Hpricot(open(fixture(:include_pattern_single_attribute))).at("#logo").attributes['src'] 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/reltag_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | require 'mofo/rel_tag' 3 | 4 | context "An array of reltag arrays created from the corkd review webpage" do 5 | setup do 6 | $tags ||= RelTag.find(:all => fixture(:corkd)) 7 | end 8 | 9 | specify "should consist of 23 tags" do 10 | $tags.size.should.equal 23 11 | end 12 | 13 | specify "should include the berry and slippery tags" do 14 | $tags.flatten.should.include 'berry' 15 | $tags.flatten.should.include 'slippery' 16 | end 17 | end 18 | 19 | context "A web page with three rel tags" do 20 | setup do 21 | $page ||= <<-EOF 22 | 23 | 24 | 29 | 30 | 31 | EOF 32 | end 33 | 34 | specify "should produce an array of three RelTag objects" do 35 | tags = RelTag.find(:all, :text => $page) 36 | tags.should.be.an.instance_of Array 37 | tags.size.should.equal 3 38 | tags.should.equal ["miracle", "wonder", "amusement"] 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/subclass_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/test_helper' 2 | require 'mofo/hcard' 3 | 4 | module Formats 5 | class Card < HCard 6 | end 7 | end 8 | 9 | context "Subclassing an hCard" do 10 | specify "should parse a page with an hcard" do 11 | proc { Formats::Card.find(fixture(:fauxtank)) }.should.not.raise MicroformatNotFound 12 | end 13 | 14 | specify "should raise an error if no hcard is found in strict mode" do 15 | proc { Formats::Card.find(fixture(:fake), :strict => true) }.should.raise MicroformatNotFound 16 | end 17 | 18 | specify "should return an empty array if no hcard is found" do 19 | Formats::Card.find(fixture(:fake)).should.equal [] 20 | end 21 | 22 | specify "should return nil if no hcard is found with :first" do 23 | Formats::Card.find(:first => fixture(:fake)).should.equal nil 24 | end 25 | 26 | specify "should return nil if no hcard is found with :all" do 27 | Formats::Card.find(:all => fixture(:fake)).should.equal [] 28 | end 29 | 30 | specify "should accept a :text option" do 31 | Formats::Card.find(:text => open(fixture(:fauxtank)).read).should.not.equal [] 32 | Formats::Card.find(:text => open(fixture(:fauxtank)).read).should.not.equal nil 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /vendor/gems/mofo-0.2.8/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $:.unshift 'lib/', File.dirname(__FILE__) + '/../lib' 2 | 3 | require 'rubygems' 4 | 5 | try = proc do |library, version| 6 | begin 7 | dashed = library.gsub('/','-') 8 | require library 9 | gem dashed, version 10 | rescue LoadError 11 | puts "=> You need the #{library} gem to run these tests.", 12 | "=> $ sudo gem install #{dashed}" 13 | exit 14 | end 15 | end 16 | 17 | try['test/spec', '>= 0.3'] 18 | try['mocha', '>= 0.4'] 19 | 20 | begin require 'redgreen'; rescue LoadError; nil end 21 | 22 | def fixture(name) 23 | File.dirname(__FILE__) + "/fixtures/#{name}.html" 24 | end 25 | --------------------------------------------------------------------------------