open_conference_ware 1.0.0.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 (471) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.autotest +14 -0
  3. data/.coveralls.yml +1 -0
  4. data/.gitignore +21 -0
  5. data/.rspec +1 -0
  6. data/.travis.yml +18 -0
  7. data/CHANGES.md +280 -0
  8. data/CONTRIBUTORS.markdown +17 -0
  9. data/Gemfile +21 -0
  10. data/Gemfile.lock +296 -0
  11. data/Guardfile +24 -0
  12. data/LICENSE.txt +23 -0
  13. data/README.markdown +173 -0
  14. data/Rakefile +27 -0
  15. data/TODO.txt +22 -0
  16. data/app/assets/images/open_conference_ware/accept.png +0 -0
  17. data/app/assets/images/open_conference_ware/arrow-left.png +0 -0
  18. data/app/assets/images/open_conference_ware/arrow-out.png +0 -0
  19. data/app/assets/images/open_conference_ware/arrow-right.png +0 -0
  20. data/app/assets/images/open_conference_ware/arrow-up.png +0 -0
  21. data/app/assets/images/open_conference_ware/arrow_refresh.png +0 -0
  22. data/app/assets/images/open_conference_ware/comment.png +0 -0
  23. data/app/assets/images/open_conference_ware/comment_edit.png +0 -0
  24. data/app/assets/images/open_conference_ware/delete.png +0 -0
  25. data/app/assets/images/open_conference_ware/disk.png +0 -0
  26. data/app/assets/images/open_conference_ware/document-blank.png +0 -0
  27. data/app/assets/images/open_conference_ware/document.png +0 -0
  28. data/app/assets/images/open_conference_ware/edit.png +0 -0
  29. data/app/assets/images/open_conference_ware/extras/001_01.png +0 -0
  30. data/app/assets/images/open_conference_ware/extras/001_05.png +0 -0
  31. data/app/assets/images/open_conference_ware/extras/001_05x16.png +0 -0
  32. data/app/assets/images/open_conference_ware/extras/001_21.png +0 -0
  33. data/app/assets/images/open_conference_ware/extras/001_23.png +0 -0
  34. data/app/assets/images/open_conference_ware/extras/001_24.png +0 -0
  35. data/app/assets/images/open_conference_ware/extras/001_29.png +0 -0
  36. data/app/assets/images/open_conference_ware/extras/01.png +0 -0
  37. data/app/assets/images/open_conference_ware/extras/05.png +0 -0
  38. data/app/assets/images/open_conference_ware/extras/06.png +0 -0
  39. data/app/assets/images/open_conference_ware/extras/1.png +0 -0
  40. data/app/assets/images/open_conference_ware/extras/14.png +0 -0
  41. data/app/assets/images/open_conference_ware/extras/16.png +0 -0
  42. data/app/assets/images/open_conference_ware/extras/2.png +0 -0
  43. data/app/assets/images/open_conference_ware/extras/21.png +0 -0
  44. data/app/assets/images/open_conference_ware/extras/28.png +0 -0
  45. data/app/assets/images/open_conference_ware/extras/3.png +0 -0
  46. data/app/assets/images/open_conference_ware/extras/31.png +0 -0
  47. data/app/assets/images/open_conference_ware/extras/32.png +0 -0
  48. data/app/assets/images/open_conference_ware/extras/35.png +0 -0
  49. data/app/assets/images/open_conference_ware/extras/36.png +0 -0
  50. data/app/assets/images/open_conference_ware/extras/4.png +0 -0
  51. data/app/assets/images/open_conference_ware/extras/44.png +0 -0
  52. data/app/assets/images/open_conference_ware/extras/45.png +0 -0
  53. data/app/assets/images/open_conference_ware/extras/46.png +0 -0
  54. data/app/assets/images/open_conference_ware/extras/cancel.png +0 -0
  55. data/app/assets/images/open_conference_ware/extras/cancelx16.png +0 -0
  56. data/app/assets/images/open_conference_ware/extras/icon.trashcan.gif +0 -0
  57. data/app/assets/images/open_conference_ware/favorite.png +0 -0
  58. data/app/assets/images/open_conference_ware/feed.png +0 -0
  59. data/app/assets/images/open_conference_ware/heart.png +0 -0
  60. data/app/assets/images/open_conference_ware/house.png +0 -0
  61. data/app/assets/images/open_conference_ware/ignite_portland_header3_clear.png +0 -0
  62. data/app/assets/images/open_conference_ware/ignite_portland_header3_clear_cropped.png +0 -0
  63. data/app/assets/images/open_conference_ware/jquery.wysiwyg.gif +0 -0
  64. data/app/assets/images/open_conference_ware/lock.png +0 -0
  65. data/app/assets/images/open_conference_ware/new_window.gif +0 -0
  66. data/app/assets/images/open_conference_ware/openid-icon.gif +0 -0
  67. data/app/assets/images/open_conference_ware/pencil.png +0 -0
  68. data/app/assets/images/open_conference_ware/plus.png +0 -0
  69. data/app/assets/images/open_conference_ware/quote.png +0 -0
  70. data/app/assets/images/open_conference_ware/rails.png +0 -0
  71. data/app/assets/images/open_conference_ware/redx.png +0 -0
  72. data/app/assets/images/open_conference_ware/reset-fff.png +0 -0
  73. data/app/assets/images/open_conference_ware/spinner-big.gif +0 -0
  74. data/app/assets/images/open_conference_ware/spinner.gif +0 -0
  75. data/app/assets/images/open_conference_ware/star.png +0 -0
  76. data/app/assets/images/open_conference_ware/tag_blue.png +0 -0
  77. data/app/assets/images/open_conference_ware/time.png +0 -0
  78. data/app/assets/javascripts/open_conference_ware/application.js +18 -0
  79. data/app/assets/javascripts/open_conference_ware/base.js +15 -0
  80. data/app/assets/javascripts/open_conference_ware/favorites.js +76 -0
  81. data/app/assets/javascripts/open_conference_ware/ie.js +2 -0
  82. data/app/assets/javascripts/open_conference_ware/menu.js +47 -0
  83. data/app/assets/javascripts/open_conference_ware/persona.js +10 -0
  84. data/app/assets/javascripts/open_conference_ware/proposals.js +208 -0
  85. data/app/assets/javascripts/open_conference_ware/schedule.js +20 -0
  86. data/app/assets/javascripts/open_conference_ware/spinner.js +11 -0
  87. data/app/assets/javascripts/open_conference_ware/util.js +23 -0
  88. data/app/assets/stylesheets/open_conference_ware/application.css +8 -0
  89. data/app/assets/stylesheets/open_conference_ware/common.css.scss +491 -0
  90. data/app/assets/stylesheets/open_conference_ware/custom.css.scss +1033 -0
  91. data/app/assets/stylesheets/open_conference_ware/scaffold.css +54 -0
  92. data/app/controllers/open_conference_ware/application_controller.rb +488 -0
  93. data/app/controllers/open_conference_ware/authentications_controller.rb +42 -0
  94. data/app/controllers/open_conference_ware/comments_controller.rb +86 -0
  95. data/app/controllers/open_conference_ware/events_controller.rb +36 -0
  96. data/app/controllers/open_conference_ware/manage/events_controller.rb +157 -0
  97. data/app/controllers/open_conference_ware/manage/snippets_controller.rb +110 -0
  98. data/app/controllers/open_conference_ware/proposals_controller.rb +521 -0
  99. data/app/controllers/open_conference_ware/rooms_controller.rb +130 -0
  100. data/app/controllers/open_conference_ware/schedule_items_controller.rb +128 -0
  101. data/app/controllers/open_conference_ware/selector_votes_controller.rb +71 -0
  102. data/app/controllers/open_conference_ware/session_types_controller.rb +123 -0
  103. data/app/controllers/open_conference_ware/tracks_controller.rb +118 -0
  104. data/app/controllers/open_conference_ware/user_favorites_controller.rb +68 -0
  105. data/app/controllers/open_conference_ware/users_controller.rb +120 -0
  106. data/app/helpers/open_conference_ware/application_helper.rb +167 -0
  107. data/app/helpers/open_conference_ware/authentications_helper.rb +25 -0
  108. data/app/helpers/open_conference_ware/cache_if_helper.rb +13 -0
  109. data/app/helpers/open_conference_ware/display_link_to_helper.rb +25 -0
  110. data/app/helpers/open_conference_ware/display_textile_for_helper.rb +11 -0
  111. data/app/helpers/open_conference_ware/field_annotation_helper.rb +11 -0
  112. data/app/helpers/open_conference_ware/focus_helper.rb +16 -0
  113. data/app/helpers/open_conference_ware/localcss_helper.rb +10 -0
  114. data/app/helpers/open_conference_ware/page_title_helper.rb +17 -0
  115. data/app/helpers/open_conference_ware/proposals_helper.rb +54 -0
  116. data/app/helpers/open_conference_ware/rooms_helper.rb +5 -0
  117. data/app/helpers/open_conference_ware/scroll_to_helper.rb +15 -0
  118. data/app/helpers/open_conference_ware/session_types_helper.rb +5 -0
  119. data/app/helpers/open_conference_ware/snippets_helper.rb +36 -0
  120. data/app/helpers/open_conference_ware/time_range_helper.rb +198 -0
  121. data/app/helpers/open_conference_ware/tracks_helper.rb +9 -0
  122. data/app/helpers/open_conference_ware/user_favorites_helper.rb +15 -0
  123. data/app/mailers/open_conference_ware/speaker_mailer.rb +51 -0
  124. data/app/mixins/open_conference_ware/breadcrumbs_mixin.rb +76 -0
  125. data/app/mixins/open_conference_ware/cache_lookups_mixin.rb +128 -0
  126. data/app/mixins/open_conference_ware/faux_routes_mixin.rb +83 -0
  127. data/app/mixins/open_conference_ware/normalize_url_mixin.rb +40 -0
  128. data/app/mixins/open_conference_ware/public_attributes_mixin.rb +62 -0
  129. data/app/mixins/open_conference_ware/schedule_overlaps_mixin.rb +12 -0
  130. data/app/mixins/open_conference_ware/settings_checkers_mixin.rb +50 -0
  131. data/app/mixins/open_conference_ware/simple_slug_mixin.rb +26 -0
  132. data/app/models/open_conference_ware/authentication.rb +47 -0
  133. data/app/models/open_conference_ware/base.rb +6 -0
  134. data/app/models/open_conference_ware/comment.rb +26 -0
  135. data/app/models/open_conference_ware/event.rb +227 -0
  136. data/app/models/open_conference_ware/proposal.rb +625 -0
  137. data/app/models/open_conference_ware/room.rb +42 -0
  138. data/app/models/open_conference_ware/schedule.rb +216 -0
  139. data/app/models/open_conference_ware/schedule_item.rb +55 -0
  140. data/app/models/open_conference_ware/selector_vote.rb +22 -0
  141. data/app/models/open_conference_ware/session_type.rb +33 -0
  142. data/app/models/open_conference_ware/snippet.rb +58 -0
  143. data/app/models/open_conference_ware/track.rb +51 -0
  144. data/app/models/open_conference_ware/user.rb +262 -0
  145. data/app/models/open_conference_ware/user_favorite.rb +42 -0
  146. data/app/observers/open_conference_ware/cache_watcher.rb +42 -0
  147. data/app/views/layouts/open_conference_ware/_header.html.erb +106 -0
  148. data/app/views/layouts/open_conference_ware/application.atom.erb +1 -0
  149. data/app/views/layouts/open_conference_ware/application.html.erb +126 -0
  150. data/app/views/layouts/open_conference_ware/scaffold.html.erb +21 -0
  151. data/app/views/open_conference_ware/404.html.erb +8 -0
  152. data/app/views/open_conference_ware/422.html.erb +11 -0
  153. data/app/views/open_conference_ware/500.html.erb +11 -0
  154. data/app/views/open_conference_ware/_email_link.html.erb +24 -0
  155. data/app/views/open_conference_ware/_google_analytics.html.erb +9 -0
  156. data/app/views/open_conference_ware/authentications/_developer.html.erb +7 -0
  157. data/app/views/open_conference_ware/authentications/_openid.html.erb +11 -0
  158. data/app/views/open_conference_ware/authentications/_persona.html.erb +17 -0
  159. data/app/views/open_conference_ware/authentications/sign_in.html.erb +12 -0
  160. data/app/views/open_conference_ware/comments/_list.html.erb +31 -0
  161. data/app/views/open_conference_ware/comments/index.atom.builder +25 -0
  162. data/app/views/open_conference_ware/comments/index.html.erb +3 -0
  163. data/app/views/open_conference_ware/events/index.html.erb +9 -0
  164. data/app/views/open_conference_ware/events/show.html.erb +0 -0
  165. data/app/views/open_conference_ware/events/speakers.html.erb +7 -0
  166. data/app/views/open_conference_ware/manage/events/_form.html.erb +107 -0
  167. data/app/views/open_conference_ware/manage/events/edit.html.erb +3 -0
  168. data/app/views/open_conference_ware/manage/events/index.html.erb +41 -0
  169. data/app/views/open_conference_ware/manage/events/new.html.erb +3 -0
  170. data/app/views/open_conference_ware/manage/events/proposals.html.erb +133 -0
  171. data/app/views/open_conference_ware/manage/events/show.html.erb +181 -0
  172. data/app/views/open_conference_ware/manage/snippets/_form.html.erb +30 -0
  173. data/app/views/open_conference_ware/manage/snippets/edit.html.erb +3 -0
  174. data/app/views/open_conference_ware/manage/snippets/index.html.erb +34 -0
  175. data/app/views/open_conference_ware/manage/snippets/new.html.erb +3 -0
  176. data/app/views/open_conference_ware/manage/snippets/show.html.erb +32 -0
  177. data/app/views/open_conference_ware/proposals/_admin_controls.html.erb +33 -0
  178. data/app/views/open_conference_ware/proposals/_form.html.erb +381 -0
  179. data/app/views/open_conference_ware/proposals/_list.html.erb +164 -0
  180. data/app/views/open_conference_ware/proposals/_list_concise.html.erb +93 -0
  181. data/app/views/open_conference_ware/proposals/_manage_speakers.html.erb +30 -0
  182. data/app/views/open_conference_ware/proposals/_room_control.html.erb +21 -0
  183. data/app/views/open_conference_ware/proposals/_schedule_block.html.erb +8 -0
  184. data/app/views/open_conference_ware/proposals/_schedule_control.html.erb +13 -0
  185. data/app/views/open_conference_ware/proposals/_search_speakers.html.erb +20 -0
  186. data/app/views/open_conference_ware/proposals/_sub_list.html.erb +65 -0
  187. data/app/views/open_conference_ware/proposals/_sub_list_for_kind.html.erb +31 -0
  188. data/app/views/open_conference_ware/proposals/_transition_control.html.erb +16 -0
  189. data/app/views/open_conference_ware/proposals/create.html.erb +29 -0
  190. data/app/views/open_conference_ware/proposals/edit.html.erb +7 -0
  191. data/app/views/open_conference_ware/proposals/index.atom.builder +63 -0
  192. data/app/views/open_conference_ware/proposals/index.html.erb +46 -0
  193. data/app/views/open_conference_ware/proposals/new.html.erb +3 -0
  194. data/app/views/open_conference_ware/proposals/schedule.html.erb +108 -0
  195. data/app/views/open_conference_ware/proposals/sessions_index_terse.html.erb +22 -0
  196. data/app/views/open_conference_ware/proposals/show.html.erb +316 -0
  197. data/app/views/open_conference_ware/proposals/stats.html.erb +72 -0
  198. data/app/views/open_conference_ware/rooms/_form.html.erb +36 -0
  199. data/app/views/open_conference_ware/rooms/edit.html.erb +3 -0
  200. data/app/views/open_conference_ware/rooms/index.html.erb +13 -0
  201. data/app/views/open_conference_ware/rooms/new.html.erb +3 -0
  202. data/app/views/open_conference_ware/rooms/show.html.erb +27 -0
  203. data/app/views/open_conference_ware/schedule_items/_form.html.erb +35 -0
  204. data/app/views/open_conference_ware/schedule_items/edit.html.erb +3 -0
  205. data/app/views/open_conference_ware/schedule_items/index.html.erb +31 -0
  206. data/app/views/open_conference_ware/schedule_items/new.html.erb +3 -0
  207. data/app/views/open_conference_ware/schedule_items/show.html.erb +30 -0
  208. data/app/views/open_conference_ware/selector_votes/index.html.erb +81 -0
  209. data/app/views/open_conference_ware/session_types/_form.html.erb +23 -0
  210. data/app/views/open_conference_ware/session_types/edit.html.erb +3 -0
  211. data/app/views/open_conference_ware/session_types/index.html.erb +18 -0
  212. data/app/views/open_conference_ware/session_types/new.html.erb +3 -0
  213. data/app/views/open_conference_ware/session_types/show.html.erb +14 -0
  214. data/app/views/open_conference_ware/speaker_mailer/speaker_email.text.erb +14 -0
  215. data/app/views/open_conference_ware/tracks/_colors.css.erb +7 -0
  216. data/app/views/open_conference_ware/tracks/_form.html.erb +36 -0
  217. data/app/views/open_conference_ware/tracks/edit.html.erb +3 -0
  218. data/app/views/open_conference_ware/tracks/index.html.erb +25 -0
  219. data/app/views/open_conference_ware/tracks/new.html.erb +3 -0
  220. data/app/views/open_conference_ware/tracks/show.html.erb +19 -0
  221. data/app/views/open_conference_ware/user_favorites/index.html.erb +12 -0
  222. data/app/views/open_conference_ware/users/_account_box.html.erb +10 -0
  223. data/app/views/open_conference_ware/users/_block.html.erb +80 -0
  224. data/app/views/open_conference_ware/users/_list.html.erb +17 -0
  225. data/app/views/open_conference_ware/users/edit.html.erb +73 -0
  226. data/app/views/open_conference_ware/users/index.html.erb +28 -0
  227. data/app/views/open_conference_ware/users/new.html.erb +7 -0
  228. data/app/views/open_conference_ware/users/proposals.html.erb +24 -0
  229. data/app/views/open_conference_ware/users/show.html.erb +5 -0
  230. data/app/views/open_conference_ware/welcome/test.html.haml +8 -0
  231. data/bin/rails +8 -0
  232. data/ci/Gemfile.ci +13 -0
  233. data/ci/copy_database_config.rb +6 -0
  234. data/ci/database.mysql.yml +5 -0
  235. data/ci/database.postgresql.yml +4 -0
  236. data/ci/database.sqlite.yml +5 -0
  237. data/config/initializers/acts_as_taggable_on.rb +2 -0
  238. data/config/initializers/date_time_formats.rb +9 -0
  239. data/config/routes.rb +74 -0
  240. data/db/migrate/20131203235128_create_open_conference_ware_authentications.rb +14 -0
  241. data/db/migrate/20131203235216_create_open_conference_ware_comments.rb +14 -0
  242. data/db/migrate/20131203235418_create_open_conference_ware_events.rb +27 -0
  243. data/db/migrate/20131203235524_create_open_conference_ware_proposals.rb +36 -0
  244. data/db/migrate/20131203235723_create_open_conference_ware_rooms.rb +20 -0
  245. data/db/migrate/20131203235831_create_open_conference_ware_schedule_items.rb +18 -0
  246. data/db/migrate/20131203235910_create_open_conference_ware_selector_votes.rb +10 -0
  247. data/db/migrate/20131203235934_create_open_conference_ware_session_types.rb +14 -0
  248. data/db/migrate/20131204000008_create_open_conference_ware_snippets.rb +15 -0
  249. data/db/migrate/20131204000048_create_open_conference_ware_taggings.rb +16 -0
  250. data/db/migrate/20131204000129_create_open_conference_ware_tags.rb +7 -0
  251. data/db/migrate/20131204000147_create_open_conference_ware_tracks.rb +15 -0
  252. data/db/migrate/20131204000230_create_open_conference_ware_user_favorites.rb +10 -0
  253. data/db/migrate/20131204000251_create_open_conference_ware_users.rb +24 -0
  254. data/db/migrate/20131204000355_create_proposals_users_join_table.rb +8 -0
  255. data/db/seeds.rb +31 -0
  256. data/features/comment_create.feature +9 -0
  257. data/features/comment_destroy.feature +22 -0
  258. data/features/comment_new.feature +22 -0
  259. data/features/step_definitions/authentication_steps.rb +22 -0
  260. data/features/step_definitions/comment_create_steps.rb +5 -0
  261. data/features/step_definitions/comment_destroy_steps.rb +13 -0
  262. data/features/step_definitions/comment_new_steps.rb +41 -0
  263. data/features/step_definitions/notification_steps.rb +3 -0
  264. data/features/step_definitions/web_steps.rb +263 -0
  265. data/features/support/env.rb +58 -0
  266. data/features/support/helpers.rb +17 -0
  267. data/features/support/paths.rb +35 -0
  268. data/gem-public_cert.pem +22 -0
  269. data/lib/defer_proxy.rb +127 -0
  270. data/lib/ext/color_rgb_serializer_fix.rb +18 -0
  271. data/lib/ext/string_possessiveize.rb +7 -0
  272. data/lib/ext/vpim_icalendar_extra_properties.rb +25 -0
  273. data/lib/generators/open_conference_ware/install/USAGE +12 -0
  274. data/lib/generators/open_conference_ware/install/install_generator.rb +35 -0
  275. data/lib/generators/open_conference_ware/install/templates/config_initializer.rb +110 -0
  276. data/lib/generators/open_conference_ware/install/templates/omniauth_initializer.rb +33 -0
  277. data/lib/open_conference_ware.rb +156 -0
  278. data/lib/open_conference_ware/dependencies.rb +38 -0
  279. data/lib/open_conference_ware/engine.rb +38 -0
  280. data/lib/open_conference_ware/omni_auth_builder.rb +8 -0
  281. data/lib/open_conference_ware/version.rb +3 -0
  282. data/lib/rwikibot_page_drone.rb +70 -0
  283. data/lib/tasks/.gitkeep +0 -0
  284. data/lib/tasks/audio.rake +53 -0
  285. data/lib/tasks/cucumber.rake +65 -0
  286. data/lib/tasks/export.rake +170 -0
  287. data/lib/tasks/mediawiki.rake +96 -0
  288. data/lib/tasks/open_conference_ware_tasks.rake +16 -0
  289. data/lib/tasks/schedule.rake +103 -0
  290. data/lib/tasks/snippets.rake +23 -0
  291. data/open_conference_ware.gemspec +67 -0
  292. data/original_graphics/favorite.psd +0 -0
  293. data/spec/controllers/open_conference_ware/application_controller_spec.rb +309 -0
  294. data/spec/controllers/open_conference_ware/authentications_controller_spec.rb +87 -0
  295. data/spec/controllers/open_conference_ware/comments_controller_spec.rb +146 -0
  296. data/spec/controllers/open_conference_ware/events_controller_spec.rb +102 -0
  297. data/spec/controllers/open_conference_ware/manage_events_controller_spec.rb +103 -0
  298. data/spec/controllers/open_conference_ware/proposals_controller_spec.rb +1273 -0
  299. data/spec/controllers/open_conference_ware/rooms_controller_spec.rb +190 -0
  300. data/spec/controllers/open_conference_ware/selector_votes_controller_spec.rb +263 -0
  301. data/spec/controllers/open_conference_ware/session_types_controller_spec.rb +190 -0
  302. data/spec/controllers/open_conference_ware/sessions_routing_spec.rb +13 -0
  303. data/spec/controllers/open_conference_ware/tracks_controller_spec.rb +190 -0
  304. data/spec/controllers/open_conference_ware/user_favorites_controller_spec.rb +127 -0
  305. data/spec/controllers/open_conference_ware/users_controller_spec.rb +166 -0
  306. data/spec/dummy/README.rdoc +28 -0
  307. data/spec/dummy/Rakefile +6 -0
  308. data/spec/dummy/app/assets/images/.keep +0 -0
  309. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  310. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  311. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  312. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  313. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  314. data/spec/dummy/app/mailers/.keep +0 -0
  315. data/spec/dummy/app/models/.keep +0 -0
  316. data/spec/dummy/app/models/concerns/.keep +0 -0
  317. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  318. data/spec/dummy/bin/bundle +3 -0
  319. data/spec/dummy/bin/rails +4 -0
  320. data/spec/dummy/bin/rake +4 -0
  321. data/spec/dummy/config.ru +4 -0
  322. data/spec/dummy/config/application.rb +30 -0
  323. data/spec/dummy/config/boot.rb +5 -0
  324. data/spec/dummy/config/database.yml +25 -0
  325. data/spec/dummy/config/environment.rb +5 -0
  326. data/spec/dummy/config/environments/development.rb +29 -0
  327. data/spec/dummy/config/environments/production.rb +80 -0
  328. data/spec/dummy/config/environments/test.rb +36 -0
  329. data/spec/dummy/config/initializers/01_open_conference_ware.rb +110 -0
  330. data/spec/dummy/config/initializers/02_omniauth.rb +17 -0
  331. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  332. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  333. data/spec/dummy/config/initializers/inflections.rb +16 -0
  334. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  335. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  336. data/spec/dummy/config/initializers/session_store.rb +3 -0
  337. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  338. data/spec/dummy/config/locales/en.yml +23 -0
  339. data/spec/dummy/config/routes.rb +3 -0
  340. data/spec/dummy/db/schema.rb +219 -0
  341. data/spec/dummy/db/seeds.rb +10 -0
  342. data/spec/dummy/lib/assets/.keep +0 -0
  343. data/spec/dummy/log/.keep +0 -0
  344. data/spec/dummy/public/404.html +58 -0
  345. data/spec/dummy/public/422.html +58 -0
  346. data/spec/dummy/public/500.html +57 -0
  347. data/spec/dummy/public/favicon.ico +0 -0
  348. data/spec/factories/authentication_factory.rb +16 -0
  349. data/spec/factories/common_factory.rb +4 -0
  350. data/spec/factories/event_factory.rb +26 -0
  351. data/spec/factories/proposal_factory.rb +57 -0
  352. data/spec/factories/proposal_user_factory.rb +7 -0
  353. data/spec/factories/room_factory.rb +11 -0
  354. data/spec/factories/schedule_item_factory.rb +13 -0
  355. data/spec/factories/session_types_factory.rb +10 -0
  356. data/spec/factories/snippet_factory.rb +7 -0
  357. data/spec/factories/track_factory.rb +12 -0
  358. data/spec/factories/user_factory.rb +22 -0
  359. data/spec/factories/user_favorite_factory.rb +7 -0
  360. data/spec/features/sign_in_spec.rb +11 -0
  361. data/spec/features/snippets_spec.rb +38 -0
  362. data/spec/fixtures/open_conference_ware_comments.yml +27 -0
  363. data/spec/fixtures/open_conference_ware_events.yml +56 -0
  364. data/spec/fixtures/open_conference_ware_proposals.yml +256 -0
  365. data/spec/fixtures/open_conference_ware_rooms.yml +13 -0
  366. data/spec/fixtures/open_conference_ware_schedule_items.yml +23 -0
  367. data/spec/fixtures/open_conference_ware_session_types.yml +19 -0
  368. data/spec/fixtures/open_conference_ware_snippets.yml +62 -0
  369. data/spec/fixtures/open_conference_ware_tracks.yml +65 -0
  370. data/spec/fixtures/open_conference_ware_user_favorites.yml +7 -0
  371. data/spec/fixtures/open_conference_ware_users.yml +87 -0
  372. data/spec/helpers/open_conference_ware/application_helper_spec.rb +58 -0
  373. data/spec/helpers/open_conference_ware/authentications_helper_spec.rb +15 -0
  374. data/spec/helpers/open_conference_ware/display_link_to_helper_spec.rb +52 -0
  375. data/spec/helpers/open_conference_ware/proposals_helper_spec.rb +32 -0
  376. data/spec/helpers/open_conference_ware/rooms_helper_spec.rb +11 -0
  377. data/spec/helpers/open_conference_ware/session_types_helper_spec.rb +15 -0
  378. data/spec/helpers/open_conference_ware/time_range_helper_spec.rb +56 -0
  379. data/spec/helpers/open_conference_ware/tracks_helper_spec.rb +11 -0
  380. data/spec/helpers/open_conference_ware/user_favorites_helper_spec.rb +11 -0
  381. data/spec/integration/open_conference_ware/cache_lookups_mixin_spec.rb +122 -0
  382. data/spec/mixins/open_conference_ware/normalize_url_mixin_spec.rb +65 -0
  383. data/spec/models/open_conference_ware/authentication_spec.rb +67 -0
  384. data/spec/models/open_conference_ware/event_spec.rb +211 -0
  385. data/spec/models/open_conference_ware/proposal_spec.rb +606 -0
  386. data/spec/models/open_conference_ware/room_spec.rb +14 -0
  387. data/spec/models/open_conference_ware/schedule_item_spec.rb +12 -0
  388. data/spec/models/open_conference_ware/schedule_spec.rb +358 -0
  389. data/spec/models/open_conference_ware/selector_vote_spec.rb +12 -0
  390. data/spec/models/open_conference_ware/session_type_spec.rb +15 -0
  391. data/spec/models/open_conference_ware/snippet_spec.rb +13 -0
  392. data/spec/models/open_conference_ware/speaker_mailer_spec.rb +91 -0
  393. data/spec/models/open_conference_ware/track_spec.rb +36 -0
  394. data/spec/models/open_conference_ware/user_favorite_spec.rb +41 -0
  395. data/spec/models/open_conference_ware/user_spec.rb +77 -0
  396. data/spec/ocw_config.rb +76 -0
  397. data/spec/rcov.opts +2 -0
  398. data/spec/spec.opts +3 -0
  399. data/spec/spec_helper.rb +55 -0
  400. data/spec/spec_helper_customizations.rb +125 -0
  401. data/spec/support/add_all_helpers_to_view.rb +24 -0
  402. data/spec/support/authenticated_test_helper.rb +27 -0
  403. data/spec/support/fixture_shortcuts.rb +18 -0
  404. data/spec/support/omniauth.rb +34 -0
  405. data/spec/support/valid_params_extraction.rb +15 -0
  406. data/spec/views/open_conference_ware/proposals/_room_control.html.erb_spec.rb +23 -0
  407. data/spec/views/open_conference_ware/proposals/_transition_control.html.erb_spec.rb +14 -0
  408. data/spec/views/open_conference_ware/proposals/show.html.erb_spec.rb +128 -0
  409. data/spec/views/open_conference_ware/rooms/index.html.erb_spec.rb +19 -0
  410. data/spec/views/open_conference_ware/rooms/show.html.erb_spec.rb +15 -0
  411. data/spec/views/open_conference_ware/selector_votes/index.html.erb_spec.rb +41 -0
  412. data/spec/views/open_conference_ware/session_types/edit.html.erb_spec.rb +25 -0
  413. data/spec/views/open_conference_ware/session_types/index.html.erb_spec.rb +19 -0
  414. data/spec/views/open_conference_ware/session_types/new.html.erb_spec.rb +24 -0
  415. data/spec/views/open_conference_ware/session_types/show.html.erb_spec.rb +18 -0
  416. data/spec/views/open_conference_ware/tracks/edit.html.erb_spec.rb +25 -0
  417. data/spec/views/open_conference_ware/tracks/index.html.erb_spec.rb +56 -0
  418. data/spec/views/open_conference_ware/tracks/new.html.erb_spec.rb +26 -0
  419. data/spec/views/open_conference_ware/tracks/show.html.erb_spec.rb +23 -0
  420. data/spec/views/open_conference_ware/user_favorites/index.html.erb_spec.rb +29 -0
  421. data/spec/views/open_conference_ware/users/index_spec.rb +24 -0
  422. data/util/add_id3_tags_to_mp3.rb +57 -0
  423. data/util/schedule_demo.rb +36 -0
  424. data/util/seed_schedule.rb +61 -0
  425. data/util/sessions_to_lanyrd.rb +166 -0
  426. data/util/transfer_schedule_items.rb +25 -0
  427. data/util/update_proposal_status_from_voting_spreadsheet.rb +26 -0
  428. data/util/user_favorites_contention_report.rb +42 -0
  429. data/util/user_favorites_contention_report.sh +9 -0
  430. data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  431. data/vendor/assets/fonts/glyphicons-halflings-regular.svg +228 -0
  432. data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  433. data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  434. data/vendor/assets/images/farbtastic/marker.png +0 -0
  435. data/vendor/assets/images/farbtastic/mask.png +0 -0
  436. data/vendor/assets/images/farbtastic/wheel.png +0 -0
  437. data/vendor/assets/images/idselector/aol.ico +0 -0
  438. data/vendor/assets/images/idselector/arrow.gif +0 -0
  439. data/vendor/assets/images/idselector/arrow_white_back.png +0 -0
  440. data/vendor/assets/images/idselector/arrow_white_forward.png +0 -0
  441. data/vendor/assets/images/idselector/blogger.ico +0 -0
  442. data/vendor/assets/images/idselector/claimid.ico +0 -0
  443. data/vendor/assets/images/idselector/flickr.ico +0 -0
  444. data/vendor/assets/images/idselector/google.ico +0 -0
  445. data/vendor/assets/images/idselector/lj.ico +0 -0
  446. data/vendor/assets/images/idselector/myopenid.ico +0 -0
  447. data/vendor/assets/images/idselector/openid.ico +0 -0
  448. data/vendor/assets/images/idselector/technorati.ico +0 -0
  449. data/vendor/assets/images/idselector/verisign.ico +0 -0
  450. data/vendor/assets/images/idselector/vidoop2.ico +0 -0
  451. data/vendor/assets/images/idselector/vox.ico +0 -0
  452. data/vendor/assets/images/idselector/yahoo.ico +0 -0
  453. data/vendor/assets/javascripts/audiojs/audio.min.js +23 -0
  454. data/vendor/assets/javascripts/audiojs/audiojs.swf +0 -0
  455. data/vendor/assets/javascripts/audiojs/player-graphics.gif +0 -0
  456. data/vendor/assets/javascripts/bootstrap.js +1999 -0
  457. data/vendor/assets/javascripts/farbtastic.js +329 -0
  458. data/vendor/assets/javascripts/html5shiv.js +8 -0
  459. data/vendor/assets/javascripts/idselector.js +538 -0
  460. data/vendor/assets/javascripts/idselector~original.js +532 -0
  461. data/vendor/assets/javascripts/jquery-migrate-1.2.1.js +521 -0
  462. data/vendor/assets/javascripts/jquery.localScroll.js +106 -0
  463. data/vendor/assets/javascripts/jquery.scrollTo.js +174 -0
  464. data/vendor/assets/javascripts/respond.min.js +6 -0
  465. data/vendor/assets/stylesheets/bootstrap-theme.css +384 -0
  466. data/vendor/assets/stylesheets/bootstrap.css +6805 -0
  467. data/vendor/assets/stylesheets/farbtastic.css.scss +38 -0
  468. data/vendor/assets/stylesheets/persona-buttons.css +229 -0
  469. data/vendor/assets/stylesheets/reset-fonts-grids.css +7 -0
  470. metadata +1174 -0
  471. metadata.gz.sig +0 -0
@@ -0,0 +1,25 @@
1
+ module OpenConferenceWare
2
+ module AuthenticationsHelper
3
+ def auth_path(provider)
4
+ "#{OmniAuth.config.path_prefix}/#{provider}"
5
+ end
6
+
7
+ def auth_callback_path(provider)
8
+ "#{OmniAuth.config.path_prefix}/#{provider}/callback"
9
+ end
10
+
11
+ def grouped_auth_providers
12
+ @grouped_auth_providers ||= OpenConferenceWare.auth_providers.group_by do |provider|
13
+ lookup_context.find_all("open_conference_ware/authentications/_#{provider}").any? ? :with_partials : :without_partials
14
+ end
15
+ end
16
+
17
+ def auth_providers_with_partials
18
+ grouped_auth_providers[:with_partials]
19
+ end
20
+
21
+ def auth_providers_without_partials
22
+ grouped_auth_providers[:without_partials]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ module OpenConferenceWare
2
+ module CacheIfHelper
3
+ # Caches +block+ in view only if the +condition+ is true.
4
+ # http://skionrails.wordpress.com/2008/05/22/conditional-fragment-caching/
5
+ def cache_if(condition, name={}, &block)
6
+ if condition
7
+ cache(name, &block)
8
+ else
9
+ block.call
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ module OpenConferenceWare
2
+ module DisplayLinkToHelper
3
+
4
+ # Return a #link_to for a +url+ that's been sanitized by #h, had its text
5
+ # truncated, and optionally has the 'rel="nofollow"' flag set.
6
+ #
7
+ # Options:
8
+ # * maxlength: Maximum length of the displayed URL. Defaults to 64.
9
+ # * nofollow: Include a 'rel="nofollow"' in link to discourage spammers. Defaults to true.
10
+ # * mailto: The URL is an email address and should be rendered as a mailto link.
11
+ # * title: Title to give link, else URL.
12
+ def display_link_to(url, opts={})
13
+ opts.symbolize_keys!.reverse_merge!({
14
+ maxlength: 64,
15
+ nofollow: true,
16
+ mailto: false
17
+ })
18
+ link_to_opts = {}
19
+ link_to_opts[:rel] = "nofollow" if opts[:nofollow]
20
+ truncated_url = truncate(url, length: opts[:maxlength])
21
+ url = "mailto:#{url}" if opts[:mailto];
22
+ return link_to(h(opts[:title] || truncated_url), h(url), link_to_opts)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module OpenConferenceWare
2
+ module DisplayTextileForHelper
3
+ def display_textile_for(text)
4
+ return auto_link(textilize(sanitize(text || "")).html_safe, :all, rel: 'nofollow').html_safe
5
+ end
6
+
7
+ def display_textile_help_link
8
+ return link_to('Formatting', 'http://redcloth.org/hobix.com/textile/', target: "_blank")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module OpenConferenceWare
2
+ module FieldAnnotationHelper
3
+ def required_field
4
+ content_tag :span, "*", class: "required-field"
5
+ end
6
+
7
+ def private_field
8
+ content_tag :span, "%", class: "private-field"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module OpenConferenceWare
2
+ module FocusHelper
3
+
4
+ # Focus the form input on the +target+ id element.
5
+ def focus(target)
6
+ # # Plain JavaScript
7
+ # content_for :javascript, <<-HERE
8
+ # document.getElementById('#{target}').focus();
9
+ # HERE
10
+
11
+ # jQuery
12
+ run_when_dom_is_ready "$('##{h target.to_s}').focus();"
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ module OpenConferenceWare
2
+ module LocalcssHelper
3
+ # Use local CSS files? These are used if the server is running the
4
+ # "development" environment, or if there is a "localcss.flag" file, or the
5
+ # LOCALCSS environmental variable is set.
6
+ def localcss?
7
+ return Rails.env == "development" || ENV['LOCALCSS'] || File.exist?(File.join(Rails.root, "localcss.flag"))
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ module OpenConferenceWare
2
+ # = PageTitleHelper
3
+ #
4
+ # This mixin provides a #page_title helper for easily getting/setting the
5
+ # page's title, and providing a reasonable title if none was set.
6
+ module PageTitleHelper
7
+
8
+ # Return string to be used as a page title (e.g., for HTML's TITLE and H1).
9
+ # If +value+ provided, also sets page title. If no page title was set,
10
+ # provides a reasonable simulation based on the controller's name and action.
11
+ def page_title(value=nil)
12
+ @_page_title = value if value
13
+ return(@_page_title || "#{controller.controller_name.humanize}: #{action_name.humanize}")
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,54 @@
1
+ module OpenConferenceWare
2
+ module ProposalsHelper
3
+ # Return link with a +label+ for sorting records by +field+. The optional
4
+ # +kind+ (e.g., :sessions or :proposals) determines what URLs to generate, if
5
+ # one isn't specified, then the @kind instance variable will be used.
6
+ def sort_link_for(label, field, kind=nil)
7
+ kind ||= @kind
8
+
9
+ opts = {sort: field}
10
+ opts[:dir] = 'desc' if ( field == params[:sort] && params[:dir] != 'desc' )
11
+
12
+ link = link_to(label, self.send("event_#{kind}_path", @event, opts))
13
+ link += ( params[:dir] == 'desc' ? ' &or;' : ' &and;' ).html_safe if field == params[:sort]
14
+
15
+ return link
16
+ end
17
+
18
+ # Return a link path for the given +object+. The optional +kind+ (e.g.,
19
+ # :sessions or :proposals) determines what kind of links to make, if one
20
+ # isn't specified, then the @kind instance variable will be used.
21
+ def record_path(object, kind=nil)
22
+ kind ||= @kind
23
+ raise ArgumentError, "No kind or @kind specified" unless kind
24
+ kind = kind.to_s.singularize
25
+ return self.send("#{kind}_path", object)
26
+ end
27
+
28
+ # Return a link path for the collection. The optional +kind+ (e.g.,
29
+ # :sessions or :proposals) determines what kind of links to make, if one
30
+ # isn't specified, then the @kind instance variable will be used.
31
+ def records_path(kind=nil)
32
+ kind = (kind || @kind).to_s.pluralize
33
+ return self.send("event_#{kind}_path", @event)
34
+ end
35
+
36
+ # Return a path to the next proposal after +proposal+. Or none if none.
37
+ def next_proposal_path_from(proposal)
38
+ if next_proposal = proposal.next_proposal
39
+ return proposal_path(next_proposal)
40
+ else
41
+ return nil
42
+ end
43
+ end
44
+
45
+ # Return a path to the previous proposal after +proposal+. Or none if none.
46
+ def previous_proposal_path_from(proposal)
47
+ if previous_proposal = proposal.previous_proposal
48
+ return proposal_path(previous_proposal)
49
+ else
50
+ return nil
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,5 @@
1
+ module OpenConferenceWare
2
+ module RoomsHelper
3
+ include FauxRoutesMixin
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ module OpenConferenceWare
2
+ module ScrollToHelper
3
+ # Scroll the window with jQuery to the target selection.
4
+ #
5
+ # To an id:
6
+ #
7
+ # <% scroll_to '#event_open_text' %>
8
+ #
9
+ # To a query:
10
+ # <% scroll_to 'label[for=event_open_text]' %>
11
+ def scroll_to(target)
12
+ run_when_dom_is_ready "$('html,body').animate({scrollTop: $('#{h target.to_s}').offset().top},'slow');"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module OpenConferenceWare
2
+ module SessionTypesHelper
3
+ include FauxRoutesMixin
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ module OpenConferenceWare
2
+ # SnippetsHelper retrieves Snippet records and contents for views.
3
+ module SnippetsHelper
4
+ # Return the Snippet record matching the +slug+, else raise a
5
+ # ActiveRecord::RecordNotFound.
6
+ def snippet_record_for(slug)
7
+ if record = Snippet.lookup(slug.to_s)
8
+ return record
9
+ else
10
+ raise ActiveRecord::RecordNotFound, "Can't find snippet: #{slug}"
11
+ end
12
+ end
13
+
14
+ # Return the raw snippet content for a +slug+, else raises a
15
+ # ActiveRecord::RecordNotFound.
16
+ def raw_snippet_for(slug)
17
+ snippet_record_for(slug).content
18
+ end
19
+
20
+ # Returns the snippet content adorned with an "Edit" link if the user is an
21
+ # admin, the raw content if the user is a mortal, else raises a
22
+ # ActiveRecord::RecordNotFound.
23
+ def snippet_for(slug, use_simple_format=true)
24
+ record = snippet_record_for(slug)
25
+ string = record.content
26
+ if admin?
27
+ if matcher = string.match(%r{(.+)(</(?:div|p)>)\s*$}s)
28
+ string = matcher[1] + link_to("Edit", edit_manage_snippet_path(record), class: :snippet_edit_link) + matcher[2]
29
+ else
30
+ string = string + link_to("Edit", edit_manage_snippet_path(record), class: :snippet_edit_link)
31
+ end
32
+ end
33
+ return use_simple_format ? simple_format(string) : string
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,198 @@
1
+ module OpenConferenceWare
2
+ module TimeRangeHelper
3
+ def normalize_time(start_time, end_time=nil, opts=nil)
4
+ TimeRange.new(start_time, end_time, opts).to_s
5
+ # datetime_format(time,time.min == 0 ? '%I%p' : '%I:%M%p').downcase
6
+ end
7
+ end
8
+
9
+ class TimeRange
10
+ # A representation of a time or range of time that can format itself
11
+ # in a meaningful way. Examples:
12
+ # "Thursday, April 3, 2008"
13
+ # "Thursday, April 3, 2008 at 4pm"
14
+ # "Thursday, April 3, 2008 from 4:30-6pm"
15
+ # (context: in the list for today) "11:30am-2pm"
16
+ # "Thursday-Friday, April 3-5, 2008"
17
+ # (context: during 2008) "Thursday April 5, 2009 at 3:30pm through Friday, April 5 at 8:45pm, 2009"
18
+ # (same, context: during 2009) "Thursday April 5 at 3:30pm through Friday, April 5 at 8:45pm"
19
+
20
+ @@to_s_cache = {}
21
+
22
+ def initialize(start_time, end_time=nil, opts=nil)
23
+ # Initialize with a single DateTime, a pair of DateTimes,
24
+ # or an object that responds_to start_time and end_time, and
25
+ # several options
26
+ #
27
+ # By default (unless format: :text) include <abbr> tags
28
+ # for hCalendar, and (unless relative: false) refer to
29
+ # "today", "yesterday", and "tomorrow" using those labels;
30
+ # if a :context date is provided, omit unnecessary date parts.
31
+ if end_time.is_a? Hash
32
+ opts = end_time
33
+ end_time = nil
34
+ else
35
+ opts ||= {}
36
+ end
37
+ if end_time.nil? and start_time.respond_to?(:start_time)
38
+ @start_time = start_time.start_time
39
+ @end_time = start_time.end_time
40
+ else
41
+ @start_time = start_time
42
+ @end_time = end_time
43
+ end
44
+ @format = opts[:format] || :hcal
45
+ @relative = opts[:relative] || false
46
+ @context_date = opts[:context]
47
+ end
48
+
49
+ def cache_key
50
+ return [@start_time, @end_time, @format, @relative, @context_date].hash
51
+ end
52
+
53
+ def to_s
54
+ return @@to_s_cache[cache_key] ||= self.to_s_raw.html_safe
55
+ end
56
+
57
+ def to_s_raw
58
+ # Assume one date only, equal start/end
59
+ start_format_list = [nil, :wday, :month, :day, :year, :at, :hour, :min, :suffix, nil]
60
+
61
+ start_details = time_details(@start_time)
62
+ if @end_time.nil? or @start_time == @end_time
63
+ # One date only, or equal dates.
64
+ end_format_list = conjunction = nil
65
+ else
66
+ end_details = time_details(@end_time)
67
+ if @start_time.to_date == @end_time.to_date
68
+ start_format_list[start_format_list.index(:at)] = :from
69
+ conjunction = @format == :text ? " - " : " &ndash; "
70
+ if start_details[:suffix] == end_details[:suffix]
71
+ # same day & am/pm
72
+ # Tuesday, April 1, 2008 from 9-11am
73
+ start_format_list.delete(:suffix)
74
+ end_format_list = [nil, :hour, :min, :suffix, nil]
75
+ else
76
+ # same day, different am/pm
77
+ # Tuesday, April 1, 2008 from 9am-1:30pm
78
+ end_format_list = [nil, :hour, :min, :suffix, nil]
79
+ end
80
+ else
81
+ # different days:
82
+ # Tuesday, April 1, 2008 at 9am through Wednesday, April 1, 2009 at 1:30pm
83
+ end_format_list = start_format_list.clone
84
+ conjunction = " through "
85
+ end
86
+ end
87
+
88
+ # Remove stuff implied by our context
89
+ if @context_date
90
+ # Do it to both start & end lists
91
+ [[@start_time, start_format_list], [@end_time, end_format_list]].each do |t, list|
92
+ if t and list
93
+ list.delete(:year) if @context_date.year == t.year # same year
94
+ [:wday, :month, :day, :at, :from].each do |k|
95
+ list.delete(k)
96
+ end if @context_date == t.to_date
97
+ end
98
+ end
99
+ end
100
+
101
+ # Combine the pieces
102
+ results = []
103
+ results << %Q|<abbr class="dtstart" title="#{@start_time.strftime('%Y-%m-%dT%H:%M:%S')}">| if @format == :hcal
104
+ results << format_details_by_list(start_details, start_format_list)
105
+ results << %Q|</abbr>| if @format == :hcal
106
+ if end_format_list
107
+ results << conjunction
108
+ results << %Q|<abbr class="dtend" title="#{@end_time.strftime('%Y-%m-%dT%H:%M:%S')}">| if @format == :hcal
109
+ results << format_details_by_list(end_details, end_format_list)
110
+ results << %Q|</abbr>| if @format == :hcal
111
+ end
112
+ results.join
113
+ end
114
+
115
+ protected
116
+
117
+ PREFIXES = {
118
+ hour: " ",
119
+ [nil, :hour] => "",
120
+ year: ", ",
121
+ end_hour: " ",
122
+ end_year: ", ",
123
+ }
124
+ SUFFIXES = {
125
+ month: " ",
126
+ wday: ", ",
127
+ }
128
+ STRINGS = {
129
+ from: " from",
130
+ at: " at",
131
+ }
132
+
133
+ def format_details_by_list(details, format_list)
134
+ # Given a hash of date details, and a format_list of the keys
135
+ # that should be emitted, produce a list of the pieces.
136
+ #
137
+ # Include any extra pieces implied by juxtaposition: eg,
138
+ # if PREFIXES[:hour] is " ", include a " " piece just
139
+ # before the hour, unless nil immediately
140
+ # preceded :hour and we have a PREFIXES[[nil, :hour]], in
141
+ # which case we'll emit that instead.
142
+ results = []
143
+ format_list.each_cons(3) do |before, part, after|
144
+ results << (PREFIXES[[before, part]] || PREFIXES[part])
145
+ results << (details[part] || STRINGS[part])
146
+ results << (SUFFIXES[[part, after]] || SUFFIXES[part])
147
+ end
148
+ results
149
+ end
150
+
151
+ def date_details(d)
152
+ # Get the parts for formatting a date, as a hash of
153
+ # strings: keys (roughly) match the equivalent methods on Date, but only
154
+ # relevant keys will be filled in. If relative is true (the default):
155
+ # - if it's today, tomorrow, or yesterday, :wday will be eg "today"
156
+ # (with no other date fields)
157
+ case @relative && d.to_date - Date.today
158
+ when 1
159
+ { wday: "tomorrow" }
160
+ when 0
161
+ { wday: "today" }
162
+ when -1
163
+ { wday: "yesterday" }
164
+ else
165
+ { wday: Date::DAYNAMES[d.wday],
166
+ month: Date::MONTHNAMES[d.month],
167
+ day: d.day.to_s,
168
+ year: d.year.to_s }
169
+ end
170
+ end
171
+
172
+ def time_details(t)
173
+ # Get the parts for formatting this time, as a hash of
174
+ # strings: keys (roughly) match the equivalent methods on DateTime, but only
175
+ # relevant keys will be filled in. If relative is true (the default):
176
+ # - if it's today, tomorrow, or yesterday, :wday will be eg "today"
177
+ # (with no other date fields)
178
+ # - if it's exactly noon or midnight, :hour will be eg "noon"
179
+ # (with no other time fields)
180
+ details = date_details(t)
181
+ if t.min == 0
182
+ return details.merge(hour: "Midnight") if t.hour == 0
183
+ return details.merge(hour: "Noon") if t.hour == 12
184
+ end
185
+ if t.hour >= 12
186
+ suffix = "pm"
187
+ h = t.hour - (t.hour > 12 ? 12 : 0)
188
+ else
189
+ suffix = "am"
190
+ h = t.hour == 0 ? 12 : t.hour
191
+ end
192
+ m = ":%02d" % t.min
193
+ details.merge(hour: h.to_s,
194
+ min: m,
195
+ suffix: suffix)
196
+ end
197
+ end
198
+ end