recognize: fix compat with 3.6 (fix #500)
Signed-off-by: Varun Patil <varunpatil@ucla.edu>pull/504/head
parent
1e424d7e46
commit
47e2d9197f
|
@ -39,8 +39,9 @@ class PeopleController extends ApiBase
|
||||||
*/
|
*/
|
||||||
public function recognizePeople(): JSONResponse
|
public function recognizePeople(): JSONResponse
|
||||||
{
|
{
|
||||||
$user = $this->userSession->getUser();
|
try {
|
||||||
if (null === $user) {
|
$uid = $this->getUID();
|
||||||
|
} catch (\Exception $e) {
|
||||||
return Errors::NotLoggedIn();
|
return Errors::NotLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ class PeopleController extends ApiBase
|
||||||
|
|
||||||
// Run actual query
|
// Run actual query
|
||||||
$list = $this->timelineQuery->getPeopleRecognize(
|
$list = $this->timelineQuery->getPeopleRecognize(
|
||||||
$root,
|
$root, $uid
|
||||||
);
|
);
|
||||||
|
|
||||||
return new JSONResponse($list, Http::STATUS_OK);
|
return new JSONResponse($list, Http::STATUS_OK);
|
||||||
|
@ -74,8 +75,9 @@ class PeopleController extends ApiBase
|
||||||
*/
|
*/
|
||||||
public function recognizePeoplePreview(int $id): Http\Response
|
public function recognizePeoplePreview(int $id): Http\Response
|
||||||
{
|
{
|
||||||
$user = $this->userSession->getUser();
|
try {
|
||||||
if (null === $user) {
|
$uid = $this->getUID();
|
||||||
|
} catch (\Exception $e) {
|
||||||
return Errors::NotLoggedIn();
|
return Errors::NotLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,13 +93,13 @@ class PeopleController extends ApiBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run actual query
|
// Run actual query
|
||||||
$detections = $this->timelineQuery->getPeopleRecognizePreview($root, $id);
|
$detections = $this->timelineQuery->getPeopleRecognizePreview($root, $id, $uid);
|
||||||
|
|
||||||
if (null === $detections || 0 === \count($detections)) {
|
if (0 === \count($detections)) {
|
||||||
return Errors::NotFound('detections');
|
return Errors::NotFound('detections');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getPreviewResponse($detections, $user, 1.5);
|
return $this->getPreviewResponse($detections, 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,7 +185,7 @@ class PeopleController extends ApiBase
|
||||||
return Errors::NotFound('detections');
|
return Errors::NotFound('detections');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getPreviewResponse($detections, $user, 1.8);
|
return $this->getPreviewResponse($detections, 1.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,16 +197,17 @@ class PeopleController extends ApiBase
|
||||||
*/
|
*/
|
||||||
private function getPreviewResponse(
|
private function getPreviewResponse(
|
||||||
array $detections,
|
array $detections,
|
||||||
\OCP\IUser $user,
|
|
||||||
float $padding
|
float $padding
|
||||||
): Http\Response {
|
): Http\Response {
|
||||||
// Get preview manager
|
// Get preview manager
|
||||||
$previewManager = \OC::$server->get(\OCP\IPreview::class);
|
$previewManager = \OC::$server->get(\OCP\IPreview::class);
|
||||||
|
|
||||||
// Find the first detection that has a preview
|
|
||||||
/** @var \Imagick */
|
/** @var \Imagick */
|
||||||
$image = null;
|
$image = null;
|
||||||
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
|
|
||||||
|
// Find the first detection that has a preview
|
||||||
|
$userFolder = $this->rootFolder->getUserFolder($this->getUID());
|
||||||
|
|
||||||
foreach ($detections as &$detection) {
|
foreach ($detections as &$detection) {
|
||||||
// Get the file (also checks permissions)
|
// Get the file (also checks permissions)
|
||||||
$files = $userFolder->getById($detection['file_id']);
|
$files = $userFolder->getById($detection['file_id']);
|
||||||
|
|
|
@ -11,14 +11,19 @@ trait TimelineQueryPeopleRecognize
|
||||||
{
|
{
|
||||||
protected IDBConnection $connection;
|
protected IDBConnection $connection;
|
||||||
|
|
||||||
public function transformPeopleRecognitionFilter(IQueryBuilder &$query, string $userId, string $faceStr, bool $isAggregate)
|
public function transformPeopleRecognitionFilter(IQueryBuilder $query, string $userId, string $faceStr, bool $isAggregate)
|
||||||
{
|
{
|
||||||
// Get name and uid of face user
|
// Get name and uid of face user
|
||||||
$faceNames = explode('/', $faceStr);
|
$faceNames = explode('/', $faceStr);
|
||||||
if (2 !== \count($faceNames)) {
|
if (2 !== \count($faceNames)) {
|
||||||
throw new \Exception('Invalid face query');
|
throw new \Exception('Invalid face query');
|
||||||
}
|
}
|
||||||
$faceUid = $faceNames[0];
|
|
||||||
|
// Starting with Recognize v3.6, the detections are duplicated for each user
|
||||||
|
// So we don't need to use the user ID provided by the user, but retain
|
||||||
|
// this here for backwards compatibility + API consistency with Face Recognition
|
||||||
|
// $faceUid = $faceNames[0];
|
||||||
|
|
||||||
$faceName = $faceNames[1];
|
$faceName = $faceNames[1];
|
||||||
|
|
||||||
if (!$isAggregate) {
|
if (!$isAggregate) {
|
||||||
|
@ -28,15 +33,15 @@ trait TimelineQueryPeopleRecognize
|
||||||
|
|
||||||
// Join with cluster
|
// Join with cluster
|
||||||
$clusterQuery = null;
|
$clusterQuery = null;
|
||||||
if ('NULL' !== $faceName) {
|
if ('NULL' === $faceName) {
|
||||||
|
$clusterQuery = $query->expr()->isNull('rfd.cluster_id');
|
||||||
|
} else {
|
||||||
$nameField = is_numeric($faceName) ? 'rfc.id' : 'rfc.title';
|
$nameField = is_numeric($faceName) ? 'rfc.id' : 'rfc.title';
|
||||||
$query->innerJoin('m', 'recognize_face_clusters', 'rfc', $query->expr()->andX(
|
$query->innerJoin('m', 'recognize_face_clusters', 'rfc', $query->expr()->andX(
|
||||||
$query->expr()->eq('rfc.user_id', $query->createNamedParameter($faceUid)),
|
$query->expr()->eq('rfc.user_id', $query->createNamedParameter($userId)),
|
||||||
$query->expr()->eq($nameField, $query->createNamedParameter($faceName)),
|
$query->expr()->eq($nameField, $query->createNamedParameter($faceName)),
|
||||||
));
|
));
|
||||||
$clusterQuery = $query->expr()->eq('rfd.cluster_id', 'rfc.id');
|
$clusterQuery = $query->expr()->eq('rfd.cluster_id', 'rfc.id');
|
||||||
} else {
|
|
||||||
$clusterQuery = $query->expr()->isNull('rfd.cluster_id');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join with detections
|
// Join with detections
|
||||||
|
@ -57,7 +62,7 @@ trait TimelineQueryPeopleRecognize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPeopleRecognize(TimelineRoot &$root)
|
public function getPeopleRecognize(TimelineRoot &$root, string $uid)
|
||||||
{
|
{
|
||||||
$query = $this->connection->getQueryBuilder();
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
|
||||||
|
@ -74,6 +79,9 @@ trait TimelineQueryPeopleRecognize
|
||||||
// WHERE these photos are in the user's requested folder recursively
|
// WHERE these photos are in the user's requested folder recursively
|
||||||
$query = $this->joinFilecache($query, $root, true, false);
|
$query = $this->joinFilecache($query, $root, true, false);
|
||||||
|
|
||||||
|
// WHERE this cluster belongs to the user
|
||||||
|
$query->where($query->expr()->eq('rfc.user_id', $query->createNamedParameter($uid)));
|
||||||
|
|
||||||
// GROUP by ID of face cluster
|
// GROUP by ID of face cluster
|
||||||
$query->groupBy('rfc.id');
|
$query->groupBy('rfc.id');
|
||||||
|
|
||||||
|
@ -89,15 +97,15 @@ trait TimelineQueryPeopleRecognize
|
||||||
// Post process
|
// Post process
|
||||||
foreach ($faces as &$row) {
|
foreach ($faces as &$row) {
|
||||||
$row['id'] = (int) $row['id'];
|
$row['id'] = (int) $row['id'];
|
||||||
|
$row['count'] = (int) $row['count'];
|
||||||
$row['name'] = $row['title'];
|
$row['name'] = $row['title'];
|
||||||
unset($row['title']);
|
unset($row['title']);
|
||||||
$row['count'] = (int) $row['count'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $faces;
|
return $faces;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPeopleRecognizePreview(TimelineRoot &$root, int $id)
|
public function getPeopleRecognizePreview(TimelineRoot &$root, int $id, string $uid): array
|
||||||
{
|
{
|
||||||
$query = $this->connection->getQueryBuilder();
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
|
||||||
|
@ -113,7 +121,12 @@ trait TimelineQueryPeopleRecognize
|
||||||
'm.fileid',
|
'm.fileid',
|
||||||
'm.datetaken', // Just in case, for postgres
|
'm.datetaken', // Just in case, for postgres
|
||||||
)->from('recognize_face_detections', 'rfd');
|
)->from('recognize_face_detections', 'rfd');
|
||||||
$query->where($query->expr()->eq('rfd.cluster_id', $query->createNamedParameter($id)));
|
|
||||||
|
// WHERE detection belongs to this cluster AND user
|
||||||
|
$query->where($query->expr()->andX(
|
||||||
|
$query->expr()->eq('rfd.cluster_id', $query->createNamedParameter($id)),
|
||||||
|
$query->expr()->eq('rfd.user_id', $query->createNamedParameter($uid)),
|
||||||
|
));
|
||||||
|
|
||||||
// WHERE these photos are memories indexed
|
// WHERE these photos are memories indexed
|
||||||
$query->innerJoin('rfd', 'memories', 'm', $query->expr()->eq('m.fileid', 'rfd.file_id'));
|
$query->innerJoin('rfd', 'memories', 'm', $query->expr()->eq('m.fileid', 'rfd.file_id'));
|
||||||
|
@ -132,7 +145,7 @@ trait TimelineQueryPeopleRecognize
|
||||||
$cursor = $this->executeQueryWithCTEs($query);
|
$cursor = $this->executeQueryWithCTEs($query);
|
||||||
$previews = $cursor->fetchAll();
|
$previews = $cursor->fetchAll();
|
||||||
if (empty($previews)) {
|
if (empty($previews)) {
|
||||||
return null;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Score the face detections
|
// Score the face detections
|
||||||
|
|
Loading…
Reference in New Issue