diff options
author | Olivier Paroz <github@oparoz.com> | 2015-04-04 01:59:01 +0300 |
---|---|---|
committer | Olivier Paroz <github@oparoz.com> | 2015-04-04 01:59:01 +0300 |
commit | d7b8a33d5027e30098bbe5fbfb2b040121ff7a9b (patch) | |
tree | e2d0cd21afefc5bd657d39f7cbac2915e007205e | |
parent | 046783374ca01a30494ff5c3e1d906f716311e8f (diff) |
Add inheritance support to the album configuration
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | js/gallery.js | 63 | ||||
-rw-r--r-- | js/galleryconfig.js | 125 | ||||
-rw-r--r-- | js/galleryview.js | 2 | ||||
-rw-r--r-- | service/configservice.php | 225 | ||||
-rw-r--r-- | service/previewservice.php | 2 | ||||
-rw-r--r-- | templates/part.content.php | 1 | ||||
-rw-r--r-- | templates/public.php | 1 |
8 files changed, 308 insertions, 113 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 626af060..8fd9f260 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ owncloud-galleryplus (2.0.8) * Remove extra slash in preview URL #100 (@oparoz) * Fix thumbnail rendering so that the view doesn't break when a new request is made while the previous one is still not completed #56 (@oparoz) * Introduce album configuration via a text file #85 (@oparoz) -* Introduce image labels +* Introduce image labels #106 (@oparoz) owncloud-galleryplus (2.0.7) * Improved IE11 compatibility diff --git a/js/gallery.js b/js/gallery.js index 89e29748..02841d33 100644 --- a/js/gallery.js +++ b/js/gallery.js @@ -1,19 +1,18 @@ -/* global OC, $, _, t, Album, GalleryImage, SlideShow, oc_requesttoken, marked */ +/* global OC, $, _, t, GalleryConfig, Album, GalleryImage, SlideShow, oc_requesttoken, marked */ var Gallery = {}; Gallery.mediaTypes = {}; Gallery.images = []; Gallery.currentAlbum = null; Gallery.users = []; -Gallery.albumsInfo = {}; +Gallery.albumConfig = {}; Gallery.albumMap = {}; Gallery.imageMap = {}; Gallery.appName = 'galleryplus'; Gallery.token = undefined; -Gallery.currentSort = {}; /** * Returns a list of supported media types - * + * * @returns {string} */ Gallery.getMediaTypes = function () { @@ -78,6 +77,7 @@ Gallery.getFiles = function () { Gallery.images = []; Gallery.albumMap = {}; Gallery.imageMap = {}; + Gallery.albumConfig = null; var currentLocation = window.location.href.split('#')[1] || ''; var params = { location: currentLocation, @@ -91,14 +91,10 @@ Gallery.getFiles = function () { var mimeType = null; var mTime = null; var files = data.files; + var albumInfo = data.albuminfo; - Gallery.albumsInfo[albumInfo.path] = { - fileid: albumInfo.fileid, - permissions: albumInfo.permissions, - description: albumInfo.description, - copyright: albumInfo.copyright, - copyrightLink: albumInfo.copyright_link - }; + Gallery.albumConfig = new GalleryConfig(albumInfo); + for (var i = 0; i < files.length; i++) { path = files[i].path; fileId = files[i].fileid; @@ -116,27 +112,13 @@ Gallery.getFiles = function () { album.images.push(image); Gallery.imageMap[image.path] = image; } - var sortType = 'name'; - var sortOrder = 'asc'; - var albumSortOrder = 'asc'; - if (!$.isEmptyObject(albumInfo.sorting)) { - sortType = albumInfo.sorting; - } - if (!$.isEmptyObject(albumInfo.sort_order)) { - sortOrder = albumInfo.sort_order; - if (sortType === 'name') { - albumSortOrder = sortOrder; - } - } - - Gallery.currentSort = { - type: sortType, - order: sortOrder - }; + var currentSort = Gallery.albumConfig.getAlbumSorting(); for (var j = 0, keys = Object.keys(Gallery.albumMap); j < keys.length; j++) { - Gallery.albumMap[keys[j]].images.sort(Gallery.sortBy(sortType, sortOrder)); - Gallery.albumMap[keys[j]].subAlbums.sort(Gallery.sortBy('name', albumSortOrder)); + Gallery.albumMap[keys[j]].images.sort(Gallery.sortBy(currentSort.type, + currentSort.order)); + Gallery.albumMap[keys[j]].subAlbums.sort(Gallery.sortBy('name', + currentSort.albumOrder)); } }, function () { // Triggered if we couldn't find a working folder @@ -224,9 +206,9 @@ Gallery.share = function (event) { }; })(); - var albumInfo = Gallery.albumsInfo[Gallery.currentAlbum]; - $('a.share').data('item', albumInfo.fileid).data('link', true) - .data('possible-permissions', albumInfo.permissions). + var albumPermissions = Gallery.albumConfig.getAlbumPermissions(Gallery.currentAlbum); + $('a.share').data('item', albumPermissions.fileid).data('link', true) + .data('possible-permissions', albumPermissions.permissions). click(); if (!$('#linkCheckbox').is(':checked')) { $('#linkText').hide(); @@ -292,7 +274,7 @@ Gallery.showInfo = function (event) { if (infoContentElement.is(':visible')) { infoContentElement.slideUp(); } else { - var albumInfo = Gallery.albumsInfo[Gallery.currentAlbum]; + var albumInfo = Gallery.albumConfig.getAlbumInfo(); if (!albumInfo.infoLoaded) { infoContentElement.addClass('icon-loading'); infoContentElement.empty(); @@ -300,7 +282,7 @@ Gallery.showInfo = function (event) { infoContentElement.slideDown(); if (!$.isEmptyObject(albumInfo.description)) { var params = { - file: Gallery.currentAlbum + '/' + albumInfo.description + file: albumInfo.filePath + '/' + albumInfo.description }; var descriptionUrl = Gallery.buildUrl('download', '', params); $.get(descriptionUrl).done(function (data) { @@ -319,7 +301,8 @@ Gallery.showInfo = function (event) { Gallery.showCopyright(albumInfo, infoContentElement); adjustHeight(); } - albumInfo.infoLoaded = true; + Gallery.albumConfig.setInfoLoaded(); + } else { infoContentElement.slideDown(); } @@ -349,7 +332,7 @@ Gallery.showCopyright = function (albumInfo, infoContentElement) { if (!$.isEmptyObject(albumInfo.copyrightLink)) { var subUrl = ''; var params = { - path: '/' + Gallery.currentAlbum, + path: '/' + albumInfo.filePath, files: albumInfo.copyrightLink }; if (Gallery.token) { @@ -547,10 +530,12 @@ $(document).ready(function () { }); $(window).scroll(function () { - Gallery.view.loadVisibleRows(Gallery.albumMap[Gallery.currentAlbum], Gallery.currentAlbum); + Gallery.view.loadVisibleRows(Gallery.albumMap[Gallery.currentAlbum], + Gallery.currentAlbum); }); $('#content-wrapper').scroll(function () { - Gallery.view.loadVisibleRows(Gallery.albumMap[Gallery.currentAlbum], Gallery.currentAlbum); + Gallery.view.loadVisibleRows(Gallery.albumMap[Gallery.currentAlbum], + Gallery.currentAlbum); }); // A shorter delay avoids redrawing the view in the middle of a previous request, but it diff --git a/js/galleryconfig.js b/js/galleryconfig.js new file mode 100644 index 00000000..f95739bd --- /dev/null +++ b/js/galleryconfig.js @@ -0,0 +1,125 @@ +/* global $ */ +/** + * Stores the configuration about the current album + * @constructor + */ +var GalleryConfig = function (albumConfig) { + this.albumPermissions = this.setAlbumPermissions(albumConfig); + this.albumInfo = this.setAlbumInfo(albumConfig); + this.sorting = this.setAlbumSorting(albumConfig); +}; + +GalleryConfig.prototype = { + /** + * Saves the permissions for the current album + * + * @param albumConfig + * + * @returns {{fileid: *, permissions: *}} + */ + setAlbumPermissions: function (albumConfig) { + return { + fileid: albumConfig.fileid, + permissions: albumConfig.permissions + }; + }, + + /** + * Saves the description and copyright information for the current album + * + * @param albumConfig + * + * @returns {{}} + */ + setAlbumInfo: function (albumConfig) { + var albumPath = albumConfig.path; + var albumInfo = albumConfig.information; + var params = {}; + if (!$.isEmptyObject(albumInfo)) { + var docPath = albumPath; + var level = albumInfo.level; + if (level > 0) { + if (docPath.indexOf('/') !== -1) { + var folders = docPath.split('/'); + folders = folders.slice(-0, -level); + docPath = folders.join('/') + '/'; + } else { + docPath = ''; + } + } + + params = { + description: albumInfo.description, + copyright: albumInfo.copyright, + copyrightLink: albumInfo.copyright_link, + filePath: docPath + }; + } + + return params; + }, + + /** + * Saves the sorting configuration for the current album + * + * @param albumConfig + * + * @returns {{type: string, order: string, albumOrder: string}} + */ + setAlbumSorting: function (albumConfig) { + var sortType = 'name'; + var sortOrder = 'asc'; + var albumSortOrder = 'asc'; + if (!$.isEmptyObject(albumConfig.sorting)) { + if (!$.isEmptyObject(albumConfig.sorting.type)) { + sortType = albumConfig.sorting.type; + } + if (!$.isEmptyObject(albumConfig.sorting.order)) { + sortOrder = albumConfig.sorting.order; + if (sortType === 'name') { + albumSortOrder = sortOrder; + } + } + } + + return { + type: sortType, + order: sortOrder, + albumOrder: albumSortOrder + }; + }, + + /** + * Saves the fact that the description has been successfully loaded + */ + setInfoLoaded: function () { + this.albumInfo.infoLoaded = true; + }, + + /** + * Retrieves the permissions for the current album + * + * @returns {*|{fileid, permissions}|{fileid: *, permissions: *}} + */ + getAlbumPermissions: function () { + return this.albumPermissions; + }, + + /** + * Retrieves the description and copyright information for the current album + * + * @returns {*|{}} + */ + getAlbumInfo: function () { + return this.albumInfo; + }, + + /** + * Retrieves the sorting configuration for the current album + * + * @returns {*|{type, order, albumOrder}|{type: string, order: string, albumOrder: string}} + */ + getAlbumSorting: function () { + return this.sorting; + } +};
\ No newline at end of file diff --git a/js/galleryview.js b/js/galleryview.js index f829a8ed..d2e26cc1 100644 --- a/js/galleryview.js +++ b/js/galleryview.js @@ -101,7 +101,7 @@ Gallery.view.infoButtonSetup = function () { var infoContentElement = $('.album-info-content'); infoContentElement.slideUp(); infoContentElement.css('max-height', $(window).height() - 150); - var albumInfo = Gallery.albumsInfo[Gallery.currentAlbum]; + var albumInfo = Gallery.albumConfig.getAlbumInfo(); if ($.isEmptyObject(albumInfo.description) && $.isEmptyObject(albumInfo.copyright) && $.isEmptyObject(albumInfo.copyrightLink)) { diff --git a/service/configservice.php b/service/configservice.php index 34c167e5..fac4aa13 100644 --- a/service/configservice.php +++ b/service/configservice.php @@ -20,7 +20,8 @@ use OCP\Files\File; /** * Finds configurations files, parses them and returns a configuration array * - * Checks the current and parent folders for configuration files + * Checks the current and parent folders for configuration files and the privacy flag + * Supports explicit inheritance * * @package OCA\GalleryPlus\Service */ @@ -37,61 +38,77 @@ class ConfigService extends Service { * @param Folder $folderNode * @param string $folderPathFromRoot * - * @return array<string,string|int> + * @return array<null|array,bool> */ public function getAlbumInfo($folderNode, $folderPathFromRoot) { $configName = 'gallery.cnf'; $privacyChecker = '.nomedia'; - $albumInfo = []; + $configItems = ['information' => false, 'sorting' => false]; + list ($albumConfig, $privateAlbum) = - $this->getAlbumConfig($folderNode, $privacyChecker, $configName); + $this->getAlbumConfig($folderNode, $privacyChecker, $configName, $configItems); if (!$privateAlbum) { - $albumInfo = [ - 'path' => $folderPathFromRoot, - 'fileid' => $folderNode->getID(), - 'permissions' => $folderNode->getPermissions() - ]; - $albumInfo = array_merge($albumInfo, $albumConfig); + $albumConfig = + $this->addAlbumPermissions($albumConfig, $folderNode, $folderPathFromRoot); } - return [$albumInfo, $privateAlbum]; + return [$albumConfig, $privateAlbum]; } /** * Returns an album configuration array * + * Goes through all the parent folders until either we're told the album is private or we've + * gathered all the information we need + * * @param Folder $folder * @param string $privacyChecker * @param string $configName + * @param array $configItems * @param int $level - * @param array $configArray - * @param bool $configComplete + * @param array $config * - * @return array <null|string,string> + * @return array<null|array,bool> */ private function getAlbumConfig( - $folder, $privacyChecker, $configName, $level = 0, $configArray = [], - $configComplete = false + $folder, $privacyChecker, $configName, $configItems, $level = 0, $config = [] ) { if ($folder->nodeExists($privacyChecker)) { // Cancel as soon as we find out that the folder is private return [null, true]; } - list($configArray, $configComplete) = - $this->parseConfig($folder, $configName, $configArray, $configComplete, $level); - $parentFolder = $folder->getParent(); - $path = $parentFolder->getPath(); - if ($path !== '' && $path !== '/') { - $level++; - - return $this->getAlbumConfig( - $parentFolder, $privacyChecker, $configName, $level, $configArray, $configComplete + if ($folder->nodeExists($configName)) { + list($config, $configItems) = + $this->parseFolderConfig($folder, $configName, $config, $configItems, $level); + } + if (!$this->isConfigComplete($configItems)) { + return $this->getParentConfig( + $folder, $privacyChecker, $configName, $configItems, $level, $config ); } - // We have reached the root folder - return [$configArray, false]; + // We have found a valid config or have reached the root folder + return [$config, false]; + } + + /** + * Adds the permission settings to the album config + * + * @param null|array<string,string|int> $albumConfig + * @param Folder $folderNode + * @param string $folderPathFromRoot + * + * @return null|array,bool + */ + private function addAlbumPermissions($albumConfig, $folderNode, $folderPathFromRoot) { + $albumInfo = [ + 'path' => $folderPathFromRoot, + 'fileid' => $folderNode->getID(), + 'permissions' => $folderNode->getPermissions() + ]; + + return array_merge($albumConfig, $albumInfo); } /** @@ -99,35 +116,81 @@ class ConfigService extends Service { * * @param Folder $folder * @param string $configName - * @param array $currentConfigArray - * @param bool $configComplete + * @param array $currentConfig + * @param array $configItems * @param int $level * - * @return array<array,bool> + * @return array<null|array,array<string,bool>> */ - private function parseConfig( - $folder, $configName, $currentConfigArray, $configComplete, $level - ) { - $configArray = $currentConfigArray; - // Let's try to find the missing information in the configuration located in this folder - if (!$configComplete && $folder->nodeExists($configName)) { - /** @type File $configFile */ - $configFile = $folder->get($configName); - try { - $rawConfig = $configFile->getContent(); - $saneConfig = $this->bomFixer($rawConfig); - $parsedConfigArray = Yaml::parse($saneConfig); - list($configArray, $configComplete) = - $this->validateConfig($currentConfigArray, $parsedConfigArray, $level); - } catch (\Exception $exception) { - $this->logger->error( - "Problem while parsing the configuration file : {path}", - ['path' => $folder->getPath() . '/' . $configFile->getPath()] - ); + private function parseFolderConfig($folder, $configName, $currentConfig, $configItems, $level) { + $config = $currentConfig; + /** @type File $configFile */ + $configFile = $folder->get($configName); + try { + $rawConfig = $configFile->getContent(); + $saneConfig = $this->bomFixer($rawConfig); + $parsedConfig = Yaml::parse($saneConfig); + + list($config, $configItems) = + $this->buildAlbumConfig($currentConfig, $parsedConfig, $configItems, $level); + } catch (\Exception $exception) { + $this->logger->error( + "Problem while parsing the configuration file : {path}", + ['path' => $folder->getPath() . '/' . $configFile->getPath()] + ); + } + + return [$config, $configItems]; + } + + /** + * Decides whether we have all the elements we need or not + * + * @param $configItems + * + * @return bool + */ + private function isConfigComplete($configItems) { + $configComplete = false; + $completedItems = 0; + foreach ($configItems as $key => $complete) { + if ($complete === true) { + $completedItems++; } } + if ($completedItems === sizeof($configItems)) { + $configComplete = true; + } + + return $configComplete; + } + + /** + * Looks for an album configuration in the parent folder + * + * @param Folder $folder + * @param string $privacyChecker + * @param string $configName + * @param array $configItems + * @param int $level + * @param array <null|string,string> $config + * + * @return array<null|array,array<string,bool>> + */ + private function getParentConfig( + $folder, $privacyChecker, $configName, $configItems, $level, $config + ) { + $parentFolder = $folder->getParent(); + $path = $parentFolder->getPath(); + if ($path !== '' && $path !== '/') { + $level++; + + return $this->getAlbumConfig( + $parentFolder, $privacyChecker, $configName, $configItems, $level, $config + ); + } - return [$configArray, $configComplete]; + return [$config, false]; } /** @@ -151,33 +214,53 @@ class ConfigService extends Service { /** * Returns either the local config or one merged with a config containing sorting information * - * @param array $currentConfigArray - * @param array $parsedConfigArray + * @param array $currentConfig + * @param array $parsedConfig + * @param array $configItems * @param int $level * - * @return array<array,bool> + * @return array<null|array,array<string,bool>> */ - private function validateConfig($currentConfigArray, $parsedConfigArray, $level) { - $configComplete = false; - $sorting = $parsedConfigArray['sorting']; - $sortOrder = $parsedConfigArray['sort_order']; - $configArray = $parsedConfigArray; - if ($sorting) { - $configComplete = true; - if ($level > 0) { - // We only need the sorting information - $currentConfigArray['sorting'] = $sorting; - $currentConfigArray['sort_order'] = $sortOrder; - $configArray = $currentConfigArray; - } - } else { - if ($level > 0) { - // Reset the array to what we had earlier since we didn't find any sorting information - $configArray = $currentConfigArray; + private function buildAlbumConfig($currentConfig, $parsedConfig, $configItems, $level) { + foreach ($configItems as $key => $complete) { + if (!$complete && array_key_exists($key, $parsedConfig)) { + $parsedConfigItem = $parsedConfig[$key]; + list($configItem, $itemComplete) = + $this->addConfigItem($key, $parsedConfigItem, $level); + + $currentConfig = array_merge($currentConfig, $configItem); + $configItems[$key] = $itemComplete; } } - return [$configArray, $configComplete]; + return [$currentConfig, $configItems]; + } + + /** + * Adds a config sub-section to the global config + * + * @param string $key + * @param array $parsedConfigItem + * @param int $level + * + * @return array<null|array<string,string>,bool> + */ + private function addConfigItem($key, $parsedConfigItem, $level) { + $configItem = []; + $itemComplete = false; + $inherit = false; + + if (array_key_exists('inherit', $parsedConfigItem)) { + $inherit = $parsedConfigItem['inherit']; + } + + if ($level === 0 || $inherit === 'yes') { + $parsedConfigItem['level'] = $level; + $configItem = [$key => $parsedConfigItem]; + $itemComplete = true; + } + + return [$configItem, $itemComplete]; } } diff --git a/service/previewservice.php b/service/previewservice.php index 0484e20d..ef8ecccc 100644 --- a/service/previewservice.php +++ b/service/previewservice.php @@ -107,7 +107,7 @@ class PreviewService extends Service { } // If it's enabled, but doesn't work, an exception will be raised. // If it's disabled, we support it via the browser's native support - if (!$supportedMimes['image/svg+xml']) { + if (!in_array('image/svg+xml', $supportedMimes)) { $supportedMimes['image/svg+xml'] = Template::mimetype_icon('image/svg+xml'); } diff --git a/templates/part.content.php b/templates/part.content.php index 8239c057..607cb371 100644 --- a/templates/part.content.php +++ b/templates/part.content.php @@ -9,6 +9,7 @@ script( $_['appName'], [ 'gallery', + 'galleryconfig', 'galleryview', 'album', 'thumbnail', diff --git a/templates/public.php b/templates/public.php index 13403da3..311b334f 100644 --- a/templates/public.php +++ b/templates/public.php @@ -9,6 +9,7 @@ script( $_['appName'], [ 'gallery', + 'galleryconfig', 'galleryview', 'album', 'thumbnail', |