tagManager = $tagManager; $this->jobList = $jobList; $this->settingsService = $settingsService; $this->queue = $queue; $this->clusterMapper = $clusterMapper; $this->detectionMapper = $detectionMapper; $this->config = $config; $this->faceDetections = $faceDetections; $this->binaryFinder = $binaryFinder; } public function reset(): JSONResponse { $this->tagManager->resetClassifications(); return new JSONResponse([]); } public function clearAllJobs(): JSONResponse { $this->queue->clearQueue('imagenet'); $this->queue->clearQueue('faces'); $this->queue->clearQueue('landmarks'); $this->queue->clearQueue('movinet'); $this->queue->clearQueue('musicnn'); $this->jobList->remove(ClassifyFacesJob::class); $this->jobList->remove(ClassifyImagenetJob::class); $this->jobList->remove(ClassifyLandmarksJob::class); $this->jobList->remove(ClassifyMusicnnJob::class); $this->jobList->remove(ClassifyMovinetJob::class); $this->jobList->remove(ClusterFacesJob::class); $this->jobList->remove(SchedulerJob::class); $this->jobList->remove(StorageCrawlJob::class); return new JSONResponse([]); } public function recrawl(): JSONResponse { $this->clearAllJobs(); $this->jobList->add(SchedulerJob::class); return new JSONResponse([]); } public function resetFaces(): JSONResponse { try { $this->clusterMapper->deleteAll(); $this->detectionMapper->deleteAll(); } catch (Exception $e) { return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); } return new JSONResponse([]); } public function count(): JSONResponse { $count = count($this->tagManager->findClassifiedFiles()); return new JSONResponse(['count' => $count]); } public function countMissed(): JSONResponse { $count = count($this->tagManager->findMissedClassifications()); return new JSONResponse(['count' => $count]); } public function countQueued(): JSONResponse { $imagenetCount = $this->queue->count('imagenet'); $facesCount = $this->queue->count('faces'); $landmarksCount = $this->queue->count('landmarks'); $movinetCount = $this->queue->count('movinet'); $musicnnCount = $this->queue->count('musicnn'); $clusterFacesCount = $this->faceDetections->countUnclustered(); return new JSONResponse([ 'imagenet' => $imagenetCount, 'faces' => $facesCount, 'landmarks' => $landmarksCount, 'movinet' => $movinetCount, 'musicnn' => $musicnnCount, 'clusterFaces' => $clusterFacesCount, ]); } public function hasJobs(string $task): JSONResponse { $tasks = [ 'faces' => ClassifyFacesJob::class, 'imagenet' => ClassifyImagenetJob::class, 'landmarks' => ClassifyLandmarksJob::class, 'musicnn' => ClassifyMusicnnJob::class, 'movinet' => ClassifyMovinetJob::class, 'clusterFaces' => ClusterFacesJob::class, ]; if (!isset($tasks[$task])) { return new JSONResponse([], Http::STATUS_BAD_REQUEST); } $iterator = $this->jobList->getJobsIterator($tasks[$task], null, 0); $lastRun = []; foreach ($iterator as $job) { $lastRun[] = $job->getLastRun(); } $count = count($lastRun); $lastRun = $lastRun? max($lastRun) : 0; return new JSONResponse([ 'scheduled' => $count, 'lastRun' => $lastRun, ]); } public function avx(): JSONResponse { try { $cpuinfo = file_get_contents('/proc/cpuinfo'); } catch (\Throwable $e) { return new JSONResponse(['avx' => null]); } return new JSONResponse(['avx' => $cpuinfo !== false && strpos($cpuinfo, 'avx') !== false]); } public function platform(): JSONResponse { return new JSONResponse(['platform' => php_uname('m')]); } public function musl(): JSONResponse { try { exec('ldd /bin/sh' . ' 2>&1', $output, $returnCode); } catch (\Throwable $e) { return new JSONResponse(['musl' => null]); } if ($returnCode !== 0) { return new JSONResponse(['musl' => null]); } $ldd = trim(implode("\n", $output)); return new JSONResponse(['musl' => strpos($ldd, 'musl') !== false]); } public function nice(): JSONResponse { /* use nice binary from settings if available */ if ($this->config->getAppValueString('nice_binary', '') !== '') { $nice_path = $this->config->getAppValueString('nice_binary'); } else { /* returns the path to the nice binary or false if not found */ $nice_path = $this->binaryFinder->findBinaryPath('nice'); } if ($nice_path !== false) { $this->config->setAppValueString('nice_binary', $nice_path); } else { $this->config->setAppValueString('nice_binary', ''); return new JSONResponse(['nice' => false]); } try { exec($nice_path . ' true' . ' 2>&1', $output, $returnCode); } catch (\Throwable $e) { return new JSONResponse(['nice' => false]); } if ($returnCode !== 0) { return new JSONResponse(['nice' => false]); } return new JSONResponse(['nice' => $nice_path]); } public function nodejs(): JSONResponse { try { exec($this->settingsService->getSetting('node_binary') . ' --version' . ' 2>&1', $output, $returnCode); } catch (\Throwable $e) { return new JSONResponse(['nodejs' => null]); } if ($returnCode !== 0) { return new JSONResponse(['nodejs' => false]); } $version = trim(implode("\n", $output)); return new JSONResponse(['nodejs' => $version]); } public function ffmpeg(): JSONResponse { try { exec($this->settingsService->getSetting('ffmpeg_binary') . ' -version' . ' 2>&1', $output, $returnCode); } catch (\Throwable $e) { return new JSONResponse(['ffmpeg' => null]); } if ($returnCode !== 0) { return new JSONResponse(['ffmpeg' => false]); } if (preg_match('/version (.*?) /', trim($output[0]), $matches) !== 1) { return new JSONResponse(['ffmpeg' => false]); } $version = $matches[1]; return new JSONResponse(['ffmpeg' => $version]); } public function libtensorflow(): JSONResponse { try { exec($this->settingsService->getSetting('node_binary') . ' ' . __DIR__ . '/../../src/test_libtensorflow.js' . ' 2>&1', $output, $returnCode); } catch (\Throwable $e) { return new JSONResponse(['libtensorflow' => false]); } if ($returnCode !== 0) { return new JSONResponse(['libtensorflow' => false]); } return new JSONResponse(['libtensorflow' => true]); } public function wasmtensorflow(): JSONResponse { try { exec($this->settingsService->getSetting('node_binary') . ' ' . __DIR__ . '/../../src/test_wasmtensorflow.js' . ' 2>&1', $output, $returnCode); } catch (\Throwable $e) { return new JSONResponse(['wasmtensorflow' => false]); } if ($returnCode !== 0) { return new JSONResponse(['wasmtensorflow' => false]); } return new JSONResponse(['wasmtensorflow' => true]); } public function gputensorflow(): JSONResponse { try { exec($this->settingsService->getSetting('node_binary') . ' ' . __DIR__ . '/../../src/test_gputensorflow.js' . ' 2>&1', $output, $returnCode); } catch (\Throwable $e) { return new JSONResponse(['gputensorflow' => false]); } if ($returnCode !== 0) { return new JSONResponse(['gputensorflow' => false]); } return new JSONResponse(['gputensorflow' => true]); } public function cron(): JSONResponse { try { /** @var IAppConfig $appConfig */ $appConfig = \OC::$server->getRegisteredAppContainer('core')->get(IAppConfig::class); $cron = $appConfig->getAppValueString('backgroundjobs_mode', ''); } catch (QueryException|AppConfigTypeConflictException $e) { return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); } return new JSONResponse(['cron' => $cron]); } /** * @param string $setting * @param scalar $value * @return JSONResponse */ public function setSetting(string $setting, float|bool|int|string $value): JSONResponse { try { $this->settingsService->setSetting($setting, (string) $value); return new JSONResponse([], Http::STATUS_OK); } catch (\OCA\Recognize\Exception\Exception $e) { return new JSONResponse([], Http::STATUS_BAD_REQUEST); } } public function getSetting(string $setting): JSONResponse { return new JSONResponse(['value' => $this->settingsService->getSetting($setting)]); } }