calagator 0.0.1.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +23 -0
  3. data/README.md +75 -0
  4. data/Rakefile +12 -0
  5. data/app/assets/images/confused-alligator-sm.png +0 -0
  6. data/app/assets/images/disk.png +0 -0
  7. data/app/assets/images/edit.png +0 -0
  8. data/app/assets/images/external_sites/epdx.png +0 -0
  9. data/app/assets/images/external_sites/external.gif +0 -0
  10. data/app/assets/images/external_sites/facebook.png +0 -0
  11. data/app/assets/images/external_sites/foursquare.png +0 -0
  12. data/app/assets/images/external_sites/gowalla.png +0 -0
  13. data/app/assets/images/external_sites/lanyrd.png +0 -0
  14. data/app/assets/images/external_sites/meetup.png +0 -0
  15. data/app/assets/images/external_sites/plancast.png +0 -0
  16. data/app/assets/images/external_sites/shizzow.png +0 -0
  17. data/app/assets/images/external_sites/upcoming.png +0 -0
  18. data/app/assets/images/external_sites/yelp.png +0 -0
  19. data/app/assets/images/feed.png +0 -0
  20. data/app/assets/images/heart.png +0 -0
  21. data/app/assets/images/icon_ical.gif +0 -0
  22. data/app/assets/images/information.png +0 -0
  23. data/app/assets/images/nav_marker.gif +0 -0
  24. data/app/assets/images/nav_marker.png +0 -0
  25. data/app/assets/images/plus.png +0 -0
  26. data/app/assets/images/redx.png +0 -0
  27. data/app/assets/images/site-icon.png +0 -0
  28. data/app/assets/images/spinner.gif +0 -0
  29. data/app/assets/images/star.png +0 -0
  30. data/app/assets/images/subnav_marker.gif +0 -0
  31. data/app/assets/images/subnav_marker.png +0 -0
  32. data/app/assets/images/tag_blue.png +0 -0
  33. data/app/assets/images/tag_icons/angular.png +0 -0
  34. data/app/assets/images/tag_icons/beer.png +0 -0
  35. data/app/assets/images/tag_icons/bitcoin.png +0 -0
  36. data/app/assets/images/tag_icons/free.png +0 -0
  37. data/app/assets/images/tag_icons/golang.png +0 -0
  38. data/app/assets/images/tag_icons/html.png +0 -0
  39. data/app/assets/images/tag_icons/javascript.png +0 -0
  40. data/app/assets/images/tag_icons/linux.png +0 -0
  41. data/app/assets/images/tag_icons/php.png +0 -0
  42. data/app/assets/images/tag_icons/pizza.png +0 -0
  43. data/app/assets/images/tag_icons/python.png +0 -0
  44. data/app/assets/images/tag_icons/rails.png +0 -0
  45. data/app/assets/images/tag_icons/ruby.png +0 -0
  46. data/app/assets/images/tag_icons/sass.png +0 -0
  47. data/app/assets/images/tag_icons/swift.png +0 -0
  48. data/app/assets/images/transmit_blue.png +0 -0
  49. data/app/assets/images/weekday_background.gif +0 -0
  50. data/app/assets/javascripts/calagator.js +18 -0
  51. data/app/assets/javascripts/calagator/forms.js +60 -0
  52. data/app/assets/stylesheets/calagator.scss +8 -0
  53. data/app/assets/stylesheets/calagator/common.scss +14 -0
  54. data/app/assets/stylesheets/calagator/datepicker.scss +177 -0
  55. data/app/assets/stylesheets/calagator/errors.css +110 -0
  56. data/app/assets/stylesheets/calagator/forms.scss +4 -0
  57. data/app/assets/stylesheets/calagator/reset.css +40 -0
  58. data/app/assets/stylesheets/calagator/theme.css +0 -0
  59. data/app/controllers/calagator/admin_controller.rb +27 -0
  60. data/app/controllers/calagator/application_controller.rb +82 -0
  61. data/app/controllers/calagator/events_controller.rb +171 -0
  62. data/app/controllers/calagator/site_controller.rb +35 -0
  63. data/app/controllers/calagator/sources_controller.rb +94 -0
  64. data/app/controllers/calagator/venues_controller.rb +133 -0
  65. data/app/controllers/calagator/versions_controller.rb +20 -0
  66. data/app/helpers/calagator/application_helper.rb +128 -0
  67. data/app/helpers/calagator/events_helper.rb +184 -0
  68. data/app/helpers/calagator/google_event_export_helper.rb +67 -0
  69. data/app/helpers/calagator/mapping_helper.rb +103 -0
  70. data/app/helpers/calagator/sources_helper.rb +10 -0
  71. data/app/helpers/calagator/tags_helper.rb +42 -0
  72. data/app/helpers/calagator/time_range_helper.rb +166 -0
  73. data/app/models/calagator/event.rb +246 -0
  74. data/app/models/calagator/event/cloner.rb +39 -0
  75. data/app/models/calagator/event/ical_renderer.rb +155 -0
  76. data/app/models/calagator/event/overview.rb +45 -0
  77. data/app/models/calagator/event/saver.rb +58 -0
  78. data/app/models/calagator/event/search.rb +72 -0
  79. data/app/models/calagator/event/search_engine.rb +28 -0
  80. data/app/models/calagator/event/search_engine/apache_sunspot.rb +106 -0
  81. data/app/models/calagator/event/search_engine/sql.rb +107 -0
  82. data/app/models/calagator/source.rb +115 -0
  83. data/app/models/calagator/source/importer.rb +46 -0
  84. data/app/models/calagator/source/parser.rb +128 -0
  85. data/app/models/calagator/source/parser/facebook.rb +67 -0
  86. data/app/models/calagator/source/parser/hcal.rb +108 -0
  87. data/app/models/calagator/source/parser/http_authentication_required_error.rb +6 -0
  88. data/app/models/calagator/source/parser/ical.rb +186 -0
  89. data/app/models/calagator/source/parser/meetup.rb +72 -0
  90. data/app/models/calagator/source/parser/not_found.rb +9 -0
  91. data/app/models/calagator/source/parser/plancast.rb +59 -0
  92. data/app/models/calagator/venue.rb +161 -0
  93. data/app/models/calagator/venue/geocoder.rb +51 -0
  94. data/app/models/calagator/venue/search.rb +63 -0
  95. data/app/models/calagator/venue/search_engine.rb +24 -0
  96. data/app/models/calagator/venue/search_engine/apache_sunspot.rb +85 -0
  97. data/app/models/calagator/venue/search_engine/sql.rb +68 -0
  98. data/app/models/event/search_engine/base.rb +0 -0
  99. data/app/observers/calagator/cache_observer.rb +37 -0
  100. data/app/views/calagator/admin/events.html.erb +28 -0
  101. data/app/views/calagator/admin/index.html.erb +8 -0
  102. data/app/views/calagator/events/_feed_item.html.erb +62 -0
  103. data/app/views/calagator/events/_form.html.erb +63 -0
  104. data/app/views/calagator/events/_gcal_reminder.html.erb +1 -0
  105. data/app/views/calagator/events/_hcal.html.erb +41 -0
  106. data/app/views/calagator/events/_item.html.erb +120 -0
  107. data/app/views/calagator/events/_list.html.erb +30 -0
  108. data/app/views/calagator/events/_list_item.html.erb +37 -0
  109. data/app/views/calagator/events/_search_section.html.erb +15 -0
  110. data/app/views/calagator/events/_subnav.html.erb +13 -0
  111. data/app/views/calagator/events/_table.html.erb +74 -0
  112. data/app/views/calagator/events/duplicates.html.erb +58 -0
  113. data/app/views/calagator/events/edit.html.erb +3 -0
  114. data/app/views/calagator/events/index.atom.builder +32 -0
  115. data/app/views/calagator/events/index.html.erb +51 -0
  116. data/app/views/calagator/events/index.kml.erb +20 -0
  117. data/app/views/calagator/events/new.html.erb +7 -0
  118. data/app/views/calagator/events/search.html.erb +25 -0
  119. data/app/views/calagator/events/show.html.erb +81 -0
  120. data/app/views/calagator/site/_appropriateness_message.html.erb +15 -0
  121. data/app/views/calagator/site/_description.html.erb +3 -0
  122. data/app/views/calagator/site/about.html.erb +7 -0
  123. data/app/views/calagator/site/defunct.html.erb +15 -0
  124. data/app/views/calagator/site/export.html.erb +4 -0
  125. data/app/views/calagator/site/index.html.erb +40 -0
  126. data/app/views/calagator/site/opensearch.xml.builder +8 -0
  127. data/app/views/calagator/sources/_subnav.html.erb +0 -0
  128. data/app/views/calagator/sources/edit.html.erb +12 -0
  129. data/app/views/calagator/sources/import.html.erb +10 -0
  130. data/app/views/calagator/sources/index.html.erb +22 -0
  131. data/app/views/calagator/sources/new.html.erb +32 -0
  132. data/app/views/calagator/sources/show.html.erb +16 -0
  133. data/app/views/calagator/venues/_form.html.erb +57 -0
  134. data/app/views/calagator/venues/_subnav.html.erb +10 -0
  135. data/app/views/calagator/venues/duplicates.html.erb +65 -0
  136. data/app/views/calagator/venues/edit.html.erb +3 -0
  137. data/app/views/calagator/venues/index.html.erb +93 -0
  138. data/app/views/calagator/venues/index.kml.erb +15 -0
  139. data/app/views/calagator/venues/map.html.erb +4 -0
  140. data/app/views/calagator/venues/new.html.erb +5 -0
  141. data/app/views/calagator/venues/show.html.erb +113 -0
  142. data/app/views/calagator/versions/_chooser.html.erb +28 -0
  143. data/app/views/calagator/versions/_edit_with_chooser.html.erb +16 -0
  144. data/app/views/layouts/calagator/application.html.erb +110 -0
  145. data/config/deploy/local.rb +37 -0
  146. data/config/deploy/lucca.rb +33 -0
  147. data/config/initializers/dates.rb +7 -0
  148. data/config/initializers/formtastic.rb +82 -0
  149. data/config/initializers/geokit.rb +74 -0
  150. data/config/initializers/ics_renderer.rb +6 -0
  151. data/config/initializers/load_tag_model_extensions.rb +3 -0
  152. data/config/initializers/mime_types.rb +9 -0
  153. data/config/initializers/observers.rb +1 -0
  154. data/config/initializers/search_engine.rb +4 -0
  155. data/config/initializers/set_default_url_host.rb +5 -0
  156. data/config/initializers/time_get_zone.rb +8 -0
  157. data/config/locales/en.yml +5 -0
  158. data/config/routes.rb +55 -0
  159. data/config/secrets.yml.blag +75 -0
  160. data/config/sunspot.yml +23 -0
  161. data/db/development.sqlite3 +0 -0
  162. data/db/development.sqlite3.bak +0 -0
  163. data/db/development.sqlite3.old +0 -0
  164. data/db/development~20111112@110950.sqlite3 +0 -0
  165. data/db/migrate/001_create_events.rb +17 -0
  166. data/db/migrate/002_create_venues.rb +17 -0
  167. data/db/migrate/003_create_sources.rb +16 -0
  168. data/db/migrate/004_add_detailed_fields_to_venue.rb +19 -0
  169. data/db/migrate/005_add_end_time_to_events.rb +9 -0
  170. data/db/migrate/006_add_source_id_to_events.rb +9 -0
  171. data/db/migrate/008_add_source_id_to_venues.rb +10 -0
  172. data/db/migrate/009_add_duplicate_of_column_to_venues.rb +9 -0
  173. data/db/migrate/010_add_duplicate_of_column_to_events.rb +9 -0
  174. data/db/migrate/011_change_lat_long_type.rb +12 -0
  175. data/db/migrate/012_add_source_reimport.rb +9 -0
  176. data/db/migrate/013_change_end_time_to_duration.rb +11 -0
  177. data/db/migrate/014_remove_format_type_from_source.rb +9 -0
  178. data/db/migrate/015_create_updates.rb +15 -0
  179. data/db/migrate/016_remove_next_update_from_source.rb +9 -0
  180. data/db/migrate/20080705163959_change_duration_to_end_time.rb +11 -0
  181. data/db/migrate/20080705164959_create_tags_and_taggings.rb +28 -0
  182. data/db/migrate/20081011181519_create_versioned_events.rb +25 -0
  183. data/db/migrate/20081011193124_create_versioned_venues.rb +32 -0
  184. data/db/migrate/20081115190515_add_rrule_to_events.rb +15 -0
  185. data/db/migrate/20090912082129_create_versions.rb +18 -0
  186. data/db/migrate/20110219205156_add_closed_flag_to_venues.rb +9 -0
  187. data/db/migrate/20110220001008_add_wifi_flag_to_venues.rb +9 -0
  188. data/db/migrate/20110220011427_add_access_notes_to_venues.rb +9 -0
  189. data/db/migrate/20110220031117_add_events_count_to_venues.rb +8 -0
  190. data/db/migrate/20110604174521_add_venue_details_to_events.rb +9 -0
  191. data/db/migrate/20110717231316_acts_as_taggable_on_migration.rb +50 -0
  192. data/db/migrate/20120709092821_cleanup.rb +14 -0
  193. data/db/migrate/20120831234448_specify_venues_latitude_and_longitude_precision.rb +11 -0
  194. data/db/migrate/20150206085809_remove_updates.rb +13 -0
  195. data/db/migrate/20150207231355_add_locked_status_to_events.rb +5 -0
  196. data/db/production.sqlite3 +0 -0
  197. data/db/schema.rb +102 -0
  198. data/db/seeds.rb +16 -0
  199. data/db/test.sqlite3 +0 -0
  200. data/db/test2.sqlite3 +0 -0
  201. data/lib/calagator.rb +30 -0
  202. data/lib/calagator/blacklist_validator.rb +69 -0
  203. data/lib/calagator/decode_html_entities_hack.rb +33 -0
  204. data/lib/calagator/duplicate_checking.rb +133 -0
  205. data/lib/calagator/duplicate_checking/controller_actions.rb +38 -0
  206. data/lib/calagator/duplicate_checking/duplicate_finder.rb +83 -0
  207. data/lib/calagator/duplicate_checking/duplicate_squasher.rb +74 -0
  208. data/lib/calagator/engine.rb +30 -0
  209. data/lib/calagator/strip_whitespace.rb +19 -0
  210. data/lib/calagator/tag_model_extensions.rb +104 -0
  211. data/lib/calagator/url_prefixer.rb +9 -0
  212. data/lib/calagator/version.rb +3 -0
  213. data/lib/generators/calagator/install_generator.rb +39 -0
  214. data/lib/generators/calagator/templates/config/calagator.rb +26 -0
  215. data/lib/generators/calagator/templates/config/secrets.yml.sample +83 -0
  216. data/lib/secrets_reader.rb +76 -0
  217. data/lib/tasks/spec_db.rake +53 -0
  218. data/lib/tasks/sunspot_reindex_calagator.rake +6 -0
  219. data/lib/tasks/sunspot_solr_restart_enhancements.rake +19 -0
  220. data/lib/tasks/update_counter_caches.rake +13 -0
  221. data/lib/templates/erb/scaffold/_form.html.erb +11 -0
  222. data/lib/theme_reader.rb +17 -0
  223. data/lib/wait_for_solr.rb +25 -0
  224. data/spec/controllers/calagator/application_controller_spec.rb +47 -0
  225. data/spec/controllers/calagator/events_controller_spec.rb +794 -0
  226. data/spec/controllers/calagator/site_controller_spec.rb +59 -0
  227. data/spec/controllers/calagator/sources_controller_spec.rb +439 -0
  228. data/spec/controllers/calagator/venues_controller_spec.rb +319 -0
  229. data/spec/controllers/calagator/versions_controller_spec.rb +82 -0
  230. data/spec/controllers/squash_many_duplicates_examples.rb +49 -0
  231. data/spec/dummy/Gemfile +39 -0
  232. data/spec/dummy/Gemfile.lock +195 -0
  233. data/spec/dummy/README.rdoc +261 -0
  234. data/spec/dummy/Rakefile +7 -0
  235. data/spec/dummy/app/assets/images/rails.png +0 -0
  236. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  237. data/spec/dummy/app/assets/stylesheets/application.css +14 -0
  238. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  239. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  240. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  241. data/spec/dummy/config.ru +4 -0
  242. data/spec/dummy/config/application.rb +62 -0
  243. data/spec/dummy/config/boot.rb +6 -0
  244. data/spec/dummy/config/database.yml +25 -0
  245. data/spec/dummy/config/environment.rb +5 -0
  246. data/spec/dummy/config/environments/development.rb +37 -0
  247. data/spec/dummy/config/environments/production.rb +67 -0
  248. data/spec/dummy/config/environments/test.rb +37 -0
  249. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  250. data/spec/dummy/config/initializers/calagator.rb +26 -0
  251. data/spec/dummy/config/initializers/inflections.rb +15 -0
  252. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  253. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  254. data/spec/dummy/config/initializers/session_store.rb +8 -0
  255. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  256. data/spec/dummy/config/locales/en.yml +5 -0
  257. data/spec/dummy/config/routes.rb +59 -0
  258. data/spec/dummy/config/secrets.yml +83 -0
  259. data/spec/dummy/db/development.sqlite3 +0 -0
  260. data/spec/dummy/db/migrate/20150309023304_create_events.calagator.rb +18 -0
  261. data/spec/dummy/db/migrate/20150309023305_create_venues.calagator.rb +18 -0
  262. data/spec/dummy/db/migrate/20150309023306_create_sources.calagator.rb +17 -0
  263. data/spec/dummy/db/migrate/20150309023307_add_detailed_fields_to_venue.calagator.rb +20 -0
  264. data/spec/dummy/db/migrate/20150309023308_add_end_time_to_events.calagator.rb +10 -0
  265. data/spec/dummy/db/migrate/20150309023309_add_source_id_to_events.calagator.rb +10 -0
  266. data/spec/dummy/db/migrate/20150309023310_add_source_id_to_venues.calagator.rb +11 -0
  267. data/spec/dummy/db/migrate/20150309023311_add_duplicate_of_column_to_venues.calagator.rb +10 -0
  268. data/spec/dummy/db/migrate/20150309023312_add_duplicate_of_column_to_events.calagator.rb +10 -0
  269. data/spec/dummy/db/migrate/20150309023313_change_lat_long_type.calagator.rb +13 -0
  270. data/spec/dummy/db/migrate/20150309023314_add_source_reimport.calagator.rb +10 -0
  271. data/spec/dummy/db/migrate/20150309023315_change_end_time_to_duration.calagator.rb +12 -0
  272. data/spec/dummy/db/migrate/20150309023316_remove_format_type_from_source.calagator.rb +10 -0
  273. data/spec/dummy/db/migrate/20150309023317_create_updates.calagator.rb +16 -0
  274. data/spec/dummy/db/migrate/20150309023318_remove_next_update_from_source.calagator.rb +10 -0
  275. data/spec/dummy/db/migrate/20150309023319_change_duration_to_end_time.calagator.rb +12 -0
  276. data/spec/dummy/db/migrate/20150309023320_create_tags_and_taggings.calagator.rb +29 -0
  277. data/spec/dummy/db/migrate/20150309023321_create_versioned_events.calagator.rb +26 -0
  278. data/spec/dummy/db/migrate/20150309023322_create_versioned_venues.calagator.rb +33 -0
  279. data/spec/dummy/db/migrate/20150309023323_add_rrule_to_events.calagator.rb +16 -0
  280. data/spec/dummy/db/migrate/20150309023324_create_versions.calagator.rb +19 -0
  281. data/spec/dummy/db/migrate/20150309023325_add_closed_flag_to_venues.calagator.rb +10 -0
  282. data/spec/dummy/db/migrate/20150309023326_add_wifi_flag_to_venues.calagator.rb +10 -0
  283. data/spec/dummy/db/migrate/20150309023327_add_access_notes_to_venues.calagator.rb +10 -0
  284. data/spec/dummy/db/migrate/20150309023328_add_events_count_to_venues.calagator.rb +9 -0
  285. data/spec/dummy/db/migrate/20150309023329_add_venue_details_to_events.calagator.rb +10 -0
  286. data/spec/dummy/db/migrate/20150309023330_acts_as_taggable_on_migration.calagator.rb +51 -0
  287. data/spec/dummy/db/migrate/20150309023331_cleanup.calagator.rb +15 -0
  288. data/spec/dummy/db/migrate/20150309023332_specify_venues_latitude_and_longitude_precision.calagator.rb +12 -0
  289. data/spec/dummy/db/migrate/20150309023333_remove_updates.calagator.rb +14 -0
  290. data/spec/dummy/db/migrate/20150309023334_add_locked_status_to_events.calagator.rb +6 -0
  291. data/spec/dummy/db/schema.rb +95 -0
  292. data/spec/dummy/db/seeds.rb +7 -0
  293. data/spec/dummy/db/test.sqlite3 +0 -0
  294. data/spec/dummy/doc/README_FOR_APP +2 -0
  295. data/spec/dummy/log/development.log +273 -0
  296. data/spec/dummy/public/404.html +26 -0
  297. data/spec/dummy/public/422.html +26 -0
  298. data/spec/dummy/public/500.html +25 -0
  299. data/spec/dummy/public/favicon.ico +0 -0
  300. data/spec/dummy/public/robots.txt +5 -0
  301. data/spec/dummy/script/rails +6 -0
  302. data/spec/dummy/test/performance/browsing_test.rb +12 -0
  303. data/spec/dummy/test/test_helper.rb +13 -0
  304. data/spec/factories.rb +93 -0
  305. data/spec/features/add_event_spec.rb +99 -0
  306. data/spec/features/add_venue_spec.rb +34 -0
  307. data/spec/features/admin_auth_spec.rb +22 -0
  308. data/spec/features/admin_lock_event_spec.rb +41 -0
  309. data/spec/features/import_events_from_feed_spec.rb +43 -0
  310. data/spec/features/managing_event_spec.rb +111 -0
  311. data/spec/features/managing_venue_spec.rb +71 -0
  312. data/spec/features/search_event_spec.rb +27 -0
  313. data/spec/helpers/calagator/application_helper_spec.rb +82 -0
  314. data/spec/helpers/calagator/events_helper_spec.rb +172 -0
  315. data/spec/helpers/calagator/google_event_export_helper_spec.rb +70 -0
  316. data/spec/helpers/calagator/sources_helper_spec.rb +12 -0
  317. data/spec/helpers/calagator/tags_helper_spec.rb +85 -0
  318. data/spec/helpers/calagator/time_range_helper_spec.rb +59 -0
  319. data/spec/lib/calagator/blacklist_validator_spec.rb +65 -0
  320. data/spec/lib/calagator/decode_html_entities_hack_spec.rb +54 -0
  321. data/spec/lib/calagator/settings_spec.rb +20 -0
  322. data/spec/lib/calagator/url_prefixer_spec.rb +33 -0
  323. data/spec/lib/secrets_reader_spec.rb +65 -0
  324. data/spec/models/calagator/event/cloner_spec.rb +43 -0
  325. data/spec/models/calagator/event/overview_spec.rb +79 -0
  326. data/spec/models/calagator/event/search_spec.rb +103 -0
  327. data/spec/models/calagator/event_search_spec.rb +149 -0
  328. data/spec/models/calagator/event_spec.rb +859 -0
  329. data/spec/models/calagator/source/parser_facebook_spec.rb +73 -0
  330. data/spec/models/calagator/source/parser_hcal_spec.rb +69 -0
  331. data/spec/models/calagator/source/parser_ical_non_standard_spec.rb +91 -0
  332. data/spec/models/calagator/source/parser_ical_spec.rb +322 -0
  333. data/spec/models/calagator/source/parser_meetup_spec.rb +69 -0
  334. data/spec/models/calagator/source/parser_plancast_spec.rb +53 -0
  335. data/spec/models/calagator/source/parser_spec.rb +238 -0
  336. data/spec/models/calagator/source_spec.rb +135 -0
  337. data/spec/models/calagator/venue/search_spec.rb +92 -0
  338. data/spec/models/calagator/venue_search_spec.rb +124 -0
  339. data/spec/models/calagator/venue_spec.rb +346 -0
  340. data/spec/models/tag_spec.rb +35 -0
  341. data/spec/rails_helper.rb +39 -0
  342. data/spec/spec_helper.rb +140 -0
  343. data/spec/support/disable_geocoding.rb +1 -0
  344. data/spec/support/http_samples.rb +5 -0
  345. data/spec/support/samples/facebook.json +23 -0
  346. data/spec/support/samples/hcal_basic.xml +6 -0
  347. data/spec/support/samples/hcal_dup_event_dup_venue.xml +13 -0
  348. data/spec/support/samples/hcal_event_duplicates_fixture.xml +13 -0
  349. data/spec/support/samples/hcal_event_wo_lat_and_long.xml +14 -0
  350. data/spec/support/samples/hcal_multiple.xml +16 -0
  351. data/spec/support/samples/hcal_same_event_twice_with_different_venues.xml +12 -0
  352. data/spec/support/samples/hcal_single.xml +8 -0
  353. data/spec/support/samples/hcal_two_identical_events.xml +14 -0
  354. data/spec/support/samples/hcal_upcoming_v1.html +412 -0
  355. data/spec/support/samples/hcal_upcoming_v2.html +749 -0
  356. data/spec/support/samples/hcal_upcoming_v3.html +685 -0
  357. data/spec/support/samples/hcal_upcoming_v4.html +761 -0
  358. data/spec/support/samples/ical_apple.ics +22 -0
  359. data/spec/support/samples/ical_apple_v3.ics +37 -0
  360. data/spec/support/samples/ical_basic.ics +15 -0
  361. data/spec/support/samples/ical_basic_with_duration.ics +16 -0
  362. data/spec/support/samples/ical_event_with_squashed_venue.ics +12 -0
  363. data/spec/support/samples/ical_eventful_many.ics +504 -0
  364. data/spec/support/samples/ical_gmt.ics +12 -0
  365. data/spec/support/samples/ical_google.ics +786 -0
  366. data/spec/support/samples/ical_multiple_calendars.ics +111 -0
  367. data/spec/support/samples/ical_upcoming.ics +36 -0
  368. data/spec/support/samples/ical_upcoming_many.ics +682 -0
  369. data/spec/support/samples/ical_upcoming_v2.ics +43 -0
  370. data/spec/support/samples/ical_z.ics +10 -0
  371. data/spec/support/samples/meetup.ics +16 -0
  372. data/spec/support/samples/meetup.json +31 -0
  373. data/spec/support/samples/plancast.ics +59 -0
  374. data/spec/support/samples/plancast.json +51 -0
  375. data/spec/support/samples/plancast_with_missing_venue.json +39 -0
  376. data/spec/support/samples/upcoming_v1.xml +8 -0
  377. data/spec/support/samples/upcoming_v2_with_invalid_utc_dates.xml +8 -0
  378. data/spec/support/time_convenience_methods.rb +8 -0
  379. data/spec/support/time_zones.rb +12 -0
  380. data/spec/support/url_helpers.rb +5 -0
  381. data/spec/support/wait_for_ajax.rb +15 -0
  382. data/spec/support/webmock.rb +8 -0
  383. data/spec/travis_spec.rb +7 -0
  384. metadata +1194 -0
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActsAsTaggableOn::Tag, :type => :model do
4
+ describe "handling machine tags" do
5
+ before do
6
+ @valid_machine_tag = ActsAsTaggableOn::Tag.new(:name => 'meetup:group=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 'meetup'
15
+ expect(@valid_machine_tag.machine_tag[:predicate]).to eq 'group'
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://www.meetup.com/1234"
21
+ end
22
+
23
+ it "should redirect to 'defunct' page with archive url as query param" do
24
+ @event = FactoryGirl.create :event, tag_list: 'upcoming:event=1234'
25
+ event_date = @event.start_time.strftime("%Y%m%d")
26
+ expect(@event.tags.last.machine_tag[:url]).to eq "http://localhost:3000/defunct?url=https://web.archive.org/web/#{event_date}/http://upcoming.yahoo.com/event/1234"
27
+ end
28
+
29
+ it "should redirect correctly for venue tags also" do
30
+ @venue = FactoryGirl.create :venue, tag_list: 'upcoming:venue=1234'
31
+ venue_date = @venue.created_at.strftime("%Y%m%d")
32
+ expect(@venue.tags.last.machine_tag[:url]).to eq "http://localhost:3000/defunct?url=https://web.archive.org/web/#{venue_date}/http://upcoming.yahoo.com/venue/1234"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require 'spec_helper'
4
+ require File.expand_path("../dummy/config/environment", __FILE__)
5
+ require 'rspec/rails'
6
+
7
+ # Requires supporting ruby files with custom matchers and macros, etc, in
8
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
9
+ # run as spec files by default. This means that files in spec/support that end
10
+ # in _spec.rb will both be required and run as specs, causing the specs to be
11
+ # run twice. It is recommended that you do not name files matching this glob to
12
+ # end with _spec.rb. You can configure this pattern with with the --pattern
13
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
14
+ Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
15
+
16
+ RSpec.configure do |config|
17
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
18
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
19
+
20
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
21
+ # examples within a transaction, remove the following line or assign false
22
+ # instead of true.
23
+ config.use_transactional_fixtures = true
24
+
25
+ # RSpec Rails can automatically mix in different behaviours to your tests
26
+ # based on their file location, for example enabling you to call `get` and
27
+ # `post` in specs under `spec/controllers`.
28
+ #
29
+ # You can disable this behaviour by removing the line below, and instead
30
+ # explicitly tag your specs with their type, e.g.:
31
+ #
32
+ # RSpec.describe UsersController, :type => :controller do
33
+ # # ...
34
+ # end
35
+ #
36
+ # The different available types are documented in the features, such as in
37
+ # https://relishapp.com/rspec/rspec-rails/docs
38
+ config.infer_spec_type_from_file_location!
39
+ end
@@ -0,0 +1,140 @@
1
+ if !File.exist?("spec/dummy")
2
+ raise "Missing dummy app in spec/dummy! Run bin/calagator new spec/dummy to generate one."
3
+ end
4
+
5
+ unless RUBY_ENGINE == "rbx" # SimpleCov slows down Rubinius dramatically (using rbx 2.2.6)
6
+ require 'simplecov'
7
+ require 'coveralls'
8
+
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ Coveralls::SimpleCov::Formatter,
12
+ ]
13
+ SimpleCov.start('rails')
14
+ end
15
+
16
+ require "rails_helper"
17
+ require "rspec-activemodel-mocks"
18
+ require "rspec/its"
19
+ require "rspec-rails"
20
+ require "rspec/collection_matchers"
21
+ require "factory_girl_rails"
22
+ require "capybara"
23
+ require "database_cleaner"
24
+ require "capybara/poltergeist"
25
+ require "timecop"
26
+ require "webmock"
27
+
28
+ # Load support files
29
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
30
+
31
+ # This file was generated by the `rails generate rspec:install` command. Conventionally, all
32
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
33
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
34
+ # file to always be loaded, without a need to explicitly require it in any files.
35
+ #
36
+ # Given that it is always loaded, you are encouraged to keep this file as
37
+ # light-weight as possible. Requiring heavyweight dependencies from this file
38
+ # will add to the boot time of your test suite on EVERY test run, even for an
39
+ # individual file that may not need all of that loaded. Instead, make a
40
+ # separate helper file that requires this one and then use it only in the specs
41
+ # that actually need it.
42
+ #
43
+ # The `.rspec` file also contains a few flags that are not defaults but that
44
+ # users commonly want.
45
+ #
46
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
47
+ RSpec.configure do |config|
48
+ config.include FactoryGirl::Syntax::Methods
49
+ config.use_transactional_fixtures = false
50
+
51
+ config.before(:suite) do |example|
52
+ DatabaseCleaner.clean_with(:truncation)
53
+ end
54
+ config.before(:each) do |example|
55
+ DatabaseCleaner.strategy = example.metadata[:js] ? :truncation : :transaction
56
+ DatabaseCleaner.start
57
+ end
58
+ config.after(:each) do
59
+ DatabaseCleaner.clean
60
+ end
61
+
62
+ require 'capybara/poltergeist'
63
+ Capybara.register_driver :poltergeist do |app|
64
+ Capybara::Poltergeist::Driver.new(app, timeout: 90)
65
+ end
66
+ Capybara.javascript_driver = :poltergeist
67
+
68
+ # config.include(Capybara::Webkit::RspecMatchers, :type => :feature)
69
+
70
+ # These two settings work together to allow you to limit a spec run
71
+ # to individual examples or groups you care about by tagging them with
72
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
73
+ # get run.
74
+ config.filter_run :focus
75
+ config.run_all_when_everything_filtered = true
76
+
77
+ # Many RSpec users commonly either run the entire suite or an individual
78
+ # file, and it's useful to allow more verbose output when running an
79
+ # individual spec file.
80
+ if config.files_to_run.one?
81
+ # Use the documentation formatter for detailed output,
82
+ # unless a formatter has already been configured
83
+ # (e.g. via a command-line flag).
84
+ config.default_formatter = 'doc'
85
+ end
86
+
87
+ # Print the 10 slowest examples and example groups at the
88
+ # end of the spec run, to help surface which specs are running
89
+ # particularly slow.
90
+ # config.profile_examples = 10
91
+
92
+ # Run specs in random order to surface order dependencies. If you find an
93
+ # order dependency and want to debug it, you can fix the order by providing
94
+ # the seed, which is printed after each run.
95
+ # --seed 1234
96
+ config.order = :random
97
+
98
+ # Seed global randomization in this process using the `--seed` CLI option.
99
+ # Setting this allows you to use `--seed` to deterministically reproduce
100
+ # test failures related to randomization by passing the same `--seed` value
101
+ # as the one that triggered the failure.
102
+ Kernel.srand config.seed
103
+
104
+ # rspec-expectations config goes here. You can use an alternate
105
+ # assertion/expectation library such as wrong or the stdlib/minitest
106
+ # assertions if you prefer.
107
+ config.expect_with :rspec do |expectations|
108
+ # Enable only the newer, non-monkey-patching expect syntax.
109
+ # For more details, see:
110
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
111
+ expectations.syntax = [:should, :expect]
112
+ end
113
+
114
+ # rspec-mocks config goes here. You can use an alternate test double
115
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
116
+ config.mock_with :rspec do |mocks|
117
+ # Enable only the newer, non-monkey-patching expect syntax.
118
+ # For more details, see:
119
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
120
+ mocks.syntax = [:should, :expect]
121
+
122
+ # Prevents you from mocking or stubbing a method that does not exist on
123
+ # a real object. This is generally recommended.
124
+ # mocks.verify_partial_doubles = true
125
+ end
126
+
127
+ # Reset to the Sql search engine before each test. Individual tests that
128
+ # override this use "around"; we'll use "around" here too to ensure that
129
+ # this block runs before the individual test's override.
130
+ config.around do |example|
131
+ Calagator::Event::SearchEngine.use(:sql)
132
+ Calagator::Venue::SearchEngine.use(:sql)
133
+ example.run
134
+ end
135
+
136
+ config.alias_example_to :fscenario, focus: true
137
+
138
+ # all features should run using the capybara js driver
139
+ config.alias_example_group_to :feature, capybara_feature: true, type: :feature, js: true
140
+ end
@@ -0,0 +1 @@
1
+ Calagator::Venue::Geocoder.perform_geocoding = false
@@ -0,0 +1,5 @@
1
+ SAMPLES_PATH = File.expand_path(File.dirname(__FILE__) + "/samples") unless defined?(SAMPLES_PATH)
2
+
3
+ def read_sample(path_fragment)
4
+ File.read(File.join(SAMPLES_PATH, path_fragment))
5
+ end
@@ -0,0 +1,23 @@
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
+ }
@@ -0,0 +1,6 @@
1
+ <div class="vevent">
2
+ <a class="url" href="http://www.web2con.com/">http://www.web2con.com/</a>
3
+ <span class="summary">Web 2.0 Conference</span>:
4
+ <abbr class="dtstart" title="2007-10-05">Friday, October 5, 2007</abbr>,
5
+ at the <span class="location">Argent Hotel, San Francisco, CA</span>
6
+ </div>
@@ -0,0 +1,13 @@
1
+ <div class="vevent">
2
+ <a class="url" href="http://www.web2con.com/">http://www.web2con.com/</a>
3
+ <span class="summary">Web 2.0 Conference</span>:
4
+ <abbr class="dtstart" title="2007-10-05 00:00:00">Friday, October 5, 2007</abbr>,
5
+ at the
6
+ <div class="venue location vcard">
7
+ <span class="fn org"><a href="/venue/40384/">CubeSpace2</a></span><br />
8
+ <div class="address adr">
9
+ <span class="street-address">622 SE Grand Ave.</span><br />
10
+ <span class="locality">Portland</span>, <span class="region">OR</span> <span class="postal-code">97204</span>
11
+ </div>
12
+ </div>
13
+ </div>
@@ -0,0 +1,13 @@
1
+ <div class="vevent">
2
+ <a class="url" href="http://www.web2con.com/">http://www.web2con.com/</a>
3
+ <span class="summary">Web 2.0 Conference</span>:
4
+ <abbr class="dtstart" title="2007-10-05 00:00:00">Friday, October 5, 2007</abbr>,
5
+ at the
6
+ <div class="venue location vcard">
7
+ <span class="fn org"><a href="/venue/40384/">CubeSpace2</a></span><br />
8
+ <div class="address adr">
9
+ <span class="street-address">622 SE Grand Ave.</span><br />
10
+ <span class="locality">Portland</span>, <span class="region">OR</span> <span class="postal-code">97204</span>
11
+ </div>
12
+ </div>
13
+ </div>
@@ -0,0 +1,14 @@
1
+ <div id="event" class="vevent">
2
+ <span class="summary">Ignite Portland 2010</span>
3
+ <abbr class="dtstart" title="20100618T180000">June 18, 2010</abbr>
4
+ <abbr class="dtend" title="20100618T210000">9:00 PM</abbr>
5
+ <div class="venue location vcard">
6
+ <span class="fn org">Bagdad Theater and Pub</span><br />
7
+ <div class="address adr">
8
+ <span class="street-address">3702 S.E. Hawthorne Blvd</span><br />
9
+ <span class="locality">Portland</span>,
10
+ <span class="region">OR</span>
11
+ <span class="postal-code">97214</span>
12
+ </div>
13
+ </div>
14
+ </div>
@@ -0,0 +1,16 @@
1
+ <div class="vevent">
2
+ <a href="http://www.cubespacepdx.com" class="url">
3
+ <abbr title="20080119" class="dtstart">January 19th</abbr>,
4
+ <abbr title="20080120" class="dtend"> 2008</abbr>
5
+ <span class="summary">Calendar event</span>– at
6
+ <span class="location">Cubespace, 622 SE Grand Ave. Portland, OR 97214</span></a>
7
+ <div class="description">Check it out!</div>
8
+ </div>
9
+ <div class="vevent">
10
+ <a href="http://www.cubespacepdx.com" class="url">
11
+ <abbr title="20080202" class="dtstart">February 2nd</abbr>,
12
+ <abbr title="20080203" class="dtend"> 2008</abbr>
13
+ <span class="summary">Calendar event</span>– at
14
+ <span class="location">Cubespace, 622 SE Grand Ave. Portland, OR 97214</span></a>
15
+ <div class="description">Check it out!</div>
16
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="vevent">
2
+ <a href="http://www.cubespacepdx.com" class="url">
3
+ <span class="summary">Same hCal event twice</span>
4
+ <abbr title="20080119" class="dtstart"></abbr>
5
+ <span class="location">First venue</span></a>
6
+ </div>
7
+ <div class="vevent">
8
+ <a href="http://www.cubespacepdx.com" class="url">
9
+ <span class="summary">Same hCal event twice</span>
10
+ <abbr title="20080119" class="dtstart"></abbr>
11
+ <span class="location">Different venue</span></a>
12
+ </div>
@@ -0,0 +1,8 @@
1
+ <div class="vevent">
2
+ <a href="http://www.cubespacepdx.com" class="url">
3
+ <abbr title="20080119" class="dtstart">January 19th</abbr>,
4
+ <abbr title="20080120" class="dtend"> 2008</abbr>
5
+ <span class="summary">Calendar event</span>– at
6
+ <span class="location">Cubespace, 622 SE Grand Ave. Portland, OR 97214</span></a>
7
+ <div class="description">Check it out!</div>
8
+ </div>`
@@ -0,0 +1,14 @@
1
+ <div class="vevent">
2
+ <a href="http://www.france.gov.fr" class="url">
3
+ <abbr title="20080714" class="dtstart"></abbr>,
4
+ <span class="summary">Bastille Day</span> at
5
+ <span class="location">Arc de Triomphe</span></a>
6
+ <div class="description">Alors!</div>
7
+ </div>`
8
+ <div class="vevent">
9
+ <a href="http://www.france.gov.fr" class="url">
10
+ <abbr title="20080714" class="dtstart"></abbr>,
11
+ <span class="summary">Bastille Day</span> at
12
+ <span class="location">Arc de Triomphe</span></a>
13
+ <div class="description">Alors!</div>
14
+ </div>`
@@ -0,0 +1,412 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <title>February BarCamp Portland Informal Tech Meetup at Jive Software Office (Thursday, February 28, 2008) - Upcoming</title>
6
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
7
+ <meta http-equiv="Content-Language" content="en-us" />
8
+ <link rel="shortcut icon" href="/favicon.ico" />
9
+ <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/reset-fonts-grids/reset-fonts-grids.css" />
10
+ <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/calendar/assets/calendar.css" />
11
+ <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/container/assets/container.css" />
12
+ <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/container/assets/skins/sam/container.css" />
13
+ <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/calendar/assets/skins/sam/calendar.css" />
14
+ <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/autocomplete/assets/skins/sam/autocomplete.css" />
15
+ <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css" />
16
+ <script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/utilities/utilities.js"></script>
17
+ <script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/container/container-min.js"></script>
18
+ <script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/calendar/calendar-min.js"></script>
19
+ <script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/autocomplete/autocomplete-min.js"></script>
20
+ <script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/menu/menu-min.js"></script>
21
+ <link rel="stylesheet" type="text/css" href="http://l.yimg.com/ycs.upcoming.yahoo.com/css/default_3386bb892387df5429a8f1f09cf63e47.css" />
22
+ <link rel="stylesheet" type="text/css" href="http://l.yimg.com/ycs.upcoming.yahoo.com/css/base_d325632afbe941a6aea4b5506f36597c.css" />
23
+ </head>
24
+ <body>
25
+ <div id="doc2" class="wrapper yui-t7">
26
+ <div id="hd">
27
+ <div class="header-logo"><a href="/"><img src="http://l.yimg.com/ycs.upcoming.yahoo.com/images/logo_c1e7e61d4b270328ac1c07c895ae47a3.gif" border="0" alt="Upcoming"></a></div>
28
+ <div id="nav">
29
+ <p>
30
+ <a href="https://login.yahoo.com/config/login_verify2?.pd=c%3d7VX_qHOp2e4WEc1FoX0E7L8-&.intl=us&.src=upcm&.done=http%3A%2F%2Fupcoming.yahoo.com%2Fdetect%2F%3Fr%3Dhttp%253A%252F%252Fupcoming.yahoo.com%252Fevent%252F428964%252F">Sign in</a> or <a href="https://login.yahoo.com/config/eval_register?.intl=us&.done=http%3A%2F%2Fupcoming.yahoo.com%2Fdetect%2F%3Fr%3Dhttp%253A%252F%252Fupcoming.yahoo.com%252Fevent%252F428964%252F&.src=upcm">join now</a>
31
+ <strong><a href="/help/">Help?</a></strong>
32
+ </p>
33
+ <div id="nav-list">
34
+ <ul>
35
+ <li><a href="/">Home</a></li>
36
+ <li><a href="/event/">Events</a></li>
37
+ <li><a href="/place/">Places</a></li>
38
+ <li><a href="/friend/">Friends</a></li>
39
+ <li><a href="/group/">Groups</a></li>
40
+ <li><a href="/popular/">Popular</a></li>
41
+ <li><a href="/event/add/" style="background: none">Add New Event &raquo;</a></li>
42
+ </ul>
43
+ </div>
44
+ <a href="http://www.yahoo.com/" class="brand"><img src="http://l.yimg.com/ycs.upcoming.yahoo.com/images/logo/yahoo_service_41b1f50dadc4f7111705b35ca98c7203.png" alt="A Yahoo! Service"></a>
45
+ </div><!-- /#nav -->
46
+ <div id="nav-sub">
47
+ <ul>
48
+ <li><a href="/myevents/">My Events</a></li>
49
+ <li><a href="/history/myevents/">My Scrapbook</a></li>
50
+ <li><a href="/friend/event/">My Friends' Events</a></li>
51
+ </ul>
52
+ </div>
53
+ </div><!-- /#hd -->
54
+
55
+ <div id="bd">
56
+ <div id="bd-top" class="yui-g">
57
+ <div id="location" class="yui-u first">
58
+ <h1><a href="http://upcoming.yahoo.com/place/RlEYPWubBZtlFXkb">Portland</a></h1>
59
+ <div class="breadcrumb">
60
+ <a href="http://upcoming.yahoo.com/place/AHzl7sWYA5mP8oDGHg">Multnomah County</a> / <a href="http://upcoming.yahoo.com/place/4vvLDQabApjbhCKB">Oregon</a> / <a href="http://upcoming.yahoo.com/place/4KO02SibApitvSBieQ">United States</a>&nbsp; </div>
61
+ </div>
62
+ <div id="search" class="yui-u">
63
+ <div class="searchForm" id="searchwidget_form">
64
+ <form method="get" id="searchwidget_actualform" action="/search/">
65
+ <input type="hidden" name="type" id="form_searchtype" value="Events" />
66
+
67
+ <h4>Find <span id="searchtype">events</span> <a href="javascript:void(0);"><img id="searchwidget_type_toggle" src="http://l.yimg.com/ycs.upcoming.yahoo.com/images/sort_dn_1_a866c8c373a9909aac88d6572277750d.gif" width="12" height="11" /></a></h4>
68
+ <p><label for="search_what">What? <em>(e.g. jazz, U2, Lakers)</em></label>
69
+ <input type="text" name="q" id="searchwidget_q" value="" /></p>
70
+ <input id="search_rt" type="hidden" name="rt" value="1" />
71
+ <p id="psearchloc"><label for="search_where">Where?</label>
72
+ <input type="text" name="loc" id="search_loc" value="Portland, Oregon, United States" /><p id="psearchgo"><label for="Search">&nbsp;</label><input id="searchgo" type="submit" name="Search" class="submit" value="GO" /></p>
73
+ </form>
74
+ </div>
75
+ </div>
76
+ </div><!-- /#bd-top -->
77
+ <div id="yui-main" class="content">
78
+
79
+
80
+
81
+ <div id="calendarContainer" class="vcalendar"> <!-- Begin vCalendar -->
82
+
83
+
84
+
85
+
86
+ <div id="event" class="vevent">
87
+ <h1>
88
+ <span class="name summary">
89
+ February BarCamp Portland Informal Tech Meetup </span>
90
+
91
+
92
+
93
+ </h1>
94
+
95
+ <div id="eventMain">
96
+
97
+ <div id="eventMetadata">
98
+
99
+ <div class="map">
100
+ <div id="mapContainer" style="height: 160px; width:180px;"></div>
101
+ <form style="display:none;">
102
+ <input type="hidden" id="mapLat" value="45.5191" />
103
+ <input type="hidden" id="mapLon" value="-122.675" />
104
+ </form>
105
+
106
+ <div class="directions">
107
+ <a href="http://maps.yahoo.com/dd?taddr=317+SW+Alder+St+Ste+500&tcsz=portland%2Cor%2C97204&tcountry=us">Driving directions</a> / <a href="http://maps.yahoo.com/maps_result.php?addr=317+SW+Alder+St+Ste+500&csz=portland%2Cor%2C97204&country=us&mag=5">Larger Map</a>
108
+ </div>
109
+ </div>
110
+
111
+
112
+ <div class="date">
113
+ <abbr class="dtstart" title="20080228T173000">
114
+ Thursday, February 28, 2008 </abbr>
115
+ </div> <!-- /.date -->
116
+ <div class="time">
117
+ 5:30 PM - <abbr class="dtend" title="20080228T193000">7:30 PM</abbr>
118
+ </div> <!-- /.time -->
119
+
120
+ <br />
121
+ <div class="venue location vcard">
122
+ <span class="fn org"><a href="/venue/40384/">Jive Software Office</a></span><br />
123
+ <div class="address adr">
124
+ <span class="street-address">317 SW Alder St Ste 500</span><br />
125
+ <span class="locality">portland</span>, <span class="region"></span> <span class="postal-code">97204</span>
126
+ </div>
127
+ <span class="geo" style="display: none">
128
+ <span class="latitude">45.5191</span>,
129
+ <span class="longitude">-122.675</span>
130
+ </span>
131
+
132
+ </div> <!-- /.venue -->
133
+
134
+ <div class="small">Category</div>
135
+ <div class="category">
136
+ Social </div>
137
+
138
+ <div class="small">Description</div>
139
+ <div class="description">
140
+ The intent is to get a group of cool people interested in technology together to chat over drinks on the fourth Thursday of every month. Anyone working in high-tech is welcome to attend. Conversations usually range from wikis to open source to blogs to who knows what!<br /><br />
141
+ Please RSVP here as attending to help us get a count for the event. You might also want to join the Google Group to get notifications of any changes to this event and get reminders for future events! <a rel="nofollow" href="http://groups.google.com/group/barcampportland">http://groups.google.com/group/barcampportland</a><br /><br />
142
+ You can visit <a rel="nofollow" href="http://barcamp.org/BarCampPortlandMeetups">http://barcamp.org/BarCampPortlandMeetups</a> for more information.<br />
143
+ </div>
144
+
145
+
146
+ <div class="small">Homepage</div>
147
+ <div class="homepage">
148
+ <a href="http://barcamp.org/BarCampPortlandMeetups" class="url">http://barcamp.org/BarCampPortlandMeetups</a>
149
+ </div>
150
+
151
+
152
+ &nbsp;
153
+ </div> <!-- /#eventMetadata -->
154
+
155
+ <div class="byline">
156
+ Added by
157
+
158
+ <a href="/user/92824/"><img src="http://static.flickr.com/20/buddyicons/52257913@N00.jpg" height="12" width="12" border="0" /></a>
159
+ <span><a class="" title="" href="http://upcoming.yahoo.com/user/92824/">GeekyGirlDawn</a></span>
160
+ on February 10, 2008 </div>
161
+
162
+ <div id="eventComments">
163
+ <div id="eventPhotos">
164
+ <div class="heading">Photos
165
+ <span class="small" id="photos_loading_msg">(<a href="http://flickr.com/photos/tags/upcoming:event=428964" id="photos_see_all_link">loading...</a>)</span>
166
+ </div>
167
+ <div id="photo_container"></div>
168
+ <div id="add_photo_button_container"><a id="add_photo_link" href="javascript:void(0);">Add your own...</a></div>
169
+ <div id="add_photo_container" class="clicker_menu">
170
+ <div class="hd"></div>
171
+ <div class="bd"></div>
172
+ <b>Add Photos from <a href="http://flickr.com">Flickr</a>!</b> (<a href="" id="add_photo_close_link">close</a>)
173
+ <hr />
174
+ <ul>
175
+ <li><b>Tag</b> a public <a href="http://flickr.com/">Flickr</a> photo with: <input style="display: inline;" type="text" onFocus="this.select();" value="upcoming:event=428964" /></li>
176
+ <li>Your photos <b>will appear</b> on this event page automagically in a little while!</li>
177
+ </ul>
178
+ <div class="ft"></div>
179
+ </div>
180
+
181
+ </div> <!-- /#eventPhotos -->
182
+
183
+ <div class="heading">Comments</div>
184
+ <br /><br />
185
+ <div id="addcomments" class="info">
186
+ <a href="https://login.yahoo.com/config/eval_register?.intl=us&.done=http%3A%2F%2Fupcoming.yahoo.com%2Fdetect%2F%3Fr%3D%252Fevent%252F428964%252F&.src=upcm">Sign Up</a> or <a href="https://login.yahoo.com/config/login_verify2?.pd=c%3d7VX_qHOp2e4WEc1FoX0E7L8-&.intl=us&.src=upcm&.done=http%3A%2F%2Fupcoming.yahoo.com%2Fdetect%2F%3Fr%3D%252Fevent%252F428964%252F">Sign In</a> to comment on this event!
187
+ </div>
188
+
189
+ </div> <!-- /#eventComments -->
190
+ </div> <!-- /#eventMain -->
191
+
192
+ <div id="eventSidebar">
193
+
194
+
195
+ <div id="eventAttendance">
196
+ <form method="get" id="watch_form" action="/add/watchlist/">
197
+ <input type="hidden" name="_ucrumb" value="" />
198
+
199
+ <div class="attend">
200
+ <input type="radio" name="status" value="attend" id="status_attend" onClick="document.getElementById('watch_form').submit();" /> <label for="status_attend" onClick="document.getElementById('status_attend').checked = true;document.getElementById('watch_form').submit();">
201
+ I'm Attending
202
+ </label><br />
203
+
204
+ </div> <!-- /.attend -->
205
+
206
+ <div class="watch">
207
+ <input type="radio" name="status" value="watch" id="status_watch" onClick="document.getElementById('watch_form').submit();" /> <label for="status_watch" onClick="document.getElementById('status_watch').checked = true;document.getElementById('watch_form').submit();"> I'm Watching
208
+ </label><br />
209
+
210
+ </div> <!-- /.watch -->
211
+
212
+
213
+
214
+
215
+ <input type="hidden" name="action" value="add" />
216
+
217
+ <input type="hidden" name="event_id" value="428964" />
218
+ <noscript>
219
+ <input type="submit" name="submit" value="Do it!"/>
220
+ </noscript>
221
+ </form>
222
+
223
+ </div>
224
+ <br />
225
+
226
+ <div class="userlist">
227
+
228
+ <div class="userlistAttend">
229
+ <div class="title">
230
+ 12
231
+ Attending
232
+ </div>
233
+
234
+ <a href="/user/92824/"><img src="http://static.flickr.com/20/buddyicons/52257913@N00.jpg" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 10, 2008 10:18 AM" href="http://upcoming.yahoo.com/user/92824/">GeekyGirlDawn</a></span><br />
235
+ <a href="/user/89306/"><img src="http://static.flickr.com/1/buddyicons/46661228@N00.jpg" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 10, 2008 10:53 AM" href="http://upcoming.yahoo.com/user/89306/">spinnerin</a></span><br />
236
+ <a href="/user/122240/"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr/48x48_photomissing_icon.gif" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 10, 2008 10:55 AM" href="http://upcoming.yahoo.com/user/122240/">igal</a></span><br />
237
+ <a href="/user/197377/"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr/48x48_photomissing_icon.gif" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 10, 2008 11:56 AM" href="http://upcoming.yahoo.com/user/197377/">ahockley</a></span><br />
238
+ <a href="/user/197382/"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr/48x48_photomissing_icon.gif" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 10, 2008 01:16 PM" href="http://upcoming.yahoo.com/user/197382/">Bart Massey</a></span><br />
239
+ <a href="/user/88776/"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr/48x48_photomissing_icon.gif" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 11, 2008 07:12 AM" href="http://upcoming.yahoo.com/user/88776/">samkeen</a></span><br />
240
+ <a href="/user/147796/"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr/48x48_photomissing_icon.gif" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 11, 2008 08:49 AM" href="http://upcoming.yahoo.com/user/147796/">Paul Bingman</a></span><br />
241
+ <a href="/user/138844/"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr/48x48_photomissing_icon.gif" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 11, 2008 01:19 PM" href="http://upcoming.yahoo.com/user/138844/">chris.faulkner</a></span><br />
242
+ <a href="/user/20440/"><img src="http://static.flickr.com/3/buddyicons/97525854@N00.jpg" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 12, 2008 09:42 AM" href="http://upcoming.yahoo.com/user/20440/">dieselboi</a></span><br />
243
+ <a href="/user/214824/"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr/48x48_photomissing_icon.gif" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Attending since Feb 13, 2008 10:15 PM" href="http://upcoming.yahoo.com/user/214824/">nathanpbell</a></span><div id="attendees_hidden" style="display:none;"></div> </div> <!-- /.userlistAttend -->
244
+
245
+ <div class="userlistWatch">
246
+ <div class="title">
247
+ 4
248
+ Watching
249
+ </div>
250
+ <a href="/user/198761/"><img src="http://static.flickr.com/2134/buddyicons/22254860@N03.jpg" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Watching since Feb 10, 2008 01:23 PM" href="http://upcoming.yahoo.com/user/198761/">mototom</a></span><br />
251
+ <a href="/user/119942/"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr/48x48_photomissing_icon.gif" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Watching since Feb 10, 2008 08:24 PM" href="http://upcoming.yahoo.com/user/119942/">multimodal</a></span><br />
252
+ <a href="/user/134047/"><img src="http://static.flickr.com/1023/buddyicons/25244539@N00.jpg" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Watching since Feb 10, 2008 11:45 PM" href="http://upcoming.yahoo.com/user/134047/">turoczy</a></span><br />
253
+ <a href="/user/206379/"><img src="http://static.flickr.com/27/buddyicons/71572571@N00.jpg" class="avatar" height="12" width="12" border="0" /></a><span><a class="" title="Watching since Feb 12, 2008 04:13 AM" href="http://upcoming.yahoo.com/user/206379/">amycgx</a></span><div id="watchers_hidden" style="display:none;"></div> </div> <!-- /.userlistWatch -->
254
+
255
+ <div id="userlistExpand">
256
+ <a id="hide_attendees" href="javascript:void(0);" style="display:none;" class="tab">Hide...</a>
257
+
258
+ <a id="expand_attendees" href="javascript:void(0);" style="display:none;" class="tab">Show all 16...</a>
259
+ <a id="placeholder_attendees" href="javascript:void(0);" class="tab">Page loading...</a>
260
+ </div>
261
+ </div> <!-- /.userlist -->
262
+
263
+
264
+ <div class="eventRelated">
265
+ <div class="inset" id="insetContent">
266
+ <div class="insetTitle">
267
+ We're also going to...
268
+ </div>
269
+ <div class="insetBody">
270
+ <table>
271
+ <tr>
272
+ <td width="70" valign="top">Wed, Feb 27</td>
273
+ <td><b><a href="/event/174640/">Portland Open Coffee</a></b></td>
274
+ </tr>
275
+ <tr>
276
+ <td width="70" valign="top">Thu, Mar 27</td>
277
+ <td><b><a href="/event/428967/">March BarCamp Portland Informal Tech Meetup</a></b></td>
278
+ </tr>
279
+ <tr>
280
+ <td width="70" valign="top">Sat, Mar 29</td>
281
+ <td><b><a href="/event/349225/">Startupalooza</a></b></td>
282
+ </tr>
283
+ <tr>
284
+ <td width="70" valign="top">Thu, Apr 24</td>
285
+ <td><b><a href="/event/428968/">April BarCamp Portland Informal Tech Meetup</a></b></td>
286
+ </tr>
287
+ <tr>
288
+ <td width="70" valign="top">Fri, May 2</td>
289
+ <td><b><a href="/event/421147/">BarCampPortland</a></b></td>
290
+ </tr>
291
+ </table>
292
+ </div>
293
+ </div>
294
+ </div>
295
+ <!-- Cached recommendations as of 2008-02-16 10:37:58 -->
296
+ <div class="venueRelated">
297
+ <div class="inset" id="insetContent">
298
+ <div class="insetTitle">
299
+ Also at this venue
300
+ </div><!-- end insetTitle -->
301
+ <div class="insetBody">
302
+ <table>
303
+ <tr>
304
+ <td width="70" valign="top">Thu, Mar 27</td>
305
+ <td><b><a href="/event/428967/">March BarCamp Portland Informal Tech Meetup</a></b></td>
306
+ </tr>
307
+ <tr>
308
+ <td width="70" valign="top">Thu, Apr 24</td>
309
+ <td><b><a href="/event/428968/">April BarCamp Portland Informal Tech Meetup</a></b></td>
310
+ </tr>
311
+ </table>
312
+ </div><!-- end insetBody -->
313
+ </div><!-- end insetContent -->
314
+ </div> <!-- end insetContainer -->
315
+
316
+ <div id="eventTags">
317
+ <div class="insetTitle">
318
+ Tags
319
+ </div><!-- end insetTitle -->
320
+ <div class="insetBody categories">
321
+ <div id="tag_list">
322
+ <a href="/tag/technology/" rel="tag" class="category">technology</a>
323
+ <br />
324
+ <a href="/tag/portland/" rel="tag" class="category">portland</a>
325
+ <br />
326
+ <a href="/tag/software/" rel="tag" class="category">software</a>
327
+ <br />
328
+ <a href="/tag/legionoftech/" rel="tag" class="category">Legion of Tech</a>
329
+ <br />
330
+ <a href="/tag/jivesoftware/" rel="tag" class="category">Jive Software</a>
331
+ <br />
332
+ <a href="/tag/oregon/" rel="tag" class="category">oregon</a>
333
+ <br />
334
+ </div>
335
+ <div id="add_tag">
336
+ </div>
337
+ </div><!-- /.insetBody -->
338
+ </div> <!-- /#eventTags -->
339
+
340
+ <div id="eventGroups">
341
+ <div class="insetTitle">Groups</div>
342
+ <div class="insetBody">
343
+ <div><ul id="group_list"><a href="/group/4025/">Legion Of Tech</a></li><li><a href="/group/4070/">Silicon Florist</a></ul></div> <div id="send_to_group">
344
+
345
+ </div>
346
+ </div> <!-- /.insetBody -->
347
+ </div> <!-- /#eventGroups -->
348
+
349
+
350
+ </div> <!-- /#eventSidebar -->
351
+ <div id="hidden_event_id" style="visibility:hidden;">428964</div>
352
+ </div> <!-- /#event -->
353
+
354
+ <br style="clear: both">
355
+
356
+ <script language="JavaScript">
357
+ <!--
358
+ ctxt_ad_partner = '6872253410';
359
+ ctxt_ad_section = '6984';
360
+ ctxt_ad_bg = '';
361
+ ctxt_ad_width = 468;
362
+ ctxt_ad_height = 60;
363
+ ctxt_ad_bc = 'FBFBFB';
364
+ ctxt_ad_cc = 'FBFBFB';
365
+ ctxt_ad_lc = '002CD9';
366
+ ctxt_ad_tc = '333333';
367
+ ctxt_ad_uc = 'C80D00';
368
+ // -->
369
+ </script>
370
+ <script language="JavaScript" src="http://ypn-js.overture.com/partner/js/ypn.js">
371
+ </script><br />
372
+
373
+
374
+ </div> <!-- End vCalendar -->
375
+ </div> <!-- /#yui-main -->
376
+ </div> <!-- /#bd -->
377
+ <input type="hidden" id="_cmb" name="_cmb" value="" />
378
+
379
+ <div id="footer">
380
+ <div id="footer-nav">
381
+
382
+ <p>
383
+ <strong>Tools</strong>
384
+ <a href="/badge/">Upcoming Badges for Your Blog/Website</a>
385
+ | <a href="/site_invite/">Invite Friends</a>
386
+ | <a href="/group/">Groups</a>
387
+ | <a href="/services/api/">Developers API</a>
388
+ </p>
389
+
390
+ <p>
391
+ <strong>Help</strong>
392
+ <a href="/news/">News Blog</a>
393
+ | <a href="/help/guidelines/">Community Guidelines</a>
394
+ | <a href="/help/faq/">FAQ</a>
395
+ | <a href="/contact/">Contact Us</a>
396
+ | <a href="http://suggestions.yahoo.com/?prop=upcoming">Suggestion Board</a>
397
+ </p>
398
+ </div>
399
+
400
+ <div id="footer-legal">
401
+ Copyright &copy; 2008 Yahoo! Inc. All rights reserved. -
402
+ <a href="http://docs.yahoo.com/info/copyright/copyright.html">Copyright/IP Policy</a> -
403
+ <a href="http://docs.yahoo.com/info/terms/">Terms of Service</a> -
404
+ <a href="http://privacy.yahoo.com/privacy/us/upcoming/">Privacy Policy</a>
405
+ </div>
406
+ </div><!-- /#footer -->
407
+ </div> <!-- end 'wrapper' -->
408
+ <!-- spaceId: 97348559 -->
409
+ <script type="text/javascript" src="http://l.yimg.com/ycs.upcoming.yahoo.com/js/minimega_d5cca161a178fa5163dfb97cdb86947b.js"></script></script>
410
+ <script type="text/javascript" src="http://l.yimg.com/ycs.upcoming.yahoo.com/js/event_page_3769988cc5d17697b99021096a1641c7.js"></script><script type="text/javascript" src="/js/ajaxymaphack"></script><script type="text/javascript" src="http://l.yimg.com/ycs.upcoming.yahoo.com/js/venue_widget_1f85a919e0951c433e80ac053ced08f8.js"></script></body>
411
+ </html>
412
+ <!-- web4.up.sp1.yahoo.com uncompressed/chunked Sat Feb 16 17:09:07 PST 2008 -->