fs: fix recursion in folder previews

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/877/head
Varun Patil 2023-10-13 16:18:37 -07:00
parent 8414dbcda7
commit 0c2de94ee3
4 changed files with 55 additions and 16 deletions

View File

@ -2,7 +2,7 @@
namespace OCA\Memories\Controller;
use OCA\Memories\Db\TimelineQuery;
use OCA\Memories\Db\TimelineRoot;
use OCA\Memories\Exceptions;
use OCA\Memories\Util;
use OCP\AppFramework\Http;
@ -11,8 +11,6 @@ use OCP\Files\Folder;
class FoldersController extends GenericApiController
{
protected TimelineQuery $timelineQuery;
/**
* @NoAdminRequired
*/
@ -42,13 +40,23 @@ class FoldersController extends GenericApiController
// Sort by name
usort($folders, static fn ($a, $b) => strnatcmp($a->getName(), $b->getName()));
// Construct root for the base folder. This way we can reuse the
// root by filtering out the subfolders we don't want.
$root = new TimelineRoot();
$this->fs->populateRoot($root);
// Process to response type
$list = array_map(fn ($node) => [
'fileid' => $node->getId(),
'name' => $node->getName(),
'path' => $node->getPath(),
'previews' => $this->timelineQuery->getFolderPreviews($node),
], $folders);
$list = array_map(function ($node) use ($root) {
$root->addFolder($node);
$root->baseChange($node->getPath());
return [
'fileid' => $node->getId(),
'name' => $node->getName(),
'path' => $node->getPath(),
'previews' => $this->timelineQuery->getRootPreviews($root),
];
}, $folders);
return new Http\JSONResponse($list, Http::STATUS_OK);
});

View File

@ -68,8 +68,13 @@ class FsManager
$this->nomediaCache = $cacheFactory->createLocal('memories:nomedia');
}
/** Get the TimelineRoot object relevant to the request */
public function populateRoot(TimelineRoot &$root, bool $recursive)
/**
* Populate TimelineRoot object relevant to the request.
*
* @param TimelineRoot $root Root object to populate (by reference)
* @param bool $recursive Whether to get the folders recursively
*/
public function populateRoot(TimelineRoot &$root, bool $recursive = true)
{
$user = $this->userSession->getUser();

View File

@ -4,14 +4,20 @@ declare(strict_types=1);
namespace OCA\Memories\Db;
use OCP\Files\FileInfo;
use OCP\IDBConnection;
trait TimelineQueryFolders
{
protected IDBConnection $connection;
public function getFolderPreviews(FileInfo $folder)
/**
* Get the previews inside a given TimelineRoot.
* The root folder passed to this function must already be populated
* with the mount points recursively, if this is desired.
*
* @param TimelineRoot $root The root to use for the query
*/
public function getRootPreviews(TimelineRoot $root)
{
$query = $this->connection->getQueryBuilder();
@ -19,8 +25,6 @@ trait TimelineQueryFolders
$query->select('f.fileid', 'f.etag')->from('memories', 'm');
// WHERE these photos are in the user's requested folder recursively
$root = new TimelineRoot();
$root->addFolder($folder);
$query = $this->joinFilecache($query, $root, true, false);
// ORDER descending by fileid

View File

@ -39,7 +39,9 @@ class TimelineRoot
$this->setFolder($info->getId(), $info, $path);
}
// Add mountpoints recursively
/**
* Add mountpoints recursively.
*/
public function addMountPoints()
{
$manager = \OC\Files\Filesystem::getMountManager();
@ -51,6 +53,11 @@ class TimelineRoot
}
}
/**
* Exclude all folders that are in the given paths.
*
* @param string[] $paths The paths to exclude
*/
public function excludePaths(array $paths)
{
foreach ($paths as $path) {
@ -65,6 +72,21 @@ class TimelineRoot
}
}
/**
* Change the base folder to a different one.
* This excludes all folders not prefixed with the new base path.
*
* @param string $path The new base path
*/
public function baseChange(string $path)
{
foreach ($this->folderPaths as $id => $folderPath) {
if (!str_starts_with($folderPath.'/', $path.'/')) {
unset($this->folderPaths[$id], $this->folders[$id]);
}
}
}
public function getFolderPath(int $id)
{
return $this->folderPaths[$id];