mirror of
https://github.com/nextcloud/server.git
synced 2026-02-03 20:41:22 -05:00
feat(TaskProcessingApi): Add endpoint for getting the next task
Signed-off-by: provokateurin <kate@provokateurin.de>
This commit is contained in:
parent
5aefdc399e
commit
f5ff8136ac
10 changed files with 9759 additions and 410 deletions
|
|
@ -14,21 +14,29 @@ use OCA\Core\ResponseDefinitions;
|
|||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\AnonRateLimit;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\Attribute\ExAppRequired;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\PublicPage;
|
||||
use OCP\AppFramework\Http\Attribute\UserRateLimit;
|
||||
use OCP\AppFramework\Http\DataDownloadResponse;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\GenericFileException;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\IL10N;
|
||||
use OCP\IRequest;
|
||||
use OCP\Lock\LockedException;
|
||||
use OCP\TaskProcessing\EShapeType;
|
||||
use OCP\TaskProcessing\Exception\Exception;
|
||||
use OCP\TaskProcessing\Exception\NotFoundException;
|
||||
use OCP\TaskProcessing\Exception\PreConditionNotMetException;
|
||||
use OCP\TaskProcessing\Exception\UnauthorizedException;
|
||||
use OCP\TaskProcessing\Exception\ValidationException;
|
||||
use OCP\TaskProcessing\IManager;
|
||||
use OCP\TaskProcessing\ShapeDescriptor;
|
||||
use OCP\TaskProcessing\Task;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @psalm-import-type CoreTaskProcessingTask from ResponseDefinitions
|
||||
|
|
@ -36,11 +44,11 @@ use OCP\TaskProcessing\Task;
|
|||
*/
|
||||
class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private \OCP\TaskProcessing\IManager $taskProcessingManager,
|
||||
private IL10N $l,
|
||||
private ?string $userId,
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private IManager $taskProcessingManager,
|
||||
private IL10N $l,
|
||||
private ?string $userId,
|
||||
private IRootFolder $rootFolder,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
|
|
@ -109,13 +117,13 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
return new DataResponse([
|
||||
'task' => $json,
|
||||
]);
|
||||
} catch (\OCP\TaskProcessing\Exception\PreConditionNotMetException) {
|
||||
} catch (PreConditionNotMetException) {
|
||||
return new DataResponse(['message' => $this->l->t('The given provider is not available')], Http::STATUS_PRECONDITION_FAILED);
|
||||
} catch (ValidationException $e) {
|
||||
return new DataResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
||||
} catch (UnauthorizedException $e) {
|
||||
} catch (UnauthorizedException) {
|
||||
return new DataResponse(['message' => 'User does not have access to the files mentioned in the task input'], Http::STATUS_UNAUTHORIZED);
|
||||
} catch (\OCP\TaskProcessing\Exception\Exception $e) {
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => 'Internal server error'], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -144,9 +152,9 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
return new DataResponse([
|
||||
'task' => $json,
|
||||
]);
|
||||
} catch (\OCP\TaskProcessing\Exception\NotFoundException $e) {
|
||||
} catch (NotFoundException) {
|
||||
return new DataResponse(['message' => $this->l->t('Task not found')], Http::STATUS_NOT_FOUND);
|
||||
} catch (\RuntimeException $e) {
|
||||
} catch (RuntimeException) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -169,9 +177,9 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
$this->taskProcessingManager->deleteTask($task);
|
||||
|
||||
return new DataResponse(null);
|
||||
} catch (\OCP\TaskProcessing\Exception\NotFoundException $e) {
|
||||
} catch (NotFoundException) {
|
||||
return new DataResponse(null);
|
||||
} catch (\OCP\TaskProcessing\Exception\Exception $e) {
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -199,7 +207,7 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
return new DataResponse([
|
||||
'tasks' => $json,
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -226,7 +234,7 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
return new DataResponse([
|
||||
'tasks' => $json,
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -247,37 +255,72 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
public function getFileContents(int $taskId, int $fileId): Http\DataDownloadResponse|DataResponse {
|
||||
try {
|
||||
$task = $this->taskProcessingManager->getUserTask($taskId, $this->userId);
|
||||
$ids = $this->extractFileIdsFromTask($task);
|
||||
if (!in_array($fileId, $ids)) {
|
||||
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
$node = $this->rootFolder->getFirstNodeById($fileId);
|
||||
if ($node === null) {
|
||||
$node = $this->rootFolder->getFirstNodeByIdInPath($fileId, '/' . $this->rootFolder->getAppDataDirectoryName() . '/');
|
||||
if (!$node instanceof File) {
|
||||
throw new \OCP\TaskProcessing\Exception\NotFoundException('Node is not a file');
|
||||
}
|
||||
} elseif (!$node instanceof File) {
|
||||
throw new \OCP\TaskProcessing\Exception\NotFoundException('Node is not a file');
|
||||
}
|
||||
return new Http\DataDownloadResponse($node->getContent(), $node->getName(), $node->getMimeType());
|
||||
} catch (\OCP\TaskProcessing\Exception\NotFoundException $e) {
|
||||
return $this->getFileContentsInternal($task, $fileId);
|
||||
} catch (NotFoundException) {
|
||||
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
|
||||
} catch (Exception $e) {
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of a file referenced in a task(ExApp route version)
|
||||
*
|
||||
* @param int $taskId The id of the task
|
||||
* @param int $fileId The file id of the file to retrieve
|
||||
* @return DataDownloadResponse<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
|
||||
*
|
||||
* 200: File content returned
|
||||
* 404: Task or file not found
|
||||
*/
|
||||
#[ExAppRequired]
|
||||
#[ApiRoute(verb: 'GET', url: '/tasks_provider/{taskId}/file/{fileId}', root: '/taskprocessing')]
|
||||
public function getFileContentsExApp(int $taskId, int $fileId): Http\DataDownloadResponse|DataResponse {
|
||||
try {
|
||||
$task = $this->taskProcessingManager->getTask($taskId);
|
||||
return $this->getFileContentsInternal($task, $fileId);
|
||||
} catch (NotFoundException) {
|
||||
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotPermittedException
|
||||
* @throws NotFoundException
|
||||
* @throws GenericFileException
|
||||
* @throws LockedException
|
||||
*
|
||||
* @return DataDownloadResponse<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
|
||||
*/
|
||||
private function getFileContentsInternal(Task $task, int $fileId): Http\DataDownloadResponse|DataResponse {
|
||||
$ids = $this->extractFileIdsFromTask($task);
|
||||
if (!in_array($fileId, $ids)) {
|
||||
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
$node = $this->rootFolder->getFirstNodeById($fileId);
|
||||
if ($node === null) {
|
||||
$node = $this->rootFolder->getFirstNodeByIdInPath($fileId, '/' . $this->rootFolder->getAppDataDirectoryName() . '/');
|
||||
if (!$node instanceof File) {
|
||||
throw new NotFoundException('Node is not a file');
|
||||
}
|
||||
} elseif (!$node instanceof File) {
|
||||
throw new NotFoundException('Node is not a file');
|
||||
}
|
||||
return new Http\DataDownloadResponse($node->getContent(), $node->getName(), $node->getMimeType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Task $task
|
||||
* @return list<int>
|
||||
* @throws \OCP\TaskProcessing\Exception\NotFoundException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
private function extractFileIdsFromTask(Task $task): array {
|
||||
$ids = [];
|
||||
$taskTypes = $this->taskProcessingManager->getAvailableTaskTypes();
|
||||
if (!isset($taskTypes[$task->getTaskTypeId()])) {
|
||||
throw new \OCP\TaskProcessing\Exception\NotFoundException('Could not find task type');
|
||||
throw new NotFoundException('Could not find task type');
|
||||
}
|
||||
$taskType = $taskTypes[$task->getTaskTypeId()];
|
||||
foreach ($taskType['inputShape'] + $taskType['optionalInputShape'] as $key => $descriptor) {
|
||||
|
|
@ -317,12 +360,12 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
* 200: Progress updated successfully
|
||||
* 404: Task not found
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[ApiRoute(verb: 'POST', url: '/tasks/{taskId}/progress', root: '/taskprocessing')]
|
||||
#[ExAppRequired]
|
||||
#[ApiRoute(verb: 'POST', url: '/tasks_provider/{taskId}/progress', root: '/taskprocessing')]
|
||||
public function setProgress(int $taskId, float $progress): DataResponse {
|
||||
try {
|
||||
$this->taskProcessingManager->setTaskProgress($taskId, $progress);
|
||||
$task = $this->taskProcessingManager->getUserTask($taskId, $this->userId);
|
||||
$task = $this->taskProcessingManager->getTask($taskId);
|
||||
|
||||
/** @var CoreTaskProcessingTask $json */
|
||||
$json = $task->jsonSerialize();
|
||||
|
|
@ -330,9 +373,9 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
return new DataResponse([
|
||||
'task' => $json,
|
||||
]);
|
||||
} catch (\OCP\TaskProcessing\Exception\NotFoundException $e) {
|
||||
} catch (NotFoundException) {
|
||||
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
|
||||
} catch (Exception $e) {
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -348,15 +391,13 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
* 200: Result updated successfully
|
||||
* 404: Task not found
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[ApiRoute(verb: 'POST', url: '/tasks/{taskId}/result', root: '/taskprocessing')]
|
||||
#[ExAppRequired]
|
||||
#[ApiRoute(verb: 'POST', url: '/tasks_provider/{taskId}/result', root: '/taskprocessing')]
|
||||
public function setResult(int $taskId, ?array $output = null, ?string $errorMessage = null): DataResponse {
|
||||
try {
|
||||
// Check if the current user can access the task
|
||||
$this->taskProcessingManager->getUserTask($taskId, $this->userId);
|
||||
// set result
|
||||
$this->taskProcessingManager->setTaskResult($taskId, $errorMessage, $output);
|
||||
$task = $this->taskProcessingManager->getUserTask($taskId, $this->userId);
|
||||
$task = $this->taskProcessingManager->getTask($taskId);
|
||||
|
||||
/** @var CoreTaskProcessingTask $json */
|
||||
$json = $task->jsonSerialize();
|
||||
|
|
@ -364,9 +405,9 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
return new DataResponse([
|
||||
'task' => $json,
|
||||
]);
|
||||
} catch (\OCP\TaskProcessing\Exception\NotFoundException $e) {
|
||||
} catch (NotFoundException) {
|
||||
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
|
||||
} catch (Exception $e) {
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -396,9 +437,59 @@ class TaskProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
return new DataResponse([
|
||||
'task' => $json,
|
||||
]);
|
||||
} catch (\OCP\TaskProcessing\Exception\NotFoundException $e) {
|
||||
} catch (NotFoundException) {
|
||||
return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND);
|
||||
} catch (Exception $e) {
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next scheduled task for the taskTypeId
|
||||
*
|
||||
* @param list<string> $providerIds The ids of the providers
|
||||
* @param list<string> $taskTypeIds The ids of the task types
|
||||
* @return DataResponse<Http::STATUS_OK, array{task: CoreTaskProcessingTask, provider: array{name: string}}, array{}>|DataResponse<Http::STATUS_NO_CONTENT, null, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
|
||||
*
|
||||
* 200: Task returned
|
||||
* 204: No task found
|
||||
*/
|
||||
#[ExAppRequired]
|
||||
#[ApiRoute(verb: 'GET', url: '/tasks_provider/next', root: '/taskprocessing')]
|
||||
public function getNextScheduledTask(array $providerIds, array $taskTypeIds): DataResponse {
|
||||
try {
|
||||
// restrict $providerIds to providers that are configured as preferred for the passed task types
|
||||
$providerIds = array_values(array_intersect(array_unique(array_map(fn ($taskTypeId) => $this->taskProcessingManager->getPreferredProvider($taskTypeId)->getId(), $taskTypeIds)), $providerIds));
|
||||
// restrict $taskTypeIds to task types that can actually be run by one of the now restricted providers
|
||||
$taskTypeIds = array_values(array_filter($taskTypeIds, fn ($taskTypeId) => in_array($this->taskProcessingManager->getPreferredProvider($taskTypeId)->getId(), $providerIds, true)));
|
||||
if (count($providerIds) === 0 || count($taskTypeIds) === 0) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
$taskIdsToIgnore = [];
|
||||
while (true) {
|
||||
$task = $this->taskProcessingManager->getNextScheduledTask($taskTypeIds, $taskIdsToIgnore);
|
||||
$provider = $this->taskProcessingManager->getPreferredProvider($task->getTaskTypeId());
|
||||
if (in_array($provider->getId(), $providerIds, true)) {
|
||||
if ($this->taskProcessingManager->lockTask($task)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$taskIdsToIgnore[] = (int)$task->getId();
|
||||
}
|
||||
|
||||
/** @var CoreTaskProcessingTask $json */
|
||||
$json = $task->jsonSerialize();
|
||||
|
||||
return new DataResponse([
|
||||
'task' => $json,
|
||||
'provider' => [
|
||||
'name' => $provider->getId(),
|
||||
],
|
||||
]);
|
||||
} catch (NotFoundException) {
|
||||
return new DataResponse(null, Http::STATUS_NO_CONTENT);
|
||||
} catch (Exception) {
|
||||
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
844
core/openapi-administration.json
Normal file
844
core/openapi-administration.json
Normal file
|
|
@ -0,0 +1,844 @@
|
|||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "core-administration",
|
||||
"version": "0.0.1",
|
||||
"description": "Core functionality of Nextcloud",
|
||||
"license": {
|
||||
"name": "agpl"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"basic_auth": {
|
||||
"type": "http",
|
||||
"scheme": "basic"
|
||||
},
|
||||
"bearer_auth": {
|
||||
"type": "http",
|
||||
"scheme": "bearer"
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"Capabilities": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"core"
|
||||
],
|
||||
"properties": {
|
||||
"core": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"pollinterval",
|
||||
"webdav-root",
|
||||
"reference-api",
|
||||
"reference-regex",
|
||||
"mod-rewrite-working"
|
||||
],
|
||||
"properties": {
|
||||
"pollinterval": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"webdav-root": {
|
||||
"type": "string"
|
||||
},
|
||||
"reference-api": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"reference-regex": {
|
||||
"type": "string"
|
||||
},
|
||||
"mod-rewrite-working": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OCSMeta": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"status",
|
||||
"statuscode"
|
||||
],
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"statuscode": {
|
||||
"type": "integer"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"totalitems": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemsperpage": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PublicCapabilities": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"bruteforce"
|
||||
],
|
||||
"properties": {
|
||||
"bruteforce": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"delay",
|
||||
"allow-listed"
|
||||
],
|
||||
"properties": {
|
||||
"delay": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"allow-listed": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"TaskProcessingIO": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"TaskProcessingTask": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"lastUpdated",
|
||||
"type",
|
||||
"status",
|
||||
"userId",
|
||||
"appId",
|
||||
"input",
|
||||
"output",
|
||||
"customId",
|
||||
"completionExpectedAt",
|
||||
"progress"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"lastUpdated": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"STATUS_CANCELLED",
|
||||
"STATUS_FAILED",
|
||||
"STATUS_SUCCESSFUL",
|
||||
"STATUS_RUNNING",
|
||||
"STATUS_SCHEDULED",
|
||||
"STATUS_UNKNOWN"
|
||||
]
|
||||
},
|
||||
"userId": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"appId": {
|
||||
"type": "string"
|
||||
},
|
||||
"input": {
|
||||
"$ref": "#/components/schemas/TaskProcessingIO"
|
||||
},
|
||||
"output": {
|
||||
"$ref": "#/components/schemas/TaskProcessingIO",
|
||||
"nullable": true
|
||||
},
|
||||
"customId": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"completionExpectedAt": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"nullable": true
|
||||
},
|
||||
"progress": {
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"/ocs/v2.php/taskprocessing/tasks_provider/{taskId}/file/{fileId}": {
|
||||
"get": {
|
||||
"operationId": "task_processing_api-get-file-contents-ex-app",
|
||||
"summary": "Returns the contents of a file referenced in a task(ExApp route version)",
|
||||
"description": "This endpoint requires admin access",
|
||||
"tags": [
|
||||
"task_processing_api"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "taskId",
|
||||
"in": "path",
|
||||
"description": "The id of the task",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "fileId",
|
||||
"in": "path",
|
||||
"description": "The file id of the file to retrieve",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "File content returned",
|
||||
"content": {
|
||||
"*/*": {
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Task or file not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/taskprocessing/tasks_provider/{taskId}/progress": {
|
||||
"post": {
|
||||
"operationId": "task_processing_api-set-progress",
|
||||
"summary": "Sets the task progress",
|
||||
"description": "This endpoint requires admin access",
|
||||
"tags": [
|
||||
"task_processing_api"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "progress",
|
||||
"in": "query",
|
||||
"description": "The progress",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "taskId",
|
||||
"in": "path",
|
||||
"description": "The id of the task",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Progress updated successfully",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"task"
|
||||
],
|
||||
"properties": {
|
||||
"task": {
|
||||
"$ref": "#/components/schemas/TaskProcessingTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Task not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/taskprocessing/tasks_provider/{taskId}/result": {
|
||||
"post": {
|
||||
"operationId": "task_processing_api-set-result",
|
||||
"summary": "Sets the task result",
|
||||
"description": "This endpoint requires admin access",
|
||||
"tags": [
|
||||
"task_processing_api"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "output",
|
||||
"in": "query",
|
||||
"description": "The resulting task output",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "errorMessage",
|
||||
"in": "query",
|
||||
"description": "An error message if the task failed",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "taskId",
|
||||
"in": "path",
|
||||
"description": "The id of the task",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Result updated successfully",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"task"
|
||||
],
|
||||
"properties": {
|
||||
"task": {
|
||||
"$ref": "#/components/schemas/TaskProcessingTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Task not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/taskprocessing/tasks_provider/next": {
|
||||
"get": {
|
||||
"operationId": "task_processing_api-get-next-scheduled-task",
|
||||
"summary": "Returns the next scheduled task for the taskTypeId",
|
||||
"description": "This endpoint requires admin access",
|
||||
"tags": [
|
||||
"task_processing_api"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "providerIds[]",
|
||||
"in": "query",
|
||||
"description": "The ids of the providers",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "taskTypeIds[]",
|
||||
"in": "query",
|
||||
"description": "The ids of the task types",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Task returned",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"task",
|
||||
"provider"
|
||||
],
|
||||
"properties": {
|
||||
"task": {
|
||||
"$ref": "#/components/schemas/TaskProcessingTask"
|
||||
},
|
||||
"provider": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"204": {
|
||||
"description": "No task found"
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "avatar",
|
||||
"description": "Class AvatarController"
|
||||
},
|
||||
{
|
||||
"name": "guest_avatar",
|
||||
"description": "This controller handles guest avatar requests."
|
||||
},
|
||||
{
|
||||
"name": "ocm",
|
||||
"description": "Controller about the endpoint /ocm-provider/"
|
||||
}
|
||||
]
|
||||
}
|
||||
2
core/openapi-administration.json.license
Normal file
2
core/openapi-administration.json.license
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
8701
core/openapi-full.json
Normal file
8701
core/openapi-full.json
Normal file
File diff suppressed because it is too large
Load diff
2
core/openapi-full.json.license
Normal file
2
core/openapi-full.json.license
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
|
@ -4331,344 +4331,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/taskprocessing/tasks/{taskId}/progress": {
|
||||
"post": {
|
||||
"operationId": "task_processing_api-set-progress",
|
||||
"summary": "Sets the task progress",
|
||||
"tags": [
|
||||
"task_processing_api"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "progress",
|
||||
"in": "query",
|
||||
"description": "The progress",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "taskId",
|
||||
"in": "path",
|
||||
"description": "The id of the task",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Progress updated successfully",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"task"
|
||||
],
|
||||
"properties": {
|
||||
"task": {
|
||||
"$ref": "#/components/schemas/TaskProcessingTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Task not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/taskprocessing/tasks/{taskId}/result": {
|
||||
"post": {
|
||||
"operationId": "task_processing_api-set-result",
|
||||
"summary": "Sets the task result",
|
||||
"tags": [
|
||||
"task_processing_api"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "output",
|
||||
"in": "query",
|
||||
"description": "The resulting task output",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "errorMessage",
|
||||
"in": "query",
|
||||
"description": "An error message if the task failed",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "taskId",
|
||||
"in": "path",
|
||||
"description": "The id of the task",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Result updated successfully",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"task"
|
||||
],
|
||||
"properties": {
|
||||
"task": {
|
||||
"$ref": "#/components/schemas/TaskProcessingTask"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Task not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/taskprocessing/tasks/{taskId}/cancel": {
|
||||
"post": {
|
||||
"operationId": "task_processing_api-cancel-task",
|
||||
|
|
|
|||
|
|
@ -45,21 +45,33 @@ class TaskMapper extends QBMapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string|null $taskType
|
||||
* @param list<string> $taskTypes
|
||||
* @param list<int> $taskIdsToIgnore
|
||||
* @return Task
|
||||
* @throws DoesNotExistException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function findOldestScheduledByType(?string $taskType): Task {
|
||||
public function findOldestScheduledByType(array $taskTypes, array $taskIdsToIgnore): Task {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select(Task::$columns)
|
||||
->from($this->tableName)
|
||||
->where($qb->expr()->eq('status', $qb->createPositionalParameter(\OCP\TaskProcessing\Task::STATUS_SCHEDULED, IQueryBuilder::PARAM_INT)))
|
||||
->setMaxResults(1)
|
||||
->orderBy('last_updated', 'ASC');
|
||||
if ($taskType !== null) {
|
||||
$qb->andWhere($qb->expr()->eq('type', $qb->createPositionalParameter($taskType)));
|
||||
|
||||
if (count($taskTypes) > 0) {
|
||||
$filter = $qb->expr()->orX();
|
||||
foreach ($taskTypes as $taskType) {
|
||||
$filter->add($qb->expr()->eq('type', $qb->createPositionalParameter($taskType)));
|
||||
}
|
||||
|
||||
$qb->andWhere($filter);
|
||||
}
|
||||
|
||||
if (count($taskIdsToIgnore) > 0) {
|
||||
$qb->andWhere($qb->expr()->notIn('id', $qb->createNamedParameter($taskIdsToIgnore, IQueryBuilder::PARAM_INT_ARRAY)));
|
||||
}
|
||||
|
||||
return $this->findEntity($qb);
|
||||
}
|
||||
|
||||
|
|
@ -140,4 +152,17 @@ class TaskMapper extends QBMapper {
|
|||
$entity->setLastUpdated($this->timeFactory->now()->getTimestamp());
|
||||
return parent::update($entity);
|
||||
}
|
||||
|
||||
public function lockTask(Entity $entity): int {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->update($this->tableName)
|
||||
->set('status', $qb->createPositionalParameter(\OCP\TaskProcessing\Task::STATUS_RUNNING, IQueryBuilder::PARAM_INT))
|
||||
->where($qb->expr()->eq('id', $qb->createPositionalParameter($entity->getId(), IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->neq('status', $qb->createPositionalParameter(2, IQueryBuilder::PARAM_INT)));
|
||||
try {
|
||||
return $qb->executeStatement();
|
||||
} catch (Exception) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -420,21 +420,6 @@ class Manager implements IManager {
|
|||
return $taskTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $taskType
|
||||
* @return IProvider
|
||||
* @throws \OCP\TaskProcessing\Exception\Exception
|
||||
*/
|
||||
private function _getPreferredProvider(string $taskType) {
|
||||
$providers = $this->getProviders();
|
||||
foreach ($providers as $provider) {
|
||||
if ($provider->getTaskTypeId() === $taskType) {
|
||||
return $provider;
|
||||
}
|
||||
}
|
||||
throw new \OCP\TaskProcessing\Exception\Exception('No matching provider found');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ShapeDescriptor[] $spec
|
||||
* @param array $io
|
||||
|
|
@ -507,6 +492,16 @@ class Manager implements IManager {
|
|||
return $this->providers;
|
||||
}
|
||||
|
||||
public function getPreferredProvider(string $taskType) {
|
||||
$providers = $this->getProviders();
|
||||
foreach ($providers as $provider) {
|
||||
if ($provider->getTaskTypeId() === $taskType) {
|
||||
return $provider;
|
||||
}
|
||||
}
|
||||
throw new \OCP\TaskProcessing\Exception\Exception('No matching provider found');
|
||||
}
|
||||
|
||||
public function getAvailableTaskTypes(): array {
|
||||
if ($this->availableTaskTypes === null) {
|
||||
$taskTypes = $this->_getTaskTypes();
|
||||
|
|
@ -579,7 +574,7 @@ class Manager implements IManager {
|
|||
// remove superfluous keys and set input
|
||||
$task->setInput($this->removeSuperfluousArrayKeys($task->getInput(), $inputShape, $optionalInputShape));
|
||||
$task->setStatus(Task::STATUS_SCHEDULED);
|
||||
$provider = $this->_getPreferredProvider($task->getTaskTypeId());
|
||||
$provider = $this->getPreferredProvider($task->getTaskTypeId());
|
||||
// calculate expected completion time
|
||||
$completionExpectedAt = new \DateTime('now');
|
||||
$completionExpectedAt->add(new \DateInterval('PT'.$provider->getExpectedRuntime().'S'));
|
||||
|
|
@ -698,9 +693,9 @@ class Manager implements IManager {
|
|||
$this->dispatcher->dispatchTyped($event);
|
||||
}
|
||||
|
||||
public function getNextScheduledTask(?string $taskTypeId = null): Task {
|
||||
public function getNextScheduledTask(array $taskTypeIds = [], array $taskIdsToIgnore = []): Task {
|
||||
try {
|
||||
$taskEntity = $this->taskMapper->findOldestScheduledByType($taskTypeId);
|
||||
$taskEntity = $this->taskMapper->findOldestScheduledByType($taskTypeIds, $taskIdsToIgnore);
|
||||
return $taskEntity->toPublicTask();
|
||||
} catch (DoesNotExistException $e) {
|
||||
throw new \OCP\TaskProcessing\Exception\NotFoundException('Could not find the task', 0, $e);
|
||||
|
|
@ -866,4 +861,13 @@ class Manager implements IManager {
|
|||
$input = $this->fillInputFileData($task->getUserId(), $input, $inputShape, $optionalInputShape);
|
||||
return $input;
|
||||
}
|
||||
|
||||
public function lockTask(Task $task): bool {
|
||||
$taskEntity = \OC\TaskProcessing\Db\Task::fromPublicTask($task);
|
||||
if ($this->taskMapper->lockTask($taskEntity) === 0) {
|
||||
return false;
|
||||
}
|
||||
$task->setStatus(Task::STATUS_RUNNING);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class SynchronousBackgroundJob extends QueuedJob {
|
|||
}
|
||||
$taskType = $provider->getTaskTypeId();
|
||||
try {
|
||||
$task = $this->taskProcessingManager->getNextScheduledTask($taskType);
|
||||
$task = $this->taskProcessingManager->getNextScheduledTask([$taskType]);
|
||||
} catch (NotFoundException $e) {
|
||||
continue;
|
||||
} catch (Exception $e) {
|
||||
|
|
@ -91,7 +91,7 @@ class SynchronousBackgroundJob extends QueuedJob {
|
|||
));
|
||||
$taskTypesWithTasks = array_filter($taskTypes, function ($taskType) {
|
||||
try {
|
||||
$this->taskProcessingManager->getNextScheduledTask($taskType);
|
||||
$this->taskProcessingManager->getNextScheduledTask([$taskType]);
|
||||
return true;
|
||||
} catch (NotFoundException|Exception $e) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,14 @@ interface IManager {
|
|||
*/
|
||||
public function getProviders(): array;
|
||||
|
||||
/**
|
||||
* @param string $taskType
|
||||
* @return IProvider
|
||||
* @throws Exception
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public function getPreferredProvider(string $taskType);
|
||||
|
||||
/**
|
||||
* @return array<string,array{name: string, description: string, inputShape: ShapeDescriptor[], optionalInputShape: ShapeDescriptor[], outputShape: ShapeDescriptor[], optionalOutputShape: ShapeDescriptor[]}>
|
||||
* @since 30.0.0
|
||||
|
|
@ -101,13 +109,14 @@ interface IManager {
|
|||
public function setTaskProgress(int $id, float $progress): bool;
|
||||
|
||||
/**
|
||||
* @param string|null $taskTypeId
|
||||
* @param list<string> $taskTypeIds
|
||||
* @param list<int> $taskIdsToIgnore
|
||||
* @return Task
|
||||
* @throws Exception If the query failed
|
||||
* @throws NotFoundException If no task could not be found
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public function getNextScheduledTask(?string $taskTypeId = null): Task;
|
||||
public function getNextScheduledTask(array $taskTypeIds = [], array $taskIdsToIgnore = []): Task;
|
||||
|
||||
/**
|
||||
* @param int $id The id of the task
|
||||
|
|
@ -154,4 +163,13 @@ interface IManager {
|
|||
* @since 30.0.0
|
||||
*/
|
||||
public function prepareInputData(Task $task): array;
|
||||
|
||||
/**
|
||||
* Changes the task status to STATUS_RUNNING and, if successful, returns True.
|
||||
*
|
||||
* @param Task $task
|
||||
* @return bool
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public function lockTask(Task $task): bool;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue