Support for recognize v3.8 (fix #618)
Signed-off-by: Varun Patil <radialapps@gmail.com>pull/653/head
parent
e1986b6991
commit
429c821fbf
|
@ -57,9 +57,13 @@ class RecognizeBackend extends Backend
|
|||
|
||||
public function transformDayQuery(&$query, bool $aggregate): void
|
||||
{
|
||||
$faceStr = (string) $this->request->getParam('recognize');
|
||||
// Check if Recognize is enabled
|
||||
if (!$this->isEnabled()) {
|
||||
throw \OCA\Memories\Exceptions::NotEnabled('Recognize');
|
||||
}
|
||||
|
||||
// Get name and uid of face user
|
||||
$faceStr = (string) $this->request->getParam('recognize');
|
||||
$faceNames = explode('/', $faceStr);
|
||||
if (2 !== \count($faceNames)) {
|
||||
throw new \Exception('Invalid face query');
|
||||
|
|
|
@ -92,7 +92,7 @@ class Util
|
|||
}
|
||||
|
||||
$v = $appManager->getAppVersion('recognize');
|
||||
if (!version_compare($v, '3.0.0-alpha', '>=')) {
|
||||
if (!version_compare($v, '3.8.0', '>=')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -801,17 +801,23 @@ export default defineComponent({
|
|||
|
||||
// Check photo ownership
|
||||
if (this.$route.params.user !== getCurrentUser()?.uid) {
|
||||
showError(
|
||||
this.t('memories', 'Only user "{user}" can update this person', {
|
||||
user,
|
||||
})
|
||||
);
|
||||
showError(this.t('memories', 'Only user "{user}" can update this person', { user }));
|
||||
return;
|
||||
}
|
||||
|
||||
// Run query
|
||||
for await (let delIds of dav.removeFaceImages(<string>user, <string>name, Array.from(selection.values()))) {
|
||||
this.deleteSelectedPhotosById(delIds, selection);
|
||||
// Make map to get back photo from faceid
|
||||
const map = new Map<number, IPhoto>();
|
||||
for (const photo of selection.values()) {
|
||||
if (photo.faceid) {
|
||||
map.set(photo.faceid, photo);
|
||||
}
|
||||
}
|
||||
const photos = Array.from(map.values());
|
||||
|
||||
// Run WebDAV query
|
||||
for await (let delIds of dav.recognizeDeleteFaceImages(user, name, photos)) {
|
||||
const fileIds = delIds.map((id) => map.get(id)?.fileid ?? 0).filter((id) => id);
|
||||
this.deleteSelectedPhotosById(fileIds, selection);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -77,9 +77,9 @@ export default defineComponent({
|
|||
async save() {
|
||||
try {
|
||||
if (this.$route.name === 'recognize') {
|
||||
await client.deleteFile(`/recognize/${this.user}/faces/${this.name}`);
|
||||
await dav.recognizeDeleteFace(this.user, this.name);
|
||||
} else {
|
||||
await dav.setVisibilityPeopleFaceRecognition(this.name, false);
|
||||
await dav.faceRecognitionSetPersonVisibility(this.name, false);
|
||||
}
|
||||
this.$router.push({ name: this.$route.name as string });
|
||||
this.close();
|
||||
|
|
|
@ -89,12 +89,9 @@ export default defineComponent({
|
|||
async save() {
|
||||
try {
|
||||
if (this.$route.name === 'recognize') {
|
||||
await client.moveFile(
|
||||
`/recognize/${this.user}/faces/${this.oldName}`,
|
||||
`/recognize/${this.user}/faces/${this.name}`
|
||||
);
|
||||
await dav.recognizeRenameFace(this.user, this.oldName, this.name);
|
||||
} else {
|
||||
await dav.renamePeopleFaceRecognition(this.oldName, this.name);
|
||||
await dav.faceRecognitionRenamePerson(this.oldName, this.name);
|
||||
}
|
||||
this.$router.push({
|
||||
name: this.$route.name as string,
|
||||
|
|
|
@ -89,14 +89,13 @@ export default defineComponent({
|
|||
async clickFace(face: IFace) {
|
||||
const user = this.$route.params.user || '';
|
||||
const name = this.$route.params.name || '';
|
||||
|
||||
const newName = String(face.name || face.cluster_id);
|
||||
const target = String(face.name || face.cluster_id);
|
||||
|
||||
if (
|
||||
!confirm(
|
||||
this.t('memories', 'Are you sure you want to move the selected photos from {name} to {newName}?', {
|
||||
this.t('memories', 'Are you sure you want to move the selected photos from {name} to {target}?', {
|
||||
name,
|
||||
newName,
|
||||
target,
|
||||
})
|
||||
)
|
||||
) {
|
||||
|
@ -108,31 +107,19 @@ export default defineComponent({
|
|||
this.updateLoading(1);
|
||||
|
||||
// Create map to return IPhoto later
|
||||
let photoMap = new Map<number, IPhoto>();
|
||||
for (const photo of this.photos) {
|
||||
photoMap.set(photo.fileid, photo);
|
||||
const map = new Map<number, IPhoto>();
|
||||
for (const photo of this.photos.filter((p) => p.faceid)) {
|
||||
map.set(photo.faceid!, photo);
|
||||
}
|
||||
|
||||
// Create move calls
|
||||
const calls = this.photos.map((p) => async () => {
|
||||
try {
|
||||
await client.moveFile(
|
||||
`/recognize/${user}/faces/${name}/${p.fileid}-${p.basename}`,
|
||||
`/recognize/${face.user_id}/faces/${newName}/${p.fileid}-${p.basename}`
|
||||
);
|
||||
return photoMap.get(p.fileid);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
showError(this.t('memories', 'Error while moving {basename}', <any>p));
|
||||
}
|
||||
});
|
||||
for await (const resp of dav.runInParallel(calls, 10)) {
|
||||
const valid = resp.filter((r): r is IPhoto => r !== undefined);
|
||||
this.moved(valid);
|
||||
// Run WebDAV query
|
||||
const photos = Array.from(map.values());
|
||||
for await (let delIds of dav.recognizeMoveFaceImages(user, name, target, photos)) {
|
||||
this.moved(delIds.filter((id) => id).map((id) => map.get(id)!));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
showError(this.t('photos', 'Failed to move {name}.', { name }));
|
||||
showError(this.t('photos', 'An error occured while moving photos from {name}.', { name }));
|
||||
} finally {
|
||||
this.updateLoading(-1);
|
||||
this.close();
|
||||
|
|
|
@ -11,7 +11,12 @@ export async function getFaceList(app: 'recognize' | 'facerecognition') {
|
|||
return (await axios.get<IFace[]>(API.FACE_LIST(app))).data;
|
||||
}
|
||||
|
||||
export async function updatePeopleFaceRecognition(name: string, params: object) {
|
||||
/**
|
||||
* Update a person or cluster in face recognition
|
||||
* @param name Name of face (or ID)
|
||||
* @param params Parameters to update
|
||||
*/
|
||||
export async function faceRecognitionUpdatePerson(name: string, params: object) {
|
||||
if (Number.isInteger(Number(name))) {
|
||||
return await axios.put(generateUrl(`/apps/facerecognition/api/2.0/cluster/${name}`), params);
|
||||
} else {
|
||||
|
@ -19,16 +24,22 @@ export async function updatePeopleFaceRecognition(name: string, params: object)
|
|||
}
|
||||
}
|
||||
|
||||
export async function renamePeopleFaceRecognition(name: string, newName: string) {
|
||||
return await updatePeopleFaceRecognition(name, {
|
||||
name: newName,
|
||||
});
|
||||
/**
|
||||
* Rename a face in face recognition
|
||||
* @param name Name of face (or ID)
|
||||
* @param target Target name of face
|
||||
*/
|
||||
export async function faceRecognitionRenamePerson(name: string, target: string) {
|
||||
return await faceRecognitionUpdatePerson(name, { name: target });
|
||||
}
|
||||
|
||||
export async function setVisibilityPeopleFaceRecognition(name: string, visibility: boolean) {
|
||||
return await updatePeopleFaceRecognition(name, {
|
||||
visible: visibility,
|
||||
});
|
||||
/**
|
||||
* Set visibility of a face
|
||||
* @param name Name of face (or ID)
|
||||
* @param visible Visibility of face
|
||||
*/
|
||||
export async function faceRecognitionSetPersonVisibility(name: string, visible: boolean) {
|
||||
return await faceRecognitionUpdatePerson(name, { visible });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,19 +48,19 @@ export async function setVisibilityPeopleFaceRecognition(name: string, visibilit
|
|||
* @param user User ID of face
|
||||
* @param name Name of face (or ID)
|
||||
* @param photos List of photos to remove
|
||||
* @returns Generator
|
||||
* @returns Generator for face IDs
|
||||
*/
|
||||
export async function* removeFaceImages(user: string, name: string, photos: IPhoto[]) {
|
||||
export async function* recognizeDeleteFaceImages(user: string, name: string, photos: IPhoto[]) {
|
||||
// Remove each file
|
||||
const calls = photos.map((f) => async () => {
|
||||
const calls = photos.map((p) => async () => {
|
||||
try {
|
||||
await client.deleteFile(`/recognize/${user}/faces/${name}/${f.fileid}-${f.basename}`);
|
||||
return f.fileid;
|
||||
await client.deleteFile(`/recognize/${user}/faces/${name}/${p.faceid}-${p.basename}`);
|
||||
return p.faceid!;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
showError(
|
||||
t('memories', 'Failed to remove {filename} from face.', {
|
||||
filename: f.basename ?? f.fileid,
|
||||
filename: p.basename ?? p.fileid,
|
||||
})
|
||||
);
|
||||
return 0;
|
||||
|
@ -58,3 +69,56 @@ export async function* removeFaceImages(user: string, name: string, photos: IPho
|
|||
|
||||
yield* base.runInParallel(calls, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move faces from one face to another
|
||||
*
|
||||
* @param user User ID of face
|
||||
* @param face Name of face (or ID)
|
||||
* @param target Name of target face (or ID)
|
||||
* @param photos List of photos to move
|
||||
* @returns Generator for face IDs
|
||||
*/
|
||||
export async function* recognizeMoveFaceImages(user: string, face: string, target: string, photos: IPhoto[]) {
|
||||
// Remove each file
|
||||
const calls = photos.map((p) => async () => {
|
||||
try {
|
||||
await client.moveFile(
|
||||
`/recognize/${user}/faces/${face}/${p.faceid}-${p.basename}`,
|
||||
`/recognize/${user}/faces/${target}/${p.faceid}-${p.basename}`
|
||||
);
|
||||
return p.faceid!;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
showError(
|
||||
t('memories', 'Failed to move {filename} from face.', {
|
||||
filename: p.basename ?? p.fileid,
|
||||
})
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
yield* base.runInParallel(calls, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a face entirely
|
||||
*
|
||||
* @param user User ID of face
|
||||
* @param name Name of face (or ID)
|
||||
*/
|
||||
export async function recognizeDeleteFace(user: string, name: string) {
|
||||
return await client.deleteFile(`/recognize/${user}/faces/${name}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a face in recognize
|
||||
*
|
||||
* @param user User ID of face
|
||||
* @param name Name of face (or ID)
|
||||
* @param target Target name of face
|
||||
*/
|
||||
export async function recognizeRenameFace(user: string, name: string, target: string) {
|
||||
await client.moveFile(`/recognize/${user}/faces/${name}`, `/recognize/${user}/faces/${target}`);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue