From 32f717420d0f6443e1c672217b5342b9e475644a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Hanol?= <regis@hanol.fr>
Date: Mon, 26 Aug 2013 00:24:24 +0200
Subject: [PATCH] add max_image_height site setting

---
 app/models/site_setting.rb                    |  1 +
 config/locales/server.en.yml                  |  1 +
 config/locales/server.fr.yml                  |  1 +
 lib/cooked_post_processor.rb                  |  3 +-
 lib/image_sizer.rb                            | 10 +++---
 spec/components/cooked_post_processor_spec.rb |  1 +
 spec/components/image_sizer_spec.rb           | 36 +++++++++++++++++--
 7 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index cf780f3a7..e5bbf96db 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -78,6 +78,7 @@ class SiteSetting < ActiveRecord::Base
   setting(:queue_jobs, !Rails.env.test?)
   setting(:crawl_images, !Rails.env.test?)
   setting(:max_image_width, 690)
+  setting(:max_image_height, 500)
   setting(:create_thumbnails, true)
   client_setting(:category_featured_topics, 6)
   setting(:topics_per_page, 30)
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 2a2d34847..59ccf20b8 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -470,6 +470,7 @@ en:
     edit_history_visible_to_public: "Allow everyone to see previous versions of an edited post. When disabled, only staff members can view edit history."
     delete_removed_posts_after: "Number of hours after which posts removed by the author will be deleted."
     max_image_width: "Maximum allowed width of images in a post"
+    max_image_height: "Maximum allowed height of images in a post"
     category_featured_topics: "Number of topics displayed per category in the /categories page"
     add_rel_nofollow_to_user_content: "Add rel nofollow to all submitted user content, except for internal links (including parent domains) changing this requires you update all your baked markdown with: \"rake posts:rebake\""
     exclude_rel_nofollow_domains: "A comma delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"
diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml
index 7edd18878..188d41f94 100644
--- a/config/locales/server.fr.yml
+++ b/config/locales/server.fr.yml
@@ -446,6 +446,7 @@ fr:
     crawl_images: "permettre la récupération des images provenant de sources tierces"
     ninja_edit_window: "temps d'édition avant de sauvegarder une nouvelle version, en secondes."
     max_image_width: "largeur maximale des images d'un message"
+    max_image_height: "hauteur maximale des images d'un message"
     category_featured_topics: "nombre de discussions affichées dans la liste par catégories"
     add_rel_nofollow_to_user_content: "Ajouter rel nofollow à tous les contenus des utilisateurs, sauf les liens internes (incluant les domaines parents) Modifier ceci requiert une mise à jour de tout votre markdown (<code>rake posts:rebake</code>)"
     exclude_rel_nofollow_domains: "Une liste séparée par des virgules contenant les noms de domaines de premier niveau pour lesquels il faut ajouter un attribut nofollow (exemple.com va automatiquement fonctionner aussi avec sous.domaine.exemple.com)"
diff --git a/lib/cooked_post_processor.rb b/lib/cooked_post_processor.rb
index b72e4eaf0..7924991a4 100644
--- a/lib/cooked_post_processor.rb
+++ b/lib/cooked_post_processor.rb
@@ -117,7 +117,8 @@ class CookedPostProcessor
     original_width, original_height = get_size(src)
 
     return if original_width.to_i <= width && original_height.to_i <= height
-    return if original_width.to_i <= SiteSetting.max_image_width
+    return if original_width.to_i <= SiteSetting.max_image_width && original_height.to_i <= SiteSetting.max_image_height
+
     return if is_a_hyperlink(img)
 
     if upload
diff --git a/lib/image_sizer.rb b/lib/image_sizer.rb
index 3af9f679b..3fa016004 100644
--- a/lib/image_sizer.rb
+++ b/lib/image_sizer.rb
@@ -2,16 +2,18 @@ module ImageSizer
 
   # Resize an image to the aspect ratio we want
   def self.resize(width, height)
-    max_width = SiteSetting.max_image_width.to_f
     return if width.blank? || height.blank?
 
+    max_width = SiteSetting.max_image_width.to_f
+    max_height = SiteSetting.max_image_height.to_f
+
     w = width.to_f
     h = height.to_f
 
-    return [w.floor, h.floor] if w < max_width
+    return [w.floor, h.floor] if w <= max_width && h <= max_height
 
-    # Using the maximum width, resize the height retaining the aspect ratio
-    [max_width.floor, (h * (max_width / w)).floor]
+    ratio = [max_width / w, max_height / h].min;
+    [(w * ratio).floor, (h * ratio).floor]
   end
 
 end
diff --git a/spec/components/cooked_post_processor_spec.rb b/spec/components/cooked_post_processor_spec.rb
index b0339b888..692af6d94 100644
--- a/spec/components/cooked_post_processor_spec.rb
+++ b/spec/components/cooked_post_processor_spec.rb
@@ -123,6 +123,7 @@ describe CookedPostProcessor do
       let(:cpp) { CookedPostProcessor.new(post) }
 
       before do
+        SiteSetting.stubs(:max_image_height).returns(2000)
         SiteSetting.stubs(:create_thumbnails?).returns(true)
         Upload.expects(:get_from_url).returns(upload)
         cpp.stubs(:associate_to_post)
diff --git a/spec/components/image_sizer_spec.rb b/spec/components/image_sizer_spec.rb
index b9c0b1691..627e47f30 100644
--- a/spec/components/image_sizer_spec.rb
+++ b/spec/components/image_sizer_spec.rb
@@ -4,10 +4,11 @@ require 'image_sizer'
 describe ImageSizer do
 
   before do
-    SiteSetting.expects(:max_image_width).returns(500)
+    SiteSetting.stubs(:max_image_width).returns(500)
+    SiteSetting.stubs(:max_image_height).returns(500)
   end
 
-  it 'returns the same dimensions if the width is less than the maximum' do
+  it 'returns the same dimensions when smaller than the maximums' do
     ImageSizer.resize(400, 200).should == [400, 200]
   end
 
@@ -23,7 +24,7 @@ describe ImageSizer do
     ImageSizer.resize('100', '101').should == [100, 101]
   end
 
-  describe 'when larger than the maximum' do
+  describe 'when larger than the maximum width' do
 
     before do
       @w, @h = ImageSizer.resize(600, 123)
@@ -39,4 +40,33 @@ describe ImageSizer do
 
   end
 
+  describe 'when larger than the maximum height' do
+
+    before do
+      @w, @h = ImageSizer.resize(123, 600)
+    end
+
+    it 'returns the maxmimum height if larger than the maximum' do
+      @h.should == 500
+    end
+
+    it 'resizes the width retaining the aspect ratio' do
+      @w.should == 102
+    end
+
+  end
+
+  describe 'when larger than the maximums' do
+
+    before do
+      @w, @h = ImageSizer.resize(533, 800)
+    end
+
+    it 'resizes both dimensions retaining the aspect ratio' do
+      @h.should == 500
+      @w.should == 333
+    end
+
+  end
+
 end