Fix filename of recursive mounts
parent
f1e9765814
commit
0c6d5a57b5
|
@ -9,16 +9,18 @@ use OCP\Files\Folder;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
|
|
||||||
const CTE_FOLDERS = // CTE to get all folders recursively in the given top folders excluding archive
|
const CTE_FOLDERS = // CTE to get all folders recursively in the given top folders excluding archive
|
||||||
'WITH RECURSIVE *PREFIX*cte_folders(fileid) AS (
|
'WITH RECURSIVE *PREFIX*cte_folders(fileid, rootid) AS (
|
||||||
SELECT
|
SELECT
|
||||||
f.fileid
|
f.fileid,
|
||||||
|
f.fileid AS rootid
|
||||||
FROM
|
FROM
|
||||||
*PREFIX*filecache f
|
*PREFIX*filecache f
|
||||||
WHERE
|
WHERE
|
||||||
f.fileid IN (:topFolderIds)
|
f.fileid IN (:topFolderIds)
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT
|
SELECT
|
||||||
f.fileid
|
f.fileid,
|
||||||
|
c.rootid
|
||||||
FROM
|
FROM
|
||||||
*PREFIX*filecache f
|
*PREFIX*filecache f
|
||||||
INNER JOIN *PREFIX*cte_folders c
|
INNER JOIN *PREFIX*cte_folders c
|
||||||
|
@ -65,6 +67,9 @@ trait TimelineQueryDays
|
||||||
{
|
{
|
||||||
protected IDBConnection $connection;
|
protected IDBConnection $connection;
|
||||||
|
|
||||||
|
/** Map of rootid => mount point */
|
||||||
|
private $topFolderPaths = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the days response from the database for the timeline.
|
* Get the days response from the database for the timeline.
|
||||||
*
|
*
|
||||||
|
@ -196,30 +201,51 @@ trait TimelineQueryDays
|
||||||
*/
|
*/
|
||||||
private function processDay(&$day, $uid, $folder)
|
private function processDay(&$day, $uid, $folder)
|
||||||
{
|
{
|
||||||
$basePath = '#__#__#';
|
/**
|
||||||
$davPath = '';
|
* Path entry in database for folder.
|
||||||
|
* We need to splice this from the start of the file path.
|
||||||
|
*/
|
||||||
|
$internalPaths = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DAV paths for the folders.
|
||||||
|
* We need to prefix this to the start of the file path.
|
||||||
|
*/
|
||||||
|
$davPaths = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root folder id for the folder.
|
||||||
|
* We fallback to this if rootid is not found
|
||||||
|
*/
|
||||||
|
$defaultRootId = 0;
|
||||||
|
|
||||||
if (null !== $folder) {
|
if (null !== $folder) {
|
||||||
|
// Get root id of the top folder
|
||||||
|
$defaultRootId = $folder->getId();
|
||||||
|
|
||||||
// No way to get the internal path from the folder
|
// No way to get the internal path from the folder
|
||||||
$query = $this->connection->getQueryBuilder();
|
$query = $this->connection->getQueryBuilder();
|
||||||
$query->select('path')
|
$query->select('fileid', 'path')
|
||||||
->from('filecache')
|
->from('filecache')
|
||||||
->where($query->expr()->eq('fileid', $query->createNamedParameter($folder->getId(), IQueryBuilder::PARAM_INT)))
|
->where($query->expr()->in('fileid', $query->createNamedParameter(array_keys($this->topFolderPaths), IQueryBuilder::PARAM_INT_ARRAY)))
|
||||||
;
|
;
|
||||||
$path = $query->executeQuery()->fetchOne();
|
$paths = $query->executeQuery()->fetchAll();
|
||||||
$basePath = $path ?: $basePath;
|
foreach ($paths as &$path) {
|
||||||
|
$fileid = (int) $path['fileid'];
|
||||||
|
$internalPaths[$fileid] = $path['path'];
|
||||||
|
|
||||||
// Get user facing path
|
// Get DAV path.
|
||||||
// getPath looks like /user/files/... but we want /files/user/...
|
// getPath looks like /user/files/... but we want /files/user/...
|
||||||
// Split at / and swap these
|
// Split at / and swap these
|
||||||
// For public shares, we just give the relative path
|
// For public shares, we just give the relative path
|
||||||
if (!empty($uid)) {
|
if (!empty($uid) && ($actualPath = $this->topFolderPaths[$fileid])) {
|
||||||
$actualPath = $folder->getPath();
|
|
||||||
$actualPath = explode('/', $actualPath);
|
$actualPath = explode('/', $actualPath);
|
||||||
if (\count($actualPath) >= 3) {
|
if (\count($actualPath) >= 3) {
|
||||||
$tmp = $actualPath[1];
|
$tmp = $actualPath[1];
|
||||||
$actualPath[1] = $actualPath[2];
|
$actualPath[1] = $actualPath[2];
|
||||||
$actualPath[2] = $tmp;
|
$actualPath[2] = $tmp;
|
||||||
$davPath = implode('/', $actualPath);
|
$davPaths[$fileid] = implode('/', $actualPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,9 +271,14 @@ trait TimelineQueryDays
|
||||||
|
|
||||||
// Check if path exists and starts with basePath and remove
|
// Check if path exists and starts with basePath and remove
|
||||||
if (isset($row['path']) && !empty($row['path'])) {
|
if (isset($row['path']) && !empty($row['path'])) {
|
||||||
|
$rootId = $row['rootid'] ?: $defaultRootId;
|
||||||
|
$basePath = $internalPaths[$rootId] ?: '#__#';
|
||||||
|
$davPath = $davPaths[$rootId] ?: '';
|
||||||
|
|
||||||
if (0 === strpos($row['path'], $basePath)) {
|
if (0 === strpos($row['path'], $basePath)) {
|
||||||
$row['filename'] = $davPath.substr($row['path'], \strlen($basePath));
|
$row['filename'] = $davPath.substr($row['path'], \strlen($basePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($row['path']);
|
unset($row['path']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,18 +311,10 @@ trait TimelineQueryDays
|
||||||
*/
|
*/
|
||||||
private function addSubfolderJoinParams(
|
private function addSubfolderJoinParams(
|
||||||
IQueryBuilder &$query,
|
IQueryBuilder &$query,
|
||||||
Folder &$folder,
|
|
||||||
bool $archive
|
bool $archive
|
||||||
) {
|
) {
|
||||||
// Get storages recursively
|
|
||||||
$topFolderIds = [$folder->getId()];
|
|
||||||
$mounts = \OC\Files\Filesystem::getMountManager()->findIn($folder->getPath());
|
|
||||||
foreach ($mounts as &$mount) {
|
|
||||||
$topFolderIds[] = $mount->getStorageRootId();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add query parameters
|
// Add query parameters
|
||||||
$query->setParameter('topFolderIds', $topFolderIds, IQueryBuilder::PARAM_INT_ARRAY);
|
$query->setParameter('topFolderIds', array_keys($this->topFolderPaths), IQueryBuilder::PARAM_INT_ARRAY);
|
||||||
$query->setParameter('cteFoldersArchive', $archive, IQueryBuilder::PARAM_BOOL);
|
$query->setParameter('cteFoldersArchive', $archive, IQueryBuilder::PARAM_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,12 +338,25 @@ trait TimelineQueryDays
|
||||||
return $query->innerJoin('m', 'filecache', 'f', $baseOp);
|
return $query->innerJoin('m', 'filecache', 'f', $baseOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create top folders paths for later processing
|
||||||
|
$this->topFolderPaths = [];
|
||||||
|
$this->topFolderPaths[$folder->getId()] = $folder->getPath();
|
||||||
|
|
||||||
// Filter by folder (recursive or otherwise)
|
// Filter by folder (recursive or otherwise)
|
||||||
$pathOp = null;
|
$pathOp = null;
|
||||||
if ($recursive) {
|
if ($recursive) {
|
||||||
|
// Add mountpoints recursively
|
||||||
|
$this->mounts = \OC\Files\Filesystem::getMountManager()->findIn($folder->getPath());
|
||||||
|
foreach ($this->mounts as &$mount) {
|
||||||
|
$id = $mount->getStorageRootId();
|
||||||
|
$path = $mount->getMountPoint();
|
||||||
|
$this->topFolderPaths[$id] = $path;
|
||||||
|
}
|
||||||
|
|
||||||
// Join with folders CTE
|
// Join with folders CTE
|
||||||
$this->addSubfolderJoinParams($query, $folder, $archive);
|
$this->addSubfolderJoinParams($query, $archive);
|
||||||
$query->innerJoin('f', 'cte_folders', 'cte_f', $query->expr()->eq('f.parent', 'cte_f.fileid'));
|
$query->innerJoin('f', 'cte_folders', 'cte_f', $query->expr()->eq('f.parent', 'cte_f.fileid'));
|
||||||
|
$query->addSelect('cte_f.rootid');
|
||||||
} else {
|
} else {
|
||||||
// If getting non-recursively folder only check for parent
|
// If getting non-recursively folder only check for parent
|
||||||
$pathOp = $query->expr()->eq('f.parent', $query->createNamedParameter($folder->getId(), IQueryBuilder::PARAM_INT));
|
$pathOp = $query->expr()->eq('f.parent', $query->createNamedParameter($folder->getId(), IQueryBuilder::PARAM_INT));
|
||||||
|
|
|
@ -917,7 +917,9 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
head.day.detail.length === photos.length &&
|
head.day.detail.length === photos.length &&
|
||||||
head.day.detail.every(
|
head.day.detail.every(
|
||||||
(p, i) =>
|
(p, i) =>
|
||||||
p.fileid === photos[i].fileid && p.etag === photos[i].etag
|
p.fileid === photos[i].fileid &&
|
||||||
|
p.etag === photos[i].etag &&
|
||||||
|
p.filename === photos[i].filename
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue