Add get tags API
parent
90ccce5477
commit
994320f78e
|
@ -20,6 +20,7 @@ return [
|
|||
['name' => 'api#days', 'url' => '/api/days', 'verb' => 'GET'],
|
||||
['name' => 'api#dayPost', 'url' => '/api/days', 'verb' => 'POST'],
|
||||
['name' => 'api#day', 'url' => '/api/days/{id}', 'verb' => 'GET'],
|
||||
['name' => 'api#tags', 'url' => '/api/tags', 'verb' => 'GET'],
|
||||
['name' => 'api#imageInfo', 'url' => '/api/info/{id}', 'verb' => 'GET'],
|
||||
['name' => 'api#imageEdit', 'url' => '/api/edit/{id}', 'verb' => 'PATCH'],
|
||||
['name' => 'api#archive', 'url' => '/api/archive/{id}', 'verb' => 'PATCH'],
|
||||
|
|
|
@ -261,6 +261,31 @@ class ApiController extends Controller {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*
|
||||
* Get list of tags with counts of images
|
||||
* @return JSONResponse
|
||||
*/
|
||||
public function tags(): JSONResponse {
|
||||
$user = $this->userSession->getUser();
|
||||
if (is_null($user)) {
|
||||
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
// If this isn't the timeline folder then things aren't going to work
|
||||
$folder = $this->getRequestFolder();
|
||||
if (is_null($folder)) {
|
||||
return new JSONResponse([], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Run actual query
|
||||
$list = $this->timelineQuery->getTags(
|
||||
$folder,
|
||||
);
|
||||
return new JSONResponse($list, Http::STATUS_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*
|
||||
|
|
|
@ -8,6 +8,7 @@ use OCP\IDBConnection;
|
|||
class TimelineQuery {
|
||||
use TimelineQueryDays;
|
||||
use TimelineQueryFilters;
|
||||
use TimelineQueryTags;
|
||||
|
||||
protected IDBConnection $connection;
|
||||
|
||||
|
|
|
@ -44,26 +44,4 @@ trait TimelineQueryFilters {
|
|||
public function transformVideoFilter(IQueryBuilder &$query, string $userId) {
|
||||
$query->andWhere($query->expr()->eq('m.isvideo', $query->createNamedParameter('1')));
|
||||
}
|
||||
|
||||
public function getSystemTagId(IQueryBuilder &$query, string $tagName) {
|
||||
$sqb = $query->getConnection()->getQueryBuilder();
|
||||
return $sqb->select('id')->from('systemtag')->where(
|
||||
$sqb->expr()->andX(
|
||||
$sqb->expr()->eq('name', $sqb->createNamedParameter($tagName)),
|
||||
$sqb->expr()->eq('visibility', $sqb->createNamedParameter(1)),
|
||||
))->executeQuery()->fetchOne();
|
||||
}
|
||||
|
||||
public function transformTagFilter(IQueryBuilder &$query, string $userId, string $tagName) {
|
||||
$tagId = $this->getSystemTagId($query, $tagName);
|
||||
if ($tagId === FALSE) {
|
||||
$tagId = 0; // cannot abort here; that will show up everything in the response
|
||||
}
|
||||
|
||||
$query->innerJoin('m', 'systemtag_object_mapping', 'stom', $query->expr()->andX(
|
||||
$query->expr()->eq('stom.objecttype', $query->createNamedParameter("files")),
|
||||
$query->expr()->eq('stom.objectid', 'm.fileid'),
|
||||
$query->expr()->eq('stom.systemtagid', $query->createNamedParameter($tagId)),
|
||||
));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Memories\Db;
|
||||
|
||||
use OCP\IDBConnection;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\Files\Folder;
|
||||
|
||||
trait TimelineQueryTags {
|
||||
protected IDBConnection $connection;
|
||||
|
||||
public function getSystemTagId(IQueryBuilder &$query, string $tagName) {
|
||||
$sqb = $query->getConnection()->getQueryBuilder();
|
||||
return $sqb->select('id')->from('systemtag')->where(
|
||||
$sqb->expr()->andX(
|
||||
$sqb->expr()->eq('name', $sqb->createNamedParameter($tagName)),
|
||||
$sqb->expr()->eq('visibility', $sqb->createNamedParameter(1)),
|
||||
))->executeQuery()->fetchOne();
|
||||
}
|
||||
|
||||
public function transformTagFilter(IQueryBuilder &$query, string $userId, string $tagName) {
|
||||
$tagId = $this->getSystemTagId($query, $tagName);
|
||||
if ($tagId === FALSE) {
|
||||
$tagId = 0; // cannot abort here; that will show up everything in the response
|
||||
}
|
||||
|
||||
$query->innerJoin('m', 'systemtag_object_mapping', 'stom', $query->expr()->andX(
|
||||
$query->expr()->eq('stom.objecttype', $query->createNamedParameter("files")),
|
||||
$query->expr()->eq('stom.objectid', 'm.fileid'),
|
||||
$query->expr()->eq('stom.systemtagid', $query->createNamedParameter($tagId)),
|
||||
));
|
||||
}
|
||||
|
||||
public function getTags(Folder $folder) {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
// SELECT visible tag name and count of photos
|
||||
$count = $query->func()->count($query->createFunction('DISTINCT m.fileid'), 'count');
|
||||
$query->select('st.name', $count)->from('systemtag', 'st')->where(
|
||||
$query->expr()->eq('visibility', $query->createNamedParameter(1)),
|
||||
);
|
||||
|
||||
// WHERE there are items with this tag
|
||||
$query->innerJoin('st', 'systemtag_object_mapping', 'stom', $query->expr()->andX(
|
||||
$query->expr()->eq('stom.systemtagid', 'st.id'),
|
||||
$query->expr()->eq('stom.objecttype', $query->createNamedParameter("files")),
|
||||
));
|
||||
|
||||
// WHERE these items are memories indexed photos
|
||||
$query->innerJoin('stom', 'memories', 'm', $query->expr()->eq('m.fileid', 'stom.objectid'));
|
||||
|
||||
// WHERE these photos are in the user's requested folder recursively
|
||||
$query->innerJoin('m', 'filecache', 'f', $this->getFilecacheJoinQuery($query, $folder, true, false));
|
||||
|
||||
// GROUP by tag name
|
||||
$query->groupBy('st.name');
|
||||
|
||||
// FETCH all tags
|
||||
$tags = $query->executeQuery()->fetchAll();
|
||||
return $tags;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue