Skip to content

Commit 9ace8e5

Browse files
Merge pull request #38003 from nextcloud/bugfix/noid/improve-translations-api
Improve translations api with detecting languages
2 parents 8013bc9 + 9d6ec68 commit 9ace8e5

File tree

6 files changed

+73
-12
lines changed

6 files changed

+73
-12
lines changed

core/Controller/TranslationApiController.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
use OCP\IL10N;
3333
use OCP\IRequest;
3434
use OCP\PreConditionNotMetException;
35+
use OCP\Translation\CouldNotTranslateException;
3536
use OCP\Translation\ITranslationManager;
36-
use RuntimeException;
3737

3838
class TranslationApiController extends \OCP\AppFramework\OCSController {
3939
private ITranslationManager $translationManager;
@@ -68,15 +68,19 @@ public function languages(): DataResponse {
6868
*/
6969
public function translate(string $text, ?string $fromLanguage, string $toLanguage): DataResponse {
7070
try {
71+
$translation = $this->translationManager->translate($text, $fromLanguage, $toLanguage);
72+
7173
return new DataResponse([
72-
'text' => $this->translationManager->translate($text, $fromLanguage, $toLanguage)
74+
'text' => $translation,
75+
'from' => $fromLanguage,
76+
7377
]);
7478
} catch (PreConditionNotMetException) {
7579
return new DataResponse(['message' => $this->l->t('No translation provider available')], Http::STATUS_PRECONDITION_FAILED);
7680
} catch (InvalidArgumentException) {
7781
return new DataResponse(['message' => $this->l->t('Could not detect language')], Http::STATUS_BAD_REQUEST);
78-
} catch (RuntimeException) {
79-
return new DataResponse(['message' => $this->l->t('Unable to translate')], Http::STATUS_BAD_REQUEST);
82+
} catch (CouldNotTranslateException $e) {
83+
return new DataResponse(['message' => $this->l->t('Unable to translate'), 'from' => $e->getFrom()], Http::STATUS_BAD_REQUEST);
8084
}
8185
}
8286
}

lib/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@
615615
'OCP\\Talk\\IConversationOptions' => $baseDir . '/lib/public/Talk/IConversationOptions.php',
616616
'OCP\\Talk\\ITalkBackend' => $baseDir . '/lib/public/Talk/ITalkBackend.php',
617617
'OCP\\Template' => $baseDir . '/lib/public/Template.php',
618+
'OCP\\Translation\\CouldNotTranslateException' => $baseDir . '/lib/public/Translation/CouldNotTranslateException.php',
618619
'OCP\\Translation\\IDetectLanguageProvider' => $baseDir . '/lib/public/Translation/IDetectLanguageProvider.php',
619620
'OCP\\Translation\\ITranslationManager' => $baseDir . '/lib/public/Translation/ITranslationManager.php',
620621
'OCP\\Translation\\ITranslationProvider' => $baseDir . '/lib/public/Translation/ITranslationProvider.php',

lib/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
648648
'OCP\\Talk\\IConversationOptions' => __DIR__ . '/../../..' . '/lib/public/Talk/IConversationOptions.php',
649649
'OCP\\Talk\\ITalkBackend' => __DIR__ . '/../../..' . '/lib/public/Talk/ITalkBackend.php',
650650
'OCP\\Template' => __DIR__ . '/../../..' . '/lib/public/Template.php',
651+
'OCP\\Translation\\CouldNotTranslateException' => __DIR__ . '/../../..' . '/lib/public/Translation/CouldNotTranslateException.php',
651652
'OCP\\Translation\\IDetectLanguageProvider' => __DIR__ . '/../../..' . '/lib/public/Translation/IDetectLanguageProvider.php',
652653
'OCP\\Translation\\ITranslationManager' => __DIR__ . '/../../..' . '/lib/public/Translation/ITranslationManager.php',
653654
'OCP\\Translation\\ITranslationProvider' => __DIR__ . '/../../..' . '/lib/public/Translation/ITranslationProvider.php',

lib/private/Translation/TranslationManager.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use OC\AppFramework\Bootstrap\Coordinator;
3131
use OCP\IServerContainer;
3232
use OCP\PreConditionNotMetException;
33+
use OCP\Translation\CouldNotTranslateException;
3334
use OCP\Translation\IDetectLanguageProvider;
3435
use OCP\Translation\ITranslationManager;
3536
use OCP\Translation\ITranslationProvider;
@@ -58,28 +59,36 @@ public function getLanguages(): array {
5859
return $languages;
5960
}
6061

61-
public function translate(string $text, ?string $fromLanguage, string $toLanguage): string {
62+
public function translate(string $text, ?string &$fromLanguage, string $toLanguage): string {
6263
if (!$this->hasProviders()) {
6364
throw new PreConditionNotMetException('No translation providers available');
6465
}
6566

66-
foreach ($this->getProviders() as $provider) {
67-
if ($fromLanguage === null && $provider instanceof IDetectLanguageProvider) {
68-
$fromLanguage = $provider->detectLanguage($text);
67+
if ($fromLanguage === null) {
68+
foreach ($this->getProviders() as $provider) {
69+
if ($provider instanceof IDetectLanguageProvider) {
70+
$fromLanguage = $provider->detectLanguage($text);
71+
}
72+
73+
if ($fromLanguage !== null) {
74+
break;
75+
}
6976
}
7077

7178
if ($fromLanguage === null) {
7279
throw new InvalidArgumentException('Could not detect language');
7380
}
81+
}
7482

83+
foreach ($this->getProviders() as $provider) {
7584
try {
7685
return $provider->translate($fromLanguage, $toLanguage, $text);
7786
} catch (RuntimeException $e) {
7887
$this->logger->warning("Failed to translate from {$fromLanguage} to {$toLanguage}", ['exception' => $e]);
7988
}
8089
}
8190

82-
throw new RuntimeException('Could not translate text');
91+
throw new CouldNotTranslateException($fromLanguage);
8392
}
8493

8594
public function getProviders(): array {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* @copyright Copyright (c) 2023 Joas Schilling <[email protected]>
7+
*
8+
* @author Joas Schilling <[email protected]>
9+
*
10+
* @license GNU AGPL version 3 or any later version
11+
*
12+
* This program is free software: you can redistribute it and/or modify
13+
* it under the terms of the GNU Affero General Public License as
14+
* published by the Free Software Foundation, either version 3 of the
15+
* License, or (at your option) any later version.
16+
*
17+
* This program is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU Affero General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU Affero General Public License
23+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
*/
25+
26+
namespace OCP\Translation;
27+
28+
/**
29+
* @since 27.0.0
30+
*/
31+
class CouldNotTranslateException extends \RuntimeException {
32+
/**
33+
* @since 27.0.0
34+
*/
35+
public function __construct(
36+
protected ?string $from,
37+
) {
38+
parent::__construct();
39+
}
40+
41+
/**
42+
* @since 27.0.0
43+
*/
44+
public function getFrom(): ?string {
45+
return $this->from;
46+
}
47+
}

lib/public/Translation/ITranslationManager.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
use InvalidArgumentException;
3030
use OCP\PreConditionNotMetException;
31-
use RuntimeException;
3231

3332
/**
3433
* @since 26.0.0
@@ -54,7 +53,7 @@ public function getLanguages(): array;
5453
* @since 26.0.0
5554
* @throws PreConditionNotMetException If no provider was registered but this method was still called
5655
* @throws InvalidArgumentException If no matching provider was found that can detect a language
57-
* @throws RuntimeException If the translation failed for other reasons
56+
* @throws CouldNotTranslateException If the translation failed for other reasons
5857
*/
59-
public function translate(string $text, ?string $fromLanguage, string $toLanguage): string;
58+
public function translate(string $text, ?string &$fromLanguage, string $toLanguage): string;
6059
}

0 commit comments

Comments
 (0)