From 0ec36785f0a7c3d295f689fc2950b636c11b0a7f Mon Sep 17 00:00:00 2001 From: evazion Date: Wed, 4 Sep 2019 14:49:52 -0500 Subject: [PATCH] uploads: don't clean up replaced files too early. Don't try delete files belonging to completed uploads during pruning. If an uploaded post was replaced shortly after upload, then the original file could get deleted during pruning since it's no longer in use, but this isn't supposed to happen until the replacement grace period (30 days) is over. --- app/models/upload.rb | 2 +- test/models/upload_service_test.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/models/upload.rb b/app/models/upload.rb index 00fcbe6f4..511bf6af7 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -101,7 +101,7 @@ class Upload < ApplicationRecord def delete_files # md5 is blank if the upload errored out before downloading the file. - if md5.blank? || Upload.where(md5: md5).exists? || Post.where(md5: md5).exists? + if is_completed? || md5.blank? || Upload.where(md5: md5).exists? || Post.where(md5: md5).exists? return end diff --git a/test/models/upload_service_test.rb b/test/models/upload_service_test.rb index f9b573cf3..b343e356a 100644 --- a/test/models/upload_service_test.rb +++ b/test/models/upload_service_test.rb @@ -1274,6 +1274,23 @@ class UploadServiceTest < ActiveSupport::TestCase refute(File.exists?(Danbooru.config.storage_manager.file_path(@upload2.md5, "jpg", :original))) end + should "not delete files that were replaced after upload and are still pending deletion" do + @upload = as(@user) { UploadService.new(file: upload_file("test/files/test.jpg")).start! } + assert(@upload.is_completed?) + + as(@user) { @upload.post.replace!(replacement_file: upload_file("test/files/test.png"), replacement_url: "") } + assert_not_equal(@upload.md5, @upload.post.md5) + + # after replacement the uploaded file is no longer in use, but it shouldn't be + # deleted yet. it should only be deleted by the replacer after the grace period. + @upload.destroy! + assert(File.exists?(Danbooru.config.storage_manager.file_path(@upload.md5, "jpg", :original))) + + travel (PostReplacement::DELETION_GRACE_PERIOD + 1).days + workoff_active_jobs + refute(File.exists?(Danbooru.config.storage_manager.file_path(@upload.md5, "jpg", :original))) + end + should "work on uploads without a file" do @upload = as(@user) { UploadService.new(source: "http://14903gf0vm3g134yjq3n535yn3n.com/does_not_exist.jpg").start! }