Exclude mounts in nomedia
Signed-off-by: Varun Patil <varunpatil@ucla.edu>pull/579/head
parent
8ec21747f3
commit
3ada3d6510
|
@ -23,12 +23,17 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Memories\Db;
|
||||
|
||||
use OC\Files\Search\SearchComparison;
|
||||
use OC\Files\Search\SearchQuery;
|
||||
use OCA\Memories\Exceptions;
|
||||
use OCA\Memories\Exif;
|
||||
use OCA\Memories\Util;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Search\ISearchComparison;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserManager;
|
||||
|
@ -42,19 +47,22 @@ class FsManager
|
|||
protected IRootFolder $rootFolder;
|
||||
protected AlbumsQuery $albumsQuery;
|
||||
protected IRequest $request;
|
||||
protected ICache $nomediaCache;
|
||||
|
||||
public function __construct(
|
||||
IConfig $config,
|
||||
IUserSession $userSession,
|
||||
IRootFolder $rootFolder,
|
||||
AlbumsQuery $albumsQuery,
|
||||
IRequest $request
|
||||
IRequest $request,
|
||||
ICacheFactory $cacheFactory
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->userSession = $userSession;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->albumsQuery = $albumsQuery;
|
||||
$this->request = $request;
|
||||
$this->nomediaCache = $cacheFactory->createLocal('memories:nomedia');
|
||||
}
|
||||
|
||||
/** Get the TimelineRoot object relevant to the request */
|
||||
|
@ -98,16 +106,30 @@ class FsManager
|
|||
$folder = $userFolder->get(Exif::removeExtraSlash($folderPath));
|
||||
$root->addFolder($folder);
|
||||
} else {
|
||||
// Get timeline paths
|
||||
$paths = Exif::getTimelinePaths($uid);
|
||||
if ($path = $this->request->getParam('timelinePath', null)) {
|
||||
$paths = [Exif::removeExtraSlash($path)];
|
||||
}
|
||||
|
||||
// Combined etag, for cache invalidation.
|
||||
// This is cheaper and more sensible than the root etag.
|
||||
// The only time this breaks down is if the user places a .nomedia
|
||||
// outside the timeline path; rely on expiration for that.
|
||||
$cEtag = $uid;
|
||||
|
||||
// Multiple timeline path support
|
||||
foreach ($paths as $path) {
|
||||
$root->addFolder($userFolder->get($path));
|
||||
$node = $userFolder->get($path);
|
||||
$root->addFolder($node);
|
||||
$cEtag .= $node->getEtag();
|
||||
}
|
||||
|
||||
// Add shares or external stores inside the current folders
|
||||
$root->addMountPoints();
|
||||
|
||||
// Exclude .nomedia folders
|
||||
$root->excludePaths($this->getNoMediaFolders($userFolder, md5($cEtag)));
|
||||
}
|
||||
} catch (\OCP\Files\NotFoundException $e) {
|
||||
$msg = $e->getMessage();
|
||||
|
@ -118,6 +140,27 @@ class FsManager
|
|||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of folders with .nomedia file.
|
||||
*
|
||||
* @param Folder $root root folder
|
||||
* @param string $key etag for cache key
|
||||
*/
|
||||
public function getNoMediaFolders(Folder $root, string $key): array
|
||||
{
|
||||
if (null !== ($paths = $this->nomediaCache->get($key))) {
|
||||
return $paths;
|
||||
}
|
||||
|
||||
$comp = new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', '.nomedia');
|
||||
$search = $root->search(new SearchQuery($comp, 0, 0, [], Util::getUser()));
|
||||
|
||||
$paths = array_map(fn (File $node) => \dirname($node->getPath()), $search);
|
||||
$this->nomediaCache->set($key, $paths, 60 * 60); // 1 hour
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file with ID for the current user.
|
||||
*
|
||||
|
|
|
@ -154,6 +154,11 @@ trait TimelineQueryDays
|
|||
$root = $this->root();
|
||||
}
|
||||
|
||||
// Never join against an empty root
|
||||
if (!$root || $root->isEmpty()) {
|
||||
throw new \InvalidArgumentException('Timeline root is empty');
|
||||
}
|
||||
|
||||
// Join with memories
|
||||
$baseOp = $query->expr()->eq('f.fileid', 'm.fileid');
|
||||
if ($root->isEmpty()) {
|
||||
|
|
|
@ -14,6 +14,8 @@ class TimelineRoot
|
|||
/** Initialize */
|
||||
public function __construct()
|
||||
{
|
||||
$this->folders = [];
|
||||
$this->folderPaths = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,35 +33,42 @@ class TimelineRoot
|
|||
*/
|
||||
public function addFolder(FileInfo $info)
|
||||
{
|
||||
$folderPath = $info->getPath();
|
||||
$path = $info->getPath();
|
||||
|
||||
if (FileInfo::MIMETYPE_FOLDER !== $info->getMimetype()) {
|
||||
throw new \Exception("Not a folder: {$folderPath}");
|
||||
throw new \Exception("Not a folder: {$path}");
|
||||
}
|
||||
|
||||
if (!$info->isReadable()) {
|
||||
throw new \Exception("Folder not readable: {$folderPath}");
|
||||
throw new \Exception("Folder not readable: {$path}");
|
||||
}
|
||||
|
||||
// Add top level folder
|
||||
$id = $info->getId();
|
||||
$this->folders[$id] = $info;
|
||||
$this->folderPaths[$id] = $folderPath;
|
||||
$this->setFolder($info->getId(), $info, $path);
|
||||
}
|
||||
|
||||
// Add mountpoints recursively
|
||||
public function addMountPoints()
|
||||
{
|
||||
$mp = [];
|
||||
$folders = [];
|
||||
foreach ($this->folderPaths as $id => $folderPath) {
|
||||
$mounts = \OC\Files\Filesystem::getMountManager()->findIn($folderPath);
|
||||
foreach ($mounts as &$mount) {
|
||||
$id = $mount->getStorageRootId();
|
||||
$path = $mount->getMountPoint();
|
||||
$mp[$id] = $path;
|
||||
foreach ($mounts as $mount) {
|
||||
$this->setFolder($mount->getStorageRootId(), null, $mount->getMountPoint());
|
||||
}
|
||||
}
|
||||
$this->folderPaths += $folders;
|
||||
}
|
||||
|
||||
public function excludePaths(array $paths)
|
||||
{
|
||||
foreach ($paths as $path) {
|
||||
foreach ($this->folderPaths as $id => $folderPath) {
|
||||
if (str_starts_with($folderPath, $path)) {
|
||||
unset($this->folderPaths[$id], $this->folders[$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->folderPaths += $mp;
|
||||
}
|
||||
|
||||
public function getFolderPath(int $id)
|
||||
|
@ -86,4 +95,15 @@ class TimelineRoot
|
|||
{
|
||||
return empty($this->folderPaths);
|
||||
}
|
||||
|
||||
private function setFolder(int $id, ?FileInfo $fileInfo, ?string $path)
|
||||
{
|
||||
if (null !== $path) {
|
||||
$this->folderPaths[$id] = $path;
|
||||
}
|
||||
|
||||
if (null !== $fileInfo) {
|
||||
$this->folders[$id] = $fileInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue