Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>tags/v11.0RC2
@@ -23,15 +23,14 @@ | |||
namespace OC\Core\Controller; | |||
use OC\PreviewManager; | |||
use OC\DatabaseException; | |||
use OCP\AppFramework\Controller; | |||
use OCP\Files\File; | |||
use OCP\AppFramework\Http; | |||
use OCP\AppFramework\Http\DataResponse; | |||
use OCP\Files\IAppData; | |||
use OCP\Files\IRootFolder; | |||
use OCP\Files\NotFoundException; | |||
use OCP\IConfig; | |||
use OCP\IPreview; | |||
use OCP\IRequest; | |||
class PreviewController extends Controller { | |||
@@ -42,29 +41,28 @@ class PreviewController extends Controller { | |||
/** @var IRootFolder */ | |||
private $root; | |||
/** @var IConfig */ | |||
private $config; | |||
/** @var PreviewManager */ | |||
private $previewManager; | |||
/** @var IAppData */ | |||
private $appData; | |||
/** @var IPreview */ | |||
private $preview; | |||
/** | |||
* PreviewController constructor. | |||
* | |||
* @param string $appName | |||
* @param IRequest $request | |||
* @param IPreview $preview | |||
* @param IRootFolder $root | |||
* @param string $userId | |||
*/ | |||
public function __construct($appName, | |||
IRequest $request, | |||
IPreview $preview, | |||
IRootFolder $root, | |||
IConfig $config, | |||
PreviewManager $previewManager, | |||
IAppData $appData, | |||
$userId | |||
) { | |||
parent::__construct($appName, $request); | |||
$this->previewManager = $previewManager; | |||
$this->preview = $preview; | |||
$this->root = $root; | |||
$this->config = $config; | |||
$this->appData = $appData; | |||
$this->userId = $userId; | |||
} | |||
@@ -103,21 +101,17 @@ class PreviewController extends Controller { | |||
return new DataResponse([], Http::STATUS_NOT_FOUND); | |||
} | |||
if (!($file instanceof File) || (!$forceIcon && !$this->previewManager->isAvailable($file))) { | |||
if (!($file instanceof File) || (!$forceIcon && !$this->preview->isAvailable($file))) { | |||
return new DataResponse([], Http::STATUS_NOT_FOUND); | |||
} else if (!$file->isReadable()) { | |||
return new DataResponse([], Http::STATUS_FORBIDDEN); | |||
} | |||
$preview = new \OC\Preview\Generator( | |||
$this->root, | |||
$this->config, | |||
$this->previewManager, | |||
$file, | |||
$this->appData | |||
); | |||
$f = $preview->getPreview($x, $y, !$a, $mode); | |||
try { | |||
$f = $this->preview->getPreview($file, $x, $y, !$a, $mode); | |||
} catch (NotFoundException $e) { | |||
return new DataResponse([], Http::STATUS_NOT_FOUND); | |||
} | |||
return new Http\FileDisplayResponse($f, Http::STATUS_OK, ['Content-Type' => $f->getMimeType()]); | |||
} | |||
} |
@@ -37,16 +37,9 @@ use OCP\IPreview; | |||
use OCP\Preview\IProvider; | |||
class Generator { | |||
//the thumbnail folder | |||
const THUMBNAILS_FOLDER = 'thumbnails'; | |||
const MODE_FILL = 'fill'; | |||
const MODE_COVER = 'cover'; | |||
/** @var IRootFolder*/ | |||
private $rootFolder; | |||
/** @var File */ | |||
private $file; | |||
/** @var IPreview */ | |||
private $previewManager; | |||
/** @var IConfig */ | |||
@@ -58,19 +51,16 @@ class Generator { | |||
* @param IRootFolder $rootFolder | |||
* @param IConfig $config | |||
* @param IPreview $previewManager | |||
* @param File $file | |||
* @param IAppData $appData | |||
*/ | |||
public function __construct( | |||
IRootFolder $rootFolder, | |||
IConfig $config, | |||
IPreview $previewManager, | |||
File $file, | |||
IAppData $appData | |||
) { | |||
$this->rootFolder = $rootFolder; | |||
$this->config = $config; | |||
$this->file = $file; | |||
$this->previewManager = $previewManager; | |||
$this->appData = $appData; | |||
} | |||
@@ -81,6 +71,7 @@ class Generator { | |||
* The cache is searched first and if nothing usable was found then a preview is | |||
* generated by one of the providers | |||
* | |||
* @param File $file | |||
* @param int $width | |||
* @param int $height | |||
* @param bool $crop | |||
@@ -88,8 +79,8 @@ class Generator { | |||
* @return ISimpleFile | |||
* @throws NotFoundException | |||
*/ | |||
public function getPreview($width = -1, $height = -1, $crop = false, $mode = Generator::MODE_FILL) { | |||
if (!$this->previewManager->isMimeSupported($this->file->getMimeType())) { | |||
public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL) { | |||
if (!$this->previewManager->isMimeSupported($file->getMimeType())) { | |||
throw new NotFoundException(); | |||
} | |||
@@ -97,10 +88,10 @@ class Generator { | |||
* Get the preview folder | |||
* TODO: Separate preview creation from storing previews | |||
*/ | |||
$previewFolder = $this->getPreviewFolder(); | |||
$previewFolder = $this->getPreviewFolder($file); | |||
// Get the max preview and infer the max preview sizes from that | |||
$maxPreview = $this->getMaxPreview($previewFolder); | |||
$maxPreview = $this->getMaxPreview($previewFolder, $file); | |||
list($maxWidth, $maxHeight) = $this->getPreviewSize($maxPreview); | |||
// Calculate the preview size | |||
@@ -118,10 +109,11 @@ class Generator { | |||
/** | |||
* @param ISimpleFolder $previewFolder | |||
* @param File $file | |||
* @return ISimpleFile | |||
* @throws NotFoundException | |||
*/ | |||
private function getMaxPreview(ISimpleFolder $previewFolder) { | |||
private function getMaxPreview(ISimpleFolder $previewFolder, File $file) { | |||
$nodes = $previewFolder->getDirectoryListing(); | |||
foreach ($nodes as $node) { | |||
@@ -132,7 +124,7 @@ class Generator { | |||
$previewProviders = $this->previewManager->getProviders(); | |||
foreach ($previewProviders as $supportedMimeType => $providers) { | |||
if (!preg_match($supportedMimeType, $this->file->getMimeType())) { | |||
if (!preg_match($supportedMimeType, $file->getMimeType())) { | |||
continue; | |||
} | |||
@@ -142,7 +134,7 @@ class Generator { | |||
continue; | |||
} | |||
list($view, $path) = $this->getViewAndPath($this->file); | |||
list($view, $path) = $this->getViewAndPath($file); | |||
$maxWidth = (int)$this->config->getSystemValue('preview_max_x', 2048); | |||
$maxHeight = (int)$this->config->getSystemValue('preview_max_y', 2048); | |||
@@ -239,13 +231,13 @@ class Generator { | |||
* Fill means that the $height and $width are the max | |||
* Cover means min. | |||
*/ | |||
if ($mode === self::MODE_FILL) { | |||
if ($mode === IPreview::MODE_FILL) { | |||
if ($ratioH > $ratioW) { | |||
$height = $width * $ratio; | |||
} else { | |||
$width = $height / $ratio; | |||
} | |||
} else if ($mode === self::MODE_COVER) { | |||
} else if ($mode === IPreview::MODE_COVER) { | |||
if ($ratioH > $ratioW) { | |||
$width = $height / $ratio; | |||
} else { | |||
@@ -352,13 +344,14 @@ class Generator { | |||
/** | |||
* Get the specific preview folder for this file | |||
* | |||
* @param File $file | |||
* @return ISimpleFolder | |||
*/ | |||
private function getPreviewFolder() { | |||
private function getPreviewFolder(File $file) { | |||
try { | |||
$folder = $this->appData->getFolder($this->file->getId()); | |||
$folder = $this->appData->getFolder($file->getId()); | |||
} catch (NotFoundException $e) { | |||
$folder = $this->appData->newFolder($this->file->getId()); | |||
$folder = $this->appData->newFolder($file->getId()); | |||
} | |||
return $folder; |
@@ -25,13 +25,29 @@ | |||
*/ | |||
namespace OC; | |||
use OC\Preview\Generator; | |||
use OCP\Files\File; | |||
use OCP\Files\IAppData; | |||
use OCP\Files\IRootFolder; | |||
use OCP\Files\NotFoundException; | |||
use OCP\Files\SimpleFS\ISimpleFile; | |||
use OCP\IConfig; | |||
use OCP\IPreview; | |||
use OCP\Preview\IProvider; | |||
class PreviewManager implements IPreview { | |||
/** @var \OCP\IConfig */ | |||
/** @var IConfig */ | |||
protected $config; | |||
/** @var IRootFolder */ | |||
protected $rootFolder; | |||
/** @var IAppData */ | |||
protected $appData; | |||
/** @var Generator */ | |||
private $generator; | |||
/** @var bool */ | |||
protected $providerListDirty = false; | |||
@@ -52,8 +68,12 @@ class PreviewManager implements IPreview { | |||
* | |||
* @param \OCP\IConfig $config | |||
*/ | |||
public function __construct(\OCP\IConfig $config) { | |||
public function __construct(IConfig $config, | |||
IRootFolder $rootFolder, | |||
IAppData $appData) { | |||
$this->config = $config; | |||
$this->rootFolder = $rootFolder; | |||
$this->appData = $appData; | |||
} | |||
/** | |||
@@ -120,6 +140,34 @@ class PreviewManager implements IPreview { | |||
return $preview->getPreview(); | |||
} | |||
/** | |||
* Returns a preview of a file | |||
* | |||
* The cache is searched first and if nothing usable was found then a preview is | |||
* generated by one of the providers | |||
* | |||
* @param File $file | |||
* @param int $width | |||
* @param int $height | |||
* @param bool $crop | |||
* @param string $mode | |||
* @return ISimpleFile | |||
* @throws NotFoundException | |||
* @since 9.2.0 | |||
*/ | |||
public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL) { | |||
if ($this->generator === null) { | |||
$this->generator = new Generator( | |||
$this->rootFolder, | |||
$this->config, | |||
$this, | |||
$this->appData | |||
); | |||
} | |||
return $this->generator->getPreview($file, $width, $height, $crop, $mode); | |||
} | |||
/** | |||
* returns true if the passed mime type is supported | |||
* |
@@ -117,7 +117,11 @@ class Server extends ServerContainer implements IServerContainer { | |||
}); | |||
$this->registerService('PreviewManager', function (Server $c) { | |||
return new PreviewManager($c->getConfig()); | |||
return new PreviewManager( | |||
$c->getConfig(), | |||
$c->getRootFolder(), | |||
$c->getAppDataDir('preview') | |||
); | |||
}); | |||
$this->registerService(\OC\Preview\Watcher::class, function (Server $c) { |
@@ -33,11 +33,19 @@ | |||
// This means that they should be used by apps instead of the internal ownCloud classes | |||
namespace OCP; | |||
use OCP\Files\File; | |||
use OCP\Files\SimpleFS\ISimpleFile; | |||
use OCP\Files\NotFoundException; | |||
/** | |||
* This class provides functions to render and show thumbnails and previews of files | |||
* @since 6.0.0 | |||
*/ | |||
interface IPreview { | |||
const MODE_FILL = 'fill'; | |||
const MODE_COVER = 'cover'; | |||
/** | |||
* In order to improve lazy loading a closure can be registered which will be | |||
* called in case preview providers are actually requested | |||
@@ -73,9 +81,26 @@ interface IPreview { | |||
* @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly | |||
* @return \OCP\IImage | |||
* @since 6.0.0 | |||
* @deprecated 9.2.0 Use getPreview | |||
*/ | |||
public function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false); | |||
/** | |||
* Returns a preview of a file | |||
* | |||
* The cache is searched first and if nothing usable was found then a preview is | |||
* generated by one of the providers | |||
* | |||
* @param File $file | |||
* @param int $width | |||
* @param int $height | |||
* @param bool $crop | |||
* @param string $mode | |||
* @return ISimpleFile | |||
* @throws NotFoundException | |||
* @since 9.2.0 | |||
*/ | |||
public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL); | |||
/** | |||
* Returns true if the passed mime type is supported |