mirror of https://github.com/nextcloud/bookmarks
115 lines
2.7 KiB
PHP
115 lines
2.7 KiB
PHP
<?php
|
|
/*
|
|
* Copyright (c) 2020-2024. The Nextcloud Bookmarks contributors.
|
|
*
|
|
* This file is licensed under the Affero General Public License version 3 or later. See the COPYING file.
|
|
*/
|
|
|
|
namespace OCA\Bookmarks\Service\Previewers;
|
|
|
|
use Exception;
|
|
use OCA\Bookmarks\Contract\IBookmarkPreviewer;
|
|
use OCA\Bookmarks\Contract\IImage;
|
|
use OCA\Bookmarks\Db\Bookmark;
|
|
use OCA\Bookmarks\Image;
|
|
use OCP\IConfig;
|
|
use OCP\ITempManager;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class PageresBookmarkPreviewer implements IBookmarkPreviewer {
|
|
public const CACHE_PREFIX = 'bookmarks.WebshotPreviewService';
|
|
public const CAPTURE_MAX_RETRIES = 3;
|
|
|
|
/** @var LoggerInterface */
|
|
private $logger;
|
|
|
|
/**
|
|
* @var ITempManager
|
|
*/
|
|
private $tempManager;
|
|
/**
|
|
* @var IConfig
|
|
*/
|
|
private $config;
|
|
|
|
public function __construct(ITempManager $tempManager, LoggerInterface $logger, IConfig $config) {
|
|
$this->tempManager = $tempManager;
|
|
$this->logger = $logger;
|
|
$this->config = $config;
|
|
}
|
|
|
|
/**
|
|
* @param Bookmark|null $bookmark
|
|
*
|
|
* @return Image|null
|
|
*/
|
|
public function getImage($bookmark): ?IImage {
|
|
if (!isset($bookmark)) {
|
|
return null;
|
|
}
|
|
|
|
$serverPath = self::getPageresPath();
|
|
if ($serverPath === null) {
|
|
return null;
|
|
}
|
|
|
|
$url = $bookmark->getUrl();
|
|
|
|
// Fetch image from remote server
|
|
return $this->fetchImage($serverPath, $url);
|
|
}
|
|
|
|
/**
|
|
* @param string $serverPath
|
|
* @param string $url
|
|
*
|
|
* @return Image
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
protected function fetchImage(string $serverPath, string $url): Image {
|
|
$tempPath = $this->tempManager->getTemporaryFile('.png');
|
|
$tempDir = dirname($tempPath);
|
|
$tempFile = basename($tempPath, '.png');
|
|
$command = $serverPath;
|
|
$escapedUrl = escapeshellarg($url);
|
|
$env = $this->config->getAppValue('bookmarks', 'previews.pageres.env');
|
|
|
|
$cmd = "cd {$tempDir} && {$env} {$command} {$escapedUrl} 1024x768" .
|
|
' --delay=4 --filename=' . escapeshellarg($tempFile) . ' --crop --overwrite 2>&1';
|
|
|
|
$retries = 0;
|
|
$output = [];
|
|
while ($retries < self::CAPTURE_MAX_RETRIES) {
|
|
$output = [];
|
|
@exec($cmd, $output, $returnCode);
|
|
|
|
if ($returnCode === 0 && is_file($tempPath)) {
|
|
$content = file_get_contents($tempPath);
|
|
unlink($tempPath);
|
|
|
|
return new Image('image/png', $content);
|
|
} else {
|
|
$this->logger->debug('Executing pageres failed');
|
|
$this->logger->debug(implode("\n", $output));
|
|
}
|
|
|
|
$retries++;
|
|
}
|
|
|
|
throw new Exception("Pageres Error\nCommand: {$cmd}\nOutput: " . implode(' ' . PHP_EOL, $output) . PHP_EOL);
|
|
}
|
|
|
|
/**
|
|
* @return null|string
|
|
*/
|
|
public static function getPageresPath(): ?string {
|
|
$serverPath = @exec('which pageres');
|
|
if (!empty($serverPath) && is_readable($serverPath)) {
|
|
return $serverPath;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|