Merge pull request #3015 from evazion/feat-replace-images

Fix #2949: Sample image replacement ability
This commit is contained in:
Albert Yi
2017-05-12 17:11:29 -07:00
committed by GitHub
12 changed files with 295 additions and 26 deletions

View File

@@ -7,6 +7,8 @@ class Post < ActiveRecord::Base
class RevertError < Exception ; end
class SearchError < Exception ; end
DELETION_GRACE_PERIOD = 30.days
before_validation :initialize_uploader, :on => :create
before_validation :merge_old_changes
before_validation :normalize_tags
@@ -30,7 +32,6 @@ class Post < ActiveRecord::Base
after_save :expire_essential_tag_string_cache
after_destroy :remove_iqdb_async
after_destroy :delete_files
after_destroy :delete_remote_files
after_commit :update_iqdb_async, :on => :create
after_commit :notify_pubsub
@@ -61,24 +62,31 @@ class Post < ActiveRecord::Base
attr_accessor :old_tag_string, :old_parent_id, :old_source, :old_rating, :has_constraints, :disable_versioning, :view_count
module FileMethods
extend ActiveSupport::Concern
module ClassMethods
def delete_files(post_id, file_path, large_file_path, preview_file_path)
# the large file and the preview don't necessarily exist. if so errors will be ignored.
FileUtils.rm_f(file_path)
FileUtils.rm_f(large_file_path)
FileUtils.rm_f(preview_file_path)
RemoteFileManager.new(file_path).delete
RemoteFileManager.new(large_file_path).delete
RemoteFileManager.new(preview_file_path).delete
end
end
def delete_files
Post.delete_files(id, file_path, large_file_path, preview_file_path)
end
def distribute_files
RemoteFileManager.new(file_path).distribute
RemoteFileManager.new(preview_file_path).distribute if has_preview?
RemoteFileManager.new(large_file_path).distribute if has_large?
end
def delete_remote_files
RemoteFileManager.new(file_path).delete
RemoteFileManager.new(preview_file_path).delete if has_preview?
RemoteFileManager.new(large_file_path).delete if has_large?
end
def delete_files
FileUtils.rm_f(file_path)
FileUtils.rm_f(large_file_path)
FileUtils.rm_f(preview_file_path)
end
def file_path_prefix
Rails.env == "test" ? "test." : ""
end
@@ -1421,6 +1429,52 @@ class Post < ActiveRecord::Base
Post.expire_cache_for_all(tag_array)
ModAction.log("undeleted post ##{id}")
end
def replace!(url, replacer = CurrentUser.user)
# TODO for posts with notes we need to rescale the notes if the dimensions change.
if notes.size > 0
raise NotImplementedError.new("Replacing images with notes not yet supported.")
end
# TODO for ugoiras we need to replace the frame data.
if is_ugoira?
raise NotImplementedError.new("Replacing ugoira images not yet supported.")
end
# TODO images hosted on s3 need to be deleted from s3 instead of the local filesystem.
if Danbooru.config.use_s3_proxy?(self)
raise NotImplementedError.new("Replacing S3 hosted images not yet supported.")
end
transaction do
upload = Upload.create!(source: url, rating: self.rating, tag_string: self.tag_string)
upload.process_upload
upload.update(status: "completed", post_id: id)
# queue the deletion *before* updating the post so that we use the old
# md5/file_ext to delete the old files. if saving the post fails,
# this is rolled back so the job won't run.
Post.delay(queue: "default", run_at: Time.now + DELETION_GRACE_PERIOD).delete_files(id, file_path, large_file_path, preview_file_path)
self.md5 = upload.md5
self.file_ext = upload.file_ext
self.image_width = upload.image_width
self.image_height = upload.image_height
self.file_size = upload.file_size
self.source = upload.source
self.tag_string = upload.tag_string
comments.create!({creator: User.system, body: presenter.comment_replacement_message(replacer), do_not_bump_post: true}, without_protection: true)
ModAction.log(presenter.modaction_replacement_message)
save!
end
# point of no return: these things can't be rolled back, so we do them
# only after the transaction successfully commits.
distribute_files
update_iqdb_async
end
end
module VersionMethods

View File

@@ -105,7 +105,7 @@ class Upload < ActiveRecord::Base
end
module ConversionMethods
def process_once
def process_upload
CurrentUser.scoped(uploader, uploader_ip_addr) do
update_attribute(:status, "processing")
self.source = strip_source
@@ -129,16 +129,19 @@ class Upload < ActiveRecord::Base
move_file
validate_md5_confirmation_after_move
save
post = convert_to_post
post.distribute_files
if post.save
User.where(id: CurrentUser.id).update_all("post_upload_count = post_upload_count + 1")
create_artist_commentary(post) if include_artist_commentary?
ugoira_service.save_frame_data(post) if is_ugoira?
update_attributes(:status => "completed", :post_id => post.id)
else
update_attribute(:status, "error: " + post.errors.full_messages.join(", "))
end
end
end
def create_post_from_upload
post = convert_to_post
post.distribute_files
if post.save
User.where(id: CurrentUser.id).update_all("post_upload_count = post_upload_count + 1")
create_artist_commentary(post) if include_artist_commentary?
ugoira_service.save_frame_data(post) if is_ugoira?
update_attributes(:status => "completed", :post_id => post.id)
else
update_attribute(:status, "error: " + post.errors.full_messages.join(", "))
end
end
@@ -146,7 +149,8 @@ class Upload < ActiveRecord::Base
@tries ||= 0
return if !force && status =~ /processing|completed|error/
process_once
process_upload
create_post_from_upload
rescue Timeout::Error, Net::HTTP::Persistent::Error => x
if @tries > 3