Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
100.00% |
1 / 1 |
|
100.00% |
14 / 14 |
CRAP | |
100.00% |
70 / 70 |
| FilesService | |
100.00% |
1 / 1 |
|
100.00% |
14 / 14 |
30 | |
100.00% |
70 / 70 |
| getNodes | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| isAllowedAndAvailable | |
100.00% |
1 / 1 |
4 | |
100.00% |
5 / 5 |
|||
| getNodeType | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| getNodeData | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
| getFolderData | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| getAllowedSubFolder | |
100.00% |
1 / 1 |
3 | |
100.00% |
4 / 4 |
|||
| isRootFolder | |
100.00% |
1 / 1 |
3 | |
100.00% |
8 / 8 |
|||
| recoverFromGetNodesError | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| isAllowed | |
100.00% |
1 / 1 |
4 | |
100.00% |
7 / 7 |
|||
| isAvailable | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| isExternalShareAllowed | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| isExternalShare | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
| getOwnerData | |
100.00% |
1 / 1 |
2 | |
100.00% |
6 / 6 |
|||
| formatNodeData | |
100.00% |
1 / 1 |
1 | |
100.00% |
8 / 8 |
|||
| <?php | |
| /** | |
| * Gallery | |
| * | |
| * This file is licensed under the Affero General Public License version 3 or | |
| * later. See the COPYING file. | |
| * | |
| * @author Olivier Paroz <galleryapps@oparoz.com> | |
| * | |
| * @copyright Olivier Paroz 2014-2016 | |
| */ | |
| namespace OCA\Gallery\Service; | |
| use OCP\Files\File; | |
| use OCP\Files\Folder; | |
| use OCP\Files\Node; | |
| /** | |
| * Contains various methods to retrieve information from the filesystem | |
| * | |
| * @package OCA\Gallery\Service | |
| */ | |
| abstract class FilesService extends Service { | |
| /** @var int */ | |
| protected $virtualRootLevel = null; | |
| /** @var string[] */ | |
| protected $features; | |
| /** @var string */ | |
| protected $ignoreAlbum = '.nomedia'; | |
| /** | |
| * Retrieves all files and sub-folders contained in a folder | |
| * | |
| * If we can't find anything in the current folder, we throw an exception as there is no point | |
| * in doing any more work, but if we're looking at a sub-folder, we return an empty array so | |
| * that it can be simply ignored | |
| * | |
| * @param Folder $folder | |
| * @param int $subDepth | |
| * | |
| * @return array | |
| */ | |
| protected function getNodes($folder, $subDepth) { | |
| try { | |
| $nodes = $folder->getDirectoryListing(); | |
| } catch (\Exception $exception) { | |
| $nodes = $this->recoverFromGetNodesError($subDepth, $exception); | |
| } | |
| return $nodes; | |
| } | |
| /** | |
| * Determines if the files are hosted locally (shared or not) and can be used by the preview | |
| * system | |
| * | |
| * isMounted() doesn't include externally hosted shares, so we need to exclude those from the | |
| * non-mounted nodes | |
| * | |
| * @param Node $node | |
| * | |
| * @return bool | |
| */ | |
| protected function isAllowedAndAvailable($node) { | |
| try { | |
| return $node && $this->isAllowed($node) && $this->isAvailable($node); | |
| } catch (\Exception $exception) { | |
| $message = 'The folder is not available: ' . $exception->getMessage(); | |
| $this->logger->error($message); | |
| return false; | |
| } | |
| } | |
| /** | |
| * Returns the node type, either 'dir' or 'file' | |
| * | |
| * If there is a problem, we return an empty string so that the node can be ignored | |
| * | |
| * @param Node $node | |
| * | |
| * @return string | |
| */ | |
| protected function getNodeType($node) { | |
| try { | |
| $nodeType = $node->getType(); | |
| } catch (\Exception $exception) { | |
| return ''; | |
| } | |
| return $nodeType; | |
| } | |
| /** | |
| * Returns various information about a node | |
| * | |
| * @param Node|File|Folder $node | |
| * | |
| * @return array<string,int|string|bool|array<string,int|string>> | |
| */ | |
| protected function getNodeData($node) { | |
| $imagePath = $this->environment->getPathFromVirtualRoot($node); | |
| $nodeId = $node->getId(); | |
| $mTime = $node->getMTime(); | |
| $etag = $node->getEtag(); | |
| $size = $node->getSize(); | |
| $sharedWithUser = $node->isShared(); | |
| $ownerData = $this->getOwnerData($node); | |
| $permissions = $node->getPermissions(); | |
| //$this->logger->debug("Image path : {var1}", ['var1' => $imagePath]); | |
| return $this->formatNodeData( | |
| $imagePath, $nodeId, $mTime, $etag, $size, $sharedWithUser, $ownerData, $permissions | |
| ); | |
| } | |
| /** | |
| * Returns various information about a folder | |
| * | |
| * @param Folder $node | |
| * | |
| * @return array<string,int|string|bool|array<string,int|string>> | |
| */ | |
| protected function getFolderData($node) { | |
| $folderData = $this->getNodeData($node); | |
| $folderData['freespace'] = $node->getFreeSpace(); | |
| return $folderData; | |
| } | |
| /** | |
| * Returns the node if it's a folder we have access to | |
| * | |
| * @param Folder $node | |
| * @param string $nodeType | |
| * | |
| * @return array|Folder | |
| */ | |
| protected function getAllowedSubFolder($node, $nodeType) { | |
| if ($nodeType === 'dir') { | |
| /** @var Folder $node */ | |
| if (!$node->nodeExists($this->ignoreAlbum)) { | |
| return [$node]; | |
| } | |
| } | |
| return []; | |
| } | |
| /** | |
| * Determines if we've reached the root folder | |
| * | |
| * @param Folder $folder | |
| * @param int $level | |
| * | |
| * @return bool | |
| */ | |
| protected function isRootFolder($folder, $level) { | |
| $isRootFolder = false; | |
| $rootFolder = $this->environment->getVirtualRootFolder(); | |
| if ($folder->getPath() === $rootFolder->getPath()) { | |
| $isRootFolder = true; | |
| } | |
| $virtualRootFolder = $this->environment->getPathFromVirtualRoot($folder); | |
| if (empty($virtualRootFolder)) { | |
| $this->virtualRootLevel = $level; | |
| } | |
| return $isRootFolder; | |
| } | |
| /** | |
| * Throws an exception if this problem occurs in the current folder, otherwise just ignores the | |
| * sub-folder | |
| * | |
| * @param int $subDepth | |
| * @param \Exception $exception | |
| * | |
| * @return array | |
| * @throws NotFoundServiceException | |
| */ | |
| private function recoverFromGetNodesError($subDepth, $exception) { | |
| if ($subDepth === 0) { | |
| throw new NotFoundServiceException($exception->getMessage()); | |
| } | |
| return []; | |
| } | |
| /** | |
| * Determines if we can consider the node mounted locally or if it's been authorised to be | |
| * scanned | |
| * | |
| * @param Node $node | |
| * | |
| * @return bool | |
| */ | |
| private function isAllowed($node) { | |
| $allowed = true; | |
| if ($this->isExternalShare($node)) { | |
| $allowed = $this->isExternalShareAllowed(); | |
| } | |
| if ($node->isMounted()) { | |
| $mount = $node->getMountPoint(); | |
| $allowed = $mount && $mount->getOption('previews', true); | |
| } | |
| return $allowed; | |
| } | |
| /** | |
| * Determines if the node is available, as in readable | |
| * | |
| * @todo Test to see by how much using file_exists slows things down | |
| * | |
| * @param Node $node | |
| * | |
| * @return bool | |
| */ | |
| private function isAvailable($node) { | |
| return $node->isReadable(); | |
| } | |
| /** | |
| * Determines if the user has allowed the use of external shares | |
| * | |
| * @return bool | |
| */ | |
| private function isExternalShareAllowed() { | |
| $rootFolder = $this->environment->getVirtualRootFolder(); | |
| return ($this->isExternalShare($rootFolder) | |
| || in_array('external_shares', $this->features)); | |
| } | |
| /** | |
| * Determines if the node is a share which is hosted externally | |
| * | |
| * | |
| * @param Node $node | |
| * | |
| * @return bool | |
| */ | |
| private function isExternalShare($node) { | |
| $sid = explode( | |
| ':', | |
| $node->getStorage() | |
| ->getId() | |
| ); | |
| return ($sid[0] === 'shared' && $sid[2][0] !== '/'); | |
| } | |
| /** | |
| * Returns what we known about the owner of a node | |
| * | |
| * @param Node $node | |
| * | |
| * @return null|array<string,int|string> | |
| */ | |
| private function getOwnerData($node) { | |
| $owner = $node->getOwner(); | |
| $ownerData = []; | |
| if ($owner) { | |
| $ownerData = [ | |
| 'uid' => $owner->getUID(), | |
| 'displayname' => $owner->getDisplayName() | |
| ]; | |
| } | |
| return $ownerData; | |
| } | |
| /** | |
| * Returns an array containing information about a node | |
| * | |
| * @param string $imagePath | |
| * @param int $nodeId | |
| * @param int $mTime | |
| * @param string $etag | |
| * @param int $size | |
| * @param bool $sharedWithUser | |
| * @param array <string,int|string> $ownerData | |
| * @param int $permissions | |
| * | |
| * @return array | |
| */ | |
| private function formatNodeData( | |
| $imagePath, $nodeId, $mTime, $etag, $size, $sharedWithUser, $ownerData, $permissions | |
| ) { | |
| return [ | |
| 'path' => $imagePath, | |
| 'nodeid' => $nodeId, | |
| 'mtime' => $mTime, | |
| 'etag' => $etag, | |
| 'size' => $size, | |
| 'sharedwithuser' => $sharedWithUser, | |
| 'owner' => $ownerData, | |
| 'permissions' => $permissions | |
| ]; | |
| } | |
| } |