diff --git a/script/downsize_uploads.rb b/script/downsize_uploads.rb index 27a2555736f..a9983f80b9c 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"