atreides 2.0.0

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 (309) hide show
  1. data/LICENSE +7 -0
  2. data/README.rdoc +1 -0
  3. data/app/assets/javascripts/atreides/admin.js +22 -0
  4. data/app/assets/javascripts/atreides/admin_base.js.erb +247 -0
  5. data/app/assets/javascripts/atreides/admin_edit.js +9 -0
  6. data/app/assets/javascripts/atreides/application.js +15 -0
  7. data/app/assets/javascripts/atreides/comments.coffee +50 -0
  8. data/app/assets/javascripts/atreides/public.js +24 -0
  9. data/app/assets/javascripts/atreides/public_base.js.erb +119 -0
  10. data/app/assets/javascripts/atreides/terryblr.js +57 -0
  11. data/app/assets/stylesheets/atreides/admin.css +21 -0
  12. data/app/assets/stylesheets/atreides/admin_base.css.erb +1762 -0
  13. data/app/assets/stylesheets/atreides/application.css +13 -0
  14. data/app/assets/stylesheets/atreides/formtastic_changes.css +10 -0
  15. data/app/assets/stylesheets/atreides/iphone-checkboxes.css.erb +97 -0
  16. data/app/assets/stylesheets/atreides/jBreadCrumb.css +109 -0
  17. data/app/assets/stylesheets/atreides/public.css +15 -0
  18. data/app/assets/stylesheets/atreides/public_base.css +101 -0
  19. data/app/assets/stylesheets/atreides/swfupload.css.erb +63 -0
  20. data/app/controllers/admin/atreides/comments_controller.rb +47 -0
  21. data/app/controllers/admin/atreides/content_parts_controller.rb +43 -0
  22. data/app/controllers/admin/atreides/dropbox_controller.rb +40 -0
  23. data/app/controllers/admin/atreides/features_controller.rb +63 -0
  24. data/app/controllers/admin/atreides/github_controller.rb +35 -0
  25. data/app/controllers/admin/atreides/links_controller.rb +3 -0
  26. data/app/controllers/admin/atreides/messages_controller.rb +3 -0
  27. data/app/controllers/admin/atreides/orders_controller.rb +35 -0
  28. data/app/controllers/admin/atreides/pages_controller.rb +59 -0
  29. data/app/controllers/admin/atreides/photos_controller.rb +79 -0
  30. data/app/controllers/admin/atreides/posts_controller.rb +109 -0
  31. data/app/controllers/admin/atreides/products_controller.rb +39 -0
  32. data/app/controllers/admin/atreides/sessions_controller.rb +7 -0
  33. data/app/controllers/admin/atreides/sizes_controller.rb +4 -0
  34. data/app/controllers/admin/atreides/tags_controller.rb +20 -0
  35. data/app/controllers/admin/atreides/users_controller.rb +50 -0
  36. data/app/controllers/admin/atreides/videos_controller.rb +53 -0
  37. data/app/controllers/atreides/admin_controller.rb +96 -0
  38. data/app/controllers/atreides/admin_home_controller.rb +211 -0
  39. data/app/controllers/atreides/application_controller.rb +93 -0
  40. data/app/controllers/atreides/comments_controller.rb +43 -0
  41. data/app/controllers/atreides/home_controller.rb +71 -0
  42. data/app/controllers/atreides/likes_controller.rb +44 -0
  43. data/app/controllers/atreides/pages_controller.rb +34 -0
  44. data/app/controllers/atreides/posts_controller.rb +119 -0
  45. data/app/controllers/atreides/public_controller.rb +43 -0
  46. data/app/helpers/admin/atreides/comments_helper.rb +8 -0
  47. data/app/helpers/admin/atreides/dropbox_helper.rb +42 -0
  48. data/app/helpers/admin/atreides/features_helper.rb +4 -0
  49. data/app/helpers/admin/atreides/github_helper.rb +43 -0
  50. data/app/helpers/admin/atreides/links_helper.rb +4 -0
  51. data/app/helpers/admin/atreides/messages_helper.rb +4 -0
  52. data/app/helpers/admin/atreides/orders_helper.rb +30 -0
  53. data/app/helpers/admin/atreides/pages_helper.rb +17 -0
  54. data/app/helpers/admin/atreides/photos_helper.rb +14 -0
  55. data/app/helpers/admin/atreides/posts_helper.rb +41 -0
  56. data/app/helpers/admin/atreides/products_helper.rb +37 -0
  57. data/app/helpers/admin/atreides/sizes_helper.rb +4 -0
  58. data/app/helpers/admin/atreides/user_sessions_helper.rb +4 -0
  59. data/app/helpers/admin/atreides/users_helper.rb +8 -0
  60. data/app/helpers/admin/atreides/videos_helper.rb +4 -0
  61. data/app/helpers/atreides/admin_helper.rb +243 -0
  62. data/app/helpers/atreides/admin_home_helper.rb +4 -0
  63. data/app/helpers/atreides/application_helper.rb +210 -0
  64. data/app/helpers/atreides/home_helper.rb +4 -0
  65. data/app/helpers/atreides/posts_helper.rb +119 -0
  66. data/app/inputs/files_input.rb +13 -0
  67. data/app/inputs/price_input.rb +18 -0
  68. data/app/inputs/underline_input.rb +16 -0
  69. data/app/models/atreides/ability.rb +24 -0
  70. data/app/models/atreides/comment.rb +93 -0
  71. data/app/models/atreides/content_part.rb +107 -0
  72. data/app/models/atreides/feature.rb +90 -0
  73. data/app/models/atreides/github.rb +74 -0
  74. data/app/models/atreides/like.rb +35 -0
  75. data/app/models/atreides/line_item.rb +4 -0
  76. data/app/models/atreides/link.rb +32 -0
  77. data/app/models/atreides/message.rb +34 -0
  78. data/app/models/atreides/order.rb +209 -0
  79. data/app/models/atreides/page.rb +114 -0
  80. data/app/models/atreides/photo.rb +130 -0
  81. data/app/models/atreides/post.rb +271 -0
  82. data/app/models/atreides/product.rb +75 -0
  83. data/app/models/atreides/site.rb +59 -0
  84. data/app/models/atreides/size.rb +44 -0
  85. data/app/models/atreides/tag.rb +31 -0
  86. data/app/models/atreides/tweet.rb +123 -0
  87. data/app/models/atreides/user.rb +129 -0
  88. data/app/models/atreides/video.rb +206 -0
  89. data/app/models/atreides/vote.rb +43 -0
  90. data/app/models/fb_post_publisher_job.rb +72 -0
  91. data/app/models/settings.rb +19 -0
  92. data/app/models/tumblr_post_publisher_job.rb +75 -0
  93. data/app/models/tw_post_publisher_job.rb +54 -0
  94. data/app/views/admin/_edit_head_content.html.haml +2 -0
  95. data/app/views/admin/atreides/comments/_line.html.haml +60 -0
  96. data/app/views/admin/atreides/comments/_sidebar.html.haml +52 -0
  97. data/app/views/admin/atreides/comments/create.js.haml +1 -0
  98. data/app/views/admin/atreides/comments/index.html.haml +34 -0
  99. data/app/views/admin/atreides/content_parts/_form.html.haml +21 -0
  100. data/app/views/admin/atreides/content_parts/_photos.html.haml +18 -0
  101. data/app/views/admin/atreides/content_parts/_text.html.haml +1 -0
  102. data/app/views/admin/atreides/content_parts/_videos.html.haml +12 -0
  103. data/app/views/admin/atreides/content_parts/destroy.js.haml +3 -0
  104. data/app/views/admin/atreides/content_parts/edit.html.haml +0 -0
  105. data/app/views/admin/atreides/content_parts/new.html.haml +0 -0
  106. data/app/views/admin/atreides/content_parts/new.js.haml +11 -0
  107. data/app/views/admin/atreides/dropbox/_uploader.html.haml +134 -0
  108. data/app/views/admin/atreides/dropbox/list.html.haml +27 -0
  109. data/app/views/admin/atreides/dropbox/setup.html.haml +8 -0
  110. data/app/views/admin/atreides/features/_form.html.haml +60 -0
  111. data/app/views/admin/atreides/features/edit.html.haml +1 -0
  112. data/app/views/admin/atreides/features/index.html.haml +24 -0
  113. data/app/views/admin/atreides/features/new.html.haml +1 -0
  114. data/app/views/admin/atreides/github/index.html.haml +26 -0
  115. data/app/views/admin/atreides/github/show.html.haml +19 -0
  116. data/app/views/admin/atreides/likes/create.js.haml +2 -0
  117. data/app/views/admin/atreides/orders/_sidebar.html.haml +20 -0
  118. data/app/views/admin/atreides/orders/edit.html.haml +52 -0
  119. data/app/views/admin/atreides/orders/index.html.haml +8 -0
  120. data/app/views/admin/atreides/pages/_form.html.haml +31 -0
  121. data/app/views/admin/atreides/pages/edit.html.haml +3 -0
  122. data/app/views/admin/atreides/pages/index.html.haml +15 -0
  123. data/app/views/admin/atreides/pages/index.js.haml +4 -0
  124. data/app/views/admin/atreides/pages/new.html.haml +2 -0
  125. data/app/views/admin/atreides/photos/create.js.haml +18 -0
  126. data/app/views/admin/atreides/photos/destroy.js.haml +3 -0
  127. data/app/views/admin/atreides/posts/_archives.html.haml +19 -0
  128. data/app/views/admin/atreides/posts/_form.html.haml +66 -0
  129. data/app/views/admin/atreides/posts/_form_buttons.html.haml +9 -0
  130. data/app/views/admin/atreides/posts/_form_sidebar.html.haml +85 -0
  131. data/app/views/admin/atreides/posts/edit.html.haml +2 -0
  132. data/app/views/admin/atreides/posts/index.html.haml +24 -0
  133. data/app/views/admin/atreides/posts/index.js.haml +1 -0
  134. data/app/views/admin/atreides/posts/new.html.haml +2 -0
  135. data/app/views/admin/atreides/products/edit.html.haml +69 -0
  136. data/app/views/admin/atreides/products/index.html.haml +31 -0
  137. data/app/views/admin/atreides/sessions/new.html.haml +13 -0
  138. data/app/views/admin/atreides/user_sessions/new.html.haml +10 -0
  139. data/app/views/admin/atreides/users/_form.html.haml +19 -0
  140. data/app/views/admin/atreides/users/edit.html.haml +6 -0
  141. data/app/views/admin/atreides/users/index.html.haml +11 -0
  142. data/app/views/admin/atreides/users/new.html.haml +6 -0
  143. data/app/views/admin/atreides/users/show.html.haml +4 -0
  144. data/app/views/admin/atreides/videos/create.js.haml +9 -0
  145. data/app/views/admin/atreides/videos/destroy.js.haml +3 -0
  146. data/app/views/admin/common/_archive_sidebar.html.haml +29 -0
  147. data/app/views/admin/common/_list_table.html.erb +37 -0
  148. data/app/views/admin/common/_list_table_row.html.erb +18 -0
  149. data/app/views/admin/common/_pagination.html.erb +1 -0
  150. data/app/views/admin/common/_search_form.html.erb +6 -0
  151. data/app/views/admin/common/access_denied.html.haml +1 -0
  152. data/app/views/atreides/admin/_content_nav.html.haml +8 -0
  153. data/app/views/atreides/admin_home/_analytics.html.haml +93 -0
  154. data/app/views/atreides/admin_home/_fb_page_likes_analytics_tbody.haml +10 -0
  155. data/app/views/atreides/admin_home/_fb_page_views_analytics_tbody.haml +10 -0
  156. data/app/views/atreides/admin_home/_top_landing_pages_analytics_tbody.haml +14 -0
  157. data/app/views/atreides/admin_home/_top_referrers_analytics_tbody.haml +12 -0
  158. data/app/views/atreides/admin_home/_tweets_analytics_tbody.html.haml +8 -0
  159. data/app/views/atreides/admin_home/_visitors_analytics_tbody.html.haml +12 -0
  160. data/app/views/atreides/admin_home/index.html.haml +57 -0
  161. data/app/views/atreides/admin_home/search.html.haml +11 -0
  162. data/app/views/atreides/admin_home/setup.html.haml +15 -0
  163. data/app/views/atreides/common/_gallery_params.xml.erb +174 -0
  164. data/app/views/atreides/common/slideshow.xml.haml +6 -0
  165. data/app/views/atreides/errors/404.html.haml +10 -0
  166. data/app/views/atreides/errors/500.html.haml +4 -0
  167. data/app/views/atreides/home/index.html.haml +30 -0
  168. data/app/views/atreides/home/index.js.haml +1 -0
  169. data/app/views/atreides/home/robots.txt.erb +5 -0
  170. data/app/views/atreides/home/sitemap.xml.builder +35 -0
  171. data/app/views/atreides/pages/show.html.haml +3 -0
  172. data/app/views/atreides/posts/_archives.html.haml +19 -0
  173. data/app/views/atreides/posts/_featured_posts.html.haml +10 -0
  174. data/app/views/atreides/posts/_list.html.haml +9 -0
  175. data/app/views/atreides/posts/archives.html.haml +3 -0
  176. data/app/views/atreides/posts/archives.js.haml +1 -0
  177. data/app/views/atreides/posts/gallery_params.xml.haml +1 -0
  178. data/app/views/atreides/posts/index.atom.builder +22 -0
  179. data/app/views/atreides/posts/index.html.haml +13 -0
  180. data/app/views/atreides/posts/index.rss.builder +21 -0
  181. data/app/views/atreides/posts/show.html.haml +23 -0
  182. data/app/views/atreides/posts/tagged.html.haml +4 -0
  183. data/app/views/atreides/posts/tagged.js.haml +1 -0
  184. data/app/views/layouts/admin.html.haml +62 -0
  185. data/app/views/layouts/application.html.haml +37 -0
  186. data/app/views/layouts/atreides/application.html.erb +14 -0
  187. data/app/views/layouts/public.html.haml +39 -0
  188. data/config/cucumber.yml +11 -0
  189. data/config/locales/en.yml +236 -0
  190. data/config/locales/fr.yml +199 -0
  191. data/config/routes.rb +119 -0
  192. data/lib/assets/images/atreides/admin/add.png +0 -0
  193. data/lib/assets/images/atreides/admin/add_btn.png +0 -0
  194. data/lib/assets/images/atreides/admin/add_dashboard.png +0 -0
  195. data/lib/assets/images/atreides/admin/add_photo_button_sprite.png +0 -0
  196. data/lib/assets/images/atreides/admin/add_photos_btn.png +0 -0
  197. data/lib/assets/images/atreides/admin/background.png +0 -0
  198. data/lib/assets/images/atreides/admin/calendar.png +0 -0
  199. data/lib/assets/images/atreides/admin/chevron.gif +0 -0
  200. data/lib/assets/images/atreides/admin/chevron_overlay.png +0 -0
  201. data/lib/assets/images/atreides/admin/choose_photos_button_sprite.png +0 -0
  202. data/lib/assets/images/atreides/admin/content_bg.png +0 -0
  203. data/lib/assets/images/atreides/admin/content_bg_edit_form.png +0 -0
  204. data/lib/assets/images/atreides/admin/content_part_break.png +0 -0
  205. data/lib/assets/images/atreides/admin/content_part_drop_target.png +0 -0
  206. data/lib/assets/images/atreides/admin/content_part_icons.png +0 -0
  207. data/lib/assets/images/atreides/admin/content_part_photos.png +0 -0
  208. data/lib/assets/images/atreides/admin/content_part_text.png +0 -0
  209. data/lib/assets/images/atreides/admin/content_part_videos.png +0 -0
  210. data/lib/assets/images/atreides/admin/content_top_edit_form.png +0 -0
  211. data/lib/assets/images/atreides/admin/dashboard-indicator.gif +0 -0
  212. data/lib/assets/images/atreides/admin/dashboard_controls_activity.png +0 -0
  213. data/lib/assets/images/atreides/admin/dashboard_controls_customize.png +0 -0
  214. data/lib/assets/images/atreides/admin/dashboard_controls_drafts.png +0 -0
  215. data/lib/assets/images/atreides/admin/dashboard_controls_open.png +0 -0
  216. data/lib/assets/images/atreides/admin/dashboard_controls_posts.png +0 -0
  217. data/lib/assets/images/atreides/admin/dashboard_controls_queue.png +0 -0
  218. data/lib/assets/images/atreides/admin/dashboard_nav_border.png +0 -0
  219. data/lib/assets/images/atreides/admin/delete_bg.png +0 -0
  220. data/lib/assets/images/atreides/admin/down_arrow.png +0 -0
  221. data/lib/assets/images/atreides/admin/dropbox_big.jpg +0 -0
  222. data/lib/assets/images/atreides/admin/dropbox_btn.png +0 -0
  223. data/lib/assets/images/atreides/admin/dropbox_folder.png +0 -0
  224. data/lib/assets/images/atreides/admin/dropbox_icon.gif +0 -0
  225. data/lib/assets/images/atreides/admin/dropbox_icon.png +0 -0
  226. data/lib/assets/images/atreides/admin/expand_collapse.png +0 -0
  227. data/lib/assets/images/atreides/admin/form_sidebar_divider.png +0 -0
  228. data/lib/assets/images/atreides/admin/grey_hatch_bg.png +0 -0
  229. data/lib/assets/images/atreides/admin/header.png +0 -0
  230. data/lib/assets/images/atreides/admin/icon_dropbox.gif +0 -0
  231. data/lib/assets/images/atreides/admin/icon_home.gif +0 -0
  232. data/lib/assets/images/atreides/admin/input_bg.gif +0 -0
  233. data/lib/assets/images/atreides/admin/large_loading.gif +0 -0
  234. data/lib/assets/images/atreides/admin/new_content_icons.png +0 -0
  235. data/lib/assets/images/atreides/admin/off.png +0 -0
  236. data/lib/assets/images/atreides/admin/on.png +0 -0
  237. data/lib/assets/images/atreides/admin/page_icon.png +0 -0
  238. data/lib/assets/images/atreides/admin/permalink.png +0 -0
  239. data/lib/assets/images/atreides/admin/photos-display-type-gallery.png +0 -0
  240. data/lib/assets/images/atreides/admin/photos-display-type-photos.png +0 -0
  241. data/lib/assets/images/atreides/admin/product.png +0 -0
  242. data/lib/assets/images/atreides/admin/remove.png +0 -0
  243. data/lib/assets/images/atreides/admin/resize.png +0 -0
  244. data/lib/assets/images/atreides/admin/save_btn.png +0 -0
  245. data/lib/assets/images/atreides/admin/search_icon.png +0 -0
  246. data/lib/assets/images/atreides/admin/select_arrows.png +0 -0
  247. data/lib/assets/images/atreides/admin/slider.png +0 -0
  248. data/lib/assets/images/atreides/admin/slider_center.png +0 -0
  249. data/lib/assets/images/atreides/admin/slider_left.png +0 -0
  250. data/lib/assets/images/atreides/admin/slider_right.png +0 -0
  251. data/lib/assets/images/atreides/admin/sprite.png +0 -0
  252. data/lib/assets/images/atreides/admin/upload_btn.png +0 -0
  253. data/lib/assets/images/atreides/admin/video_bg.png +0 -0
  254. data/lib/assets/images/atreides/blank.gif +0 -0
  255. data/lib/assets/images/atreides/closelabel.png +0 -0
  256. data/lib/assets/images/atreides/loading.gif +0 -0
  257. data/lib/assets/images/atreides/sprite.png +0 -0
  258. data/lib/assets/images/atreides/tipsy.gif +0 -0
  259. data/lib/atreides.rb +82 -0
  260. data/lib/atreides/base/aasmstates.rb +117 -0
  261. data/lib/atreides/base/base.rb +40 -0
  262. data/lib/atreides/base/taggable.rb +43 -0
  263. data/lib/atreides/base/validation.rb +23 -0
  264. data/lib/atreides/configuration.rb +61 -0
  265. data/lib/atreides/engine.rb +41 -0
  266. data/lib/atreides/extendable.rb +12 -0
  267. data/lib/atreides/i18n_helpers.rb +65 -0
  268. data/lib/atreides/railties/tasks.rake +68 -0
  269. data/lib/atreides/time_formats.rb +19 -0
  270. data/lib/atreides/validators.rb +15 -0
  271. data/lib/atreides/version.rb +4 -0
  272. data/lib/generators/atreides/USAGE +0 -0
  273. data/lib/generators/atreides/atreides_generator.rb +58 -0
  274. data/lib/generators/templates/Procfile +2 -0
  275. data/lib/generators/templates/add_role_to_users.rb +16 -0
  276. data/lib/generators/templates/add_userid_to_resources.rb +15 -0
  277. data/lib/generators/templates/create_comments.rb +19 -0
  278. data/lib/generators/templates/create_content_parts.rb +66 -0
  279. data/lib/generators/templates/create_features.rb +21 -0
  280. data/lib/generators/templates/create_likes.rb +16 -0
  281. data/lib/generators/templates/create_line_items.rb +21 -0
  282. data/lib/generators/templates/create_links.rb +16 -0
  283. data/lib/generators/templates/create_messages.rb +24 -0
  284. data/lib/generators/templates/create_orders.rb +31 -0
  285. data/lib/generators/templates/create_pages.rb +31 -0
  286. data/lib/generators/templates/create_photos.rb +22 -0
  287. data/lib/generators/templates/create_posts.rb +38 -0
  288. data/lib/generators/templates/create_products.rb +24 -0
  289. data/lib/generators/templates/create_sessions.rb +16 -0
  290. data/lib/generators/templates/create_sites.rb +35 -0
  291. data/lib/generators/templates/create_sizes.rb +16 -0
  292. data/lib/generators/templates/create_tweets.rb +25 -0
  293. data/lib/generators/templates/create_videos.rb +24 -0
  294. data/lib/generators/templates/create_votes.rb +20 -0
  295. data/lib/generators/templates/delayed_job.rb +5 -0
  296. data/lib/generators/templates/devise_create_users.rb +42 -0
  297. data/lib/generators/templates/disqussion.rb +30 -0
  298. data/lib/generators/templates/em-net-http_override.rb +74 -0
  299. data/lib/generators/templates/initializer.rb +21 -0
  300. data/lib/generators/templates/new_relic.rb +6 -0
  301. data/lib/generators/templates/oembed.yml +63 -0
  302. data/lib/generators/templates/settings.yml +110 -0
  303. data/lib/generators/templates/string_extensions.rb +20 -0
  304. data/lib/generators/templates/unicorn.rb +2 -0
  305. data/lib/tasks/atreides_tasks.rake +4 -0
  306. data/lib/tasks/cucumber.rake +58 -0
  307. data/lib/tasks/tasks.rake +403 -0
  308. data/lib/tasks/yard.rake +18 -0
  309. metadata +1458 -0
@@ -0,0 +1,107 @@
1
+ class Atreides::ContentPart < Atreides::Base
2
+
3
+ include Atreides::Base::Validation
4
+
5
+ #
6
+ # Constants
7
+ #
8
+ @@content_types = %w(text photos videos)
9
+ @@display_types = %w(photos gallery)
10
+
11
+ #
12
+ # Associatons
13
+ #
14
+ belongs_to :contentable, :polymorphic => true, :touch => true
15
+ has_many :photos, :as => :photoable, :order => "display_order", :class_name => "Atreides::Photo", :dependent => :destroy
16
+ has_many :videos, :order => "display_order", :class_name => "Atreides::Video", :dependent => :destroy
17
+
18
+ #
19
+ # Behaviours
20
+ #
21
+
22
+ #XXX acts_as_commentable
23
+ accepts_nested_attributes_for :photos, :allow_destroy => true
24
+ accepts_nested_attributes_for :videos, :allow_destroy => true
25
+
26
+ #
27
+ # Validations
28
+ #
29
+ validates_inclusion_of :content_type, :in => @@content_types
30
+ validates_inclusion_of :display_type, :in => @@display_types, :if => Proc.new {|c| c.content_type? && c.content_type.photos? }
31
+ validate :should_have_text, :if => Proc.new {|c| c.content_type? && c.content_type.text? }
32
+ validate :should_have_photos, :if => Proc.new {|c| c.content_type? && c.content_type.photos? }
33
+ validate :should_have_video, :if => Proc.new {|c| c.content_type? && c.content_type.videos? }
34
+
35
+ #
36
+ # Scopes
37
+ #
38
+
39
+ @@content_types.each do |type|
40
+ scope type.pluralize, where(:content_type => type.to_s)
41
+ end
42
+
43
+ #
44
+ # Callbacks
45
+ #
46
+ after_initialize :set_display_type
47
+ before_create :add_to_queue
48
+
49
+ #
50
+ # Class Methods
51
+ #
52
+ class << self
53
+
54
+ def content_types
55
+ @@content_types
56
+ end
57
+
58
+ def display_types
59
+ @@display_types
60
+ end
61
+
62
+ def base_class
63
+ self
64
+ end
65
+
66
+ end
67
+
68
+ #
69
+ # Instance Methods
70
+ #
71
+ def content_type
72
+ @_content_type ||= ActiveSupport::StringInquirer.new(read_attribute(:content_type)) unless read_attribute(:content_type).blank?
73
+ end
74
+
75
+ def display_type
76
+ @_display_type ||= ActiveSupport::StringInquirer.new(read_attribute(:display_type)) unless read_attribute(:display_type).blank?
77
+ end
78
+
79
+ def content_types
80
+ self.class.content_types
81
+ end
82
+
83
+ private
84
+
85
+ def add_to_queue
86
+ # Set the display order to be last
87
+ self.display_order ||= Atreides::ContentPart.where(:contentable_id => self.contentable_id, :contentable_type => self.contentable_type).count
88
+ end
89
+
90
+ def set_display_type
91
+ self.display_type ||= @@display_types.first
92
+ end
93
+
94
+ def should_have_text
95
+ errors.add(:body, "should not be empty") unless body?
96
+ end
97
+
98
+ def should_have_photos
99
+ errors.add(:photos, "should not be empty") if photos.empty?
100
+ end
101
+
102
+ def should_have_video
103
+ errors.add(:videos, "should not be empty") if videos.empty?
104
+ end
105
+
106
+ include Atreides::Extendable
107
+ end
@@ -0,0 +1,90 @@
1
+ class Atreides::Feature < Atreides::Base
2
+
3
+ #
4
+ # Behaviours
5
+ #
6
+ include Atreides::Base::Taggable
7
+ include Atreides::Base::AasmStates
8
+ include Atreides::Base::Validation
9
+
10
+ #
11
+ # Associatons
12
+ #
13
+ belongs_to :photo
14
+ belongs_to :post, :class_name => "Atreides::Post"
15
+ belongs_to :site, :class_name => "Atreides::Site"
16
+
17
+ #
18
+ # Constants
19
+ #
20
+ attr_accessor :photo_url
21
+ accepts_nested_attributes_for :photo, :allow_destroy => true
22
+
23
+ #
24
+ # Validations
25
+ #
26
+ include ActiveRecord::Validations
27
+ validates_presence_of :photo, :display_order, :if => Proc.new{|f| !f.pending? && !f.post_id? }
28
+ validates_numericality_of :display_order
29
+ validates :url, :presence => true, :url => true, :if => :url?
30
+ validates :tag_list, :presence => true, :allow_blank => false
31
+
32
+
33
+ #
34
+ # Scopes
35
+ #
36
+ default_scope order("features.display_order asc, features.id desc")
37
+
38
+ #
39
+ # Callbacks
40
+ #
41
+ after_initialize :set_tag_list
42
+
43
+ def set_tag_list
44
+ self.tag_list = [Settings.tags.posts.features.first] if self.tag_list.empty? rescue []
45
+ end
46
+
47
+ #
48
+ # Class Methods
49
+ #
50
+ class << self
51
+ end
52
+
53
+ #
54
+ # Instance Methods
55
+ #
56
+
57
+ def thumbnail(size = :thumb)
58
+ # Find the first thumbnail image
59
+ if post_id?
60
+ post.thumbnail
61
+ elsif photo_id?
62
+ photo.image(size)
63
+ else
64
+ # FIXME: THIS NEEDS TO BE MOVED TO A VIEW/PRESENTER/DECORATOR
65
+ # asset_path('atreides/missing_thumb.png')
66
+
67
+ "/images/missing_thumb.png"
68
+ end
69
+ end
70
+
71
+ def photo
72
+ if post_id?
73
+ part = post.parts.detect{|p|p.content_type && p.content_type.photos?}
74
+ part ? part.photos.first : nil
75
+ elsif photo_id?
76
+ @photo ||= Atreides::Photo.find(photo_id)
77
+ end
78
+ end
79
+
80
+ def video
81
+ if post_id?
82
+ part = post.parts.detect{|p|p.content_type && p.content_type.videos?}
83
+ part ? part.videos.first : nil
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ include Atreides::Extendable
90
+ end
@@ -0,0 +1,74 @@
1
+ class Atreides::Github
2
+ attr_reader :data
3
+
4
+ def initialize(json_data)
5
+ @data = Hashie::Mash.new(json_data)
6
+ end
7
+
8
+ def method_missing(method)
9
+ @data.send(method)
10
+ end
11
+
12
+ def comments
13
+ id = @data.number
14
+ @comments ||= get_comments(id)
15
+ end
16
+
17
+
18
+ class << self
19
+ def all(options={})
20
+ issues(options)
21
+ end
22
+
23
+ def find(id)
24
+ Atreides::Github.new(issue(id))
25
+ end
26
+
27
+ def issue(id)
28
+ JSON.parse( get("repos/#{Settings.github.user}/#{Settings.github.repo}/issues/#{id}").body )
29
+ end
30
+
31
+ def issues(options)
32
+ options.reverse_merge!({:labels => "site,review me"})
33
+ JSON.parse( get("repos/#{Settings.github.user}/#{Settings.github.repo}/issues", {:params => options}).body )
34
+ end
35
+
36
+ def get(method, params={})
37
+ access_token.get("https://api.github.com/#{method}", params)
38
+ end
39
+
40
+ def authorize_url
41
+ client.auth_code.authorize_url(:redirect_uri => Settings.github.callback, :scope => Settings.github.scope)
42
+ end
43
+
44
+ def get_token(code)
45
+ client.auth_code.get_token(code, :redirect_uri => Settings.github.callback)
46
+ end
47
+
48
+ private
49
+
50
+ def client
51
+ OAuth2::Client.new( Settings.github.id,
52
+ Settings.github.secret,
53
+ :site => "https://github.com/",
54
+ :authorize_url => Settings.github.auth_url,
55
+ :token_url => Settings.github.access_token_url,
56
+ :http_method => :get
57
+ )
58
+ end
59
+
60
+ def access_token
61
+ OAuth2::AccessToken.new( client, Settings.github.token )
62
+ end
63
+
64
+
65
+
66
+ end
67
+
68
+ private
69
+
70
+ def get_comments(id)
71
+ JSON.parse( Atreides::Github.get("repos/#{Settings.github.user}/#{Settings.github.repo}/issues/#{id}/comments").body )
72
+ end
73
+
74
+ end
@@ -0,0 +1,35 @@
1
+ class Atreides::Like < Atreides::Base
2
+
3
+ #
4
+ # Constants
5
+ #
6
+
7
+ #
8
+ # Associations
9
+ #
10
+ belongs_to :likeable, :polymorphic => true, :counter_cache => true
11
+ belongs_to :user
12
+
13
+ #
14
+ # Validations
15
+ #
16
+ validates_presence_of :user
17
+ validates_uniqueness_of :user_id, :scope => [:likeable_type, :likeable_id]
18
+
19
+ #
20
+ # Scopes
21
+ #
22
+ default_scope order('created_at ASC')
23
+
24
+ #
25
+ # Class Methods
26
+ #
27
+ class << self
28
+ end
29
+
30
+ #
31
+ # Instance Methods
32
+ #
33
+
34
+ include Atreides::Extendable
35
+ end
@@ -0,0 +1,4 @@
1
+ class Atreides::LineItem < Atreides::Base
2
+
3
+ include Atreides::Extendable
4
+ end
@@ -0,0 +1,32 @@
1
+ class Atreides::Link < Atreides::Base
2
+
3
+ #
4
+ # Constants
5
+ #
6
+
7
+ #
8
+ # Associatons
9
+ #
10
+ belongs_to :post
11
+
12
+ #
13
+ # Validations
14
+ #
15
+ validates :url, :presence => true, :url => true, :if => :url?
16
+
17
+ #
18
+ # Scopes
19
+ #
20
+
21
+ #
22
+ # Class Methods
23
+ #
24
+ class << self
25
+ end
26
+
27
+ #
28
+ # Instance Methods
29
+ #
30
+
31
+ include Atreides::Extendable
32
+ end
@@ -0,0 +1,34 @@
1
+ class Atreides::Message < Atreides::Base
2
+
3
+ #
4
+ # Constants
5
+ #
6
+
7
+ #
8
+ # Associatons
9
+ #
10
+ belongs_to :messagable, :polymorphic => true
11
+ belongs_to :user
12
+
13
+ #
14
+ # Validations
15
+ #
16
+ validates_presence_of :name, :email, :body, :messagable_type, :messagable_id
17
+ validates_email_format_of :email
18
+
19
+ #
20
+ # Scopes
21
+ #
22
+
23
+ #
24
+ # Class Methods
25
+ #
26
+ class << self
27
+ end
28
+
29
+ #
30
+ # Instance Methods
31
+ #
32
+
33
+ include Atreides::Extendable
34
+ end
@@ -0,0 +1,209 @@
1
+ class Atreides::Order < Atreides::Base
2
+
3
+ #
4
+ # Constants
5
+ #
6
+ BILLING_COLS = %w(zip country street city province).freeze
7
+
8
+ #
9
+ # Behaviours
10
+ #
11
+ composed_of :amount, :class_name => "Money", :mapping => [%w(amount_cents cents), %w(currency currency)]
12
+ composed_of :discount, :class_name => "Money", :mapping => [%w(discount_cents cents), %w(currency currency)]
13
+ composed_of :final_amount, :class_name => "Money", :mapping => [%w(final_amount_cents cents), %w(currency currency)]
14
+
15
+ serialize :gateway_data
16
+
17
+ attr_accessor :card_type, :card_number, :card_verification, :card_expires_on
18
+
19
+ #
20
+ # States
21
+ #
22
+ require 'aasm'
23
+ include ::AASM
24
+ aasm_column :state
25
+ aasm_initial_state :pending
26
+ aasm_state :pending
27
+ aasm_state :completed
28
+ aasm_state :failed
29
+
30
+ aasm_event :complete do
31
+ transitions :from => [:pending], :to => :completed
32
+ end
33
+
34
+ aasm_event :fail do
35
+ transitions :from => [:pending, :failed], :to => :failed
36
+ end
37
+
38
+ #
39
+ # Associatons
40
+ #
41
+ belongs_to :user
42
+ has_many :line_items
43
+ has_many :products, :through => :line_items
44
+
45
+ #
46
+ # Validations
47
+ #
48
+ validates_numericality_of :amount_cents, :greater_than => 0
49
+ validates_numericality_of :discount_cents, :greater_than_or_equal_to => 0
50
+ validates_numericality_of :final_amount_cents, :greater_than_or_equal_to => 0
51
+ validates_presence_of :user, :email, :first_name, :last_name, :zip, :currency, :country, :street, :city, :province, :ip_address, :products
52
+
53
+ #
54
+ # Scopes
55
+ #
56
+ default_scope order('created_at DESC')
57
+
58
+ scope :by_month, lambda { |month|
59
+ where("MONTH(created_at) = ?", month.to_i)
60
+ }
61
+
62
+ scope :by_year, lambda { |year|
63
+ where("YEAR(created_at) = ?", year.to_i)
64
+ }
65
+
66
+ #
67
+ # Callbacks
68
+ #
69
+ after_create :do_gateway_payment
70
+ after_create :reduce_qty
71
+ before_validation :total_amounts, :on => :create
72
+
73
+ #
74
+ # Class Methods
75
+ #
76
+ class << self
77
+ def build_order_for_user(user)
78
+ # Get address info if user has previous orders
79
+ attrs = {}
80
+ if old_order = user.orders.first
81
+ old_order.attributes.each{|k,v| attrs[k] = v if BILLING_COLS.include?(k) }
82
+ end
83
+
84
+ # Build new object
85
+ new(attrs.update({
86
+ :user => user,
87
+ :first_name => user.first_name,
88
+ :last_name => user.last_name,
89
+ :line_items => user.cart_items,
90
+ :amount => Money.new(user.cart_items.sum(:price_cents)),
91
+ :ip_address => user.current_login_ip
92
+ }))
93
+ end
94
+ end
95
+
96
+ #
97
+ # Instance Methods
98
+ #
99
+ def full_name
100
+ [first_name, last_name].join(' ')
101
+ end
102
+
103
+ def number
104
+ # TODO: Format this as something more user friendly
105
+ [id, created_at].map(&:to_i).join('-')
106
+ end
107
+
108
+ def address
109
+ %w(street city province zip country).map{|f| self.send(f) }.compact.join("\n")
110
+ end
111
+
112
+ def total_amounts
113
+ # Set price
114
+ self.amount = line_items.to_a.sum{ |i| i.total_price }
115
+
116
+ # Set final amount to be paid
117
+ self.final_amount = amount - discount
118
+ end
119
+
120
+ private
121
+
122
+ def reduce_qty
123
+ sold_outs = []
124
+ line_items.each do |l|
125
+ if product_size = l.product.sizes.detect{|s| s.name == l.size }
126
+ product_size.increment!(:qty, -1)
127
+ if product_size.qty.zero?
128
+ sold_outs << product_size.product
129
+ end
130
+ end
131
+ end
132
+
133
+ # Mail admin if sold out
134
+ Notifier.deliver_sold_out_warning(sold_outs) if !sold_outs.empty?
135
+ end
136
+
137
+ def do_gateway_payment
138
+ # we set the serials first to raise error before payment
139
+ auth = gateway.authorize(final_amount, credit_card, purchase_options)
140
+
141
+ raise auth.message unless auth.success?
142
+
143
+ # Authorization is zero if account is globally in test mode, you cannot capture:
144
+ unless auth.authorization == "0"
145
+ capture = gateway.capture(price, capture.authorization) #, purchase_options)
146
+ end
147
+
148
+ update_attribute(:gateway_data, capture)
149
+
150
+ capture.success? ? complete! : fail!
151
+ capture.success?
152
+ end
153
+
154
+ def purchase_options
155
+ options = {
156
+ :order_id => id,
157
+ :ip => ip_address,
158
+ :customer => full_name,
159
+ :invoice => number,
160
+ :merchant => Settings.app_name,
161
+ :description => "#{Settings.domain}: Purchase of #{products.map(&:title).join(', ')}",
162
+ :email => email,
163
+ :currency => currency,
164
+ :billing_address => {
165
+ :name => full_name,
166
+ :city => city,
167
+ :state => province,
168
+ :country => country,
169
+ :zip => zip,
170
+ :address1 => street
171
+ }
172
+ }
173
+ options[:test] = true if Rails.env.development?
174
+ options
175
+ end
176
+
177
+ def credit_card
178
+ @credit_card ||= ActiveMerchant::Billing::CreditCard.new(
179
+ :type => card_type,
180
+ :number => card_number,
181
+ :verification_value => card_verification,
182
+ :month => card_expires_on.month,
183
+ :year => card_expires_on.year,
184
+ :first_name => first_name,
185
+ :last_name => last_name
186
+ )
187
+ end
188
+
189
+ def validate_card
190
+ unless credit_card.valid?
191
+ credit_card.errors.full_messages.each do |message|
192
+ errors.add(:base, message)
193
+ end
194
+ end
195
+ end
196
+
197
+ def gateway
198
+ ActiveMerchant::Billing::Base.mode = Rails.env.production? ? :production : :test
199
+ if Rails.env.test? || Rails.env.development?
200
+ ActiveMerchant::Billing::BogusGateway.new
201
+ else
202
+ ActiveMerchant::Billing::AuthorizeNetGateway.new({
203
+ :login => Settings.paypal.login,
204
+ :password => Settings.paypal.password})
205
+ end
206
+ end
207
+
208
+ include Atreides::Extendable
209
+ end