From 8e310a04c145a4b556c5c68d699e9e2bc79a2e5a Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Tue, 26 Mar 2024 14:00:19 +0100 Subject: [PATCH] add OpenAPI doc to generate specs Signed-off-by: Julien Veyssier --- .gitignore | 1 + appinfo/info.xml | 16 +- appinfo/routes.php | 2 +- composer.json | 18 +- lib/AppInfo/Application.php | 30 +- lib/Capabilities.php | 4 +- lib/Command/CleanupAssistantTasks.php | 6 +- lib/Command/CleanupImageGenerations.php | 6 +- lib/Controller/AssistantApiController.php | 72 +- lib/Controller/AssistantController.php | 8 +- lib/Controller/ConfigController.php | 6 +- lib/Controller/FreePromptController.php | 6 +- lib/Controller/PreviewController.php | 8 +- lib/Controller/SpeechToTextApiController.php | 34 +- lib/Controller/SpeechToTextController.php | 8 +- lib/Controller/Text2ImageApiController.php | 99 +- lib/Controller/Text2ImageController.php | 34 +- lib/Cron/CleanupAssistantTasks.php | 4 +- lib/Cron/CleanupImageGenerations.php | 4 +- lib/Db/FreePrompt/Prompt.php | 2 +- lib/Db/FreePrompt/PromptMapper.php | 4 +- lib/Db/MetaTask.php | 2 +- lib/Db/MetaTaskMapper.php | 4 +- lib/Db/Text2Image/ImageFileName.php | 2 +- lib/Db/Text2Image/ImageFileNameMapper.php | 2 +- lib/Db/Text2Image/ImageGeneration.php | 2 +- lib/Db/Text2Image/ImageGenerationMapper.php | 4 +- lib/Db/Text2Image/Prompt.php | 2 +- lib/Db/Text2Image/PromptMapper.php | 4 +- lib/Db/Text2Image/StaleGeneration.php | 2 +- lib/Db/Text2Image/StaleGenerationMapper.php | 2 +- .../BeforeAssistantNotificationEvent.php | 2 +- .../BeforeTemplateRenderedListener.php | 4 +- .../FreePromptReferenceListener.php | 4 +- .../SpeechToTextReferenceListener.php | 6 +- .../SpeechToTextResultListener.php | 8 +- lib/Listener/TaskFailedListener.php | 10 +- lib/Listener/TaskSuccessfulListener.php | 10 +- .../Text2ImageReferenceListener.php | 4 +- .../Text2Image/Text2ImageResultListener.php | 12 +- .../Version010003Date20231208083112.php | 2 +- .../Version010004Date20240131182344.php | 2 +- lib/Notification/Notifier.php | 4 +- lib/Reference/FreePromptReferenceProvider.php | 4 +- .../SpeechToTextReferenceProvider.php | 4 +- lib/Reference/Text2ImageReferenceProvider.php | 6 +- lib/ResponseDefinitions.php | 67 + lib/Service/AssistantService.php | 16 +- lib/Service/FreePrompt/FreePromptService.php | 8 +- lib/Service/NotificationService.php | 6 +- lib/Service/PreviewService.php | 4 +- .../SpeechToText/SpeechToTextService.php | 8 +- lib/Service/Text2Image/CleanUpService.php | 6 +- .../Text2Image/Text2ImageHelperService.php | 32 +- lib/Settings/Admin.php | 4 +- lib/Settings/Personal.php | 8 +- lib/Settings/PersonalSection.php | 2 +- openapi.json | 2605 +++++++++++++++++ src/assistant.js | 8 +- src/main.js | 9 +- .../Text2ImageCustomPickerElement.vue | 6 +- templates/adminSettings.php | 2 +- templates/imageGenerationPage.php | 2 +- templates/personalSettings.php | 2 +- templates/speechToTextResultPage.php | 2 +- templates/taskResultPage.php | 2 +- tests/bootstrap.php | 2 +- .../Service/TextProcessingServiceTest.php | 4 +- 68 files changed, 3042 insertions(+), 243 deletions(-) create mode 100644 lib/ResponseDefinitions.php create mode 100644 openapi.json diff --git a/.gitignore b/.gitignore index 00eb3e66..0e7f975f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ node_modules /composer.lock /vendor/ +/tests/.phpunit*cache diff --git a/appinfo/info.xml b/appinfo/info.xml index 13df2476..65b33d17 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -54,7 +54,7 @@ Known providers: 1.0.7 agpl Julien Veyssier - TpAssistant + Assistant https://github.com/nextcloud/assistant @@ -65,19 +65,19 @@ Known providers: https://github.com/nextcloud/assistant/raw/main/img/screenshot2.jpg https://github.com/nextcloud/assistant/raw/main/img/screenshot3.jpg - OCA\TpAssistant\Cron\CleanupImageGenerations - OCA\TpAssistant\Cron\CleanupAssistantTasks + OCA\Assistant\Cron\CleanupImageGenerations + OCA\Assistant\Cron\CleanupAssistantTasks - OCA\TpAssistant\Command\CleanupImageGenerations - OCA\TpAssistant\Command\CleanupAssistantTasks + OCA\Assistant\Command\CleanupImageGenerations + OCA\Assistant\Command\CleanupAssistantTasks - OCA\TpAssistant\Settings\Admin - OCA\TpAssistant\Settings\Personal - OCA\TpAssistant\Settings\PersonalSection + OCA\Assistant\Settings\Admin + OCA\Assistant\Settings\Personal + OCA\Assistant\Settings\PersonalSection diff --git a/appinfo/routes.php b/appinfo/routes.php index dd9ce373..2cf95d67 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -13,6 +13,7 @@ ['name' => 'assistant#getAssistantTaskResultPage', 'url' => '/task/view/{metaTaskId}', 'verb' => 'GET'], ['name' => 'Text2Image#showGenerationPage', 'url' => '/i/{imageGenId}', 'verb' => 'GET'], + ['name' => 'Text2Image#getPromptHistory', 'url' => '/i/prompt_history', 'verb' => 'GET'], ['name' => 'FreePrompt#processPrompt', 'url' => '/f/process_prompt', 'verb' => 'POST'], ['name' => 'FreePrompt#getPromptHistory', 'url' => '/f/prompt_history', 'verb' => 'GET'], @@ -35,7 +36,6 @@ ['name' => 'assistantApi#cancelTask', 'url' => '/api/{apiVersion}/task/cancel/{metaTaskId}', 'verb' => 'PUT', 'requirements' => $requirements], ['name' => 'Text2ImageApi#processPrompt', 'url' => '/api/{apiVersion}/i/process_prompt', 'verb' => 'POST', 'requirements' => $requirements], - ['name' => 'Text2ImageApi#getPromptHistory', 'url' => '/api/{apiVersion}/i/prompt_history', 'verb' => 'GET', 'requirements' => $requirements], ['name' => 'Text2ImageApi#getGenerationInfo', 'url' => '/api/{apiVersion}/i/info/{imageGenId}', 'verb' => 'GET', 'requirements' => $requirements], ['name' => 'Text2ImageApi#getImage', 'url' => '/api/{apiVersion}/i/{imageGenId}/{fileNameId}', 'verb' => 'GET', 'requirements' => $requirements], ['name' => 'Text2ImageApi#cancelGeneration', 'url' => '/api/{apiVersion}/i/cancel_generation', 'verb' => 'POST', 'requirements' => $requirements], diff --git a/composer.json b/composer.json index 4d39d301..fe51a0b4 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "php": "^8.0", + "php": "^8.1", "erusev/parsedown": "^1.7", "phpoffice/phpword": "^1.2" }, @@ -20,20 +20,28 @@ "cs:check": "php-cs-fixer fix --dry-run --diff", "cs:fix": "php-cs-fixer fix", "psalm": "psalm.phar --no-cache", - "test:unit": "phpunit --config tests/phpunit.xml" + "test:unit": "phpunit --config tests/phpunit.xml", + "openapi": "generate-spec --verbose --allow-missing-docs --continue-on-error" }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/nextcloud/openapi-extractor" + } + ], "require-dev": { "nextcloud/coding-standard": "^1.1", "psalm/phar": "^5.16", "nextcloud/ocp": "dev-master", - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^9.5", + "nextcloud/openapi-extractor": "dev-main" }, "config": { "sort-packages": true, "optimize-autoloader": true, "platform": { - "php": "8.0" + "php": "8.1" }, - "autoloader-suffix": "TpAssistant" + "autoloader-suffix": "Assistant" } } diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index fda929fb..4960cb4c 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -1,20 +1,20 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Command; +namespace OCA\Assistant\Command; use Exception; use OC\Core\Command\Base; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Db\MetaTaskMapper; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Db\MetaTaskMapper; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; diff --git a/lib/Command/CleanupImageGenerations.php b/lib/Command/CleanupImageGenerations.php index 47171723..a8ce0e1e 100644 --- a/lib/Command/CleanupImageGenerations.php +++ b/lib/Command/CleanupImageGenerations.php @@ -3,12 +3,12 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Command; +namespace OCA\Assistant\Command; use Exception; use OC\Core\Command\Base; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Service\Text2Image\CleanUpService; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Service\Text2Image\CleanUpService; use OCP\IConfig; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; diff --git a/lib/Controller/AssistantApiController.php b/lib/Controller/AssistantApiController.php index 525d60e0..f15d4cbf 100644 --- a/lib/Controller/AssistantApiController.php +++ b/lib/Controller/AssistantApiController.php @@ -1,18 +1,24 @@ }, array{}> */ #[NoAdminRequired] #[NoCSRFRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['task_management'])] public function getAvailableTaskTypes(): DataResponse { $taskTypes = $this->assistantService->getAvailableTaskTypes(); return new DataResponse(['types' => $taskTypes]); } /** + * Delete an assistant task + * * @param int $metaTaskId - * @return DataResponse + * @return DataResponse */ #[NoAdminRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['task_management'])] public function deleteTask(int $metaTaskId): DataResponse { if ($this->userId !== null) { try { @@ -54,9 +66,10 @@ public function deleteTask(int $metaTaskId): DataResponse { /** * @param int $metaTaskId - * @return DataResponse + * @return DataResponse */ #[NoAdminRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['task_management'])] public function cancelTask(int $metaTaskId): DataResponse { if ($this->userId !== null) { try { @@ -70,10 +83,16 @@ public function cancelTask(int $metaTaskId): DataResponse { } /** + * Get an assistant task + * * @param int $metaTaskId - * @return DataResponse + * @return DataResponse|DataResponse + * + * 200: Task has been found + * 404: Task has not been found */ #[NoAdminRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['task_management'])] public function getAssistantTask(int $metaTaskId): DataResponse { if ($this->userId !== null) { $task = $this->assistantService->getAssistantTask($this->userId, $metaTaskId); @@ -86,7 +105,15 @@ public function getAssistantTask(int $metaTaskId): DataResponse { return new DataResponse('', Http::STATUS_NOT_FOUND); } + /** + * Get user's tasks + * + * @param string|null $taskType + * @param int|null $category + * @return DataResponse}, array{}>|DataResponse + */ #[NoAdminRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['task_management'])] public function getUserTasks(?string $taskType = null, ?int $category = null): DataResponse { if ($this->userId !== null) { try { @@ -103,13 +130,16 @@ public function getUserTasks(?string $taskType = null, ?int $category = null): D } /** - * @param array $inputs + * Run a text processing task + * + * @param array $inputs * @param string $type * @param string $appId * @param string $identifier - * @return DataResponse + * @return DataResponse|DataResponse */ #[NoAdminRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['text_processing'])] public function runTextProcessingTask(string $type, array $inputs, string $appId, string $identifier): DataResponse { if ($this->userId === null) { return new DataResponse('Unknow user', Http::STATUS_BAD_REQUEST); @@ -126,13 +156,16 @@ public function runTextProcessingTask(string $type, array $inputs, string $appId } /** - * @param array $inputs + * Schedule a text processing task + * + * @param array $inputs * @param string $type * @param string $appId * @param string $identifier - * @return DataResponse + * @return DataResponse|DataResponse */ #[NoAdminRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['text_processing'])] public function scheduleTextProcessingTask(string $type, array $inputs, string $appId, string $identifier): DataResponse { if ($this->userId === null) { return new DataResponse('Unknow user', Http::STATUS_BAD_REQUEST); @@ -149,13 +182,18 @@ public function scheduleTextProcessingTask(string $type, array $inputs, string $ } /** - * @param array $inputs + * Run or schedule a text processing task + * + * If the task runs immediately or is schedule depends on the estimated runtime declared by the provider. + * + * @param array $inputs * @param string $type * @param string $appId * @param string $identifier - * @return DataResponse + * @return DataResponse|DataResponse */ #[NoAdminRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['text_processing'])] public function runOrScheduleTextProcessingTask(string $type, array $inputs, string $appId, string $identifier): DataResponse { if ($this->userId === null) { return new DataResponse('Unknow user', Http::STATUS_BAD_REQUEST); @@ -172,10 +210,12 @@ public function runOrScheduleTextProcessingTask(string $type, array $inputs, str } /** - * Parse text from file (if parsing the file type is supported) + * Extract text from file + * + * Parse and extract text content of a file (if the file type is supported) * * @param string $filePath - * @return DataResponse + * @return DataResponse|DataResponse */ #[NoAdminRequired] public function parseTextFromFile(string $filePath): DataResponse { diff --git a/lib/Controller/AssistantController.php b/lib/Controller/AssistantController.php index 018dea1b..4b68b0a8 100644 --- a/lib/Controller/AssistantController.php +++ b/lib/Controller/AssistantController.php @@ -1,17 +1,19 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Controller; +namespace OCA\Assistant\Controller; use Exception; -use OCA\TpAssistant\Service\FreePrompt\FreePromptService; +use OCA\Assistant\Service\FreePrompt\FreePromptService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\DataResponse; use OCP\IL10N; use OCP\IRequest; +#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)] class FreePromptController extends Controller { public function __construct( string $appName, diff --git a/lib/Controller/PreviewController.php b/lib/Controller/PreviewController.php index 6f15b7a3..4f616216 100644 --- a/lib/Controller/PreviewController.php +++ b/lib/Controller/PreviewController.php @@ -1,6 +1,6 @@ . */ -namespace OCA\TpAssistant\Controller; +namespace OCA\Assistant\Controller; use Exception; use InvalidArgumentException; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Service\SpeechToText\SpeechToTextService; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Service\SpeechToText\SpeechToTextService; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\DataResponse; @@ -43,7 +43,7 @@ class SpeechToTextApiController extends OCSController { public function __construct( string $appName, IRequest $request, - private SpeechToTextService $service, + private SpeechToTextService $sttService, private LoggerInterface $logger, private IL10N $l10n, private ?string $userId, @@ -52,8 +52,10 @@ public function __construct( } /** + * Get transcription text from transcription task ID + * * @param int $id Transcript ID - * @return DataResponse + * @return DataResponse */ #[NoAdminRequired] public function getTranscript(int $id): DataResponse { @@ -61,15 +63,19 @@ public function getTranscript(int $id): DataResponse { return new DataResponse('', Http::STATUS_UNAUTHORIZED); } try { - return new DataResponse($this->service->internalGetTask($this->userId, $id)->getOutput()); + return new DataResponse($this->sttService->internalGetTask($this->userId, $id)->getOutput()); } catch (Exception $e) { - return new DataResponse($e->getMessage(), intval($e->getCode())); + /** @var Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND $exceptionCode */ + $exceptionCode = (int) $e->getCode(); + return new DataResponse($e->getMessage(), $exceptionCode); } } /** - * @return DataResponse + * Run audio transcription of an uploaded file + * + * @return DataResponse * @throws NotPermittedException */ #[NoAdminRequired] @@ -89,8 +95,8 @@ public function transcribeAudio(): DataResponse { } try { - $this->service->transcribeAudio($audioData['tmp_name'], $this->userId); - return new DataResponse('ok'); + $this->sttService->transcribeAudio($audioData['tmp_name'], $this->userId); + return new DataResponse(''); } catch (RuntimeException $e) { $this->logger->error( 'Runtime exception: ' . $e->getMessage(), @@ -116,8 +122,10 @@ public function transcribeAudio(): DataResponse { } /** + * Run audio transcription of a user's file + * * @param string $path Nextcloud file path - * @return DataResponse + * @return DataResponse */ #[NoAdminRequired] public function transcribeFile(string $path): DataResponse { @@ -126,8 +134,8 @@ public function transcribeFile(string $path): DataResponse { } try { - $this->service->transcribeFile($path, $this->userId); - return new DataResponse('ok'); + $this->sttService->transcribeFile($path, $this->userId); + return new DataResponse(''); } catch (NotFoundException $e) { $this->logger->error('Audio file not found: ' . $e->getMessage(), ['app' => Application::APP_ID]); return new DataResponse( diff --git a/lib/Controller/SpeechToTextController.php b/lib/Controller/SpeechToTextController.php index 3fae1da4..fb1c7487 100644 --- a/lib/Controller/SpeechToTextController.php +++ b/lib/Controller/SpeechToTextController.php @@ -20,19 +20,21 @@ * along with this program. If not, see . */ -namespace OCA\TpAssistant\Controller; +namespace OCA\Assistant\Controller; use Exception; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Service\SpeechToText\SpeechToTextService; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Service\SpeechToText\SpeechToTextService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; use OCP\IRequest; +#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)] class SpeechToTextController extends Controller { public function __construct( diff --git a/lib/Controller/Text2ImageApiController.php b/lib/Controller/Text2ImageApiController.php index 67daf89b..9967cc67 100644 --- a/lib/Controller/Text2ImageApiController.php +++ b/lib/Controller/Text2ImageApiController.php @@ -3,26 +3,31 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Controller; +namespace OCA\Assistant\Controller; use Exception; -use OCA\TpAssistant\Service\Text2Image\Text2ImageHelperService; +use OCA\Assistant\ResponseDefinitions; +use OCA\Assistant\Service\Text2Image\Text2ImageHelperService; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\AnonRateLimit; use OCP\AppFramework\Http\Attribute\BruteForceProtection; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\DataDisplayResponse; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; -use OCP\Db\Exception as DbException; use OCP\Files\NotPermittedException; use OCP\IL10N; use OCP\IRequest; use OCP\TextToImage\Exception\TaskFailureException; +/** + * @psalm-import-type AssistantImageProcessPromptResponse from ResponseDefinitions + * @psalm-import-type AssistantImageGenInfo from ResponseDefinitions + */ class Text2ImageApiController extends OCSController { public function __construct( string $appName, @@ -35,6 +40,8 @@ public function __construct( } /** + * Run or schedule an image generation task + * * @param string $appId * @param string $identifier * @param string $prompt @@ -42,10 +49,11 @@ public function __construct( * @param bool $displayPrompt * @param bool $notifyReadyIfScheduled * @param bool $schedule - * @return DataResponse + * @return DataResponse|DataResponse */ #[NoAdminRequired] #[NoCSRFRequired] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['image_generation'])] public function processPrompt( string $appId, string $identifier, string $prompt, int $nResults = 1, bool $displayPrompt = false, bool $notifyReadyIfScheduled = false, bool $schedule = false @@ -63,42 +71,29 @@ public function processPrompt( } /** - * @return DataResponse - */ - #[NoAdminRequired] - #[NoCSRFRequired] - public function getPromptHistory(): DataResponse { - - if ($this->userId === null) { - return new DataResponse(['error' => $this->l10n->t('Failed to get prompt history; unknown user')], Http::STATUS_INTERNAL_SERVER_ERROR); - } - - try { - $response = $this->text2ImageHelperService->getPromptHistory($this->userId); - } catch (DbException $e) { - return new DataResponse(['error' => $this->l10n->t('Unknown error while retrieving prompt history.')], Http::STATUS_INTERNAL_SERVER_ERROR); - } - - return new DataResponse($response); - } - - /** + * Get one image of a generation + * * @param string $imageGenId * @param int $fileNameId - * @return DataDisplayResponse | DataResponse + * @return DataDisplayResponse>|DataResponse + * + * 200: Returns the image data */ #[NoAdminRequired] #[NoCSRFRequired] #[PublicPage] #[BruteForceProtection(action: 'imageGenId')] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['image_generation'])] public function getImage(string $imageGenId, int $fileNameId): DataDisplayResponse | DataResponse { try { $result = $this->text2ImageHelperService->getImage($imageGenId, $fileNameId); } catch (Exception $e) { - $response = new DataResponse(['error' => $e->getMessage()], (int) $e->getCode()); - if ($e->getCode() === Http::STATUS_BAD_REQUEST || $e->getCode() === Http::STATUS_UNAUTHORIZED) { + /** @var Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_BAD_REQUEST $exceptionCode */ + $exceptionCode = (int) $e->getCode(); + $response = new DataResponse(['error' => $e->getMessage()], $exceptionCode); + if ($exceptionCode === Http::STATUS_BAD_REQUEST || $exceptionCode === Http::STATUS_UNAUTHORIZED) { // Throttle brute force attempts - $response->throttle(['imageGenId' => $imageGenId, 'fileId' => $fileNameId, 'status' => $e->getCode()]); + $response->throttle(['imageGenId' => $imageGenId, 'fileId' => $fileNameId, 'status' => $exceptionCode]); } return $response; } @@ -119,21 +114,31 @@ public function getImage(string $imageGenId, int $fileNameId): DataDisplayRespon } /** + * Get image generation information + * * @param string $imageGenId - * @return DataResponse + * @return DataResponse|DataResponse + * + * 200: Returns the requested data + * 400: The image generation does not exist + * 404: The image generation has been deleted + * 500: Other error */ #[NoAdminRequired] #[NoCSRFRequired] #[PublicPage] #[BruteForceProtection(action: 'imageGenId')] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['image_generation'])] public function getGenerationInfo(string $imageGenId): DataResponse { try { $result = $this->text2ImageHelperService->getGenerationInfo($imageGenId, $this->userId, true); } catch (Exception $e) { - $response = new DataResponse(['error' => $e->getMessage()], (int) $e->getCode()); - if ($e->getCode() === Http::STATUS_BAD_REQUEST || $e->getCode() === Http::STATUS_UNAUTHORIZED) { + /** @var Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR $exceptionCode */ + $exceptionCode = (int) $e->getCode(); + $response = new DataResponse(['error' => $e->getMessage()], $exceptionCode); + if ($exceptionCode === Http::STATUS_BAD_REQUEST || $exceptionCode === Http::STATUS_UNAUTHORIZED) { // Throttle brute force attempts - $response->throttle(['imageGenId' => $imageGenId, 'status' => $e->getCode()]); + $response->throttle(['imageGenId' => $imageGenId, 'status' => $exceptionCode]); } return $response; } @@ -142,34 +147,39 @@ public function getGenerationInfo(string $imageGenId): DataResponse { } /** + * Set visibility of images in one generation + * * @param string $imageGenId - * @param array $fileVisStatusArray - * @return DataResponse + * @param array $fileVisStatusArray + * @return DataResponse|DataResponse */ #[NoAdminRequired] #[NoCSRFRequired] #[BruteForceProtection(action: 'imageGenId')] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['image_generation'])] public function setVisibilityOfImageFiles(string $imageGenId, array $fileVisStatusArray): DataResponse { if ($this->userId === null) { return new DataResponse(['error' => $this->l10n->t('Failed to set visibility of image files; unknown user')], Http::STATUS_INTERNAL_SERVER_ERROR); } if (count($fileVisStatusArray) < 1) { - return new DataResponse('File visibility array empty', Http::STATUS_BAD_REQUEST); + return new DataResponse(['error' => 'File visibility array empty'], Http::STATUS_BAD_REQUEST); } try { $this->text2ImageHelperService->setVisibilityOfImageFiles($imageGenId, $fileVisStatusArray, $this->userId); } catch (Exception $e) { - $response = new DataResponse(['error' => $e->getMessage()], (int) $e->getCode()); - if($e->getCode() === Http::STATUS_BAD_REQUEST || $e->getCode() === Http::STATUS_UNAUTHORIZED) { + /** @var Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED|Http::STATUS_INTERNAL_SERVER_ERROR $exceptionCode */ + $exceptionCode = (int) $e->getCode(); + $response = new DataResponse(['error' => $e->getMessage()], $exceptionCode); + if($exceptionCode === Http::STATUS_BAD_REQUEST || $exceptionCode === Http::STATUS_UNAUTHORIZED) { // Throttle brute force attempts - $response->throttle(['imageGenId' => $imageGenId, 'status' => $e->getCode()]); + $response->throttle(['imageGenId' => $imageGenId, 'status' => $exceptionCode]); } return $response; } - return new DataResponse('success', Http::STATUS_OK); + return new DataResponse('', Http::STATUS_OK); } /** @@ -178,10 +188,14 @@ public function setVisibilityOfImageFiles(string $imageGenId, array $fileVisStat * Does not need bruteforce protection since we respond with success anyways * as we don't want to keep the front-end waiting. * However, we still use rate limiting to prevent timing attacks. + * + * @param string $imageGenId + * @return DataResponse|DataResponse */ #[NoAdminRequired] #[NoCSRFRequired] #[AnonRateLimit(limit: 10, period: 60)] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['image_generation'])] public function notifyWhenReady(string $imageGenId): DataResponse { if ($this->userId === null) { return new DataResponse(['error' => $this->l10n->t('Failed to notify when ready; unknown user')], Http::STATUS_INTERNAL_SERVER_ERROR); @@ -192,7 +206,7 @@ public function notifyWhenReady(string $imageGenId): DataResponse { } catch (Exception $e) { // Ignore } - return new DataResponse('success', Http::STATUS_OK); + return new DataResponse('', Http::STATUS_OK); } /** @@ -203,18 +217,19 @@ public function notifyWhenReady(string $imageGenId): DataResponse { * won't gain access to the generation since its deleted during the attack.) * * @param string $imageGenId - * @return DataResponse + * @return DataResponse|DataResponse * @throws NotPermittedException */ #[NoAdminRequired] #[NoCSRFRequired] #[AnonRateLimit(limit: 10, period: 60)] + #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['image_generation'])] public function cancelGeneration(string $imageGenId): DataResponse { if ($this->userId === null) { return new DataResponse(['error' => $this->l10n->t('Failed to cancel generation; unknown user')], Http::STATUS_INTERNAL_SERVER_ERROR); } $this->text2ImageHelperService->cancelGeneration($imageGenId, $this->userId); - return new DataResponse('success', Http::STATUS_OK); + return new DataResponse('', Http::STATUS_OK); } } diff --git a/lib/Controller/Text2ImageController.php b/lib/Controller/Text2ImageController.php index 599ca53a..c12b6042 100644 --- a/lib/Controller/Text2ImageController.php +++ b/lib/Controller/Text2ImageController.php @@ -3,22 +3,33 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Controller; +namespace OCA\Assistant\Controller; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Service\Text2Image\Text2ImageHelperService; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\Attribute\PublicPage; +use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; +use OCP\DB\Exception as DbException; +use OCP\IL10N; use OCP\IRequest; +#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)] class Text2ImageController extends Controller { + public function __construct( string $appName, IRequest $request, + private Text2ImageHelperService $text2ImageHelperService, + private IL10N $l10n, private IInitialState $initialStateService, + private ?string $userId, ) { parent::__construct($appName, $request); } @@ -43,4 +54,23 @@ public function showGenerationPage(?string $imageGenId, ?bool $forceEditMode = f return new TemplateResponse(Application::APP_ID, 'imageGenerationPage'); } + + /** + * @return DataResponse + */ + #[NoAdminRequired] + #[NoCSRFRequired] + public function getPromptHistory(): DataResponse { + if ($this->userId === null) { + return new DataResponse(['error' => $this->l10n->t('Failed to get prompt history; unknown user')], Http::STATUS_INTERNAL_SERVER_ERROR); + } + + try { + $response = $this->text2ImageHelperService->getPromptHistory($this->userId); + } catch (DbException $e) { + return new DataResponse(['error' => $this->l10n->t('Unknown error while retrieving prompt history.')], Http::STATUS_INTERNAL_SERVER_ERROR); + } + + return new DataResponse($response); + } } diff --git a/lib/Cron/CleanupAssistantTasks.php b/lib/Cron/CleanupAssistantTasks.php index 288cdb7b..2bab6621 100644 --- a/lib/Cron/CleanupAssistantTasks.php +++ b/lib/Cron/CleanupAssistantTasks.php @@ -4,10 +4,10 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Cron; +namespace OCA\Assistant\Cron; use Exception; -use OCA\TpAssistant\Db\MetaTaskMapper; +use OCA\Assistant\Db\MetaTaskMapper; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; use Psr\Log\LoggerInterface; diff --git a/lib/Cron/CleanupImageGenerations.php b/lib/Cron/CleanupImageGenerations.php index 961bccf6..f87ab312 100644 --- a/lib/Cron/CleanupImageGenerations.php +++ b/lib/Cron/CleanupImageGenerations.php @@ -4,10 +4,10 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Cron; +namespace OCA\Assistant\Cron; use Exception; -use OCA\TpAssistant\Service\Text2Image\CleanUpService; +use OCA\Assistant\Service\Text2Image\CleanUpService; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; use Psr\Log\LoggerInterface; diff --git a/lib/Db/FreePrompt/Prompt.php b/lib/Db/FreePrompt/Prompt.php index 4b3aa643..ecc29ba2 100644 --- a/lib/Db/FreePrompt/Prompt.php +++ b/lib/Db/FreePrompt/Prompt.php @@ -4,7 +4,7 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Db\FreePrompt; +namespace OCA\Assistant\Db\FreePrompt; use OCP\AppFramework\Db\Entity; diff --git a/lib/Db/FreePrompt/PromptMapper.php b/lib/Db/FreePrompt/PromptMapper.php index c9a02fd3..dc306bd8 100644 --- a/lib/Db/FreePrompt/PromptMapper.php +++ b/lib/Db/FreePrompt/PromptMapper.php @@ -5,10 +5,10 @@ declare(strict_types=1); -namespace OCA\TpAssistant\Db\FreePrompt; +namespace OCA\Assistant\Db\FreePrompt; use DateTime; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Db\QBMapper; diff --git a/lib/Db/MetaTask.php b/lib/Db/MetaTask.php index 30d3592c..3f82616f 100644 --- a/lib/Db/MetaTask.php +++ b/lib/Db/MetaTask.php @@ -4,7 +4,7 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Db; +namespace OCA\Assistant\Db; use OCP\AppFramework\Db\Entity; diff --git a/lib/Db/MetaTaskMapper.php b/lib/Db/MetaTaskMapper.php index 3ca8a0a6..7ff0d7bd 100644 --- a/lib/Db/MetaTaskMapper.php +++ b/lib/Db/MetaTaskMapper.php @@ -5,10 +5,10 @@ declare(strict_types=1); -namespace OCA\TpAssistant\Db; +namespace OCA\Assistant\Db; use DateTime; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Db\QBMapper; diff --git a/lib/Db/Text2Image/ImageFileName.php b/lib/Db/Text2Image/ImageFileName.php index e581524d..b041fd35 100644 --- a/lib/Db/Text2Image/ImageFileName.php +++ b/lib/Db/Text2Image/ImageFileName.php @@ -4,7 +4,7 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Db\Text2Image; +namespace OCA\Assistant\Db\Text2Image; use OCP\AppFramework\Db\Entity; diff --git a/lib/Db/Text2Image/ImageFileNameMapper.php b/lib/Db/Text2Image/ImageFileNameMapper.php index 89ab1bd6..5eb53719 100644 --- a/lib/Db/Text2Image/ImageFileNameMapper.php +++ b/lib/Db/Text2Image/ImageFileNameMapper.php @@ -4,7 +4,7 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Db\Text2Image; +namespace OCA\Assistant\Db\Text2Image; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; diff --git a/lib/Db/Text2Image/ImageGeneration.php b/lib/Db/Text2Image/ImageGeneration.php index 1f4de526..697d5bc0 100644 --- a/lib/Db/Text2Image/ImageGeneration.php +++ b/lib/Db/Text2Image/ImageGeneration.php @@ -4,7 +4,7 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Db\Text2Image; +namespace OCA\Assistant\Db\Text2Image; use OCP\AppFramework\Db\Entity; diff --git a/lib/Db/Text2Image/ImageGenerationMapper.php b/lib/Db/Text2Image/ImageGenerationMapper.php index adfeaf34..c3fc3107 100644 --- a/lib/Db/Text2Image/ImageGenerationMapper.php +++ b/lib/Db/Text2Image/ImageGenerationMapper.php @@ -4,10 +4,10 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Db\Text2Image; +namespace OCA\Assistant\Db\Text2Image; use DateTime; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Db\QBMapper; diff --git a/lib/Db/Text2Image/Prompt.php b/lib/Db/Text2Image/Prompt.php index b1f780ec..b03bbf40 100644 --- a/lib/Db/Text2Image/Prompt.php +++ b/lib/Db/Text2Image/Prompt.php @@ -4,7 +4,7 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Db\Text2Image; +namespace OCA\Assistant\Db\Text2Image; use OCP\AppFramework\Db\Entity; diff --git a/lib/Db/Text2Image/PromptMapper.php b/lib/Db/Text2Image/PromptMapper.php index 141bee99..788e49d1 100644 --- a/lib/Db/Text2Image/PromptMapper.php +++ b/lib/Db/Text2Image/PromptMapper.php @@ -6,10 +6,10 @@ declare(strict_types=1); -namespace OCA\TpAssistant\Db\Text2Image; +namespace OCA\Assistant\Db\Text2Image; use DateTime; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; use OCP\AppFramework\Db\MultipleObjectsReturnedException; diff --git a/lib/Db/Text2Image/StaleGeneration.php b/lib/Db/Text2Image/StaleGeneration.php index 1f0a835d..c390e52d 100644 --- a/lib/Db/Text2Image/StaleGeneration.php +++ b/lib/Db/Text2Image/StaleGeneration.php @@ -4,7 +4,7 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Db\Text2Image; +namespace OCA\Assistant\Db\Text2Image; use OCP\AppFramework\Db\Entity; diff --git a/lib/Db/Text2Image/StaleGenerationMapper.php b/lib/Db/Text2Image/StaleGenerationMapper.php index fece0816..19c0f76b 100644 --- a/lib/Db/Text2Image/StaleGenerationMapper.php +++ b/lib/Db/Text2Image/StaleGenerationMapper.php @@ -5,7 +5,7 @@ declare(strict_types=1); -namespace OCA\TpAssistant\Db\Text2Image; +namespace OCA\Assistant\Db\Text2Image; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; diff --git a/lib/Event/BeforeAssistantNotificationEvent.php b/lib/Event/BeforeAssistantNotificationEvent.php index afa8aed6..dbe9367c 100644 --- a/lib/Event/BeforeAssistantNotificationEvent.php +++ b/lib/Event/BeforeAssistantNotificationEvent.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace OCA\TpAssistant\Event; +namespace OCA\Assistant\Event; use OCP\EventDispatcher\Event; use OCP\TextProcessing\Task; diff --git a/lib/Listener/BeforeTemplateRenderedListener.php b/lib/Listener/BeforeTemplateRenderedListener.php index 46a2804c..b06de898 100644 --- a/lib/Listener/BeforeTemplateRenderedListener.php +++ b/lib/Listener/BeforeTemplateRenderedListener.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace OCA\TpAssistant\Listener; +namespace OCA\Assistant\Listener; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; diff --git a/lib/Listener/FreePrompt/FreePromptReferenceListener.php b/lib/Listener/FreePrompt/FreePromptReferenceListener.php index 3c80572e..6465be98 100644 --- a/lib/Listener/FreePrompt/FreePromptReferenceListener.php +++ b/lib/Listener/FreePrompt/FreePromptReferenceListener.php @@ -3,9 +3,9 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Listener\FreePrompt; +namespace OCA\Assistant\Listener\FreePrompt; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\Collaboration\Reference\RenderReferenceEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; diff --git a/lib/Listener/SpeechToText/SpeechToTextReferenceListener.php b/lib/Listener/SpeechToText/SpeechToTextReferenceListener.php index 94eaedde..adb72412 100644 --- a/lib/Listener/SpeechToText/SpeechToTextReferenceListener.php +++ b/lib/Listener/SpeechToText/SpeechToTextReferenceListener.php @@ -20,9 +20,9 @@ * along with this program. If not, see . */ -namespace OCA\TpAssistant\Listener\SpeechToText; +namespace OCA\Assistant\Listener\SpeechToText; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\Collaboration\Reference\RenderReferenceEvent; use OCP\EventDispatcher\Event; @@ -48,7 +48,7 @@ public function handle(Event $event): void { } if ($this->config->getAppValue(Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1' && ($this->userId === null || $this->config->getUserValue($this->userId, Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1')) { - + // Double check that atleast one provider is registered if ($this->sttProcessingManager->hasProviders()) { Util::addScript(Application::APP_ID, Application::APP_ID . '-speechToTextReference'); diff --git a/lib/Listener/SpeechToText/SpeechToTextResultListener.php b/lib/Listener/SpeechToText/SpeechToTextResultListener.php index 8b70c146..d751d2f2 100644 --- a/lib/Listener/SpeechToText/SpeechToTextResultListener.php +++ b/lib/Listener/SpeechToText/SpeechToTextResultListener.php @@ -20,11 +20,11 @@ * along with this program. If not, see . */ -namespace OCA\TpAssistant\Listener\SpeechToText; +namespace OCA\Assistant\Listener\SpeechToText; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Db\MetaTaskMapper; -use OCA\TpAssistant\Service\NotificationService; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Db\MetaTaskMapper; +use OCA\Assistant\Service\NotificationService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\SpeechToText\Events\AbstractTranscriptionEvent; diff --git a/lib/Listener/TaskFailedListener.php b/lib/Listener/TaskFailedListener.php index ba664860..019d2b92 100644 --- a/lib/Listener/TaskFailedListener.php +++ b/lib/Listener/TaskFailedListener.php @@ -1,11 +1,11 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Listener\Text2Image; +namespace OCA\Assistant\Listener\Text2Image; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\Collaboration\Reference\RenderReferenceEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; diff --git a/lib/Listener/Text2Image/Text2ImageResultListener.php b/lib/Listener/Text2Image/Text2ImageResultListener.php index 5a83ca54..aaf82cc3 100644 --- a/lib/Listener/Text2Image/Text2ImageResultListener.php +++ b/lib/Listener/Text2Image/Text2ImageResultListener.php @@ -1,12 +1,12 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Reference; +namespace OCA\Assistant\Reference; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\Collaboration\Reference\ADiscoverableReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; diff --git a/lib/Reference/SpeechToTextReferenceProvider.php b/lib/Reference/SpeechToTextReferenceProvider.php index 0b49be3b..869920c6 100644 --- a/lib/Reference/SpeechToTextReferenceProvider.php +++ b/lib/Reference/SpeechToTextReferenceProvider.php @@ -20,9 +20,9 @@ * along with this program. If not, see . */ -namespace OCA\TpAssistant\Reference; +namespace OCA\Assistant\Reference; -use OCA\TpAssistant\AppInfo\Application; +use OCA\Assistant\AppInfo\Application; use OCP\Collaboration\Reference\ADiscoverableReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; diff --git a/lib/Reference/Text2ImageReferenceProvider.php b/lib/Reference/Text2ImageReferenceProvider.php index 741ecb36..b6343e98 100644 --- a/lib/Reference/Text2ImageReferenceProvider.php +++ b/lib/Reference/Text2ImageReferenceProvider.php @@ -3,11 +3,11 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Reference; +namespace OCA\Assistant\Reference; use Exception; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Db\Text2Image\ImageGenerationMapper; use OCP\Collaboration\Reference\ADiscoverableReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\IReferenceManager; diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php new file mode 100644 index 00000000..4791128e --- /dev/null +++ b/lib/ResponseDefinitions.php @@ -0,0 +1,67 @@ + + * + * @author Julien Veyssier + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Assistant; + +/** + * @psalm-type AssistantTaskType = array{ + * id: string, + * name: string, + * description: string, + * } + * + * @psalm-type AssistantTask = array{ + * id: int, + * userId: string, + * inputs: array, + * output: string, + * appId: string, + * ocpTaskId: int, + * taskType: string, + * timestamp: int, + * status: int, + * category: int, + * identifier: string, + * } + * + * @psalm-type AssistantImageProcessPromptResponse = array{ + * task: AssistantTask, + * url: string, + * reference_url: string, + * image_gen_id: string, + * prompt: string, + * } + * + * @psalm-type AssistantImageGenInfo = array{ + * files?: array, + * prompt?: string, + * image_gen_id?: string, + * is_owner?: bool, + * processing?: int, + * } + */ +class ResponseDefinitions { +} diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php index d392be11..49c7199a 100644 --- a/lib/Service/AssistantService.php +++ b/lib/Service/AssistantService.php @@ -1,14 +1,15 @@ */ public function getAvailableTaskTypes(): array { // text processing and copywriter diff --git a/lib/Service/FreePrompt/FreePromptService.php b/lib/Service/FreePrompt/FreePromptService.php index 63fde301..a3e0b631 100644 --- a/lib/Service/FreePrompt/FreePromptService.php +++ b/lib/Service/FreePrompt/FreePromptService.php @@ -3,12 +3,12 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Service\FreePrompt; +namespace OCA\Assistant\Service\FreePrompt; use Exception; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Db\FreePrompt\PromptMapper; -use OCA\TpAssistant\Db\MetaTaskMapper; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Db\FreePrompt\PromptMapper; +use OCA\Assistant\Db\MetaTaskMapper; use OCP\AppFramework\Http; use OCP\DB\Exception as DBException; use OCP\IL10N; diff --git a/lib/Service/NotificationService.php b/lib/Service/NotificationService.php index cff326e4..7773d120 100644 --- a/lib/Service/NotificationService.php +++ b/lib/Service/NotificationService.php @@ -1,10 +1,10 @@ . */ -namespace OCA\TpAssistant\Service\SpeechToText; +namespace OCA\Assistant\Service\SpeechToText; use DateTime; use Exception; use InvalidArgumentException; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Db\MetaTask; -use OCA\TpAssistant\Db\MetaTaskMapper; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Db\MetaTask; +use OCA\Assistant\Db\MetaTaskMapper; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Http; diff --git a/lib/Service/Text2Image/CleanUpService.php b/lib/Service/Text2Image/CleanUpService.php index 1a47076a..23abcd4c 100644 --- a/lib/Service/Text2Image/CleanUpService.php +++ b/lib/Service/Text2Image/CleanUpService.php @@ -3,11 +3,11 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Service\Text2Image; +namespace OCA\Assistant\Service\Text2Image; use Exception; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Db\Text2Image\ImageGenerationMapper; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\IConfig; diff --git a/lib/Service/Text2Image/Text2ImageHelperService.php b/lib/Service/Text2Image/Text2ImageHelperService.php index 2985d0d7..7980dd18 100644 --- a/lib/Service/Text2Image/Text2ImageHelperService.php +++ b/lib/Service/Text2Image/Text2ImageHelperService.php @@ -3,21 +3,22 @@ // SPDX-FileCopyrightText: Sami Finnilä // SPDX-License-Identifier: AGPL-3.0-or-later -namespace OCA\TpAssistant\Service\Text2Image; +namespace OCA\Assistant\Service\Text2Image; use DateTime; use Exception as BaseException; use GdImage; -use OCA\TpAssistant\AppInfo\Application; -use OCA\TpAssistant\Db\MetaTaskMapper; -use OCA\TpAssistant\Db\Text2Image\ImageFileName; -use OCA\TpAssistant\Db\Text2Image\ImageFileNameMapper; -use OCA\TpAssistant\Db\Text2Image\ImageGenerationMapper; -use OCA\TpAssistant\Db\Text2Image\PromptMapper; -use OCA\TpAssistant\Db\Text2Image\StaleGenerationMapper; +use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\Db\MetaTaskMapper; +use OCA\Assistant\Db\Text2Image\ImageFileName; +use OCA\Assistant\Db\Text2Image\ImageFileNameMapper; +use OCA\Assistant\Db\Text2Image\ImageGenerationMapper; +use OCA\Assistant\Db\Text2Image\PromptMapper; +use OCA\Assistant\Db\Text2Image\StaleGenerationMapper; -use OCA\TpAssistant\Service\NotificationService; +use OCA\Assistant\ResponseDefinitions; +use OCA\Assistant\Service\NotificationService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Http; @@ -37,6 +38,9 @@ use Random\RandomException; use RuntimeException; +/** + * @psalm-import-type AssistantImageGenInfo from ResponseDefinitions + */ class Text2ImageHelperService { private ?ISimpleFolder $imageDataFolder = null; @@ -304,7 +308,7 @@ public function getImageDataFolder(): ISimpleFolder { * @param string $imageGenId * @param string|null $userId * @param bool $updateTimestamp - * @return array + * @return AssistantImageGenInfo * @throws BaseException */ public function getGenerationInfo(string $imageGenId, ?string $userId, bool $updateTimestamp = true): array { @@ -362,7 +366,6 @@ public function getGenerationInfo(string $imageGenId, ?string $userId, bool $upd $fileIds = []; foreach ($fileNameEntities as $fileNameEntity) { - if ($isOwner) { $fileIds[] = ['id' => $fileNameEntity->getId(), 'visible' => !$fileNameEntity->getHidden()]; } else { @@ -370,7 +373,12 @@ public function getGenerationInfo(string $imageGenId, ?string $userId, bool $upd } } - return ['files' => $fileIds, 'prompt' => $imageGeneration->getPrompt(), 'image_gen_id' => $imageGenId, 'is_owner' => $isOwner]; + return [ + 'files' => $fileIds, + 'prompt' => $imageGeneration->getPrompt(), + 'image_gen_id' => $imageGenId, + 'is_owner' => $isOwner, + ]; } /** diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index da390bf1..69c72e18 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -1,8 +1,8 @@ config->getAppValue(Application::APP_ID, 'assistant_enabled', '1') === '1'; $assistantEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'assistant_enabled', '1') === '1'; - + $textToImagePickerAvailable = $this->textToImageManager->hasProviders() && $this->config->getAppValue(Application::APP_ID, 'text_to_image_picker_enabled', '1') === '1'; $textToImagePickerEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'text_to_image_picker_enabled', '1') === '1'; @@ -45,7 +45,7 @@ public function getForm(): TemplateResponse { $speechToTextPickerAvailable = $speechToTextAvailable && $this->config->getAppValue(Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1'; $speechToTextPickerEnabled = $this->config->getUserValue($this->userId, Application::APP_ID, 'speech_to_text_picker_enabled', '1') === '1'; - + $userConfig = [ 'assistant_available' => $assistantAvailable, 'assistant_enabled' => $assistantEnabled, diff --git a/lib/Settings/PersonalSection.php b/lib/Settings/PersonalSection.php index 75d438f5..1d22d3eb 100644 --- a/lib/Settings/PersonalSection.php +++ b/lib/Settings/PersonalSection.php @@ -1,6 +1,6 @@ } */ -export async function openAssistantTextProcessingForm({ +export async function openAssistantForm({ appId, identifier = '', taskType = null, input = '', isInsideViewer = undefined, closeOnResult = false, actionButtons = undefined, useMetaTasks = false, }) { diff --git a/src/main.js b/src/main.js index 19a681cc..15f220b7 100644 --- a/src/main.js +++ b/src/main.js @@ -7,20 +7,23 @@ import { subscribe } from '@nextcloud/event-bus' import { loadState } from '@nextcloud/initial-state' /** - * - Expose OCA.TPAssistant.openTextProcessingModal to let apps use the assistant + * - Expose OCA.Assistant.openAssistantForm to let apps use the assistant * - Add a header right menu entry * - Listen to notification event */ function init() { - if (!OCA.TPAssistant) { + if (!OCA.Assistant) { /** * @namespace */ - OCA.TPAssistant = { + OCA.Assistant = { openAssistantForm, openAssistantTextProcessingForm, openAssistantTaskResult, } + // to keep backward compatibility (with apps that already integrate the assistant, like Text) + OCA.TPAssistant = OCA.Assistant + subscribe('notifications:action:execute', handleNotification) if (loadState('assistant', 'assistant-enabled')) { addAssistantMenuEntry() diff --git a/src/views/Text2Image/Text2ImageCustomPickerElement.vue b/src/views/Text2Image/Text2ImageCustomPickerElement.vue index 4214c5f8..8d476999 100644 --- a/src/views/Text2Image/Text2ImageCustomPickerElement.vue +++ b/src/views/Text2Image/Text2ImageCustomPickerElement.vue @@ -112,7 +112,7 @@ import ChevronRightIcon from 'vue-material-design-icons/ChevronRight.vue' import ChevronDownIcon from 'vue-material-design-icons/ChevronDown.vue' import axios from '@nextcloud/axios' -import { generateOcsUrl } from '@nextcloud/router' +import { generateUrl, generateOcsUrl } from '@nextcloud/router' import { showError, showMessage } from '@nextcloud/dialogs' import Text2ImageDisplay from '../../components/Text2Image/Text2ImageDisplay.vue' @@ -204,10 +204,10 @@ export default { }, 300) }, getPromptHistory() { - const url = generateOcsUrl('/apps/assistant/api/v1/i/prompt_history') + const url = generateUrl('/apps/assistant/i/prompt_history') return axios.get(url) .then((response) => { - this.prompts = response.data?.ocs?.data + this.prompts = response.data }) .catch((error) => { console.error(error) diff --git a/templates/adminSettings.php b/templates/adminSettings.php index 7bd7b0d9..e1a8f361 100644 --- a/templates/adminSettings.php +++ b/templates/adminSettings.php @@ -1,5 +1,5 @@ diff --git a/templates/imageGenerationPage.php b/templates/imageGenerationPage.php index 70392b4b..43fce71b 100644 --- a/templates/imageGenerationPage.php +++ b/templates/imageGenerationPage.php @@ -1,5 +1,5 @@ diff --git a/templates/speechToTextResultPage.php b/templates/speechToTextResultPage.php index d9af2293..54beb424 100644 --- a/templates/speechToTextResultPage.php +++ b/templates/speechToTextResultPage.php @@ -1,6 +1,6 @@ get(IAppManager::class)->loadApp(Application::APP_ID); diff --git a/tests/unit/Service/TextProcessingServiceTest.php b/tests/unit/Service/TextProcessingServiceTest.php index 7b5e3197..858c44f5 100644 --- a/tests/unit/Service/TextProcessingServiceTest.php +++ b/tests/unit/Service/TextProcessingServiceTest.php @@ -1,8 +1,8 @@