bumble 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. data/.gitignore +16 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +1 -0
  5. data/Readme.mdown +8 -0
  6. data/app/controllers/bumble_controller.rb +45 -0
  7. data/app/controllers/comments_controller.rb +99 -0
  8. data/app/controllers/password_resets_controller.rb +34 -0
  9. data/app/controllers/posts_controller.rb +103 -0
  10. data/app/controllers/user_sessions_controller.rb +22 -0
  11. data/app/controllers/users_controller.rb +60 -0
  12. data/app/helpers/bumble_helper.rb +50 -0
  13. data/app/models/asset.rb +57 -0
  14. data/app/models/comment.rb +78 -0
  15. data/app/models/notifier.rb +35 -0
  16. data/app/models/post.rb +57 -0
  17. data/app/models/posts/blog.rb +3 -0
  18. data/app/models/posts/code.rb +3 -0
  19. data/app/models/posts/image.rb +3 -0
  20. data/app/models/posts/link.rb +7 -0
  21. data/app/models/posts/quote.rb +3 -0
  22. data/app/models/posts/video.rb +4 -0
  23. data/app/models/user.rb +35 -0
  24. data/app/models/user_session.rb +2 -0
  25. data/app/views/comments/_comment.html.haml +14 -0
  26. data/app/views/comments/_form.html.haml +9 -0
  27. data/app/views/comments/edit.html.haml +7 -0
  28. data/app/views/comments/index.atom.builder +15 -0
  29. data/app/views/comments/new.html.haml +7 -0
  30. data/app/views/layouts/_sidebar.html.haml +20 -0
  31. data/app/views/layouts/bumble.html.haml +35 -0
  32. data/app/views/notifier/activation_confirmation.erb +5 -0
  33. data/app/views/notifier/activation_instructions.erb +5 -0
  34. data/app/views/notifier/new_comment_alert.erb +8 -0
  35. data/app/views/notifier/password_reset_instructions.erb +8 -0
  36. data/app/views/password_resets/edit.html.haml +10 -0
  37. data/app/views/password_resets/new.html.haml +7 -0
  38. data/app/views/posts/_form.html.haml +10 -0
  39. data/app/views/posts/_post.html.haml +16 -0
  40. data/app/views/posts/_preview.html.haml +8 -0
  41. data/app/views/posts/edit.html.haml +10 -0
  42. data/app/views/posts/forms/_blog.html.haml +4 -0
  43. data/app/views/posts/forms/_code.html.haml +6 -0
  44. data/app/views/posts/forms/_image.html.haml +9 -0
  45. data/app/views/posts/forms/_link.html.haml +6 -0
  46. data/app/views/posts/forms/_quote.html.haml +4 -0
  47. data/app/views/posts/forms/_video.html.haml +6 -0
  48. data/app/views/posts/index.atom.builder +15 -0
  49. data/app/views/posts/index.html.haml +21 -0
  50. data/app/views/posts/new.html.haml +8 -0
  51. data/app/views/posts/search.html.haml +27 -0
  52. data/app/views/posts/show.html.haml +22 -0
  53. data/app/views/posts/types/_blog.html.haml +4 -0
  54. data/app/views/posts/types/_code.html.haml +7 -0
  55. data/app/views/posts/types/_image.html.haml +3 -0
  56. data/app/views/posts/types/_link.html.haml +3 -0
  57. data/app/views/posts/types/_quote.html.haml +2 -0
  58. data/app/views/posts/types/_video.html.haml +5 -0
  59. data/app/views/user_sessions/new.html.haml +10 -0
  60. data/app/views/users/_form.html.haml +12 -0
  61. data/app/views/users/_user.html.haml +3 -0
  62. data/app/views/users/delete.html.haml +5 -0
  63. data/app/views/users/edit.html.haml +8 -0
  64. data/app/views/users/index.html.haml +3 -0
  65. data/app/views/users/new.html.haml +7 -0
  66. data/app/views/users/show.html.haml +6 -0
  67. data/bumble.gemspec +31 -0
  68. data/config/initializers/bumble.rb +9 -0
  69. data/config/initializers/haml.rb +2 -0
  70. data/config/initializers/html5_forms.rb +163 -0
  71. data/config/initializers/inflections.rb +10 -0
  72. data/config/initializers/mime_types.rb +5 -0
  73. data/config/initializers/will_paginate.rb +3 -0
  74. data/config/routes.rb +29 -0
  75. data/lib/bumble.rb +18 -0
  76. data/lib/bumble/version.rb +3 -0
  77. data/lib/generators/bumble/assets_generator.rb +10 -0
  78. data/lib/generators/bumble/migrations_generator.rb +40 -0
  79. data/lib/generators/bumble/templates/assets/images/.gitignore +0 -0
  80. data/lib/generators/bumble/templates/assets/images/close.png +0 -0
  81. data/lib/generators/bumble/templates/assets/images/email.png +0 -0
  82. data/lib/generators/bumble/templates/assets/images/feed.png +0 -0
  83. data/lib/generators/bumble/templates/assets/images/image.png +0 -0
  84. data/lib/generators/bumble/templates/assets/images/loading.gif +0 -0
  85. data/lib/generators/bumble/templates/assets/images/preview.png +0 -0
  86. data/lib/generators/bumble/templates/assets/images/shortcut.png +0 -0
  87. data/lib/generators/bumble/templates/assets/images/youtube.png +0 -0
  88. data/lib/generators/bumble/templates/assets/javascripts/admin.js +95 -0
  89. data/lib/generators/bumble/templates/assets/javascripts/bumble.js +76 -0
  90. data/lib/generators/bumble/templates/assets/javascripts/iphone.js +7 -0
  91. data/lib/generators/bumble/templates/assets/javascripts/jquery.autogrow.js +37 -0
  92. data/lib/generators/bumble/templates/assets/javascripts/jquery.cookie.js +96 -0
  93. data/lib/generators/bumble/templates/assets/javascripts/jquery.form.js +665 -0
  94. data/lib/generators/bumble/templates/assets/javascripts/jquery.hint.js +44 -0
  95. data/lib/generators/bumble/templates/assets/javascripts/jquery.jgrow.js +85 -0
  96. data/lib/generators/bumble/templates/assets/javascripts/jquery.js +154 -0
  97. data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.core.js +18 -0
  98. data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.tabs.js +13 -0
  99. data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.widget.js +18 -0
  100. data/lib/generators/bumble/templates/assets/javascripts/jquery.validate.js +16 -0
  101. data/lib/generators/bumble/templates/assets/javascripts/modernizr.js +13 -0
  102. data/lib/generators/bumble/templates/assets/javascripts/ui.core.js +289 -0
  103. data/lib/generators/bumble/templates/assets/javascripts/ui.tabs.js +593 -0
  104. data/lib/generators/bumble/templates/migrations/add_approved_to_comments.rb +15 -0
  105. data/lib/generators/bumble/templates/migrations/add_delta_to_posts.rb +9 -0
  106. data/lib/generators/bumble/templates/migrations/add_missing_indexes.rb +24 -0
  107. data/lib/generators/bumble/templates/migrations/add_url_to_users.rb +9 -0
  108. data/lib/generators/bumble/templates/migrations/create_assets.rb +18 -0
  109. data/lib/generators/bumble/templates/migrations/create_comments.rb +19 -0
  110. data/lib/generators/bumble/templates/migrations/create_posts.rb +25 -0
  111. data/lib/generators/bumble/templates/migrations/create_users.rb +28 -0
  112. data/lib/generators/bumble/templates/migrations/full_text_search.rb +13 -0
  113. data/public/stylesheets/sass/bumble.sass +423 -0
  114. data/public/stylesheets/sass/iphone.sass +79 -0
  115. data/public/stylesheets/sass/print.sass +2 -0
  116. data/public/stylesheets/sass/reset.sass +49 -0
  117. data/test/factories.rb +28 -0
  118. data/test/functional/comments_controller_test.rb +177 -0
  119. data/test/functional/password_resets_controller_test.rb +61 -0
  120. data/test/functional/posts_controller_test.rb +181 -0
  121. data/test/test_helper.rb +113 -0
  122. data/test/unit/comment_test.rb +18 -0
  123. data/test/unit/post_test.rb +18 -0
  124. data/test/unit/user_test.rb +37 -0
  125. metadata +403 -0
@@ -0,0 +1,57 @@
1
+ require 'open-uri'
2
+
3
+ class Asset < ActiveRecord::Base
4
+
5
+ belongs_to :post
6
+
7
+ attr_accessible :attachment, :attachment_url, :attachment_remote_url
8
+ attr_accessor :attachment_url
9
+
10
+ has_attached_file :attachment,
11
+ :storage => :s3,
12
+ :path => ":basename:normalized_style.:extension",
13
+ :default_style => :original,
14
+ :bucket => 'bumble_production',
15
+ :s3_credentials => { :access_key_id => ENV['s3_access_key_id'], :secret_access_key => ENV['s3_secret_access_key'] },
16
+ :s3_headers => { 'Cache-Control' => 'max-age=315576000', 'Expires' => 10.years.from_now.httpdate },
17
+ :styles => { :thumb => '500x500>'}
18
+
19
+
20
+ Paperclip.interpolates :normalized_style do |attachment, style|
21
+ "_#{style}" if attachment.instance.image? && style != :original
22
+ end
23
+
24
+ before_validation :download_remote_file, :if => :attachment_url_provided?
25
+
26
+ validates_presence_of :attachment_file_name
27
+ validates_presence_of :attachment_remote_url, :if => :attachment_url_provided?, :message => 'is invalid or inaccessible'
28
+ validates_uniqueness_of :attachment_file_name
29
+
30
+ before_post_process :image? # bypass image processing if not an image
31
+
32
+ def image?
33
+ !(attachment_content_type =~ /^image.*/).nil?
34
+ end
35
+
36
+ def to_s
37
+ attachment_file_name
38
+ end
39
+
40
+ private
41
+
42
+ def attachment_url_provided?
43
+ !self.attachment_url.blank?
44
+ end
45
+
46
+ def download_remote_file
47
+ self.attachment = do_download_remote_file
48
+ self.attachment_remote_url = attachment_url
49
+ end
50
+
51
+ def do_download_remote_file
52
+ io = open(URI.parse(attachment_url))
53
+ def io.original_filename; base_uri.path.split('/').last; end
54
+ io.original_filename.blank? ? nil : io
55
+ rescue # catch errors with validations
56
+ end
57
+ end
@@ -0,0 +1,78 @@
1
+ class Comment < ActiveRecord::Base
2
+ include Gravtastic
3
+ belongs_to :post # TODO , :counter_cache => true
4
+ belongs_to :user
5
+
6
+ validates_presence_of :post, :body
7
+ validates_presence_of :author_name, :author_email, :if => :anonymous?
8
+ validates_format_of :author_email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_blank => :true
9
+
10
+ is_gravtastic :with => :email, :rating => 'R', :size => 30
11
+
12
+ after_save :set_parent_delta
13
+ after_create :email_post_author
14
+
15
+ scope :ham, :conditions => {:approved => true}
16
+ scope :spam, :conditions => {:approved => false}
17
+ scope :old, lambda {{:conditions => ["created_at < :now", { :now => 14.days.ago }]}}
18
+
19
+ def set_parent_delta
20
+ self.post.update_attributes(:delta => true)
21
+ end
22
+
23
+ def email_post_author
24
+ Notifier.deliver_new_comment_alert(self) unless user_id == post.user_id
25
+ end
26
+
27
+ def anonymous?
28
+ !user_id?
29
+ end
30
+
31
+ def email
32
+ user_id.blank? ? author_email : user.email
33
+ end
34
+
35
+ def author
36
+ user_id.blank? ? author_name : user.to_s
37
+ end
38
+
39
+ def author_url
40
+ anonymous? ? read_attribute(:author_url) : user.url
41
+ end
42
+
43
+ before_create :check_for_spam
44
+
45
+ def request=(request)
46
+ self.user_ip = request.remote_ip
47
+ self.user_agent = request.env['HTTP_USER_AGENT']
48
+ self.referrer = request.env['HTTP_REFERER']
49
+ end
50
+
51
+ def check_for_spam
52
+ self.approved = !Akismetor.spam?(akismet_attributes)
53
+ true # return true so it doesn't stop save
54
+ end
55
+
56
+ def akismet_attributes
57
+ {
58
+ :key => '4a8bfe691b69',
59
+ :blog => "http://#{DOMAIN}",
60
+ :user_ip => user_ip,
61
+ :user_agent => user_agent,
62
+ :comment_author => author,
63
+ :comment_author_email => email,
64
+ :comment_author_url => author_url,
65
+ :comment_content => body
66
+ }
67
+ end
68
+
69
+ def mark_as_spam!
70
+ update_attribute(:approved, false)
71
+ Akismetor.submit_spam(akismet_attributes)
72
+ end
73
+
74
+ def mark_as_ham!
75
+ update_attribute(:approved, true)
76
+ Akismetor.submit_ham(akismet_attributes)
77
+ end
78
+ end
@@ -0,0 +1,35 @@
1
+ class Notifier < ActionMailer::Base
2
+ def password_reset_instructions(user)
3
+ setup(user)
4
+ subject "Password Reset Instructions"
5
+ body :edit_password_reset_url => edit_password_reset_url(user.perishable_token)
6
+ end
7
+
8
+ def activation_instructions(user)
9
+ setup(user)
10
+ subject "Activation Instructions"
11
+ body :account_activation_url => activate_url(user.perishable_token)
12
+ end
13
+
14
+ def activation_confirmation(user)
15
+ setup(user)
16
+ subject "Welcome to #{DOMAIN}"
17
+ body :root_url => root_url
18
+ end
19
+
20
+ def new_comment_alert(comment)
21
+ setup(comment.post.user)
22
+ subject "New comment on #{comment.post.title}"
23
+ body :comment => comment
24
+ end
25
+
26
+ protected
27
+
28
+ def setup(user)
29
+ recipients user.email
30
+ from "#{DOMAIN} <noreply@#{DOMAIN}>"
31
+ subject "#{DOMAIN} Message"
32
+ sent_on Time.now
33
+ body :user => user
34
+ end
35
+ end
@@ -0,0 +1,57 @@
1
+ class Post < ActiveRecord::Base
2
+ has_many :assets, :dependent => :destroy
3
+ has_many :comments, :dependent => :destroy, :order => :created_at
4
+ belongs_to :user
5
+
6
+ accepts_nested_attributes_for :assets
7
+
8
+ # has_permalink :title, :unless => Proc.new { |post| post.read_attribute(:title).blank? }
9
+
10
+ validates_presence_of :user, :published_at
11
+
12
+ before_validation :format_published_at
13
+
14
+ def asset
15
+ assets.first
16
+ end
17
+
18
+ def to_param
19
+ permalink.blank? ? id.to_s : permalink
20
+ end
21
+
22
+ def self.types
23
+ Dir[File.expand_path('../posts',__FILE__)+'/*.rb'].each { |f| require_dependency f }
24
+ self.subclasses.collect(&:to_s).sort
25
+ end
26
+
27
+ def self.find_by_permalink_or_id(param)
28
+ Post.find_by_permalink(param) || Post.find(param)
29
+ end
30
+
31
+ cattr_reader :per_page
32
+ @@per_page = 5
33
+
34
+ scope :all_public, :conditions => {:publicly_viewable => true}
35
+ scope :all_private, :conditions => {:publicly_viewable => false}
36
+ scope :published, lambda {{:conditions => ["published_at < :now", { :now => Time.now.utc }]}}
37
+
38
+ def title
39
+ read_attribute(:title).blank? ? "Post #{id}" : read_attribute(:title)
40
+ end
41
+
42
+ index do
43
+ title
44
+ link_url
45
+ image_url
46
+ video_embed
47
+ description
48
+ quote
49
+ permalink
50
+ type
51
+ via
52
+ end
53
+
54
+ def format_published_at
55
+ self.published_at = Time.now if self.published_at.nil?
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ class Blog < Post
2
+ validates_presence_of :description
3
+ end
@@ -0,0 +1,3 @@
1
+ class Code < Post
2
+ validates_presence_of :description
3
+ end
@@ -0,0 +1,3 @@
1
+ class Image < Post
2
+ validates_associated :asset
3
+ end
@@ -0,0 +1,7 @@
1
+ class Link < Post
2
+ validates_presence_of :link_url
3
+
4
+ def title
5
+ self.read_attribute(:title).blank? ? self.link_url : self.read_attribute(:title)
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ class Quote < Post
2
+ validates_presence_of :quote
3
+ end
@@ -0,0 +1,4 @@
1
+ class Video < Post
2
+ validates_presence_of :video_embed, :if => Proc.new { |video| video.link_url.blank? }
3
+ validates_presence_of :link_url, :if => Proc.new { |video| video.video_embed.blank? }
4
+ end
@@ -0,0 +1,35 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ acts_as_authentic
4
+
5
+ validates_presence_of :first_name
6
+
7
+ is_gravtastic :with => :email, :rating => 'R', :size => 30
8
+
9
+ def to_s
10
+ first_name
11
+ end
12
+
13
+ def name
14
+ [first_name, last_name].reject(&:blank?).join(' ')
15
+ end
16
+
17
+ def activate!
18
+ self.update_attributes(:activated_at => Time.now)
19
+ end
20
+
21
+ def deliver_password_reset_instructions!
22
+ reset_perishable_token!
23
+ Notifier.deliver_password_reset_instructions(self)
24
+ end
25
+
26
+ def deliver_activation_instructions!
27
+ reset_perishable_token!
28
+ Notifier.deliver_activation_instructions(self)
29
+ end
30
+
31
+ def deliver_activation_confirmation!
32
+ reset_perishable_token!
33
+ Notifier.deliver_activation_confirmation(self)
34
+ end
35
+ end
@@ -0,0 +1,2 @@
1
+ class UserSession < Authlogic::Session::Base
2
+ end
@@ -0,0 +1,14 @@
1
+ .vcard[comment]{:class => ('author' if comment.user_id == comment.post.user.id)}
2
+ = link_to_unless comment.author_url.blank?, image_tag(comment.gravatar_url, :class => 'photo'), h(comment.author_url)
3
+ = markdown comment.body
4
+ %p.meta
5
+ = format_datetime_ago(comment.created_at)
6
+ by
7
+ = link_to_unless comment.author_url.blank?, h(comment.author), h(comment.author_url), :rel => :nofollow, :class => 'url fn'
8
+ - if current_user
9
+ \-
10
+ = link_to 'Edit', edit_post_comment_path(comment.post, comment)
11
+ |
12
+ = link_to 'Delete', post_comment_path(comment.post, comment), :class => :delete
13
+ |
14
+ = spam_link_for comment
@@ -0,0 +1,9 @@
1
+ - unless current_user
2
+ = form.label :author_name, 'Name'
3
+ .field= form.text_field :author_name, :class => "required", :placeholder => 'Name..'
4
+ = form.label :author_email, 'Email'
5
+ .field= form.email_field :author_email, :class => "required email", :placeholder => 'Email..', :autocorrect => 'off'
6
+ = form.label :author_url, 'Url'
7
+ .field= form.url_field :author_url, :class => 'url', :placeholder => 'Url..'
8
+ = form.label :body, 'Your Comment'
9
+ .field= form.text_area :body, :rows => 6, :class => "required", :placeholder => 'Your comment..'
@@ -0,0 +1,7 @@
1
+ %h2 Edit comment
2
+
3
+ - form_for [@post, @comment], :url => post_comment_path do |form|
4
+ = render :partial => form
5
+ = form.submit "Update"
6
+ or
7
+ = link_to 'Cancel', post_path(@post)
@@ -0,0 +1,15 @@
1
+ atom_feed(:schema_date => 2008, :root_url => root_url, :url => comments_url(:format => :atom)) do |feed|
2
+ feed.title "Comments"
3
+ feed.updated @comments.first.updated_at
4
+
5
+ for comment in @comments
6
+ feed.entry(comment, :url => post_url(comment.post, :anchor => dom_id(comment))) do |entry|
7
+ entry.title "Comment #{comment.id}"
8
+ entry.author do |author|
9
+ author.name comment.author
10
+ author.uri comment.author_url
11
+ end
12
+ entry.content markdown(comment.body), :type => 'html'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ %h2 New comment
2
+
3
+ - form_for [@post, @comment], :url => post_comments_path do |form|
4
+ = render :partial => form
5
+ = form.submit "Post Comment"
6
+ or
7
+ = link_to 'Cancel', post_path(@post)
@@ -0,0 +1,20 @@
1
+ #sidebar
2
+ %h3 Search
3
+ - form_tag search_posts_path, :method => :get, :id => 'search_form' do
4
+ .field= text_field_tag :query, params[:query], :placeholder => 'Keywords..', :type => 'search'
5
+ = submit_tag 'Search'
6
+ %h3 Links
7
+ %ul#links
8
+ %li.feed= link_to "Feed", posts_path(:format => :atom)
9
+ %li.email= mail_to CONTACT_EMAIL, "Email"
10
+
11
+ - if current_user
12
+ %h3 Admin
13
+ %p
14
+ = pluralize(Post.count, 'post')
15
+ and
16
+ = pluralize(Comment.count, 'comment')
17
+ %p
18
+ = link_to "Edit account", edit_user_path(current_user)
19
+ or
20
+ = link_to "Logout", logout_path
@@ -0,0 +1,35 @@
1
+ !!!
2
+ %html.no-js
3
+ %head
4
+ %meta{'http-equiv' => 'Content-Type', :content => "text/html; charset=utf-8"}
5
+ %meta{:name => 'author', :content => 'Bumble'}
6
+ %meta{:name => 'keywords', :content => 'keywords'}
7
+ %meta{:name => 'description', :content => page_description}
8
+ = auto_discovery_link_tag :atom, posts_url(:format => :atom), :title => 'Posts feed'
9
+ = auto_discovery_link_tag :atom, comments_url(:format => :atom), :title => 'Comments feed'
10
+ - if protect_against_forgery?
11
+ :javascript
12
+ var AUTH_TOKEN=#{form_authenticity_token.inspect};
13
+ = stylesheet_link_tag('bumble', :media => 'screen, print')
14
+ = javascript_include_tag 'jquery', 'jquery.validate', 'jquery.form', 'jquery.hint', 'jquery.autogrow', 'modernizr', 'bumble'
15
+ - if current_user
16
+ = javascript_include_tag 'jquery.cookie', 'jquery.ui.core', 'jquery.ui.widget', 'jquery.ui.tabs', 'admin'
17
+ - if iphone?
18
+ %meta{:name => "viewport", :content => "width=device-width; initial-scale=1.0; maximum-scale=1.0;"}
19
+ = stylesheet_link_tag 'iphone'
20
+ = javascript_include_tag 'iphone'
21
+ %title= page_title
22
+ = yield :header
23
+ %body
24
+ #header
25
+ %h1= link_to DOMAIN, root_path, :rel => :home
26
+ #content
27
+ - flash.each do |key, msg|
28
+ .flash{:id => key}= msg
29
+ = yield
30
+ = render 'layouts/sidebar'
31
+ #footer
32
+ = link_to '#header', :class => 'up', :title => 'Back to top' do
33
+ &#x2191;
34
+ Powered by
35
+ = link_to "Bumble", 'http://github.com/andrew/bumble'
@@ -0,0 +1,5 @@
1
+ Your account has been activated. Enjoy Welcome to sparkler etc.
2
+
3
+ <%= @root_url %>
4
+
5
+ If the above URL does not work try copying and pasting it into your browser. If you continue to have problem, please feel free to contact us.
@@ -0,0 +1,5 @@
1
+ Thank you for creating an account! Click the url below to activate your account:
2
+
3
+ <%= @account_activation_url %>
4
+
5
+ If the above URL does not work try copying and pasting it into your browser. If you continue to have problem, please feel free to contact us.
@@ -0,0 +1,8 @@
1
+ A new comment has been posted on <%= @comment.post.title %> by <%= @comment.author %><%= " (#{@comment.author_url})" if @comment.author_url.present? %>:
2
+
3
+ <%= @comment.body %>
4
+
5
+ It<%= @comment.approved ? " doesn't look like" : "'s been marked as" %> spam.
6
+
7
+ -----
8
+ See it here: <%= post_url(@comment.post, :anchor => dom_id(@comment)) %>