diff options
-rw-r--r-- | appinfo/routes.php | 19 | ||||
-rw-r--r-- | controller/filescontroller.php | 27 | ||||
-rw-r--r-- | controller/previewcontroller.php | 114 | ||||
-rw-r--r-- | controller/publicpreviewcontroller.php | 32 | ||||
-rw-r--r-- | environment/environment.php | 123 | ||||
-rw-r--r-- | http/imageresponse.php | 8 | ||||
-rw-r--r-- | js/album.js | 47 | ||||
-rw-r--r-- | js/gallery.js | 33 | ||||
-rw-r--r-- | js/galleryutility.js | 11 | ||||
-rw-r--r-- | js/slideshow.js | 82 | ||||
-rw-r--r-- | js/thumbnail.js | 42 | ||||
-rw-r--r-- | service/downloadservice.php | 12 | ||||
-rw-r--r-- | service/previewservice.php | 41 | ||||
-rw-r--r-- | service/service.php | 29 |
14 files changed, 351 insertions, 269 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index bf2d97d1..04d89771 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -96,14 +96,8 @@ return [ ], // Large preview of a file [ - 'name' => 'preview#show_preview', - 'url' => '/preview', - 'verb' => 'GET' - ], - // Download the file - [ - 'name' => 'preview#download_preview', - 'url' => '/download', + 'name' => 'preview#get_preview', + 'url' => '/preview/{fileId}', 'verb' => 'GET' ], /** @@ -130,13 +124,8 @@ return [ 'verb' => 'GET' ], [ - 'name' => 'public_preview#show_preview', - 'url' => '/preview.public', - 'verb' => 'GET' - ], - [ - 'name' => 'public_preview#download_preview', - 'url' => '/download.public', + 'name' => 'public_preview#get_preview', + 'url' => '/preview.public/{fileId}', 'verb' => 'GET' ], // API, for later diff --git a/controller/filescontroller.php b/controller/filescontroller.php index 01451e1e..49ba17a1 100644 --- a/controller/filescontroller.php +++ b/controller/filescontroller.php @@ -32,6 +32,7 @@ use OCA\GalleryPlus\Service\SearchMediaService; */ class FilesController extends Controller { + use PathManipulation; use JsonHttpError; /** @@ -105,7 +106,8 @@ class FilesController extends Controller { $this->configService->getAlbumInfo($folderNode, $folderPathFromRoot, $features); $files = $this->searchMediaService->getMediaFiles($folderNode, $mediaTypesArray, $features); - + $files = $this->fixPaths($files, $folderPathFromRoot); + return $this->formatResults($files, $albumInfo, $locationHasChanged); } catch (\Exception $exception) { return $this->error($exception); @@ -113,6 +115,29 @@ class FilesController extends Controller { } /** + * Generates shortened paths to the media files + * + * We only want to keep one folder between the current folder and the found media file + * /root/folder/sub1/sub2/file.ext + * becomes + * /root/folder/file.ext + * + * @param $files + * @param $folderPathFromRoot + * + * @return array + */ + private function fixPaths($files, $folderPathFromRoot) { + if (!empty($files)) { + foreach ($files as &$file) { + $file['path'] = $this->getReducedPath($file['path'], $folderPathFromRoot); + } + } + + return $files; + } + + /** * Simply builds and returns an array containing the list of files, the album information and * whether the location has changed or not * diff --git a/controller/previewcontroller.php b/controller/previewcontroller.php index f92fde01..22f290f2 100644 --- a/controller/previewcontroller.php +++ b/controller/previewcontroller.php @@ -18,12 +18,14 @@ use OCP\IRequest; use OCP\IURLGenerator; use OCP\IEventSource; use OCP\ILogger; +use OCP\Files\File; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCA\GalleryPlus\Http\ImageResponse; use OCA\GalleryPlus\Service\ServiceException; +use OCA\GalleryPlus\Service\NotFoundServiceException; use OCA\GalleryPlus\Service\ThumbnailService; use OCA\GalleryPlus\Service\PreviewService; use OCA\GalleryPlus\Service\DownloadService; @@ -61,6 +63,10 @@ class PreviewController extends Controller { * @var ILogger */ private $logger; + /** + * @type bool + */ + private $download = false; /** * Constructor @@ -122,17 +128,18 @@ class PreviewController extends Controller { * * WARNING: Returning a JSON response does not get rid of the problem * - * @param string $images + * @param string $ids the ID of the files of which we need thumbnail previews of * @param bool $square * @param bool $scale * * @return array<string,array|string> */ - public function getThumbnails($images, $square, $scale) { - $imagesArray = explode(';', $images); + public function getThumbnails($ids, $square, $scale) { + $idsArray = explode(';', $ids); - foreach ($imagesArray as $image) { - $thumbnail = $this->getThumbnail($image, $square, $scale); + foreach ($idsArray as $id) { + $thumbnail = $this->getThumbnail((int)$id, $square, $scale); + $thumbnail['fileid'] = $id; $this->eventSource->send('preview', $thumbnail); } $this->eventSource->close(); @@ -146,18 +153,19 @@ class PreviewController extends Controller { * Sends either a large preview of the requested file or the * original file itself * - * If the browser can use the file as-is then we simply let - * the browser download the file, straight from the filesystem - * - * @param string $file - * @param int $x - * @param int $y + * @param int $fileId the ID of the file of which we need a large preview of + * @param int $width + * @param int $height + * @param string|null $download * * @return ImageResponse|Http\JSONResponse */ - public function showPreview($file, $x, $y) { + public function getPreview($fileId, $width, $height, $download) { + if (!is_null($download)) { + $this->download = true; + } try { - $preview = $this->getPreview($file, $x, $y); + $preview = $this->getPreviewData($fileId, $width, $height); return new ImageResponse($preview['data'], $preview['status']); } catch (ServiceException $exception) { @@ -165,24 +173,6 @@ class PreviewController extends Controller { } } - /** - * @NoAdminRequired - * - * Downloads the file - * - * @param string $file - * - * @return \OCA\GalleryPlus\Http\ImageResponse|Http\JSONResponse - */ - public function downloadPreview($file) { - try { - $download = $this->downloadService->downloadFile($file); - - return new ImageResponse($download); - } catch (ServiceException $exception) { - return $this->error($exception); - } - } /** * Retrieves the thumbnail to send back to the browser @@ -190,19 +180,20 @@ class PreviewController extends Controller { * The thumbnail is either a resized preview of the file or the original file * Thumbnails are base64encoded before getting sent back * - * @param string $image - * @param bool $square - * @param bool $scale + * + * @param int $fileId the ID of the file of which we need a thumbnail preview of + * @param bool $square whether the thumbnail should be square + * @param bool $scale whether we're allowed to scale the preview up * * @return array<string,array|string> */ - private function getThumbnail($image, $square, $scale) { + private function getThumbnail($fileId, $square, $scale) { list($width, $height, $aspect, $animatedPreview, $base64Encode) = $this->thumbnailService->getThumbnailSpecs($square, $scale); try { - $preview = $this->getPreview( - $image, $width, $height, $aspect, $animatedPreview, $base64Encode + $preview = $this->getPreviewData( + $fileId, $width, $height, $aspect, $animatedPreview, $base64Encode ); } catch (ServiceException $exception) { $preview = ['data' => null, 'status' => 500, 'type' => 'error']; @@ -231,7 +222,7 @@ class PreviewController extends Controller { * ] * ); * - * @param string $image + * @param int $fileId * @param int $width * @param int $height * @param bool $keepAspect @@ -239,24 +230,43 @@ class PreviewController extends Controller { * @param bool $base64Encode * * @return array<string,\OC_Image|string> + * + * @throws NotFoundServiceException */ - private function getPreview( - $image, $width, $height, $keepAspect = true, $animatedPreview = true, $base64Encode = false + private function getPreviewData( + $fileId, $width, $height, $keepAspect = true, $animatedPreview = true, $base64Encode = false ) { $status = Http::STATUS_OK; - $previewRequired = $this->previewService->isPreviewRequired($image, $animatedPreview); - if ($previewRequired) { - $type = 'preview'; - $preview = $this->previewService->createPreview( - $image, $width, $height, $keepAspect, $base64Encode - ); - if (!$this->previewService->isPreviewValid()) { - $type = 'error'; - $status = Http::STATUS_NOT_FOUND; + try { + /** @type File $file */ + $file = $this->previewService->getResourceFromId($fileId); + if (!$this->download) { + $previewRequired = + $this->previewService->isPreviewRequired($file, $animatedPreview); + if ($previewRequired) { + $type = 'preview'; + $preview = $this->previewService->createPreview( + $file, $width, $height, $keepAspect, $base64Encode + ); + if (!$this->previewService->isPreviewValid()) { + $type = 'error'; + $status = Http::STATUS_NOT_FOUND; + } + } else { + $type = 'download'; + $preview = $this->downloadService->downloadFile($file, $base64Encode); + } + } else { + $type = 'download'; + $preview = $this->downloadService->downloadFile($file, $base64Encode); } - } else { - $type = 'download'; - $preview = $this->downloadService->downloadFile($image, $base64Encode); + + $preview['name'] = $file->getName(); + + } catch (\Exception $exception) { + $type = 'error'; + $status = Http::STATUS_INTERNAL_SERVER_ERROR; + $preview = null; } return ['data' => $preview, 'status' => $status, 'type' => $type]; diff --git a/controller/publicpreviewcontroller.php b/controller/publicpreviewcontroller.php index 2a6d57f3..6686e89e 100644 --- a/controller/publicpreviewcontroller.php +++ b/controller/publicpreviewcontroller.php @@ -44,12 +44,12 @@ class PublicPreviewController extends PreviewController { * * @inheritDoc * - * @param string $images + * @param string $ids the ID of the files of which we need thumbnail previews of * @param bool $square * @param bool $scale */ - public function getThumbnails($images, $square, $scale) { - return parent::getThumbnails($images, $square, $scale); + public function getThumbnails($ids, $square, $scale) { + return parent::getThumbnails($ids, $square, $scale); } /** @@ -63,27 +63,13 @@ class PublicPreviewController extends PreviewController { * * @inheritDoc * - * @param string $file - * @param int $x - * @param int $y + * @param int $fileId the ID of the file of which we need a large preview of + * @param int $width + * @param int $height + * @param string|null $download */ - public function showPreview($file, $x, $y) { - return parent::showPreview($file, $x, $y); - } - - /** - * @PublicPage - * @UseSession - * - * Downloads the file - * - * The session needs to be maintained open or previews can't be generated - * for files located on encrypted storage - * - * @inheritDoc - */ - public function downloadPreview($file) { - return parent::downloadPreview($file); + public function getPreview($fileId, $width, $height, $download) { + return parent::getPreview($fileId, $width, $height, $download); } } diff --git a/environment/environment.php b/environment/environment.php index e6fd5906..cc8a29dd 100644 --- a/environment/environment.php +++ b/environment/environment.php @@ -147,11 +147,30 @@ class Environment { * @return File|Folder */ public function getResourceFromPath($subPath) { - $path = $this->getImagePathFromFolder($subPath); + $relativePath = $this->getRelativePath($this->fromRootToFolder); + $path = $relativePath . '/' . $subPath; $node = $this->getNode($path); return $this->getResourceFromId($node->getId()); } + + /** + * Returns the resource identified by the given ID + * + * @param int $resourceId + * + * @return Node + * + * @throws EnvironmentException + */ + public function getResourceFromId($resourceId) { + $resourcesArray = $this->userFolder->getById($resourceId); + if ($resourcesArray[0] === null) { + $this->logAndThrowNotFound('Could not locate file linked to ID: ' . $resourceId); + } + + return $resourcesArray[0]; + } /** * Returns the userId of the currently logged-in user or the sharer @@ -191,62 +210,25 @@ class Environment { } /** - * Returns /parent_folder/current_folder/_my_file + * Returns the path which goes from the file, up to the user folder, based on a node: + * parent_folder/current_folder/my_file + * + * This is used for the preview system, which needs a full path * * getPath() on the file produces a path like: - * '/userId/files/my_folder/my_sub_folder' + * '/userId/files/my_folder/my_sub_folder/my_file' * * So we substract the path to the folder, giving us a relative path - * '/my_folder/my_sub_folder' + * 'my_folder/my_sub_folder/my_file' * - * @param string $image + * @param Node $file * * @return string */ - public function getImagePathFromFolder($image) { - $origSharePath = $this->fromRootToFolder; - $folderPath = $this->userFolder->getPath(); - $origShareRelPath = str_replace($folderPath, '', $origSharePath); - $relativePath = $origShareRelPath; - - /*$this->logger->debug( - 'Full Path {origSharePath}, folder path {folderPath}, relative path {relativePath}', - [ - 'origSharePath' => $origSharePath, - 'folderPath' => $folderPath, - 'relativePath' => $relativePath - ] - );*/ - - return $relativePath . '/' . $image; - } - - /** - * Returns the Node based on the current user's files folder and a given - * path - * - * @param string $path - * - * @return Node|false - * - * @throws EnvironmentException - */ - public function getNode($path) { - $node = false; - $folder = $this->userFolder; - if ($folder === null) { - $this->logAndThrowNotFound("Could not access the user's folder"); - } else { - try { - $node = $folder->get($path); - - } catch (NotFoundException $exception) { - $message = 'Could not find anything at: ' . $exception->getMessage(); - $this->logAndThrowNotFound($message); - } - } + public function getPathFromUserFolder($file) { + $path = $file->getPath(); - return $node; + return $this->getRelativePath($path); } /** @@ -289,6 +271,7 @@ class Environment { \OC_Util::setupFS($origShareOwner); // FIXME: Private API $folder = $this->serverContainer->getUserFolder($origShareOwner); + /*// Alternative which does not exist yet $user = $this->userManager->get($origShareOwner); $folder = $user->getUserFolder();*/ @@ -314,23 +297,53 @@ class Environment { } /** - * Returns the resource identified by the given ID + * Returns the Node based on the current user's files folder and a given + * path * - * @param int $resourceId + * @param string $path * * @return File|Folder * * @throws EnvironmentException */ - private function getResourceFromId($resourceId) { - $resourcesArray = $this->userFolder->getById($resourceId); - if ($resourcesArray[0] === null) { - $this->logAndThrowNotFound('Could not resolve linkItem'); + private function getNode($path) { + $node = false; + $folder = $this->userFolder; + if ($folder === null) { + $this->logAndThrowNotFound("Could not access the user's folder"); + } else { + try { + $node = $folder->get($path); + } catch (NotFoundException $exception) { + $message = 'Could not find anything at: ' . $exception->getMessage(); + $this->logAndThrowNotFound($message); + } } - return $resourcesArray[0]; + return $node; } + + /** + * Returns the path which goes from the file, up to the user folder, based on a path: + * parent_folder/current_folder/my_file + * + * getPath() on the file produces a path like: + * '/userId/files/my_folder/my_sub_folder/my_file' + * + * So we substract the path to the user folder, giving us a relative path + * 'my_folder/my_sub_folder' + * + * @param string $fullPath + * + * @return string + */ + private function getRelativePath($fullPath) { + $folderPath = $this->userFolder->getPath() . '/'; + $origShareRelPath = str_replace($folderPath, '', $fullPath); + return $origShareRelPath; + } + /** * Logs the error and raises an exception * diff --git a/http/imageresponse.php b/http/imageresponse.php index 444cc560..2d8f5218 100644 --- a/http/imageresponse.php +++ b/http/imageresponse.php @@ -23,10 +23,6 @@ use OCP\AppFramework\Http; class ImageResponse extends Response { /** - * @var string - */ - private $path; - /** * @var \OC_Image|string */ private $preview; @@ -38,13 +34,13 @@ class ImageResponse extends Response { * @param int $statusCode the HTTP status code, defaults to 200 */ public function __construct(array $image, $statusCode = Http::STATUS_OK) { - $this->path = $image['path']; + $name = $image['name']; $this->preview = $image['preview']; $this->setStatus($statusCode); $this->addHeader('Content-type', $image['mimetype'] . '; charset=utf-8'); - \OCP\Response::setContentDispositionHeader(basename($this->path), 'attachment'); + \OCP\Response::setContentDispositionHeader($name, 'attachment'); } /** diff --git a/js/album.js b/js/album.js index 43db9901..b109d7ae 100644 --- a/js/album.js +++ b/js/album.js @@ -71,16 +71,12 @@ Album.prototype = { * @param {number} calcWidth Album width * @param {object} a * - * @returns {a} + * @returns {$.Deferred<Thumbnail>} * @private */ _getOneImage: function (image, targetHeight, calcWidth, a) { - var parts = image.src.split('/'); - parts.shift(); - var path = parts.join('/'); - var gm = new GalleryImage(image.src, path); // img is a Thumbnail.image, true means square thumbnails - gm.getThumbnail(true).then(function (img) { + return image.getThumbnail(true).then(function (img) { var backgroundHeight, backgroundWidth; img.alt = ''; backgroundHeight = (targetHeight / 2); @@ -156,8 +152,8 @@ Album.prototype = { var items = this.subAlbums.concat(this.images); var realCounter = 0; var maxThumbs = 0; - var paths = []; - var squarePaths = []; + var fileIds = []; + var squareFileIds = []; for (var i = this.preloadOffset; i < this.preloadOffset + count && i < items.length; i++) { if (items[i].subAlbums) { maxThumbs = 4; @@ -165,12 +161,12 @@ Album.prototype = { if (imagesLength > 0 && imagesLength < 4) { maxThumbs = imagesLength; } - var squarePath = items[i].getThumbnailPaths(maxThumbs); - squarePaths = squarePaths.concat(squarePath); + var squareFileId = items[i].getThumbnailIds(maxThumbs); + squareFileIds = squareFileIds.concat(squareFileId); realCounter = realCounter + maxThumbs; } else { - var path = items[i].getThumbnailPaths(); - paths = paths.concat(path); + var fileId = items[i].getThumbnailIds(); + fileIds = fileIds.concat(fileId); realCounter++; } if (realCounter >= count) { @@ -180,8 +176,8 @@ Album.prototype = { } this.preloadOffset = i; - Thumbnails.loadBatch(paths, false); - Thumbnails.loadBatch(squarePaths, true); + Thumbnails.loadBatch(fileIds, false); + Thumbnails.loadBatch(squareFileIds, true); }, /** @@ -253,20 +249,20 @@ Album.prototype = { }, /** - * Returns paths of thumbnails belonging to the album + * Returns IDs of thumbnails belonging to the album * * @param {number} count * - * @return string[] + * @return number[] */ - getThumbnailPaths: function (count) { - var paths = []; + getThumbnailIds: function (count) { + var ids = []; var items = this.images.concat(this.subAlbums); for (var i = 0; i < items.length && i < count; i++) { - paths = paths.concat(items[i].getThumbnailPaths(count)); + ids = ids.concat(items[i].getThumbnailIds(count)); } - return paths; + return ids; } }; @@ -343,12 +339,12 @@ Row.prototype = { GalleryImage.prototype = { /** - * Returns the Thumbnail path + * Returns the Thumbnail ID * - * @returns {[string]} + * @returns {[number]} */ - getThumbnailPaths: function () { - return [this.path]; + getThumbnailIds: function () { + return [this.fileId]; }, /** @@ -360,7 +356,7 @@ GalleryImage.prototype = { */ getThumbnail: function (square) { if (this.thumbnail === null) { - this.thumbnail = Thumbnails.get(this.src, square); + this.thumbnail = Thumbnails.get(this.fileId, square); } return this.thumbnail.loadingDeferred; }, @@ -373,6 +369,7 @@ GalleryImage.prototype = { * @returns {number} */ getThumbnailWidth: function () { + // img is a Thumbnail.image return this.getThumbnail(false).then(function (img) { if (img) { diff --git a/js/gallery.js b/js/gallery.js index 1321d9b4..c476014a 100644 --- a/js/gallery.js +++ b/js/gallery.js @@ -104,9 +104,6 @@ Gallery.getFiles = function () { image = new GalleryImage(path, path, fileId, mimeType, mTime, etag); var dir = OC.dirname(path); - var currentFolder = albumInfo.path; - dir = Gallery.fixDir(path, dir, currentFolder); - album = Gallery.getAlbum(dir); album.images.push(image); Gallery.imageMap[image.path] = image; @@ -129,26 +126,6 @@ Gallery.getFiles = function () { * @param dir * @param currentFolder */ -Gallery.fixDir = function (path, dir, currentFolder) { - if (dir === path) { - dir = ''; - } - - if (dir !== currentFolder) { - if (currentFolder !== '') { - currentFolder = currentFolder + '/'; - dir = dir.replace(currentFolder, ''); - } - var parts = dir.split('/'); - dir = currentFolder + parts[0]; - } - - return dir; -}; - -/** - * Sorts albums and images based on user preferences - */ Gallery.sorter = function () { var sortType = 'name'; var sortOrder = 'asc'; @@ -306,17 +283,13 @@ Gallery.slideShow = function (images, startImage, autoPlay) { var start = images.indexOf(startImage); images = images.map(function (image) { var name = OC.basename(image.path); - var previewUrl = Gallery.utility.getPreviewUrl(image.src, image.etag); - /* jshint camelcase: false */ - var params = { - file: image.src, - requesttoken: oc_requesttoken - }; - var downloadUrl = Gallery.utility.buildGalleryUrl('download', '', params); + var previewUrl = Gallery.utility.getPreviewUrl(image.fileId); + var downloadUrl = previewUrl + '&download'; return { name: name, path: image.path, + file: image.fileId, mimeType: image.mimeType, url: previewUrl, downloadUrl: downloadUrl diff --git a/js/galleryutility.js b/js/galleryutility.js index ff73c4c5..b8dcbc7e 100644 --- a/js/galleryutility.js +++ b/js/galleryutility.js @@ -92,23 +92,22 @@ * * @fixme we cannot get rid of oc_requesttoken parameter as it's missing from the headers * - * @param {string} image + * @param {number} fileId * @param {number} etag * * @return {string} */ - getPreviewUrl: function (image, etag) { + getPreviewUrl: function (fileId, etag) { var width = $(window).width() * window.devicePixelRatio; var height = $(window).height() * window.devicePixelRatio; /* jshint camelcase: false */ var params = { - file: image, c: etag, - x: width, - y: height, + width: width, + height: height, requesttoken: oc_requesttoken }; - return this.buildGalleryUrl('preview', '', params); + return this.buildGalleryUrl('preview', '/' + fileId, params); }, /** diff --git a/js/slideshow.js b/js/slideshow.js index ab211b76..dee0ed44 100644 --- a/js/slideshow.js +++ b/js/slideshow.js @@ -330,4 +330,86 @@ $(document).ready(function () { }).fail(function () { OC.Notification.show(t('core', 'Error loading slideshow template')); }); + + if (OCA.Files && OCA.Files.fileActions) { + // This is still required in OC8 + var requestToken; + if ($('#filesApp').val() && $('#isPublic').val()) { + // That's the only way to get one with the broken template + requestToken = $('#publicUploadRequestToken').val(); + } else if ($('#gallery').data('requesttoken')) { + requestToken = $('#gallery').data('requesttoken'); + } else { + requestToken = oc_requesttoken; + } + $(document).on('ajaxSend', function (elm, xhr) { + xhr.setRequestHeader('requesttoken', requestToken); + }); + + var prepareFileActions = function (mime) { + return OCA.Files.fileActions.register(mime, 'View', OC.PERMISSION_READ, '', + function (filename, context) { + var imageUrl, downloadUrl; + var fileList = context.fileList; + var files = fileList.files; + var start = 0; + var images = []; + var dir = context.dir + '/'; + var width = Math.floor($(window).width() * window.devicePixelRatio); + var height = Math.floor($(window).height() * window.devicePixelRatio); + + for (var i = 0; i < files.length; i++) { + var file = files[i]; + // We only add images to the slideshow if we think we'll be able + // to generate previews for this media type + if (file.isPreviewAvailable || file.mimetype === 'image/svg+xml') { + var params = { + width: width, + height: height, + requesttoken: requestToken + }; + imageUrl = SlideShow.buildGalleryUrl('preview', '/' + file.id, params); + downloadUrl = imageUrl + '&download'; + + images.push({ + name: file.name, + path: dir + file.name, + fileId: file.id, + mimeType: file.mimetype, + url: imageUrl, + downloadUrl: downloadUrl + }); + } + } + for (i = 0; i < images.length; i++) { + //console.log("Images in the slideshow : ", images[i]); + if (images[i].name === filename) { + start = i; + } + } + var slideShow = new SlideShow($('#slideshow'), images); + slideShow.onStop = function () { + location.hash = ''; + }; + slideShow.init(); + slideShow.show(start); + }); + }; + + var url = SlideShow.buildGalleryUrl('mediatypes', '', {slideshow: 1}); + // We're asking for a list of supported media types. Media files are retrieved through the + // context + $.getJSON(url).then(function (mediaTypes) { + //console.log("enabledPreviewProviders: ", mediaTypes); + SlideShow.mediaTypes = mediaTypes; + + // We only want to create slideshows for supported media types + for (var i = 0, keys = Object.keys(mediaTypes); i < keys.length; i++) { + // Each click handler gets the same function and images array and + // is responsible to load the slideshow + prepareFileActions(keys[i]); + OCA.Files.fileActions.setDefault(keys[i], 'View'); + } + }); + } }); diff --git a/js/thumbnail.js b/js/thumbnail.js index a841940d..c858d52b 100644 --- a/js/thumbnail.js +++ b/js/thumbnail.js @@ -2,13 +2,13 @@ /** * A thumbnail is the actual image attached to the GalleryImage object * - * @param {string} path + * @param {number} fileId * @param {bool} square * @constructor */ -function Thumbnail (path, square) { +function Thumbnail (fileId, square) { this.square = square; - this.path = path; + this.fileId = fileId; this.image = null; this.loadingDeferred = new $.Deferred(); this.height = 200; @@ -25,12 +25,12 @@ Thumbnails.squareMap = {}; /** * Retrieves the thumbnail linked to the given fileID * - * @param {string} path + * @param {number} fileId * @param {bool} square * * @returns {Thumbnail} */ -Thumbnails.get = function (path, square) { +Thumbnails.get = function (fileId, square) { var map = {}; if (square === true) { map = Thumbnails.squareMap; @@ -39,36 +39,38 @@ Thumbnails.get = function (path, square) { map = Thumbnails.map; square = false; } - if (!map[path]) { - map[path] = new Thumbnail(path, square); + if (!map[fileId]) { + map[fileId] = new Thumbnail(fileId, square); } - return map[path]; + + return map[fileId]; }; /** * Loads thumbnails in batch, using EventSource * - * @param {Array} paths + * @param {array} ids * @param {bool} square * * @returns {{}} */ -Thumbnails.loadBatch = function (paths, square) { +Thumbnails.loadBatch = function (ids, square) { var map = (square) ? Thumbnails.squareMap : Thumbnails.map; // Purely here as a precaution - paths = paths.filter(function (path) { - return !map[path]; + ids = ids.filter(function (id) { + return !map[id]; }); var batch = {}; - var i, pathsLength = paths.length; - if (pathsLength) { - for (i = 0; i < pathsLength; i++) { - var thumb = new Thumbnail(paths[i], square); + var i, idsLength = ids.length; + if (idsLength) { + for (i = 0; i < idsLength; i++) { + var thumb = new Thumbnail(ids[i], square); thumb.image = new Image(); - map[paths[i]] = batch[paths[i]] = thumb; + map[ids[i]] = batch[ids[i]] = thumb; + } var params = { - images: paths.join(';'), + ids: ids.join(';'), scale: window.devicePixelRatio, square: (square) ? 1 : 0 }; @@ -76,8 +78,8 @@ Thumbnails.loadBatch = function (paths, square) { var eventSource = new Gallery.EventSource(url); eventSource.listen('preview', function (/**{path, status, mimetype, preview}*/ preview) { - var path = preview.path; - var thumb = batch[path]; + var id = preview.fileid; + var thumb = batch[id]; thumb.status = preview.status; thumb.image.onload = function () { // Fix for SVG files which can come in all sizes diff --git a/service/downloadservice.php b/service/downloadservice.php index 3a37ce09..0914c190 100644 --- a/service/downloadservice.php +++ b/service/downloadservice.php @@ -27,22 +27,20 @@ class DownloadService extends Service { /** * Downloads the requested file * - * @param string $image + * @param File $file * @param bool $base64Encode * * @return false|array * * @throws NotFoundServiceException */ - public function downloadFile($image = '', $base64Encode = false) { - $this->logger->debug("[DownloadService] File to Download: $image"); - $file = null; + public function downloadFile($file, $base64Encode = false) { + $this->logger->debug( + "[DownloadService] File to Download: {name}", ['name' => $file->getName()] + ); $download = false; try { - /** @var File $file */ - $file = $this->environment->getResourceFromPath($image); $download = [ - 'path' => $image, 'preview' => $file->getContent(), 'mimetype' => $file->getMimeType() ]; diff --git a/service/previewservice.php b/service/previewservice.php index 57c4cd80..825b0980 100644 --- a/service/previewservice.php +++ b/service/previewservice.php @@ -17,7 +17,6 @@ use OCP\Template; use OCP\ILogger; use OCA\GalleryPlus\Environment\Environment; -use OCA\GalleryPlus\Environment\NotFoundEnvException; use OCA\GalleryPlus\Preview\Preview; /** @@ -112,23 +111,14 @@ class PreviewService extends Service { /** * Decides if we should download the file instead of generating a preview * - * @param string $image + * @param File $file * @param bool $animatedPreview * * @return bool - * - * @throws NotFoundServiceException */ - public function isPreviewRequired($image, $animatedPreview) { - $file = null; - try { - /** @var File $file */ - $file = $this->environment->getResourceFromPath($image); - - } catch (NotFoundEnvException $exception) { - $this->logAndThrowNotFound($exception->getMessage()); - } + public function isPreviewRequired($file, $animatedPreview) { $mime = $file->getMimeType(); + if ($mime === 'image/svg+xml') { return $this->isSvgPreviewRequired(); } @@ -142,24 +132,24 @@ class PreviewService extends Service { /** * Returns an array containing everything needed by the client to be able to display a preview * - * * path: the given path to the file + * * fileid: the file's ID * * mimetype: the file's media type * * preview: the preview's content * * status: a code indicating whether the conversion process was successful or not * * Example logger * $this->logger->debug( - * "[PreviewService] Path : {path} / size: {size} / mime: {mimetype} / status: {status}", + * "[PreviewService] Path : {path} / mime: {mimetype} / fileid: {fileid}", * [ - * 'path' => $perfectPreview['data']['path'], - * 'mimetype' => $perfectPreview['data']['mimetype'], - * 'status' => $perfectPreview['status'] + * 'path' => $preview['data']['path'], + * 'mimetype' => $preview['data']['mimetype'], + * 'fileid' => $preview['fileid'] * ] * ); * * @todo Get the max size from the settings * - * @param string $image path to the image, relative to the user folder + * @param File $file * @param int $maxX asked width for the preview * @param int $maxY asked height for the preview * @param bool $keepAspect @@ -169,24 +159,17 @@ class PreviewService extends Service { * @throws NotFoundServiceException */ public function createPreview( - $image, $maxX = 0, $maxY = 0, $keepAspect = true, $base64Encode = false + $file, $maxX = 0, $maxY = 0, $keepAspect = true, $base64Encode = false ) { - $file = null; - try { - /** @var File $file */ - $file = $this->environment->getResourceFromPath($image); - } catch (NotFoundEnvException $exception) { - $this->logAndThrowNotFound($exception->getMessage()); - } $userId = $this->environment->getUserId(); - $imagePathFromFolder = $this->environment->getImagePathFromFolder($image); + $imagePathFromFolder = $this->environment->getPathFromUserFolder($file); + $this->previewManager->setupView($userId, $file, $imagePathFromFolder); $preview = $this->previewManager->preparePreview($maxX, $maxY, $keepAspect); if ($base64Encode) { $preview['preview'] = $this->encode($preview['preview']); } - $preview['path'] = $image; return $preview; } diff --git a/service/service.php b/service/service.php index 8ce22553..1ab3b479 100644 --- a/service/service.php +++ b/service/service.php @@ -12,6 +12,8 @@ namespace OCA\GalleryPlus\Service; +use OCP\Files\Node; + use OCP\ILogger; use OCA\GalleryPlus\Environment\Environment; @@ -54,6 +56,33 @@ abstract class Service { } /** + * Returns the node matching the given ID + * + * @param int $nodeId ID of the resource to locate + * + * @return Node + * + * @throws NotFoundServiceException + */ + public function getResourceFromId($nodeId) { + $node = null; + try { + $node = $this->environment->getResourceFromId($nodeId); + + // Making extra sure that we can actually do something with the file + if ($node->getMimetype() && $node->isReadable()) { + return $node; + } else { + $this->logAndThrowNotFound("Can't access the file"); + } + } catch (\Exception $exception) { + $this->logAndThrowNotFound($exception->getMessage()); + } + + return null; + } + + /** * Logs the error and raises a "Not found" type exception * * @param string $message |