From 6fcb3ba4570a2e443a8a80fb5487854eb96705bd Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Fri, 7 Oct 2022 23:26:09 -0700 Subject: [PATCH] Use name for face fetching --- lib/Controller/ApiController.php | 6 +++--- lib/Db/TimelineQueryFaces.php | 21 ++++++++++++++++++--- src/components/Tag.vue | 4 +++- src/components/Timeline.vue | 4 ++-- src/router.ts | 2 +- src/services/DavRequests.ts | 1 - src/types.ts | 4 ++-- 7 files changed, 29 insertions(+), 13 deletions(-) diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php index 54add7f1..ded0edb9 100644 --- a/lib/Controller/ApiController.php +++ b/lib/Controller/ApiController.php @@ -87,9 +87,9 @@ class ApiController extends Controller { // Filter only for one face if ($this->recognizeIsEnabled()) { - $faceId = $this->request->getParam('face'); - if ($faceId) { - $transforms[] = array($this->timelineQuery, 'transformFaceFilter', intval($faceId)); + $face = $this->request->getParam('face'); + if ($face) { + $transforms[] = array($this->timelineQuery, 'transformFaceFilter', $face); } } diff --git a/lib/Db/TimelineQueryFaces.php b/lib/Db/TimelineQueryFaces.php index 581560ff..a0b12231 100644 --- a/lib/Db/TimelineQueryFaces.php +++ b/lib/Db/TimelineQueryFaces.php @@ -10,10 +10,25 @@ use OCP\Files\Folder; trait TimelineQueryFaces { protected IDBConnection $connection; - public function transformFaceFilter(IQueryBuilder &$query, string $userId, int $faceId) { + public function transformFaceFilter(IQueryBuilder &$query, string $userId, string $faceName) { + // Get title and uid of face user + $faceNames = explode('/', $faceName); + if (count($faceNames) !== 2) return; + $faceUid = $faceNames[0]; + $faceName = $faceNames[1]; + + // Get cluster ID + $sq = $query->getConnection()->getQueryBuilder(); + $id = $sq->select('id')->from('recognize_face_clusters') + ->where($query->expr()->eq('user_id', $sq->createNamedParameter($faceUid))) + ->andWhere($query->expr()->eq('title', $sq->createNamedParameter($faceName))) + ->executeQuery()->fetchOne(); + if (!$id) return; + + // Join with cluster $query->innerJoin('m', 'recognize_face_detections', 'rfd', $query->expr()->andX( $query->expr()->eq('rfd.file_id', 'm.fileid'), - $query->expr()->eq('rfd.cluster_id', $query->createNamedParameter($faceId)), + $query->expr()->eq('rfd.cluster_id', $query->createNamedParameter($id)), )); } @@ -22,7 +37,7 @@ trait TimelineQueryFaces { // SELECT all face clusters $count = $query->func()->count($query->createFunction('DISTINCT m.fileid'), 'count'); - $query->select('rfc.id', 'rfc.title', $count)->from('recognize_face_clusters', 'rfc'); + $query->select('rfc.id', 'rfc.user_id', 'rfc.title', $count)->from('recognize_face_clusters', 'rfc'); // WHERE there are faces with this cluster $query->innerJoin('rfc', 'recognize_face_detections', 'rfd', $query->expr()->eq('rfc.id', 'rfd.cluster_id')); diff --git a/src/components/Tag.vue b/src/components/Tag.vue index 5c8f279d..f4fff669 100644 --- a/src/components/Tag.vue +++ b/src/components/Tag.vue @@ -114,7 +114,9 @@ export default class Tag extends Mixins(GlobalMixin) { /** Open tag */ openTag() { if (this.isFace) { - this.$router.push({ name: 'people', params: { name: this.data.faceid.toString() }}); + const name = this.data.name; + const user = this.data.user_id; + this.$router.push({ name: 'people', params: { name, user }}); } else { this.$router.push({ name: 'tags', params: { name: this.data.name }}); } diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue index 4068b89d..cee2fa49 100644 --- a/src/components/Timeline.vue +++ b/src/components/Timeline.vue @@ -521,8 +521,8 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) { } // People - if (this.$route.name === 'people' && this.$route.params.name) { - query.set('face', this.$route.params.name); + if (this.$route.name === 'people' && this.$route.params.user && this.$route.params.name) { + query.set('face', `${this.$route.params.user}/${this.$route.params.name}`); } // Tags diff --git a/src/router.ts b/src/router.ts index b0c7b240..35fd061b 100644 --- a/src/router.ts +++ b/src/router.ts @@ -101,7 +101,7 @@ }, { - path: '/people/:name*', + path: '/people/:user?/:name?', component: Timeline, name: 'people', props: route => ({ diff --git a/src/services/DavRequests.ts b/src/services/DavRequests.ts index 54f40ae1..750cfe15 100644 --- a/src/services/DavRequests.ts +++ b/src/services/DavRequests.ts @@ -489,7 +489,6 @@ export async function getTagsData(): Promise { detail: data.map((face) => ({ ...face, fileid: hashCode(face.name), - faceid: face.id, istag: true, isface: true, } as any)), diff --git a/src/types.ts b/src/types.ts index a1220e8c..90f25f0c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -69,8 +69,8 @@ export interface ITag extends IPhoto { name: string; /** Number of images in this tag */ count: number; - /** ID of face if this is a face */ - faceid?: number; + /** User for face if face */ + user_id?: string; /** Cache of previews */ previews?: IPhoto[]; }