FIX: downsize_uploads script

FIX: downsize_uploads script

The script will now correct all width/height and thumbnail_width/thumbnail_height properties of all the uploaded images.

The script now uses width * height to filter out all unaffected images.

Also handled the case where a downsized image was already an uploaded record.

diff --git a/script/downsize_uploads.rb b/script/downsize_uploads.rb
index 27a2555..a9983f8 100644
--- a/script/downsize_uploads.rb
+++ b/script/downsize_uploads.rb
@@ -5,35 +5,95 @@ require File.expand_path("../../config/environment", __FILE__)
 # no less than 1 megapixel
 max_image_pixels = [ARGV[0].to_i, 1_000_000].max
 
-puts '', "Downsizing uploads size to no more than #{max_image_pixels} pixels"
+puts "", "Fixing all images dimensions in the database", ""
 
 count = 0
 
-Upload.where("LOWER(extension) IN ('jpg', 'jpeg', 'gif', 'png')").find_each do |upload|
+Upload
+  .where("LOWER(extension) IN ('jpg', 'jpeg', 'gif', 'png')")
+  .where("COALESCE(width, 0) = 0 OR COALESCE(height, 0) = 0 OR COALESCE(thumbnail_width, 0) = 0 OR COALESCE(thumbnail_height, 0) = 0")
+  .find_each do |upload|
+
+  count += 1
+  print "\r%8d".freeze % count
+
+  next unless source = upload.local? ? Discourse.store.path_for(upload) : "https:#{upload.url}"
+
+  w, h = FastImage.size(source)
+  ww, hh = ImageSizer.resize(w, h)
+
+  next if w == 0 || h == 0 || ww == 0 || hh == 0
+
+  upload.update!(
+    width: w,
+    height: h,
+    thumbnail_width: ww,
+    thumbnail_height: hh,
+  )
+end
+
+puts "", "Downsizing images to no more than #{max_image_pixels} pixels"
+
+count = 0
+
+Upload
+  .where("LOWER(extension) IN ('jpg', 'jpeg', 'gif', 'png')")
+  .where("width * height > ?", max_image_pixels)
+  .find_each do |upload|
+
   count += 1
   print "\r%8d".freeze % count
 
   next unless source = upload.local? ? Discourse.store.path_for(upload) : "https:#{upload.url}"
   next unless size = (FastImage.size(source) rescue nil)
-  next if size.reduce(:*) < max_image_pixels
+
+  if size.reduce(:*) < max_image_pixels
+    ww, hh = ImageSizer.resize(*size)
+
+    upload.update!(
+      width: size[0],
+      height: size[1],
+      thumbnail_width: ww,
+      thumbnail_height: hh,
+    )
+
+    next
+  end
+
   next unless path = upload.local? ? source : (Discourse.store.download(upload) rescue nil)&.path
 
   OptimizedImage.downsize(path, path, "#{max_image_pixels}@", filename: upload.original_filename)
 
   previous_short_url = upload.short_url
 
+  sha1 = Upload.generate_digest(path)
+  w, h = FastImage.size(path)
+  ww, hh = ImageSizer.resize(w, h)
+
+  new_file = true
+
+  if existing_upload = Upload.find_by(sha1: sha1)
+    upload = existing_upload
+    new_file = false
+  end
+
   upload.filesize = File.size(path)
-  upload.sha1 = Upload.generate_digest(path)
-  upload.width, upload.height = ImageSizer.resize(*FastImage.size(path))
+  upload.sha1 = sha1
+  upload.width = w
+  upload.height = h
+  upload.thumbnail_width = ww
+  upload.thumbnail_height = hh
   next unless upload.save!
 
-  next unless url = Discourse.store.store_upload(File.new(path), upload)
-  next unless upload.update!(url: url)
+  if new_file
+    next unless url = Discourse.store.store_upload(File.new(path), upload)
+    next unless upload.update!(url: url)
+  end
 
   upload.posts.each do |post|
-    post.update!(raw: post.raw.gsub(previous_short_url, upload.short_url))
+    post.update!(raw: post.raw.gsub(previous_short_url, upload.short_url)) if new_file
     Jobs.enqueue(:process_post, post_id: post.id, bypass_bump: true, cook: true)
   end
 end
 
-puts '', 'Done', ''
+puts "", "Done"

GitHub sha: e1998ef2