aboutsummaryrefslogtreecommitdiffstats
path: root/demos/droppable
Commit message (Collapse)AuthorAgeFilesLines
* Demos:Tests: Avoid self-closing HTML tagsMichał Gołębiowski-Owczarek2023-05-101-4/+4
| | | | | | | | | Self-closing tags are reported by newer versions of the htmllint Grunt plugin. They also don't make sense in our HTML files since they are not XHTML-compliant and they run in HTML mode anyway. Ref gh-2157
* Demos: Add device-width viewport meta to all demosJörn Zaefferer2015-09-306-0/+6
| | | | Ref 343c2651729af2fdf020dd538fce0855785f5a0d
* Droppable: Style updatesAlexander Schmitz2015-08-211-8/+8
| | | | | Ref #14246 Ref gh-1588
* Droppable: Remove shopping cart demo from index it was deletedAlexander Schmitz2015-07-211-1/+0
|
* Droppable: Update demos to use AMDAlexander Schmitz2015-07-216-58/+13
| | | | Ref #10119
* Droppable: Remove core event/alias and deprecated module dependenciesAlexander Schmitz2015-05-201-1/+1
|
* Droppable: Remove shopping cart demoAlexander Schmitz2015-03-111-96/+0
| | | | This has terrible UX that we shouldn't promote anymore.
* Droppable: Add classes optionAlexander Schmitz2015-03-116-15/+33
| | | | | Ref #7053 Ref gh-1411
* Build: Reorganize external directoryScott González2014-06-247-7/+7
| | | | | | | Put each external library into its own directory. Move jquery.js to external. Ref gh-1266
* Droppable: Fix dependencies in photo manager demoScott González2014-03-101-0/+1
|
* Demos: Adding <meta name="viewport"> tag for easier mobile browsingTJ VanToll2014-03-071-0/+1
|
* All: Rename jquery.js to exclude version in filenameJörn Zaefferer2014-03-057-7/+7
|
* All: Rename all files, removing the "jquery.ui." prefix;Rafael Xavier de Souza2014-01-247-47/+47
| | | | | | | - By executing https://gist.github.com/jzaefferer/893fcf70b7eebc1dc271; Fixes #9464 Closes gh-1029
* Droppable demos: Use ui-state-default for activationScott González2014-01-152-4/+4
| | | | Closes gh-1085
* Updating jQuery to 1.10.2.Bruno M. Custódio2013-07-057-7/+7
| | | | | Adding jQuery 1.10.0, 1.10.1, 1.10.2, 2.0.0, 2.0.1, 2.0.2 and 2.0.3 to the tests directory.
* Updating 'jQuery' to 1.9.1.Bruno M. Custódio2013-02-057-7/+7
|
* Updating to jQuery 1.9.0Kris Borchers2013-01-177-7/+7
|
* Upgrade jQuery to 1.8.3.Scott González2012-11-147-7/+7
|
* Droppable demo: Removed IE6 CSS hack.Scott González2012-10-261-2/+2
|
* Cleanup demos: Copy&paste errors in titles, bad descriptions or stylingJörn Zaefferer2012-10-241-1/+1
|
* Upgrade jQuery to 1.8.2.Scott González2012-09-207-7/+7
|
* Demos: Cleanup.Scott González2012-09-108-77/+30
|
* Upgrade jQuery to 1.8.0.Scott González2012-08-137-7/+7
|
* Droppable demo: Fixed styling.Scott González2012-06-151-6/+6
|
* Upgrade jQuery to 1.7.2.Scott González2012-03-227-7/+7
|
* Upgrade jQuery to 1.7.1.Scott González2011-11-227-7/+7
|
* Upgrade jQuery to 1.7.Scott González2011-11-097-7/+7
|
* Upgraded jQuery to 1.6.4.Scott González2011-10-187-7/+7
|
* Upgrade jQuery to 1.6.2.Scott González2011-07-257-7/+7
|
* Switched to latest stable jQuery 1.5.1Richard Worth2011-03-027-7/+7
|
* Lossless compression of all non-theme images using ImageOptimPhillip Barnes2010-11-194-0/+0
|
* Upgraded jQuery to 1.4.4.Scott González2010-11-127-7/+7
|
* Upgraded jQuery to 1.4.3.Scott González2010-10-217-7/+7
|
* Droppable demos: Coding standards.Scott González2010-09-108-294/+330
|
* Added position plugin to demo pages that use dialogs.Scott González2010-07-271-0/+1
|
* Shopping-Cart demo: Add new demo to droppable demo indexunknown2010-03-301-0/+1
|
* Shopping-Cart demo: Fix demo titleunknown2010-03-301-1/+1
|
* Shopping-Cart demo: Fix the eager activeClass on sortingunknown2010-03-301-1/+6
|
* Shopping-Cart demo: fix typosunknown2010-03-301-2/+2
|
* Adding shopping cart demo for integration of accordion, draggable, droppable ↵unknown2010-03-301-0/+96
| | | | and sortable
* html pages: added HTML5 meta charset UTF-8 tag, changed DOCTYPE to uppercaseRichard Worth2010-03-127-161/+168
|
* Fixed #5182 - Update to jQuery 1.4.2Richard Worth2010-02-166-6/+6
|
* fixed #5163 - themes: css files need to be renamed to be consistent with js ↵Richard Worth2010-02-166-6/+6
| | | | file renames in 1.8a1
* switched to jQuery 1.4.1Richard Worth2010-01-276-6/+6
|
* switched to jQuery 1.4Richard Worth2010-01-206-6/+6
|
* Split mouse into its own file and udpdated dependency lists.Scott González2009-12-226-0/+6
| | | | Fixes #5023 - Split mouse code into its own file.
* extracting widget factory into jquery.ui.widget.jsJörn Zaefferer2009-12-166-0/+6
|
* renamed all ui.*.js files to jquery.ui.*.js, all effects.*.js files to ↵Richard Worth2009-09-176-20/+20
| | | | jquery.effects.*.js per announcement and discussion here http://groups.google.com/group/jquery-ui-dev/msg/d565a0c56e0cb935
* demos: droppable photo manager - fixed issue where dialog would not be ↵Richard Worth2009-03-021-9/+13
| | | | centered when image first opened.
* removed margin-left rules due to IE6 conflictScott Jehl2009-02-275-5/+5
|
75/stable30'>backport/48375/stable30 Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
aboutsummaryrefslogtreecommitdiffstats
path: root/core/Controller/TextProcessingApiController.php
blob: d3e6967f16916950f9f751514a9d3a498afd93ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<?php

declare(strict_types=1);

/**
 * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */


namespace OC\Core\Controller;

use InvalidArgumentException;
use OC\Core\ResponseDefinitions;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\AnonRateLimit;
use OCP\AppFramework\Http\Attribute\ApiRoute;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\Attribute\UserRateLimit;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\Common\Exception\NotFoundException;
use OCP\DB\Exception;
use OCP\IL10N;
use OCP\IRequest;
use OCP\PreConditionNotMetException;
use OCP\TextProcessing\Exception\TaskFailureException;
use OCP\TextProcessing\IManager;
use OCP\TextProcessing\ITaskType;
use OCP\TextProcessing\Task;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;

/**
 * @psalm-import-type CoreTextProcessingTask from ResponseDefinitions
 */
class TextProcessingApiController extends OCSController {
	public function __construct(
		string $appName,
		IRequest $request,
		private IManager $textProcessingManager,
		private IL10N $l,
		private ?string $userId,
		private ContainerInterface $container,
		private LoggerInterface $logger,
	) {
		parent::__construct($appName, $request);
	}

	/**
	 * This endpoint returns all available LanguageModel task types
	 *
	 * @return DataResponse<Http::STATUS_OK, array{types: list<array{id: string, name: string, description: string}>}, array{}>
	 *
	 * 200: Task types returned
	 */
	#[PublicPage]
	#[ApiRoute(verb: 'GET', url: '/tasktypes', root: '/textprocessing')]
	public function taskTypes(): DataResponse {
		$typeClasses = $this->textProcessingManager->getAvailableTaskTypes();
		$types = [];
		/** @var string $typeClass */
		foreach ($typeClasses as $typeClass) {
			try {
				/** @var ITaskType $object */
				$object = $this->container->get($typeClass);
			} catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
				$this->logger->warning('Could not find ' . $typeClass, ['exception' => $e]);
				continue;
			}
			$types[] = [
				'id' => $typeClass,
				'name' => $object->getName(),
				'description' => $object->getDescription(),
			];
		}

		return new DataResponse([
			'types' => $types,
		]);
	}

	/**
	 * This endpoint allows scheduling a language model task
	 *
	 * @param string $input Input text
	 * @param string $type Type of the task
	 * @param string $appId ID of the app that will execute the task
	 * @param string $identifier An arbitrary identifier for the task
	 *
	 * @return DataResponse<Http::STATUS_OK, array{task: CoreTextProcessingTask}, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_BAD_REQUEST|Http::STATUS_PRECONDITION_FAILED, array{message: string}, array{}>
	 *
	 * 200: Task scheduled successfully
	 * 400: Scheduling task is not possible
	 * 412: Scheduling task is not possible
	 */
	#[PublicPage]
	#[UserRateLimit(limit: 20, period: 120)]
	#[AnonRateLimit(limit: 5, period: 120)]
	#[ApiRoute(verb: 'POST', url: '/schedule', root: '/textprocessing')]
	public function schedule(string $input, string $type, string $appId, string $identifier = ''): DataResponse {
		try {
			$task = new Task($type, $input, $appId, $this->userId, $identifier);
		} catch (InvalidArgumentException) {
			return new DataResponse(['message' => $this->l->t('Requested task type does not exist')], Http::STATUS_BAD_REQUEST);
		}
		try {
			try {
				$this->textProcessingManager->runOrScheduleTask($task);
			} catch (TaskFailureException) {
				// noop, because the task object has the failure status set already, we just return the task json
			}

			$json = $task->jsonSerialize();

			return new DataResponse([
				'task' => $json,
			]);
		} catch (PreConditionNotMetException) {
			return new DataResponse(['message' => $this->l->t('Necessary language model provider is not available')], Http::STATUS_PRECONDITION_FAILED);
		} catch (Exception) {
			return new DataResponse(['message' => 'Internal server error'], Http::STATUS_INTERNAL_SERVER_ERROR);
		}
	}

	/**
	 * This endpoint allows checking the status and results of a task.
	 * Tasks are removed 1 week after receiving their last update.
	 *
	 * @param int $id The id of the task
	 *
	 * @return DataResponse<Http::STATUS_OK, array{task: CoreTextProcessingTask}, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
	 *
	 * 200: Task returned
	 * 404: Task not found
	 */
	#[PublicPage]
	#[ApiRoute(verb: 'GET', url: '/task/{id}', root: '/textprocessing')]
	public function getTask(int $id): DataResponse {
		try {
			$task = $this->textProcessingManager->getUserTask($id, $this->userId);

			$json = $task->jsonSerialize();

			return new DataResponse([
				'task' => $json,
			]);
		} catch (NotFoundException $e) {
			return new DataResponse(['message' => $this->l->t('Task not found')], Http::STATUS_NOT_FOUND);
		} catch (\RuntimeException $e) {
			return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
		}
	}

	/**
	 * This endpoint allows to delete a scheduled task for a user
	 *
	 * @param int $id The id of the task
	 *
	 * @return DataResponse<Http::STATUS_OK, array{task: CoreTextProcessingTask}, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
	 *
	 * 200: Task returned
	 * 404: Task not found
	 */
	#[NoAdminRequired]
	#[ApiRoute(verb: 'DELETE', url: '/task/{id}', root: '/textprocessing')]
	public function deleteTask(int $id): DataResponse {
		try {
			$task = $this->textProcessingManager->getUserTask($id, $this->userId);

			$this->textProcessingManager->deleteTask($task);

			$json = $task->jsonSerialize();

			return new DataResponse([
				'task' => $json,
			]);
		} catch (NotFoundException $e) {
			return new DataResponse(['message' => $this->l->t('Task not found')], Http::STATUS_NOT_FOUND);
		} catch (\RuntimeException $e) {
			return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
		}
	}


	/**
	 * This endpoint returns a list of tasks of a user that are related
	 * with a specific appId and optionally with an identifier
	 *
	 * @param string $appId ID of the app
	 * @param string|null $identifier An arbitrary identifier for the task
	 * @return DataResponse<Http::STATUS_OK, array{tasks: list<CoreTextProcessingTask>}, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
	 *
	 * 200: Task list returned
	 */
	#[NoAdminRequired]
	#[ApiRoute(verb: 'GET', url: '/tasks/app/{appId}', root: '/textprocessing')]
	public function listTasksByApp(string $appId, ?string $identifier = null): DataResponse {
		try {
			$tasks = $this->textProcessingManager->getUserTasksByApp($this->userId, $appId, $identifier);
			$json = array_values(array_map(static function (Task $task) {
				return $task->jsonSerialize();
			}, $tasks));

			return new DataResponse([
				'tasks' => $json,
			]);
		} catch (\RuntimeException $e) {
			return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
		}
	}
}