aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2018-07-05 20:29:55 +0200
committerArthurHoaro <arthur@hoa.ro>2018-07-05 20:34:22 +0200
commitb302b3c584b84f22f0e6f187b072180ecbacdfab (patch)
tree297f72d8fcf6d158ebbb8198dee4e35a30ab0d7e
parentfcba541e2f12c85ac56c6915ba1319fbdd3e6962 (diff)
downloadShaarli-b302b3c584b84f22f0e6f187b072180ecbacdfab.tar.gz
Shaarli-b302b3c584b84f22f0e6f187b072180ecbacdfab.tar.zst
Shaarli-b302b3c584b84f22f0e6f187b072180ecbacdfab.zip
Thumbnails: add a common mode to only retrieve thumbs from popular media websites
-rw-r--r--application/PageBuilder.php6
-rw-r--r--application/Thumbnailer.php54
-rw-r--r--application/Updater.php5
-rw-r--r--index.php22
-rw-r--r--tests/ThumbnailerTest.php43
-rw-r--r--tests/Updater/UpdaterTest.php7
-rw-r--r--tests/utils/config/configJson.json.php2
-rw-r--r--tpl/default/configure.html13
-rw-r--r--tpl/vintage/configure.html13
9 files changed, 135 insertions, 30 deletions
diff --git a/application/PageBuilder.php b/application/PageBuilder.php
index 5da70811..b1abe0d0 100644
--- a/application/PageBuilder.php
+++ b/application/PageBuilder.php
@@ -1,6 +1,7 @@
1<?php 1<?php
2 2
3use Shaarli\Config\ConfigManager; 3use Shaarli\Config\ConfigManager;
4use Shaarli\Thumbnailer;
4 5
5/** 6/**
6 * This class is in charge of building the final page. 7 * This class is in charge of building the final page.
@@ -119,7 +120,10 @@ class PageBuilder
119 $this->tpl->assign('tags', $this->linkDB->linksCountPerTag()); 120 $this->tpl->assign('tags', $this->linkDB->linksCountPerTag());
120 } 121 }
121 122
122 $this->tpl->assign('thumbnails_enabled', $this->conf->get('thumbnails.enabled')); 123 $this->tpl->assign(
124 'thumbnails_enabled',
125 $this->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
126 );
123 $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width')); 127 $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width'));
124 $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height')); 128 $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height'));
125 129
diff --git a/application/Thumbnailer.php b/application/Thumbnailer.php
index d2284e79..7d0d9c33 100644
--- a/application/Thumbnailer.php
+++ b/application/Thumbnailer.php
@@ -14,6 +14,27 @@ use WebThumbnailer\Application\ConfigManager as WTConfigManager;
14 */ 14 */
15class Thumbnailer 15class Thumbnailer
16{ 16{
17 const COMMON_MEDIA_DOMAINS = [
18 'imgur.com',
19 'flickr.com',
20 'youtube.com',
21 'wikimedia.org',
22 'redd.it',
23 'gfycat.com',
24 'media.giphy.com',
25 'twitter.com',
26 'twimg.com',
27 'instagram.com',
28 'pinterest.com',
29 'pinterest.fr',
30 'tumblr.com',
31 'deviantart.com',
32 ];
33
34 const MODE_ALL = 'all';
35 const MODE_COMMON = 'common';
36 const MODE_NONE = 'none';
37
17 /** 38 /**
18 * @var WebThumbnailer instance. 39 * @var WebThumbnailer instance.
19 */ 40 */
@@ -57,13 +78,42 @@ class Thumbnailer
57 */ 78 */
58 public function get($url) 79 public function get($url)
59 { 80 {
81 if ($this->conf->get('thumbnails.mode') === self::MODE_COMMON
82 && ! $this->isCommonMediaOrImage($url)
83 ) {
84 return false;
85 }
86
60 try { 87 try {
61 return $this->wt->thumbnail($url); 88 return $this->wt->thumbnail($url);
62 } catch (WebThumbnailerException $e) { 89 } catch (WebThumbnailerException $e) {
63 // Exceptions are only thrown in debug mode. 90 // Exceptions are only thrown in debug mode.
64 error_log(get_class($e) .': '. $e->getMessage()); 91 error_log(get_class($e) . ': ' . $e->getMessage());
65 return false;
66 } 92 }
93 return false;
94 }
95
96 /**
97 * We check weather the given URL is from a common media domain,
98 * or if the file extension is an image.
99 *
100 * @param string $url to check
101 *
102 * @return bool true if it's an image or from a common media domain, false otherwise.
103 */
104 public function isCommonMediaOrImage($url)
105 {
106 foreach (self::COMMON_MEDIA_DOMAINS as $domain) {
107 if (strpos($url, $domain) !== false) {
108 return true;
109 }
110 }
111
112 if (endsWith($url, '.jpg') || endsWith($url, '.png') || endsWith($url, '.jpeg')) {
113 return true;
114 }
115
116 return false;
67 } 117 }
68 118
69 /** 119 /**
diff --git a/application/Updater.php b/application/Updater.php
index f6b9e205..2a4c807c 100644
--- a/application/Updater.php
+++ b/application/Updater.php
@@ -2,6 +2,7 @@
2use Shaarli\Config\ConfigJson; 2use Shaarli\Config\ConfigJson;
3use Shaarli\Config\ConfigPhp; 3use Shaarli\Config\ConfigPhp;
4use Shaarli\Config\ConfigManager; 4use Shaarli\Config\ConfigManager;
5use Shaarli\Thumbnailer;
5 6
6/** 7/**
7 * Class Updater. 8 * Class Updater.
@@ -497,12 +498,12 @@ class Updater
497 */ 498 */
498 public function updateMethodWebThumbnailer() 499 public function updateMethodWebThumbnailer()
499 { 500 {
500 if ($this->conf->exists('thumbnails.enabled')) { 501 if ($this->conf->exists('thumbnails.mode')) {
501 return true; 502 return true;
502 } 503 }
503 504
504 $thumbnailsEnabled = $this->conf->get('thumbnail.enable_thumbnails', true); 505 $thumbnailsEnabled = $this->conf->get('thumbnail.enable_thumbnails', true);
505 $this->conf->set('thumbnails.enabled', $thumbnailsEnabled); 506 $this->conf->set('thumbnails.mode', $thumbnailsEnabled ? Thumbnailer::MODE_ALL : Thumbnailer::MODE_NONE);
506 $this->conf->set('thumbnails.width', 125); 507 $this->conf->set('thumbnails.width', 125);
507 $this->conf->set('thumbnails.height', 90); 508 $this->conf->set('thumbnails.height', 90);
508 $this->conf->remove('thumbnail'); 509 $this->conf->remove('thumbnail');
diff --git a/index.php b/index.php
index d5a3e93d..299d6d9b 100644
--- a/index.php
+++ b/index.php
@@ -603,7 +603,9 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
603 // -------- Picture wall 603 // -------- Picture wall
604 if ($targetPage == Router::$PAGE_PICWALL) 604 if ($targetPage == Router::$PAGE_PICWALL)
605 { 605 {
606 if (! $conf->get('thumbnails.enabled')) { 606 $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli'));
607 if (! $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) === Thumbnailer::MODE_NONE) {
608 $PAGE->assign('linksToDisplay', []);
607 $PAGE->renderPage('picwall'); 609 $PAGE->renderPage('picwall');
608 exit; 610 exit;
609 } 611 }
@@ -630,7 +632,6 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
630 $PAGE->assign($key, $value); 632 $PAGE->assign($key, $value);
631 } 633 }
632 634
633 $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli'));
634 $PAGE->renderPage('picwall'); 635 $PAGE->renderPage('picwall');
635 exit; 636 exit;
636 } 637 }
@@ -1013,14 +1014,13 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1013 $conf->set('api.secret', escape($_POST['apiSecret'])); 1014 $conf->set('api.secret', escape($_POST['apiSecret']));
1014 $conf->set('translation.language', escape($_POST['language'])); 1015 $conf->set('translation.language', escape($_POST['language']));
1015 1016
1016 $thumbnailsEnabled = extension_loaded('gd') && !empty($_POST['enableThumbnails']); 1017 $thumbnailsMode = extension_loaded('gd') ? $_POST['enableThumbnails'] : Thumbnailer::MODE_NONE;
1017 $conf->set('thumbnails.enabled', $thumbnailsEnabled); 1018 if ($conf->get('thumbnails.enabled', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) {
1018
1019 if (! $conf->get('thumbnails.enabled') && $thumbnailsEnabled) {
1020 $_SESSION['warnings'][] = t( 1019 $_SESSION['warnings'][] = t(
1021 'You have enabled thumbnails. <a href="?do=thumbs_update">Please synchonize them</a>.' 1020 'You have enabled or changed thumbnails mode. <a href="?do=thumbs_update">Please synchonize them</a>.'
1022 ); 1021 );
1023 } 1022 }
1023 $conf->set('thumbnails.mode', $thumbnailsMode);
1024 1024
1025 try { 1025 try {
1026 $conf->write($loginManager->isLoggedIn()); 1026 $conf->write($loginManager->isLoggedIn());
@@ -1061,6 +1061,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1061 $PAGE->assign('languages', Languages::getAvailableLanguages()); 1061 $PAGE->assign('languages', Languages::getAvailableLanguages());
1062 $PAGE->assign('language', $conf->get('translation.language')); 1062 $PAGE->assign('language', $conf->get('translation.language'));
1063 $PAGE->assign('gd_enabled', extension_loaded('gd')); 1063 $PAGE->assign('gd_enabled', extension_loaded('gd'));
1064 $PAGE->assign('thumbnails_mode', $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE));
1064 $PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli')); 1065 $PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli'));
1065 $PAGE->renderPage('configure'); 1066 $PAGE->renderPage('configure');
1066 exit; 1067 exit;
@@ -1162,7 +1163,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1162 $link['title'] = $link['url']; 1163 $link['title'] = $link['url'];
1163 } 1164 }
1164 1165
1165 if ($conf->get('thumbnails.enabled')) { 1166 if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) {
1166 $thumbnailer = new Thumbnailer($conf); 1167 $thumbnailer = new Thumbnailer($conf);
1167 $link['thumbnail'] = $thumbnailer->get($url); 1168 $link['thumbnail'] = $thumbnailer->get($url);
1168 } 1169 }
@@ -1606,7 +1607,8 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
1606 $i = ($page-1) * $_SESSION['LINKS_PER_PAGE']; 1607 $i = ($page-1) * $_SESSION['LINKS_PER_PAGE'];
1607 $end = $i + $_SESSION['LINKS_PER_PAGE']; 1608 $end = $i + $_SESSION['LINKS_PER_PAGE'];
1608 1609
1609 if ($conf->get('thumbnails.enabled')) { 1610 $thumbnailsEnabled = $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE;
1611 if ($thumbnailsEnabled) {
1610 $thumbnailer = new Thumbnailer($conf); 1612 $thumbnailer = new Thumbnailer($conf);
1611 } 1613 }
1612 1614
@@ -1633,7 +1635,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
1633 1635
1634 // Thumbnails enabled, not a note, 1636 // Thumbnails enabled, not a note,
1635 // and (never retrieved yet or no valid cache file) 1637 // and (never retrieved yet or no valid cache file)
1636 if ($conf->get('thumbnails.enabled') && $link['url'][0] != '?' 1638 if ($thumbnailsEnabled && $link['url'][0] != '?'
1637 && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail']))) 1639 && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail'])))
1638 ) { 1640 ) {
1639 $elem = $LINKSDB[$keys[$i]]; 1641 $elem = $LINKSDB[$keys[$i]];
diff --git a/tests/ThumbnailerTest.php b/tests/ThumbnailerTest.php
index c04b8fb5..08311545 100644
--- a/tests/ThumbnailerTest.php
+++ b/tests/ThumbnailerTest.php
@@ -25,14 +25,20 @@ class ThumbnailerTest extends TestCase
25 */ 25 */
26 protected $thumbnailer; 26 protected $thumbnailer;
27 27
28 /**
29 * @var ConfigManager
30 */
31 protected $conf;
32
28 public function setUp() 33 public function setUp()
29 { 34 {
30 $conf = new ConfigManager('tests/utils/config/configJson'); 35 $this->conf = new ConfigManager('tests/utils/config/configJson');
31 $conf->set('thumbnails.width', self::WIDTH); 36 $this->conf->set('thumbnails.mode', Thumbnailer::MODE_ALL);
32 $conf->set('thumbnails.height', self::HEIGHT); 37 $this->conf->set('thumbnails.width', self::WIDTH);
33 $conf->set('dev.debug', true); 38 $this->conf->set('thumbnails.height', self::HEIGHT);
39 $this->conf->set('dev.debug', true);
34 40
35 $this->thumbnailer = new Thumbnailer($conf); 41 $this->thumbnailer = new Thumbnailer($this->conf);
36 // cache files in the sandbox 42 // cache files in the sandbox
37 WTConfigManager::addFile('tests/utils/config/wt.json'); 43 WTConfigManager::addFile('tests/utils/config/wt.json');
38 } 44 }
@@ -43,9 +49,9 @@ class ThumbnailerTest extends TestCase
43 } 49 }
44 50
45 /** 51 /**
46 * Test a thumbnail with a custom size. 52 * Test a thumbnail with a custom size in 'all' mode.
47 */ 53 */
48 public function testThumbnailValid() 54 public function testThumbnailAllValid()
49 { 55 {
50 $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/'); 56 $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/');
51 $this->assertNotFalse($thumb); 57 $this->assertNotFalse($thumb);
@@ -55,6 +61,29 @@ class ThumbnailerTest extends TestCase
55 } 61 }
56 62
57 /** 63 /**
64 * Test a thumbnail with a custom size in 'common' mode.
65 */
66 public function testThumbnailCommonValid()
67 {
68 $this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON);
69 $thumb = $this->thumbnailer->get('https://imgur.com/jlFgGpe');
70 $this->assertNotFalse($thumb);
71 $image = imagecreatefromstring(file_get_contents($thumb));
72 $this->assertEquals(self::WIDTH, imagesx($image));
73 $this->assertEquals(self::HEIGHT, imagesy($image));
74 }
75
76 /**
77 * Test a thumbnail in 'common' mode which isn't include in common websites.
78 */
79 public function testThumbnailCommonInvalid()
80 {
81 $this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON);
82 $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/');
83 $this->assertFalse($thumb);
84 }
85
86 /**
58 * Test a thumbnail that can't be retrieved. 87 * Test a thumbnail that can't be retrieved.
59 */ 88 */
60 public function testThumbnailNotValid() 89 public function testThumbnailNotValid()
diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php
index 92ff5690..05f4b8e1 100644
--- a/tests/Updater/UpdaterTest.php
+++ b/tests/Updater/UpdaterTest.php
@@ -2,6 +2,7 @@
2use Shaarli\Config\ConfigJson; 2use Shaarli\Config\ConfigJson;
3use Shaarli\Config\ConfigManager; 3use Shaarli\Config\ConfigManager;
4use Shaarli\Config\ConfigPhp; 4use Shaarli\Config\ConfigPhp;
5use Shaarli\Thumbnailer;
5 6
6require_once 'tests/Updater/DummyUpdater.php'; 7require_once 'tests/Updater/DummyUpdater.php';
7require_once 'inc/rain.tpl.class.php'; 8require_once 'inc/rain.tpl.class.php';
@@ -696,7 +697,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;';
696 $updater = new Updater([], [], $this->conf, true, $_SESSION); 697 $updater = new Updater([], [], $this->conf, true, $_SESSION);
697 $this->assertTrue($updater->updateMethodWebThumbnailer()); 698 $this->assertTrue($updater->updateMethodWebThumbnailer());
698 $this->assertFalse($this->conf->exists('thumbnail')); 699 $this->assertFalse($this->conf->exists('thumbnail'));
699 $this->assertTrue($this->conf->get('thumbnails.enabled')); 700 $this->assertEquals(\Shaarli\Thumbnailer::MODE_ALL, $this->conf->get('thumbnails.mode'));
700 $this->assertEquals(125, $this->conf->get('thumbnails.width')); 701 $this->assertEquals(125, $this->conf->get('thumbnails.width'));
701 $this->assertEquals(90, $this->conf->get('thumbnails.height')); 702 $this->assertEquals(90, $this->conf->get('thumbnails.height'));
702 $this->assertContains('You have enabled thumbnails', $_SESSION['warnings'][0]); 703 $this->assertContains('You have enabled thumbnails', $_SESSION['warnings'][0]);
@@ -712,7 +713,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;';
712 $updater = new Updater([], [], $this->conf, true, $_SESSION); 713 $updater = new Updater([], [], $this->conf, true, $_SESSION);
713 $this->assertTrue($updater->updateMethodWebThumbnailer()); 714 $this->assertTrue($updater->updateMethodWebThumbnailer());
714 $this->assertFalse($this->conf->exists('thumbnail')); 715 $this->assertFalse($this->conf->exists('thumbnail'));
715 $this->assertFalse($this->conf->get('thumbnails.enabled')); 716 $this->assertEquals(Thumbnailer::MODE_NONE, $this->conf->get('thumbnails.mode'));
716 $this->assertEquals(125, $this->conf->get('thumbnails.width')); 717 $this->assertEquals(125, $this->conf->get('thumbnails.width'));
717 $this->assertEquals(90, $this->conf->get('thumbnails.height')); 718 $this->assertEquals(90, $this->conf->get('thumbnails.height'));
718 $this->assertTrue(empty($_SESSION['warnings'])); 719 $this->assertTrue(empty($_SESSION['warnings']));
@@ -726,7 +727,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;';
726 $updater = new Updater([], [], $this->conf, true, $_SESSION); 727 $updater = new Updater([], [], $this->conf, true, $_SESSION);
727 $this->assertTrue($updater->updateMethodWebThumbnailer()); 728 $this->assertTrue($updater->updateMethodWebThumbnailer());
728 $this->assertFalse($this->conf->exists('thumbnail')); 729 $this->assertFalse($this->conf->exists('thumbnail'));
729 $this->assertTrue($this->conf->get('thumbnails.enabled')); 730 $this->assertEquals(Thumbnailer::MODE_COMMON, $this->conf->get('thumbnails.mode'));
730 $this->assertEquals(90, $this->conf->get('thumbnails.width')); 731 $this->assertEquals(90, $this->conf->get('thumbnails.width'));
731 $this->assertEquals(53, $this->conf->get('thumbnails.height')); 732 $this->assertEquals(53, $this->conf->get('thumbnails.height'));
732 $this->assertTrue(empty($_SESSION['warnings'])); 733 $this->assertTrue(empty($_SESSION['warnings']));
diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php
index a656b67c..1549ddfc 100644
--- a/tests/utils/config/configJson.json.php
+++ b/tests/utils/config/configJson.json.php
@@ -76,7 +76,7 @@
76 "extensions": [] 76 "extensions": []
77 }, 77 },
78 "thumbnails": { 78 "thumbnails": {
79 "enabled": true, 79 "mode": "common",
80 "width": 90, 80 "width": 90,
81 "height": 53 81 "height": 53
82 } 82 }
diff --git a/tpl/default/configure.html b/tpl/default/configure.html
index dca9503b..9711d151 100644
--- a/tpl/default/configure.html
+++ b/tpl/default/configure.html
@@ -259,8 +259,17 @@
259 </div> 259 </div>
260 <div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}"> 260 <div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
261 <div class="form-input"> 261 <div class="form-input">
262 <input type="checkbox" name="enableThumbnails" id="enableThumbnails" 262 <select name="enableThumbnails" id="enableThumbnails" class="align">
263 {if="$thumbnails_enabled"}checked{/if} {if="!$gd_enabled"}disabled{/if} /> 263 <option value="all" {if="$thumbnails_mode=='all'"}selected{/if}>
264 {'All'|t}
265 </option>
266 <option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
267 {'Only common media hosts'|t}
268 </option>
269 <option value="none" {if="$thumbnails_mode=='none'"}selected{/if}>
270 {'None'|t}
271 </option>
272 </select>
264 </div> 273 </div>
265 </div> 274 </div>
266 </div> 275 </div>
diff --git a/tpl/vintage/configure.html b/tpl/vintage/configure.html
index fc3a563b..9466c235 100644
--- a/tpl/vintage/configure.html
+++ b/tpl/vintage/configure.html
@@ -131,8 +131,17 @@
131 <tr> 131 <tr>
132 <td valign="top"><b>Enable thumbnails</b></td> 132 <td valign="top"><b>Enable thumbnails</b></td>
133 <td> 133 <td>
134 <input type="checkbox" name="enableThumbnails" id="enableThumbnails" 134 <select name="enableThumbnails" id="enableThumbnails" class="align">
135 {if="$thumbnails_enabled"}checked{/if} {if="!$gd_enabled"}disabled{/if}> 135 <option value="all" {if="$thumbnails_mode=='all'"}selected{/if}>
136 {'All'|t}
137 </option>
138 <option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
139 {'Only common media hosts'|t}
140 </option>
141 <option value="none" {if="$thumbnails_mode=='none'"}selected{/if}>
142 {'None'|t}
143 </option>
144 </select>
136 <label for="enableThumbnails"> 145 <label for="enableThumbnails">
137 {if="! $gd_enabled"} 146 {if="! $gd_enabled"}
138 {'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t} 147 {'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}