From 5466fbf761bfb810a43b11789b03b2ec54c9ab6e Mon Sep 17 00:00:00 2001
From: Roeland Jago Douma <roeland@famdouma.nl>
Date: Sun, 16 Oct 2016 16:48:11 +0200
Subject: [PATCH] Move Ipreview to more of DI thingy

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
---
 core/Controller/PreviewController.php | 48 +++++++++++--------------
 lib/private/Preview/Generator.php     | 37 ++++++++-----------
 lib/private/PreviewManager.php        | 52 +++++++++++++++++++++++++--
 lib/private/Server.php                |  6 +++-
 lib/public/IPreview.php               | 25 +++++++++++++
 5 files changed, 116 insertions(+), 52 deletions(-)

diff --git a/core/Controller/PreviewController.php b/core/Controller/PreviewController.php
index 425617813fa..f54681a856b 100644
--- a/core/Controller/PreviewController.php
+++ b/core/Controller/PreviewController.php
@@ -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()]);
 	}
 }
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index 08ab37057aa..ea162926afa 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -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;
diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php
index 109feb45864..0cda55751bf 100644
--- a/lib/private/PreviewManager.php
+++ b/lib/private/PreviewManager.php
@@ -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
 	 *
diff --git a/lib/private/Server.php b/lib/private/Server.php
index eb6865c4f9b..8f4e7d9ca2d 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -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) {
diff --git a/lib/public/IPreview.php b/lib/public/IPreview.php
index 071b5b8064c..0942db4784c 100644
--- a/lib/public/IPreview.php
+++ b/lib/public/IPreview.php
@@ -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
-- 
GitLab