Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class Application extends App implements IBootstrap {
public const QUOTA_RULES_CACHE_PREFIX = 'quota_rules';
public const MODELS_CACHE_TTL = 60 * 30;

public const AUDIO_TO_TEXT_LANGUAGES = [['en', 'English'], ['zh', '中文'], ['de', 'Deutsch'], ['es', 'Español'], ['ru', 'Русский'], ['ko', '한국어'], ['fr', 'Français'], ['ja', '日本語'], ['pt', 'Português'], ['tr', 'Türkçe'], ['pl', 'Polski'], ['ca', 'Català'], ['nl', 'Nederlands'], ['ar', 'العربية'], ['sv', 'Svenska'], ['it', 'Italiano'], ['id', 'Bahasa Indonesia'], ['hi', 'हिन्दी'], ['fi', 'Suomi'], ['vi', 'Tiếng Việt'], ['he', 'עברית'], ['uk', 'Українська'], ['el', 'Ελληνικά'], ['ms', 'Bahasa Melayu'], ['cs', 'Česky'], ['ro', 'Română'], ['da', 'Dansk'], ['hu', 'Magyar'], ['ta', 'தமிழ்'], ['no', 'Norsk (bokmål / riksmål)'], ['th', 'ไทย / Phasa Thai'], ['ur', 'اردو'], ['hr', 'Hrvatski'], ['bg', 'Български'], ['lt', 'Lietuvių'], ['la', 'Latina'], ['mi', 'Māori'], ['ml', 'മലയാളം'], ['cy', 'Cymraeg'], ['sk', 'Slovenčina'], ['te', 'తెలుగు'], ['fa', 'فارسی'], ['lv', 'Latviešu'], ['bn', 'বাংলা'], ['sr', 'Српски'], ['az', 'Azərbaycanca / آذربايجان'], ['sl', 'Slovenščina'], ['kn', 'ಕನ್ನಡ'], ['et', 'Eesti'], ['mk', 'Македонски'], ['br', 'Brezhoneg'], ['eu', 'Euskara'], ['is', 'Íslenska'], ['hy', 'Հայերեն'], ['ne', 'नेपाली'], ['mn', 'Монгол'], ['bs', 'Bosanski'], ['kk', 'Қазақша'], ['sq', 'Shqip'], ['sw', 'Kiswahili'], ['gl', 'Galego'], ['mr', 'मराठी'], ['pa', 'ਪੰਜਾਬੀ / पंजाबी / پنجابي'], ['si', 'සිංහල'], ['km', 'ភាសាខ្មែរ'], ['sn', 'chiShona'], ['yo', 'Yorùbá'], ['so', 'Soomaaliga'], ['af', 'Afrikaans'], ['oc', 'Occitan'], ['ka', 'ქართული'], ['be', 'Беларуская'], ['tg', 'Тоҷикӣ'], ['sd', 'सिनधि'], ['gu', 'ગુજરાતી'], ['am', 'አማርኛ'], ['yi', 'ייִדיש'], ['lo', 'ລາວ / Pha xa lao'], ['uz', 'Ўзбек'], ['fo', 'Føroyskt'], ['ht', 'Krèyol ayisyen'], ['ps', 'پښتو'], ['tk', 'Туркмен / تركمن'], ['nn', 'Norsk (nynorsk)'], ['mt', 'bil-Malti'], ['sa', 'संस्कृतम्'], ['lb', 'Lëtzebuergesch'], ['my', 'Myanmasa'], ['bo', 'བོད་ཡིག / Bod skad'], ['tl', 'Tagalog'], ['mg', 'Malagasy'], ['as', 'অসমীয়া'], ['tt', 'Tatarça'], ['haw', 'ʻŌlelo Hawaiʻi'], ['ln', 'Lingála'], ['ha', 'هَوُسَ'], ['ba', 'Башҡорт'], ['jw', 'ꦧꦱꦗꦮ'], ['su', 'Basa Sunda'], ['yue', '粤语']];
public const LANGUAGE_CODES_AND_ENDONYMS = [['en', 'English'], ['zh', '中文'], ['de', 'Deutsch'], ['es', 'Español'], ['ru', 'Русский'], ['ko', '한국어'], ['fr', 'Français'], ['ja', '日本語'], ['pt', 'Português'], ['tr', 'Türkçe'], ['pl', 'Polski'], ['ca', 'Català'], ['nl', 'Nederlands'], ['ar', 'العربية'], ['sv', 'Svenska'], ['it', 'Italiano'], ['id', 'Bahasa Indonesia'], ['hi', 'हिन्दी'], ['fi', 'Suomi'], ['vi', 'Tiếng Việt'], ['he', 'עברית'], ['uk', 'Українська'], ['el', 'Ελληνικά'], ['ms', 'Bahasa Melayu'], ['cs', 'Česky'], ['ro', 'Română'], ['da', 'Dansk'], ['hu', 'Magyar'], ['ta', 'தமிழ்'], ['no', 'Norsk (bokmål / riksmål)'], ['th', 'ไทย / Phasa Thai'], ['ur', 'اردو'], ['hr', 'Hrvatski'], ['bg', 'Български'], ['lt', 'Lietuvių'], ['la', 'Latina'], ['mi', 'Māori'], ['ml', 'മലയാളം'], ['cy', 'Cymraeg'], ['sk', 'Slovenčina'], ['te', 'తెలుగు'], ['fa', 'فارسی'], ['lv', 'Latviešu'], ['bn', 'বাংলা'], ['sr', 'Српски'], ['az', 'Azərbaycanca / آذربايجان'], ['sl', 'Slovenščina'], ['kn', 'ಕನ್ನಡ'], ['et', 'Eesti'], ['mk', 'Македонски'], ['br', 'Brezhoneg'], ['eu', 'Euskara'], ['is', 'Íslenska'], ['hy', 'Հայերեն'], ['ne', 'नेपाली'], ['mn', 'Монгол'], ['bs', 'Bosanski'], ['kk', 'Қазақша'], ['sq', 'Shqip'], ['sw', 'Kiswahili'], ['gl', 'Galego'], ['mr', 'मराठी'], ['pa', 'ਪੰਜਾਬੀ / पंजाबी / پنجابي'], ['si', 'සිංහල'], ['km', 'ភាសាខ្មែរ'], ['sn', 'chiShona'], ['yo', 'Yorùbá'], ['so', 'Soomaaliga'], ['af', 'Afrikaans'], ['oc', 'Occitan'], ['ka', 'ქართული'], ['be', 'Беларуская'], ['tg', 'Тоҷикӣ'], ['sd', 'सिनधि'], ['gu', 'ગુજરાતી'], ['am', 'አማርኛ'], ['yi', 'ייִדיש'], ['lo', 'ລາວ / Pha xa lao'], ['uz', 'Ўзбек'], ['fo', 'Føroyskt'], ['ht', 'Krèyol ayisyen'], ['ps', 'پښتو'], ['tk', 'Туркмен / تركمن'], ['nn', 'Norsk (nynorsk)'], ['mt', 'bil-Malti'], ['sa', 'संस्कृतम्'], ['lb', 'Lëtzebuergesch'], ['my', 'Myanmasa'], ['bo', 'བོད་ཡིག / Bod skad'], ['tl', 'Tagalog'], ['mg', 'Malagasy'], ['as', 'অসমীয়া'], ['tt', 'Tatarça'], ['haw', 'ʻŌlelo Hawaiʻi'], ['ln', 'Lingála'], ['ha', 'هَوُسَ'], ['ba', 'Башҡорт'], ['jw', 'ꦧꦱꦗꦮ'], ['su', 'Basa Sunda'], ['yue', '粤语']];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the original L10N Service uses endonyms, I think it makes more sense to use exonyms here and have them translatable into the user's selected language, as the user may not speak the language(s) well enough to know the proper endonym.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(see #269 )


public const SERVICE_TYPE_IMAGE = 'image';
public const SERVICE_TYPE_STT = 'stt';
Expand Down
17 changes: 3 additions & 14 deletions lib/OldProcessing/Translation/TranslationProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
use OCA\OpenAi\AppInfo\Application;
use OCA\OpenAi\Service\OpenAiAPIService;
use OCA\OpenAi\Service\OpenAiSettingsService;
use OCA\OpenAi\Service\TranslateService;
use OCP\IAppConfig;
use OCP\ICacheFactory;
use OCP\L10N\IFactory;
use OCP\Translation\IDetectLanguageProvider;
use OCP\Translation\ITranslationProvider;
use OCP\Translation\LanguageTuple;
Expand All @@ -25,7 +25,6 @@
class TranslationProvider implements ITranslationProvider, IDetectLanguageProvider {
public function __construct(
private ICacheFactory $cacheFactory,
private IFactory $l10nFactory,
private OpenAiAPIService $openAiAPIService,
private LoggerInterface $logger,
private IAppConfig $appConfig,
Expand All @@ -46,8 +45,7 @@ public function getAvailableLanguages(): array {
}, $cached);
}

$coreL = $this->l10nFactory->getLanguages();
$languages = array_merge($coreL['commonLanguages'], $coreL['otherLanguages']);
$languages = TranslateService::getStaticLanguages();

$availableLanguages = [];
foreach ($languages as $sourceLanguage) {
Expand Down Expand Up @@ -89,15 +87,6 @@ public function detectLanguage(string $text): ?string {
return null;
}

private function getCoreLanguagesByCode(): array {
$coreL = $this->l10nFactory->getLanguages();
$coreLanguages = array_reduce(array_merge($coreL['commonLanguages'], $coreL['otherLanguages']), function ($carry, $val) {
$carry[$val['code']] = $val['name'];
return $carry;
});
return $coreLanguages;
}

public function translate(?string $fromLanguage, string $toLanguage, string $text): string {
$cacheKey = ($fromLanguage ?? '') . '/' . $toLanguage . '/' . md5($text);

Expand All @@ -107,7 +96,7 @@ public function translate(?string $fromLanguage, string $toLanguage, string $tex
}

try {
$coreLanguages = $this->getCoreLanguagesByCode();
$coreLanguages = TranslateService::getCoreLanguagesByCode();

$toLanguage = $coreLanguages[$toLanguage];
if ($fromLanguage !== null) {
Expand Down
33 changes: 33 additions & 0 deletions lib/Service/TranslateService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

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

namespace OCA\OpenAi\Service;

use OCA\OpenAi\AppInfo\Application;

class TranslateService {
/**
* @return array<array{code: string, name: string}>
*/
public static function getStaticLanguages(): array {
return array_map(static function (array $language): array {
return [
'code' => $language[0],
'name' => $language[1],
];
}, Application::LANGUAGE_CODES_AND_ENDONYMS);
}

/**
* @return array<string, string>
*/
public static function getCoreLanguagesByCode(): array {
return array_column(Application::LANGUAGE_CODES_AND_ENDONYMS, 1, 0);
}
}
2 changes: 1 addition & 1 deletion lib/Settings/Personal.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function getForm(): TemplateResponse {
$userConfig = $this->openAiSettingsService->getUserConfig($this->userId);
$userConfig['api_key'] = $userConfig['api_key'] === '' ? '' : 'dummyApiKey';
$userConfig['basic_password'] = $userConfig['basic_password'] === '' ? '' : 'dummyPassword';
$languages = Application::AUDIO_TO_TEXT_LANGUAGES;
$languages = Application::LANGUAGE_CODES_AND_ENDONYMS;
array_unshift($languages, ['detect_language', $this->l->t('Detect language')]);
$languages = array_map(static function (array $language) use ($userConfig) {
return [
Expand Down
2 changes: 1 addition & 1 deletion lib/TaskProcessing/AudioToTextProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function getOptionalInputShape(): array {
public function getOptionalInputShapeEnumValues(): array {
$languageEnumValues = array_map(static function (array $language) {
return new ShapeEnumValue($language[1], $language[0]);
}, Application::AUDIO_TO_TEXT_LANGUAGES);
}, Application::LANGUAGE_CODES_AND_ENDONYMS);
$detectLanguageEnumValue = new ShapeEnumValue($this->l->t('Detect language'), 'detect_language');
$defaultLanguageEnumValue = new ShapeEnumValue($this->l->t('Default'), 'default');
return ['language' => array_merge([$detectLanguageEnumValue, $defaultLanguageEnumValue], $languageEnumValues)];
Expand Down
17 changes: 3 additions & 14 deletions lib/TaskProcessing/TranslateProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
use OCA\OpenAi\Service\ChunkService;
use OCA\OpenAi\Service\OpenAiAPIService;
use OCA\OpenAi\Service\OpenAiSettingsService;
use OCA\OpenAi\Service\TranslateService;
use OCP\IAppConfig;
use OCP\ICacheFactory;
use OCP\IL10N;
use OCP\L10N\IFactory;
use OCP\TaskProcessing\EShapeType;
use OCP\TaskProcessing\Exception\ProcessingException;
use OCP\TaskProcessing\Exception\UserFacingProcessingException;
Expand Down Expand Up @@ -57,7 +57,6 @@ public function __construct(
private IAppConfig $appConfig,
private OpenAiSettingsService $openAiSettingsService,
private IL10N $l,
private IFactory $l10nFactory,
private ICacheFactory $cacheFactory,
private LoggerInterface $logger,
private ChunkService $chunkService,
Expand All @@ -82,8 +81,7 @@ public function getExpectedRuntime(): int {
}

public function getInputShapeEnumValues(): array {
$coreL = $this->l10nFactory->getLanguages();
$languages = array_merge($coreL['commonLanguages'], $coreL['otherLanguages']);
$languages = TranslateService::getStaticLanguages();
$languageEnumValues = array_map(static function (array $language) {
return new ShapeEnumValue($language['name'], $language['code']);
}, $languages);
Expand Down Expand Up @@ -143,15 +141,6 @@ public function getOptionalOutputShapeEnumValues(): array {
return [];
}

private function getCoreLanguagesByCode(): array {
$coreL = $this->l10nFactory->getLanguages();
$coreLanguages = array_reduce(array_merge($coreL['commonLanguages'], $coreL['otherLanguages']), function ($carry, $val) {
$carry[$val['code']] = $val['name'];
return $carry;
});
return $coreLanguages;
}

public function process(?string $userId, array $input, callable $reportProgress): array {
/*
foreach (range(1, 20) as $i) {
Expand Down Expand Up @@ -185,7 +174,7 @@ public function process(?string $userId, array $input, callable $reportProgress)
$increase = 1.0 / (float)count($chunks);
$progress = 0.0;
try {
$coreLanguages = $this->getCoreLanguagesByCode();
$coreLanguages = TranslateService::getCoreLanguagesByCode();

$fromLanguage = $input['origin_language'];
$toLanguage = $coreLanguages[$input['target_language']] ?? $input['target_language'];
Expand Down
1 change: 0 additions & 1 deletion tests/unit/Providers/OpenAiProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,6 @@ public function testTranslationProvider(): void {
\OCP\Server::get(IAppConfig::class),
$this->openAiSettingsService,
$this->createMock(\OCP\IL10N::class),
\OCP\Server::get(\OCP\L10N\IFactory::class),
$this->createMock(\OCP\ICacheFactory::class),
$this->createMock(\Psr\Log\LoggerInterface::class),
$this->chunkService,
Expand Down
Loading