From 0224c61530c2942549c277dae4e7e54bf8ad2328 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 16 Jan 2018 21:19:35 +0100 Subject: [PATCH 1/2] Add preview endpoint for the fileid Signed-off-by: Roeland Jago Douma --- core/Controller/PreviewController.php | 89 ++++++++++++++++++++++----- core/routes.php | 2 +- 2 files changed, 76 insertions(+), 15 deletions(-) diff --git a/core/Controller/PreviewController.php b/core/Controller/PreviewController.php index dcb27bc888..e18487363a 100644 --- a/core/Controller/PreviewController.php +++ b/core/Controller/PreviewController.php @@ -1,4 +1,5 @@ * @@ -31,6 +32,7 @@ use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\FileDisplayResponse; use OCP\Files\IRootFolder; +use OCP\Files\Node; use OCP\Files\NotFoundException; use OCP\IPreview; use OCP\IRequest; @@ -57,12 +59,13 @@ class PreviewController extends Controller { * @param IPreview $preview * @param IRootFolder $root * @param string $userId + * @param ITimeFactory $timeFactory */ - public function __construct($appName, + public function __construct(string $appName, IRequest $request, IPreview $preview, IRootFolder $root, - $userId, + string $userId, ITimeFactory $timeFactory ) { parent::__construct($appName, $request); @@ -83,15 +86,15 @@ class PreviewController extends Controller { * @param bool $a * @param bool $forceIcon * @param string $mode - * @return DataResponse|Http\FileDisplayResponse + * @return DataResponse|FileDisplayResponse */ - public function getPreview( - $file = '', - $x = 32, - $y = 32, - $a = false, - $forceIcon = true, - $mode = 'fill') { + public function getPreview ( + string $file = '', + int $x = 32, + int $y = 32, + bool $a = false, + bool $forceIcon = true, + string $mode = 'fill'): Http\Response { if ($file === '' || $x === 0 || $y === 0) { return new DataResponse([], Http::STATUS_BAD_REQUEST); @@ -99,19 +102,77 @@ class PreviewController extends Controller { try { $userFolder = $this->root->getUserFolder($this->userId); - $file = $userFolder->get($file); + $node = $userFolder->get($file); } catch (NotFoundException $e) { return new DataResponse([], Http::STATUS_NOT_FOUND); } - if (!($file instanceof File) || (!$forceIcon && !$this->preview->isAvailable($file))) { + return $this->fetchPreview($node, $x, $y, $a, $forceIcon, $mode); + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * + * @param int $fileId + * @param int $x + * @param int $y + * @param bool $a + * @param bool $forceIcon + * @param string $mode + * + * @return DataResponse|FileDisplayResponse + */ + public function getPreviewByFileId( + int $fileId = -1, + int $x = 32, + int $y = 32, + bool $a = false, + bool $forceIcon = true, + string $mode = 'fill') { + + if ($fileId === -1 || $x === 0 || $y === 0) { + return new DataResponse([], Http::STATUS_BAD_REQUEST); + } + + $userFolder = $this->root->getUserFolder($this->userId); + $nodes = $userFolder->getById($fileId); + + if (\count($nodes) === 0) { return new DataResponse([], Http::STATUS_NOT_FOUND); - } else if (!$file->isReadable()) { + } + + $node = array_pop($nodes); + + return $this->fetchPreview($node, $x, $y, $a, $forceIcon, $mode); + } + + /** + * @param Node $node + * @param int $x + * @param int $y + * @param bool $a + * @param bool $forceIcon + * @param string $mode + * @return DataResponse|FileDisplayResponse + */ + private function fetchPreview( + Node $node, + int $x, + int $y, + bool $a = false, + bool $forceIcon = true, + string $mode) : Http\Response { + + if (!($node instanceof File) || (!$forceIcon && !$this->preview->isAvailable($node))) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + if (!$node->isReadable()) { return new DataResponse([], Http::STATUS_FORBIDDEN); } try { - $f = $this->preview->getPreview($file, $x, $y, !$a, $mode); + $f = $this->preview->getPreview($node, $x, $y, !$a, $mode); $response = new FileDisplayResponse($f, Http::STATUS_OK, ['Content-Type' => $f->getMimeType()]); // Let cache this! diff --git a/core/routes.php b/core/routes.php index 1cb44e47d9..0eed8ed179 100644 --- a/core/routes.php +++ b/core/routes.php @@ -57,7 +57,7 @@ $application->registerRoutes($this, [ ['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'], ['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'], ['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'], - ['name' => 'Preview#getPreview', 'url' => '/core/preview', 'verb' => 'GET'], + ['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'], ['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'], ['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'], ['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'], From cda811b6b49d2925fa044b5c391cea27a9da8724 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 16 Jan 2018 21:47:08 +0100 Subject: [PATCH 2/2] Make filelist and sidebar use the fileid preview endpoint This makes sure the preview is cached even after rename! yay! Signed-off-by: Roeland Jago Douma --- apps/files/js/filelist.js | 13 ++++++++++++- apps/files/js/sidebarpreviewmanager.js | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index e50b402dea..b46db79267 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1511,6 +1511,7 @@ // the typeof check ensures that the default value of animate is true if (typeof(options.animate) === 'undefined' || !!options.animate) { this.lazyLoadPreview({ + fileId: fileData.id, path: path + '/' + fileData.name, mime: mime, etag: fileData.etag, @@ -1856,7 +1857,15 @@ urlSpec.x = Math.ceil(urlSpec.x); urlSpec.y = Math.ceil(urlSpec.y); urlSpec.forceIcon = 0; - return OC.generateUrl('/core/preview.png?') + $.param(urlSpec); + + if (typeof urlSpec.fileId !== 'undefined') { + delete urlSpec.file; + return OC.generateUrl('/core/preview?') + $.param(urlSpec); + } else { + delete urlSpec.fileId; + return OC.generateUrl('/core/preview.png?') + $.param(urlSpec); + } + }, /** @@ -1869,6 +1878,7 @@ */ lazyLoadPreview : function(options) { var self = this; + var fileId = options.fileId; var path = options.path; var mime = options.mime; var ready = options.callback; @@ -1880,6 +1890,7 @@ urlSpec = {}; ready(iconURL); // set mimeicon URL + urlSpec.fileId = fileId; urlSpec.file = OCA.Files.Files.fixPath(path); if (options.x) { urlSpec.x = options.x; diff --git a/apps/files/js/sidebarpreviewmanager.js b/apps/files/js/sidebarpreviewmanager.js index 2cf4248897..27ccd4fc40 100644 --- a/apps/files/js/sidebarpreviewmanager.js +++ b/apps/files/js/sidebarpreviewmanager.js @@ -92,6 +92,7 @@ }; this._fileList.lazyLoadPreview({ + fileId: model.get('id'), path: model.getFullPath(), mime: model.get('mimetype'), etag: model.get('etag'),