droom 0.0.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (459) hide show
  1. data/README.md +2 -2
  2. data/app/assets/images/droom/Untitled-1.png +0 -0
  3. data/app/assets/images/droom/acceptance.png +0 -0
  4. data/app/assets/images/droom/add.png +0 -0
  5. data/app/assets/images/droom/asterisk.png +0 -0
  6. data/app/assets/images/droom/asterisk_up.png +0 -0
  7. data/app/assets/images/droom/checkboxes.png +0 -0
  8. data/app/assets/images/droom/clear.png +0 -0
  9. data/app/assets/images/droom/cog.png +0 -0
  10. data/app/assets/images/droom/copy.png +0 -0
  11. data/app/assets/images/droom/copy_to_dropbox.png +0 -0
  12. data/app/assets/images/droom/crosses.png +0 -0
  13. data/app/assets/images/droom/dark_scrap_icons.png +0 -0
  14. data/app/assets/images/droom/defilter.png +0 -0
  15. data/app/assets/images/droom/delete.png +0 -0
  16. data/app/assets/images/droom/dropbox.png +0 -0
  17. data/app/assets/images/droom/dropbox_button.png +0 -0
  18. data/app/assets/images/droom/dropbox_button_small.png +0 -0
  19. data/app/assets/images/droom/edit.png +0 -0
  20. data/app/assets/images/droom/expand.png +0 -0
  21. data/app/assets/images/droom/expander.png +0 -0
  22. data/app/assets/images/droom/folder.png +0 -0
  23. data/app/assets/images/droom/image_box.png +0 -0
  24. data/app/assets/images/droom/in_dropbox.png +0 -0
  25. data/app/assets/images/droom/integration_buttons.png +0 -0
  26. data/app/assets/images/droom/leftright.png +0 -0
  27. data/app/assets/images/droom/manage.png +0 -0
  28. data/app/assets/images/droom/medium_object_icons.png +0 -0
  29. data/app/assets/images/droom/object_icons.png +0 -0
  30. data/app/assets/images/droom/playable.png +0 -0
  31. data/app/assets/images/droom/revoke.png +0 -0
  32. data/app/assets/images/droom/scrap_icons.png +0 -0
  33. data/app/assets/images/droom/search.png +0 -0
  34. data/app/assets/images/droom/small_asterisk.png +0 -0
  35. data/app/assets/images/droom/small_cog.png +0 -0
  36. data/app/assets/images/droom/small_download.png +0 -0
  37. data/app/assets/images/droom/small_image_box.png +0 -0
  38. data/app/assets/images/droom/smalladd.png +0 -0
  39. data/app/assets/images/droom/smallarrows.png +0 -0
  40. data/app/assets/images/droom/smallcopy.png +0 -0
  41. data/app/assets/images/droom/smalldelete.png +0 -0
  42. data/app/assets/images/droom/smalldownload.png +0 -0
  43. data/app/assets/images/droom/smalledit.png +0 -0
  44. data/app/assets/images/droom/smallmanage.png +0 -0
  45. data/app/assets/images/droom/star.png +0 -0
  46. data/app/assets/images/droom/symbols.png +0 -0
  47. data/app/assets/images/droom/tinyarrows.png +0 -0
  48. data/app/assets/images/droom/to_dropbox.png +0 -0
  49. data/app/assets/images/droom/twisty.png +0 -0
  50. data/app/assets/images/droom/youtube_icon.png +0 -0
  51. data/app/assets/javascripts/droom.js.coffee +62 -65
  52. data/app/assets/javascripts/droom/actions.js.coffee +492 -0
  53. data/app/assets/javascripts/droom/ajax.js.coffee +84 -0
  54. data/app/assets/javascripts/droom/{lib/extensions.js.coffee → extensions.js.coffee} +22 -15
  55. data/app/assets/javascripts/droom/lib/ZeroClipboard.js +334 -0
  56. data/app/assets/javascripts/droom/lib/ZeroClipboard.swf +0 -0
  57. data/app/assets/javascripts/droom/lib/ZeroClipboard10.swf +0 -0
  58. data/app/assets/javascripts/droom/map.js.coffee +124 -86
  59. data/app/assets/javascripts/droom/popups.js.coffee +252 -0
  60. data/app/assets/javascripts/droom/stream.js.coffee +92 -0
  61. data/app/assets/javascripts/droom/utilities.js.coffee +120 -0
  62. data/app/assets/javascripts/droom/widgets.js.coffee +1209 -0
  63. data/app/assets/stylesheets/_definitions.css.sass +189 -0
  64. data/app/assets/stylesheets/droom.css.sass +1429 -376
  65. data/app/assets/stylesheets/lib/_kalendae.css.sass +2 -5
  66. data/app/assets/stylesheets/lib/_popups.css.sass +86 -0
  67. data/app/assets/stylesheets/lib/_toolbar.css.sass +17 -11
  68. data/app/controllers/droom/agenda_categories_controller.rb +24 -0
  69. data/app/controllers/droom/calendars_controller.rb +29 -0
  70. data/app/controllers/droom/confirmations_controller.rb +38 -0
  71. data/app/controllers/droom/dashboard_controller.rb +2 -0
  72. data/app/controllers/droom/documents_controller.rb +42 -51
  73. data/app/controllers/droom/dropbox_tokens_controller.rb +61 -0
  74. data/app/controllers/droom/engine_controller.rb +8 -23
  75. data/app/controllers/droom/events_controller.rb +39 -27
  76. data/app/controllers/droom/folders_controller.rb +106 -0
  77. data/app/controllers/droom/group_invitations_controller.rb +15 -7
  78. data/app/controllers/droom/groups_controller.rb +4 -4
  79. data/app/controllers/droom/invitations_controller.rb +37 -9
  80. data/app/controllers/droom/memberships_controller.rb +5 -3
  81. data/app/controllers/droom/organisations_controller.rb +53 -0
  82. data/app/controllers/droom/people_controller.rb +46 -27
  83. data/app/controllers/droom/preferences_controller.rb +34 -0
  84. data/app/controllers/droom/scraps_controller.rb +77 -0
  85. data/app/controllers/droom/search_controller.rb +66 -0
  86. data/app/controllers/droom/suggestions_controller.rb +22 -35
  87. data/app/controllers/droom/users_controller.rb +69 -0
  88. data/app/controllers/droom/venues_controller.rb +1 -2
  89. data/app/controllers/droom/youtube_controller.rb +22 -0
  90. data/app/helpers/droom/droom_helper.rb +93 -5
  91. data/app/models/droom/agenda_category.rb +8 -1
  92. data/app/models/droom/calendar.rb +19 -0
  93. data/app/models/droom/category.rb +4 -6
  94. data/app/models/droom/document.rb +103 -64
  95. data/app/models/droom/document_attachment.rb +13 -47
  96. data/app/models/droom/dropbox_document.rb +41 -0
  97. data/app/models/droom/dropbox_token.rb +29 -0
  98. data/app/models/droom/event.rb +125 -90
  99. data/app/models/droom/folder.rb +134 -0
  100. data/app/models/droom/group.rb +68 -27
  101. data/app/models/droom/group_invitation.rb +12 -3
  102. data/app/models/droom/invitation.rb +50 -8
  103. data/app/models/droom/mailing_list_membership.rb +128 -0
  104. data/app/models/droom/membership.rb +71 -9
  105. data/app/models/droom/organisation.rb +22 -0
  106. data/app/models/droom/page.rb +3 -3
  107. data/app/models/droom/person.rb +180 -166
  108. data/app/models/droom/personal_folder.rb +31 -0
  109. data/app/models/droom/preference.rb +35 -0
  110. data/app/models/droom/recurrence_rule.rb +1 -1
  111. data/app/models/droom/scrap.rb +110 -0
  112. data/app/models/droom/tag.rb +120 -0
  113. data/app/models/droom/tagging.rb +13 -0
  114. data/app/models/droom/user.rb +211 -0
  115. data/app/models/droom/user_action_observer.rb +12 -0
  116. data/app/models/droom/venue.rb +56 -39
  117. data/app/views/cropper/uploads/_crop.html.haml +46 -0
  118. data/app/views/devise/mailer/confirmation_instructions.en.html.haml +24 -0
  119. data/app/views/devise/mailer/reset_password_instructions.en.html.haml +21 -0
  120. data/app/views/devise/passwords/edit.html.haml +31 -0
  121. data/app/views/devise/passwords/new.html.haml +21 -0
  122. data/app/views/devise/sessions/new.html.haml +33 -0
  123. data/app/views/droom/agenda_categories/_form.html.haml +22 -0
  124. data/app/views/droom/agenda_categories/new.html.haml +6 -0
  125. data/app/views/droom/calendars/_action_menu.html.haml +6 -0
  126. data/app/views/droom/calendars/index.html.haml +12 -0
  127. data/app/views/droom/calendars/show.rss.builder +0 -0
  128. data/app/views/droom/confirmations/show.html.haml +40 -0
  129. data/app/views/droom/dashboard/_calendar.html.haml +1 -0
  130. data/app/views/droom/dashboard/_folders.html.haml +5 -0
  131. data/app/views/droom/dashboard/_future_events.html.haml +18 -0
  132. data/app/views/droom/dashboard/_invitations.html.haml +1 -0
  133. data/app/views/droom/dashboard/_past_events.haml +14 -0
  134. data/app/views/droom/dashboard/_quicksearch.html.haml +6 -0
  135. data/app/views/droom/dashboard/_stream.html.haml +9 -0
  136. data/app/views/droom/dashboard/index.html.haml +5 -3
  137. data/app/views/droom/documents/_action_menu.html.haml +7 -0
  138. data/app/views/droom/documents/_documents.html.haml +5 -0
  139. data/app/views/droom/documents/_documents_list.html.haml +6 -6
  140. data/app/views/droom/documents/_documents_table.html.haml +29 -10
  141. data/app/views/droom/documents/_form.html.haml +3 -7
  142. data/app/views/droom/documents/_listing.html.haml +5 -6
  143. data/app/views/droom/documents/_pagination.html.haml +8 -0
  144. data/app/views/droom/documents/_search_result.html.haml +14 -0
  145. data/app/views/droom/documents/_suggested.html.haml +0 -5
  146. data/app/views/droom/documents/_table_document.html.haml +2 -8
  147. data/app/views/droom/documents/edit.html.haml +7 -1
  148. data/app/views/droom/documents/index.html.haml +10 -27
  149. data/app/views/droom/documents/new.html.haml +10 -1
  150. data/app/views/droom/dropbox_tokens/new.html.haml +6 -0
  151. data/app/views/droom/events/_action_menu.html.haml +15 -0
  152. data/app/views/droom/events/_event.html.haml +67 -57
  153. data/app/views/droom/events/_form.html.haml +15 -4
  154. data/app/views/droom/events/_invitations.html.haml +4 -19
  155. data/app/views/droom/events/_search_result.html.haml +19 -0
  156. data/app/views/droom/events/_views.html.haml +2 -2
  157. data/app/views/droom/events/edit.html.haml +7 -1
  158. data/app/views/droom/events/index.html.haml +27 -10
  159. data/app/views/droom/events/index.rss.builder +1 -1
  160. data/app/views/droom/events/new.html.haml +6 -1
  161. data/app/views/droom/events/show.html.haml +5 -1
  162. data/app/views/droom/folders/_action_menu.html.haml +14 -0
  163. data/app/views/droom/folders/_attachments.html.haml +3 -0
  164. data/app/views/droom/folders/_contents.html.haml +6 -0
  165. data/app/views/droom/folders/_folder.html.haml +20 -0
  166. data/app/views/droom/folders/_folders.html.haml +2 -0
  167. data/app/views/droom/folders/_form.html.haml +18 -0
  168. data/app/views/droom/folders/edit.html.haml +6 -0
  169. data/app/views/droom/folders/index.html.haml +32 -0
  170. data/app/views/droom/folders/new.html.haml +6 -0
  171. data/app/views/droom/folders/show.html.haml +1 -0
  172. data/app/views/droom/group_invitations/_form.html.haml +15 -4
  173. data/app/views/droom/group_invitations/new.html.haml +6 -1
  174. data/app/views/droom/groups/_action_menu.haml +11 -0
  175. data/app/views/droom/groups/_form.html.haml +10 -11
  176. data/app/views/droom/groups/_group.html.haml +9 -10
  177. data/app/views/droom/groups/_groups.html.haml +2 -3
  178. data/app/views/droom/groups/_search_result.html.haml +16 -0
  179. data/app/views/droom/groups/_suggested.html.haml +7 -0
  180. data/app/views/droom/groups/edit.html.haml +7 -1
  181. data/app/views/droom/groups/index.html.haml +6 -3
  182. data/app/views/droom/groups/new.html.haml +7 -0
  183. data/app/views/droom/groups/show.html.haml +1 -1
  184. data/app/views/droom/invitations/_created.html.haml +1 -1
  185. data/app/views/droom/invitations/_form.html.haml +9 -5
  186. data/app/views/droom/invitations/_invitation.html.haml +9 -0
  187. data/app/views/droom/invitations/_invitations.html.haml +8 -0
  188. data/app/views/droom/invitations/new.html.haml +6 -1
  189. data/app/views/droom/memberships/_member.html.haml +1 -1
  190. data/app/views/droom/memberships/_membership_toggle.html.haml +10 -0
  191. data/app/views/droom/memberships/new.html.haml +10 -0
  192. data/app/views/droom/organisations/_action_menu.html.haml +7 -0
  193. data/app/views/droom/organisations/_form.html.haml +25 -0
  194. data/app/views/droom/organisations/_organisation.html.haml +23 -0
  195. data/app/views/droom/organisations/_organisations.html.haml +2 -0
  196. data/app/views/droom/organisations/_suggested.html.haml +7 -0
  197. data/app/views/droom/organisations/edit.html.haml +6 -0
  198. data/app/views/droom/organisations/index.html.haml +20 -0
  199. data/app/views/droom/organisations/new.html.haml +6 -0
  200. data/app/views/droom/organisations/show.html.haml +1 -0
  201. data/app/views/droom/pages/_full_page.html.haml +1 -1
  202. data/app/views/droom/pages/index.html.haml +1 -1
  203. data/app/views/droom/panels/_account.html.haml +16 -0
  204. data/app/views/droom/panels/_admin.html.haml +23 -0
  205. data/app/views/droom/panels/_devices.html.haml +19 -0
  206. data/app/views/droom/panels/_dropbox.html.haml +17 -0
  207. data/app/views/droom/panels/_email.html.haml +16 -0
  208. data/app/views/droom/panels/_keywords.html.haml +3 -0
  209. data/app/views/droom/panels/_networks.html.haml +3 -0
  210. data/app/views/droom/panels/_readers.html.haml +18 -0
  211. data/app/views/droom/panels/_rss.html.haml +10 -0
  212. data/app/views/droom/panels/_search.html.haml +16 -0
  213. data/app/views/droom/panels/_vcal.html.haml +3 -0
  214. data/app/views/droom/people/_action_menu.html.haml +22 -0
  215. data/app/views/droom/people/_form.html.haml +69 -39
  216. data/app/views/droom/people/_listing.html.haml +19 -0
  217. data/app/views/droom/people/_memberships.html.haml +24 -0
  218. data/app/views/droom/people/_people.html.haml +5 -29
  219. data/app/views/droom/people/_person.html.haml +30 -32
  220. data/app/views/droom/people/_search_result.html.haml +14 -0
  221. data/app/views/droom/people/_suggested.html.haml +10 -5
  222. data/app/views/droom/people/edit.html.haml +9 -1
  223. data/app/views/droom/people/index.html.haml +6 -9
  224. data/app/views/droom/people/new.html.haml +6 -1
  225. data/app/views/droom/people/show.html.haml +1 -1
  226. data/app/views/droom/preferences/_checkbox.html.haml +7 -0
  227. data/app/views/droom/preferences/_radio_set.html.haml +9 -0
  228. data/app/views/droom/scraps/_action_menu.html.haml +9 -0
  229. data/app/views/droom/scraps/_caption.html.haml +9 -0
  230. data/app/views/droom/scraps/_credit.html.haml +10 -0
  231. data/app/views/droom/scraps/_form.html.haml +77 -0
  232. data/app/views/droom/scraps/_heading.html.haml +16 -0
  233. data/app/views/droom/scraps/_scrap.html.haml +17 -0
  234. data/app/views/droom/scraps/_search_result.html.haml +5 -0
  235. data/app/views/droom/scraps/_stream.html.haml +4 -0
  236. data/app/views/droom/scraps/_suggested.html.haml +5 -0
  237. data/app/views/droom/scraps/_thumb.html.haml +5 -0
  238. data/app/views/droom/scraps/edit.html.haml +2 -0
  239. data/app/views/droom/scraps/full/_document.html.haml +6 -0
  240. data/app/views/droom/scraps/full/_event.html.haml +20 -0
  241. data/app/views/droom/scraps/full/_image.html.haml +4 -0
  242. data/app/views/droom/scraps/full/_link.html.haml +5 -0
  243. data/app/views/droom/scraps/full/_quote.html.haml +8 -0
  244. data/app/views/droom/scraps/full/_text.html.haml +4 -0
  245. data/app/views/droom/scraps/full/_video.html.haml +4 -0
  246. data/app/views/droom/scraps/index.atom.builder +26 -0
  247. data/app/views/droom/scraps/index.html.haml +15 -0
  248. data/app/views/droom/scraps/new.html.haml +2 -0
  249. data/app/views/droom/scraps/show.html.haml +4 -0
  250. data/app/views/droom/scraps/thumbs/_document.html.haml +9 -0
  251. data/app/views/droom/scraps/thumbs/_event.html.haml +17 -0
  252. data/app/views/droom/scraps/thumbs/_image.html.haml +6 -0
  253. data/app/views/droom/scraps/thumbs/_link.html.haml +10 -0
  254. data/app/views/droom/scraps/thumbs/_quote.html.haml +8 -0
  255. data/app/views/droom/scraps/thumbs/_text.html.haml +8 -0
  256. data/app/views/droom/scraps/thumbs/_video.html.haml +6 -0
  257. data/app/views/droom/shared/_controls.html.haml +5 -3
  258. data/app/views/droom/shared/_excerpt.html.haml +2 -0
  259. data/app/views/droom/shared/_navigation.html.haml +4 -4
  260. data/app/views/droom/shared/_panels.html.haml +4 -0
  261. data/app/views/droom/shared/_quicklinks.html.haml +5 -0
  262. data/app/views/droom/shared/_search_form.html.haml +2 -1
  263. data/app/views/droom/shared/_search_results.html.haml +9 -0
  264. data/app/views/droom/shared/_suggestions.html.haml +13 -9
  265. data/app/views/droom/shared/_title_excerpt.haml +2 -0
  266. data/app/views/droom/shared/search.html.haml +18 -0
  267. data/app/views/droom/users/_confirmation.html.haml +2 -0
  268. data/app/views/droom/users/_dropbox_status.html.haml +2 -0
  269. data/app/views/droom/users/_form.html.haml +34 -0
  270. data/app/views/droom/users/_user.html.haml +2 -0
  271. data/app/views/droom/users/_user_or_person.html.haml +63 -0
  272. data/app/views/droom/users/_users_table.html.haml +17 -0
  273. data/app/views/droom/users/edit.html.haml +10 -0
  274. data/app/views/droom/users/index.html.haml +42 -0
  275. data/app/views/droom/users/unwelcome.en.html.haml +17 -0
  276. data/app/views/droom/venues/_search_result.html.haml +17 -0
  277. data/app/views/droom/youtube/show.html.haml +12 -0
  278. data/app/views/kaminari/_paginator.html.haml +16 -0
  279. data/app/views/layouts/droom/application.html.haml +17 -17
  280. data/app/views/layouts/droom/email.html.haml +59 -0
  281. data/config/cucumber.yml +8 -0
  282. data/config/initializers/devise.rb +240 -0
  283. data/config/locales/devise.en.yml +58 -0
  284. data/config/locales/en.yml +203 -32
  285. data/config/routes.rb +55 -16
  286. data/config/sunspot.yml +17 -0
  287. data/db/migrate/20121120115447_tags.rb +18 -0
  288. data/db/migrate/20130116155331_dropbox_tokens.rb +9 -0
  289. data/db/migrate/20130118103540_folders.rb +47 -0
  290. data/db/migrate/20130124113715_preferences.rb +10 -0
  291. data/db/migrate/20130125132427_users_in_droom.rb +58 -0
  292. data/db/migrate/20130129142307_mobile_phones.rb +7 -0
  293. data/db/migrate/20130130120124_folder_ancestry_to_parents.rb +7 -0
  294. data/db/migrate/20130131161430_mailing_lists.rb +37 -0
  295. data/db/migrate/20130207091903_preference_uuids.rb +5 -0
  296. data/db/migrate/20130207123614_stream.rb +13 -0
  297. data/db/migrate/20130208035113_access_token_secret.rb +5 -0
  298. data/db/migrate/20130214145014_person_image.rb +9 -0
  299. data/db/migrate/20130217152644_devise_confirmable.rb +13 -0
  300. data/db/migrate/20130225095328_create_droom_calendars.rb +20 -0
  301. data/db/migrate/20130226092944_give_scraps_document.rb +5 -0
  302. data/db/migrate/20130228083509_privateness.rb +9 -0
  303. data/db/migrate/20130228134143_store_metadata.rb +5 -0
  304. data/db/migrate/20130305150648_folders_nicely.rb +6 -0
  305. data/db/migrate/20130305151936_niceties.rb +7 -0
  306. data/db/migrate/20130308103807_create_droom_dropbox_documents.rb +11 -0
  307. data/db/migrate/20130308154552_dropbox_documents_changed.rb +5 -0
  308. data/db/migrate/20130326135738_user_titles.rb +5 -0
  309. data/lib/droom.rb +189 -22
  310. data/lib/droom/engine.rb +6 -1
  311. data/lib/droom/folders.rb +106 -0
  312. data/lib/droom/lazy_hash.rb +73 -0
  313. data/lib/droom/{helpers.rb → model_helpers.rb} +1 -1
  314. data/lib/droom/monkeys.rb +21 -2
  315. data/lib/droom/routing.rb +13 -0
  316. data/lib/droom/searchability.rb +25 -0
  317. data/lib/droom/taggability.rb +60 -0
  318. data/lib/droom/title_case.rb +101 -0
  319. data/lib/droom/user_config.rb +67 -0
  320. data/lib/droom/validators.rb +6 -0
  321. data/lib/droom/version.rb +1 -1
  322. data/lib/generators/droom/install/templates/droom_initializer.rb +0 -1
  323. data/lib/tasks/cucumber.rake +65 -0
  324. data/spec/datasets/calendar_events_dataset.rb +44 -0
  325. data/spec/datasets/calendar_pages_dataset.rb +8 -0
  326. data/spec/datasets/calendar_sites_dataset.rb +6 -0
  327. data/spec/datasets/calendars_dataset.rb +34 -0
  328. data/spec/datasets/documents_dataset.rb +28 -0
  329. data/spec/datasets/recurrence_dataset.rb +7 -0
  330. data/spec/dummy/README.rdoc +261 -0
  331. data/spec/dummy/Rakefile +7 -0
  332. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  333. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  334. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  335. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  336. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  337. data/spec/dummy/config.ru +4 -0
  338. data/spec/dummy/config/application.rb +65 -0
  339. data/spec/dummy/config/boot.rb +10 -0
  340. data/spec/dummy/config/database.yml +21 -0
  341. data/spec/dummy/config/environment.rb +5 -0
  342. data/spec/dummy/config/environments/development.rb +38 -0
  343. data/spec/dummy/config/environments/production.rb +67 -0
  344. data/spec/dummy/config/environments/test.rb +38 -0
  345. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  346. data/spec/dummy/config/initializers/inflections.rb +15 -0
  347. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  348. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  349. data/spec/dummy/config/initializers/session_store.rb +8 -0
  350. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  351. data/spec/dummy/config/locales/en.yml +7 -0
  352. data/spec/dummy/config/routes.rb +3 -0
  353. data/spec/dummy/config/sunspot.yml +17 -0
  354. data/spec/dummy/db/migrate/20120911070124_create_droom_data.droom.rb +135 -0
  355. data/spec/dummy/db/migrate/20120921094604_agenda_sections.droom.rb +14 -0
  356. data/spec/dummy/db/migrate/20120921094605_add_postal_address_to_people.droom.rb +11 -0
  357. data/spec/dummy/db/migrate/20121102064845_give_groups_descriptions.droom.rb +6 -0
  358. data/spec/dummy/db/migrate/20121102064846_more_names.droom.rb +6 -0
  359. data/spec/dummy/db/migrate/20121102064847_event_agenda_sections.droom.rb +14 -0
  360. data/spec/dummy/db/migrate/20121102064848_create_group_invitations.droom.rb +11 -0
  361. data/spec/dummy/db/migrate/20121102064849_give_people_positions.droom.rb +6 -0
  362. data/spec/dummy/db/migrate/20121102064850_help_pages.droom.rb +14 -0
  363. data/spec/dummy/db/migrate/20121102064851_category_slugs.droom.rb +6 -0
  364. data/spec/dummy/db/migrate/20121102064852_document_links.droom.rb +15 -0
  365. data/spec/dummy/db/migrate/20121102064853_people_visibility.droom.rb +8 -0
  366. data/spec/dummy/db/migrate/20121102094820_shy_people.droom.rb +6 -0
  367. data/spec/dummy/db/migrate/20121102095927_visibility_defaults.droom.rb +10 -0
  368. data/spec/dummy/db/migrate/20130121122352_tags.droom.rb +19 -0
  369. data/spec/dummy/db/migrate/20130121122353_dropbox.droom.rb +10 -0
  370. data/spec/dummy/db/migrate/20130121122354_folders.droom.rb +48 -0
  371. data/spec/dummy/db/migrate/20130128142902_memberships_expire.droom.rb +6 -0
  372. data/spec/dummy/db/migrate/20130128142903_give_documents_extracted_text.droom.rb +6 -0
  373. data/spec/dummy/db/migrate/20130128142904_preferences.droom.rb +11 -0
  374. data/spec/dummy/db/migrate/20130128142905_users_in_droom.droom.rb +59 -0
  375. data/spec/dummy/db/migrate/20130130120631_folder_ancestry_to_parents.droom.rb +8 -0
  376. data/spec/dummy/db/migrate/20130201103737_mobile_phones.droom.rb +8 -0
  377. data/spec/dummy/db/migrate/20130201103738_mailing_lists.droom.rb +38 -0
  378. data/spec/dummy/db/schema.rb +327 -0
  379. data/spec/dummy/log/sunspot-solr-test.log.1 +222 -0
  380. data/spec/dummy/public/404.html +26 -0
  381. data/spec/dummy/public/422.html +26 -0
  382. data/spec/dummy/public/500.html +25 -0
  383. data/spec/dummy/public/favicon.ico +0 -0
  384. data/spec/dummy/public/system/droom/documents/files/000/000/001/original/frog.png +0 -0
  385. data/spec/dummy/public/system/droom/documents/files/000/000/001/original/rat.png +0 -0
  386. data/spec/dummy/script/rails +6 -0
  387. data/spec/dummy/solr/conf/admin-extra.html +31 -0
  388. data/spec/dummy/solr/conf/elevate.xml +36 -0
  389. data/spec/dummy/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  390. data/spec/dummy/solr/conf/protwords.txt +21 -0
  391. data/spec/dummy/solr/conf/schema.xml +238 -0
  392. data/spec/dummy/solr/conf/scripts.conf +24 -0
  393. data/spec/dummy/solr/conf/solrconfig.xml +934 -0
  394. data/spec/dummy/solr/conf/spellings.txt +2 -0
  395. data/spec/dummy/solr/conf/stopwords.txt +58 -0
  396. data/spec/dummy/solr/conf/synonyms.txt +31 -0
  397. data/spec/dummy/solr/data/development/index/segments.gen +0 -0
  398. data/spec/dummy/solr/data/development/index/segments_1 +0 -0
  399. data/spec/dummy/solr/data/development/spellchecker/segments.gen +0 -0
  400. data/spec/dummy/solr/data/development/spellchecker/segments_1 +0 -0
  401. data/spec/dummy/solr/data/test/index/segments.gen +0 -0
  402. data/spec/dummy/solr/data/test/index/segments_3nu +0 -0
  403. data/spec/dummy/solr/data/test/spellchecker/segments.gen +0 -0
  404. data/spec/dummy/solr/data/test/spellchecker/segments_1 +0 -0
  405. data/spec/dummy/webdav/1/group/rat.png +0 -0
  406. data/spec/dummy/webdav/1/unattached/rat.png +0 -0
  407. data/spec/dummy/webdav/group/rat.png +0 -0
  408. data/spec/dummy/webdav/unattached/rat.png +0 -0
  409. data/spec/dummy/webdav/unattached/rat_v1.png +0 -0
  410. data/spec/factories/agenda_categories.rb +5 -0
  411. data/spec/factories/categories.rb +5 -0
  412. data/spec/factories/documents.rb +16 -0
  413. data/spec/factories/events.rb +41 -0
  414. data/spec/factories/folders.rb +5 -0
  415. data/spec/factories/groups.rb +6 -0
  416. data/spec/factories/memberships.rb +5 -0
  417. data/spec/factories/people.rb +16 -0
  418. data/spec/factories/recurrence_rules.rb +25 -0
  419. data/spec/factories/user.rb +6 -0
  420. data/spec/fixtures/dummy.ics +59 -0
  421. data/spec/fixtures/images/frog.png +0 -0
  422. data/spec/fixtures/images/rat.png +0 -0
  423. data/spec/fixtures/ny.ics +36 -0
  424. data/spec/lib/droom/folders_spec.rb +46 -0
  425. data/spec/lib/droom/lazy_hash_spec.rb +33 -0
  426. data/spec/models/droom/agenda_category_spec.rb +15 -0
  427. data/spec/models/droom/document_spec.rb +76 -0
  428. data/spec/models/droom/event_spec.rb +154 -0
  429. data/spec/models/droom/folder_spec.rb +5 -0
  430. data/spec/models/droom/ical_spec.rb +62 -0
  431. data/spec/models/droom/mailing_list_membership_spec.rb +81 -0
  432. data/spec/models/droom/membership_spec.rb +22 -0
  433. data/spec/models/droom/person_spec.rb +72 -0
  434. data/spec/models/droom/recurrence_rule_spec.rb +81 -0
  435. data/spec/models/droom/user_spec.rb +27 -0
  436. data/spec/models/droom/visibility_spec.rb +6 -0
  437. data/spec/spec_helper.rb +119 -0
  438. data/spec/support/matchers/content_type_matcher.rb +17 -0
  439. metadata +591 -36
  440. data/app/assets/javascripts/droom/calendar.js.coffee +0 -121
  441. data/app/assets/javascripts/droom/drag_sort.js.coffee +0 -22
  442. data/app/assets/javascripts/droom/forms.js.coffee +0 -746
  443. data/app/assets/javascripts/droom/sort.js.coffee +0 -126
  444. data/app/assets/javascripts/droom/suggester.js.coffee +0 -230
  445. data/app/controllers/droom/document_attachments_controller.rb +0 -19
  446. data/app/models/droom/document_link.rb +0 -31
  447. data/app/models/droom/personal_document.rb +0 -98
  448. data/app/views/droom/dashboard/_marginalia.html.haml +0 -3
  449. data/app/views/droom/dashboard/_my_future_events.html.haml +0 -9
  450. data/app/views/droom/dashboard/_my_group_documents.html.haml +0 -6
  451. data/app/views/droom/dashboard/_my_past_events.haml +0 -6
  452. data/app/views/droom/documents/_event_document_form.html.haml +0 -15
  453. data/app/views/droom/errors/bang.html.haml +0 -12
  454. data/app/views/droom/errors/not_allowed.html.haml +0 -12
  455. data/app/views/droom/errors/not_found.html.haml +0 -12
  456. data/app/views/droom/events/_attachment.html.haml +0 -1
  457. data/app/views/droom/events/_attachment_list.html.haml +0 -4
  458. data/app/views/droom/invitations/_attending_people.html.haml +0 -8
  459. data/config/initializers/dav.rb +0 -2
@@ -5,42 +5,8 @@ module Droom
5
5
  belongs_to :document
6
6
  belongs_to :attachee, :polymorphic => true
7
7
  belongs_to :category
8
- belongs_to :created_by, :class_name => "User"
8
+ belongs_to :created_by, :class_name => "Droom::User"
9
9
 
10
- has_many :document_links, :dependent => :destroy
11
- has_many :people, :through => :document_links
12
-
13
- after_destroy :remove_private_document_if_unattached
14
- after_create :link_people
15
-
16
- default_scope order("(CASE WHEN droom_document_attachments.category_id IS NULL THEN 0 ELSE 1 END), droom_documents.updated_at ASC, droom_documents.created_at ASC").includes(:document)
17
-
18
- scope :unfiled, where("category_id IS NULL")
19
-
20
- scope :attached_to, lambda { |attachee|
21
- where(["droom_document_attachments.attachee_type = :class AND droom_document_attachments.attachee_id = :id", :class => attachee.class.to_s, :id => attachee.id])
22
- }
23
-
24
- scope :to_event, lambda { |event|
25
- where(["droom_document_attachments.attachee_type = 'Droom::Event' AND droom_document_attachments.attachee_id = ?", event.id])
26
- }
27
-
28
- scope :to_group, lambda { |group|
29
- where(["droom_document_attachments.attachee_type = 'Droom::Group' AND droom_document_attachments.attachee_id = ?", group.id])
30
- }
31
-
32
- scope :to_events, lambda { |events|
33
- placeholders = events.map{'?'}.join(',')
34
- ids = events.map(&:id)
35
- where(["droom_document_attachments.attachee_type = 'Droom::Event' AND droom_document_attachments.attachee_id IN (#{placeholders})", *ids])
36
- }
37
-
38
- scope :to_groups, lambda { |groups|
39
- placeholders = groups.map{'?'}.join(',')
40
- ids = groups.map(&:id)
41
- where(["droom_document_attachments.attachee_type = 'Droom::Group' AND droom_document_attachments.attachee_id IN (#{placeholders})", *ids])
42
- }
43
-
44
10
  def slug
45
11
  if attachee
46
12
  attachee.slug
@@ -53,19 +19,19 @@ module Droom
53
19
  category ? category.name : "uncategorised"
54
20
  end
55
21
 
56
- protected
57
-
58
- def remove_private_document_if_unattached
59
- unless document.public? || document.document_attachments.count > 0
60
- document.destroy
22
+ def move_document_to_folder
23
+ recipient = if category
24
+ # attachee will be an event
25
+ attachee.find_or_create_agenda_category(category)
26
+ else
27
+ attachee
28
+ end
29
+ if document
30
+ document.folder = nil
31
+ recipient.receive_document(document)
32
+ document.save
61
33
  end
62
34
  end
63
-
64
- # Upon creation we create document links to all the people who are newly entitled to see the document.
65
- # Deletion takes care of itself, as document_links are :dependent => :destroy.
66
- #
67
- def link_people
68
- people << attachee.people if attachee
69
- end
35
+
70
36
  end
71
37
  end
@@ -0,0 +1,41 @@
1
+ module Droom
2
+ class DropboxDocument < ActiveRecord::Base
3
+ attr_accessible :person_id
4
+
5
+ belongs_to :person
6
+ belongs_to :document
7
+
8
+ validates_uniqueness_of :person_id, :scope => :document_id
9
+
10
+ after_save :get_file
11
+
12
+ after_destroy :remove_dropbox_document
13
+
14
+ def get_file
15
+ bucket = Droom.aws_bucket
16
+ file = bucket.files.get(document.file.path)
17
+ dropbox_client.put_file(document.full_path, file)
18
+ end
19
+
20
+ def update
21
+ get_file
22
+ end
23
+
24
+ def dropbox_client
25
+ person.user.dropbox_client
26
+ end
27
+
28
+ def deleted=(boolean)
29
+ deleted = boolean
30
+ end
31
+
32
+ def remove_dropbox_document
33
+ dropbox_client.file_delete(document.full_path)
34
+ end
35
+
36
+ def changed?
37
+ modified?# || dropbox_client.get_file_and_metadata(document.full_path)#dropbox file has revisions
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ module Droom
2
+ class DropboxToken < ActiveRecord::Base
3
+ attr_accessible :access_token, :access_token_secret, :created_by
4
+ belongs_to :created_by, :class_name => "Droom::User"
5
+ after_create :delete_previous
6
+
7
+ scope :by_date, order("created_at DESC")
8
+ scope :other_than, lambda { |token| where "id <> ?", token.id }
9
+
10
+ def dropbox_session
11
+ unless @dbsession
12
+ @dbsession = DropboxSession.new(Droom.dropbox_app_key, Droom.dropbox_app_secret)
13
+ @dbsession.set_access_token(access_token, access_token_secret)
14
+ end
15
+ @dbsession
16
+ end
17
+
18
+ def dropbox_client
19
+ @dbclient ||= DropboxClient.new(dropbox_session)
20
+ end
21
+
22
+ protected
23
+
24
+ def delete_previous
25
+ self.created_by.dropbox_tokens.other_than(self).destroy_all
26
+ end
27
+
28
+ end
29
+ end
@@ -1,14 +1,15 @@
1
1
  require 'open-uri'
2
- require 'zip/zip'
3
2
  require 'uuidtools'
4
3
  require 'chronic'
5
4
  require 'ri_cal'
6
5
 
7
6
  module Droom
8
7
  class Event < ActiveRecord::Base
9
- attr_accessible :start, :finish, :name, :description, :event_set_id, :created_by_id, :uuid, :all_day, :master_id, :url, :start_date, :start_time, :finish_date, :finish_time, :venue, :private, :public, :venue_name
8
+ attr_accessible :start, :finish, :name, :description, :event_set_id, :created_by_id, :uuid, :all_day, :master_id, :url, :start_date, :start_time, :finish_date, :finish_time, :venue, :venue_id, :private, :public, :venue_name, :calendar_id
10
9
 
11
- belongs_to :created_by, :class_name => 'User'
10
+ belongs_to :created_by, :class_name => "Droom::User"
11
+
12
+ has_folder #... and subfolders via agenda_categories
12
13
 
13
14
  has_many :invitations, :dependent => :destroy
14
15
  has_many :people, :through => :invitations
@@ -16,18 +17,19 @@ module Droom
16
17
  has_many :group_invitations, :dependent => :destroy
17
18
  has_many :groups, :through => :group_invitations
18
19
 
19
- has_many :document_attachments, :as => :attachee, :dependent => :destroy
20
- has_many :documents, :through => :document_attachments
21
-
22
20
  has_many :agenda_categories, :dependent => :destroy
23
21
  has_many :categories, :through => :agenda_categories
24
-
22
+
25
23
  belongs_to :venue
26
24
  accepts_nested_attributes_for :venue
27
25
 
28
26
  belongs_to :event_set
29
27
  accepts_nested_attributes_for :event_set
30
-
28
+
29
+ belongs_to :calendar
30
+
31
+ has_many :scraps
32
+
31
33
  belongs_to :master, :class_name => 'Event'
32
34
  has_many :occurrences, :class_name => 'Event', :foreign_key => 'master_id', :dependent => :destroy
33
35
  has_many :recurrence_rules, :dependent => :destroy, :conditions => {:active => true}
@@ -39,20 +41,42 @@ module Droom
39
41
  validates :name, :presence => true
40
42
 
41
43
  before_validation :set_uuid
42
- before_save :check_slug
44
+ before_save :ensure_slug
43
45
  after_save :update_occurrences
44
-
46
+ after_save :index
47
+
45
48
  scope :primary, where("master_id IS NULL")
46
49
  scope :recurrent, where(:conditions => "master_id IS NOT NULL")
47
- default_scope order('start ASC').includes(:venue)
48
-
50
+
51
+ searchable do
52
+ text :name, :boost => 10, :stored => true
53
+ text :description, :stored => true
54
+ end
55
+
56
+ handle_asynchronously :solr_index
57
+
58
+ def self.highlight_fields
59
+ [:name, :description]
60
+ end
61
+
49
62
  ## Event retrieval in various ways
50
63
  #
64
+ # Events differ from other models in that they are visible to all unless marked 'private'.
65
+ # The documents attached to them are only visible to all if marked 'public'.
66
+ #
67
+ scope :all_private, where("private = 1")
68
+ scope :not_private, where("private <> 1 OR private IS NULL")
69
+ scope :all_public, where("public = 1 AND private <> 1 OR private IS NULL")
70
+ scope :not_public, where("public <> 1 OR private = 1)")
71
+
72
+ # events are visible by default. Private events are made invisible except to the people
73
+ # invited to them.
74
+
51
75
  scope :visible_to, lambda { |person|
52
76
  if person
53
77
  select('droom_events.*')
54
78
  .joins('LEFT OUTER JOIN droom_invitations ON droom_events.id = droom_invitations.event_id')
55
- .where(["(droom_events.public = 1 OR droom_invitations.person_id = ?)", person.id])
79
+ .where(["(NOT(droom_events.private = 1) OR droom_invitations.person_id = ?)", person.id])
56
80
  .group('droom_events.id')
57
81
  else
58
82
  all_public
@@ -62,25 +86,29 @@ module Droom
62
86
  scope :after, lambda { |datetime| # datetime. eg calendar.occurrences.after(Time.now)
63
87
  where(['start > ?', datetime])
64
88
  }
65
-
89
+
66
90
  scope :before, lambda { |datetime| # datetime. eg calendar.occurrences.before(Time.now)
67
91
  where(['start < :date AND (finish IS NULL or finish < :date)', :date => datetime])
68
92
  }
69
-
93
+
70
94
  scope :between, lambda { |start, finish| # datetimable objects. eg. Event.between(reader.last_login, Time.now)
71
95
  where(['start > :start AND start < :finish AND (finish IS NULL or finish < :finish)', :start => start, :finish => finish])
72
96
  }
73
-
97
+
74
98
  scope :future_and_current, lambda {
75
99
  where(['(finish > :now) OR (finish IS NULL AND start > :now)', :now => Time.now])
76
100
  }
77
-
78
- scope :unfinished, lambda { |start| # datetimable object.
79
- where(['start < :start AND finish > :start', :start => start])
101
+
102
+ scope :finished, lambda {
103
+ where(['(finish < :now) OR (finish IS NULL AND start < :now)', :now => Time.now])
80
104
  }
81
105
 
106
+ scope :unbegun, lambda {
107
+ where(['start > :now', :now => Time.now])
108
+ }
109
+
82
110
  scope :by_finish, order("finish ASC")
83
-
111
+
84
112
  scope :coincident_with, lambda { |start, finish| # datetimable objects.
85
113
  where(['(start < :finish AND finish > :start) OR (finish IS NULL AND start > :start AND start < :finish)', {:start => start, :finish => finish}])
86
114
  }
@@ -88,37 +116,31 @@ module Droom
88
116
  scope :limited_to, lambda { |limit|
89
117
  limit(limit)
90
118
  }
91
-
119
+
92
120
  scope :at_venue, lambda { |venue| # EventVenue object
93
121
  where(["venue_id = ?", venue.id])
94
122
  }
95
-
123
+
96
124
  scope :except_these_uuids, lambda { |uuids| # array of uuid strings
97
125
  placeholders = uuids.map{'?'}.join(',')
98
126
  where(["uuid NOT IN (#{placeholders})", *uuids])
99
127
  }
100
-
128
+
101
129
  scope :without_invitations_to, lambda { |person| # Person object
102
130
  select("droom_events.*")
103
131
  .joins("LEFT OUTER JOIN droom_invitations ON droom_events.id = droom_invitations.event_id AND droom_invitations.person_id = #{sanitize(person.id)}")
104
132
  .group("droom_events.id")
105
133
  .having("COUNT(droom_invitations.id) = 0")
106
134
  }
107
-
135
+
108
136
  scope :with_documents,
109
137
  select("droom_events.*")
110
138
  .joins("INNER JOIN droom_document_attachments ON droom_events.id = droom_document_attachments.attachee_id AND droom_document_attachments.attachee_type = 'Droom::Event'")
111
139
  .group("droom_events.id")
112
-
113
-
114
- scope :all_private, where("private = 1 OR private = 't'")
115
- scope :not_private, where("private = 0 OR private = 'f'")
116
- scope :all_public, where("public = 1 OR public = 't'")
117
- scope :not_public, where("public = 0 OR public = 'f'")
118
140
 
119
- scope :name_matching, lambda { |fragment|
141
+ scope :matching, lambda { |fragment|
120
142
  fragment = "%#{fragment}%"
121
- where('droom_events.name like ?', fragment)
143
+ where('droom_events.name like :f OR droom_events.description like :f', :f => fragment)
122
144
  }
123
145
 
124
146
  # All of these class methods also return scopes.
@@ -162,11 +184,11 @@ module Droom
162
184
  end
163
185
 
164
186
  def self.future
165
- after(Time.now)
187
+ unbegun.order('start ASC')
166
188
  end
167
189
 
168
190
  def self.past
169
- before(Time.now)
191
+ finished.order('start DESC')
170
192
  end
171
193
 
172
194
  ## Instance methods
@@ -174,15 +196,11 @@ module Droom
174
196
  def invite(person)
175
197
  self.people << person
176
198
  end
177
-
199
+
178
200
  def attach(doc)
179
201
  self.documents << doc
180
202
  end
181
203
 
182
- def identifier
183
- 'event'
184
- end
185
-
186
204
  # We store the start and end points of the event as a single DateTime value to make comparison simple.
187
205
  # The setters for date and time are overridden to pass strings through chronic's natural language parser
188
206
  # and to treat numbers as epoch seconds. These should all work as you'd expect:
@@ -235,15 +253,18 @@ module Droom
235
253
  def start_time=(value)
236
254
  self.start = (start_date || Date.today).to_time + parse_date(value).seconds_since_midnight
237
255
  end
238
-
256
+
239
257
  def start_date=(value)
240
258
  self.start = parse_date(value).to_date# + start_time
241
259
  end
242
-
260
+
243
261
  def finish_time=(value)
244
- self.finish = (finish_date || start_date || Date.today).to_time + parse_date(value).seconds_since_midnight
262
+ if value && !value.blank?
263
+ time_portion = parse_date(value).seconds_since_midnight
264
+ self.finish = (finish_date || start_date || Date.today).to_time + time_portion
265
+ end
245
266
  end
246
-
267
+
247
268
  def finish_date=(value)
248
269
  self.finish = parse_date(value).to_date# + finish_time
249
270
  end
@@ -259,57 +280,57 @@ module Droom
259
280
  def venue_name
260
281
  venue.name if venue
261
282
  end
262
-
283
+
263
284
  def venue_name=(name)
264
285
  self.venue = Droom::Venue.find_or_create_by_name(name)
265
286
  end
266
287
 
267
- # Agenda sections are global, and we don't want to have to manage the extra workload of associating a section with an event.
268
- # This call retrieves all the agenda sections that are associated with any of our document attachments, and is suitable for looping
269
- # on a template to display attachments per section.
270
- #
271
- def agenda_sections
272
- Droom::AgendaSection.associated_with_event(self)
288
+ def find_or_create_agenda_category(category)
289
+ agenda_categories.find_or_create_by_category_id(category.id)
273
290
  end
274
-
275
- # and this sorts our attachment list into agenda section buckets so that we don't have to go back to the database for each section.
276
- def attachments_by_category
277
- cats = {}
278
- document_attachments.each_with_object({}) do |att, hash|
279
- key = att.category_name
280
- cats[key] ||= []
281
- cats[key].push(att)
282
- end
283
- categories.each do |category|
284
- key = category.name
285
- cats[key] ||= []
286
- end
287
- cats
288
- end
289
-
291
+
290
292
  def categories_for_selection
291
293
  cats = categories.map{|c| [c.name, c.id] }
292
294
  cats.unshift(['', ''])
293
295
  cats
294
296
  end
295
-
297
+
298
+ def attended_by?(person)
299
+ person && person.invited_to?(self)
300
+ end
301
+
296
302
  def visible_to?(user_or_person)
303
+ return true if self.public?
304
+ return false if self.private?# || Droom.events_private_by_default?
305
+ return true
306
+ end
307
+
308
+ def detail_visible_to?(user_or_person)
297
309
  return true if self.public?
298
310
  return false unless user_or_person
299
311
  return true if user_or_person.admin?
312
+ return true if user_or_person.privileged?
300
313
  return true if user_or_person.person.invited_to?(self)
301
314
  return false if self.private?
302
315
  return true
303
316
  end
317
+
318
+ def has_people?
319
+ invitations.any?
320
+ end
321
+
322
+ def has_documents?
323
+ all_documents.any?
324
+ end
304
325
 
305
326
  def one_day?
306
327
  all_day? && within_day?
307
328
  end
308
-
329
+
309
330
  def within_day?
310
331
  (!finish || start.to.jd == finish.to.jd || finish == start + 1.day)
311
332
  end
312
-
333
+
313
334
  def continuing?
314
335
  finish && start < Time.now && finish > Time.now
315
336
  end
@@ -317,29 +338,25 @@ module Droom
317
338
  def finished?
318
339
  start < Time.now && (!finish || finish < Time.now)
319
340
  end
320
-
341
+
321
342
  def recurs?
322
343
  master || occurrences.any?
323
344
  end
324
-
345
+
325
346
  def recurrence
326
347
  recurrence_rules.first.to_s
327
348
  end
328
-
349
+
329
350
  def add_recurrence(rule)
330
351
  self.recurrence_rules << Droom::RecurrenceRule.from(rule)
331
352
  end
332
353
 
333
- def documents_zipped
334
- if self.documents.any?
335
- tempfile = Tempfile.new("droom-temp-#{slug}-#{Time.now}.zip")
336
- Zip::ZipOutputStream.open(tempfile.path) do |z|
337
- self.documents.each do |doc|
338
- z.add(doc.file_file_name, open(doc.file.url))
339
- end
340
- end
341
- tempfile
342
- end
354
+ def url_with_protocol
355
+ url =~ /^https?:\/\// ? url : "http://#{url}"
356
+ end
357
+
358
+ def url_without_protocol
359
+ url.sub(/^https?:\/\//, '')
343
360
  end
344
361
 
345
362
  def to_rical
@@ -349,28 +366,46 @@ module Droom
349
366
  cal_event.description = description if description
350
367
  cal_event.dtstart = (all_day? ? start_date : start) if start
351
368
  cal_event.dtend = (all_day? ? finish_date : finish) if finish
352
- cal_event.url = url if url
369
+ cal_event.url = url_with_protocol if url
353
370
  cal_event.rrules = recurrence_rules.map(&:to_rical) if recurrence_rules.any?
354
371
  cal_event.location = venue.name if venue
355
372
  end
356
373
  end
357
-
374
+
358
375
  def to_ics
359
376
  to_rical.to_s
360
377
  end
361
-
378
+
362
379
  def as_json(options={})
363
380
  json = super
364
381
  json[:datestring] = I18n.l start, :format => :natural_with_date
365
382
  json
366
383
  end
367
384
 
385
+ def as_suggestion
386
+ {
387
+ :type => 'event',
388
+ :prompt => name,
389
+ :value => name,
390
+ :id => id
391
+ }
392
+ end
393
+
394
+ def as_search_result
395
+ {
396
+ :type => 'event',
397
+ :prompt => name,
398
+ :value => name,
399
+ :id => id
400
+ }
401
+ end
402
+
368
403
  protected
369
-
370
- def check_slug
404
+
405
+ def ensure_slug
371
406
  ensure_presence_and_uniqueness_of(:slug, "#{start.strftime("%Y %m %d")} #{name}".parameterize)
372
407
  end
373
-
408
+
374
409
  def set_uuid
375
410
  self.uuid = UUIDTools::UUID.timestamp_create.to_s if uuid.blank?
376
411
  end
@@ -383,7 +418,7 @@ module Droom
383
418
  to_rical.occurrences(:before => recurrence_horizon).each do |occ|
384
419
  occurrences.create!({
385
420
  :name => self.name,
386
- :url => self.url,
421
+ :url => self.url_with_protocol,
387
422
  :description => self.description,
388
423
  :venue => self.venue,
389
424
  :start => occ.dtstart,
@@ -404,6 +439,6 @@ module Droom
404
439
  value
405
440
  end
406
441
  end
407
-
442
+
408
443
  end
409
444
  end