virgo 0.1

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. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +37 -0
  4. data/app/assets/javascripts/tinymce/manifest.coffee +1 -0
  5. data/app/assets/javascripts/tinymce/plugins/image_manager/plugin.coffee +234 -0
  6. data/app/assets/javascripts/virgo/admin/page_modules/edit_form.coffee +4 -0
  7. data/app/assets/javascripts/virgo/admin/page_modules/edit_subject_form.coffee +29 -0
  8. data/app/assets/javascripts/virgo/admin/posts/edit_locking.coffee +35 -0
  9. data/app/assets/javascripts/virgo/admin/posts/form.coffee +183 -0
  10. data/app/assets/javascripts/virgo/admin/slides/form.coffee +27 -0
  11. data/app/assets/javascripts/virgo/admin/slideshows/form.coffee +26 -0
  12. data/app/assets/javascripts/virgo/admin_only.coffee +1 -0
  13. data/app/assets/javascripts/virgo/application.coffee +51 -0
  14. data/app/assets/javascripts/virgo/common.coffee +83 -0
  15. data/app/assets/javascripts/virgo/common/character_counter.coffee +27 -0
  16. data/app/assets/javascripts/virgo/components/header.coffee +47 -0
  17. data/app/assets/javascripts/virgo/components/media_modal.coffee +151 -0
  18. data/app/assets/javascripts/virgo/components/share_bar.coffee +53 -0
  19. data/app/assets/javascripts/virgo/components/slideshow.coffee +35 -0
  20. data/app/assets/javascripts/virgo/lib/jquery-ui-multiselect.js +342 -0
  21. data/app/assets/javascripts/virgo/lib/jquery.browser.js +184 -0
  22. data/app/assets/javascripts/virgo/lib/jquery.cookie.js +114 -0
  23. data/app/assets/javascripts/virgo/lib/jquery.pjax.js +932 -0
  24. data/app/assets/javascripts/virgo/lib/jquery_ext.coffee +0 -0
  25. data/app/assets/javascripts/virgo/lib/manifest.coffee +5 -0
  26. data/app/assets/javascripts/virgo/lib/ouibounce.js +194 -0
  27. data/app/assets/javascripts/virgo/page_modules.coffee +175 -0
  28. data/app/assets/javascripts/virgo/posts/show.coffee +32 -0
  29. data/app/assets/stylesheets/tinymce/skin.sass +2 -0
  30. data/app/assets/stylesheets/tinymce/skins/railspress/content.min.sass +82 -0
  31. data/app/assets/stylesheets/tinymce/skins/railspress/fonts/tinymce-small.eot +0 -0
  32. data/app/assets/stylesheets/tinymce/skins/railspress/fonts/tinymce-small.svg +62 -0
  33. data/app/assets/stylesheets/tinymce/skins/railspress/fonts/tinymce-small.ttf +0 -0
  34. data/app/assets/stylesheets/tinymce/skins/railspress/fonts/tinymce-small.woff +0 -0
  35. data/app/assets/stylesheets/tinymce/skins/railspress/fonts/tinymce.eot +0 -0
  36. data/app/assets/stylesheets/tinymce/skins/railspress/fonts/tinymce.svg +63 -0
  37. data/app/assets/stylesheets/tinymce/skins/railspress/fonts/tinymce.ttf +0 -0
  38. data/app/assets/stylesheets/tinymce/skins/railspress/fonts/tinymce.woff +0 -0
  39. data/app/assets/stylesheets/tinymce/skins/railspress/img/anchor.gif +0 -0
  40. data/app/assets/stylesheets/tinymce/skins/railspress/img/loader.gif +0 -0
  41. data/app/assets/stylesheets/tinymce/skins/railspress/img/object.gif +0 -0
  42. data/app/assets/stylesheets/tinymce/skins/railspress/img/trans.gif +0 -0
  43. data/app/assets/stylesheets/tinymce/skins/railspress/skin.min.sass +1703 -0
  44. data/app/assets/stylesheets/virgo/_common.sass +65 -0
  45. data/app/assets/stylesheets/virgo/admin.sass +301 -0
  46. data/app/assets/stylesheets/virgo/admin/columns.sass +3 -0
  47. data/app/assets/stylesheets/virgo/admin/images.sass +14 -0
  48. data/app/assets/stylesheets/virgo/admin/media_modal.sass +72 -0
  49. data/app/assets/stylesheets/virgo/admin/post.sass +102 -0
  50. data/app/assets/stylesheets/virgo/admin/slideshow.sass +35 -0
  51. data/app/assets/stylesheets/virgo/admin/users.sass +2 -0
  52. data/app/assets/stylesheets/virgo/admin_only.sass +1 -0
  53. data/app/assets/stylesheets/virgo/application.sass +605 -0
  54. data/app/assets/stylesheets/virgo/columns.sass +51 -0
  55. data/app/assets/stylesheets/virgo/install.sass +15 -0
  56. data/app/assets/stylesheets/virgo/lib/bootstrap/bootstrap-imports.sass +9 -0
  57. data/app/assets/stylesheets/virgo/lib/bootstrap/bootstrap-overrides.sass +51 -0
  58. data/app/assets/stylesheets/virgo/lib/bootstrap/bootstrap-variables.sass +27 -0
  59. data/app/assets/stylesheets/virgo/lib/jquery-ui-multiselect.css +30 -0
  60. data/app/assets/stylesheets/virgo/lib/manifest.sass +3 -0
  61. data/app/assets/stylesheets/virgo/lib/ouibounce.css +222 -0
  62. data/app/assets/stylesheets/virgo/lib/select2-imports.sass +8 -0
  63. data/app/assets/stylesheets/virgo/page_modules.sass +54 -0
  64. data/app/assets/stylesheets/virgo/pages/authors.sass +30 -0
  65. data/app/assets/stylesheets/virgo/posts.sass +782 -0
  66. data/app/assets/stylesheets/virgo/search.sass +36 -0
  67. data/app/assets/stylesheets/virgo/ui.sass +434 -0
  68. data/app/assets/stylesheets/virgo/users.sass +9 -0
  69. data/app/controllers/virgo/admin/base_controller.rb +22 -0
  70. data/app/controllers/virgo/admin/categories_controller.rb +90 -0
  71. data/app/controllers/virgo/admin/columns_controller.rb +65 -0
  72. data/app/controllers/virgo/admin/images_controller.rb +89 -0
  73. data/app/controllers/virgo/admin/media_modal_controller.rb +101 -0
  74. data/app/controllers/virgo/admin/newsletters_controller.rb +37 -0
  75. data/app/controllers/virgo/admin/page_modules_controller.rb +62 -0
  76. data/app/controllers/virgo/admin/pages_controller.rb +6 -0
  77. data/app/controllers/virgo/admin/posts_controller.rb +173 -0
  78. data/app/controllers/virgo/admin/sites_controller.rb +31 -0
  79. data/app/controllers/virgo/admin/slides_controller.rb +71 -0
  80. data/app/controllers/virgo/admin/slideshows_controller.rb +66 -0
  81. data/app/controllers/virgo/admin/tags_controller.rb +98 -0
  82. data/app/controllers/virgo/admin/users/sessions_controller.rb +21 -0
  83. data/app/controllers/virgo/admin/users_controller.rb +84 -0
  84. data/app/controllers/virgo/application_controller.rb +151 -0
  85. data/app/controllers/virgo/categories_controller.rb +20 -0
  86. data/app/controllers/virgo/columns_controller.rb +24 -0
  87. data/app/controllers/virgo/images_controller.rb +9 -0
  88. data/app/controllers/virgo/install_controller.rb +46 -0
  89. data/app/controllers/virgo/page_modules_controller.rb +23 -0
  90. data/app/controllers/virgo/pages_controller.rb +29 -0
  91. data/app/controllers/virgo/posts_controller.rb +101 -0
  92. data/app/controllers/virgo/search_controller.rb +35 -0
  93. data/app/controllers/virgo/subscribers_controller.rb +54 -0
  94. data/app/controllers/virgo/tags_controller.rb +15 -0
  95. data/app/controllers/virgo/users/confirmations_controller.rb +18 -0
  96. data/app/controllers/virgo/users/passwords_controller.rb +31 -0
  97. data/app/controllers/virgo/users/registrations_controller.rb +41 -0
  98. data/app/controllers/virgo/users/sessions_controller.rb +32 -0
  99. data/app/controllers/virgo/users_controller.rb +15 -0
  100. data/app/helpers/virgo/admin/post_helper.rb +54 -0
  101. data/app/helpers/virgo/admin_helper.rb +15 -0
  102. data/app/helpers/virgo/application_helper.rb +124 -0
  103. data/app/helpers/virgo/hooks_helper.rb +30 -0
  104. data/app/helpers/virgo/page_modules_helper.rb +4 -0
  105. data/app/helpers/virgo/post_helper.rb +159 -0
  106. data/app/helpers/virgo/render_helper.rb +33 -0
  107. data/app/helpers/virgo/search_helper.rb +49 -0
  108. data/app/helpers/virgo/shortcode_helper.rb +7 -0
  109. data/app/helpers/virgo/text_helper.rb +12 -0
  110. data/app/helpers/virgo/video_helper.rb +34 -0
  111. data/app/models/concerns/virgo/common/slug_history.rb +36 -0
  112. data/app/models/concerns/virgo/common/uuid.rb +22 -0
  113. data/app/models/concerns/virgo/post/recommendations.rb +15 -0
  114. data/app/models/concerns/virgo/post/search.rb +100 -0
  115. data/app/models/concerns/virgo/user/search.rb +39 -0
  116. data/app/models/virgo/ability.rb +59 -0
  117. data/app/models/virgo/category.rb +44 -0
  118. data/app/models/virgo/column.rb +25 -0
  119. data/app/models/virgo/form_model.rb +19 -0
  120. data/app/models/virgo/image.rb +63 -0
  121. data/app/models/virgo/page_module.rb +42 -0
  122. data/app/models/virgo/page_module_post.rb +8 -0
  123. data/app/models/virgo/post.rb +391 -0
  124. data/app/models/virgo/post_category.rb +8 -0
  125. data/app/models/virgo/post_search.rb +7 -0
  126. data/app/models/virgo/post_tag.rb +10 -0
  127. data/app/models/virgo/site.rb +36 -0
  128. data/app/models/virgo/slide.rb +23 -0
  129. data/app/models/virgo/slideshow.rb +37 -0
  130. data/app/models/virgo/slug_history.rb +5 -0
  131. data/app/models/virgo/subscriber.rb +5 -0
  132. data/app/models/virgo/tag.rb +34 -0
  133. data/app/models/virgo/user.rb +145 -0
  134. data/app/uploaders/virgo/application_uploader.rb +11 -0
  135. data/app/uploaders/virgo/avatar_uploader.rb +21 -0
  136. data/app/uploaders/virgo/featured_image_uploader.rb +28 -0
  137. data/app/uploaders/virgo/image_uploader.rb +40 -0
  138. data/app/uploaders/virgo/slide_uploader.rb +19 -0
  139. data/app/views/layouts/virgo/admin.haml +16 -0
  140. data/app/views/layouts/virgo/admin/site_settings.haml +14 -0
  141. data/app/views/layouts/virgo/application.haml +63 -0
  142. data/app/views/layouts/virgo/errors.haml +42 -0
  143. data/app/views/layouts/virgo/main.haml +5 -0
  144. data/app/views/layouts/virgo/posts.haml +10 -0
  145. data/app/views/virgo/admin/categories/_form.haml +19 -0
  146. data/app/views/virgo/admin/categories/edit.haml +7 -0
  147. data/app/views/virgo/admin/categories/index.haml +38 -0
  148. data/app/views/virgo/admin/categories/modal_form.haml +11 -0
  149. data/app/views/virgo/admin/categories/new.haml +7 -0
  150. data/app/views/virgo/admin/categories/success_modal.haml +14 -0
  151. data/app/views/virgo/admin/columns/_form.haml +30 -0
  152. data/app/views/virgo/admin/columns/edit.haml +1 -0
  153. data/app/views/virgo/admin/columns/index.haml +30 -0
  154. data/app/views/virgo/admin/columns/new.haml +1 -0
  155. data/app/views/virgo/admin/images/_form.haml +46 -0
  156. data/app/views/virgo/admin/images/edit.haml +1 -0
  157. data/app/views/virgo/admin/images/index.haml +32 -0
  158. data/app/views/virgo/admin/images/new.haml +1 -0
  159. data/app/views/virgo/admin/media_modal/_image_settings.haml +17 -0
  160. data/app/views/virgo/admin/media_modal/_library_panel.haml +26 -0
  161. data/app/views/virgo/admin/media_modal/_upload_panel.haml +21 -0
  162. data/app/views/virgo/admin/media_modal/_upload_success.haml +7 -0
  163. data/app/views/virgo/admin/media_modal/index.haml +19 -0
  164. data/app/views/virgo/admin/newsletters/changelog.haml +25 -0
  165. data/app/views/virgo/admin/newsletters/edit.haml +6 -0
  166. data/app/views/virgo/admin/page_modules/edit.haml +33 -0
  167. data/app/views/virgo/admin/page_modules/edit_subject.haml +43 -0
  168. data/app/views/virgo/admin/pages/help.haml +114 -0
  169. data/app/views/virgo/admin/posts/_author_dropdown.haml +1 -0
  170. data/app/views/virgo/admin/posts/_categories_form.haml +7 -0
  171. data/app/views/virgo/admin/posts/_category.haml +22 -0
  172. data/app/views/virgo/admin/posts/_form.haml +201 -0
  173. data/app/views/virgo/admin/posts/_revisions.haml +40 -0
  174. data/app/views/virgo/admin/posts/edit.haml +9 -0
  175. data/app/views/virgo/admin/posts/index.haml +59 -0
  176. data/app/views/virgo/admin/posts/new.haml +1 -0
  177. data/app/views/virgo/admin/posts/revision_detail.haml +28 -0
  178. data/app/views/virgo/admin/posts/revisions.haml +3 -0
  179. data/app/views/virgo/admin/sites/edit.haml +12 -0
  180. data/app/views/virgo/admin/slides/_form.haml +41 -0
  181. data/app/views/virgo/admin/slides/edit.haml +1 -0
  182. data/app/views/virgo/admin/slides/new.haml +1 -0
  183. data/app/views/virgo/admin/slideshows/_form.haml +49 -0
  184. data/app/views/virgo/admin/slideshows/edit.haml +1 -0
  185. data/app/views/virgo/admin/slideshows/index.haml +43 -0
  186. data/app/views/virgo/admin/slideshows/new.haml +1 -0
  187. data/app/views/virgo/admin/tags/_form.haml +16 -0
  188. data/app/views/virgo/admin/tags/edit.haml +7 -0
  189. data/app/views/virgo/admin/tags/index.haml +33 -0
  190. data/app/views/virgo/admin/tags/modal_form.haml +12 -0
  191. data/app/views/virgo/admin/tags/new.haml +7 -0
  192. data/app/views/virgo/admin/tags/success_modal.haml +14 -0
  193. data/app/views/virgo/admin/users/_form.haml +62 -0
  194. data/app/views/virgo/admin/users/edit.haml +1 -0
  195. data/app/views/virgo/admin/users/index.haml +34 -0
  196. data/app/views/virgo/admin/users/new.haml +1 -0
  197. data/app/views/virgo/application/sitemap.xml.builder +0 -0
  198. data/app/views/virgo/authors/_profile_long.haml +13 -0
  199. data/app/views/virgo/authors/_profile_short.haml +10 -0
  200. data/app/views/virgo/categories/show.haml +24 -0
  201. data/app/views/virgo/columns/index.haml +19 -0
  202. data/app/views/virgo/columns/show.haml +18 -0
  203. data/app/views/virgo/common/_admin_navbar.haml +100 -0
  204. data/app/views/virgo/common/_alerts.haml +40 -0
  205. data/app/views/virgo/common/_analytics.html.erb +1 -0
  206. data/app/views/virgo/common/_base_errors.haml +8 -0
  207. data/app/views/virgo/common/_category_heading.haml +26 -0
  208. data/app/views/virgo/common/_disqus.html.erb +24 -0
  209. data/app/views/virgo/common/_disqus_comment_count.html.erb +12 -0
  210. data/app/views/virgo/common/_fb_api.html.erb +30 -0
  211. data/app/views/virgo/common/_fonts.html.erb +1 -0
  212. data/app/views/virgo/common/_footer.haml +13 -0
  213. data/app/views/virgo/common/_footer_javascript.html.erb +0 -0
  214. data/app/views/virgo/common/_header_analytics.html.erb +9 -0
  215. data/app/views/virgo/common/_list_signup.haml +20 -0
  216. data/app/views/virgo/common/_ouibounce_modal.haml +26 -0
  217. data/app/views/virgo/common/_public_nav.haml +58 -0
  218. data/app/views/virgo/common/_search_form.haml +8 -0
  219. data/app/views/virgo/common/_share_bar.haml +45 -0
  220. data/app/views/virgo/common/_user_vars.haml +2 -0
  221. data/app/views/virgo/errors/404.haml +10 -0
  222. data/app/views/virgo/errors/500.haml +10 -0
  223. data/app/views/virgo/images/_shortcode.haml +4 -0
  224. data/app/views/virgo/install/index.haml +58 -0
  225. data/app/views/virgo/install/success.haml +12 -0
  226. data/app/views/virgo/page_modules/_latest_posts.haml +29 -0
  227. data/app/views/virgo/page_modules/_popular_posts.haml +51 -0
  228. data/app/views/virgo/pages/authors.haml +8 -0
  229. data/app/views/virgo/pages/home.haml +0 -0
  230. data/app/views/virgo/pages/show.haml +6 -0
  231. data/app/views/virgo/posts/_author_info.haml +16 -0
  232. data/app/views/virgo/posts/_post_full.haml +63 -0
  233. data/app/views/virgo/posts/_post_short.haml +30 -0
  234. data/app/views/virgo/posts/_post_thumb_box.haml +13 -0
  235. data/app/views/virgo/posts/_recommendations.haml +12 -0
  236. data/app/views/virgo/posts/_sidebar_thumb.haml +4 -0
  237. data/app/views/virgo/posts/index.haml +22 -0
  238. data/app/views/virgo/posts/latest.haml +16 -0
  239. data/app/views/virgo/posts/more.haml +10 -0
  240. data/app/views/virgo/posts/rss.xml.builder +17 -0
  241. data/app/views/virgo/posts/show.haml +17 -0
  242. data/app/views/virgo/search/_form.haml +5 -0
  243. data/app/views/virgo/search/_item.haml +22 -0
  244. data/app/views/virgo/search/index.haml +11 -0
  245. data/app/views/virgo/search/new.haml +4 -0
  246. data/app/views/virgo/shortcode_templates/blockquote.haml +9 -0
  247. data/app/views/virgo/shortcode_templates/h1.haml +1 -0
  248. data/app/views/virgo/shortcode_templates/h2.haml +1 -0
  249. data/app/views/virgo/shortcode_templates/h3.haml +1 -0
  250. data/app/views/virgo/shortcode_templates/h4.haml +1 -0
  251. data/app/views/virgo/shortcode_templates/image.haml +17 -0
  252. data/app/views/virgo/shortcode_templates/pullquote.haml +3 -0
  253. data/app/views/virgo/shortcode_templates/slideshow.haml +35 -0
  254. data/app/views/virgo/shortcode_templates/tweet.haml +3 -0
  255. data/app/views/virgo/shortcode_templates/video.haml +8 -0
  256. data/app/views/virgo/subscribers/_success_modal.haml +13 -0
  257. data/app/views/virgo/subscribers/modal.haml +15 -0
  258. data/app/views/virgo/tags/show.haml +16 -0
  259. data/app/views/virgo/users/confirmations/new.html.haml +10 -0
  260. data/app/views/virgo/users/devise_mailer/confirmation_instructions.html.erb +7 -0
  261. data/app/views/virgo/users/devise_mailer/reset_password_instructions.html.haml +6 -0
  262. data/app/views/virgo/users/devise_mailer/unlock_instructions.html.haml +5 -0
  263. data/app/views/virgo/users/passwords/edit.html.haml +14 -0
  264. data/app/views/virgo/users/passwords/new.html.haml +14 -0
  265. data/app/views/virgo/users/registrations/edit.html.haml +30 -0
  266. data/app/views/virgo/users/registrations/new.html.haml +13 -0
  267. data/app/views/virgo/users/sessions/new.html.haml +12 -0
  268. data/app/views/virgo/users/shared/_links.haml +26 -0
  269. data/app/views/virgo/users/show.haml +11 -0
  270. data/app/views/virgo/users/unlocks/new.html.haml +9 -0
  271. data/config/initializers/action_mailer.rb +7 -0
  272. data/config/initializers/active_record.rb +72 -0
  273. data/config/initializers/active_record_symbolize.rb +18 -0
  274. data/config/initializers/assets.rb +17 -0
  275. data/config/initializers/backtrace_silencers.rb +7 -0
  276. data/config/initializers/carrierwave.rb +36 -0
  277. data/config/initializers/cookies_serializer.rb +3 -0
  278. data/config/initializers/devise.rb +257 -0
  279. data/config/initializers/filter_parameter_logging.rb +4 -0
  280. data/config/initializers/hash.rb +5 -0
  281. data/config/initializers/inflections.rb +16 -0
  282. data/config/initializers/mime_types.rb +4 -0
  283. data/config/initializers/nil_class.rb +13 -0
  284. data/config/initializers/non_digest_assets.rb +3 -0
  285. data/config/initializers/paper_trail.rb +30 -0
  286. data/config/initializers/schema_plus.rb +5 -0
  287. data/config/initializers/session_store.rb +3 -0
  288. data/config/initializers/shortcode.rb +12 -0
  289. data/config/initializers/simple_form.rb +170 -0
  290. data/config/initializers/simple_form_bootstrap.rb +136 -0
  291. data/config/initializers/string.rb +5 -0
  292. data/config/initializers/time_formatting.rb +23 -0
  293. data/config/initializers/wrap_parameters.rb +14 -0
  294. data/config/locales/devise.en.yml +60 -0
  295. data/config/routes.rb +96 -0
  296. data/config/schedule.rb +3 -0
  297. data/db/migrate/20150729174510_create_virgo_schema.rb +225 -0
  298. data/lib/generators/virgo/install/install_generator.rb +16 -0
  299. data/lib/generators/virgo/views/views_generator.rb +22 -0
  300. data/lib/tasks/virgo_tasks.rake +7 -0
  301. data/lib/virgo.rb +4 -0
  302. data/lib/virgo/development_mail_interceptor.rb +6 -0
  303. data/lib/virgo/email_validator.rb +6 -0
  304. data/lib/virgo/engine.rb +73 -0
  305. data/lib/virgo/reduce_validator.rb +6 -0
  306. data/lib/virgo/upload_helpers.rb +89 -0
  307. data/lib/virgo/version.rb +3 -0
  308. data/lib/virgo/view_help.rb +3 -0
  309. metadata +1051 -0
@@ -0,0 +1,8 @@
1
+ module Virgo
2
+ class PostCategory < ActiveRecord::Base
3
+ belongs_to :post
4
+ belongs_to :category
5
+
6
+ validates :category_id, uniqueness: {scope: :post_id}
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Virgo
2
+ class PostSearch < FormModel
3
+ attr_accessor :term
4
+
5
+ validates :term, presence: true
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ module Virgo
2
+ class PostTag < ActiveRecord::Base
3
+ belongs_to :post
4
+ belongs_to :tag
5
+
6
+ validates :tag_id, uniqueness: {scope: :post_id}
7
+
8
+ scope :by_position, ->{ order(position: :asc) }
9
+ end
10
+ end
@@ -0,0 +1,36 @@
1
+ module Virgo
2
+ class Site < ActiveRecord::Base
3
+ has_paper_trail only: [:weekly_newsletter_intro_copy]
4
+
5
+ after_save :expire_site_key
6
+
7
+ validates :name, presence: true
8
+
9
+ def self.instance
10
+ _instance = first
11
+
12
+ _instance = create if _instance.nil?
13
+
14
+ _instance || self.new
15
+ end
16
+
17
+ def generate_dummy_data!(opts={})
18
+ if Post.all.empty? || opts[:force] == true
19
+ require 'faker'
20
+ I18n.reload! # see https://github.com/stympy/faker/issues/285
21
+
22
+ post = Post.new(
23
+ headline: "Your First Post",
24
+ subhead: Faker::Lorem.paragraph,
25
+ author: User.order(id: :asc).first,
26
+ body: Faker::Lorem.paragraphs(10).map{|p| "<p>#{p}</p>"}.join,
27
+ status: :published,
28
+ publish_at: Time.now,
29
+ live: true
30
+ )
31
+
32
+ post.save!
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ module Virgo
2
+ class Slide < ActiveRecord::Base
3
+ belongs_to :slideshow, touch: true
4
+ belongs_to :image
5
+
6
+ scope :by_position, ->{ order(position: :asc) }
7
+
8
+ # validation disabled on editors' request
9
+ # validate :has_video_or_image
10
+
11
+ def video?
12
+ video_embed.present?
13
+ end
14
+
15
+ private
16
+
17
+ def has_video_or_image
18
+ if video_embed.blank? && image.blank?
19
+ errors[:base] << "Slide must include either a video embed or an image attachment."
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ module Virgo
2
+ class Slideshow < ActiveRecord::Base
3
+ validates :name, presence: true
4
+ after_save :expire_site_key
5
+ after_save :expire_containing_posts
6
+
7
+ belongs_to :author, class_name: 'Virgo::User'
8
+ has_many :slides, dependent: :destroy
9
+
10
+ scope :search, ->(filters=nil) {
11
+ filters ||= {}
12
+
13
+ items = all
14
+
15
+ if filters[:term].present?
16
+ if filters[:term].to_i
17
+ items = items.where("slideshows.name ILIKE :term_wildcard OR slideshows.id = :term", term_wildcard: "%#{filters[:term]}%", term: filters[:term].to_i)
18
+ else
19
+ items = items.where("slideshows.name ILIKE :term_wildcard", term_wildcard: "%#{filters[:term]}%")
20
+ end
21
+ end
22
+
23
+ items
24
+ }
25
+
26
+
27
+ def containing_posts
28
+ Post.containing_slideshow(self)
29
+ end
30
+
31
+ private
32
+
33
+ def expire_containing_posts
34
+ containing_posts.map &:touch
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ module Virgo
2
+ class SlugHistory < ActiveRecord::Base
3
+ belongs_to :record, polymorphic: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Virgo
2
+ class Subscriber < ActiveRecord::Base
3
+ validates :email, presence: true, uniqueness: {message: "is already subscribed to the mailing list"}, email: true, reduce: true
4
+ end
5
+ end
@@ -0,0 +1,34 @@
1
+ module Virgo
2
+ class Tag < ActiveRecord::Base
3
+ extend FriendlyId
4
+
5
+ friendly_id :name, use: :slugged
6
+
7
+ has_many :post_tags, dependent: :destroy
8
+ has_many :posts, through: :post_tags
9
+
10
+ belongs_to :created_by, class_name: 'Virgo::User'
11
+
12
+ validates :name, presence: true, uniqueness: {case_sensitive: false}
13
+
14
+ scope :with_post_count, ->{
15
+ select("virgo_tags.*, " +
16
+ "(SELECT COUNT(*) FROM virgo_post_tags WHERE virgo_post_tags.tag_id = virgo_tags.id) AS post_count"
17
+ )
18
+ }
19
+
20
+ def self.cache_key
21
+ "taga-#{maximum(:updated_at).try(:to_i)}-#{all.size}"
22
+ end
23
+
24
+ scope :search, ->(filters={}){
25
+ items = all
26
+
27
+ if filters[:term].present?
28
+ items = items.where("virgo_tags.name ILIKE :term", term: "%#{filters[:term]}%")
29
+ end
30
+
31
+ items
32
+ }
33
+ end
34
+ end
@@ -0,0 +1,145 @@
1
+ module Virgo
2
+ class User < ActiveRecord::Base
3
+ include User::Search
4
+
5
+ extend FriendlyId
6
+
7
+ friendly_id :byline, use: :slugged
8
+
9
+ mount_uploader :avatar, Virgo::AvatarUploader
10
+
11
+ devise :database_authenticatable, :recoverable, :validatable, :rememberable,
12
+ :timeoutable, authentication_keys: [:login], remember_for: 30.days
13
+
14
+ attr_accessor :login
15
+
16
+ symbolize :role
17
+
18
+ validates :username,
19
+ :presence => true,
20
+ :uniqueness => {
21
+ :case_sensitive => false
22
+ }
23
+
24
+ validates :byline, presence: true
25
+
26
+ has_many :posts, foreign_key: :author_id
27
+
28
+ scope :authors, ->{ where(role: [:superuser, :admin, :editor, :contributor]) }
29
+
30
+ scope :by_name, ->{ order("LOWER(virgo_users.first_name) ASC") }
31
+
32
+ scope :with_post_count, ->{
33
+ select("virgo_users.*, " +
34
+ "(SELECT COUNT(*) FROM virgo_posts WHERE virgo_posts.author_id = virgo_users.id) AS post_count"
35
+ )
36
+ }
37
+
38
+ before_validation :derive_byline
39
+
40
+ after_initialize :init
41
+
42
+ after_update :expire_posts
43
+
44
+ def admin_access?
45
+ role.in?([:superuser, :admin, :editor, :contributor])
46
+ end
47
+
48
+ def admin?
49
+ role == :admin
50
+ end
51
+
52
+ def superuser?
53
+ role == :superuser
54
+ end
55
+
56
+ def editor?
57
+ role == :editor
58
+ end
59
+
60
+ def admin_or_editor?
61
+ admin? || editor?
62
+ end
63
+
64
+ def self.role_names(opts={})
65
+ _names = {}
66
+
67
+ if opts[:superuser]
68
+ _names['Superuser'] = :superuser
69
+ end
70
+
71
+ _names.merge!(
72
+ 'Admin' => :admin,
73
+ 'Editor' => :editor,
74
+ 'Contributor' => :contributor,
75
+ 'Normal User' => :user
76
+ )
77
+
78
+
79
+ _names
80
+ end
81
+
82
+ def full_name
83
+ if first_name.present? && last_name.present?
84
+ "#{first_name} #{last_name}"
85
+ else
86
+ email
87
+ end
88
+ end
89
+
90
+ def pretty_name
91
+ if byline.present?
92
+ byline
93
+ else
94
+ full_name
95
+ end
96
+ end
97
+
98
+ def self.find_for_database_authentication(warden_conditions)
99
+ conditions = warden_conditions.dup
100
+ if login = conditions.delete(:login)
101
+ where(conditions.to_h).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
102
+ else
103
+ where(conditions.to_h).first
104
+ end
105
+ end
106
+
107
+ def self.find_first_by_auth_conditions(warden_conditions)
108
+ conditions = warden_conditions.dup
109
+ if login = conditions.delete(:login)
110
+ where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
111
+ else
112
+ if conditions[:username].nil?
113
+ where(conditions).first
114
+ else
115
+ where(username: conditions[:username]).first
116
+ end
117
+ end
118
+ end
119
+
120
+ private
121
+
122
+ def derive_byline
123
+ if byline.blank?
124
+ self.byline = username
125
+ end
126
+ end
127
+
128
+ def init
129
+ self.role = :anonymous if role.nil?
130
+ end
131
+
132
+ def should_generate_new_friendly_id?
133
+ byline_changed?
134
+ end
135
+
136
+ # because post pages reference this info,
137
+ # we want to make sure they get expired
138
+ def expire_posts
139
+ if slug_changed?
140
+ posts.update_all({updated_at: Time.now.to_datetime})
141
+ end
142
+ end
143
+ true
144
+ end
145
+ end
@@ -0,0 +1,11 @@
1
+ module Virgo
2
+ class ApplicationUploader < CarrierWave::Uploader::Base
3
+ include CarrierWave::MiniMagick
4
+
5
+ storage :file
6
+
7
+ def store_dir
8
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ module Virgo
2
+ class AvatarUploader < Virgo::ApplicationUploader
3
+ process resize_to_fill: [330, 330]
4
+
5
+ version :thumb do
6
+ process resize_to_fill: [120,120]
7
+ end
8
+
9
+ def extension_white_list
10
+ %w(jpg jpeg gif png)
11
+ end
12
+
13
+ def default_url(*args)
14
+ if version_name == :thumb
15
+ '//placehold.it/120x120'
16
+ else
17
+ '//placehold.it/330x330'
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ module Virgo
2
+ class FeaturedImageUploader < Virgo::ApplicationUploader
3
+ # Create different versions of your uploaded files:
4
+ version :thumb do
5
+ process :resize_to_fill => [301, 169]
6
+ end
7
+
8
+ version :med_thumb do
9
+ process :resize_to_fill => [600, 337]
10
+ end
11
+
12
+ version :content do
13
+ process :resize_to_limit => [800, 800]
14
+ end
15
+
16
+ version :featured do
17
+ process :resize_to_limit => [1000, 800]
18
+ end
19
+
20
+ version :wide do
21
+ process :resize_to_fill => [2000, 578]
22
+ end
23
+
24
+ def extension_white_list
25
+ %w(jpg jpeg gif png)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ module Virgo
2
+ class ImageUploader < Virgo::ApplicationUploader
3
+ # Create different versions of your uploaded files:
4
+ version :small_thumb do
5
+ process :resize_to_fill => [118, 100]
6
+ end
7
+
8
+ version :thumb do
9
+ process :resize_to_fill => [301, 169]
10
+ end
11
+
12
+ version :med_thumb do
13
+ process :resize_to_fill => [600, 337]
14
+ end
15
+
16
+ version :content do
17
+ process :resize_to_limit => [800, 800]
18
+ end
19
+
20
+ version :featured do
21
+ process :resize_to_limit => [1000, 800]
22
+ end
23
+
24
+ version :wide do
25
+ process :resize_to_fill => [2000, 578]
26
+ end
27
+
28
+ version :email do
29
+ process :resize_to_fill => [520, 300]
30
+ end
31
+
32
+ # version :large do
33
+ # process :resize_to_fit => [2000, 2000]
34
+ # end
35
+
36
+ def extension_white_list
37
+ %w(jpg jpeg gif png gif)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ module Virgo
2
+ class SlideUploader < Virgo::ApplicationUploader
3
+ version :med_thumb do
4
+ process :resize_to_fill => [500, 500]
5
+ end
6
+
7
+ version :content do
8
+ process :resize_to_limit => [800, 800]
9
+ end
10
+
11
+ def extension_white_list
12
+ %w(jpg jpeg gif png)
13
+ end
14
+
15
+ def store_dir
16
+ "uploads/#{model.class.to_s.underscore}/image/#{model.id}"
17
+ end
18
+ end
19
+ end