Skip to content

Commit ccc6e22

Browse files
committed
(fix): use the event for AppAPI to get list of AI providers
Signed-off-by: Oleksander Piskun <[email protected]>
1 parent bf4085d commit ccc6e22

File tree

4 files changed

+87
-44
lines changed

4 files changed

+87
-44
lines changed

lib/AppInfo/Application.php

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use OCA\AppAPI\Listener\DeclarativeSettings\RegisterDeclarativeSettingsListener;
1616
use OCA\AppAPI\Listener\DeclarativeSettings\SetValueListener;
1717
use OCA\AppAPI\Listener\FileEventsListener;
18+
use OCA\AppAPI\Listener\GetTaskProcessingProvidersListener;
1819
use OCA\AppAPI\Listener\LoadFilesPluginListener;
1920
use OCA\AppAPI\Listener\LoadMenuEntriesListener;
2021
use OCA\AppAPI\Listener\SabrePluginAuthInitListener;
@@ -23,7 +24,6 @@
2324
use OCA\AppAPI\Middleware\ExAppUiMiddleware;
2425
use OCA\AppAPI\Notifications\ExAppNotifier;
2526
use OCA\AppAPI\PublicCapabilities;
26-
use OCA\AppAPI\Service\ProvidersAI\TaskProcessingService;
2727
use OCA\AppAPI\SetupChecks\DaemonCheck;
2828
use OCA\DAV\Events\SabrePluginAuthInitEvent;
2929
use OCA\Files\Event\LoadAdditionalScriptsEvent;
@@ -43,8 +43,7 @@
4343
use OCP\Settings\Events\DeclarativeSettingsGetValueEvent;
4444
use OCP\Settings\Events\DeclarativeSettingsRegisterFormEvent;
4545
use OCP\Settings\Events\DeclarativeSettingsSetValueEvent;
46-
use Psr\Container\ContainerExceptionInterface;
47-
use Psr\Container\NotFoundExceptionInterface;
46+
use OCP\TaskProcessing\Events\GetTaskProcessingProvidersEvent;
4847

4948
class Application extends App implements IBootstrap {
5049
public const APP_ID = 'app_api';
@@ -61,6 +60,7 @@ public function __construct(array $urlParams = []) {
6160
* @psalm-suppress UndefinedClass
6261
*/
6362
public function register(IRegistrationContext $context): void {
63+
$context->registerEventListener(GetTaskProcessingProvidersEvent::class, GetTaskProcessingProvidersListener::class);
6464
$context->registerEventListener(LoadAdditionalEntriesEvent::class, LoadMenuEntriesListener::class);
6565
$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadFilesPluginListener::class);
6666
$context->registerCapability(Capabilities::class);
@@ -75,14 +75,6 @@ public function register(IRegistrationContext $context): void {
7575
$context->registerEventListener(DeclarativeSettingsGetValueEvent::class, GetValueListener::class);
7676
$context->registerEventListener(DeclarativeSettingsSetValueEvent::class, SetValueListener::class);
7777

78-
$container = $this->getContainer();
79-
try {
80-
/** @var TaskProcessingService $taskProcessingService */
81-
$taskProcessingService = $container->get(TaskProcessingService::class);
82-
$taskProcessingService->registerExAppTaskProcessingProviders($context, $container->getServer());
83-
$taskProcessingService->registerExAppTaskProcessingCustomTaskTypes($context);
84-
} catch (NotFoundExceptionInterface|ContainerExceptionInterface) {
85-
}
8678
$context->registerEventListener(NodeCreatedEvent::class, FileEventsListener::class);
8779
$context->registerEventListener(NodeTouchedEvent::class, FileEventsListener::class);
8880
$context->registerEventListener(NodeWrittenEvent::class, FileEventsListener::class);
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\AppAPI\Listener;
11+
12+
use JsonException;
13+
use OCA\AppAPI\Service\ProvidersAI\TaskProcessingService;
14+
use OCP\EventDispatcher\Event;
15+
use OCP\EventDispatcher\IEventListener;
16+
use OCP\TaskProcessing\Events\GetTaskProcessingProvidersEvent;
17+
use Psr\Log\LoggerInterface;
18+
19+
class GetTaskProcessingProvidersListener implements IEventListener {
20+
public function __construct(
21+
private readonly TaskProcessingService $taskProcessingService,
22+
private readonly LoggerInterface $logger,
23+
) {
24+
}
25+
26+
/**
27+
* @param Event $event
28+
* @return void
29+
*/
30+
public function handle(Event $event): void {
31+
if (!$event instanceof GetTaskProcessingProvidersEvent) {
32+
return;
33+
}
34+
35+
$exAppsProviders = $this->taskProcessingService->getRegisteredTaskProcessingProviders();
36+
37+
foreach ($exAppsProviders as $exAppProvider) {
38+
try {
39+
// Decode provider data
40+
$providerData = json_decode($exAppProvider->getProvider(), true, 512, JSON_THROW_ON_ERROR);
41+
$providerInstance = $this->taskProcessingService->getAnonymousExAppProvider($providerData);
42+
$event->addProvider($providerInstance);
43+
44+
// Decode and add custom task type if it exists
45+
$customTaskTypeDataJson = $exAppProvider->getCustomTaskType();
46+
if ($customTaskTypeDataJson !== null && $customTaskTypeDataJson !== '' && $customTaskTypeDataJson !== 'null') {
47+
$customTaskTypeData = json_decode($customTaskTypeDataJson, true, 512, JSON_THROW_ON_ERROR);
48+
$taskTypeInstance = $this->taskProcessingService->getAnonymousTaskType($customTaskTypeData);
49+
$event->addTaskType($taskTypeInstance);
50+
}
51+
} catch (JsonException $e) {
52+
$this->logger->error(
53+
'Failed to decode or process ExApp TaskProcessing provider/task type during event handling',
54+
[
55+
'exAppId' => $exAppProvider->getAppId(),
56+
'providerName' => $exAppProvider->getName(),
57+
'exception' => $e->getMessage(),
58+
]
59+
);
60+
} catch (\Throwable $e) {
61+
$this->logger->error(
62+
'Unexpected error processing ExApp TaskProcessing provider/task type during event handling',
63+
[
64+
'exAppId' => $exAppProvider->getAppId(),
65+
'providerName' => $exAppProvider->getName(),
66+
'exception' => $e->getMessage(),
67+
'trace' => $e->getTraceAsString(),
68+
]
69+
);
70+
}
71+
}
72+
}
73+
}

lib/Service/ProvidersAI/TaskProcessingService.php

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ public function registerExAppTaskProcessingProviders(IRegistrationContext $conte
244244
/**
245245
* @psalm-suppress UndefinedClass, MissingDependency, InvalidReturnStatement, InvalidReturnType
246246
*/
247-
private function getAnonymousExAppProvider(
247+
public function getAnonymousExAppProvider(
248248
array $provider,
249249
): IProvider {
250250
return new class($provider) implements IProvider {
@@ -337,38 +337,7 @@ public function unregisterExAppTaskProcessingProviders(string $appId): int {
337337
return $result;
338338
}
339339

340-
/**
341-
* @param IRegistrationContext $context
342-
*
343-
* @return void
344-
*/
345-
public function registerExAppTaskProcessingCustomTaskTypes(IRegistrationContext $context): void {
346-
$exAppsProviders = $this->getRegisteredTaskProcessingProviders();
347-
foreach ($exAppsProviders as $exAppProvider) {
348-
$customTaskType = $exAppProvider->getCustomTaskType();
349-
if ($customTaskType === null) {
350-
continue;
351-
}
352-
353-
/** @var class-string<ITaskType> $className */
354-
$className = '\\OCA\\AppAPI\\' . $exAppProvider->getAppId() . '\\' . $exAppProvider->getName() . '\\TaskType';
355-
try {
356-
$taskType = $this->getAnonymousTaskType(json_decode($customTaskType, true, 512, JSON_THROW_ON_ERROR));
357-
} catch (JsonException $e) {
358-
$this->logger->debug('Failed to register ExApp TaskProcessing custom task type', ['exAppId' => $exAppProvider->getAppId(), 'taskType' => $exAppProvider->getName(), 'exception' => $e]);
359-
continue;
360-
} catch (\Throwable) {
361-
continue;
362-
}
363-
364-
$context->registerService($className, function () use ($taskType) {
365-
return $taskType;
366-
});
367-
$context->registerTaskProcessingTaskType($className);
368-
}
369-
}
370-
371-
private function getAnonymousTaskType(
340+
public function getAnonymousTaskType(
372341
array $customTaskType,
373342
): ITaskType {
374343
return new class($customTaskType) implements ITaskType {

tests/psalm-baseline.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<code><![CDATA[LoadFilesPluginListener::class]]></code>
1010
<code><![CDATA[LoadMenuEntriesListener::class]]></code>
1111
<code><![CDATA[SabrePluginAuthInitListener::class]]></code>
12+
<code><![CDATA[registerEventListener]]></code>
1213
</InvalidArgument>
1314
<MissingDependency>
1415
<code><![CDATA[DavPlugin]]></code>
@@ -81,6 +82,14 @@
8182
<code><![CDATA[private]]></code>
8283
</MissingDependency>
8384
</file>
85+
<file src="lib/Listener/GetTaskProcessingProvidersListener.php">
86+
<MissingTemplateParam>
87+
<code><![CDATA[IEventListener]]></code>
88+
</MissingTemplateParam>
89+
<UndefinedClass>
90+
<code><![CDATA[GetTaskProcessingProvidersEvent]]></code>
91+
</UndefinedClass>
92+
</file>
8493
<file src="lib/Listener/LoadFilesPluginListener.php">
8594
<ImplementedParamTypeMismatch>
8695
<code><![CDATA[$event]]></code>

0 commit comments

Comments
 (0)