kublog 0.0.1.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/.gitignore +4 -5
  2. data/.rspec +2 -0
  3. data/Gemfile +3 -1
  4. data/Gemfile.lock +89 -77
  5. data/README.rdoc +102 -61
  6. data/Rakefile +5 -10
  7. data/app/assets/javascripts/kublog/email.js.coffee +24 -9
  8. data/app/assets/javascripts/kublog/posts.js.coffee +46 -19
  9. data/app/assets/javascripts/kublog/shared.js.coffee.erb +1 -1
  10. data/app/assets/javascripts/kublog/wysiwyg.controls.js.coffee +0 -1
  11. data/app/assets/plugins/kublog/ajaxyupload/javascripts/jquery.ajaxyupload.js +1 -1
  12. data/app/assets/stylesheets/kublog/posts.css +2 -2
  13. data/app/controllers/kublog/application_controller.rb +18 -2
  14. data/app/controllers/kublog/categories_controller.rb +2 -2
  15. data/app/controllers/kublog/notifications_controller.rb +13 -0
  16. data/app/controllers/kublog/posts_controller.rb +7 -18
  17. data/app/helpers/kublog/application_helper.rb +15 -0
  18. data/app/helpers/kublog/notifications_helper.rb +4 -0
  19. data/app/helpers/kublog/posts_helper.rb +4 -0
  20. data/app/jobs/kublog/deliver_comment.rb +14 -0
  21. data/app/mailers/kublog/comment_mailer.rb +11 -0
  22. data/app/mailers/kublog/post_mailer.rb +4 -5
  23. data/app/models/kublog/category.rb +13 -5
  24. data/app/models/kublog/comment.rb +17 -6
  25. data/app/models/kublog/notification.rb +27 -0
  26. data/app/models/kublog/post.rb +11 -6
  27. data/app/presenters/kublog/post_form_presenter.rb +19 -0
  28. data/app/presenters/kublog/posts_presenter.rb +7 -1
  29. data/app/uploaders/kublog/file_uploader.rb +0 -3
  30. data/app/views/kublog/comment_mailer/new_comment.html.erb +11 -0
  31. data/app/views/kublog/post_mailer/new_post.html.erb +1 -1
  32. data/app/views/kublog/post_mailer/new_post.liquid.html.erb +9 -1
  33. data/app/views/kublog/posts/_email_form.html.erb +27 -9
  34. data/app/views/kublog/posts/_facebook_form.html.erb +10 -0
  35. data/app/views/kublog/posts/_form.html.erb +7 -45
  36. data/app/views/kublog/posts/_twitter_form.html.erb +11 -0
  37. data/app/views/kublog/posts/edit.html.erb +1 -1
  38. data/app/views/kublog/posts/index.atom.builder +1 -2
  39. data/app/views/kublog/posts/index.rss.builder +20 -0
  40. data/app/views/kublog/posts/new.html.erb +1 -1
  41. data/config/locales/kublog/en.yml +9 -0
  42. data/config/routes.rb +8 -0
  43. data/db/migrate/20110816211552_create_kublog_posts.rb +1 -9
  44. data/db/migrate/20110901205127_create_kublog_notifications.rb +18 -0
  45. data/index.html +10 -0
  46. data/kublog.gemspec +10 -10
  47. data/lib/generators/kublog/install/USAGE +8 -0
  48. data/lib/generators/kublog/install/install_generator.rb +78 -0
  49. data/lib/generators/kublog/install/templates/configuration.rb.tt +45 -0
  50. data/lib/kublog.rb +43 -13
  51. data/lib/kublog/author.rb +2 -3
  52. data/lib/kublog/engine.rb +1 -0
  53. data/lib/kublog/network/email.rb +113 -0
  54. data/lib/kublog/network/facebook.rb +54 -0
  55. data/lib/kublog/network/twitter.rb +55 -0
  56. data/lib/kublog/notifiable.rb +2 -5
  57. data/lib/kublog/processor.rb +27 -0
  58. data/lib/kublog/version.rb +2 -2
  59. data/script/rails +1 -1
  60. data/{test → spec}/dummy/Rakefile +0 -0
  61. data/{test → spec}/dummy/app/assets/javascripts/application.js +0 -0
  62. data/{test → spec}/dummy/app/assets/javascripts/sessions.js +0 -0
  63. data/{test → spec}/dummy/app/assets/javascripts/users.js +0 -0
  64. data/{test → spec}/dummy/app/assets/stylesheets/application.css +0 -0
  65. data/{test → spec}/dummy/app/assets/stylesheets/sessions.css +0 -0
  66. data/{test → spec}/dummy/app/assets/stylesheets/users.css +0 -0
  67. data/{test → spec}/dummy/app/controllers/application_controller.rb +0 -0
  68. data/{test → spec}/dummy/app/controllers/sessions_controller.rb +0 -0
  69. data/{test → spec}/dummy/app/controllers/users_controller.rb +0 -0
  70. data/{test → spec}/dummy/app/helpers/application_helper.rb +0 -0
  71. data/{test → spec}/dummy/app/helpers/error_messages_helper.rb +0 -0
  72. data/{test → spec}/dummy/app/helpers/layout_helper.rb +0 -0
  73. data/{test → spec}/dummy/app/helpers/sessions_helper.rb +0 -0
  74. data/{test → spec}/dummy/app/helpers/users_helper.rb +0 -0
  75. data/{test → spec}/dummy/app/mailers/.gitkeep +0 -0
  76. data/{test → spec}/dummy/app/models/.gitkeep +0 -0
  77. data/{test → spec}/dummy/app/models/ability.rb +0 -0
  78. data/{test → spec}/dummy/app/models/user.rb +1 -5
  79. data/{test → spec}/dummy/app/views/layouts/_account.html.erb +0 -0
  80. data/{test → spec}/dummy/app/views/layouts/application.html.erb +0 -0
  81. data/{test → spec}/dummy/app/views/layouts/kublog/application.html.erb +0 -0
  82. data/{test → spec}/dummy/app/views/sessions/new.html.erb +0 -0
  83. data/{test → spec}/dummy/app/views/users/new.html.erb +0 -0
  84. data/{test → spec}/dummy/config.ru +0 -0
  85. data/{test → spec}/dummy/config/application.rb +0 -0
  86. data/{test → spec}/dummy/config/boot.rb +0 -0
  87. data/{test → spec}/dummy/config/database.yml +0 -0
  88. data/{test → spec}/dummy/config/environment.rb +0 -0
  89. data/{test → spec}/dummy/config/environments/development.rb +0 -0
  90. data/{test → spec}/dummy/config/environments/production.rb +0 -0
  91. data/{test → spec}/dummy/config/environments/test.rb +0 -0
  92. data/{test → spec}/dummy/config/initializers/backtrace_silencers.rb +0 -0
  93. data/{test → spec}/dummy/config/initializers/inflections.rb +0 -0
  94. data/spec/dummy/config/initializers/kublog.rb +34 -0
  95. data/{test → spec}/dummy/config/initializers/mime_types.rb +0 -0
  96. data/{test → spec}/dummy/config/initializers/secret_token.rb +0 -0
  97. data/{test → spec}/dummy/config/initializers/session_store.rb +0 -0
  98. data/{test → spec}/dummy/config/initializers/wrap_parameters.rb +0 -0
  99. data/{test → spec}/dummy/config/locales/en.yml +9 -0
  100. data/{test → spec}/dummy/config/routes.rb +0 -0
  101. data/{test → spec}/dummy/db/migrate/20110816225222_create_users.rb +1 -0
  102. data/{test → spec}/dummy/db/migrate/20110819135547_create_delayed_jobs.rb +0 -0
  103. data/{test → spec}/dummy/db/schema.rb +16 -10
  104. data/{test → spec}/dummy/lib/assets/.gitkeep +0 -0
  105. data/{test → spec}/dummy/log/.gitkeep +0 -0
  106. data/{test → spec}/dummy/public/404.html +0 -0
  107. data/{test → spec}/dummy/public/422.html +0 -0
  108. data/{test → spec}/dummy/public/500.html +0 -0
  109. data/{test → spec}/dummy/public/favicon.ico +0 -0
  110. data/{test → spec}/dummy/script/delayed_job +0 -0
  111. data/{test → spec}/dummy/script/rails +0 -0
  112. data/spec/factories.rb +54 -0
  113. data/spec/fixtures/Adrian.png +0 -0
  114. data/spec/fixtures/rendered_email.html +15 -0
  115. data/spec/lib/author_spec.rb +25 -0
  116. data/spec/lib/network/email_spec.rb +113 -0
  117. data/spec/lib/network/facebook_spec.rb +68 -0
  118. data/spec/lib/network/twitter_spec.rb +68 -0
  119. data/spec/lib/notifiable_spec.rb +23 -0
  120. data/spec/lib/processor_spec.rb +25 -0
  121. data/spec/models/kublog/category_spec.rb +43 -0
  122. data/spec/models/kublog/comment_spec.rb +56 -0
  123. data/spec/models/kublog/image_spec.rb +37 -0
  124. data/spec/models/kublog/notification_spec.rb +53 -0
  125. data/spec/models/kublog/post_spec.rb +63 -0
  126. data/spec/spec_helper.rb +43 -0
  127. metadata +198 -208
  128. data/app/assets/stylesheets/kublog/categories.css +0 -4
  129. data/app/assets/stylesheets/kublog/comments.css +0 -4
  130. data/lib/kublog/notification/email.rb +0 -86
  131. data/lib/kublog/notification/email_job.rb +0 -14
  132. data/lib/kublog/notification/fb_post.rb +0 -43
  133. data/lib/kublog/notification/fb_post_job.rb +0 -16
  134. data/lib/kublog/notification/tweet.rb +0 -68
  135. data/lib/kublog/notification/tweet_job.rb +0 -16
  136. data/test/dummy/test/fixtures/users.yml +0 -9
  137. data/test/dummy/test/functional/sessions_controller_test.rb +0 -7
  138. data/test/dummy/test/functional/users_controller_test.rb +0 -7
  139. data/test/dummy/test/unit/helpers/sessions_helper_test.rb +0 -4
  140. data/test/dummy/test/unit/helpers/users_helper_test.rb +0 -4
  141. data/test/dummy/test/unit/user_test.rb +0 -7
  142. data/test/factories.rb +0 -9
  143. data/test/fixtures/kublog/categories.yml +0 -7
  144. data/test/fixtures/kublog/comments.yml +0 -7
  145. data/test/fixtures/kublog/images.yml +0 -9
  146. data/test/fixtures/kublog/posts.yml +0 -9
  147. data/test/functional/kublog/categories_controller_test.rb +0 -9
  148. data/test/functional/kublog/comments_controller_test.rb +0 -9
  149. data/test/functional/kublog/images_controller_test.rb +0 -9
  150. data/test/functional/kublog/post_mailer_test.rb +0 -9
  151. data/test/functional/kublog/posts_controller_test.rb +0 -9
  152. data/test/integration/navigation_test.rb +0 -10
  153. data/test/kublog_test.rb +0 -7
  154. data/test/test_helper.rb +0 -12
  155. data/test/unit/helpers/kublog/categories_helper_test.rb +0 -6
  156. data/test/unit/helpers/kublog/comments_helper_test.rb +0 -6
  157. data/test/unit/helpers/kublog/images_helper_test.rb +0 -6
  158. data/test/unit/helpers/kublog/posts_helper_test.rb +0 -6
  159. data/test/unit/kublog/category_test.rb +0 -9
  160. data/test/unit/kublog/comment_test.rb +0 -9
  161. data/test/unit/kublog/image_test.rb +0 -9
  162. data/test/unit/kublog/post_test.rb +0 -19
@@ -0,0 +1,27 @@
1
+ module Kublog
2
+ class Notification < ActiveRecord::Base
3
+ include Network::Email, Network::Facebook, Network::Twitter
4
+
5
+ belongs_to :post
6
+
7
+ # Presence of content should be responsability
8
+ # Of each network module
9
+ validates_presence_of :kind
10
+
11
+ after_create :deliver
12
+ serialize :roles, Array
13
+
14
+ delegate :title, :url, :to => :post
15
+
16
+ def default?
17
+ self.send "default_#{kind}"
18
+ end
19
+
20
+ private
21
+
22
+ def deliver
23
+ self.send "deliver_#{kind}" if respond_to?("deliver_#{kind}")
24
+ end
25
+
26
+ end
27
+ end
@@ -2,23 +2,24 @@
2
2
  module Kublog
3
3
  class Post < ActiveRecord::Base
4
4
  extend FriendlyId
5
- include Notification::Email, Notification::Tweet, Notification::FbPost
6
5
 
7
6
  #Associations
8
- belongs_to :user, :class_name => Kublog.author_class
7
+ belongs_to :user, :class_name => Kublog.author_class
9
8
  belongs_to :category
10
- has_many :comments, :dependent => :destroy
9
+ has_many :comments, :dependent => :destroy
10
+ has_many :notifications, :dependent => :nullify
11
11
 
12
12
  validates_presence_of :title, :body, :user
13
13
  validate :body_with_content
14
14
 
15
15
  #Special Attributes
16
- serialize :intended_for, Array
17
16
  friendly_id :title, :use => :slugged
18
17
 
19
18
  #Scopes
20
19
  default_scope order('kublog_posts.created_at DESC')
21
20
 
21
+ accepts_nested_attributes_for :notifications
22
+
22
23
  def author
23
24
  user.to_s
24
25
  end
@@ -29,11 +30,15 @@ module Kublog
29
30
 
30
31
  # Public Access to the Post
31
32
  def url
32
- Engine.routes.url_helpers.quickie_url(self, :host => Kublog.default_url_options[:host])
33
+ unless new_record?
34
+ Engine.routes.url_helpers.quickie_url(self, :host => Kublog.default_url_options[:host])
35
+ end
33
36
  end
34
37
 
35
38
  def related_posts
36
- self.category.posts.where('id != ?', self.id) unless self.category.nil?
39
+ unless self.category.nil?
40
+ self.category.posts.where('id != ?', self.id)
41
+ end
37
42
  end
38
43
 
39
44
  private
@@ -0,0 +1,19 @@
1
+ module Kublog
2
+ class PostFormPresenter
3
+
4
+ attr_accessor :post, :notifications
5
+
6
+ def initialize(post)
7
+ @post = post
8
+ @notifications = []
9
+ @notifications << notification('twitter') if Kublog.twitter?
10
+ @notifications << notification('facebook') if Kublog.facebook?
11
+ @notifications << notification('email') if Kublog.email?
12
+ end
13
+
14
+ def notification(kind)
15
+ @post.notifications.build(:kind => kind, :post => @post)
16
+ end
17
+
18
+ end
19
+ end
@@ -1,6 +1,8 @@
1
1
  module Kublog
2
2
  class PostsPresenter
3
3
 
4
+ attr_accessor :category
5
+
4
6
  def initialize(category=nil)
5
7
  @category = category
6
8
  end
@@ -17,8 +19,12 @@ module Kublog
17
19
  @title ||= @category.nil? ? Kublog.blog_name : "#{@category.name} :: #{Kublog.blog_name}"
18
20
  end
19
21
 
22
+ def description
23
+ @description = @category.nil? ? Kublog.blog_description : "#{@category.name} :: #{Kublog.blog_name} :: #{Kublog.blog_description}"
24
+ end
25
+
20
26
  def updated
21
- self.posts.first.try(:updated_at)
27
+ self.posts.first.try(:updated_at) - 1.seconds
22
28
  end
23
29
 
24
30
  def ftime(updated)
@@ -5,12 +5,9 @@ module Kublog
5
5
 
6
6
  # Include RMagick or ImageScience support:
7
7
  include CarrierWave::RMagick
8
- # include CarrierWave::MiniMagick
9
- # include CarrierWave::ImageScience
10
8
 
11
9
  # Choose what kind of storage to use for this uploader:
12
10
  storage Kublog.image_storage
13
- # storage :fog
14
11
 
15
12
  # Override the directory where uploaded files will be stored.
16
13
  # This is a sensible default for uploaders that are meant to be mounted:
@@ -0,0 +1,11 @@
1
+ <p>
2
+ <%= t('.hi') %>, <%= @post.author %>
3
+ </p>
4
+
5
+ <p>
6
+ <strong><%= @comment.author %></strong> <%= t('.commenter_says') %> "<%= @post.title %>"
7
+ </p>
8
+
9
+ <blockquote>
10
+ <%= @comment.body %>
11
+ </blockquote>
@@ -1 +1 @@
1
- <%= Liquid::Template.parse(@post.email_body).render('user' => @user.to_s).html_safe %>
1
+ <%= Liquid::Template.parse(@email.body).render('user' => @user.to_s, 'url' => @email.url).html_safe %>
@@ -4,4 +4,12 @@
4
4
 
5
5
  <div>
6
6
  <%= post.body %>
7
- </div>
7
+ </div>
8
+
9
+ <p>
10
+ <%= I18n.t('kublog.post_mailer.new_post.read_more') %>
11
+ </p>
12
+
13
+ <p>
14
+ <a href='{{url}}'>{{url}}</a>
15
+ </p>
@@ -1,13 +1,31 @@
1
- <div style='display:none'>
2
- <%= link_to '#', '#email-template', :class => 'submit_fancybox', :id => 'link-to-email-template' %>
3
- <div id="email-template">
4
- <h2><%= t('.format_email') %></h2>
5
- <div class='field'>
6
- <%= f.text_area :email_body %>
1
+ <div class='field'>
2
+ <%= check_box_tag :email_notify, 1, notification.default?,
3
+ :checked => false, :class => 'email_checkbox' %>
4
+ <%= label_tag :email_notify, t('.email_notification') %>
5
+ <% unless user_kinds.empty? %>
6
+ <div class='optional'>
7
+ <ul>
8
+ <% user_kinds.each do |user_kind|%>
9
+ <li>
10
+ <%= check_box_tag "#{nf.object_name}[roles][]", user_kind, nil %>
11
+ <%= label_tag "#{nf.object_name}[roles][#{user_kind}]", user_kind.titleize %>
12
+ </li>
13
+ <% end %>
14
+ </ul>
7
15
  </div>
8
- <div class='field'>
9
- <%= f.submit :id => 'email_submit' %> <%= t('.or') %>
10
- <%= link_to t('.cancel'), '#', :id => 'email_cancel' %>
16
+ <% end %>
17
+ <div style='display:none' class='optional_lightbox'>
18
+ <%= nf.hidden_field :kind, :disabled => !notification.default? %>
19
+ <%= link_to '#', '#email-template', :class => 'submit_fancybox', :id => 'link-to-email-template' %>
20
+ <div id="email-template">
21
+ <h2><%= t('.format_email') %></h2>
22
+ <div class='field'>
23
+ <%= nf.text_area :content, :class => 'email_content', :disabled => !notification.default? %>
24
+ </div>
25
+ <div class='field'>
26
+ <%= submit_tag t('.send_email'), :id => 'email_submit' %> <%= t('.or') %>
27
+ <%= link_to t('.cancel'), '#', :id => 'email_cancel' %>
28
+ </div>
11
29
  </div>
12
30
  </div>
13
31
  </div>
@@ -0,0 +1,10 @@
1
+ <div class='field'>
2
+ <%= check_box_tag :facebook_notify, 1, notification.default?, :class => 'trigger-optional' %>
3
+ <%= label_tag :facebook_notify, t('.facebook_notification') %>
4
+ <div class='optional' style='<%= display?(notification.default?) %>'>
5
+ <%= nf.hidden_field :kind, :disabled => !notification.default? %>
6
+ <%= nf.text_area :content, :rows => 5, :cols => 10, :value => '',
7
+ :disabled => !notification.default?, :class => 'small mimic' %>
8
+ <small><%= t('.link_to_facebook') %></small>
9
+ </div>
10
+ </div>
@@ -1,67 +1,29 @@
1
1
  <%= form_for post, :html => {:class => 'post_form'} do |f| %>
2
2
 
3
+ <%= error_messages_for post %>
4
+
3
5
  <div class="main-attributes">
4
-
5
6
  <div class='field'>
6
7
  <%= f.label :body %><br />
7
8
  <%= f.text_area :body, :class => 'editor' %>
9
+ <%= render 'image_form' %>
8
10
  </div>
9
-
10
11
  <div class='field'>
11
12
  <%= f.label :title %> <br />
12
13
  <%= f.text_field :title, :class => 'original' %>
13
14
  </div>
14
-
15
15
  <div class='field'>
16
16
  <%= f.label :category_id %> <br />
17
17
  <%= select_tag 'post[category_id]', category_options(post).html_safe %>
18
18
  </div>
19
- <%= render "email_form", :f => f %>
20
- <%= render 'image_form' %>
21
19
  </div>
22
20
 
23
21
  <div class='sharing-attributes'>
24
-
25
- <div class='field'>
26
- <%= f.check_box :twitter_notify, :class => 'trigger-optional', :checked => post.new_record? %>
27
- <%= f.label :twitter_notify %>
28
- <div class='optional' style='<%= display? post.new_record? %>'>
29
- <span class='chars_left'>129</span>
30
- <%= f.text_area :tweet_text, :rows => 5, :cols => 10, :maxlength => 129, :value => '',
31
- :disabled => !post.new_record?, :class => 'small mimic' %>
32
- <small><%= t('.link_to_tweet') %></small>
33
- </div>
34
- </div>
35
-
36
- <div class='field'>
37
- <%= f.check_box :facebook_notify, :class => 'trigger-optional',
38
- :checked => post.new_record? %>
39
- <%= f.label :facebook_notify %>
40
- <div class='optional' style='<%= display? post.new_record? %>'>
41
- <%= f.text_area :facebook_text, :rows => 5, :cols => 10, :value => '',
42
- :disabled => !post.new_record?, :class => 'small mimic' %>
43
- <small><%= t('.link_to_facebook') %></small>
44
- </div>
45
- </div>
46
-
47
- <div class='field'>
48
- <%= f.check_box :email_notify, :class => 'trigger-optional', :checked => false %>
49
- <%= f.label :email_notify %>
50
- <% unless user_kinds.empty? %>
51
- <div class='optional'>
52
- <ul>
53
- <% user_kinds.each do |user_kind|%>
54
- <li>
55
- <%= check_box_tag "post[intended_for][]", user_kind, nil,
56
- :id => "post_intended_for_#{user_kind}" %>
57
- <%= label_tag "post_intended_for_#{user_kind}", user_kind.titleize %>
58
- </li>
59
- <% end %>
60
- </ul>
61
- </div>
22
+ <% notifications.each do |notification| %>
23
+ <%= f.fields_for :notifications, notification do |nf| %>
24
+ <%= render "#{notification.kind}_form", :notification => notification, :nf => nf %>
62
25
  <% end %>
63
- </div>
64
-
26
+ <% end %>
65
27
  </div>
66
28
 
67
29
  <div class='submit field'>
@@ -0,0 +1,11 @@
1
+ <div class='field'>
2
+ <%= check_box_tag :twitter_notify, 1, notification.default?, :class => 'trigger-optional' %>
3
+ <%= label_tag :twitter_notify, t('.twitter_notification') %>
4
+ <div class='optional' style='<%= display?(notification.default?) %>'>
5
+ <span class='chars_left'>129</span>
6
+ <%= nf.hidden_field :kind, :disabled => !notification.default? %>
7
+ <%= nf.text_area :content, :rows => 5, :cols => 10, :maxlength => 129, :value => '',
8
+ :disabled => !notification.default?, :class => 'small mimic' %>
9
+ <small><%= t('.link_to_twitter') %></small>
10
+ </div>
11
+ </div>
@@ -1,3 +1,3 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= render 'form', :post => @post %>
3
+ <%= render 'form', :post => @presenter.post, :notifications => @presenter.notifications %>
@@ -3,10 +3,9 @@ atom_feed do |feed|
3
3
  feed.updated @presenter.updated
4
4
  @presenter.posts.each do |post|
5
5
  feed.entry(post) do |entry|
6
- entry.url post.url
6
+ entry.link(:href => post.url)
7
7
  entry.title post.title
8
8
  entry.content post.body, :type => 'html'
9
- entry.updated_at @presenter.ftime(post.updated_at)
10
9
  entry.author do |author|
11
10
  author.name post.user.to_s
12
11
  end
@@ -0,0 +1,20 @@
1
+ xml.instruct! :xml, :version => "1.0", :encoding => 'UTF-8'
2
+ xml.rss :version => "2.0", 'xmlns:dc' => "http://purl.org/dc/elements/1.1/", 'xmlns:atom' => 'http://www.w3.org/2005/Atom' do
3
+ xml.channel do
4
+ xml.tag!("atom:link", :rel => 'self', :href => atom_url(@presenter))
5
+ xml.title @presenter.title
6
+ xml.description @presenter.description
7
+ xml.link root_url
8
+ @presenter.posts.each do |post|
9
+ xml.item do
10
+ xml.title post.title
11
+ xml.description post.body
12
+ xml.pubDate post.updated_at.to_s(:rfc822)
13
+ xml.link post_url(post)
14
+ xml.guid post_url(post)
15
+ xml.category post.category.to_s if post.category
16
+ xml.tag! "dc:creator", post.author
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  <h1><%= t('.title') %></h1>
2
2
 
3
- <%= render 'form', :post => @post %>
3
+ <%= render 'form', :post => @presenter.post, :notifications => @presenter.notifications %>
@@ -30,9 +30,18 @@ en:
30
30
  cancel: 'cancel'
31
31
  insert_size: 'Size'
32
32
  alt: 'Alt Text'
33
+ email_form:
34
+ notify: 'Notify by E-mail'
35
+ or: 'or'
33
36
  post_mailer:
34
37
  new_post:
35
38
  greetings: 'Greetings'
39
+ read_more: 'Read More'
40
+ comment_mailer:
41
+ new_comment:
42
+ subject: "New comment in post '%{post}'"
43
+ hi: 'Hi'
44
+ commenter_says: 'had this to say about your post '
36
45
  activerecord:
37
46
  models:
38
47
  'kublog/opst': 'Post'
@@ -1,5 +1,6 @@
1
1
  Kublog::Engine.routes.draw do
2
2
  root :to => 'posts#index'
3
+
3
4
  resources :posts do
4
5
  resources :comments
5
6
  collection do
@@ -7,6 +8,13 @@ Kublog::Engine.routes.draw do
7
8
  put :check
8
9
  end
9
10
  end
11
+
12
+ resources :notifications do
13
+ collection do
14
+ post :preview
15
+ end
16
+ end
17
+
10
18
  resources :images
11
19
  resources :categories
12
20
  match '/:id', :to => 'posts#show', :as => 'quickie'
@@ -1,19 +1,11 @@
1
1
  class CreateKublogPosts < ActiveRecord::Migration
2
+
2
3
  def change
3
4
  create_table :kublog_posts do |t|
4
5
  t.string :title
5
6
  t.text :body
6
- t.boolean :email_notify, :default => false
7
- t.text :email_body
8
- t.integer :users_notified
9
- t.boolean :twitter_notify, :default => false
10
- t.string :tweet_id
11
- t.string :tweet_text
12
- t.boolean :facebook_notify, :default => false
13
- t.text :facebook_text
14
7
  t.references :user
15
8
  t.references :category
16
- t.string :intended_for
17
9
  t.string :slug
18
10
  t.timestamps
19
11
  end
@@ -0,0 +1,18 @@
1
+ class CreateKublogNotifications < ActiveRecord::Migration
2
+ def change
3
+
4
+ create_table :kublog_notifications do |t|
5
+ t.string :kind
6
+ t.text :content
7
+ t.integer :provider_id
8
+ t.references :post
9
+ t.datetime :sent_at
10
+ t.datetime :created_at
11
+ t.text :roles
12
+ t.integer :times_delivered, :default => 0
13
+ end
14
+
15
+ add_index :kublog_notifications, :kind
16
+ add_index :kublog_notifications, :post_id
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ <!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>window.google={kEI:"ZT1oTrrUHumLsgKAoujyCw",getEI:function(a){var b;while(a&&!(a.getAttribute&&(b=a.getAttribute("eid"))))a=a.parentNode;return b||google.kEI},kEXPI:"28936,29774,30542,32214,32605",kCSI:{e:"28936,29774,30542,32214,32605",ei:"ZT1oTrrUHumLsgKAoujyCw",expi:"28936,29774,30542,32214,32605"},authuser:0,ml:function(){},kHL:"es-419",time:function(){return(new Date).getTime()},log:function(a,b,c,e){var d=new Image,f=google,h=f.lc,g=f.li,i="";d.onerror=(d.onload=(d.onabort=function(){delete h[g]}));h[g]=d;if(!c&&b.search("&ei=")==-1)i="&ei="+google.getEI(e);var j=c||"/gen_204?atyp=i&ct="+a+"&cad="+b+i+"&zx="+google.time();d.src=j;f.li=g+1},lc:[],li:0,Toolbelt:{},y:{},x:function(a,b){google.y[a.id]=[a,b];return false}};
2
+ window.google.sn="webhp";var i=window.google.timers={};window.google.startTick=function(a,b){i[a]={t:{start:(new Date).getTime()},bfr:!(!b)}};window.google.tick=function(a,b,c){if(!i[a])google.startTick(a);i[a].t[b]=c||(new Date).getTime()};google.startTick("load",true);try{}catch(v){}
3
+ var _gjwl=location;function _gjuc(){var e=_gjwl.href.indexOf("#");if(e>=0){var a=_gjwl.href.substring(e);if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var f=a.substring(d,b);if(f.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(f=="cad=h")return 0;c=b}_gjwl.href="/search?"+a+"&cad=h";return 1}}}return 0}function _gjp(){!(window._gjwl.hash&&
4
+ window._gjuc())&&setTimeout(_gjp,500)};
5
+ window._gjp && _gjp()</script><style id=gstyle>body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-bottom:20px}body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}em{font-weight:bold;font-style:normal}.lst{height:25px;width:496px}.gsfi,.lst{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{border-bottom:solid 1px #e7e7e7;border-right:solid 1px #e7e7e7;display:-moz-inline-box;display:inline-block;margin:3px 0 4px;margin-left:4px}input{font-family:inherit}a.gb1,a.gb2,a.gb3,a.gb4{color:#11c !important}#gbar,#guser{font-size:13px;padding-top:1px !important}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}body{background:#fff;color:black}input{-moz-box-sizing:content-box}a{color:#11c;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#36c}a:visited{color:#551a8b}a.gb1,a.gb4{text-decoration:underline}a.gb3:hover{text-decoration:none}#ghead a.gb2:hover{color:#fff!important}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px;}.lsbb{background:#eee;border:solid 1px;border-color:#ccc #999 #999 #ccc;height:30px;display:block}.ftl,#fll a{display:inline-block;margin:0 12px}.lsb{background:url(/images/srpr/nav_logo80.png) bottom;border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}.lsb:active{background:#ccc}.lst:focus{outline:none}#addlang a{padding:0 3px}.gac_v div{display:none}.gac_v .gac_v2,.gac_bt{display:block!important}</style><script></script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f&&document.f.q.focus();document.gbqf&&document.gbqf.q.focus();if(document.images)new Image().src='/images/srpr/nav_logo80.png'" ><textarea id=csi style=display:none></textarea><div id=mngb><div id=gbar><nobr><b class=gb1>La Web</b> <a class=gb1 href="http://www.google.com.mx/imghp?hl=es&tab=wi">Im�genes</a> <a class=gb1 href="http://video.google.com.mx/?hl=es&tab=wv">V�deos</a> <a class=gb1 href="http://news.google.com.mx/nwshp?hl=es&tab=wn">Noticias</a> <a class=gb1 href="http://translate.google.com.mx/?hl=es&tab=wT">Traductor</a> <a class=gb1 href="http://books.google.com.mx/bkshp?hl=es&tab=wp">Libros</a> <a class=gb1 href="https://mail.google.com/mail/?hl=es&tab=wm">Gmail</a> <a class=gb1 style="text-decoration:none" href="http://www.google.com.mx/intl/es/options/"><u>M�s</u> &raquo;</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe></span><a href="/preferences?hl=es-419" class=gb4>Configuraci�n</a> | <a href="https://www.google.com/accounts/ServiceLogin?hl=es&continue=http://www.google.com.mx/" class=gb4>Acceder</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div></div><center><br clear=all id=lgpd><div id=lga><div style="padding:28px 0 3px"><div align=left style="background:url(/intl/en_com/images/srpr/logo1w.png) no-repeat;height:110px;width:276px" title="Google" id=hplogo onload="window.lol&&lol()"><div nowrap style="color:#777;font-size:16px;font-weight:bold;left:214px;position:relative;top:70px">M�xico</div></div></div><br></div><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%>&nbsp;</td><td align=center nowrap><input name=hl type=hidden value=es-419><input name=source type=hidden value=hp><input type=hidden name=ie value="ISO-8859-1"><div class=ds style="height:32px;margin:4px 0"><input autocomplete=off maxlength=2048 name=q class="lst" title="Buscar con Google" value="" size=57 style="background:#fff;border:1px solid #ccc;border-bottom-color:#999;border-right-color:#999;color:#000;margin:0;padding:5px 8px 0 6px;vertical-align:top"></div><br style="line-height:0"><span class=ds ><span class=lsbb><input name=btnG type=submit value="Buscar con Google" class=lsb></span></span><span class=ds><span class=lsbb><input name=btnI type=submit class=lsb value="Me siento con suerte"></span></span></td><td nowrap width=25% align=left class="fl sblc"><a href="/advanced_search?hl=es-419">B�squeda avanzada</a><a href="/language_tools?hl=es-419">Herramientas de idioma</a></td></tr></table></form><div style="font-size:83%;min-height:3.5em"><br><div id=als><font size=-1 id=addlang>Google.com.mx ofrecido en: <a href="http://www.google.com.mx/setprefs?sig=0_-GaPH3huoX3BCf-nnUfXN5Ez3MY=&amp;hl=es">espa�ol</a></font><br><br></div></div><div id=res></div><span id=footer><center id=fctr><div style="font-size:10pt"><div id=fll style="margin:19px auto;text-align:center"><a href="/intl/es-419/ads/">Programas de publicidad</a><a href="/services/">Soluciones Empresariales</a><a href="/intl/es-419/about.html">Todo acerca de Google</a><a href="http://www.google.com/ncr" class="gl nobr">Google.com in English</a></div></div><p style="color:#767676;font-size:8pt">&copy; 2011 - <a href="/intl/es-419/privacy.html">Privacidad</a></p></center></span> <div id=xjsd></div><div id=xjsi><script>if(google.y)google.y.first=[];google.dlj=function(b){window.setTimeout(function(){var a=document.createElement("script");a.src=b;document.getElementById("xjsd").appendChild(a)},0)};
6
+ if(google.y)google.y.first=[];if(!google.xjs){google.dstr=[];google.rein=[];if(google.timers&&google.timers.load.t){google.timers.load.t.xjsls=new Date().getTime();}google.dlj('/extern_js/f/CgJlbhICdXMrMEU4ACwrMFo4ACwrMA44ACwrMBc4ACwrMDw4ACwrMFE4ACwrMJgBOAAsKzAKOABAiwEsKzAWOAAsKzAZOAAsKzAlOAAsKzBBOAAsKzBNOAAsKzBOOAAsKzBUOAAsKzBpOAAsKzCSATgALCswGDgALCswJjgALIACUJACTQ/18OygQl-cnA.js');google.xjs=1}google.neegg=1;google.mc=[];google.mc=google.mc.concat([[69,{}],[14,{}],[60,{}],[81,{}],[152,{}],[78,{}],[25,{"g":8,"k":false,"m":{"bks":true,"blg":true,"dsc":true,"evn":true,"flm":true,"frm":true,"isch":true,"klg":true,"mbl":true,"nws":true,"plcs":true,"ppl":true,"prc":true,"pts":true,"rcp":true,"shop":true,"vid":true},"t":null}],[105,{}],[22,{"m_errors":{"32":"Lo sentimos, no hay m�s resultados para mostrar.","default":"\u003Cfont color=red\u003EError:\u003C/font\u003E el servidor no ha podido completar tu solicitud. Vuelve a intentarlo dentro de 30 segundos."},"m_tip":"Haz clic para obtener m�s informaci�n"}],[77,{}],[146,{}],[84,{}],[24,{}],[38,{}]]);google.y.first.push(function(){try{var form=document.f||document.f||document.gs||document.gbqf;google.ac.i(form,form.q,'','','',{sw:1,o:1,i:1},'hp',{"dh":true,"exp":"gsis,i18n=true","host":"google.com.mx","jsonp":true,"msgs":{"lcky":"Me siento con suerte","lml":"M�s informaci�n","psrc":"Se ha eliminado esta b�squeda de tu <a href=\"/history\">Historial web</a>","psrl":"Eliminar","srch":"Buscar con Google"}});}catch(e){google.ml(e,false,{'cause':'defer'});}if(google.med){google.med('init');google.initHistory();google.med('history');}google.History&&google.History.initialize('/')});if(google.j&&google.j.en&&google.j.xi){window.setTimeout(google.j.xi,0);}</script></div><script>(function(){var a,b=window.location.href.match(/\/webhp\?[^#]*tune=[^#]*/);if(a=b&&b.length>0?"http://www.google.com/logos/2011/lespaul.html#"+b[0].substr(7):null)google.nav&&google.nav.go?google.nav.go(a):window.location.href=a;})();</script><script>(function(){
7
+ var b,d,e,f;function g(a,c){if(a.removeEventListener){a.removeEventListener("load",c,false);a.removeEventListener("error",c,false)}else{a.detachEvent("onload",c);a.detachEvent("onerror",c)}}function h(a){f=(new Date).getTime();++d;a=a||window.event;var c=a.target||a.srcElement;g(c,h)}var i=document.getElementsByTagName("img");b=i.length;d=0;for(var j=0,k;j<b;++j){k=i[j];if(k.complete||typeof k.src!="string"||!k.src)++d;else if(k.addEventListener){k.addEventListener("load",h,false);k.addEventListener("error",
8
+ h,false)}else{k.attachEvent("onload",h);k.attachEvent("onerror",h)}}e=b-d;function l(){if(!google.timers.load.t)return;google.timers.load.t.ol=(new Date).getTime();google.timers.load.t.iml=f;google.kCSI.imc=d;google.kCSI.imn=b;google.kCSI.imp=e;google.timers.load.t.xjs&&google.report&&google.report(google.timers.load,google.kCSI)}if(window.addEventListener)window.addEventListener("load",l,false);else if(window.attachEvent)window.attachEvent("onload",l);google.timers.load.t.prt=(f=(new Date).getTime());
9
+ })();
10
+ </script>