diff --git a/app/logical/post_pruner.rb b/app/logical/post_pruner.rb new file mode 100644 index 000000000..3932da151 --- /dev/null +++ b/app/logical/post_pruner.rb @@ -0,0 +1,47 @@ +class PostPruner + attr_reader :admin + + def initialize + @admin = User.where(:level => User::Levels::ADMIN).first + end + + def prune! + prune_pending! + prune_flagged! + prune_mod_actions! + end + +protected + + def prune_pending! + CurrentUser.scoped(admin, "127.0.0.1") do + Post.where("is_deleted = ? and is_pending = ? and created_at < ?", false, true, 3.days.ago).each do |post| + begin + post.flag!("Unapproved in three days") + rescue PostFlag::Error + # swallow + end + post.delete! + end + end + end + + def prune_flagged! + CurrentUser.scoped(admin, "127.0.0.1") do + Post.where("is_deleted = ? and is_flagged = ?", false, true).each do |post| + if post.flags.unresolved.old.any? + begin + post.flag!("Unapproved in three days after returning to moderation queue") + rescue PostFlag::Error + # swallow + end + post.delete! + end + end + end + end + + def prune_mod_actions! + ModAction.destroy_all(["creator_id = ? and description like ?", admin.id, "deleted post %"]) + end +end diff --git a/app/models/mod_action.rb b/app/models/mod_action.rb index e5c1428b9..529aac5ff 100644 --- a/app/models/mod_action.rb +++ b/app/models/mod_action.rb @@ -1,3 +1,8 @@ class ModAction < ActiveRecord::Base belongs_to :creator, :class_name => "User" + before_validation :initialize_creator, :on => :create + + def initialize_creator + self.creator_id = CurrentUser.id + end end diff --git a/app/models/post.rb b/app/models/post.rb index 9598ba1b7..630b71930 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -299,6 +299,7 @@ class Post < ActiveRecord::Base self.is_deleted = false self.approver_id = CurrentUser.id save! + ModAction.create(:description => "approved post ##{id}") end end @@ -900,6 +901,7 @@ class Post < ActiveRecord::Base update_column(:is_deleted, true) update_parent_on_destroy tag_array.each {|x| expire_cache(x)} + ModAction.create(:description => "deleted post ##{id}") end end @@ -907,6 +909,7 @@ class Post < ActiveRecord::Base update_column(:is_deleted, false) tag_array.each {|x| expire_cache(x)} update_parent_on_save + ModAction.create(:description => "undeleted post ##{id}") end end diff --git a/app/models/post_flag.rb b/app/models/post_flag.rb index 4cc15223b..34bccd012 100644 --- a/app/models/post_flag.rb +++ b/app/models/post_flag.rb @@ -9,8 +9,9 @@ class PostFlag < ActiveRecord::Base before_validation :initialize_creator, :on => :create validates_uniqueness_of :creator_id, :scope => :post_id, :message => "has already flagged this post" before_save :update_post - scope :resolved, where(["is_resolved = ?", true]) - scope :unresolved, where(["is_resolved = ?", false]) + scope :resolved, where("is_resolved = ?", true) + scope :unresolved, where("is_resolved = ?", false) + scope :old, lambda {where("created_at <= ?", 3.days.ago)} def update_post post.update_column(:is_flagged, true) diff --git a/config/schedule.rb b/config/schedule.rb index 24e977fe3..36227d222 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -4,6 +4,10 @@ every 1.hour do runner "TagSubscription.process_all" end +every 1.day do + runner "PostPruner.new.prune!" +end + if environment == "production" every 1.hour do runner "AmazonBackup.execute" diff --git a/test/unit/post_pruner_test.rb b/test/unit/post_pruner_test.rb new file mode 100644 index 000000000..3acd23d35 --- /dev/null +++ b/test/unit/post_pruner_test.rb @@ -0,0 +1,42 @@ +require 'test_helper' + +class PostPrunerTest < ActiveSupport::TestCase + setup do + @user = Factory.create(:admin_user) + CurrentUser.user = @user + CurrentUser.ip_addr = "127.0.0.1" + MEMCACHE.flush_all + + @flagger = Factory.create(:user) + @old_post = Factory.create(:post, :created_at => 5.days.ago, :is_pending => true) + @unresolved_flagged_post = Factory.create(:post, :is_flagged => true) + @resolved_flagged_post = Factory.create(:post, :is_flagged => true) + + CurrentUser.scoped(@flagger, "127.0.0.2") do + @unresolved_post_flag = Factory.create(:post_flag, :created_at => 5.days.ago, :is_resolved => false, :post_id => @unresolved_flagged_post.id) + @resolved_post_flag = Factory.create(:post_flag, :created_at => 5.days.ago, :is_resolved => true, :post_id => @resolved_flagged_post.id) + end + + PostPruner.new.prune! + end + + teardown do + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + + should "prune old pending posts" do + @old_post.reload + assert(@old_post.is_deleted?) + end + + should "prune old flagged posts that are still unresolved" do + @unresolved_flagged_post.reload + assert(@unresolved_flagged_post.is_deleted?) + end + + should "not prune old flagged posts that are resolved" do + @resolved_flagged_post.reload + assert(!@resolved_flagged_post.is_deleted?) + end +end