FIX: allow upload recovery to recover uploads with sha mismatch

FIX: allow upload recovery to recover uploads with sha mismatch

Filename on disk may mismatch sha of file in some old 1X setups. This will attempt to recover file even if sha1 mismatches. We had an old bug that caused this.

This also adds uploads:fix_relative_upload_links which attempts to replace urls of the format /upload/default/... with upload://

diff --git a/lib/tasks/uploads.rake b/lib/tasks/uploads.rake
index a6744f2..8619991 100644
--- a/lib/tasks/uploads.rake
+++ b/lib/tasks/uploads.rake
@@ -886,3 +886,36 @@ task "uploads:recover" => :environment do
     end
   end
 end
+
+def inline_uploads(post)
+  replaced = false
+
+  original_raw = post.raw
+
+  post.raw = post.raw.gsub(/(\((\/uploads\S+).*\))/) do
+    upload = Upload.find_by(url: $2)
+    result = $1
+
+    if upload&.id
+      result.sub!($2, upload.short_url)
+      replaced = true
+    else
+      puts "Upload not found #{$2} in Post #{post.id} - #{post.url}"
+    end
+    result
+  end
+
+  if replaced
+    puts "Corrected image urls in #{post.url} raw backup stored in custom field"
+    post.custom_fields["BACKUP_POST_RAW"] = original_raw
+    post.save_custom_fields
+    post.save!
+    post.rebake!
+  end
+end
+
+task "uploads:fix_relative_upload_links" => :environment do
+  Post.where('raw like ?', '%](/uploads%').find_each do |post|
+    inline_uploads(post)
+  end
+end
diff --git a/lib/upload_recovery.rb b/lib/upload_recovery.rb
index a4d0433..136fbfd 100644
--- a/lib/upload_recovery.rb
+++ b/lib/upload_recovery.rb
@@ -63,15 +63,27 @@ class UploadRecovery
     end
   end
 
+  def ensure_upload!(post:, sha1:, upload:)
+    return if !upload.persisted?
+
+    if upload.sha1 != sha1
+      STDERR.puts "Warning #{post.url} had an incorrect sha, remapping #{sha1} to #{upload.sha1}"
+      post.raw = post.raw.gsub(sha1, upload.sha1)
+      post.save!
+    end
+
+    post.rebake!
+  end
+
   def recover_post_upload_from_local(post:, sha1:)
     recover_from_local(sha1: sha1, user_id: post.user_id) do |upload|
-      post.rebake! if upload.persisted?
+      ensure_upload!(post: post, sha1: sha1, upload: upload)
     end
   end
 
   def recover_post_upload_from_s3(post:, sha1:)
     recover_from_s3(sha1: sha1, user_id: post.user_id) do |upload|
-      post.rebake! if upload.persisted?
+      ensure_upload!(post: post, sha1: sha1, upload: upload)
     end
   end

GitHub sha: ebcb571d

It’ll be good if we can update the specs for this change as well. discourse/upload_recovery_spec.rb at master · discourse/discourse · GitHub