From 8f1c30664937d56148ba5cdf9faacbe64f1403d1 Mon Sep 17 00:00:00 2001 From: Emanuel Albu Date: Fri, 25 Oct 2024 17:51:59 +0300 Subject: [PATCH] Add Sample for pretranslating with MS TP --- .../App.config | 6 + .../LC/AuthenticationRequestModel.cs | 15 ++ .../LC/AuthenticationResponseModel.cs | 20 ++ .../LC/LCService.cs | 100 ++++++++++ .../Program.cs | 188 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 ++++ ...teUsingMicrosoftTranslationProvider.csproj | 55 +++++ ...slateUsingMicrosoftTranslationProvider.sln | 25 +++ 8 files changed, 445 insertions(+) create mode 100644 Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/App.config create mode 100644 Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/AuthenticationRequestModel.cs create mode 100644 Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/AuthenticationResponseModel.cs create mode 100644 Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/LCService.cs create mode 100644 Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/Program.cs create mode 100644 Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/Properties/AssemblyInfo.cs create mode 100644 Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.csproj create mode 100644 Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.sln diff --git a/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/App.config b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/App.config new file mode 100644 index 0000000000..4bfa005618 --- /dev/null +++ b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/AuthenticationRequestModel.cs b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/AuthenticationRequestModel.cs new file mode 100644 index 0000000000..16fe5fac88 --- /dev/null +++ b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/AuthenticationRequestModel.cs @@ -0,0 +1,15 @@ +namespace StandAloneConsoleApp_PretranslateUsingProvider.LC +{ + public class AuthenticationRequestModel + { + public string Audience { get; set; } + + public string GrantType { get; set; } + + public string ClientSecret { get; set; } + + public string ClientId { get; set; } + + public string TenantId { get; set; } + } +} diff --git a/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/AuthenticationResponseModel.cs b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/AuthenticationResponseModel.cs new file mode 100644 index 0000000000..120c274d7a --- /dev/null +++ b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/AuthenticationResponseModel.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; + +namespace StandAloneConsoleApp_PretranslateUsingProvider.LC +{ + public class AuthenticationResponseModel + { + [JsonProperty("access_token")] + public string AccessToken { get; set; } + + [JsonProperty("expires_in")] + public int ExpiresIn { get; set; } + + [JsonProperty("token_type")] + public string TokenType { get; set; } + } +} diff --git a/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/LCService.cs b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/LCService.cs new file mode 100644 index 0000000000..e770a4538f --- /dev/null +++ b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/LC/LCService.cs @@ -0,0 +1,100 @@ +using Newtonsoft.Json; +using Sdl.LanguageCloud.IdentityApi; +using System.Collections.Generic; +using System; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using System.Xml.XPath; + +namespace StandAloneConsoleApp_PretranslateUsingProvider.LC +{ + internal class LCService + { + + public bool LoginToLC() + { + // Populate the `ClientId`, `ClientSecret`, and `TenantId` fields with actual values. + // These can be retrieved from the Language Cloud web interface: + // + // Navigate to: Users -> Integrations -> Applications -> + // Select an application with API access -> API Access tab. + // Copy the `ClientId` and `ClientSecret` from the selected application. + // + // For the TenantID, navigate to: Users -> Manage Account. + // Copy the 'Trados Account ID' from the web UI. + var result = LoginAsync(new AuthenticationRequestModel() + { + ClientId = "", // Paste the actual ClientId + ClientSecret = "", // Paste the actual ClientSecret + Audience = "https://api.sdl.com", // Do not change the value + GrantType = "client_credentials", // Do not change the value + TenantId = "" // Paste the actual TenantID + }); + + return result.Result; + } + + private async Task LoginAsync(AuthenticationRequestModel model) + { + var lcInstance = LanguageCloudIdentityApi.Instance; + + var authData = await GetAuthToken(model); + var loginData = new LoginData + { + AccessToken = authData.AccessToken, + TenantId = model.TenantId + }; + + return lcInstance.LoginWithToken(loginData); + } + + private async Task GetAuthToken(AuthenticationRequestModel model) + { + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Post, "https://sdl-prod.eu.auth0.com/oauth/token"); + + // Prepare form data as KeyValuePairs for the request content + var collection = new List> + { + new KeyValuePair("client_id", model.ClientId), + new KeyValuePair("client_secret", model.ClientSecret), + new KeyValuePair("grant_type", model.GrantType), + new KeyValuePair("audience", model.Audience) + }; + + var content = new FormUrlEncodedContent(collection); + request.Content = content; + + try + { + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + + var jsonResponse = await response.Content.ReadAsStringAsync(); + + // Use Newtonsoft.Json to deserialize the JSON response + var authToken = JsonConvert.DeserializeObject(jsonResponse); + + Console.WriteLine($"Access Token: {authToken.AccessToken}"); + return authToken; + } + catch (HttpRequestException httpEx) + { + Console.WriteLine($"HTTP Request error: {httpEx.Message}"); + return null; // Handle as appropriate + } + catch (JsonException jsonEx) + { + Console.WriteLine($"JSON Deserialization error: {jsonEx.Message}"); + return null; // Handle as appropriate + } + catch (Exception ex) + { + Console.WriteLine($"Unexpected error: {ex.Message}"); + return null; // Handle as appropriate + } + } + } +} diff --git a/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/Program.cs b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/Program.cs new file mode 100644 index 0000000000..95e2826422 --- /dev/null +++ b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/Program.cs @@ -0,0 +1,188 @@ +using System; +using System.IO; +using Newtonsoft.Json; +using Sdl.Core.Globalization; +using Sdl.ProjectAutomation.Core; +using Sdl.ProjectAutomation.FileBased; +using Sdl.ProjectAutomation.Settings; + +namespace StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider +{ + public class Program + { + private static string GetOutputProjectDirectory(string baseFolder) + { + var dateTimeString = GetDateTimeToString(DateTime.Now); + var projectDirectory = Path.Combine(baseFolder, dateTimeString); + + if (!Directory.Exists(projectDirectory)) + { + Directory.CreateDirectory(projectDirectory); + } + + return projectDirectory; + } + + private static string GetDateTimeToString(DateTime dateTime) + { + var value = dateTime.Year + + dateTime.Month.ToString().PadLeft(2, '0') + + dateTime.Day.ToString().PadLeft(2, '0') + + "-" + + dateTime.Hour.ToString().PadLeft(2, '0') + + dateTime.Minute.ToString().PadLeft(2, '0') + + dateTime.Second.ToString().PadLeft(2, '0'); + return value; + } + + private static void Main(string[] args) + { + // Change the path with the actual directory where projects should be saved... + var projectsDirectory = @""; + + // Change the path with the actual project template path + var templatePath = @""; + + if (!Directory.Exists(projectsDirectory)) + { + Directory.CreateDirectory(projectsDirectory); + } + + var sourceLanguage = "en-US"; + var targetLanguage = "de-DE"; + + var projectDirectory = GetOutputProjectDirectory(projectsDirectory); + + var projectName = "TestProject-" + DateTime.Now.Year + "-" + DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + + DateTime.Now.Hour + "-" + DateTime.Now.Minute + "-" + DateTime.Now.Second; + + var projectInfo = new ProjectInfo + { + Name = projectName, + SourceLanguage = new Language(sourceLanguage), + TargetLanguages = new[] { new Language(targetLanguage) }, + LocalProjectFolder = projectDirectory + }; + + + var project = !string.IsNullOrEmpty(templatePath) + ? new FileBasedProject(projectInfo, new ProjectTemplateReference(templatePath)) + : new FileBasedProject(projectInfo); + + UpdateProjectProviderSettings(project); + + var tpUriString = "microsofttranslatorprovider:///"; // Paste URI here + var apiKey = ""; // Paste the API Key here + + var credentials = new + { + APIKey = apiKey, + Region = "" + }; + + if (string.IsNullOrEmpty(templatePath)) + { + var tpConfig = project.GetTranslationProviderConfiguration(); + + var tpReference = new TranslationProviderReference(new Uri(tpUriString), null, true); + var tpCascadeEntry = new TranslationProviderCascadeEntry(tpReference, true, true, false); + tpConfig.Entries.Add(tpCascadeEntry); + project.UpdateTranslationProviderConfiguration(tpConfig); + } + + project.Credentials.AddCredential(new Uri(tpUriString), JsonConvert.SerializeObject(credentials)); + + project.Save(); + + AddFilesToProject(project, @""); // Paste the source files path + + RunScanTaskFiles(project); + RunAnalyzeTaskFiles(project, targetLanguage); + RunPreTranslateFiles(project, targetLanguage); + + project.Save(); + } + + private static void AddFilesToProject(IProject project, string sourceFilesDirectory) + { + project.AddFolderWithFiles(sourceFilesDirectory, true); + + var projectFiles = project.GetSourceLanguageFiles(); + + var scanResult = project.RunAutomaticTask( + projectFiles.GetIds(), + AutomaticTaskTemplateIds.Scan + ); + + Console.WriteLine("Scan: " + scanResult.Status); + + var files = project.GetSourceLanguageFiles(); + + for (var i = 0; i < project.GetSourceLanguageFiles().Length; i++) + { + Guid[] currentFileId = { files[i].Id }; + + var currentFileName = files[i].Name; + project.SetFileRole(currentFileId, FileRole.Translatable); + } + } + + private static void RunScanTaskFiles(IProject project) + { + var sourceFiles = project.GetSourceLanguageFiles(); + var sourceFilesIds = sourceFiles.GetIds(); + + var scanTask = project.RunAutomaticTask( + sourceFiles.GetIds(), + AutomaticTaskTemplateIds.Scan); + + Console.WriteLine("RunScanTaskFiles: " + scanTask.Status); + + var convertTask = project.RunAutomaticTask( + sourceFilesIds, + AutomaticTaskTemplateIds.ConvertToTranslatableFormat); + + Console.WriteLine("RunConvertTaskFiles: " + convertTask.Status); + + var splitTask = project.RunAutomaticTask( + sourceFilesIds, + AutomaticTaskTemplateIds.CopyToTargetLanguages); + + Console.WriteLine("RunSplitTaskFiles: " + splitTask.Status); + } + + private static void RunAnalyzeTaskFiles(IProject project, string targetLanguage) + { + var targetFiles = project.GetTargetLanguageFiles(Sdl.Core.Globalization.LanguageRegistry.LanguageRegistryApi.Instance.GetLanguage(targetLanguage)); + + var task = project.RunAutomaticTask( + targetFiles.GetIds(), + AutomaticTaskTemplateIds.AnalyzeFiles + ); + + Console.WriteLine("RunAnalyzeTaskFiles: " + task.Status); + } + + private static void RunPreTranslateFiles(IProject project, string targetLanguage) + { + var targetFiles = project.GetTargetLanguageFiles(Sdl.Core.Globalization.LanguageRegistry.LanguageRegistryApi.Instance.GetLanguage(targetLanguage)); + + var task = project.RunAutomaticTask( + targetFiles.GetIds(), + AutomaticTaskTemplateIds.PreTranslateFiles); + + Console.WriteLine("RunPreTranslateFiles: " + task.Status); + } + + private static void UpdateProjectProviderSettings(FileBasedProject project) + { + var settings = project.GetSettings(); + var preTranslateSettings = settings.GetSettingsGroup(); + preTranslateSettings.NoTranslationMemoryMatchFoundAction.Value = NoTranslationMemoryMatchFoundAction.ApplyAutomatedTranslation; + preTranslateSettings.MinimumMatchScore.Value = 75; + + project.UpdateSettings(settings); + project.Save(); + } + } +} \ No newline at end of file diff --git a/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/Properties/AssemblyInfo.cs b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..56740336d3 --- /dev/null +++ b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("StandAloneConsoleApp_PretranslateUsingProvider")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("StandAloneConsoleApp_PretranslateUsingProvider")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fdb17e01-04fa-4821-bb12-c38a271133ef")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.csproj b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.csproj new file mode 100644 index 0000000000..ac2c72b212 --- /dev/null +++ b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.csproj @@ -0,0 +1,55 @@ + + + net48 + false + true + ..\..\SdlCommunity.snk + false + true + true + C:\Code\SDL\Trados\Bin\Mixed Platforms\Debug + Exe + $(TradosFolder)\ + x86 + + + + $(TradosFolder)\Sdl.Core.Globalization.dll + + + $(TradosFolder)\Sdl.Core.Globalization.Async.dll + + + $(TradosFolder)\Sdl.Core.Settings.dll + + + $(TradosFolder)\Sdl.LanguagePlatform.TranslationMemoryApi.dll + + + $(TradosFolder)\Sdl.ProjectAutomation.Core.dll + + + $(TradosFolder)\Sdl.ProjectAutomation.FileBased.dll + + + $(TradosFolder)\Sdl.ProjectAutomation.Settings.dll + + + $(TradosFolder)\Sdl.LanguageCloud.IdentityApi.dll + + + $(TradosFolder)\Newtonsoft.Json.dll + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.sln b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.sln new file mode 100644 index 0000000000..f5d057f025 --- /dev/null +++ b/Code samples/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider/StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35327.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider", "StandAloneConsoleApp_PretranslateUsingMicrosoftTranslationProvider.csproj", "{FDB17E01-04FA-4821-BB12-C38A271133EF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FDB17E01-04FA-4821-BB12-C38A271133EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FDB17E01-04FA-4821-BB12-C38A271133EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FDB17E01-04FA-4821-BB12-C38A271133EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FDB17E01-04FA-4821-BB12-C38A271133EF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {515BD5EB-98CA-48B1-9784-0EC7E867C5D2} + EndGlobalSection +EndGlobal