]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Thumbnails: add a common mode to only retrieve thumbs from popular media websites
authorArthurHoaro <arthur@hoa.ro>
Thu, 5 Jul 2018 18:29:55 +0000 (20:29 +0200)
committerArthurHoaro <arthur@hoa.ro>
Thu, 5 Jul 2018 18:34:22 +0000 (20:34 +0200)
application/PageBuilder.php
application/Thumbnailer.php
application/Updater.php
index.php
tests/ThumbnailerTest.php
tests/Updater/UpdaterTest.php
tests/utils/config/configJson.json.php
tpl/default/configure.html
tpl/vintage/configure.html

index 5da70811610ddbcc22d4b49e4fd134db3f416978..b1abe0d05fd724182cea8a0ecda659f93734f6c2 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use Shaarli\Config\ConfigManager;
+use Shaarli\Thumbnailer;
 
 /**
  * This class is in charge of building the final page.
@@ -119,7 +120,10 @@ class PageBuilder
             $this->tpl->assign('tags', $this->linkDB->linksCountPerTag());
         }
 
-        $this->tpl->assign('thumbnails_enabled', $this->conf->get('thumbnails.enabled'));
+        $this->tpl->assign(
+            'thumbnails_enabled',
+            $this->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
+        );
         $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width'));
         $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height'));
 
index d2284e795eb3b43261cfc4577832e610a390b036..7d0d9c33203f9724afdde1b3db102d54aaa53d2b 100644 (file)
@@ -14,6 +14,27 @@ use WebThumbnailer\Application\ConfigManager as WTConfigManager;
  */
 class Thumbnailer
 {
+    const COMMON_MEDIA_DOMAINS = [
+        'imgur.com',
+        'flickr.com',
+        'youtube.com',
+        'wikimedia.org',
+        'redd.it',
+        'gfycat.com',
+        'media.giphy.com',
+        'twitter.com',
+        'twimg.com',
+        'instagram.com',
+        'pinterest.com',
+        'pinterest.fr',
+        'tumblr.com',
+        'deviantart.com',
+    ];
+
+    const MODE_ALL = 'all';
+    const MODE_COMMON = 'common';
+    const MODE_NONE = 'none';
+
     /**
      * @var WebThumbnailer instance.
      */
@@ -57,13 +78,42 @@ class Thumbnailer
      */
     public function get($url)
     {
+        if ($this->conf->get('thumbnails.mode') === self::MODE_COMMON
+            && ! $this->isCommonMediaOrImage($url)
+        ) {
+            return false;
+        }
+
         try {
             return $this->wt->thumbnail($url);
         } catch (WebThumbnailerException $e) {
             // Exceptions are only thrown in debug mode.
-            error_log(get_class($e) .': '. $e->getMessage());
-            return false;
+            error_log(get_class($e) . ': ' . $e->getMessage());
         }
+        return false;
+    }
+
+    /**
+     * We check weather the given URL is from a common media domain,
+     * or if the file extension is an image.
+     *
+     * @param string $url to check
+     *
+     * @return bool true if it's an image or from a common media domain, false otherwise.
+     */
+    public function isCommonMediaOrImage($url)
+    {
+        foreach (self::COMMON_MEDIA_DOMAINS as $domain) {
+            if (strpos($url, $domain) !== false) {
+                return true;
+            }
+        }
+
+        if (endsWith($url, '.jpg') || endsWith($url, '.png') || endsWith($url, '.jpeg')) {
+            return true;
+        }
+
+        return false;
     }
 
     /**
index f6b9e205d61ba29c33a23cdd998b57ba3218ed74..2a4c807cbcccda5e77180fa80297fc476e51547b 100644 (file)
@@ -2,6 +2,7 @@
 use Shaarli\Config\ConfigJson;
 use Shaarli\Config\ConfigPhp;
 use Shaarli\Config\ConfigManager;
+use Shaarli\Thumbnailer;
 
 /**
  * Class Updater.
@@ -497,12 +498,12 @@ class Updater
      */
     public function updateMethodWebThumbnailer()
     {
-        if ($this->conf->exists('thumbnails.enabled')) {
+        if ($this->conf->exists('thumbnails.mode')) {
             return true;
         }
 
         $thumbnailsEnabled = $this->conf->get('thumbnail.enable_thumbnails', true);
-        $this->conf->set('thumbnails.enabled', $thumbnailsEnabled);
+        $this->conf->set('thumbnails.mode', $thumbnailsEnabled ? Thumbnailer::MODE_ALL : Thumbnailer::MODE_NONE);
         $this->conf->set('thumbnails.width', 125);
         $this->conf->set('thumbnails.height', 90);
         $this->conf->remove('thumbnail');
index d5a3e93d24b3691dfb3fb5a1c7b239e818bbc754..299d6d9b9e8dbba0462e6cdb4b830af9f1cd9803 100644 (file)
--- a/index.php
+++ b/index.php
@@ -603,7 +603,9 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
     // -------- Picture wall
     if ($targetPage == Router::$PAGE_PICWALL)
     {
-        if (! $conf->get('thumbnails.enabled')) {
+        $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli'));
+        if (! $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) === Thumbnailer::MODE_NONE) {
+            $PAGE->assign('linksToDisplay', []);
             $PAGE->renderPage('picwall');
             exit;
         }
@@ -630,7 +632,6 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
             $PAGE->assign($key, $value);
         }
 
-        $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli'));
         $PAGE->renderPage('picwall');
         exit;
     }
@@ -1013,14 +1014,13 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
             $conf->set('api.secret', escape($_POST['apiSecret']));
             $conf->set('translation.language', escape($_POST['language']));
 
-            $thumbnailsEnabled = extension_loaded('gd') && !empty($_POST['enableThumbnails']);
-            $conf->set('thumbnails.enabled', $thumbnailsEnabled);
-
-            if (! $conf->get('thumbnails.enabled') && $thumbnailsEnabled) {
+            $thumbnailsMode = extension_loaded('gd') ? $_POST['enableThumbnails'] : Thumbnailer::MODE_NONE;
+            if ($conf->get('thumbnails.enabled', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) {
                 $_SESSION['warnings'][] = t(
-                    'You have enabled thumbnails. <a href="?do=thumbs_update">Please synchonize them</a>.'
+                    'You have enabled or changed thumbnails mode. <a href="?do=thumbs_update">Please synchonize them</a>.'
                 );
             }
+            $conf->set('thumbnails.mode', $thumbnailsMode);
 
             try {
                 $conf->write($loginManager->isLoggedIn());
@@ -1061,6 +1061,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
             $PAGE->assign('languages', Languages::getAvailableLanguages());
             $PAGE->assign('language', $conf->get('translation.language'));
             $PAGE->assign('gd_enabled', extension_loaded('gd'));
+            $PAGE->assign('thumbnails_mode', $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE));
             $PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli'));
             $PAGE->renderPage('configure');
             exit;
@@ -1162,7 +1163,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
             $link['title'] = $link['url'];
         }
 
-        if ($conf->get('thumbnails.enabled')) {
+        if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) {
             $thumbnailer = new Thumbnailer($conf);
             $link['thumbnail'] = $thumbnailer->get($url);
         }
@@ -1606,7 +1607,8 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
     $i = ($page-1) * $_SESSION['LINKS_PER_PAGE'];
     $end = $i + $_SESSION['LINKS_PER_PAGE'];
 
-    if ($conf->get('thumbnails.enabled')) {
+    $thumbnailsEnabled = $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE;
+    if ($thumbnailsEnabled) {
         $thumbnailer = new Thumbnailer($conf);
     }
 
@@ -1633,7 +1635,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
 
         // Thumbnails enabled, not a note,
         // and (never retrieved yet or no valid cache file)
-        if ($conf->get('thumbnails.enabled') && $link['url'][0] != '?'
+        if ($thumbnailsEnabled && $link['url'][0] != '?'
             && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail'])))
         ) {
             $elem = $LINKSDB[$keys[$i]];
index c04b8fb56021c5d18aa34528a24a60e15db51ea9..08311545ef3b597f19d124aa7e6dc7286b69ae1d 100644 (file)
@@ -25,14 +25,20 @@ class ThumbnailerTest extends TestCase
      */
     protected $thumbnailer;
 
+    /**
+     * @var ConfigManager
+     */
+    protected $conf;
+
     public function setUp()
     {
-        $conf = new ConfigManager('tests/utils/config/configJson');
-        $conf->set('thumbnails.width', self::WIDTH);
-        $conf->set('thumbnails.height', self::HEIGHT);
-        $conf->set('dev.debug', true);
+        $this->conf = new ConfigManager('tests/utils/config/configJson');
+        $this->conf->set('thumbnails.mode', Thumbnailer::MODE_ALL);
+        $this->conf->set('thumbnails.width', self::WIDTH);
+        $this->conf->set('thumbnails.height', self::HEIGHT);
+        $this->conf->set('dev.debug', true);
 
-        $this->thumbnailer = new Thumbnailer($conf);
+        $this->thumbnailer = new Thumbnailer($this->conf);
         // cache files in the sandbox
         WTConfigManager::addFile('tests/utils/config/wt.json');
     }
@@ -43,9 +49,9 @@ class ThumbnailerTest extends TestCase
     }
 
     /**
-     * Test a thumbnail with a custom size.
+     * Test a thumbnail with a custom size in 'all' mode.
      */
-    public function testThumbnailValid()
+    public function testThumbnailAllValid()
     {
         $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/');
         $this->assertNotFalse($thumb);
@@ -54,6 +60,29 @@ class ThumbnailerTest extends TestCase
         $this->assertEquals(self::HEIGHT, imagesy($image));
     }
 
+    /**
+     * Test a thumbnail with a custom size in 'common' mode.
+     */
+    public function testThumbnailCommonValid()
+    {
+        $this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON);
+        $thumb = $this->thumbnailer->get('https://imgur.com/jlFgGpe');
+        $this->assertNotFalse($thumb);
+        $image = imagecreatefromstring(file_get_contents($thumb));
+        $this->assertEquals(self::WIDTH, imagesx($image));
+        $this->assertEquals(self::HEIGHT, imagesy($image));
+    }
+
+    /**
+     * Test a thumbnail in 'common' mode which isn't include in common websites.
+     */
+    public function testThumbnailCommonInvalid()
+    {
+        $this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON);
+        $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/');
+        $this->assertFalse($thumb);
+    }
+
     /**
      * Test a thumbnail that can't be retrieved.
      */
index 92ff569075bfd3fbf7645a673bfeabb867abf479..05f4b8e104e3eabdc0a494fc4e75cef94f038072 100644 (file)
@@ -2,6 +2,7 @@
 use Shaarli\Config\ConfigJson;
 use Shaarli\Config\ConfigManager;
 use Shaarli\Config\ConfigPhp;
+use Shaarli\Thumbnailer;
 
 require_once 'tests/Updater/DummyUpdater.php';
 require_once 'inc/rain.tpl.class.php';
@@ -696,7 +697,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;';
         $updater = new Updater([], [], $this->conf, true, $_SESSION);
         $this->assertTrue($updater->updateMethodWebThumbnailer());
         $this->assertFalse($this->conf->exists('thumbnail'));
-        $this->assertTrue($this->conf->get('thumbnails.enabled'));
+        $this->assertEquals(\Shaarli\Thumbnailer::MODE_ALL, $this->conf->get('thumbnails.mode'));
         $this->assertEquals(125, $this->conf->get('thumbnails.width'));
         $this->assertEquals(90, $this->conf->get('thumbnails.height'));
         $this->assertContains('You have enabled thumbnails', $_SESSION['warnings'][0]);
@@ -712,7 +713,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;';
         $updater = new Updater([], [], $this->conf, true, $_SESSION);
         $this->assertTrue($updater->updateMethodWebThumbnailer());
         $this->assertFalse($this->conf->exists('thumbnail'));
-        $this->assertFalse($this->conf->get('thumbnails.enabled'));
+        $this->assertEquals(Thumbnailer::MODE_NONE, $this->conf->get('thumbnails.mode'));
         $this->assertEquals(125, $this->conf->get('thumbnails.width'));
         $this->assertEquals(90, $this->conf->get('thumbnails.height'));
         $this->assertTrue(empty($_SESSION['warnings']));
@@ -726,7 +727,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;';
         $updater = new Updater([], [], $this->conf, true, $_SESSION);
         $this->assertTrue($updater->updateMethodWebThumbnailer());
         $this->assertFalse($this->conf->exists('thumbnail'));
-        $this->assertTrue($this->conf->get('thumbnails.enabled'));
+        $this->assertEquals(Thumbnailer::MODE_COMMON, $this->conf->get('thumbnails.mode'));
         $this->assertEquals(90, $this->conf->get('thumbnails.width'));
         $this->assertEquals(53, $this->conf->get('thumbnails.height'));
         $this->assertTrue(empty($_SESSION['warnings']));
index a656b67c1f8723e1fc32a46d93e579939c4ae0b8..1549ddfc500acf72602d2f351cde4c5a69af9ef0 100644 (file)
@@ -76,7 +76,7 @@
         "extensions": []
     },
     "thumbnails": {
-        "enabled": true,
+        "mode": "common",
         "width": 90,
         "height": 53
     }
index dca9503b0208063691c76d315a040a15850b2a7b..9711d151a4cfd0fd4736cb0f38a343d88ee46084 100644 (file)
         </div>
         <div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
           <div class="form-input">
-            <input type="checkbox" name="enableThumbnails" id="enableThumbnails"
-                   {if="$thumbnails_enabled"}checked{/if} {if="!$gd_enabled"}disabled{/if} />
+            <select name="enableThumbnails" id="enableThumbnails" class="align">
+              <option value="all"    {if="$thumbnails_mode=='all'"}selected{/if}>
+                {'All'|t}
+              </option>
+              <option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
+                {'Only common media hosts'|t}
+              </option>
+              <option value="none"   {if="$thumbnails_mode=='none'"}selected{/if}>
+                {'None'|t}
+              </option>
+            </select>
           </div>
         </div>
       </div>
index fc3a563b0a36a81459c9cd87beb4f5a944d917c7..9466c2354780cbdb8a8f7805041d733a4b7025fc 100644 (file)
       <tr>
         <td valign="top"><b>Enable thumbnails</b></td>
         <td>
-          <input type="checkbox" name="enableThumbnails" id="enableThumbnails"
-                 {if="$thumbnails_enabled"}checked{/if} {if="!$gd_enabled"}disabled{/if}>
+          <select name="enableThumbnails" id="enableThumbnails" class="align">
+            <option value="all"    {if="$thumbnails_mode=='all'"}selected{/if}>
+            {'All'|t}
+            </option>
+            <option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
+            {'Only common media hosts'|t}
+            </option>
+            <option value="none"   {if="$thumbnails_mode=='none'"}selected{/if}>
+            {'None'|t}
+            </option>
+          </select>
           <label for="enableThumbnails">
             {if="! $gd_enabled"}
               {'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}