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,75 @@
1
+ class Atreides::Product < Atreides::Base
2
+
3
+ #
4
+ # Constants
5
+ #
6
+
7
+ #
8
+ # Associatons
9
+ #
10
+ has_many :photos, :as => :photoable, :order => "display_order"
11
+ has_many :line_items
12
+ has_many :orders, :through => :line_items
13
+ has_many :sizes, :order => "display_order"
14
+
15
+ #
16
+ # Behaviours
17
+ #
18
+ include Atreides::Base::Taggable
19
+ include Atreides::Base::AasmStates
20
+ composed_of :price, :class_name => "Money", :mapping => [%w(price_cents cents), %w(price_currency currency)]
21
+ accepts_nested_attributes_for :photos, :allow_destroy => true
22
+ accepts_nested_attributes_for :sizes, :allow_destroy => true, :reject_if => Proc.new {|s| s['name'].blank? }
23
+
24
+ #
25
+ # Validations
26
+ #
27
+ validates_presence_of :title, :body, :slug, :unless => :pending?
28
+ validates_uniqueness_of :slug, :unless => :pending?
29
+ validates_associated :sizes
30
+ validates_numericality_of :price_cents
31
+
32
+ validate :check_price, :on => :update
33
+
34
+ def check_price
35
+ errors.add(:price, "must be greater than zero") if price.zero? and !pending?
36
+ end
37
+
38
+ #
39
+ # Scopes
40
+ #
41
+
42
+ #
43
+ # Callbacks
44
+ #
45
+ before_validation :set_slug
46
+
47
+ def set_slug
48
+ # Set slug
49
+ self.slug = title.to_s.parameterize if !slug?
50
+ end
51
+
52
+ #
53
+ # Class Methods
54
+ #
55
+ class << self
56
+ def base_class
57
+ self
58
+ end
59
+ end
60
+
61
+ #
62
+ # Instance Methods
63
+ #
64
+ def size_for_name(name)
65
+ sizes.first(:conditions => {:name => name})
66
+ end
67
+
68
+ def sold_out?
69
+ self.sizes.sum(:qty).zero?
70
+ end
71
+
72
+ private
73
+
74
+ include Atreides::Extendable
75
+ end
@@ -0,0 +1,59 @@
1
+ class Atreides::Site < Atreides::Base
2
+
3
+ #
4
+ # Constants
5
+ #
6
+
7
+ #
8
+ # Associatons
9
+ #
10
+ has_many :posts
11
+ has_many :pages
12
+ has_many :features
13
+
14
+ #
15
+ # Validations
16
+ #
17
+ validates :name, :presence => true, :uniqueness => true
18
+ validates :lang, :presence => true, :inclusion => { :in => I18n.available_locales }
19
+ before_validation :set_default_lang
20
+
21
+ #
22
+ # Scopes
23
+ #
24
+ default_scope :order => "id asc"
25
+
26
+ #
27
+ # Callbacks
28
+ #
29
+
30
+
31
+ #
32
+ # Class Methods
33
+ #
34
+ class << self
35
+
36
+ # Use www or go for the first one
37
+ def default
38
+ find_by_name('www') || first || create(:name => 'www', :lang => I18n.locale)
39
+ end
40
+
41
+ end
42
+
43
+ #
44
+ # Instance methods
45
+ #
46
+ def lang
47
+ # Symbolize to make easier to integrate w I18n
48
+ read_attribute(:lang) ? read_attribute(:lang).to_sym : nil
49
+ end
50
+
51
+ private
52
+
53
+ def set_default_lang
54
+ # Set the default value
55
+ self.lang ||= I18n.locale if new_record?
56
+ end
57
+
58
+ include Atreides::Extendable
59
+ end
@@ -0,0 +1,44 @@
1
+ class Atreides::Size < Atreides::Base
2
+
3
+ #
4
+ # Constants
5
+ #
6
+
7
+ #
8
+ # Associatons
9
+ #
10
+ belongs_to :product
11
+
12
+ #
13
+ # Validations
14
+ #
15
+ validates_presence_of :name, :qty
16
+ validates_uniqueness_of :name, :scope => :product_id, :message => "can only be used once per product", :if => :product_id?
17
+ validates_numericality_of :qty, :greater_than_or_equal_to => 0
18
+ validates_numericality_of :display_order
19
+
20
+ #
21
+ # Scopes
22
+ #
23
+
24
+ #
25
+ # Callbacks
26
+ #
27
+
28
+ #
29
+ # Class Methods
30
+ #
31
+ class << self
32
+
33
+ def base_class
34
+ self
35
+ end
36
+
37
+ end
38
+
39
+ #
40
+ # Instance Methods
41
+ #
42
+
43
+ include Atreides::Extendable
44
+ end
@@ -0,0 +1,31 @@
1
+ class Atreides::Tag < ActsAsTaggableOn::Tag
2
+
3
+ #
4
+ # Constants
5
+ #
6
+
7
+ #
8
+ # Associatons
9
+ #
10
+
11
+ #
12
+ # Validations
13
+ #
14
+
15
+ #
16
+ # Callbacks
17
+ #
18
+
19
+
20
+ #
21
+ # Class Methods
22
+ #
23
+ class << self
24
+ end
25
+
26
+ #
27
+ # Instance Methods
28
+ #
29
+
30
+ include Atreides::Extendable
31
+ end
@@ -0,0 +1,123 @@
1
+ class Atreides::Tweet < Atreides::Base
2
+
3
+ #
4
+ # Constants
5
+ #
6
+
7
+ #
8
+ # Associatons
9
+ #
10
+
11
+ #
12
+ # Validations
13
+ #
14
+ validates_presence_of :twitter_id, :text, :from_user, :tweeted_at
15
+ validates_uniqueness_of :twitter_id
16
+
17
+ class << self
18
+ def analytics(since = 1.month.ago)
19
+ days = select("count(id) as twitter_id, sum(reach) as reach, DATE(tweeted_at) as tweeted_at").
20
+ where("tweeted_at > ?", since).
21
+ group("DATE(tweeted_at)").order(:twitter_id).map { |t|
22
+ {
23
+ :tweets => t.twitter_id,
24
+ :reach => t.reach,
25
+ :date => t.tweeted_at.to_date
26
+ }
27
+ }
28
+ end
29
+
30
+ def exposure(since = 1.month.ago)
31
+ where("tweeted_at > ?", since).sum(:reach)
32
+ end
33
+
34
+ def reach(since = 1.month.ago)
35
+ select("distinct(from_user), reach").where("tweeted_at > ?", since).to_a.sum(&:reach)
36
+ end
37
+
38
+ # Get most recent
39
+ def fetch_recent(started_at = nil)
40
+ # Twitter mentions
41
+ started_at ||= Time.zone.now
42
+ continue = true
43
+ users = []
44
+ per_page = 100
45
+
46
+ while continue do
47
+ # Get most recent tweets
48
+ tweets = twitter[:search].search.json?(
49
+ :q => Settings.twitter.search_for,
50
+ :since_id => Atreides::Tweet.maximum(:twitter_id),
51
+ # :since => (Atreides::Tweet.maximum(:tweeted_at) || 1.month.ago).to_date.to_s,
52
+ # :max_id => self.minimum(:twitter_id, :conditions => ["created_at >= ?", started_at]),
53
+ :rpp => per_page,
54
+ :lang => "all"
55
+ ).results
56
+
57
+ if continue = !tweets.size.zero?
58
+ # Get user ids
59
+ user_ids = tweets.map(&:from_user).uniq
60
+ page = 0
61
+
62
+ # Don't double fetch user-ids
63
+ unless users.empty?
64
+ user_ids -= users.map(&:screen_name).map(&:downcase)
65
+ end
66
+
67
+ continue_u = true
68
+ while continue_u do
69
+ sub_users = user_ids[page*per_page .. (page+1)*per_page] || []
70
+ if continue_u = !sub_users.size.zero?
71
+ page +=1
72
+ results = twitter.users.lookup.json?(:screen_name => sub_users.join(','))
73
+ # Append to list
74
+ users += results
75
+ end
76
+ end
77
+
78
+ # Add to DB
79
+ tweets.each do |twt|
80
+ u = users.detect{|u|u.screen_name.downcase==twt.from_user}
81
+ self.create(
82
+ :twitter_id => twt.id,
83
+ :tweeted_at => Time.zone.parse(twt.created_at),
84
+ :text => twt.text,
85
+ :from_user => twt.from_user,
86
+ :to_user => twt.to_user,
87
+ :reach => (u ? u.followers_count : 0),
88
+ :profile_image_url => twt.profile_image_url
89
+ )
90
+ end
91
+ end
92
+
93
+ # Return new tweets created
94
+ where("created_at >= ?", started_at).count(:id)
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def twitter
101
+ require 'grackle' unless defined?(Grackle)
102
+ @twitter ||= Grackle::Client.new(:auth => {
103
+ :type => :oauth,
104
+ :consumer_key => Settings.twitter.consumer_key,
105
+ :consumer_secret => Settings.twitter.consumer_secret,
106
+ :token => Settings.twitter.app_user_token,
107
+ :token_secret => Settings.twitter.app_user_secret
108
+ })
109
+ # Show debugging info
110
+ @twitter.transport.debug = true unless Rails.env.production?
111
+ @twitter
112
+ end
113
+
114
+ end
115
+
116
+ private
117
+
118
+ def twitter
119
+ self.class.twitter
120
+ end
121
+
122
+ include Atreides::Extendable
123
+ end
@@ -0,0 +1,129 @@
1
+ class Atreides::User < Atreides::Base
2
+ # Include default devise modules. Others available are:
3
+ # :token_authenticatable, :confirmable, :lockable and :timeoutable
4
+ begin
5
+ devise :database_authenticatable, :registerable,
6
+ :recoverable, :rememberable, :trackable, :validatable
7
+ rescue NoMethodError
8
+ puts "[WARNING] The Devise initializer seems to be missing. If you are generators, this is normal."
9
+ def self.devise *args
10
+ end
11
+ end
12
+
13
+ # Setup accessible (or protected) attributes for your model
14
+ attr_accessible :email, :password, :password_confirmation, :remember_me, :role
15
+
16
+
17
+ #
18
+ # Constants
19
+ #
20
+
21
+ #
22
+ # Associatons
23
+ #
24
+ has_many :comments
25
+ has_many :line_items
26
+ has_many :cart_items, :class_name => "LineItem", :conditions => "order_id is null"
27
+ has_many :orders
28
+ has_many :likes
29
+ has_many :posts, :class_name => "Atreides::Post", :through => :author_id
30
+ has_many :pages, :class_name => "Atreides::Page", :through => :author_id
31
+
32
+ #
33
+ # Behvaiours
34
+ #
35
+ attr_accessible :first_name, :last_name
36
+ # attr_accessible :twitter_token, :twitter_secret, :profile_pic_url, :fb_session_key
37
+
38
+ #
39
+ # Validations
40
+ #
41
+ validates :email, :presence => true, :uniqueness => true
42
+ validates :first_name, :presence => true
43
+ validates :last_name, :presence => true
44
+
45
+
46
+ #
47
+ # Callbacks
48
+ #
49
+ before_destroy :prevent_destroying_last_admin
50
+
51
+ #
52
+ # Scopes
53
+ #
54
+ scope :admins, lambda { where(:role => :admin) }
55
+
56
+ #
57
+ # Class Methods
58
+ #
59
+ class << self
60
+ def build_admin props
61
+ self.new (props || {}).merge :role => :admin
62
+ end
63
+
64
+ def can_destroy_admin?
65
+ admins.count > 1
66
+ end
67
+
68
+ # Sort by descending order of ability
69
+ def roles
70
+ [:admin, :editor, :writer]
71
+ end
72
+
73
+ def available_roles(user)
74
+ idx = roles.find_index(user.role.to_sym)
75
+ idx == nil ? [] : roles[idx..-1]
76
+ end
77
+ end
78
+
79
+ def prevent_destroying_last_admin
80
+ errors.add(:base, "not allowed destroying the last administrator") unless destroyable?
81
+ destroyable?
82
+ end
83
+
84
+ def destroyable?
85
+ !admin? || self.class.admins.count > 1
86
+ end
87
+
88
+ def admin?
89
+ role && role.to_sym == :admin
90
+ end
91
+
92
+ def role
93
+ @role ||= (self.attributes['role'] && self.attributes['role'].to_sym)
94
+ end
95
+
96
+ #
97
+ # Instance Methods
98
+ #
99
+ def full_name
100
+ [first_name, last_name].join(' ')
101
+ end
102
+
103
+ def add_to_cart(opts = {})
104
+ product = opts[:product]
105
+ size = opts[:size].to_s
106
+ qty = opts[:qty].to_i
107
+ return if !product or !product.is_a?(Product)
108
+
109
+ # Look for exisiting item
110
+ item = cart_items.detect{|i|i.product==product and i.product.size_for_name(size) }
111
+
112
+ # Create if not found
113
+ item = cart_items.build(:product => product, :size => size) if item.nil?
114
+
115
+ # Update qty
116
+ item.qty += qty
117
+
118
+ item.save
119
+ item
120
+ end
121
+
122
+ protected
123
+
124
+ def password_required?
125
+ !persisted? || password.present? || password_confirmation.present?
126
+ end
127
+
128
+ include Atreides::Extendable
129
+ end