| Scheduled TMX Imports |
Like file-based TMs, you can import *.tmx documents into server-based TMs (see Importing a TMX File). However, in contrast to file TMs, you need to consider the following: If a large *.tmx file needs to be imported over a WAN connection, there is a risk that the Internet connection breaks down, thus failing the import. It is therefore preferable to upload the import file to the server, and then schedule the import to take place once the file has been fully uploaded, so that the import can take place locally on the server, and not through an Internet connection. In this chapter you will learn how to upload a *.tmx file for a scheduled import.
Start by adding a class called ServerImporter to your project. Then implement a public function called ImportTmx, which takes a TM Server object, the organization and TM name, and the file name and path of the import file as parameters.
First, open the server TM into which the TMX content should be imported by creating a server TM object. You do this applying the GetTranslationMemory method to the TM Server and provide the organization name and the TM name as string parameters. Note that selecting a server TM requires the full TM path name including the organization, e.g. /Organization Name/TM Name.
ServerBasedTranslationMemory tm = tmServer.GetTranslationMemory(
orgName + tmName, TranslationMemoryProperties.All);Next, create an object for the scheduled TMX import. The language direction of the TMX import file must, of course, match the language direction of the target TM. If you try to import, for example, an English-French TMX file into a server TM that does not offer this language pair, the import cannot work. When creating the object for the scheduled import you need to provide the language direction object.
ScheduledTranslationMemoryImportOperation importer = new ScheduledTranslationMemoryImportOperation( this.GetLanguageDirection(tm, CultureInfo.GetCultureInfo("en-US"), CultureInfo.GetCultureInfo("de-DE")));
private ServerBasedTranslationMemoryLanguageDirection GetLanguageDirection(ServerBasedTranslationMemory tm, CultureInfo source, CultureInfo target) { foreach (ServerBasedTranslationMemoryLanguageDirection item in tm.LanguageDirections) { if (item.SourceLanguage == source && item.TargetLanguage == target) { return item; } } throw new Exception("Requested direction doesn't exist."); }
In the next step, specify the settings to apply to the import. There are various parameters that you can configure such as the ChunkSize, which specifies the maximum amount of units that should be imported in one go. This can help to achieve a more steady, uninterrupted import process, as you limit the number of units that are read into the memory at a given time. The minimum value here is 25. Note that the default value is 50 (DefaultTranslationUnitChunkSize), the maximum value is 200 (MaxTranslationUnitChunkSize). You can also specify whether the import should continue if an error has occurred. You can set the ContinueOnError property to True if you want to prevent one faulty unit to stop the entire import. If, for example, among 10,000 units an invalid unit is encountered, this particular unit will not be imported, but the remaining (valid) units will. The most important piece of information is, of course, the import file and path, which is provided as a FileInfo object.
importer.ChunkSize = 25; importer.ContinueOnError = true; importer.Source = new FileInfo(importFilePath); this.GetImportSettings(importer.ImportSettings);
private void GetImportSettings(Sdl.LanguagePlatform.TranslationMemory.ImportSettings importSettings) { if (importSettings == null) { importSettings = new ImportSettings(); } importSettings.CheckMatchingSublanguages = true; importSettings.ExistingTUsUpdateMode = ImportSettings.TUUpdateMode.Overwrite; }
Through the settings, you may also specify whether any existing TUs should be overwritten. For example, if the TMX file contains a TU with the same source segment, but with a different translation, the TU in the TM can be overwritten by the import TU. You may also specify what should happen to any TM fields associated with a TU. Example: A TU in a TM has the field value Customer: Microsoft. The same TU exists in the TMX import file, but there the same field has the value Apple. Through the ExistingFieldsUpdateMode property you can set whether existing field values should be overwritten, left unchanged, or merged.
Now apply the Create method to the importer object. This will create an import task on the server, without actually executing the import. It just acts as a placeholder for the import that should happen after the complete file has been uploaded to the server, which is done through the Upload method.
importer.Create();
importer.Upload(this.importer_Uploaded);
importer.Queue();private void importer_Uploaded(object sender, FileTransferEventArgs e) { MessageBox.Show("Transferred - " + e.BytesTransferred.ToString() + " out of " + e.TotalBytes.ToString() + " bytes\r\n"); e.Cancel = false; }
The import task can have a number of statuses that should cause the operation to stop such as aborted, canceled, error, or completed. There are also various statuses that should cause the import operation to be refreshed such as recovering, queued, allocated, etc. Through the following while loop you can determine based on the current scheduled operation status whether to refresh or to stop the import. For example, if the status is Recovering, you apply the Refresh method to the importer object. Statuses such as CancelledOn should not cause a refresh.
bool continueWaiting = true; while (continueWaiting) { switch (importer.Status) { case ScheduledOperationStatus.Abort: case ScheduledOperationStatus.Aborted: case ScheduledOperationStatus.Cancel: case ScheduledOperationStatus.Cancelled: case ScheduledOperationStatus.Completed: case ScheduledOperationStatus.Error: continueWaiting = false; break; case ScheduledOperationStatus.Aborting: case ScheduledOperationStatus.Allocated: case ScheduledOperationStatus.Cancelling: case ScheduledOperationStatus.NotSet: case ScheduledOperationStatus.Queued: case ScheduledOperationStatus.Recovered: case ScheduledOperationStatus.Recovering: case ScheduledOperationStatus.Recovery: continueWaiting = true; importer.Refresh(); break; default: continueWaiting = false; break; } }
At the end, you should check whether the import completed successfully indeed. For this, too, you can use the ScheduledOperationStatus. If the value is Completed, you can output a success message. If the value is Error, you output an error message.
if (importer.Status == ScheduledOperationStatus.Completed) { MessageBox.Show("Import successfuly finished."); } else if (importer.Status == ScheduledOperationStatus.Error) { MessageBox.Show(importer.ErrorMessage); } else { MessageBox.Show("Import didn't finish."); }
The complete class should look as shown below:
namespace Sdl.SDK.LanguagePlatform.Samples.TmAutomation { using System; using System.Globalization; using System.IO; using System.Windows.Forms; using Sdl.LanguagePlatform.TranslationMemory; using Sdl.LanguagePlatform.TranslationMemoryApi; public class ServerImporter { public void ImportTmx(TranslationProviderServer tmServer, string orgName, string tmName, string importFilePath) { if (!orgName.StartsWith("/")) orgName = "/" + orgName; if (!orgName.EndsWith("/")) orgName += "/"; #region "OpenTm" ServerBasedTranslationMemory tm = tmServer.GetTranslationMemory( orgName + tmName, TranslationMemoryProperties.All); #endregion #region "importer" ScheduledTranslationMemoryImportOperation importer = new ScheduledTranslationMemoryImportOperation( this.GetLanguageDirection(tm, CultureInfo.GetCultureInfo("en-US"), CultureInfo.GetCultureInfo("de-DE"))); #endregion #region "params" importer.ChunkSize = 25; importer.ContinueOnError = true; importer.Source = new FileInfo(importFilePath); this.GetImportSettings(importer.ImportSettings); #endregion #region "upload" importer.Create(); importer.Upload(this.importer_Uploaded); importer.Queue(); #endregion #region "wait" bool continueWaiting = true; while (continueWaiting) { switch (importer.Status) { case ScheduledOperationStatus.Abort: case ScheduledOperationStatus.Aborted: case ScheduledOperationStatus.Cancel: case ScheduledOperationStatus.Cancelled: case ScheduledOperationStatus.Completed: case ScheduledOperationStatus.Error: continueWaiting = false; break; case ScheduledOperationStatus.Aborting: case ScheduledOperationStatus.Allocated: case ScheduledOperationStatus.Cancelling: case ScheduledOperationStatus.NotSet: case ScheduledOperationStatus.Queued: case ScheduledOperationStatus.Recovered: case ScheduledOperationStatus.Recovering: case ScheduledOperationStatus.Recovery: continueWaiting = true; importer.Refresh(); break; default: continueWaiting = false; break; } } #endregion #region "completed" if (importer.Status == ScheduledOperationStatus.Completed) { MessageBox.Show("Import successfuly finished."); } else if (importer.Status == ScheduledOperationStatus.Error) { MessageBox.Show(importer.ErrorMessage); } else { MessageBox.Show("Import didn't finish."); } #endregion } #region "settings" private void GetImportSettings(Sdl.LanguagePlatform.TranslationMemory.ImportSettings importSettings) { if (importSettings == null) { importSettings = new ImportSettings(); } importSettings.CheckMatchingSublanguages = true; importSettings.ExistingTUsUpdateMode = ImportSettings.TUUpdateMode.Overwrite; } #endregion #region "LanguageDirection" private ServerBasedTranslationMemoryLanguageDirection GetLanguageDirection(ServerBasedTranslationMemory tm, CultureInfo source, CultureInfo target) { foreach (ServerBasedTranslationMemoryLanguageDirection item in tm.LanguageDirections) { if (item.SourceLanguage == source && item.TargetLanguage == target) { return item; } } throw new Exception("Requested direction doesn't exist."); } #endregion #region "event" private void importer_Uploaded(object sender, FileTransferEventArgs e) { MessageBox.Show("Transferred - " + e.BytesTransferred.ToString() + " out of " + e.TotalBytes.ToString() + " bytes\r\n"); e.Cancel = false; } #endregion } }