FEATURE: automatically rebake out-of-date posts

This commit is contained in:
Sam 2014-05-28 12:30:43 +10:00
parent 2791852bd8
commit f6753d3d46
5 changed files with 75 additions and 30 deletions

View File

@ -26,6 +26,9 @@ module Jobs
# Automatically close stuff that we missed
Topic.auto_close
# Forces rebake of old posts where needed
Post.rebake_old(250)
end
end

View File

@ -15,6 +15,10 @@ class Post < ActiveRecord::Base
include Trashable
include HasCustomFields
# rebake all posts baked before this date
# in our periodical job
REBAKE_BEFORE = Time.new(2014,5,27)
rate_limit
rate_limit :limit_posts_per_day
@ -310,6 +314,35 @@ class Post < ActiveRecord::Base
PostRevisor.new(self).revise!(updated_by, new_raw, opts)
end
def self.rebake_old(limit)
Post.where('baked_at IS NULL OR baked_at < ?', REBAKE_BEFORE)
.limit(limit).each do |p|
begin
p.rebake!
rescue => e
Discourse.handle_exception(e)
end
end
end
def rebake!(opts={})
new_cooked = cook(
raw,
topic_id: topic_id,
invalidate_oneboxes: opts.fetch(:invalidate_oneboxes, false)
)
old_cooked = cooked
update_columns(cooked: new_cooked, baked_at: Time.new)
# Extracts urls from the body
TopicLink.extract_from self
# make sure we trigger the post process
trigger_post_process(true)
new_cooked != old_cooked
end
def set_owner(new_user, actor)
revise(actor, self.raw, {
new_user: new_user,
@ -357,6 +390,7 @@ class Post < ActiveRecord::Base
before_save do
self.last_editor_id ||= user_id
self.cooked = cook(raw, topic_id: topic_id) unless new_record?
self.baked_at = Time.new
end
after_save do

View File

@ -0,0 +1,5 @@
class AddBakedAtToPosts < ActiveRecord::Migration
def change
add_column :posts, :baked_at, :datetime
end
end

View File

@ -9,25 +9,12 @@ task 'posts:refresh_oneboxes' => :environment do
end
def rebake_post(post,opts)
cooked = post.cook(
post.raw,
topic_id: post.topic_id,
invalidate_oneboxes: opts.fetch(:invalidate_oneboxes, false)
)
if cooked != post.cooked
Post.exec_sql('update posts set cooked = ? where id = ?', cooked, post.id)
post.cooked = cooked
changed = post.rebake!(opts)
if changed
putc "#"
else
putc "."
end
# Extracts urls from the body
TopicLink.extract_from post
# make sure we trigger the post process
post.trigger_post_process(true)
rescue => e
puts "\n\nFailed to bake topic_id #{post.topic_id} post_id #{post.id} #{e}\n#{e.backtrace.join("\n")} \n\n"
end

View File

@ -11,8 +11,6 @@ describe Post do
Fabricate.build(:post, args)
end
it { should belong_to :user }
it { should belong_to :topic }
it { should validate_presence_of :raw }
# Min/max body lengths, respecting padding
@ -20,17 +18,6 @@ describe Post do
it { should_not allow_value("x" * (SiteSetting.max_post_length + 1)).for(:raw) }
it { should_not allow_value((" " * SiteSetting.min_post_length) + "x").for(:raw) }
it { should have_many :post_replies }
it { should have_many :replies }
it { should have_many :post_uploads }
it { should have_many :uploads }
it { should have_many :post_details }
it { should have_many :post_revisions }
it { should have_many :revisions}
it { should rate_limit }
let(:topic) { Fabricate(:topic) }
@ -805,11 +792,11 @@ describe Post do
post.has_host_spam?.should == false
SiteSetting.stubs(:newuser_spam_host_threshold).returns(1)
SiteSetting.newuser_spam_host_threshold = 1
post.has_host_spam?.should == true
SiteSetting.stubs(:white_listed_spam_host_domains).returns("bla.com|boo.com | somesite.com ")
SiteSetting.white_listed_spam_host_domains = "bla.com|boo.com | somesite.com "
post.has_host_spam?.should == false
end
end
@ -826,4 +813,33 @@ describe Post do
post.custom_fields.should == {"Tommy" => "Hanks", "Vincent" => "Vega"}
end
describe "#rebake!" do
it "will rebake a post correctly" do
post = create_post
post.baked_at.should_not == nil
first_baked = post.baked_at
first_cooked = post.cooked
Post.exec_sql("UPDATE posts SET cooked = 'frogs' WHERE id = ?", post.id)
post.reload
result = post.rebake!
post.baked_at.should_not == first_baked
post.cooked.should == first_cooked
result.should == true
end
end
describe ".rebake_old" do
it "will catch posts it needs to rebake" do
post = create_post
post.update_column(:baked_at, Time.new(2000,1,1))
Post.rebake_old(100)
post.reload
post.baked_at.should > 1.day.ago
end
end
end