Allow scheduling specific classifier/crawl jobs per model

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
This commit is contained in:
Marcel Klehr
2022-09-21 14:07:33 +02:00
parent 7645628fb5
commit 3b30a32de3
3 changed files with 87 additions and 5 deletions

View File

@ -9,6 +9,11 @@ namespace OCA\Recognize\BackgroundJobs;
use OC\Files\Cache\CacheQueryBuilder; use OC\Files\Cache\CacheQueryBuilder;
use OC\SystemConfig; use OC\SystemConfig;
use OCA\Recognize\Classifiers\Audio\MusicnnClassifier;
use OCA\Recognize\Classifiers\Images\ClusteringFaceClassifier;
use OCA\Recognize\Classifiers\Images\ImagenetClassifier;
use OCA\Recognize\Classifiers\Images\LandmarksClassifier;
use OCA\Recognize\Classifiers\Video\MovinetClassifier;
use OCA\Recognize\Service\Logger; use OCA\Recognize\Service\Logger;
use OCP\AppFramework\Utility\ITimeFactory; use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\IJobList; use OCP\BackgroundJob\IJobList;
@ -49,6 +54,14 @@ class SchedulerJob extends QueuedJob {
} }
protected function run($argument): void { protected function run($argument): void {
$models = $argument['models'] ?? [
ClusteringFaceClassifier::MODEL_NAME,
ImagenetClassifier::MODEL_NAME,
LandmarksClassifier::MODEL_NAME,
MovinetClassifier::MODEL_NAME,
MusicnnClassifier::MODEL_NAME,
];
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('root_id', 'storage_id', 'mount_provider_class') $qb->select('root_id', 'storage_id', 'mount_provider_class')
->from('mounts') ->from('mounts')
@ -80,6 +93,7 @@ class SchedulerJob extends QueuedJob {
'root_id' => $rootId, 'root_id' => $rootId,
'override_root' => $overrideRoot, 'override_root' => $overrideRoot,
'last_file_id' => 0, 'last_file_id' => 0,
'models' => $models,
]); ]);
} }

View File

@ -12,11 +12,13 @@ use OC\SystemConfig;
use OCA\Recognize\Classifiers\Audio\MusicnnClassifier; use OCA\Recognize\Classifiers\Audio\MusicnnClassifier;
use OCA\Recognize\Classifiers\Images\ClusteringFaceClassifier; use OCA\Recognize\Classifiers\Images\ClusteringFaceClassifier;
use OCA\Recognize\Classifiers\Images\ImagenetClassifier; use OCA\Recognize\Classifiers\Images\ImagenetClassifier;
use OCA\Recognize\Classifiers\Images\LandmarksClassifier;
use OCA\Recognize\Classifiers\Video\MovinetClassifier; use OCA\Recognize\Classifiers\Video\MovinetClassifier;
use OCA\Recognize\Constants; use OCA\Recognize\Constants;
use OCA\Recognize\Db\QueueFile; use OCA\Recognize\Db\QueueFile;
use OCA\Recognize\Service\Logger; use OCA\Recognize\Service\Logger;
use OCA\Recognize\Service\QueueService; use OCA\Recognize\Service\QueueService;
use OCA\Recognize\Service\TagManager;
use OCP\AppFramework\Utility\ITimeFactory; use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\IJobList; use OCP\BackgroundJob\IJobList;
use OCP\BackgroundJob\QueuedJob; use OCP\BackgroundJob\QueuedJob;
@ -33,8 +35,9 @@ class StorageCrawlJob extends QueuedJob {
private IJobList $jobList; private IJobList $jobList;
private IDBConnection $db; private IDBConnection $db;
private SystemConfig $systemConfig; private SystemConfig $systemConfig;
private TagManager $tagManager;
public function __construct(ITimeFactory $timeFactory, Logger $logger, IMimeTypeLoader $mimeTypes, QueueService $queue, IJobList $jobList, IDBConnection $db, SystemConfig $systemConfig) { public function __construct(ITimeFactory $timeFactory, Logger $logger, IMimeTypeLoader $mimeTypes, QueueService $queue, IJobList $jobList, IDBConnection $db, SystemConfig $systemConfig, TagManager $tagManager) {
parent::__construct($timeFactory); parent::__construct($timeFactory);
$this->logger = $logger; $this->logger = $logger;
$this->mimeTypes = $mimeTypes; $this->mimeTypes = $mimeTypes;
@ -42,6 +45,7 @@ class StorageCrawlJob extends QueuedJob {
$this->jobList = $jobList; $this->jobList = $jobList;
$this->db = $db; $this->db = $db;
$this->systemConfig = $systemConfig; $this->systemConfig = $systemConfig;
$this->tagManager = $tagManager;
} }
protected function run($argument): void { protected function run($argument): void {
@ -49,6 +53,14 @@ class StorageCrawlJob extends QueuedJob {
$rootId = $argument['root_id']; $rootId = $argument['root_id'];
$overrideRoot = $argument['override_root']; $overrideRoot = $argument['override_root'];
$lastFileId = $argument['last_file_id']; $lastFileId = $argument['last_file_id'];
$models = $argument['models'] ?? [
ClusteringFaceClassifier::MODEL_NAME,
ImagenetClassifier::MODEL_NAME,
LandmarksClassifier::MODEL_NAME,
MovinetClassifier::MODEL_NAME,
MusicnnClassifier::MODEL_NAME,
];
$qb = new CacheQueryBuilder($this->db, $this->systemConfig, $this->logger); $qb = new CacheQueryBuilder($this->db, $this->systemConfig, $this->logger);
try { try {
$root = $qb->selectFileCache() $root = $qb->selectFileCache()
@ -63,13 +75,26 @@ class StorageCrawlJob extends QueuedJob {
$videoTypes = array_map(fn ($mimeType) => $this->mimeTypes->getId($mimeType), Constants::VIDEO_FORMATS); $videoTypes = array_map(fn ($mimeType) => $this->mimeTypes->getId($mimeType), Constants::VIDEO_FORMATS);
$audioTypes = array_map(fn ($mimeType) => $this->mimeTypes->getId($mimeType), Constants::AUDIO_FORMATS); $audioTypes = array_map(fn ($mimeType) => $this->mimeTypes->getId($mimeType), Constants::AUDIO_FORMATS);
$mimeTypes = [];
if (in_array(ClusteringFaceClassifier::MODEL_NAME, $models) ||
in_array(ImagenetClassifier::MODEL_NAME, $models) ||
in_array(LandmarksClassifier::MODEL_NAME, $models)) {
$mimeTypes = array_merge($imageTypes, $mimeTypes);
}
if (in_array(MovinetClassifier::MODEL_NAME, $models)) {
$mimeTypes = array_merge($videoTypes, $mimeTypes);
}
if (in_array(MusicnnClassifier::MODEL_NAME, $models)) {
$mimeTypes = array_merge($audioTypes, $mimeTypes);
}
try { try {
$qb = new CacheQueryBuilder($this->db, $this->systemConfig, $this->logger); $qb = new CacheQueryBuilder($this->db, $this->systemConfig, $this->logger);
$files = $qb->selectFileCache() $files = $qb->selectFileCache()
->whereStorageId($storageId) ->whereStorageId($storageId)
->andWhere($qb->expr()->like('path', $qb->createNamedParameter($root['path'] . '/%'))) ->andWhere($qb->expr()->like('path', $qb->createNamedParameter($root['path'] . '/%')))
->andWhere($qb->expr()->eq('storage', $qb->createNamedParameter($storageId))) ->andWhere($qb->expr()->eq('storage', $qb->createNamedParameter($storageId)))
->andWhere($qb->expr()->in('mimetype', $qb->createNamedParameter(array_merge($imageTypes, $videoTypes, $audioTypes), IQueryBuilder::PARAM_INT_ARRAY))) ->andWhere($qb->expr()->in('mimetype', $qb->createNamedParameter($mimeTypes, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->gt('filecache.fileid', $qb->createNamedParameter($lastFileId))) ->andWhere($qb->expr()->gt('filecache.fileid', $qb->createNamedParameter($lastFileId)))
->orderBy('filecache.fileid', 'ASC') ->orderBy('filecache.fileid', 'ASC')
->setMaxResults(100) ->setMaxResults(100)
@ -92,8 +117,23 @@ class StorageCrawlJob extends QueuedJob {
$queueFile->setUpdate(false); $queueFile->setUpdate(false);
try { try {
if (in_array($file['mimetype'], $imageTypes)) { if (in_array($file['mimetype'], $imageTypes)) {
$this->queue->insertIntoQueue(ImagenetClassifier::MODEL_NAME, $queueFile); if (in_array(ImagenetClassifier::class, $models)) {
$this->queue->insertIntoQueue(ClusteringFaceClassifier::MODEL_NAME, $queueFile); $this->queue->insertIntoQueue(ImagenetClassifier::MODEL_NAME, $queueFile);
}
if (!in_array(ImagenetClassifier::class, $models) && in_array(LandmarksClassifier::class, $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);
});
if (count($landmarkTags) > 0) {
$this->queue->insertIntoQueue(LandmarksClassifier::MODEL_NAME, $queueFile);
}
}
if (in_array(ClusteringFaceClassifier::class, $models)) {
$this->queue->insertIntoQueue(ClusteringFaceClassifier::MODEL_NAME, $queueFile);
}
} }
if (in_array($file['mimetype'], $videoTypes)) { if (in_array($file['mimetype'], $videoTypes)) {
$this->queue->insertIntoQueue(MovinetClassifier::MODEL_NAME, $queueFile); $this->queue->insertIntoQueue(MovinetClassifier::MODEL_NAME, $queueFile);
@ -113,7 +153,8 @@ class StorageCrawlJob extends QueuedJob {
'storage_id' => $storageId, 'storage_id' => $storageId,
'root_id' => $rootId, 'root_id' => $rootId,
'override_root' => $overrideRoot, 'override_root' => $overrideRoot,
'last_file_id' => $queueFile->getFileId() 'last_file_id' => $queueFile->getFileId(),
'models' => $models,
]); ]);
} }
} }

View File

@ -3,6 +3,11 @@
namespace OCA\Recognize\Controller; namespace OCA\Recognize\Controller;
use OCA\Recognize\BackgroundJobs\SchedulerJob; use OCA\Recognize\BackgroundJobs\SchedulerJob;
use OCA\Recognize\Classifiers\Audio\MusicnnClassifier;
use OCA\Recognize\Classifiers\Images\ClusteringFaceClassifier;
use OCA\Recognize\Classifiers\Images\ImagenetClassifier;
use OCA\Recognize\Classifiers\Images\LandmarksClassifier;
use OCA\Recognize\Classifiers\Video\MovinetClassifier;
use OCA\Recognize\Service\QueueService; use OCA\Recognize\Service\QueueService;
use OCA\Recognize\Service\TagManager; use OCA\Recognize\Service\TagManager;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
@ -109,6 +114,28 @@ class AdminController extends Controller {
} }
public function setSetting(string $setting, $value) { public function setSetting(string $setting, $value) {
if ($value === true && $this->config->getAppValue('recognize', $setting, 'false') === 'false') {
// Additional model enabled: Schedule new crawl run for the affected mime types
switch ($setting) {
case ClusteringFaceClassifier::MODEL_NAME . '.enabled':
$this->jobList->add(SchedulerJob::class, ['models' => [ClusteringFaceClassifier::MODEL_NAME]]);
break;
case ImagenetClassifier::MODEL_NAME . '.enabled':
$this->jobList->add(SchedulerJob::class, ['models' => [ImagenetClassifier::MODEL_NAME]]);
// no break
case LandmarksClassifier::MODEL_NAME . '.enabled':
$this->jobList->add(SchedulerJob::class, ['models' => [LandmarksClassifier::MODEL_NAME]]);
break;
case MovinetClassifier::MODEL_NAME . '.enabled':
$this->jobList->add(SchedulerJob::class, ['models' => [MovinetClassifier::MODEL_NAME]]);
break;
case MusicnnClassifier::MODEL_NAME . '.enabled':
$this->jobList->add(SchedulerJob::class, ['models' => [MusicnnClassifier::MODEL_NAME]]);
break;
default:
break;
}
}
$this->config->setAppValue('recognize', $setting, $value); $this->config->setAppValue('recognize', $setting, $value);
} }