From 1b93137e16694f52952c930848e1a7928e8a00a6 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 9 Nov 2016 18:57:02 +0100 Subject: [PATCH 1/9] Use web-thumbnailer to retrieve thumbnails * requires PHP 5.6 * use blazy on linklist since a lot more thumbs are retrieved * thumbnails can be disabled * thumbs size is now 120x120 * thumbs are now cropped to fit the expected size Fixes #345 #425 #487 #543 #588 #590 --- application/PageBuilder.php | 5 + application/Thumbnailer.php | 49 +++ application/config/ConfigManager.php | 4 + assets/vintage/css/shaarli.css | 8 +- composer.json | 1 + inc/web-thumbnailer.json | 9 + index.php | 490 ++++--------------------- tests/ThumbnailerTest.php | 51 +++ tests/utils/config/configJson.json.php | 3 + tpl/vintage/configure.html | 12 + tpl/vintage/linklist.html | 11 +- tpl/vintage/picwall.html | 6 +- 12 files changed, 222 insertions(+), 427 deletions(-) create mode 100644 application/Thumbnailer.php create mode 100644 inc/web-thumbnailer.json create mode 100644 tests/ThumbnailerTest.php diff --git a/application/PageBuilder.php b/application/PageBuilder.php index a448387..3dba767 100644 --- a/application/PageBuilder.php +++ b/application/PageBuilder.php @@ -105,6 +105,11 @@ class PageBuilder if ($this->linkDB !== null) { $this->tpl->assign('tags', $this->linkDB->linksCountPerTag()); } + + $this->tpl->assign('thumbnails_enabled', $this->conf->get('thumbnails.enabled')); + $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width')); + $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height')); + // To be removed with a proper theme configuration. $this->tpl->assign('conf', $this->conf); } diff --git a/application/Thumbnailer.php b/application/Thumbnailer.php new file mode 100644 index 0000000..b669ada --- /dev/null +++ b/application/Thumbnailer.php @@ -0,0 +1,49 @@ +conf = $conf; + $this->wt = new WebThumbnailer(); + \WebThumbnailer\Application\ConfigManager::addFile('inc/web-thumbnailer.json'); + $this->wt->maxWidth($this->conf->get('thumbnails.width')) + ->maxHeight($this->conf->get('thumbnails.height')) + ->crop(true) + ->debug($this->conf->get('dev.debug', false)); + } + + /** + * Retrieve a thumbnail for given URL + * + * @param string $url where to look for a thumbnail. + * + * @return bool|string The thumbnail relative cache file path, or false if none has been found. + */ + public function get($url) + { + return $this->wt->thumbnail($url); + } +} diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php index 82f4a36..124fedc 100644 --- a/application/config/ConfigManager.php +++ b/application/config/ConfigManager.php @@ -319,6 +319,10 @@ class ConfigManager $this->setEmpty('general.enabled_plugins', self::$DEFAULT_PLUGINS); $this->setEmpty('general.default_note_title', 'Note: '); + $this->setEmpty('thumbnails.enabled', true); + $this->setEmpty('thumbnails.width', 120); + $this->setEmpty('thumbnails.height', 120); + $this->setEmpty('updates.check_updates', false); $this->setEmpty('updates.check_updates_branch', 'stable'); $this->setEmpty('updates.check_updates_interval', 86400); diff --git a/assets/vintage/css/shaarli.css b/assets/vintage/css/shaarli.css index c919339..05e2c17 100644 --- a/assets/vintage/css/shaarli.css +++ b/assets/vintage/css/shaarli.css @@ -701,8 +701,8 @@ a.bigbutton, #pageheader a.bigbutton { position: relative; display: table-cell; vertical-align: middle; - width: 90px; - height: 90px; + width: 120px; + height: 120px; overflow: hidden; text-align: center; float: left; @@ -739,9 +739,9 @@ a.bigbutton, #pageheader a.bigbutton { position: absolute; top: 0; left: 0; - width: 90px; + width: 120px; font-weight: bold; - font-size: 8pt; + font-size: 9pt; color: #fff; text-align: left; background-color: transparent; diff --git a/composer.json b/composer.json index 0d4c623..983bf9e 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "shaarli/netscape-bookmark-parser": "^2.0", "erusev/parsedown": "^1.6", "slim/slim": "^3.0", + "arthurhoaro/web-thumbnailer": "dev-master", "pubsubhubbub/publisher": "dev-master", "gettext/gettext": "^4.4" }, diff --git a/inc/web-thumbnailer.json b/inc/web-thumbnailer.json new file mode 100644 index 0000000..8a19f07 --- /dev/null +++ b/inc/web-thumbnailer.json @@ -0,0 +1,9 @@ +{ + "settings": { + "default": { + "_comment": "infinite cache", + "cache_duration": -1, + "timeout": 60 + } + } +} \ No newline at end of file diff --git a/index.php b/index.php index ddd5dbf..28dfd3b 100644 --- a/index.php +++ b/index.php @@ -74,6 +74,7 @@ require_once 'application/Url.php'; require_once 'application/Utils.php'; require_once 'application/PluginManager.php'; require_once 'application/Router.php'; +require_once 'application/Thumbnailer.php'; require_once 'application/Updater.php'; use \Shaarli\Languages; use \Shaarli\ThemeUtils; @@ -601,20 +602,52 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, // -------- Picture wall if ($targetPage == Router::$PAGE_PICWALL) { + if (! $conf->get('thumbnails.enabled')) { + header('Location: ?'); + exit; + } + // Optionally filter the results: $links = $LINKSDB->filterSearch($_GET); $linksToDisplay = array(); + $thumbnailer = new Thumbnailer($conf); + + + $cpt = 0; // Get only links which have a thumbnail. foreach($links as $link) { $permalink='?'.$link['shorturl']; - $thumb=lazyThumbnail($conf, $link['url'],$permalink); - if ($thumb!='') // Only output links which have a thumbnail. - { - $link['thumbnail']=$thumb; // Thumbnail HTML code. - $linksToDisplay[]=$link; // Add to array. + // Not a note, + // and (never retrieved yet or no valid cache file) + if ($link['url'][0] != '?' + && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail']))) + ) { + $link['thumbnail'] = $thumbnailer->get($link['url']); + // FIXME! we really need to get rid of ArrayAccess... + $item = $LINKSDB[$link['linkdate']]; + $item['thumbnail'] = $link['thumbnail']; + $LINKSDB[$link['linkdate']] = $item; + $updateDB = true; + $cpt++; } + + if (isset($link['thumbnail']) && $link['thumbnail'] !== false) { + $linksToDisplay[] = $link; // Add to array. + } + + // If we retrieved new thumbnails, we update the database every 20 links. + // Downloading everything the first time may take a very long time + if (!empty($updateDB) && $cpt == 20) { + $LINKSDB->save($conf->get('resource.page_cache')); + $updateDB = false; + $cpt = 0; + } + } + + if (!empty($updateDB)) { + $LINKSDB->save($conf->get('resource.page_cache')); } $data = array( @@ -1008,6 +1041,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $conf->set('api.enabled', !empty($_POST['enableApi'])); $conf->set('api.secret', escape($_POST['apiSecret'])); $conf->set('translation.language', escape($_POST['language'])); + $conf->set('thumbnails.enabled', !empty($_POST['enableThumbnails'])); try { $conf->write($loginManager->isLoggedIn()); @@ -1148,6 +1182,11 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $link['title'] = $link['url']; } + if ($conf->get('thumbnails.enabled')) { + $thumbnailer = new Thumbnailer($conf); + $link['thumbnail'] = $thumbnailer->get($url); + } + $pluginManager->executeHooks('save_link', $link); $LINKSDB[$id] = $link; @@ -1549,6 +1588,11 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) // Start index. $i = ($page-1) * $_SESSION['LINKS_PER_PAGE']; $end = $i + $_SESSION['LINKS_PER_PAGE']; + + if ($conf->get('thumbnails.enabled')) { + $thumbnailer = new Thumbnailer($conf); + } + $linkDisp = array(); while ($i<$end && $iget('thumbnails.enabled') && $link['url'][0] != '?' + && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail']))) + ) { + $link['thumbnail'] = $thumbnailer->get($link['url']); + // FIXME! we really need to get rid of ArrayAccess... + $item = $LINKSDB[$keys[$i]]; + $item['thumbnail'] = $link['thumbnail']; + $LINKSDB[$keys[$i]] = $item; + $updateDB = true; + } + // Check for both signs of a note: starting with ? and 7 chars long. - if ($link['url'][0] === '?' && - strlen($link['url']) === 7) { + if ($link['url'][0] === '?' && strlen($link['url']) === 7) { $link['url'] = index_url($_SERVER) . $link['url']; } @@ -1579,6 +1636,11 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) $i++; } + // If we retrieved new thumbnails, we update the database. + if (!empty($updateDB)) { + $LINKSDB->save($conf->get('resource.page_cache')); + } + // Compute paging navigation $searchtagsUrl = $searchtags === '' ? '' : '&searchtags=' . urlencode($searchtags); $searchtermUrl = empty($searchterm) ? '' : '&searchterm=' . urlencode($searchterm); @@ -1629,194 +1691,6 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) return; } -/** - * Compute the thumbnail for a link. - * - * With a link to the original URL. - * Understands various services (youtube.com...) - * Input: $url = URL for which the thumbnail must be found. - * $href = if provided, this URL will be followed instead of $url - * Returns an associative array with thumbnail attributes (src,href,width,height,style,alt) - * Some of them may be missing. - * Return an empty array if no thumbnail available. - * - * @param ConfigManager $conf Configuration Manager instance. - * @param string $url - * @param string|bool $href - * - * @return array - */ -function computeThumbnail($conf, $url, $href = false) -{ - if (!$conf->get('thumbnail.enable_thumbnails')) return array(); - if ($href==false) $href=$url; - - // For most hosts, the URL of the thumbnail can be easily deduced from the URL of the link. - // (e.g. http://www.youtube.com/watch?v=spVypYk4kto ---> http://img.youtube.com/vi/spVypYk4kto/default.jpg ) - // ^^^^^^^^^^^ ^^^^^^^^^^^ - $domain = parse_url($url,PHP_URL_HOST); - if ($domain=='youtube.com' || $domain=='www.youtube.com') - { - parse_str(parse_url($url,PHP_URL_QUERY), $params); // Extract video ID and get thumbnail - if (!empty($params['v'])) return array('src'=>'https://img.youtube.com/vi/'.$params['v'].'/default.jpg', - 'href'=>$href,'width'=>'120','height'=>'90','alt'=>'YouTube thumbnail'); - } - if ($domain=='youtu.be') // Youtube short links - { - $path = parse_url($url,PHP_URL_PATH); - return array('src'=>'https://img.youtube.com/vi'.$path.'/default.jpg', - 'href'=>$href,'width'=>'120','height'=>'90','alt'=>'YouTube thumbnail'); - } - if ($domain=='pix.toile-libre.org') // pix.toile-libre.org image hosting - { - parse_str(parse_url($url,PHP_URL_QUERY), $params); // Extract image filename. - if (!empty($params) && !empty($params['img'])) return array('src'=>'http://pix.toile-libre.org/upload/thumb/'.urlencode($params['img']), - 'href'=>$href,'style'=>'max-width:120px; max-height:150px','alt'=>'pix.toile-libre.org thumbnail'); - } - - if ($domain=='imgur.com') - { - $path = parse_url($url,PHP_URL_PATH); - if (startsWith($path,'/a/')) return array(); // Thumbnails for albums are not available. - if (startsWith($path,'/r/')) return array('src'=>'https://i.imgur.com/'.basename($path).'s.jpg', - 'href'=>$href,'width'=>'90','height'=>'90','alt'=>'imgur.com thumbnail'); - if (startsWith($path,'/gallery/')) return array('src'=>'https://i.imgur.com'.substr($path,8).'s.jpg', - 'href'=>$href,'width'=>'90','height'=>'90','alt'=>'imgur.com thumbnail'); - - if (substr_count($path,'/')==1) return array('src'=>'https://i.imgur.com/'.substr($path,1).'s.jpg', - 'href'=>$href,'width'=>'90','height'=>'90','alt'=>'imgur.com thumbnail'); - } - if ($domain=='i.imgur.com') - { - $pi = pathinfo(parse_url($url,PHP_URL_PATH)); - if (!empty($pi['filename'])) return array('src'=>'https://i.imgur.com/'.$pi['filename'].'s.jpg', - 'href'=>$href,'width'=>'90','height'=>'90','alt'=>'imgur.com thumbnail'); - } - if ($domain=='dailymotion.com' || $domain=='www.dailymotion.com') - { - if (strpos($url,'dailymotion.com/video/')!==false) - { - $thumburl=str_replace('dailymotion.com/video/','dailymotion.com/thumbnail/video/',$url); - return array('src'=>$thumburl, - 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'DailyMotion thumbnail'); - } - } - if (endsWith($domain,'.imageshack.us')) - { - $ext=strtolower(pathinfo($url,PATHINFO_EXTENSION)); - if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') - { - $thumburl = substr($url,0,strlen($url)-strlen($ext)).'th.'.$ext; - return array('src'=>$thumburl, - 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'imageshack.us thumbnail'); - } - } - - // Some other hosts are SLOW AS HELL and usually require an extra HTTP request to get the thumbnail URL. - // So we deport the thumbnail generation in order not to slow down page generation - // (and we also cache the thumbnail) - - if (! $conf->get('thumbnail.enable_localcache')) return array(); // If local cache is disabled, no thumbnails for services which require the use a local cache. - - if ($domain=='flickr.com' || endsWith($domain,'.flickr.com') - || $domain=='vimeo.com' - || $domain=='ted.com' || endsWith($domain,'.ted.com') - || $domain=='xkcd.com' || endsWith($domain,'.xkcd.com') - ) - { - if ($domain=='vimeo.com') - { // Make sure this vimeo URL points to a video (/xxx... where xxx is numeric) - $path = parse_url($url,PHP_URL_PATH); - if (!preg_match('!/\d+.+?!',$path)) return array(); // This is not a single video URL. - } - if ($domain=='xkcd.com' || endsWith($domain,'.xkcd.com')) - { // Make sure this URL points to a single comic (/xxx... where xxx is numeric) - $path = parse_url($url,PHP_URL_PATH); - if (!preg_match('!/\d+.+?!',$path)) return array(); - } - if ($domain=='ted.com' || endsWith($domain,'.ted.com')) - { // Make sure this TED URL points to a video (/talks/...) - $path = parse_url($url,PHP_URL_PATH); - if ("/talks/" !== substr($path,0,7)) return array(); // This is not a single video URL. - } - $sign = hash_hmac('sha256', $url, $conf->get('credentials.salt')); // We use the salt to sign data (it's random, secret, and specific to each installation) - return array('src'=>index_url($_SERVER).'?do=genthumbnail&hmac='.$sign.'&url='.urlencode($url), - 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'thumbnail'); - } - - // For all other, we try to make a thumbnail of links ending with .jpg/jpeg/png/gif - // Technically speaking, we should download ALL links and check their Content-Type to see if they are images. - // But using the extension will do. - $ext=strtolower(pathinfo($url,PATHINFO_EXTENSION)); - if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') - { - $sign = hash_hmac('sha256', $url, $conf->get('credentials.salt')); // We use the salt to sign data (it's random, secret, and specific to each installation) - return array('src'=>index_url($_SERVER).'?do=genthumbnail&hmac='.$sign.'&url='.urlencode($url), - 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'thumbnail'); - } - return array(); // No thumbnail. - -} - - -// Returns the HTML code to display a thumbnail for a link -// with a link to the original URL. -// Understands various services (youtube.com...) -// Input: $url = URL for which the thumbnail must be found. -// $href = if provided, this URL will be followed instead of $url -// Returns '' if no thumbnail available. -function thumbnail($url,$href=false) -{ - // FIXME! - global $conf; - $t = computeThumbnail($conf, $url,$href); - if (count($t)==0) return ''; // Empty array = no thumbnail for this URL. - - $html=''; - - // Lazy image - $html.='get('credentials.salt')); - if ($sign!=$_GET['hmac']) die('Naughty boy!'); - - $cacheDir = $conf->get('resource.thumbnails_cache', 'cache'); - // Let's see if we don't already have the image for this URL in the cache. - $thumbname=hash('sha1',$_GET['url']).'.jpg'; - if (is_file($cacheDir .'/'. $thumbname)) - { // We have the thumbnail, just serve it: - header('Content-Type: image/jpeg'); - echo file_get_contents($cacheDir .'/'. $thumbname); - return; - } - // We may also serve a blank image (if service did not respond) - $blankname=hash('sha1',$_GET['url']).'.gif'; - if (is_file($cacheDir .'/'. $blankname)) - { - header('Content-Type: image/gif'); - echo file_get_contents($cacheDir .'/'. $blankname); - return; - } - - // Otherwise, generate the thumbnail. - $url = $_GET['url']; - $domain = parse_url($url,PHP_URL_HOST); - - if ($domain=='flickr.com' || endsWith($domain,'.flickr.com')) - { - // Crude replacement to handle new flickr domain policy (They prefer www. now) - $url = str_replace('http://flickr.com/','http://www.flickr.com/',$url); - - // Is this a link to an image, or to a flickr page ? - $imageurl=''; - if (endsWith(parse_url($url, PHP_URL_PATH), '.jpg')) - { // This is a direct link to an image. e.g. http://farm1.staticflickr.com/5/5921913_ac83ed27bd_o.jpg - preg_match('!(http://farm\d+\.staticflickr\.com/\d+/\d+_\w+_)\w.jpg!',$url,$matches); - if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; - } - else // This is a flickr page (html) - { - // Get the flickr html page. - list($headers, $content) = get_http_response($url, 20); - if (strpos($headers[0], '200 OK') !== false) - { - // flickr now nicely provides the URL of the thumbnail in each flickr page. - preg_match('! - if ($imageurl=='') - { - preg_match('! tag on that page - // http://www.ted.com/talks/mikko_hypponen_fighting_viruses_defending_the_net.html - // - list($headers, $content) = get_http_response($url, 5); - if (strpos($headers[0], '200 OK') !== false) { - // Extract the link to the thumbnail - preg_match('!link rel="image_src" href="(http://images.ted.com/images/ted/.+_\d+x\d+\.jpg)"!', $content, $matches); - if (!empty($matches[1])) - { // Let's download the image. - $imageurl=$matches[1]; - // No control on image size, so wait long enough - list($headers, $content) = get_http_response($imageurl, 20); - if (strpos($headers[0], '200 OK') !== false) { - $filepath = $cacheDir .'/'. $thumbname; - file_put_contents($filepath, $content); // Save image to cache. - if (resizeImage($filepath)) - { - header('Content-Type: image/jpeg'); - echo file_get_contents($filepath); - return; - } - } - } - } - } - - elseif ($domain=='xkcd.com' || endsWith($domain,'.xkcd.com')) - { - // There is no thumbnail available for xkcd comics, so download the whole image and resize it. - // http://xkcd.com/327/ - // <BLABLA> - list($headers, $content) = get_http_response($url, 5); - if (strpos($headers[0], '200 OK') !== false) { - // Extract the link to the thumbnail - preg_match('! diff --git a/tpl/vintage/configure.html b/tpl/vintage/configure.html index 479284e..e47c71a 100644 --- a/tpl/vintage/configure.html +++ b/tpl/vintage/configure.html @@ -128,6 +128,18 @@ + + Enable thumbnails + + + + + diff --git a/tpl/vintage/linklist.html b/tpl/vintage/linklist.html index 1ca51be..9bdafa8 100644 --- a/tpl/vintage/linklist.html +++ b/tpl/vintage/linklist.html @@ -80,7 +80,16 @@ {loop="$links"} -
{$value.url|thumbnail}
+ {if="$thumbnails_enabled && !empty($value.thumbnail)"} + + {/if} {/if} +{if="!empty($global_warnings) && $is_logged_in"} +
+
+
+ {loop="global_warnings"} +

{$value}

+ {/loop} +
+
+ +
+
+{/if} +
diff --git a/tpl/default/thumbnails.html b/tpl/default/thumbnails.html new file mode 100644 index 0000000..a8cf904 --- /dev/null +++ b/tpl/default/thumbnails.html @@ -0,0 +1,48 @@ + + + + {include="includes"} + + +{include="page.header"} + +
+
+
+

{'Thumbnails update'|t}

+ +
+
+
+
+
+
+ +
+
+
+ + +
+
+
+
+
+ +
+
+
+
+ 0 / {$ids|count} +
+
+
+ + +
+
+ +{include="page.footer"} + + + diff --git a/tpl/vintage/configure.html b/tpl/vintage/configure.html index e47c71a..fc3a563 100644 --- a/tpl/vintage/configure.html +++ b/tpl/vintage/configure.html @@ -132,11 +132,13 @@ Enable thumbnails + {if="$thumbnails_enabled"}checked{/if} {if="!$gd_enabled"}disabled{/if}> diff --git a/tpl/vintage/thumbnails.html b/tpl/vintage/thumbnails.html new file mode 100644 index 0000000..79aebf8 --- /dev/null +++ b/tpl/vintage/thumbnails.html @@ -0,0 +1,28 @@ + + +{include="includes"} + + + +
+
+ + + +
+
+
+ +
+ 0 / {$ids|count} +
+
+ + + +{include="page.footer"} + + + diff --git a/webpack.config.js b/webpack.config.js index 1fc5d01..ed548c7 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -24,6 +24,7 @@ module.exports = [ { entry: { thumbnails: './assets/common/js/thumbnails.js', + thumbnails_update: './assets/common/js/thumbnails-update.js', pluginsadmin: './assets/default/js/plugins-admin.js', shaarli: [ './assets/default/js/base.js', @@ -97,6 +98,7 @@ module.exports = [ './assets/vintage/css/shaarli.css', ].concat(glob.sync('./assets/vintage/img/*')), thumbnails: './assets/common/js/thumbnails.js', + thumbnails_update: './assets/common/js/thumbnails-update.js', }, output: { filename: '[name].min.js', From fcba541e2f12c85ac56c6915ba1319fbdd3e6962 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sun, 1 Jul 2018 11:44:35 +0200 Subject: [PATCH 7/9] Bump WT version --- composer.lock | 179 ++++++++++++++++++++------------------- tpl/default/picwall.html | 4 +- 2 files changed, 92 insertions(+), 91 deletions(-) diff --git a/composer.lock b/composer.lock index 43c4ba6..5ba4bdc 100644 --- a/composer.lock +++ b/composer.lock @@ -8,20 +8,21 @@ "packages": [ { "name": "arthurhoaro/web-thumbnailer", - "version": "v1.1.2", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/ArthurHoaro/web-thumbnailer.git", - "reference": "21cf6493014cb0949a7485bfc170763d964aefd4" + "reference": "d6bc683c7081ee6a0bdedc317ad88a9d9cddc4d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ArthurHoaro/web-thumbnailer/zipball/21cf6493014cb0949a7485bfc170763d964aefd4", - "reference": "21cf6493014cb0949a7485bfc170763d964aefd4", + "url": "https://api.github.com/repos/ArthurHoaro/web-thumbnailer/zipball/d6bc683c7081ee6a0bdedc317ad88a9d9cddc4d6", + "reference": "d6bc683c7081ee6a0bdedc317ad88a9d9cddc4d6", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=5.6", + "phpunit/php-text-template": "^1.2" }, "conflict": { "phpunit/php-timer": ">=2" @@ -51,7 +52,7 @@ } ], "description": "PHP library which will retrieve a thumbnail for any given URL", - "time": "2018-05-05T10:32:59+00:00" + "time": "2018-06-30T12:12:07+00:00" }, { "name": "container-interop/container-interop", @@ -132,16 +133,16 @@ }, { "name": "gettext/gettext", - "version": "v4.5.0", + "version": "v4.6.0", "source": { "type": "git", "url": "https://github.com/oscarotero/Gettext.git", - "reference": "81c05cb213e8e4828db7aabd9dd363367ebca9f2" + "reference": "cae84aff39a87e07bd6e5cddb5adb720a0ffa357" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/oscarotero/Gettext/zipball/81c05cb213e8e4828db7aabd9dd363367ebca9f2", - "reference": "81c05cb213e8e4828db7aabd9dd363367ebca9f2", + "url": "https://api.github.com/repos/oscarotero/Gettext/zipball/cae84aff39a87e07bd6e5cddb5adb720a0ffa357", + "reference": "cae84aff39a87e07bd6e5cddb5adb720a0ffa357", "shasum": "" }, "require": { @@ -150,7 +151,7 @@ }, "require-dev": { "illuminate/view": "*", - "phpunit/phpunit": "^4.8|^5.7", + "phpunit/phpunit": "^4.8|^5.7|^6.5", "squizlabs/php_codesniffer": "^3.0", "symfony/yaml": "~2", "twig/extensions": "*", @@ -190,20 +191,20 @@ "po", "translation" ], - "time": "2018-04-23T17:22:10+00:00" + "time": "2018-06-26T16:51:09+00:00" }, { "name": "gettext/languages", - "version": "2.3.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/mlocati/cldr-to-gettext-plural-rules.git", - "reference": "49c39e51569963cc917a924b489e7025bfb9d8c7" + "reference": "1b74377bd0c4cd87e8d72b948f5d8867e23505a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mlocati/cldr-to-gettext-plural-rules/zipball/49c39e51569963cc917a924b489e7025bfb9d8c7", - "reference": "49c39e51569963cc917a924b489e7025bfb9d8c7", + "url": "https://api.github.com/repos/mlocati/cldr-to-gettext-plural-rules/zipball/1b74377bd0c4cd87e8d72b948f5d8867e23505a5", + "reference": "1b74377bd0c4cd87e8d72b948f5d8867e23505a5", "shasum": "" }, "require": { @@ -251,7 +252,7 @@ "translations", "unicode" ], - "time": "2017-03-23T17:02:28+00:00" + "time": "2018-06-21T15:58:36+00:00" }, { "name": "katzgrau/klogger", @@ -349,6 +350,47 @@ ], "time": "2018-02-13T20:26:39+00:00" }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, { "name": "pimple/pimple", "version": "v3.2.3", @@ -1240,47 +1282,6 @@ ], "time": "2017-11-27T13:52:08+00:00" }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" - }, { "name": "phpunit/php-timer", "version": "1.0.9", @@ -2254,16 +2255,16 @@ }, { "name": "symfony/config", - "version": "v3.4.11", + "version": "v3.4.12", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "73e055cf2e6467715f187724a0347ea32079967c" + "reference": "1fffdeb349ff36a25184e5564c25289b1dbfc402" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/73e055cf2e6467715f187724a0347ea32079967c", - "reference": "73e055cf2e6467715f187724a0347ea32079967c", + "url": "https://api.github.com/repos/symfony/config/zipball/1fffdeb349ff36a25184e5564c25289b1dbfc402", + "reference": "1fffdeb349ff36a25184e5564c25289b1dbfc402", "shasum": "" }, "require": { @@ -2314,20 +2315,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-05-14T16:49:53+00:00" + "time": "2018-06-19T14:02:58+00:00" }, { "name": "symfony/console", - "version": "v3.4.11", + "version": "v3.4.12", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27" + "reference": "1b97071a26d028c9bd4588264e101e14f6e7cd00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/36f83f642443c46f3cf751d4d2ee5d047d757a27", - "reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27", + "url": "https://api.github.com/repos/symfony/console/zipball/1b97071a26d028c9bd4588264e101e14f6e7cd00", + "reference": "1b97071a26d028c9bd4588264e101e14f6e7cd00", "shasum": "" }, "require": { @@ -2383,20 +2384,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-05-16T08:49:21+00:00" + "time": "2018-05-23T05:02:55+00:00" }, { "name": "symfony/debug", - "version": "v3.4.11", + "version": "v3.4.12", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "b28fd73fefbac341f673f5efd707d539d6a19f68" + "reference": "47e6788c5b151cf0cfdf3329116bf33800632d75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/b28fd73fefbac341f673f5efd707d539d6a19f68", - "reference": "b28fd73fefbac341f673f5efd707d539d6a19f68", + "url": "https://api.github.com/repos/symfony/debug/zipball/47e6788c5b151cf0cfdf3329116bf33800632d75", + "reference": "47e6788c5b151cf0cfdf3329116bf33800632d75", "shasum": "" }, "require": { @@ -2439,20 +2440,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2018-05-16T14:03:39+00:00" + "time": "2018-06-25T11:10:40+00:00" }, { "name": "symfony/dependency-injection", - "version": "v3.4.11", + "version": "v3.4.12", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "8a4672aca8db6d807905d695799ea7d83c8e5bba" + "reference": "a0be80e3f8c11aca506e250c00bb100c04c35d10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/8a4672aca8db6d807905d695799ea7d83c8e5bba", - "reference": "8a4672aca8db6d807905d695799ea7d83c8e5bba", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a0be80e3f8c11aca506e250c00bb100c04c35d10", + "reference": "a0be80e3f8c11aca506e250c00bb100c04c35d10", "shasum": "" }, "require": { @@ -2510,20 +2511,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-05-25T11:57:15+00:00" + "time": "2018-06-25T08:36:56+00:00" }, { "name": "symfony/filesystem", - "version": "v3.4.11", + "version": "v3.4.12", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "8e03ca3fa52a0f56b87506f38cf7bd3f9442b3a0" + "reference": "8a721a5f2553c6c3482b1c5b22ed60fe94dd63ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/8e03ca3fa52a0f56b87506f38cf7bd3f9442b3a0", - "reference": "8e03ca3fa52a0f56b87506f38cf7bd3f9442b3a0", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/8a721a5f2553c6c3482b1c5b22ed60fe94dd63ed", + "reference": "8a721a5f2553c6c3482b1c5b22ed60fe94dd63ed", "shasum": "" }, "require": { @@ -2560,20 +2561,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-05-16T08:49:21+00:00" + "time": "2018-06-21T11:10:19+00:00" }, { "name": "symfony/finder", - "version": "v3.4.11", + "version": "v3.4.12", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "472a92f3df8b247b49ae364275fb32943b9656c6" + "reference": "3a8c3de91d2b2c68cd2d665cf9d00f7ef9eaa394" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/472a92f3df8b247b49ae364275fb32943b9656c6", - "reference": "472a92f3df8b247b49ae364275fb32943b9656c6", + "url": "https://api.github.com/repos/symfony/finder/zipball/3a8c3de91d2b2c68cd2d665cf9d00f7ef9eaa394", + "reference": "3a8c3de91d2b2c68cd2d665cf9d00f7ef9eaa394", "shasum": "" }, "require": { @@ -2609,7 +2610,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-05-16T08:49:21+00:00" + "time": "2018-06-19T20:52:10+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2727,7 +2728,7 @@ }, { "name": "symfony/yaml", - "version": "v3.4.11", + "version": "v3.4.12", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", diff --git a/tpl/default/picwall.html b/tpl/default/picwall.html index 1ea9c20..1b8bf3b 100644 --- a/tpl/default/picwall.html +++ b/tpl/default/picwall.html @@ -24,9 +24,9 @@ {/loop} -
+
{loop="$linksToDisplay"} -
+
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore} Date: Thu, 5 Jul 2018 20:29:55 +0200 Subject: [PATCH 8/9] Thumbnails: add a common mode to only retrieve thumbs from popular media websites --- application/PageBuilder.php | 6 ++- application/Thumbnailer.php | 54 +++++++++++++++++++++++++- application/Updater.php | 5 ++- index.php | 22 ++++++----- tests/ThumbnailerTest.php | 43 ++++++++++++++++---- tests/Updater/UpdaterTest.php | 7 ++-- tests/utils/config/configJson.json.php | 2 +- tpl/default/configure.html | 13 ++++++- tpl/vintage/configure.html | 13 ++++++- 9 files changed, 135 insertions(+), 30 deletions(-) diff --git a/application/PageBuilder.php b/application/PageBuilder.php index 5da7081..b1abe0d 100644 --- a/application/PageBuilder.php +++ b/application/PageBuilder.php @@ -1,6 +1,7 @@ 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')); diff --git a/application/Thumbnailer.php b/application/Thumbnailer.php index d2284e7..7d0d9c3 100644 --- a/application/Thumbnailer.php +++ b/application/Thumbnailer.php @@ -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; } /** diff --git a/application/Updater.php b/application/Updater.php index f6b9e20..2a4c807 100644 --- a/application/Updater.php +++ b/application/Updater.php @@ -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'); diff --git a/index.php b/index.php index d5a3e93..299d6d9 100644 --- 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. Please synchonize them.' + 'You have enabled or changed thumbnails mode. Please synchonize them.' ); } + $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]]; diff --git a/tests/ThumbnailerTest.php b/tests/ThumbnailerTest.php index c04b8fb..0831154 100644 --- a/tests/ThumbnailerTest.php +++ b/tests/ThumbnailerTest.php @@ -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. */ diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 92ff569..05f4b8e 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -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'])); diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php index a656b67..1549ddf 100644 --- a/tests/utils/config/configJson.json.php +++ b/tests/utils/config/configJson.json.php @@ -76,7 +76,7 @@ "extensions": [] }, "thumbnails": { - "enabled": true, + "mode": "common", "width": 90, "height": 53 } diff --git a/tpl/default/configure.html b/tpl/default/configure.html index dca9503..9711d15 100644 --- a/tpl/default/configure.html +++ b/tpl/default/configure.html @@ -259,8 +259,17 @@
- +
diff --git a/tpl/vintage/configure.html b/tpl/vintage/configure.html index fc3a563..9466c23 100644 --- a/tpl/vintage/configure.html +++ b/tpl/vintage/configure.html @@ -131,8 +131,17 @@ Enable thumbnails - +