From 977759de0d6d79d5c0d97b123f6e0b1142424d80 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 10 Sep 2024 15:54:43 +0200 Subject: [PATCH 01/15] Add command line option "retry" Signed-off-by: Niels --- lib/Command/Classify.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index 9df010f2..035c8926 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -21,6 +21,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\ExceptionInterface; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class Classify extends Command { @@ -53,7 +54,8 @@ public function __construct( */ protected function configure() { $this->setName('recognize:classify') - ->setDescription('Classify all files with the current settings in one go (will likely take a long time)'); + ->setDescription('Classify all files with the current settings in one go (will likely take a long time)') + ->addOption('retry', null, InputOption::VALUE_NONE, "Only classify untagged images"); } /** From 154db4d6f50f08b207adabf5806572445ed8bff1 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 10 Sep 2024 16:11:04 +0200 Subject: [PATCH 02/15] Use the tag manager to skip tagged files Signed-off-by: Niels --- lib/Command/Classify.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index 035c8926..c98b1542 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -16,6 +16,7 @@ use OCA\Recognize\Service\Logger; use OCA\Recognize\Service\SettingsService; use OCA\Recognize\Service\StorageService; +use OCA\Recognize\Service\TagManager; use OCP\Files\Config\ICachedMountInfo; use OCP\Files\Config\IUserMountCache; use Symfony\Component\Console\Command\Command; @@ -30,6 +31,7 @@ class Classify extends Command { public function __construct( private StorageService $storageService, + private TagManager $tagManager, private Logger $logger, ImagenetClassifier $imagenet, ClusteringFaceClassifier $faces, @@ -79,6 +81,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int MusicnnClassifier::MODEL_NAME, ], fn ($modelName) => $this->settings->getSetting($modelName . '.enabled') === 'true')); + $processedTag = $this->tagManager->getProcessedTag(); + foreach ($this->storageService->getMounts() as $mount) { $this->logger->info('Processing storage ' . $mount['storage_id'] . ' with root ID ' . $mount['override_root']); @@ -102,6 +106,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($this->storageService->getFilesInMount($mount['storage_id'], $mount['override_root'], $models, $lastFileId) as $file) { $i++; $lastFileId = $file['fileid']; + // if retry flag is set, skip tagged files + if ($input->getOption('retry')) { + $fileTags = $this->tagManager->getTagsForFiles([$lastFileId]); + // check if processed tag is already in the tags + if (in_array($processedTag, $fileTags)) { + continue; + } + } $queueFile = new QueueFile(); $queueFile->setStorageId($mount['storage_id']); $queueFile->setRootId($mount['root_id']); From 7d5c2d33e0a70c60bc4a5a4ea58ea7ca3bd7b740 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 10 Sep 2024 16:31:25 +0200 Subject: [PATCH 03/15] Fix invocation of clear background jobs Signed-off-by: Niels --- lib/Command/Classify.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index c98b1542..ae4c8fa6 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -22,6 +22,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\ExceptionInterface; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -72,7 +73,11 @@ protected function configure() { protected function execute(InputInterface $input, OutputInterface $output): int { $this->logger->setCliOutput($output); - $this->clearBackgroundJobs->run($input, $output); + // pop "retry" flag from parameters passed to clear background jobs + $clearBackgroundJobs = new ArrayInput([ + 'command' => 'recognize:clear-background-jobs', + ]); + $this->clearBackgroundJobs->run($clearBackgroundJobs, $output); $models = array_values(array_filter([ ClusteringFaceClassifier::MODEL_NAME, From 0b1d0d3842f3a81ab96ab4d84d605f591aa80a74 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 10 Sep 2024 16:50:48 +0200 Subject: [PATCH 04/15] Fix checks Signed-off-by: Niels --- lib/Command/Classify.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index ae4c8fa6..75832e26 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -109,16 +109,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int MusicnnClassifier::MODEL_NAME => [], ]; foreach ($this->storageService->getFilesInMount($mount['storage_id'], $mount['override_root'], $models, $lastFileId) as $file) { - $i++; - $lastFileId = $file['fileid']; // if retry flag is set, skip tagged files if ($input->getOption('retry')) { $fileTags = $this->tagManager->getTagsForFiles([$lastFileId]); // check if processed tag is already in the tags - if (in_array($processedTag, $fileTags)) { + if (in_array($processedTag, $fileTags[$lastFileId])) { continue; } } + $i++; + $lastFileId = $file['fileid']; $queueFile = new QueueFile(); $queueFile->setStorageId($mount['storage_id']); $queueFile->setRootId($mount['root_id']); From 44b46d7161172a571dad5332f370bd1f74d765c5 Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 10 Sep 2024 16:55:59 +0200 Subject: [PATCH 05/15] Fix counting Signed-off-by: Niels --- lib/Command/Classify.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index 75832e26..8d1ca483 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -109,6 +109,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int MusicnnClassifier::MODEL_NAME => [], ]; foreach ($this->storageService->getFilesInMount($mount['storage_id'], $mount['override_root'], $models, $lastFileId) as $file) { + $i++; // if retry flag is set, skip tagged files if ($input->getOption('retry')) { $fileTags = $this->tagManager->getTagsForFiles([$lastFileId]); @@ -117,7 +118,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int continue; } } - $i++; $lastFileId = $file['fileid']; $queueFile = new QueueFile(); $queueFile->setStorageId($mount['storage_id']); From e0bb483ce1c5f3ac5ee3b3d3cd951ab5690d439c Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 10 Sep 2024 21:19:45 +0200 Subject: [PATCH 06/15] Fix which file is skipped Signed-off-by: Niels --- lib/Command/Classify.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index 8d1ca483..5ee62625 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -111,6 +111,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($this->storageService->getFilesInMount($mount['storage_id'], $mount['override_root'], $models, $lastFileId) as $file) { $i++; // if retry flag is set, skip tagged files + $lastFileId = $file['fileid']; if ($input->getOption('retry')) { $fileTags = $this->tagManager->getTagsForFiles([$lastFileId]); // check if processed tag is already in the tags @@ -118,7 +119,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int continue; } } - $lastFileId = $file['fileid']; $queueFile = new QueueFile(); $queueFile->setStorageId($mount['storage_id']); $queueFile->setRootId($mount['root_id']); From eb9643845f68227ea04f703541b93d79804c07a1 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 11 Sep 2024 13:11:12 +0200 Subject: [PATCH 07/15] Skip only non-face cluster for tagged files --- lib/Command/Classify.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index 5ee62625..5e407bfe 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -110,8 +110,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int ]; foreach ($this->storageService->getFilesInMount($mount['storage_id'], $mount['override_root'], $models, $lastFileId) as $file) { $i++; - // if retry flag is set, skip tagged files $lastFileId = $file['fileid']; + $queueFile = new QueueFile(); + $queueFile->setStorageId($mount['storage_id']); + $queueFile->setRootId($mount['root_id']); + $queueFile->setFileId($file['fileid']); + $queueFile->setUpdate(false); + + if ($file['image']) { + if (in_array(ClusteringFaceClassifier::MODEL_NAME, $models)) { + $queues[ClusteringFaceClassifier::MODEL_NAME][] = $queueFile; + } + } + // if retry flag is set, skip other classifiers for tagged files if ($input->getOption('retry')) { $fileTags = $this->tagManager->getTagsForFiles([$lastFileId]); // check if processed tag is already in the tags @@ -119,19 +130,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int continue; } } - $queueFile = new QueueFile(); - $queueFile->setStorageId($mount['storage_id']); - $queueFile->setRootId($mount['root_id']); - $queueFile->setFileId($file['fileid']); - $queueFile->setUpdate(false); - if ($file['image']) { if (in_array(ImagenetClassifier::MODEL_NAME, $models)) { $queues[ImagenetClassifier::MODEL_NAME][] = $queueFile; } - if (in_array(ClusteringFaceClassifier::MODEL_NAME, $models)) { - $queues[ClusteringFaceClassifier::MODEL_NAME][] = $queueFile; - } } if ($file['video']) { if (in_array(MovinetClassifier::MODEL_NAME, $models)) { From 3d58670b3cd6271fa03f70d2524df2a038d7c3f0 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Thu, 12 Sep 2024 10:50:02 +0200 Subject: [PATCH 08/15] Update composer deps Signed-off-by: Marcel Klehr From af3bef3f80b649dbbd054ed69ebfce55ed83a08d Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Thu, 12 Sep 2024 10:50:12 +0200 Subject: [PATCH 09/15] fix: run cs:fix Signed-off-by: Marcel Klehr --- lib/Command/Classify.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index 5e407bfe..cddf5c2a 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -21,8 +21,8 @@ use OCP\Files\Config\IUserMountCache; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\ExceptionInterface; -use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -127,7 +127,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $fileTags = $this->tagManager->getTagsForFiles([$lastFileId]); // check if processed tag is already in the tags if (in_array($processedTag, $fileTags[$lastFileId])) { - continue; + continue; } } if ($file['image']) { From 76dc7b707ab0494d02cb69c8a6b99241d758177b Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Thu, 12 Sep 2024 10:50:47 +0200 Subject: [PATCH 10/15] fix(ClassifyCommand): Don't pass any params to clear-background-jobs Signed-off-by: Marcel Klehr --- lib/Command/Classify.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/Command/Classify.php b/lib/Command/Classify.php index cddf5c2a..62f6ce93 100644 --- a/lib/Command/Classify.php +++ b/lib/Command/Classify.php @@ -74,9 +74,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->logger->setCliOutput($output); // pop "retry" flag from parameters passed to clear background jobs - $clearBackgroundJobs = new ArrayInput([ - 'command' => 'recognize:clear-background-jobs', - ]); + $clearBackgroundJobs = new ArrayInput([]); $this->clearBackgroundJobs->run($clearBackgroundJobs, $output); $models = array_values(array_filter([ From 2f97223930e83551e145a263eb22628dc8827f56 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Thu, 12 Sep 2024 11:11:42 +0200 Subject: [PATCH 11/15] fix: run cs:fix Signed-off-by: Marcel Klehr --- lib/BackgroundJobs/ClassifierJob.php | 6 +++--- lib/Controller/AdminController.php | 2 +- lib/Migration/InstallDeps.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/BackgroundJobs/ClassifierJob.php b/lib/BackgroundJobs/ClassifierJob.php index 6bd13e6b..144efbd9 100644 --- a/lib/BackgroundJobs/ClassifierJob.php +++ b/lib/BackgroundJobs/ClassifierJob.php @@ -71,15 +71,15 @@ protected function runClassifier(string $model, array $argument): void { try { $this->logger->debug('Running ' . $model . ' classifier'); $this->classify($files); - } catch(\RuntimeException $e) { + } catch (\RuntimeException $e) { $this->logger->warning('Temporary problem with ' . $model . ' classifier, trying again soon', ['exception' => $e]); - } catch(\ErrorException $e) { + } catch (\ErrorException $e) { $this->settingsService->setSetting($model.'.status', 'false'); $this->logger->warning('Problem with ' . $model . ' classifier', ['exception' => $e]); $this->logger->debug('Removing '.static::class.' with argument ' . var_export($argument, true) . 'from oc_jobs'); $this->jobList->remove(static::class, $argument); throw $e; - } catch(\Throwable $e) { + } catch (\Throwable $e) { $this->settingsService->setSetting($model.'.status', 'false'); throw $e; } diff --git a/lib/Controller/AdminController.php b/lib/Controller/AdminController.php index e7fd7dc8..6c99eb02 100644 --- a/lib/Controller/AdminController.php +++ b/lib/Controller/AdminController.php @@ -136,7 +136,7 @@ public function hasJobs(string $task): JSONResponse { } $iterator = $this->jobList->getJobsIterator($tasks[$task], null, 0); $lastRun = []; - foreach($iterator as $job) { + foreach ($iterator as $job) { $lastRun[] = $job->getLastRun(); } $count = count($lastRun); diff --git a/lib/Migration/InstallDeps.php b/lib/Migration/InstallDeps.php index c6b2f0c4..7e477b23 100644 --- a/lib/Migration/InstallDeps.php +++ b/lib/Migration/InstallDeps.php @@ -90,7 +90,7 @@ public function run(IOutput $output): void { $this->runFfmpegInstall($binaryPath); $this->runTfjsGpuInstall($binaryPath); $this->setNiceBinaryPath(); - } catch(\Throwable $e) { + } catch (\Throwable $e) { $output->warning('Failed to automatically install dependencies for recognize. Check the recognize admin panel for potential problems.'); $this->logger->error('Failed to automatically install dependencies for recognize. Check the recognize admin panel for potential problems.', ['exception' => $e]); } From 3b8df2d003d95452747db3ca60b12d4aa426972b Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Fri, 13 Sep 2024 09:31:02 +0200 Subject: [PATCH 12/15] chore: Allow installing on stable30 Signed-off-by: Marcel Klehr From 884475ba76d0762a3241e69f76c2df0bd4832f8d Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Fri, 13 Sep 2024 09:36:43 +0200 Subject: [PATCH 13/15] fix: Psalm static analysis issues Signed-off-by: Marcel Klehr --- lib/BackgroundJobs/StorageCrawlJob.php | 1 - lib/Service/TagManager.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/BackgroundJobs/StorageCrawlJob.php b/lib/BackgroundJobs/StorageCrawlJob.php index a63d5b4c..e8b1d5b5 100644 --- a/lib/BackgroundJobs/StorageCrawlJob.php +++ b/lib/BackgroundJobs/StorageCrawlJob.php @@ -77,7 +77,6 @@ protected function run($argument): void { } if (!in_array(ImagenetClassifier::MODEL_NAME, $models) && in_array(LandmarksClassifier::MODEL_NAME, $models)) { $tags = $this->tagManager->getTagsForFiles([$queueFile->getFileId()]); - /** @var \OCP\SystemTag\ISystemTag[] $fileTags */ $fileTags = $tags[$queueFile->getFileId()]; $landmarkTags = array_filter($fileTags, function ($tag) { return in_array($tag->getName(), LandmarksClassifier::PRECONDITION_TAGS); diff --git a/lib/Service/TagManager.php b/lib/Service/TagManager.php index 21ebd10f..116e57dc 100644 --- a/lib/Service/TagManager.php +++ b/lib/Service/TagManager.php @@ -79,7 +79,7 @@ public function assignTags(int $fileId, array $tags): void { /** * @param array $fileIds - * @return array + * @return array> */ public function getTagsForFiles(array $fileIds): array { /** @var array $tagsByFile */ From 6f8e746f5b494bd501b69c6d1ea2fa9e4b1fcab3 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Sun, 8 Dec 2024 18:03:00 +0100 Subject: [PATCH 14/15] fix(codestyle): Run cs:fix Signed-off-by: Marcel Klehr --- lib/BackgroundJobs/ClassifierJob.php | 1 + lib/BackgroundJobs/ClassifyFacesJob.php | 1 + lib/BackgroundJobs/ClassifyImagenetJob.php | 1 + lib/BackgroundJobs/ClassifyLandmarksJob.php | 1 + lib/BackgroundJobs/ClassifyMovinetJob.php | 1 + lib/BackgroundJobs/ClassifyMusicnnJob.php | 1 + lib/BackgroundJobs/ClusterFacesJob.php | 1 + lib/BackgroundJobs/MaintenanceJob.php | 1 + lib/BackgroundJobs/SchedulerJob.php | 1 + lib/BackgroundJobs/StorageCrawlJob.php | 1 + lib/Classifiers/Audio/MusicnnClassifier.php | 1 + lib/Classifiers/Classifier.php | 1 + .../Images/ClusteringFaceClassifier.php | 1 + lib/Classifiers/Images/ImagenetClassifier.php | 1 + .../Images/LandmarksClassifier.php | 1 + lib/Classifiers/Video/MovinetClassifier.php | 1 + lib/Clustering/DualTreeBall.php | 1 + lib/Clustering/DualTreeClique.php | 1 + lib/Clustering/HDBSCAN.php | 1 + lib/Clustering/MrdBallTree.php | 1 + lib/Clustering/MstClusterer.php | 1 + lib/Clustering/MstSolver.php | 1 + lib/Clustering/SquaredDistance.php | 1 + lib/Command/Classify.php | 1 + lib/Command/CleanupTags.php | 1 + lib/Command/ClearBackgroundJobs.php | 1 + lib/Command/ClusterFaces.php | 1 + lib/Command/DownloadModels.php | 1 + lib/Command/Recrawl.php | 1 + lib/Command/RemoveLegacyTags.php | 1 + lib/Command/ResetFaceClusters.php | 1 + lib/Command/ResetFaces.php | 1 + lib/Command/ResetTags.php | 1 + lib/Constants.php | 1 + lib/Dav/Faces/FacePhoto.php | 1 + lib/Dav/Faces/FaceRoot.php | 1 + lib/Dav/Faces/FacesHome.php | 1 + lib/Dav/Faces/PropFindPlugin.php | 1 + lib/Dav/Faces/UnassignedFacePhoto.php | 1 + lib/Dav/Faces/UnassignedFacesHome.php | 1 + lib/Dav/RecognizeHome.php | 1 + lib/Dav/RootCollection.php | 1 + lib/Db/FaceCluster.php | 1 + lib/Db/FaceClusterMapper.php | 1 + lib/Db/FaceDetection.php | 1 + lib/Db/FaceDetectionMapper.php | 1 + lib/Db/FaceDetectionWithTitle.php | 1 + lib/Db/QueueFile.php | 1 + lib/Db/QueueMapper.php | 1 + lib/Exception/Exception.php | 1 + lib/Helper/Archive.php | 1 + lib/Helper/TAR.php | 1 + lib/Hooks/FileListener.php | 1 + .../Version002002000Date20220614094721.php | 1 + .../Version002003000Date20220713094721.php | 1 + .../Version003001000Date20221017094721.php | 1 + .../Version003004000Date20230107094721.php | 1 + lib/Service/DownloadModelsService.php | 1 + lib/Service/FaceClusterAnalyzer.php | 1 + lib/Service/IgnoreService.php | 1 + lib/Service/Logger.php | 1 + lib/Service/QueueService.php | 1 + lib/Service/StorageService.php | 1 + lib/Service/TagManager.php | 1 + lib/Settings/AdminSection.php | 1 + lib/Settings/AdminSettings.php | 1 + vendor-bin/php-scoper/composer.lock | 104 +++++++++--------- 67 files changed, 118 insertions(+), 52 deletions(-) diff --git a/lib/BackgroundJobs/ClassifierJob.php b/lib/BackgroundJobs/ClassifierJob.php index 144efbd9..d4d43a45 100644 --- a/lib/BackgroundJobs/ClassifierJob.php +++ b/lib/BackgroundJobs/ClassifierJob.php @@ -1,4 +1,5 @@ Date: Sun, 8 Dec 2024 18:05:11 +0100 Subject: [PATCH 15/15] fix(staticanalysis): Add implicit string cast to baseline Signed-off-by: Marcel Klehr --- psalm-baseline.xml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index d66b43c4..dce4491f 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + getContainer()]]> @@ -1050,6 +1050,19 @@ + + + + + + + + + + + + +