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,9 @@
1
+ module OpenConferenceWare
2
+ module TracksHelper
3
+ include FauxRoutesMixin
4
+
5
+ def track_css_class(track)
6
+ "track-#{track.id}"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module OpenConferenceWare
2
+ module UserFavoritesHelper
3
+ # Add JavaScript to layout that populates the user's favorites and binds these controls.
4
+ def include_user_favorites_javascript
5
+ expose_to_js :favorites_path, user_favorites_path(user_id: :me)
6
+ run_when_dom_is_ready 'populate_user_favorites();'
7
+ run_when_dom_is_ready 'bind_user_favorite_controls();'
8
+ end
9
+
10
+ # Return link for a UserFavorite control for the given +proposal+.
11
+ def user_favorite_control_for(proposal)
12
+ return link_to(content_tag(:span, "*"), user_favorites_path(:me), class: "favorite favorite_#{proposal.id}")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,51 @@
1
+ module OpenConferenceWare
2
+ class SpeakerMailer < ActionMailer::Base
3
+
4
+ # Provide ::raw_snippet_for
5
+ include SnippetsHelper
6
+
7
+ # Provide ::strip_tags
8
+ include ActionView::Helpers::SanitizeHelper
9
+ extend ActionView::Helpers::SanitizeHelper::ClassMethods
10
+
11
+
12
+ def self.configured?
13
+ if !Rails.env.test? && (OpenConferenceWare.email.blank? || OpenConferenceWare.email['action_mailer'].blank? || OpenConferenceWare.email['default_from_address'] == 'test')
14
+ return false
15
+ else
16
+ return true
17
+ end
18
+ end
19
+
20
+ def clean_snippet(slug)
21
+ text = raw_snippet_for(slug)
22
+ text = text.gsub(/<br>/, "\n")
23
+ strip_tags(text)
24
+ end
25
+
26
+ def speaker_email(subject_snippet, body_snippet, proposal)
27
+ unless self.class.configured?
28
+ raise ArgumentError, "Email settings must be set in 'config/secrets.yml'"
29
+ end
30
+
31
+ @proposal = proposal
32
+ @body_text = clean_snippet(body_snippet)
33
+
34
+ mail(
35
+ to: proposal.mailto_emails,
36
+ bcc: OpenConferenceWare.default_bcc_address,
37
+ from: OpenConferenceWare.default_from_address,
38
+ subject: clean_snippet(subject_snippet),
39
+ template_name: 'speaker_email'
40
+ )
41
+ end
42
+
43
+ def speaker_accepted_email(proposal)
44
+ speaker_email('proposals_acceptance_email_subject', 'proposals_acceptance_email_text', proposal)
45
+ end
46
+
47
+ def speaker_rejected_email(proposal)
48
+ speaker_email('proposals_rejected_email_subject', 'proposals_rejected_email_text', proposal)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,76 @@
1
+ module OpenConferenceWare
2
+
3
+ # = BreadcrumbsMixin
4
+ #
5
+ # Adds breadcrumb trail to pages.
6
+ #
7
+ # == Usage
8
+ #
9
+ # In your application controller:
10
+ #
11
+ # class Application < ActionController::Base
12
+ # include BreadcrumbsMixin
13
+ # end
14
+ #
15
+ # In each controller you want to add a resource-level breadcrumb:
16
+ #
17
+ # class ThingsController < ActionController::Base
18
+ # add_breadcrumb "Things", "/things"
19
+ # end
20
+ #
21
+ # In each action you want to add a breadcrumb:
22
+ #
23
+ # class ThingsController < ActionController::Base
24
+ # ...
25
+ #
26
+ # def show
27
+ # ...
28
+ # @thing = Thing.find(params[:id])
29
+ # add_breadcrumb @thing.title, thing_path(@thing)
30
+ # end
31
+ # end
32
+ module BreadcrumbsMixin
33
+
34
+ def self.included(mixee)
35
+ mixee.module_eval do
36
+ # http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/
37
+
38
+ # Add a breadcrumb. E.g.:
39
+ #
40
+ # add_breadcrumb('Ignite Portland', 'http://igniteportland.com/')
41
+ def add_breadcrumb(name, url='')
42
+ @breadcrumbs ||= []
43
+ url = eval(url) if url =~ /_path|_url|@/
44
+ @breadcrumbs << [name, url]
45
+ end
46
+
47
+ # Add multiple breadcrumbs at once. Input is an array of arrays whose
48
+ # elements are a name and URL. E.g.:
49
+ #
50
+ # add_breadcrumbs([
51
+ # ['Ignite Portland', 'http://igniteportland.com/'],
52
+ # ['Proposals', '/proposals/'],
53
+ # ])
54
+ def add_breadcrumbs(breadcrumbs)
55
+ breadcrumbs.each do |breadcrumb|
56
+ add_breadcrumb(*breadcrumb)
57
+ end
58
+ end
59
+
60
+ # Add breadcrumb within a controller. Accepts same arguments as #add_breadcrumb.
61
+ def self.add_breadcrumb(name, url='', options={})
62
+ before_filter(options) do |controller|
63
+ controller.send(:add_breadcrumb, name, url)
64
+ end
65
+ end
66
+
67
+ # Add multiple breadcrumbs within a controller. Accepts same arguments as #add_breadcrumb.
68
+ def self.add_breadcrumbs(breadcrumbs, options={})
69
+ before_filter(options) do |controller|
70
+ controller.send(:add_breadcrumbs, breadcrumbs)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,128 @@
1
+ module OpenConferenceWare
2
+
3
+ # = CacheLookupsMixin
4
+ #
5
+ # A mixin that provides simple caching for ActiveRecord models. It's best used
6
+ # for models that have relatively few records (less than a thousand) and are
7
+ # updated infrequently (less than once per second).
8
+ #
9
+ # == Example of usage
10
+ #
11
+ # Setup lookups for Thing:
12
+ #
13
+ # class Thing < ActiveRecord::Base
14
+ # cache_lookups_for :id, order: :created_at
15
+ # ...
16
+ # end
17
+ #
18
+ # Return array of things in the order they were created:
19
+ # things = Thing.lookup
20
+ #
21
+ # Return a particular Thing matching ID 66:
22
+ # thing = Thing.lookup(66)
23
+ module CacheLookupsMixin
24
+ def self.included(mixee)
25
+ mixee.send(:extend, ClassMethods)
26
+ mixee.class_eval do
27
+ # ActiveRecord model's attribute to use when asked to lookup a specific
28
+ # item. Defaults to :id.
29
+ cattr_accessor :lookup_key
30
+ self.lookup_key = :id
31
+
32
+ # Hash of options passed to ActiveRecord::Base.find when populating the
33
+ # cache. This makes it possible to add :order and filter by :condition.
34
+ cattr_accessor :lookup_opts
35
+ self.lookup_opts = {}
36
+ end
37
+ end
38
+
39
+ module ClassMethods
40
+ # Should lookups be cached? If the "perform_caching" Rails environment
41
+ # configuration setting is enabled, default to using cache.
42
+ #
43
+ # You can force caching on or off using the CACHELOOKUPS environmental
44
+ # variable, e.g. activate with:
45
+ #
46
+ # CACHELOOKUPS=1 ./script/server
47
+ def cache_lookups?
48
+ if Rails.configuration.action_controller.perform_caching
49
+ return ENV['CACHELOOKUPS'] != '0'
50
+ else
51
+ return ENV['CACHELOOKUPS'] == '1'
52
+ end
53
+ end
54
+
55
+ # Setup the lookup caching system.
56
+ #
57
+ # Arguments:
58
+ # * key: The attribute you'll use as a key for doing lookups.
59
+ # * opts: Options to pass to ActiveRecord::Base.find.
60
+ def cache_lookups_for(key, opts={})
61
+ self.lookup_key = key
62
+ self.lookup_opts = opts
63
+ end
64
+
65
+ # Return silo that this class's values will be stored in.
66
+ def lookup_silo_name
67
+ return "#{self.name.gsub('::', '__')}_dict"
68
+ end
69
+
70
+ def query_one(key)
71
+ return self.where(self.lookup_key => key).first
72
+ end
73
+
74
+ def query_all
75
+ scope = self
76
+ scope = scope.order(self.lookup_opts[:order]) if self.lookup_opts[:order]
77
+ scope = scope.includes(*self.lookup_opts[:include]) if self.lookup_opts[:include]
78
+ return scope
79
+ end
80
+
81
+ # Return instance from cache matching +key+. If +key+ is undefined, returns
82
+ # array of all instances.
83
+ def lookup(key=nil)
84
+ unless self.cache_lookups?
85
+ return key ?
86
+ self.query_one(key) :
87
+ self.query_all
88
+ end
89
+
90
+ silo = self.lookup_silo_name
91
+ key_number = key.try(:[], '#'+to_s) if key.present?
92
+ ActiveRecord::Base.benchmark("Lookup: #{silo}#{key_number}") do
93
+ dict = self.fetch_object(silo){
94
+ # FIXME Exceptions within this block are silently swallowed by something. This is bad.
95
+ dict = Hashery::Dictionary.new
96
+ for record in self.query_all
97
+ dict[record.send(self.lookup_key)] = record
98
+ end
99
+ dict
100
+ }
101
+ return key ? dict[key.kind_of?(Symbol) ? key.to_s : key] : dict.values
102
+ end
103
+ end
104
+
105
+ def expire_cache
106
+ Rails.logger.info("Lookup, expiring: #{self.name}")
107
+ CacheWatcher.expire(/#{lookup_silo_name}_.+/)
108
+ end
109
+
110
+ def fetch_object(silo, &block)
111
+ self.revive_associations_for(self)
112
+ return Rails.cache.fetch(silo, &block)
113
+ end
114
+
115
+ def revive_associations_for(object)
116
+ if object.kind_of?(ActiveRecord::Base) || object.ancestors.include?(ActiveRecord::Base)
117
+ object.reflect_on_all_associations.each do |association|
118
+ name = association.class_name
119
+ unless object.constants.include?(name)
120
+ name.constantize # This line forces Rails to load this class
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ end
128
+ end
@@ -0,0 +1,83 @@
1
+ module OpenConferenceWare
2
+
3
+ # = FauxRoutesMixin
4
+ #
5
+ # The FauxRoutesMixin generates a bunch of route helpers for the
6
+ # TracksController and SessionTypesController nested resources.
7
+ #
8
+ # == Examples
9
+ #
10
+ # Long-hand way of expressing "/events/:event_id/tracks/:track_id":
11
+ # event_track_path(@event, @track)
12
+ #
13
+ # Faux route helper for expressing the same thing and getting Event from @event:
14
+ # track_path(@track)
15
+ #
16
+ module FauxRoutesMixin
17
+ # FIXME this implementation is 10x more complex than it should be, but I don't know how to make it simpler
18
+
19
+ TRACE = false
20
+
21
+ def self.included(mixee)
22
+ mixee.extend(Methods)
23
+
24
+ if mixee.ancestors.include?(ActionController::Base)
25
+ mixee.class_eval do
26
+ Methods.instance_methods.each do |name|
27
+ Rails.logger.debug("Faux route, helperized: #{name}") if TRACE
28
+ helper_method(name)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ module Methods
35
+ # Create a single route for the +options+.
36
+ faux_route_for = lambda do |opts|
37
+ verb = opts[:verb] # The action prefix for the route, e.g., the "new" in "new_track".
38
+ noun = opts[:noun] # The singular resource to create a route for, e.g., "track".
39
+ item = opts[:item] # Does this verb operate on an item and need an id, e.g., "new_track" does not, but "edit_track" does.
40
+ for kind in %w[path url]
41
+ real = "#{verb ? verb+'_' : nil}event_#{noun}_#{kind}"
42
+ faux = "#{verb ? verb+'_' : nil}#{noun}_#{kind}"
43
+ msg = nil
44
+ if item
45
+ msg = "Faux route, created for item: #{faux} <= #{real}"
46
+ define_method(faux, proc{|item, *args| send(real, item.event, item, *args)})
47
+ else
48
+ msg = "Faux route, created for inference: #{faux} <= #{real}"
49
+ define_method(faux, proc{|*args|
50
+ event = @event
51
+ if ! event && self.respond_to?(:get_current_event_and_assignment_status)
52
+ event = self.get_current_event_and_assignment_status.first
53
+ end
54
+ raise ArgumentError, "No event found for faux route" unless event
55
+ send(real, event, *args)
56
+ })
57
+ end
58
+ Rails.logger.debug(msg) if TRACE
59
+ end
60
+ end
61
+
62
+ # Create all common routes for this +resource+.
63
+ faux_routes_for = lambda do |resource|
64
+ resource = resource.to_s.singularize
65
+ faux_route_for[noun: resource]
66
+ faux_route_for[noun: resource.pluralize]
67
+ faux_route_for[noun: resource, verb: "new"]
68
+ faux_route_for[noun: resource, item: true]
69
+ faux_route_for[noun: resource, verb: "edit", item: true]
70
+ end
71
+
72
+ # Create faux routes for the following +resources+:
73
+ faux_routes_for["tracks"]
74
+ faux_routes_for["session_types"]
75
+ faux_routes_for["rooms"]
76
+ faux_routes_for["schedule_items"]
77
+ end
78
+
79
+ include Methods
80
+ extend Methods
81
+
82
+ end
83
+ end
@@ -0,0 +1,40 @@
1
+ module OpenConferenceWare
2
+ module NormalizeUrlMixin
3
+ def self.included(mixee)
4
+ mixee.send(:extend, ClassMethods)
5
+ mixee.send(:include, ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ # Return a normalized URL, with the scheme prefix added, or raise an
10
+ # URI::InvalidURIError if invalid.
11
+ def normalize_url!(url)
12
+ uri = URI.parse(url.strip)
13
+ uri.scheme = 'http' unless ['http','ftp'].include?(uri.scheme) || uri.scheme.nil?
14
+ return URI.parse(uri.scheme.nil? ? 'http://'+url.strip : uri.to_s).normalize.to_s
15
+ end
16
+
17
+ # Validate that +attributes+ each contain a valid URL or are blank. If any
18
+ # are invalid, returns false. Invalid attributes will be marked with an
19
+ # ActiveRecord validation error.
20
+ def validate_url_attribute(*attributes)
21
+ valid = true
22
+ for attribute in [attributes].flatten
23
+ value = self.read_attribute(attribute)
24
+ next if value.blank?
25
+ begin
26
+ url = self.normalize_url!(value)
27
+ self.send("#{attribute}=", url)
28
+ rescue URI::InvalidURIError => e
29
+ self.errors.add(attribute, 'is invalid')
30
+ valid = false
31
+ end
32
+ end
33
+ return valid
34
+ end
35
+ end
36
+
37
+ include ClassMethods
38
+ extend ClassMethods
39
+ end
40
+ end
@@ -0,0 +1,62 @@
1
+ module OpenConferenceWare
2
+ # = PublicAttributesMixin
3
+ #
4
+ # The PublicAttributesMixin provides a simple way to mark attributes as
5
+ # publicly-known and export only their data. This mixin is useful for
6
+ # selectively exposing attributes to AJAX methods and exporter programs where
7
+ # you do not want to publish confidential data, such as email addresses,
8
+ # passwords, etc.
9
+ #
10
+ # == Usage
11
+ #
12
+ # Include the mixin and set the public attribute names:
13
+ #
14
+ # class User < ActiveRecord::Base
15
+ # include PublicAttributesMixin
16
+ # set_public_attributes :id, :first_name, :last_name
17
+ # end
18
+ #
19
+ # Export data for a record:
20
+ #
21
+ # user = User.first
22
+ # puts user.public_attributes.inspect
23
+ # # => {"id" => 123, "first_name" => "Bubba", "last_name" => "Smith"}
24
+ module PublicAttributesMixin
25
+ def self.included(receiver)
26
+ receiver.send(:cattr_accessor, :public_attribute_keys)
27
+ receiver.send("public_attribute_keys=", [])
28
+ receiver.send(:extend, ClassMethods)
29
+ receiver.send(:include, InstanceMethods)
30
+ end
31
+
32
+ module ClassMethods
33
+ # Set the names of public attributes. Can specify attributes using strings
34
+ # or symbols, and as an array or arguments.
35
+ def set_public_attributes(*args)
36
+ self.public_attribute_keys = [args].flatten.map(&:to_sym)
37
+ end
38
+ end
39
+
40
+ module InstanceMethods
41
+ # Return a hash of public attributes.
42
+ def public_attributes
43
+ return self.public_attribute_keys.inject({}) do |result, key|
44
+ result[key.to_s] = self.send(key) if self.public_attribute_keys.include?(key.to_sym)
45
+ result
46
+ end
47
+ end
48
+
49
+ def serializable_hash(options={})
50
+ if (options.keys & [:only, :except, :methods, :include]).present?
51
+ super(options)
52
+ else
53
+ public_attributes
54
+ end
55
+ end
56
+
57
+ def to_xml(options={})
58
+ serializable_hash(options).to_xml(options)
59
+ end
60
+ end
61
+ end
62
+ end