using DeepL; using DeepL.Model; using FictionArchive.Service.TranslationService.Models; using FictionArchive.Service.TranslationService.Models.Enums; using Polly; using Language = FictionArchive.Common.Enums.Language; namespace FictionArchive.Service.TranslationService.Services.TranslationEngines.DeepLTranslate; public class DeepLTranslationEngine : ITranslationEngine { private readonly DeepLClient _deepLClient; private readonly ResiliencePipeline _pipeline; private readonly ILogger _logger; private const string DisplayName = "DeepL"; private const string Key = "deepl"; public DeepLTranslationEngine( DeepLClient deepLClient, ResiliencePipeline pipeline, ILogger logger) { _deepLClient = deepLClient; _pipeline = pipeline; _logger = logger; } public TranslationEngineDescriptor Descriptor => new() { DisplayName = DisplayName, Key = Key, }; public async Task GetTranslation(string body, Language from, Language to) { TextResult translationResult = await _pipeline.ExecuteAsync( async _ => await _deepLClient.TranslateTextAsync(body, GetLanguageCode(from), GetLanguageCode(to))); _logger.LogInformation( "Translated text. Usage statistics: CHARACTERS BILLED {TranslationResultBilledCharacters}", translationResult.BilledCharacters); return new TranslationResult { OriginalText = body, From = from, To = to, TranslationEngineKey = Key, BilledCharacterCount = (uint)translationResult.BilledCharacters, Status = TranslationRequestStatus.Success, TranslatedText = translationResult.Text }; } private string GetLanguageCode(Language language) { return language switch { Language.En => LanguageCode.EnglishAmerican, Language.Kr => LanguageCode.Korean, Language.Ch => LanguageCode.Chinese, Language.Ja => LanguageCode.Japanese, _ => throw new ArgumentOutOfRangeException(nameof(language), language, null) }; } }