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.
- data/LICENSE +7 -0
- data/README.rdoc +1 -0
- data/app/assets/javascripts/atreides/admin.js +22 -0
- data/app/assets/javascripts/atreides/admin_base.js.erb +247 -0
- data/app/assets/javascripts/atreides/admin_edit.js +9 -0
- data/app/assets/javascripts/atreides/application.js +15 -0
- data/app/assets/javascripts/atreides/comments.coffee +50 -0
- data/app/assets/javascripts/atreides/public.js +24 -0
- data/app/assets/javascripts/atreides/public_base.js.erb +119 -0
- data/app/assets/javascripts/atreides/terryblr.js +57 -0
- data/app/assets/stylesheets/atreides/admin.css +21 -0
- data/app/assets/stylesheets/atreides/admin_base.css.erb +1762 -0
- data/app/assets/stylesheets/atreides/application.css +13 -0
- data/app/assets/stylesheets/atreides/formtastic_changes.css +10 -0
- data/app/assets/stylesheets/atreides/iphone-checkboxes.css.erb +97 -0
- data/app/assets/stylesheets/atreides/jBreadCrumb.css +109 -0
- data/app/assets/stylesheets/atreides/public.css +15 -0
- data/app/assets/stylesheets/atreides/public_base.css +101 -0
- data/app/assets/stylesheets/atreides/swfupload.css.erb +63 -0
- data/app/controllers/admin/atreides/comments_controller.rb +47 -0
- data/app/controllers/admin/atreides/content_parts_controller.rb +43 -0
- data/app/controllers/admin/atreides/dropbox_controller.rb +40 -0
- data/app/controllers/admin/atreides/features_controller.rb +63 -0
- data/app/controllers/admin/atreides/github_controller.rb +35 -0
- data/app/controllers/admin/atreides/links_controller.rb +3 -0
- data/app/controllers/admin/atreides/messages_controller.rb +3 -0
- data/app/controllers/admin/atreides/orders_controller.rb +35 -0
- data/app/controllers/admin/atreides/pages_controller.rb +59 -0
- data/app/controllers/admin/atreides/photos_controller.rb +79 -0
- data/app/controllers/admin/atreides/posts_controller.rb +109 -0
- data/app/controllers/admin/atreides/products_controller.rb +39 -0
- data/app/controllers/admin/atreides/sessions_controller.rb +7 -0
- data/app/controllers/admin/atreides/sizes_controller.rb +4 -0
- data/app/controllers/admin/atreides/tags_controller.rb +20 -0
- data/app/controllers/admin/atreides/users_controller.rb +50 -0
- data/app/controllers/admin/atreides/videos_controller.rb +53 -0
- data/app/controllers/atreides/admin_controller.rb +96 -0
- data/app/controllers/atreides/admin_home_controller.rb +211 -0
- data/app/controllers/atreides/application_controller.rb +93 -0
- data/app/controllers/atreides/comments_controller.rb +43 -0
- data/app/controllers/atreides/home_controller.rb +71 -0
- data/app/controllers/atreides/likes_controller.rb +44 -0
- data/app/controllers/atreides/pages_controller.rb +34 -0
- data/app/controllers/atreides/posts_controller.rb +119 -0
- data/app/controllers/atreides/public_controller.rb +43 -0
- data/app/helpers/admin/atreides/comments_helper.rb +8 -0
- data/app/helpers/admin/atreides/dropbox_helper.rb +42 -0
- data/app/helpers/admin/atreides/features_helper.rb +4 -0
- data/app/helpers/admin/atreides/github_helper.rb +43 -0
- data/app/helpers/admin/atreides/links_helper.rb +4 -0
- data/app/helpers/admin/atreides/messages_helper.rb +4 -0
- data/app/helpers/admin/atreides/orders_helper.rb +30 -0
- data/app/helpers/admin/atreides/pages_helper.rb +17 -0
- data/app/helpers/admin/atreides/photos_helper.rb +14 -0
- data/app/helpers/admin/atreides/posts_helper.rb +41 -0
- data/app/helpers/admin/atreides/products_helper.rb +37 -0
- data/app/helpers/admin/atreides/sizes_helper.rb +4 -0
- data/app/helpers/admin/atreides/user_sessions_helper.rb +4 -0
- data/app/helpers/admin/atreides/users_helper.rb +8 -0
- data/app/helpers/admin/atreides/videos_helper.rb +4 -0
- data/app/helpers/atreides/admin_helper.rb +243 -0
- data/app/helpers/atreides/admin_home_helper.rb +4 -0
- data/app/helpers/atreides/application_helper.rb +210 -0
- data/app/helpers/atreides/home_helper.rb +4 -0
- data/app/helpers/atreides/posts_helper.rb +119 -0
- data/app/inputs/files_input.rb +13 -0
- data/app/inputs/price_input.rb +18 -0
- data/app/inputs/underline_input.rb +16 -0
- data/app/models/atreides/ability.rb +24 -0
- data/app/models/atreides/comment.rb +93 -0
- data/app/models/atreides/content_part.rb +107 -0
- data/app/models/atreides/feature.rb +90 -0
- data/app/models/atreides/github.rb +74 -0
- data/app/models/atreides/like.rb +35 -0
- data/app/models/atreides/line_item.rb +4 -0
- data/app/models/atreides/link.rb +32 -0
- data/app/models/atreides/message.rb +34 -0
- data/app/models/atreides/order.rb +209 -0
- data/app/models/atreides/page.rb +114 -0
- data/app/models/atreides/photo.rb +130 -0
- data/app/models/atreides/post.rb +271 -0
- data/app/models/atreides/product.rb +75 -0
- data/app/models/atreides/site.rb +59 -0
- data/app/models/atreides/size.rb +44 -0
- data/app/models/atreides/tag.rb +31 -0
- data/app/models/atreides/tweet.rb +123 -0
- data/app/models/atreides/user.rb +129 -0
- data/app/models/atreides/video.rb +206 -0
- data/app/models/atreides/vote.rb +43 -0
- data/app/models/fb_post_publisher_job.rb +72 -0
- data/app/models/settings.rb +19 -0
- data/app/models/tumblr_post_publisher_job.rb +75 -0
- data/app/models/tw_post_publisher_job.rb +54 -0
- data/app/views/admin/_edit_head_content.html.haml +2 -0
- data/app/views/admin/atreides/comments/_line.html.haml +60 -0
- data/app/views/admin/atreides/comments/_sidebar.html.haml +52 -0
- data/app/views/admin/atreides/comments/create.js.haml +1 -0
- data/app/views/admin/atreides/comments/index.html.haml +34 -0
- data/app/views/admin/atreides/content_parts/_form.html.haml +21 -0
- data/app/views/admin/atreides/content_parts/_photos.html.haml +18 -0
- data/app/views/admin/atreides/content_parts/_text.html.haml +1 -0
- data/app/views/admin/atreides/content_parts/_videos.html.haml +12 -0
- data/app/views/admin/atreides/content_parts/destroy.js.haml +3 -0
- data/app/views/admin/atreides/content_parts/edit.html.haml +0 -0
- data/app/views/admin/atreides/content_parts/new.html.haml +0 -0
- data/app/views/admin/atreides/content_parts/new.js.haml +11 -0
- data/app/views/admin/atreides/dropbox/_uploader.html.haml +134 -0
- data/app/views/admin/atreides/dropbox/list.html.haml +27 -0
- data/app/views/admin/atreides/dropbox/setup.html.haml +8 -0
- data/app/views/admin/atreides/features/_form.html.haml +60 -0
- data/app/views/admin/atreides/features/edit.html.haml +1 -0
- data/app/views/admin/atreides/features/index.html.haml +24 -0
- data/app/views/admin/atreides/features/new.html.haml +1 -0
- data/app/views/admin/atreides/github/index.html.haml +26 -0
- data/app/views/admin/atreides/github/show.html.haml +19 -0
- data/app/views/admin/atreides/likes/create.js.haml +2 -0
- data/app/views/admin/atreides/orders/_sidebar.html.haml +20 -0
- data/app/views/admin/atreides/orders/edit.html.haml +52 -0
- data/app/views/admin/atreides/orders/index.html.haml +8 -0
- data/app/views/admin/atreides/pages/_form.html.haml +31 -0
- data/app/views/admin/atreides/pages/edit.html.haml +3 -0
- data/app/views/admin/atreides/pages/index.html.haml +15 -0
- data/app/views/admin/atreides/pages/index.js.haml +4 -0
- data/app/views/admin/atreides/pages/new.html.haml +2 -0
- data/app/views/admin/atreides/photos/create.js.haml +18 -0
- data/app/views/admin/atreides/photos/destroy.js.haml +3 -0
- data/app/views/admin/atreides/posts/_archives.html.haml +19 -0
- data/app/views/admin/atreides/posts/_form.html.haml +66 -0
- data/app/views/admin/atreides/posts/_form_buttons.html.haml +9 -0
- data/app/views/admin/atreides/posts/_form_sidebar.html.haml +85 -0
- data/app/views/admin/atreides/posts/edit.html.haml +2 -0
- data/app/views/admin/atreides/posts/index.html.haml +24 -0
- data/app/views/admin/atreides/posts/index.js.haml +1 -0
- data/app/views/admin/atreides/posts/new.html.haml +2 -0
- data/app/views/admin/atreides/products/edit.html.haml +69 -0
- data/app/views/admin/atreides/products/index.html.haml +31 -0
- data/app/views/admin/atreides/sessions/new.html.haml +13 -0
- data/app/views/admin/atreides/user_sessions/new.html.haml +10 -0
- data/app/views/admin/atreides/users/_form.html.haml +19 -0
- data/app/views/admin/atreides/users/edit.html.haml +6 -0
- data/app/views/admin/atreides/users/index.html.haml +11 -0
- data/app/views/admin/atreides/users/new.html.haml +6 -0
- data/app/views/admin/atreides/users/show.html.haml +4 -0
- data/app/views/admin/atreides/videos/create.js.haml +9 -0
- data/app/views/admin/atreides/videos/destroy.js.haml +3 -0
- data/app/views/admin/common/_archive_sidebar.html.haml +29 -0
- data/app/views/admin/common/_list_table.html.erb +37 -0
- data/app/views/admin/common/_list_table_row.html.erb +18 -0
- data/app/views/admin/common/_pagination.html.erb +1 -0
- data/app/views/admin/common/_search_form.html.erb +6 -0
- data/app/views/admin/common/access_denied.html.haml +1 -0
- data/app/views/atreides/admin/_content_nav.html.haml +8 -0
- data/app/views/atreides/admin_home/_analytics.html.haml +93 -0
- data/app/views/atreides/admin_home/_fb_page_likes_analytics_tbody.haml +10 -0
- data/app/views/atreides/admin_home/_fb_page_views_analytics_tbody.haml +10 -0
- data/app/views/atreides/admin_home/_top_landing_pages_analytics_tbody.haml +14 -0
- data/app/views/atreides/admin_home/_top_referrers_analytics_tbody.haml +12 -0
- data/app/views/atreides/admin_home/_tweets_analytics_tbody.html.haml +8 -0
- data/app/views/atreides/admin_home/_visitors_analytics_tbody.html.haml +12 -0
- data/app/views/atreides/admin_home/index.html.haml +57 -0
- data/app/views/atreides/admin_home/search.html.haml +11 -0
- data/app/views/atreides/admin_home/setup.html.haml +15 -0
- data/app/views/atreides/common/_gallery_params.xml.erb +174 -0
- data/app/views/atreides/common/slideshow.xml.haml +6 -0
- data/app/views/atreides/errors/404.html.haml +10 -0
- data/app/views/atreides/errors/500.html.haml +4 -0
- data/app/views/atreides/home/index.html.haml +30 -0
- data/app/views/atreides/home/index.js.haml +1 -0
- data/app/views/atreides/home/robots.txt.erb +5 -0
- data/app/views/atreides/home/sitemap.xml.builder +35 -0
- data/app/views/atreides/pages/show.html.haml +3 -0
- data/app/views/atreides/posts/_archives.html.haml +19 -0
- data/app/views/atreides/posts/_featured_posts.html.haml +10 -0
- data/app/views/atreides/posts/_list.html.haml +9 -0
- data/app/views/atreides/posts/archives.html.haml +3 -0
- data/app/views/atreides/posts/archives.js.haml +1 -0
- data/app/views/atreides/posts/gallery_params.xml.haml +1 -0
- data/app/views/atreides/posts/index.atom.builder +22 -0
- data/app/views/atreides/posts/index.html.haml +13 -0
- data/app/views/atreides/posts/index.rss.builder +21 -0
- data/app/views/atreides/posts/show.html.haml +23 -0
- data/app/views/atreides/posts/tagged.html.haml +4 -0
- data/app/views/atreides/posts/tagged.js.haml +1 -0
- data/app/views/layouts/admin.html.haml +62 -0
- data/app/views/layouts/application.html.haml +37 -0
- data/app/views/layouts/atreides/application.html.erb +14 -0
- data/app/views/layouts/public.html.haml +39 -0
- data/config/cucumber.yml +11 -0
- data/config/locales/en.yml +236 -0
- data/config/locales/fr.yml +199 -0
- data/config/routes.rb +119 -0
- data/lib/assets/images/atreides/admin/add.png +0 -0
- data/lib/assets/images/atreides/admin/add_btn.png +0 -0
- data/lib/assets/images/atreides/admin/add_dashboard.png +0 -0
- data/lib/assets/images/atreides/admin/add_photo_button_sprite.png +0 -0
- data/lib/assets/images/atreides/admin/add_photos_btn.png +0 -0
- data/lib/assets/images/atreides/admin/background.png +0 -0
- data/lib/assets/images/atreides/admin/calendar.png +0 -0
- data/lib/assets/images/atreides/admin/chevron.gif +0 -0
- data/lib/assets/images/atreides/admin/chevron_overlay.png +0 -0
- data/lib/assets/images/atreides/admin/choose_photos_button_sprite.png +0 -0
- data/lib/assets/images/atreides/admin/content_bg.png +0 -0
- data/lib/assets/images/atreides/admin/content_bg_edit_form.png +0 -0
- data/lib/assets/images/atreides/admin/content_part_break.png +0 -0
- data/lib/assets/images/atreides/admin/content_part_drop_target.png +0 -0
- data/lib/assets/images/atreides/admin/content_part_icons.png +0 -0
- data/lib/assets/images/atreides/admin/content_part_photos.png +0 -0
- data/lib/assets/images/atreides/admin/content_part_text.png +0 -0
- data/lib/assets/images/atreides/admin/content_part_videos.png +0 -0
- data/lib/assets/images/atreides/admin/content_top_edit_form.png +0 -0
- data/lib/assets/images/atreides/admin/dashboard-indicator.gif +0 -0
- data/lib/assets/images/atreides/admin/dashboard_controls_activity.png +0 -0
- data/lib/assets/images/atreides/admin/dashboard_controls_customize.png +0 -0
- data/lib/assets/images/atreides/admin/dashboard_controls_drafts.png +0 -0
- data/lib/assets/images/atreides/admin/dashboard_controls_open.png +0 -0
- data/lib/assets/images/atreides/admin/dashboard_controls_posts.png +0 -0
- data/lib/assets/images/atreides/admin/dashboard_controls_queue.png +0 -0
- data/lib/assets/images/atreides/admin/dashboard_nav_border.png +0 -0
- data/lib/assets/images/atreides/admin/delete_bg.png +0 -0
- data/lib/assets/images/atreides/admin/down_arrow.png +0 -0
- data/lib/assets/images/atreides/admin/dropbox_big.jpg +0 -0
- data/lib/assets/images/atreides/admin/dropbox_btn.png +0 -0
- data/lib/assets/images/atreides/admin/dropbox_folder.png +0 -0
- data/lib/assets/images/atreides/admin/dropbox_icon.gif +0 -0
- data/lib/assets/images/atreides/admin/dropbox_icon.png +0 -0
- data/lib/assets/images/atreides/admin/expand_collapse.png +0 -0
- data/lib/assets/images/atreides/admin/form_sidebar_divider.png +0 -0
- data/lib/assets/images/atreides/admin/grey_hatch_bg.png +0 -0
- data/lib/assets/images/atreides/admin/header.png +0 -0
- data/lib/assets/images/atreides/admin/icon_dropbox.gif +0 -0
- data/lib/assets/images/atreides/admin/icon_home.gif +0 -0
- data/lib/assets/images/atreides/admin/input_bg.gif +0 -0
- data/lib/assets/images/atreides/admin/large_loading.gif +0 -0
- data/lib/assets/images/atreides/admin/new_content_icons.png +0 -0
- data/lib/assets/images/atreides/admin/off.png +0 -0
- data/lib/assets/images/atreides/admin/on.png +0 -0
- data/lib/assets/images/atreides/admin/page_icon.png +0 -0
- data/lib/assets/images/atreides/admin/permalink.png +0 -0
- data/lib/assets/images/atreides/admin/photos-display-type-gallery.png +0 -0
- data/lib/assets/images/atreides/admin/photos-display-type-photos.png +0 -0
- data/lib/assets/images/atreides/admin/product.png +0 -0
- data/lib/assets/images/atreides/admin/remove.png +0 -0
- data/lib/assets/images/atreides/admin/resize.png +0 -0
- data/lib/assets/images/atreides/admin/save_btn.png +0 -0
- data/lib/assets/images/atreides/admin/search_icon.png +0 -0
- data/lib/assets/images/atreides/admin/select_arrows.png +0 -0
- data/lib/assets/images/atreides/admin/slider.png +0 -0
- data/lib/assets/images/atreides/admin/slider_center.png +0 -0
- data/lib/assets/images/atreides/admin/slider_left.png +0 -0
- data/lib/assets/images/atreides/admin/slider_right.png +0 -0
- data/lib/assets/images/atreides/admin/sprite.png +0 -0
- data/lib/assets/images/atreides/admin/upload_btn.png +0 -0
- data/lib/assets/images/atreides/admin/video_bg.png +0 -0
- data/lib/assets/images/atreides/blank.gif +0 -0
- data/lib/assets/images/atreides/closelabel.png +0 -0
- data/lib/assets/images/atreides/loading.gif +0 -0
- data/lib/assets/images/atreides/sprite.png +0 -0
- data/lib/assets/images/atreides/tipsy.gif +0 -0
- data/lib/atreides.rb +82 -0
- data/lib/atreides/base/aasmstates.rb +117 -0
- data/lib/atreides/base/base.rb +40 -0
- data/lib/atreides/base/taggable.rb +43 -0
- data/lib/atreides/base/validation.rb +23 -0
- data/lib/atreides/configuration.rb +61 -0
- data/lib/atreides/engine.rb +41 -0
- data/lib/atreides/extendable.rb +12 -0
- data/lib/atreides/i18n_helpers.rb +65 -0
- data/lib/atreides/railties/tasks.rake +68 -0
- data/lib/atreides/time_formats.rb +19 -0
- data/lib/atreides/validators.rb +15 -0
- data/lib/atreides/version.rb +4 -0
- data/lib/generators/atreides/USAGE +0 -0
- data/lib/generators/atreides/atreides_generator.rb +58 -0
- data/lib/generators/templates/Procfile +2 -0
- data/lib/generators/templates/add_role_to_users.rb +16 -0
- data/lib/generators/templates/add_userid_to_resources.rb +15 -0
- data/lib/generators/templates/create_comments.rb +19 -0
- data/lib/generators/templates/create_content_parts.rb +66 -0
- data/lib/generators/templates/create_features.rb +21 -0
- data/lib/generators/templates/create_likes.rb +16 -0
- data/lib/generators/templates/create_line_items.rb +21 -0
- data/lib/generators/templates/create_links.rb +16 -0
- data/lib/generators/templates/create_messages.rb +24 -0
- data/lib/generators/templates/create_orders.rb +31 -0
- data/lib/generators/templates/create_pages.rb +31 -0
- data/lib/generators/templates/create_photos.rb +22 -0
- data/lib/generators/templates/create_posts.rb +38 -0
- data/lib/generators/templates/create_products.rb +24 -0
- data/lib/generators/templates/create_sessions.rb +16 -0
- data/lib/generators/templates/create_sites.rb +35 -0
- data/lib/generators/templates/create_sizes.rb +16 -0
- data/lib/generators/templates/create_tweets.rb +25 -0
- data/lib/generators/templates/create_videos.rb +24 -0
- data/lib/generators/templates/create_votes.rb +20 -0
- data/lib/generators/templates/delayed_job.rb +5 -0
- data/lib/generators/templates/devise_create_users.rb +42 -0
- data/lib/generators/templates/disqussion.rb +30 -0
- data/lib/generators/templates/em-net-http_override.rb +74 -0
- data/lib/generators/templates/initializer.rb +21 -0
- data/lib/generators/templates/new_relic.rb +6 -0
- data/lib/generators/templates/oembed.yml +63 -0
- data/lib/generators/templates/settings.yml +110 -0
- data/lib/generators/templates/string_extensions.rb +20 -0
- data/lib/generators/templates/unicorn.rb +2 -0
- data/lib/tasks/atreides_tasks.rake +4 -0
- data/lib/tasks/cucumber.rake +58 -0
- data/lib/tasks/tasks.rake +403 -0
- data/lib/tasks/yard.rake +18 -0
- metadata +1458 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
class Atreides::Page < Atreides::Base
|
|
2
|
+
|
|
3
|
+
include Atreides::Base::Taggable
|
|
4
|
+
include Atreides::Base::AasmStates
|
|
5
|
+
include Atreides::Base::Validation
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Constants
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Associatons
|
|
13
|
+
#
|
|
14
|
+
belongs_to :site, :class_name => "Atreides::Site"
|
|
15
|
+
belongs_to :author, :class_name => "Atreides::User"
|
|
16
|
+
belongs_to :last_editor, :class_name => "Atreides::User"
|
|
17
|
+
has_many :photos, :as => :photoable, :order => "display_order", :class_name => "Atreides::Photo"
|
|
18
|
+
has_many :messages, :as => :messagable, :class_name => "Atreides::Message"
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Behaviours
|
|
22
|
+
#
|
|
23
|
+
|
|
24
|
+
accepts_nested_attributes_for :messages
|
|
25
|
+
accepts_nested_attributes_for :photos, :allow_destroy => true
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Validations
|
|
29
|
+
#
|
|
30
|
+
validate :site_id, :presence => true
|
|
31
|
+
validates_presence_of :title, :body, :slug, :unless => :pending?
|
|
32
|
+
validate :slug, :uniqueness => true, :if => :slug?, :scope => :site_id
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Scopes
|
|
36
|
+
#
|
|
37
|
+
scope :roots, where(:parent_id => nil)
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Callbacks
|
|
41
|
+
#
|
|
42
|
+
before_validation :update_slug
|
|
43
|
+
|
|
44
|
+
def update_slug
|
|
45
|
+
# Set slug if not set or changed
|
|
46
|
+
self.slug = title.to_s.parameterize if !slug? or (!new_record? && title_changed?)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Class Methods
|
|
51
|
+
#
|
|
52
|
+
class << self
|
|
53
|
+
def base_class
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
#
|
|
59
|
+
# Instance Methods
|
|
60
|
+
#
|
|
61
|
+
|
|
62
|
+
def thumbnail(size = :thumb)
|
|
63
|
+
# Find the first thumbnail image
|
|
64
|
+
url = nil
|
|
65
|
+
url = photos.first.image.url(size) unless photos.empty?
|
|
66
|
+
|
|
67
|
+
# FIXME: THIS NEEDS TO BE MOVED TO A VIEW/PRESENTER/DECORATOR
|
|
68
|
+
# asset_path('atreides/missing_thumb.png')
|
|
69
|
+
|
|
70
|
+
url || "/images/missing_thumb.png"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def children
|
|
75
|
+
@children ||= self.class.find_all_by_parent_id(id)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def parent
|
|
79
|
+
@parent ||= parent_of
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def parents
|
|
83
|
+
@parents ||= []
|
|
84
|
+
return @parents unless @parents.empty?
|
|
85
|
+
|
|
86
|
+
prnt = self
|
|
87
|
+
while prnt.parent_id?
|
|
88
|
+
prnt = parent_of(prnt)
|
|
89
|
+
@parents << prnt
|
|
90
|
+
end
|
|
91
|
+
@parents
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def root()
|
|
95
|
+
return @root unless @root.nil?
|
|
96
|
+
prnt = self.parent || self
|
|
97
|
+
while prnt.parent_id?
|
|
98
|
+
prnt = parent_of(prnt)
|
|
99
|
+
end
|
|
100
|
+
@root = prnt
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
def do_publish
|
|
106
|
+
update_attribute :published_at, Time.zone.now
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def parent_of(page = self)
|
|
110
|
+
page.parent_id? ? self.class.find(page.parent_id) : nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
include Atreides::Extendable
|
|
114
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
class Atreides::Photo < Atreides::Base
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Constants
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Behaviours
|
|
9
|
+
#
|
|
10
|
+
serialize :sizes
|
|
11
|
+
|
|
12
|
+
# Regen thumbs with rake paperclip:refresh CLASS=Atreides::Photo or .reprocess!
|
|
13
|
+
has_attached_file :image,
|
|
14
|
+
:styles => Settings.photo_dimensions.dup.symbolize_keys,
|
|
15
|
+
:storage => Settings.s3_enabled? ? :s3 : :filesystem,
|
|
16
|
+
:convert_options => {
|
|
17
|
+
:all => Settings.photo_conv_options || "-density 72 "
|
|
18
|
+
},
|
|
19
|
+
:path => Settings.s3_enabled? ? ":attachment/:id/:style/:basename.:extension" : ":rails_root/public/system/:attachment/:id/:style/:basename.:extension",
|
|
20
|
+
:url => Settings.s3_enabled? ? ":attachment/:id/:style/:basename.:extension" : "/system/:attachment/:id/:style/:basename.:extension",
|
|
21
|
+
:s3_credentials => (Settings.s3.symbolize_keys rescue nil),
|
|
22
|
+
:bucket => [Settings.app_name, Rails.env].join('-').parameterize.to_s,
|
|
23
|
+
:log_command => Rails.env.development?
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Callbacks
|
|
27
|
+
#
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# Associatons
|
|
31
|
+
#
|
|
32
|
+
belongs_to :photoable, :polymorphic => true, :touch => true
|
|
33
|
+
has_many :features, :class_name => "Atreides::Feature"
|
|
34
|
+
|
|
35
|
+
# using :dependent => :nullify just did not worked on the has_many :features association
|
|
36
|
+
# so we make this to make each features clean and valid
|
|
37
|
+
before_destroy :clean_features
|
|
38
|
+
def clean_features
|
|
39
|
+
features.each do |f|
|
|
40
|
+
f.photo = nil
|
|
41
|
+
f.save
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
#
|
|
45
|
+
# Validations
|
|
46
|
+
#
|
|
47
|
+
validates_attachment_presence :image
|
|
48
|
+
validates_attachment_size :image, :less_than => 3.megabytes
|
|
49
|
+
validates_presence_of :url, :unless => :image_file_name?
|
|
50
|
+
validates :url, :presence => true, :url => true, :if => :url?
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# Scopes
|
|
54
|
+
#
|
|
55
|
+
default_scope :order => "display_order asc, id desc"
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Class Methods
|
|
59
|
+
#
|
|
60
|
+
class << self
|
|
61
|
+
|
|
62
|
+
def base_class
|
|
63
|
+
self
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# Instance Methods
|
|
70
|
+
#
|
|
71
|
+
before_validation :fetch_remote_image
|
|
72
|
+
before_create :add_to_queue
|
|
73
|
+
after_save :update_associated_models
|
|
74
|
+
|
|
75
|
+
def fetch_remote_image
|
|
76
|
+
# If there is a URL then download it and use
|
|
77
|
+
self.image = do_download_remote_image if url_changed?
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def add_to_queue
|
|
81
|
+
# Set the display order to be last
|
|
82
|
+
self.display_order = Atreides::Photo.count(:conditions => {:photoable_id => self.photoable_id, :photoable_type => self.photoable_type})
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def update_associated_models
|
|
86
|
+
# Update assoc'd models
|
|
87
|
+
features.update_all({:updated_at => Time.zone.now})
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def size(thumb)
|
|
91
|
+
sizes[thumb.to_sym]
|
|
92
|
+
rescue => exception
|
|
93
|
+
logger.error { "Error getting image sizes: #{exception}" }
|
|
94
|
+
{}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Overload Paperclip so that images are only resaved when it changes - uses too much memory otherwise
|
|
98
|
+
def save_attached_files
|
|
99
|
+
super if image_file_size_changed?
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Save the images dimensions before being sent to storage
|
|
103
|
+
after_post_process :calculate_attachment_sizes
|
|
104
|
+
def calculate_attachment_sizes
|
|
105
|
+
if (image_file_name?)
|
|
106
|
+
self.sizes = {}
|
|
107
|
+
self.image.queued_for_write.each {|key,file|
|
|
108
|
+
self.sizes[key.to_sym]={}
|
|
109
|
+
geo = Paperclip::Geometry.from_file(file.path)
|
|
110
|
+
%w(width height).each{|dim|
|
|
111
|
+
self.sizes[key.to_sym][dim.to_sym] = geo.send(dim.to_sym).to_i
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def do_download_remote_image
|
|
120
|
+
require 'open-uri'
|
|
121
|
+
io = open(URI.parse(url))
|
|
122
|
+
def io.original_filename; base_uri.path.split('/').last; end
|
|
123
|
+
io.original_filename.blank? ? nil : io
|
|
124
|
+
rescue Exception
|
|
125
|
+
errors.add(:url, "not valid. Unable to download image.")
|
|
126
|
+
return nil
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
include Atreides::Extendable
|
|
130
|
+
end
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
class Atreides::Post < Atreides::Base
|
|
2
|
+
|
|
3
|
+
include Atreides::Base::Taggable
|
|
4
|
+
include Atreides::Base::AasmStates
|
|
5
|
+
include Atreides::Base::Validation
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Constants
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Associatons
|
|
13
|
+
#
|
|
14
|
+
has_many :parts, :as => :contentable, :order => "display_order", :class_name => "Atreides::ContentPart", :dependent => :destroy
|
|
15
|
+
has_many :features, :class_name => "Atreides::Feature"
|
|
16
|
+
belongs_to :site, :class_name => "Atreides::Site"
|
|
17
|
+
belongs_to :tw_delayed_job, :class_name => "::Delayed::Job"
|
|
18
|
+
belongs_to :fb_delayed_job, :class_name => "::Delayed::Job"
|
|
19
|
+
belongs_to :tumblr_delayed_job, :class_name => "::Delayed::Job"
|
|
20
|
+
belongs_to :author, :class_name => "Atreides::User"
|
|
21
|
+
belongs_to :last_editor, :class_name => "Atreides::User"
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Behaviours
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
attr_accessor :url, :tw_me, :fb_me, :tumblr_me
|
|
28
|
+
accepts_nested_attributes_for :parts, :allow_destroy => true
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Validations
|
|
32
|
+
#
|
|
33
|
+
validate :site_id, :presence => true
|
|
34
|
+
validates :title, :presence => true, :if => :published?
|
|
35
|
+
validates :slug, :presence => { :message => "can't be blank. Did you set a title?" }, :if => :published?
|
|
36
|
+
validates :social_msg, :length => { :within => 0..140 }, :if => :social_msg?
|
|
37
|
+
validate :content_parts
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Scopes
|
|
41
|
+
#
|
|
42
|
+
default_scope order("posts.published_at desc, posts.id desc")
|
|
43
|
+
|
|
44
|
+
scope :for_month, lambda { |date, col|
|
|
45
|
+
col ||= :published_at
|
|
46
|
+
where("#{col} >= ? AND #{col} <= ?", date.to_time.beginning_of_month, date.to_time.end_of_month)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
scope :by_month, lambda { |*args|
|
|
50
|
+
# Needs to be sep variable or AR will cache the first time and it'll never change
|
|
51
|
+
now = Time.zone.now
|
|
52
|
+
select("distinct(EXTRACT(DAY from posts.published_at)), posts.*").
|
|
53
|
+
where("EXTRACT(MONTH from posts.published_at) = ? and EXTRACT(YEAR from posts.published_at) = ? and posts.published_at <= ?", args.flatten[0].to_i, now.year, now).
|
|
54
|
+
order("posts.published_at asc")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
scope :by_year, lambda { |year|
|
|
58
|
+
# Needs to be sep variable or AR will cache the first time and it'll never change
|
|
59
|
+
where("EXTRACT(YEAR from posts.published_at) = ? and posts.published_at <= ?", year.to_i, Time.zone.now)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
scope :popular_photos, lambda {
|
|
63
|
+
now = Time.zone.now
|
|
64
|
+
joins("INNER JOIN photos ON photos.photoable_type = 'Atreides::Post' AND photos.photoable_id = posts.id").
|
|
65
|
+
select("posts.*, ((comments_count*2)+likes_count) as final_count").
|
|
66
|
+
where("posts.state = 'published' AND posts.published_at < ? AND posts.published_at < ?", now-1.week, now).
|
|
67
|
+
order("final_count desc, published_at desc").
|
|
68
|
+
group("posts.id").
|
|
69
|
+
limit(6)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
#
|
|
73
|
+
# Callbacks
|
|
74
|
+
#
|
|
75
|
+
after_initialize :setup_social_network
|
|
76
|
+
after_initialize :set_diary
|
|
77
|
+
|
|
78
|
+
def setup_social_network
|
|
79
|
+
# Setup social network callback flags
|
|
80
|
+
begin
|
|
81
|
+
self.tw_me ||= ((Settings.default_cross_post_to?(:twitter) && pending?) or tw_delayed_job_id?) unless twitter_id?
|
|
82
|
+
self.fb_me ||= ((Settings.default_cross_post_to?(:facebook) && pending?) or fb_delayed_job_id?) unless facebook_id?
|
|
83
|
+
self.tumblr_me ||= ((Settings.default_cross_post_to?(:tumblr) && pending?) or tumblr_delayed_job_id?) unless tumblr_id?
|
|
84
|
+
rescue
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def set_diary
|
|
89
|
+
# Set diary as default location
|
|
90
|
+
if pending? or new_record? and respond_to?(:location_list) and location_list.empty?
|
|
91
|
+
location_list << Settings.tags.posts.location.first
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
before_save :push_publication
|
|
96
|
+
after_save :push_to_social
|
|
97
|
+
|
|
98
|
+
def push_publication
|
|
99
|
+
# If have just been saved as published then do do_publish to post to twitter/fb etc
|
|
100
|
+
do_publish if (state_changed? and published?) or (!state_changed? and published_at_changed?)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def push_to_social
|
|
104
|
+
# Atreides::Post to social networks
|
|
105
|
+
social_cross_posts if published? and (tw_me or fb_me or tumblr_me)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
#
|
|
109
|
+
# Class Methods
|
|
110
|
+
#
|
|
111
|
+
class << self
|
|
112
|
+
|
|
113
|
+
def next(post)
|
|
114
|
+
with_exclusive_scope {
|
|
115
|
+
# Due to problems with the default_scope ordering the 'live' scope must come AFTER the order scope
|
|
116
|
+
where("published_at >= ? and id != ?", post.published_at, post.id).order("published_at asc, id asc").live.first
|
|
117
|
+
}
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def previous(post)
|
|
121
|
+
with_exclusive_scope {
|
|
122
|
+
# Due to problems with the default_scope ordering the 'live' scope must come AFTER the order scope
|
|
123
|
+
where("published_at <= ? and id != ?", post.published_at, post.id).order("published_at desc, id desc").live.first
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def next_month(month = Date.today.month)
|
|
128
|
+
p = self.live.first(:conditions => ["EXTRACT(MONTH from published_at) > ?", month.to_i], :order => "published_at asc, id desc")
|
|
129
|
+
p ? p.published_at.month : nil
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def previous_month(month = Date.today.month)
|
|
133
|
+
p = self.live.first(:conditions => ["EXTRACT(MONTH from published_at) < ?", month.to_i], :order => "published_at desc, id desc")
|
|
134
|
+
p ? p.published_at.month : nil
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def base_class
|
|
138
|
+
self
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
#
|
|
143
|
+
# Instance Methods
|
|
144
|
+
#
|
|
145
|
+
def to_param
|
|
146
|
+
# Used for urls like /posts/:id/:slug
|
|
147
|
+
id.to_s
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def next
|
|
151
|
+
@_next ||= self.class.next(self)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def previous
|
|
155
|
+
@_previous ||= self.class.previous(self)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def related_posts
|
|
159
|
+
# Don't recalc twice
|
|
160
|
+
return @related_posts unless @related_posts.nil?
|
|
161
|
+
|
|
162
|
+
max = 6
|
|
163
|
+
@related_posts = []
|
|
164
|
+
@related_posts += Atreides::Post.live.tagged_with(tag_list, :match_all => :true).all(:conditions => ["posts.id not in (?)", [id]], :limit => max) rescue []
|
|
165
|
+
@related_posts += Atreides::Post.live.tagged_with(tag_list, :any => :true).all(:conditions => ["posts.id not in (?)", @related_posts.map(&:id)+[id]], :limit => max - @related_posts.size) if @related_posts.size < max rescue []
|
|
166
|
+
@related_posts.uniq!
|
|
167
|
+
@related_posts += Atreides::Post.live.all(:conditions => ["posts.id not in (?)", @related_posts.map(&:id)+[id]], :limit => max - @related_posts.size) if @related_posts.size < max rescue []
|
|
168
|
+
@related_posts
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Return the first found text/video/photo
|
|
172
|
+
def first_body
|
|
173
|
+
(part = parts.where(:content_type => :text).detect{|p| p.body? }) ? part.body : ""
|
|
174
|
+
end
|
|
175
|
+
alias_method :body, :first_body
|
|
176
|
+
|
|
177
|
+
def first_photo
|
|
178
|
+
(part = parts.where(:content_type => :photos).detect{|p| !p.photos.first.nil? }) ? part.photos.first : nil
|
|
179
|
+
end
|
|
180
|
+
alias_method :photo, :first_photo
|
|
181
|
+
|
|
182
|
+
def first_video
|
|
183
|
+
(part = parts.where(:content_type => :videos).detect{|p| !p.videos.first.nil? }) ? part.videos.first : nil
|
|
184
|
+
end
|
|
185
|
+
alias_method :video, :first_video
|
|
186
|
+
|
|
187
|
+
# Return the first found photo
|
|
188
|
+
def thumbnail(size = :thumb)
|
|
189
|
+
# Find the first thumbnail image
|
|
190
|
+
url = if first_photo
|
|
191
|
+
first_photo.image.url(size)
|
|
192
|
+
elsif first_video
|
|
193
|
+
first_video.thumb_url
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# FIXME: THIS NEEDS TO BE MOVED TO A VIEW/PRESENTER/DECORATOR
|
|
197
|
+
# asset_path('atreides/missing_thumb.png')
|
|
198
|
+
|
|
199
|
+
url || "/images/missing_thumb.png"
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def update_twitter_id(twitter_id)
|
|
204
|
+
self.twitter_id = twitter_id
|
|
205
|
+
save
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def update_facebook_id(facebook_id)
|
|
209
|
+
self.facebook_id = facebook_id
|
|
210
|
+
save
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def update_tumblr_id(tumblr_id)
|
|
214
|
+
self.tumblr_id = tumblr_id
|
|
215
|
+
save
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def post_types
|
|
219
|
+
@post_types ||= parts.map {|part| part.content_type}
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def slug=(value)
|
|
223
|
+
# Do not let id based slugs through
|
|
224
|
+
write_attribute(:slug, value.to_s.match(/^\d+$/) ? nil : value)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Make social posting flags understand booleans and form submitted num booleans
|
|
228
|
+
def tw_me=(value)
|
|
229
|
+
@tw_me = (value.is_a?(TrueClass) || value.is_a?(FalseClass)) ? value : !value.to_i.zero?
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def fb_me=(value)
|
|
233
|
+
@fb_me = (value.is_a?(TrueClass) || value.is_a?(FalseClass)) ? value : !value.to_i.zero?
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def tumblr_me=(value)
|
|
237
|
+
@tumblr_me = (value.is_a?(TrueClass) || value.is_a?(FalseClass)) ? value : !value.to_i.zero?
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
private
|
|
241
|
+
|
|
242
|
+
def content_parts
|
|
243
|
+
errors.add(:parts, "cannot be empty. Add some content!") if parts.empty? and published?
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def do_publish(msg = nil)
|
|
247
|
+
self.published_at = Time.zone.now if published_at.nil?
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def social_cross_posts
|
|
251
|
+
%w(tw fb).each do |prefix|
|
|
252
|
+
next unless self.send("#{prefix}_me")
|
|
253
|
+
|
|
254
|
+
assoc = "#{prefix}_delayed_job"
|
|
255
|
+
|
|
256
|
+
# No Delayed Job id set or is failed? Then create one.
|
|
257
|
+
if !self.send("#{assoc}_id?") or (self.send(assoc) and self.send(assoc).failed_at?)
|
|
258
|
+
# Create new instance of class that will post to the soc network
|
|
259
|
+
job = "#{prefix.capitalize}PostPublisherJob".constantize.new(self.id)
|
|
260
|
+
dj = ::Delayed::Job.enqueue :payload_object => job, :priority => 0, :run_at => self.published_at
|
|
261
|
+
self.send("#{assoc}=", dj)
|
|
262
|
+
|
|
263
|
+
# If already got a delayed job awaiting, then update the exec date
|
|
264
|
+
elsif self.send(assoc) and self.send(assoc).run_at != self.published_at
|
|
265
|
+
self.send(assoc).update_attribute(:run_at, self.published_at)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
include Atreides::Extendable
|
|
271
|
+
end
|