Merge pull request #3240 from evazion/fix-3235

Fix #3235: Replacements deleting files currently in use.
This commit is contained in:
Albert Yi
2017-07-26 17:10:44 -07:00
committed by GitHub
4 changed files with 62 additions and 14 deletions

View File

@@ -67,9 +67,11 @@ class Post < ApplicationRecord
module ClassMethods
def delete_files(post_id, file_path, large_file_path, preview_file_path, force: false)
unless force
post = Post.find(post_id)
# XXX should pass in the md5 instead of parsing it.
preview_file_path =~ %r!/data/preview/(?:test\.)?([a-z0-9]{32})\.jpg\z!
md5 = $1
if post.file_path == file_path || post.large_file_path == large_file_path || post.preview_file_path == preview_file_path
if Post.where(md5: md5).exists?
raise DeletionError.new("Files still in use; skipping deletion.")
end
end

View File

@@ -19,7 +19,14 @@ class PostReplacement < ApplicationRecord
def process!
transaction do
upload = Upload.create!(file: replacement_file, source: replacement_url, rating: post.rating, tag_string: self.tags)
upload = Upload.create!(
file: replacement_file,
source: replacement_url,
rating: post.rating,
tag_string: self.tags,
replaced_post: post,
)
upload.process_upload
upload.update(status: "completed", post_id: post.id)

View File

@@ -7,7 +7,7 @@ class Upload < ApplicationRecord
attr_accessor :file, :image_width, :image_height, :file_ext, :md5,
:file_size, :as_pending, :artist_commentary_title,
:artist_commentary_desc, :include_artist_commentary,
:referer_url, :downloaded_source
:referer_url, :downloaded_source, :replaced_post
belongs_to :uploader, :class_name => "User"
belongs_to :post
before_validation :initialize_uploader, :on => :create
@@ -22,7 +22,7 @@ class Upload < ApplicationRecord
:tag_string, :status, :backtrace, :post_id, :md5_confirmation,
:parent_id, :server, :artist_commentary_title,
:artist_commentary_desc, :include_artist_commentary,
:referer_url
:referer_url, :replaced_post
module ValidationMethods
def uploader_is_not_limited
@@ -46,7 +46,10 @@ class Upload < ApplicationRecord
# Because uploads are processed serially, there's no race condition here.
def validate_md5_uniqueness
md5_post = Post.find_by_md5(md5)
if md5_post
if md5_post && replaced_post
raise "duplicate: #{md5_post.id}" if replaced_post != md5_post
elsif md5_post
raise "duplicate: #{md5_post.id}"
end
end