parent
5c9f1c4915
commit
78d063eed6
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
|||
namespace OCA\Memories\ClustersBackend;
|
||||
|
||||
use OCA\Memories\Db\TimelineQuery;
|
||||
use OCA\Memories\Db\TimelineRoot;
|
||||
use OCA\Memories\Util;
|
||||
use OCP\IConfig;
|
||||
|
||||
|
@ -32,7 +31,6 @@ class FaceRecognitionBackend extends Backend
|
|||
{
|
||||
use PeopleBackendUtils;
|
||||
|
||||
public TimelineRoot $root;
|
||||
protected TimelineQuery $timelineQuery;
|
||||
protected IConfig $config;
|
||||
|
||||
|
@ -58,14 +56,14 @@ class FaceRecognitionBackend extends Backend
|
|||
public function getClusters(): array
|
||||
{
|
||||
return array_merge(
|
||||
$this->timelineQuery->getFaceRecognitionPersons($this->root, $this->model()),
|
||||
$this->timelineQuery->getFaceRecognitionClusters($this->root, $this->model())
|
||||
$this->timelineQuery->getFaceRecognitionPersons($this->model()),
|
||||
$this->timelineQuery->getFaceRecognitionClusters($this->model())
|
||||
);
|
||||
}
|
||||
|
||||
public function getPhotos(string $name, ?int $limit = null): array
|
||||
{
|
||||
return $this->timelineQuery->getFaceRecognitionPhotos($name, $this->model(), $this->root, $limit) ?? [];
|
||||
return $this->timelineQuery->getFaceRecognitionPhotos($name, $this->model(), $limit) ?? [];
|
||||
}
|
||||
|
||||
public function sortPhotosForPreview(array &$photos)
|
||||
|
|
|
@ -24,12 +24,10 @@ declare(strict_types=1);
|
|||
namespace OCA\Memories\ClustersBackend;
|
||||
|
||||
use OCA\Memories\Db\TimelineQuery;
|
||||
use OCA\Memories\Db\TimelineRoot;
|
||||
use OCA\Memories\Util;
|
||||
|
||||
class PlacesBackend extends Backend
|
||||
{
|
||||
public TimelineRoot $root;
|
||||
protected TimelineQuery $timelineQuery;
|
||||
|
||||
public function __construct(
|
||||
|
@ -50,11 +48,11 @@ class PlacesBackend extends Backend
|
|||
|
||||
public function getClusters(): array
|
||||
{
|
||||
return $this->timelineQuery->getPlaces($this->root);
|
||||
return $this->timelineQuery->getPlaces();
|
||||
}
|
||||
|
||||
public function getPhotos(string $name, ?int $limit = null): array
|
||||
{
|
||||
return $this->timelineQuery->getPlacePhotos((int) $name, $this->root, $limit) ?? [];
|
||||
return $this->timelineQuery->getPlacePhotos((int) $name, $limit) ?? [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,14 +24,12 @@ declare(strict_types=1);
|
|||
namespace OCA\Memories\ClustersBackend;
|
||||
|
||||
use OCA\Memories\Db\TimelineQuery;
|
||||
use OCA\Memories\Db\TimelineRoot;
|
||||
use OCA\Memories\Util;
|
||||
|
||||
class RecognizeBackend extends Backend
|
||||
{
|
||||
use PeopleBackendUtils;
|
||||
|
||||
public TimelineRoot $root;
|
||||
protected TimelineQuery $timelineQuery;
|
||||
|
||||
public function __construct(
|
||||
|
@ -52,12 +50,12 @@ class RecognizeBackend extends Backend
|
|||
|
||||
public function getClusters(): array
|
||||
{
|
||||
return $this->timelineQuery->getPeopleRecognize($this->root, Util::getUID());
|
||||
return $this->timelineQuery->getPeopleRecognize(Util::getUID());
|
||||
}
|
||||
|
||||
public function getPhotos(string $name, ?int $limit = null): array
|
||||
{
|
||||
return $this->timelineQuery->getPeopleRecognizePhotos((int) $name, $this->root, $limit) ?? [];
|
||||
return $this->timelineQuery->getPeopleRecognizePhotos((int) $name, $limit) ?? [];
|
||||
}
|
||||
|
||||
public function sortPhotosForPreview(array &$photos)
|
||||
|
|
|
@ -24,12 +24,10 @@ declare(strict_types=1);
|
|||
namespace OCA\Memories\ClustersBackend;
|
||||
|
||||
use OCA\Memories\Db\TimelineQuery;
|
||||
use OCA\Memories\Db\TimelineRoot;
|
||||
use OCA\Memories\Util;
|
||||
|
||||
class TagsBackend extends Backend
|
||||
{
|
||||
public TimelineRoot $root;
|
||||
protected TimelineQuery $timelineQuery;
|
||||
|
||||
public function __construct(
|
||||
|
@ -50,11 +48,11 @@ class TagsBackend extends Backend
|
|||
|
||||
public function getClusters(): array
|
||||
{
|
||||
return $this->timelineQuery->getTags($this->root);
|
||||
return $this->timelineQuery->getTags();
|
||||
}
|
||||
|
||||
public function getPhotos(string $name, ?int $limit = null): array
|
||||
{
|
||||
return $this->timelineQuery->getTagPhotos($name, $this->root, $limit) ?? [];
|
||||
return $this->timelineQuery->getTagPhotos($name, $limit) ?? [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,13 +123,6 @@ class ClustersController extends GenericApiController
|
|||
if (!$this->backend->isEnabled()) {
|
||||
throw Exceptions::NotEnabled($this->backend->appName());
|
||||
}
|
||||
|
||||
if (property_exists($this->backend, 'root')) {
|
||||
$this->backend->root = $this->getRequestRoot();
|
||||
if ($this->backend->root->isEmpty()) {
|
||||
throw Exceptions::NoRequestRoot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Memories\Controller;
|
||||
|
||||
use OCA\Memories\Db\TimelineRoot;
|
||||
use OCA\Memories\Exceptions;
|
||||
use OCA\Memories\Util;
|
||||
use OCP\AppFramework\Http;
|
||||
|
@ -42,10 +41,8 @@ class DaysController extends GenericApiController
|
|||
{
|
||||
return Util::guardEx(function () {
|
||||
$uid = $this->getShareToken() ? '' : Util::getUID();
|
||||
$root = $this->getRequestRoot();
|
||||
|
||||
$list = $this->timelineQuery->getDays(
|
||||
$root,
|
||||
$uid,
|
||||
$this->isRecursive(),
|
||||
$this->isArchive(),
|
||||
|
@ -57,7 +54,7 @@ class DaysController extends GenericApiController
|
|||
$list = $this->timelineQuery->daysToMonths($list);
|
||||
} else {
|
||||
// Preload some day responses
|
||||
$this->preloadDays($list, $uid, $root);
|
||||
$this->preloadDays($list, $uid);
|
||||
}
|
||||
|
||||
// Reverse response if requested. Folders still stay at top.
|
||||
|
@ -67,6 +64,7 @@ class DaysController extends GenericApiController
|
|||
|
||||
// Add subfolder info if querying non-recursively
|
||||
if (!$this->isRecursive()) {
|
||||
$root = $this->timelineQuery->root();
|
||||
array_unshift($list, $this->getSubfoldersEntry($root->getFolder($root->getOneId())));
|
||||
}
|
||||
|
||||
|
@ -98,9 +96,6 @@ class DaysController extends GenericApiController
|
|||
return new JSONResponse([], Http::STATUS_OK);
|
||||
}
|
||||
|
||||
// Get the folder to show
|
||||
$root = $this->getRequestRoot();
|
||||
|
||||
// Convert to actual dayIds if month view
|
||||
if ($this->isMonthView()) {
|
||||
$dayIds = $this->timelineQuery->monthIdToDayIds((int) $dayIds[0]);
|
||||
|
@ -108,7 +103,6 @@ class DaysController extends GenericApiController
|
|||
|
||||
// Run actual query
|
||||
$list = $this->timelineQuery->getDay(
|
||||
$root,
|
||||
$uid,
|
||||
$dayIds,
|
||||
$this->isRecursive(),
|
||||
|
@ -158,17 +152,9 @@ class DaysController extends GenericApiController
|
|||
{
|
||||
$transforms = [];
|
||||
|
||||
// Add extra information, basename and mimetype
|
||||
if (!$aggregateOnly && ($fields = $this->request->getParam('fields'))) {
|
||||
$fields = explode(',', $fields);
|
||||
$transforms[] = [$this->timelineQuery, 'transformExtraFields', $fields];
|
||||
}
|
||||
|
||||
// Filter for one album
|
||||
if (Util::albumsIsEnabled()) {
|
||||
if ($albumId = $this->request->getParam('album')) {
|
||||
$transforms[] = [$this->timelineQuery, 'transformAlbumFilter', $albumId];
|
||||
}
|
||||
if (($albumId = $this->request->getParam('album')) && Util::albumsIsEnabled()) {
|
||||
$transforms[] = [$this->timelineQuery, 'transformAlbumFilter', $albumId];
|
||||
}
|
||||
|
||||
// Other transforms not allowed for public shares
|
||||
|
@ -235,11 +221,10 @@ class DaysController extends GenericApiController
|
|||
/**
|
||||
* Preload a few "day" at the start of "days" response.
|
||||
*
|
||||
* @param array $days the days array
|
||||
* @param string $uid User ID or blank for public shares
|
||||
* @param TimelineRoot $root the root folder
|
||||
* @param array $days the days array
|
||||
* @param string $uid User ID or blank for public shares
|
||||
*/
|
||||
private function preloadDays(array &$days, string $uid, TimelineRoot &$root)
|
||||
private function preloadDays(array &$days, string $uid)
|
||||
{
|
||||
$transforms = $this->getTransformations(false);
|
||||
$preloaded = 0;
|
||||
|
@ -261,7 +246,6 @@ class DaysController extends GenericApiController
|
|||
|
||||
if (\count($preloadDayIds) > 0) {
|
||||
$allDetails = $this->timelineQuery->getDay(
|
||||
$root,
|
||||
$uid,
|
||||
$preloadDayIds,
|
||||
$this->isRecursive(),
|
||||
|
|
|
@ -128,7 +128,7 @@ class DownloadController extends GenericApiController
|
|||
public function one(int $fileid): Http\Response
|
||||
{
|
||||
return Util::guardEx(function () use ($fileid) {
|
||||
$file = $this->getUserFile($fileid);
|
||||
$file = $this->fs->getUserFile($fileid);
|
||||
if (null === $file) {
|
||||
return Exceptions::NotFoundFile($fileid);
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ class DownloadController extends GenericApiController
|
|||
|
||||
try {
|
||||
// This checks permissions
|
||||
$file = $this->getUserFile($fileId);
|
||||
$file = $this->fs->getUserFile($fileId);
|
||||
if (null === $file) {
|
||||
throw new \Exception('File not found');
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace OCA\Memories\Controller;
|
|||
|
||||
use OCA\Memories\AppInfo\Application;
|
||||
use OCA\Memories\Db\TimelineQuery;
|
||||
use OCA\Memories\Manager\FsManager;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\Files\IRootFolder;
|
||||
|
@ -36,16 +37,16 @@ use Psr\Log\LoggerInterface;
|
|||
|
||||
abstract class GenericApiController extends Controller
|
||||
{
|
||||
use GenericApiControllerFs;
|
||||
use GenericApiControllerParams;
|
||||
|
||||
protected IConfig $config;
|
||||
protected IUserSession $userSession;
|
||||
protected IRootFolder $rootFolder;
|
||||
protected IAppManager $appManager;
|
||||
protected TimelineQuery $timelineQuery;
|
||||
protected IDBConnection $connection;
|
||||
protected LoggerInterface $logger;
|
||||
protected TimelineQuery $timelineQuery;
|
||||
protected FsManager $fs;
|
||||
|
||||
public function __construct(
|
||||
IRequest $request,
|
||||
|
@ -55,7 +56,8 @@ abstract class GenericApiController extends Controller
|
|||
IRootFolder $rootFolder,
|
||||
IAppManager $appManager,
|
||||
LoggerInterface $logger,
|
||||
TimelineQuery $timelineQuery
|
||||
TimelineQuery $timelineQuery,
|
||||
FsManager $fs
|
||||
) {
|
||||
parent::__construct(Application::APPNAME, $request);
|
||||
|
||||
|
@ -66,5 +68,6 @@ abstract class GenericApiController extends Controller
|
|||
$this->appManager = $appManager;
|
||||
$this->logger = $logger;
|
||||
$this->timelineQuery = $timelineQuery;
|
||||
$this->fs = $fs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class ImageController extends GenericApiController
|
|||
throw Exceptions::MissingParameter('id, x, y');
|
||||
}
|
||||
|
||||
$file = $this->getUserFile($id);
|
||||
$file = $this->fs->getUserFile($id);
|
||||
if (!$file) {
|
||||
throw Exceptions::NotFoundFile($id);
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ class ImageController extends GenericApiController
|
|||
continue;
|
||||
}
|
||||
|
||||
$file = $this->getUserFile($fileid);
|
||||
$file = $this->fs->getUserFile($fileid);
|
||||
if (!$file) {
|
||||
continue;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ class ImageController extends GenericApiController
|
|||
bool $tags = false
|
||||
): Http\Response {
|
||||
return Util::guardEx(function () use ($id, $basic, $current, $tags) {
|
||||
$file = $this->getUserFile((int) $id);
|
||||
$file = $this->fs->getUserFile((int) $id);
|
||||
if (!$file) {
|
||||
throw Exceptions::NotFoundFile($id);
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ class ImageController extends GenericApiController
|
|||
public function setExif(string $id, array $raw): Http\Response
|
||||
{
|
||||
return Util::guardEx(function () use ($id, $raw) {
|
||||
$file = $this->getUserFile((int) $id);
|
||||
$file = $this->fs->getUserFile((int) $id);
|
||||
if (!$file) {
|
||||
throw Exceptions::NotFoundFile($id);
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ class ImageController extends GenericApiController
|
|||
public function decodable(string $id): Http\Response
|
||||
{
|
||||
return Util::guardEx(function () use ($id) {
|
||||
$file = $this->getUserFile((int) $id);
|
||||
$file = $this->fs->getUserFile((int) $id);
|
||||
if (!$file) {
|
||||
throw Exceptions::NotFoundFile($id);
|
||||
}
|
||||
|
|
|
@ -36,9 +36,6 @@ class MapController extends GenericApiController
|
|||
public function clusters(): Http\Response
|
||||
{
|
||||
return Util::guardEx(function () {
|
||||
// Get the folder to show
|
||||
$root = $this->getRequestRoot();
|
||||
|
||||
// Make sure we have bounds and zoom level
|
||||
// Zoom level is used to determine the grid length
|
||||
$bounds = $this->request->getParam('bounds');
|
||||
|
@ -52,11 +49,11 @@ class MapController extends GenericApiController
|
|||
$clusterDensity = 1;
|
||||
$gridLen = 180.0 / (2 ** $zoomLevel * $clusterDensity);
|
||||
|
||||
$clusters = $this->timelineQuery->getMapClusters($gridLen, $bounds, $root);
|
||||
$clusters = $this->timelineQuery->getMapClusters($gridLen, $bounds);
|
||||
|
||||
// Get previews for each cluster
|
||||
$clusterIds = array_map(fn ($cluster) => (int) $cluster['id'], $clusters);
|
||||
$previews = $this->timelineQuery->getMapClusterPreviews($clusterIds, $root);
|
||||
$previews = $this->timelineQuery->getMapClusterPreviews($clusterIds);
|
||||
|
||||
// Merge the responses
|
||||
$fileMap = [];
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace OCA\Memories\Controller;
|
|||
|
||||
use OCA\Memories\AppInfo\Application;
|
||||
use OCA\Memories\Db\TimelineQuery;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\AuthPublicShareController;
|
||||
use OCP\AppFramework\Http\Template\PublicTemplateResponse;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
|
@ -16,7 +15,6 @@ use OCP\IConfig;
|
|||
use OCP\IRequest;
|
||||
use OCP\ISession;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Share\IManager as IShareManager;
|
||||
use OCP\Share\IShare;
|
||||
|
@ -30,8 +28,6 @@ class PublicController extends AuthPublicShareController
|
|||
protected IUserSession $userSession;
|
||||
protected IRootFolder $rootFolder;
|
||||
protected IShareManager $shareManager;
|
||||
protected IUserManager $userManager;
|
||||
protected IAppManager $appManager;
|
||||
protected IConfig $config;
|
||||
protected TimelineQuery $timelineQuery;
|
||||
|
||||
|
@ -47,8 +43,6 @@ class PublicController extends AuthPublicShareController
|
|||
IUserSession $userSession,
|
||||
IRootFolder $rootFolder,
|
||||
IShareManager $shareManager,
|
||||
IUserManager $userManager,
|
||||
IAppManager $appManager,
|
||||
IConfig $config,
|
||||
TimelineQuery $timelineQuery
|
||||
) {
|
||||
|
@ -58,8 +52,6 @@ class PublicController extends AuthPublicShareController
|
|||
$this->userSession = $userSession;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->shareManager = $shareManager;
|
||||
$this->userManager = $userManager;
|
||||
$this->appManager = $appManager;
|
||||
$this->config = $config;
|
||||
$this->timelineQuery = $timelineQuery;
|
||||
}
|
||||
|
@ -106,7 +98,7 @@ class PublicController extends AuthPublicShareController
|
|||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if (!self::validateShare($share)) {
|
||||
if (!\OCA\Memories\Manager\FsManager::validateShare($share)) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
|
@ -144,38 +136,6 @@ class PublicController extends AuthPublicShareController
|
|||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the permissions of the share.
|
||||
*/
|
||||
public static function validateShare(?IShare $share): bool
|
||||
{
|
||||
if (null === $share) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get user manager
|
||||
$userManager = \OC::$server->get(IUserManager::class);
|
||||
|
||||
// Check if share read is allowed
|
||||
if (!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the owner is disabled no access to the linke is granted
|
||||
$owner = $userManager->get($share->getShareOwner());
|
||||
if (null === $owner || !$owner->isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the initiator of the share is disabled no access is granted
|
||||
$initiator = $userManager->get($share->getSharedBy());
|
||||
if (null === $initiator || !$initiator->isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $share->getNode()->isReadable() && $share->getNode()->isShareable();
|
||||
}
|
||||
|
||||
protected function showAuthFailed(): TemplateResponse
|
||||
{
|
||||
$templateParameters = ['share' => $this->share, 'wrongpw' => true];
|
||||
|
|
|
@ -118,7 +118,7 @@ class ShareController extends GenericApiController
|
|||
try {
|
||||
$file = null;
|
||||
if ($id) {
|
||||
$file = $this->getUserFile($id);
|
||||
$file = $this->fs->getUserFile($id);
|
||||
} elseif ($path) {
|
||||
$file = Util::getUserFolder($uid)->get($path);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ class TagsController extends GenericApiController
|
|||
}
|
||||
|
||||
// Check the user is allowed to edit the file
|
||||
$file = $this->getUserFile($id);
|
||||
$file = $this->fs->getUserFile($id);
|
||||
if (null === $file) {
|
||||
throw Exceptions::NotFoundFile($id);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ class VideoController extends GenericApiController
|
|||
}
|
||||
|
||||
// Get file
|
||||
$file = $this->getUserFile($fileid);
|
||||
$file = $this->fs->getUserFile($fileid);
|
||||
if (!$file || !$file->isReadable()) {
|
||||
throw Exceptions::NotFoundFile($fileid);
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ class VideoController extends GenericApiController
|
|||
string $transcode = ''
|
||||
) {
|
||||
return Util::guardEx(function () use ($fileid, $liveid, $format, $transcode) {
|
||||
$file = $this->getUserFile($fileid);
|
||||
$file = $this->fs->getUserFile($fileid);
|
||||
if (null === $file) {
|
||||
throw Exceptions::NotFoundFile($fileid);
|
||||
}
|
||||
|
|
|
@ -27,12 +27,24 @@ class TimelineQuery
|
|||
];
|
||||
|
||||
protected IDBConnection $connection;
|
||||
private ?TimelineRoot $_root = null;
|
||||
|
||||
public function __construct(IDBConnection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function root(): TimelineRoot
|
||||
{
|
||||
if (null === $this->_root) {
|
||||
$this->_root = new TimelineRoot();
|
||||
$fsManager = \OC::$server->get(\OCA\Memories\Manager\FsManager::class);
|
||||
$fsManager->populateRoot($this->_root);
|
||||
}
|
||||
|
||||
return $this->_root;
|
||||
}
|
||||
|
||||
public static function debugQuery(IQueryBuilder &$query, string $sql = '')
|
||||
{
|
||||
// Print the query and exit
|
||||
|
@ -63,10 +75,6 @@ class TimelineQuery
|
|||
return $sql;
|
||||
}
|
||||
|
||||
public function transformExtraFields(IQueryBuilder &$query, string $uid, array &$fields)
|
||||
{
|
||||
}
|
||||
|
||||
public function getInfoById(int $id, bool $basic): array
|
||||
{
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
|
|
|
@ -78,15 +78,13 @@ trait TimelineQueryDays
|
|||
/**
|
||||
* Get the days response from the database for the timeline.
|
||||
*
|
||||
* @param TimelineRoot $root The root to get the days from
|
||||
* @param bool $recursive Whether to get the days recursively
|
||||
* @param bool $archive Whether to get the days only from the archive folder
|
||||
* @param array $queryTransforms An array of query transforms to apply to the query
|
||||
* @param bool $recursive Whether to get the days recursively
|
||||
* @param bool $archive Whether to get the days only from the archive folder
|
||||
* @param array $queryTransforms An array of query transforms to apply to the query
|
||||
*
|
||||
* @return array The days response
|
||||
*/
|
||||
public function getDays(
|
||||
TimelineRoot &$root,
|
||||
string $uid,
|
||||
bool $recursive,
|
||||
bool $archive,
|
||||
|
@ -99,7 +97,7 @@ trait TimelineQueryDays
|
|||
$query->select('m.dayid', $count)
|
||||
->from('memories', 'm')
|
||||
;
|
||||
$query = $this->joinFilecache($query, $root, $recursive, $archive);
|
||||
$query = $this->joinFilecache($query, null, $recursive, $archive);
|
||||
|
||||
// Group and sort by dayid
|
||||
$query->groupBy('m.dayid')
|
||||
|
@ -119,18 +117,16 @@ trait TimelineQueryDays
|
|||
/**
|
||||
* Get the day response from the database for the timeline.
|
||||
*
|
||||
* @param TimelineRoot $root The root to get the day from
|
||||
* @param string $uid The user id
|
||||
* @param int[] $day_ids The day ids to fetch
|
||||
* @param bool $recursive If the query should be recursive
|
||||
* @param bool $archive If the query should include only the archive folder
|
||||
* @param array $queryTransforms The query transformations to apply
|
||||
* @param mixed $day_ids
|
||||
* @param string $uid The user id
|
||||
* @param int[] $day_ids The day ids to fetch
|
||||
* @param bool $recursive If the query should be recursive
|
||||
* @param bool $archive If the query should include only the archive folder
|
||||
* @param array $queryTransforms The query transformations to apply
|
||||
* @param mixed $day_ids
|
||||
*
|
||||
* @return array An array of day responses
|
||||
*/
|
||||
public function getDay(
|
||||
TimelineRoot &$root,
|
||||
string $uid,
|
||||
?array $day_ids,
|
||||
bool $recursive,
|
||||
|
@ -150,7 +146,7 @@ trait TimelineQueryDays
|
|||
;
|
||||
|
||||
// JOIN with filecache for existing files
|
||||
$query = $this->joinFilecache($query, $root, $recursive, $archive);
|
||||
$query = $this->joinFilecache($query, null, $recursive, $archive);
|
||||
|
||||
// JOIN with mimetypes to get the mimetype
|
||||
$query->join('f', 'mimetypes', 'mimetypes', $query->expr()->eq('f.mimetype', 'mimetypes.id'));
|
||||
|
@ -271,11 +267,15 @@ trait TimelineQueryDays
|
|||
* @param bool $archive Whether to get the days only from the archive folder
|
||||
*/
|
||||
private function joinFilecache(
|
||||
IQueryBuilder &$query,
|
||||
TimelineRoot &$root,
|
||||
bool $recursive,
|
||||
bool $archive
|
||||
IQueryBuilder $query,
|
||||
?TimelineRoot $root = null,
|
||||
bool $recursive = true,
|
||||
bool $archive = false
|
||||
) {
|
||||
if (null === $root) {
|
||||
$root = $this->root();
|
||||
}
|
||||
|
||||
// Join with memories
|
||||
$baseOp = $query->expr()->eq('f.fileid', 'm.fileid');
|
||||
if ($root->isEmpty()) {
|
||||
|
|
|
@ -33,8 +33,7 @@ trait TimelineQueryMap
|
|||
|
||||
public function getMapClusters(
|
||||
float $gridLen,
|
||||
string $bounds,
|
||||
TimelineRoot &$root
|
||||
string $bounds
|
||||
): array {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -57,7 +56,7 @@ trait TimelineQueryMap
|
|||
$query->innerJoin('c', 'memories', 'm', $query->expr()->eq('c.id', 'm.mapcluster'));
|
||||
|
||||
// JOIN with filecache for existing files
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// Bound the query to the map bounds
|
||||
$this->transformMapBoundsFilter($query, '', $bounds, 'c');
|
||||
|
@ -86,7 +85,7 @@ trait TimelineQueryMap
|
|||
return $clusters;
|
||||
}
|
||||
|
||||
public function getMapClusterPreviews(array $clusterIds, TimelineRoot &$root)
|
||||
public function getMapClusterPreviews(array $clusterIds)
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -97,7 +96,7 @@ trait TimelineQueryMap
|
|||
);
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// GROUP BY the cluster
|
||||
$query->groupBy('m.mapcluster');
|
||||
|
|
|
@ -58,7 +58,7 @@ trait TimelineQueryPeopleFaceRecognition
|
|||
);
|
||||
}
|
||||
|
||||
public function getFaceRecognitionPhotos(string $id, int $currentModel, TimelineRoot &$root, ?int $limit)
|
||||
public function getFaceRecognitionPhotos(string $id, int $currentModel, ?int $limit)
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -95,7 +95,7 @@ trait TimelineQueryPeopleFaceRecognition
|
|||
}
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// LIMIT results
|
||||
if (null !== $limit) {
|
||||
|
@ -110,7 +110,7 @@ trait TimelineQueryPeopleFaceRecognition
|
|||
return $this->executeQueryWithCTEs($query)->fetchAll();
|
||||
}
|
||||
|
||||
public function getFaceRecognitionClusters(TimelineRoot &$root, int $currentModel, bool $show_singles = false, bool $show_hidden = false)
|
||||
public function getFaceRecognitionClusters(int $currentModel, bool $show_singles = false, bool $show_hidden = false)
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -133,7 +133,7 @@ trait TimelineQueryPeopleFaceRecognition
|
|||
));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// GROUP by ID of face cluster
|
||||
$query->groupBy('frp.id');
|
||||
|
@ -170,7 +170,7 @@ trait TimelineQueryPeopleFaceRecognition
|
|||
return $faces;
|
||||
}
|
||||
|
||||
public function getFaceRecognitionPersons(TimelineRoot &$root, int $currentModel)
|
||||
public function getFaceRecognitionPersons(int $currentModel)
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -193,7 +193,7 @@ trait TimelineQueryPeopleFaceRecognition
|
|||
));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// GROUP by name of face clusters
|
||||
$query->where($query->expr()->isNotNull('frp.name'));
|
||||
|
|
|
@ -62,7 +62,7 @@ trait TimelineQueryPeopleRecognize
|
|||
);
|
||||
}
|
||||
|
||||
public function getPeopleRecognize(TimelineRoot &$root, string $uid)
|
||||
public function getPeopleRecognize(string $uid)
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -77,7 +77,7 @@ trait TimelineQueryPeopleRecognize
|
|||
$query->innerJoin('rfd', 'memories', 'm', $query->expr()->eq('m.fileid', 'rfd.file_id'));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// WHERE this cluster belongs to the user
|
||||
$query->where($query->expr()->eq('rfc.user_id', $query->createNamedParameter($uid)));
|
||||
|
@ -105,7 +105,7 @@ trait TimelineQueryPeopleRecognize
|
|||
return $faces;
|
||||
}
|
||||
|
||||
public function getPeopleRecognizePhotos(int $id, TimelineRoot $root, ?int $limit): array
|
||||
public function getPeopleRecognizePhotos(int $id, ?int $limit): array
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -129,7 +129,7 @@ trait TimelineQueryPeopleRecognize
|
|||
$query->innerJoin('rfd', 'memories', 'm', $query->expr()->eq('m.fileid', 'rfd.file_id'));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// LIMIT results
|
||||
if (null !== $limit) {
|
||||
|
|
|
@ -19,7 +19,7 @@ trait TimelineQueryPlaces
|
|||
));
|
||||
}
|
||||
|
||||
public function getPlaces(TimelineRoot &$root)
|
||||
public function getPlaces()
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -34,7 +34,7 @@ trait TimelineQueryPlaces
|
|||
$query->innerJoin('mp', 'memories', 'm', $query->expr()->eq('m.fileid', 'mp.fileid'));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// GROUP and ORDER by tag name
|
||||
$query->groupBy('e.osm_id', 'e.name');
|
||||
|
@ -54,7 +54,7 @@ trait TimelineQueryPlaces
|
|||
return $places;
|
||||
}
|
||||
|
||||
public function getPlacePhotos(int $id, TimelineRoot $root, ?int $limit): array
|
||||
public function getPlacePhotos(int $id, ?int $limit): array
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -67,7 +67,7 @@ trait TimelineQueryPlaces
|
|||
$query->innerJoin('mp', 'memories', 'm', $query->expr()->eq('m.fileid', 'mp.fileid'));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// MAX number of photos
|
||||
if (null !== $limit) {
|
||||
|
|
|
@ -37,7 +37,7 @@ trait TimelineQueryTags
|
|||
));
|
||||
}
|
||||
|
||||
public function getTags(TimelineRoot &$root)
|
||||
public function getTags()
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
|
@ -57,7 +57,7 @@ trait TimelineQueryTags
|
|||
$query->innerJoin('stom', 'memories', 'm', $query->expr()->eq('m.objectid', 'stom.objectid'));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// GROUP and ORDER by tag name
|
||||
$query->groupBy('st.id');
|
||||
|
@ -77,7 +77,7 @@ trait TimelineQueryTags
|
|||
return $tags;
|
||||
}
|
||||
|
||||
public function getTagPhotos(string $tagName, TimelineRoot $root, ?int $limit)
|
||||
public function getTagPhotos(string $tagName, ?int $limit)
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$tagId = $this->getSystemTagId($query, $tagName);
|
||||
|
@ -98,7 +98,7 @@ trait TimelineQueryTags
|
|||
$query->innerJoin('stom', 'memories', 'm', $query->expr()->eq('m.objectid', 'stom.objectid'));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query = $this->joinFilecache($query, $root, true, false);
|
||||
$query = $this->joinFilecache($query);
|
||||
|
||||
// MAX number of files
|
||||
if (null !== $limit) {
|
||||
|
|
|
@ -68,7 +68,7 @@ class Exif
|
|||
/**
|
||||
* Get the path to the user's configured photos directory.
|
||||
*/
|
||||
public static function getPhotosPath(IConfig &$config, string &$userId)
|
||||
public static function getPhotosPath(IConfig $config, string &$userId)
|
||||
{
|
||||
$p = $config->getUserValue($userId, Application::APPNAME, 'timelinePath', '');
|
||||
if (empty($p)) {
|
||||
|
|
|
@ -21,7 +21,7 @@ declare(strict_types=1);
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OCA\Memories\Controller;
|
||||
namespace OCA\Memories\Manager;
|
||||
|
||||
use OCA\Memories\Db\TimelineQuery;
|
||||
use OCA\Memories\Db\TimelineRoot;
|
||||
|
@ -31,22 +31,37 @@ use OCP\Files\File;
|
|||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Share\IShare;
|
||||
|
||||
trait GenericApiControllerFs
|
||||
class FsManager
|
||||
{
|
||||
use GenericApiControllerParams;
|
||||
|
||||
protected IConfig $config;
|
||||
protected IUserSession $userSession;
|
||||
protected IRootFolder $rootFolder;
|
||||
protected TimelineQuery $timelineQuery;
|
||||
protected IRequest $request;
|
||||
|
||||
public function __construct(
|
||||
IConfig $config,
|
||||
IUserSession $userSession,
|
||||
IRootFolder $rootFolder,
|
||||
TimelineQuery $timelineQuery,
|
||||
IRequest $request
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->userSession = $userSession;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->timelineQuery = $timelineQuery;
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/** Get the TimelineRoot object relevant to the request */
|
||||
protected function getRequestRoot()
|
||||
public function populateRoot(TimelineRoot &$root)
|
||||
{
|
||||
$user = $this->userSession->getUser();
|
||||
$root = new TimelineRoot();
|
||||
|
||||
// Albums have no folder
|
||||
if ($this->request->getParam('album') && Util::albumsIsEnabled()) {
|
||||
|
@ -71,7 +86,7 @@ trait GenericApiControllerFs
|
|||
|
||||
// Anything else needs a user
|
||||
if (null === $user) {
|
||||
throw new \Exception('User not logged in');
|
||||
throw new \Exception('User not logged in: no timeline root');
|
||||
}
|
||||
$uid = $user->getUID();
|
||||
|
||||
|
@ -107,7 +122,7 @@ trait GenericApiControllerFs
|
|||
/**
|
||||
* Get a file with ID for the current user.
|
||||
*/
|
||||
protected function getUserFile(int $fileId): ?File
|
||||
public function getUserFile(int $fileId): ?File
|
||||
{
|
||||
// Don't check self for share token
|
||||
if ($this->getShareToken()) {
|
||||
|
@ -122,7 +137,7 @@ trait GenericApiControllerFs
|
|||
/**
|
||||
* Get a file with ID from user's folder.
|
||||
*/
|
||||
protected function getUserFolderFile(int $id): ?File
|
||||
public function getUserFolderFile(int $id): ?File
|
||||
{
|
||||
$user = $this->userSession->getUser();
|
||||
if (null === $user) {
|
||||
|
@ -138,8 +153,10 @@ trait GenericApiControllerFs
|
|||
|
||||
/**
|
||||
* Get a file with ID from an album.
|
||||
*
|
||||
* @param int $id FileID
|
||||
*/
|
||||
protected function getAlbumFile(int $id): ?File
|
||||
public function getAlbumFile(int $id): ?File
|
||||
{
|
||||
$user = $this->userSession->getUser();
|
||||
if (null === $user) {
|
||||
|
@ -163,9 +180,9 @@ trait GenericApiControllerFs
|
|||
/**
|
||||
* Get a file with ID from a public share.
|
||||
*
|
||||
* @param int $fileId
|
||||
* @param int $id FileID
|
||||
*/
|
||||
protected function getShareFile(int $id): ?File
|
||||
public function getShareFile(int $id): ?File
|
||||
{
|
||||
try {
|
||||
// Album share
|
||||
|
@ -205,7 +222,7 @@ trait GenericApiControllerFs
|
|||
return null;
|
||||
}
|
||||
|
||||
protected function getShareObject()
|
||||
public function getShareObject()
|
||||
{
|
||||
// Get token from request
|
||||
$token = $this->getShareToken();
|
||||
|
@ -215,7 +232,7 @@ trait GenericApiControllerFs
|
|||
|
||||
// Get share by token
|
||||
$share = \OC::$server->get(\OCP\Share\IManager::class)->getShareByToken($token);
|
||||
if (!PublicController::validateShare($share)) {
|
||||
if (!self::validateShare($share)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -235,14 +252,14 @@ trait GenericApiControllerFs
|
|||
return $share;
|
||||
}
|
||||
|
||||
protected function getShareNode()
|
||||
public function getShareNode()
|
||||
{
|
||||
$share = $this->getShareObject();
|
||||
if (null === $share) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get node from share
|
||||
// Get node from share
|
||||
$node = $share->getNode(); // throws exception if not found
|
||||
if (!$node->isReadable() || !$node->isShareable()) {
|
||||
throw new \Exception('Share not found or invalid');
|
||||
|
@ -254,6 +271,38 @@ trait GenericApiControllerFs
|
|||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the permissions of the share.
|
||||
*/
|
||||
public static function validateShare(?IShare $share): bool
|
||||
{
|
||||
if (null === $share) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get user manager
|
||||
$userManager = \OC::$server->get(IUserManager::class);
|
||||
|
||||
// Check if share read is allowed
|
||||
if (!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the owner is disabled no access to the linke is granted
|
||||
$owner = $userManager->get($share->getShareOwner());
|
||||
if (null === $owner || !$owner->isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the initiator of the share is disabled no access is granted
|
||||
$initiator = $userManager->get($share->getSharedBy());
|
||||
if (null === $initiator || !$initiator->isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $share->getNode()->isReadable() && $share->getNode()->isShareable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get one file or null from a fiolder.
|
||||
*
|
||||
|
@ -287,4 +336,9 @@ trait GenericApiControllerFs
|
|||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function getShareToken()
|
||||
{
|
||||
return $this->request->getParam('token');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue