You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
3.0 KiB

  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OC\Core\Controller;
  8. use InvalidArgumentException;
  9. use OCP\AppFramework\Http;
  10. use OCP\AppFramework\Http\Attribute\AnonRateLimit;
  11. use OCP\AppFramework\Http\Attribute\ApiRoute;
  12. use OCP\AppFramework\Http\Attribute\PublicPage;
  13. use OCP\AppFramework\Http\Attribute\UserRateLimit;
  14. use OCP\AppFramework\Http\DataResponse;
  15. use OCP\AppFramework\OCSController;
  16. use OCP\IL10N;
  17. use OCP\IRequest;
  18. use OCP\PreConditionNotMetException;
  19. use OCP\Translation\CouldNotTranslateException;
  20. use OCP\Translation\ITranslationManager;
  21. class TranslationApiController extends OCSController {
  22. public function __construct(
  23. string $appName,
  24. IRequest $request,
  25. private ITranslationManager $translationManager,
  26. private IL10N $l10n,
  27. ) {
  28. parent::__construct($appName, $request);
  29. }
  30. /**
  31. * Get the list of supported languages
  32. *
  33. * @return DataResponse<Http::STATUS_OK, array{languages: list<array{from: string, fromLabel: string, to: string, toLabel: string}>, languageDetection: bool}, array{}>
  34. *
  35. * 200: Supported languages returned
  36. */
  37. #[PublicPage]
  38. #[ApiRoute(verb: 'GET', url: '/languages', root: '/translation')]
  39. public function languages(): DataResponse {
  40. return new DataResponse([
  41. 'languages' => array_values(array_map(fn ($lang) => $lang->jsonSerialize(), $this->translationManager->getLanguages())),
  42. 'languageDetection' => $this->translationManager->canDetectLanguage(),
  43. ]);
  44. }
  45. /**
  46. * Translate a text
  47. *
  48. * @param string $text Text to be translated
  49. * @param string|null $fromLanguage Language to translate from
  50. * @param string $toLanguage Language to translate to
  51. * @return DataResponse<Http::STATUS_OK, array{text: string, from: ?string}, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_PRECONDITION_FAILED|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string, from?: ?string}, array{}>
  52. *
  53. * 200: Translated text returned
  54. * 400: Language not detected or unable to translate
  55. * 412: Translating is not possible
  56. */
  57. #[PublicPage]
  58. #[UserRateLimit(limit: 25, period: 120)]
  59. #[AnonRateLimit(limit: 10, period: 120)]
  60. #[ApiRoute(verb: 'POST', url: '/translate', root: '/translation')]
  61. public function translate(string $text, ?string $fromLanguage, string $toLanguage): DataResponse {
  62. try {
  63. $translation = $this->translationManager->translate($text, $fromLanguage, $toLanguage);
  64. return new DataResponse([
  65. 'text' => $translation,
  66. 'from' => $fromLanguage,
  67. ]);
  68. } catch (PreConditionNotMetException) {
  69. return new DataResponse(['message' => $this->l10n->t('No translation provider available')], Http::STATUS_PRECONDITION_FAILED);
  70. } catch (InvalidArgumentException) {
  71. return new DataResponse(['message' => $this->l10n->t('Could not detect language')], Http::STATUS_BAD_REQUEST);
  72. } catch (CouldNotTranslateException $e) {
  73. return new DataResponse(['message' => $this->l10n->t('Unable to translate'), 'from' => $e->getFrom()], Http::STATUS_BAD_REQUEST);
  74. }
  75. }
  76. }