Files
UnrealEngineUWP/Engine/Source/Programs/AutomationTool/Scripts/Localisation.Automation.cs
Peter Sauerbrei dc1d815f84 refactored the logging system for UAT/UBT to be more like UE4
we now use an enum similar to UE4 with Fatal, Error, Warning, Display, Log, Verbose, and VeryVerbose
Log will only go to the log file unless -verbose is passed on the command line
reduced some of the output from UAT to be Log only

[CL 2631062 by Peter Sauerbrei in Main branch]
2015-07-23 14:51:46 -04:00

247 lines
12 KiB
C#

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.IO;
using AutomationTool;
using UnrealBuildTool;
using OneSky;
using EpicGames.OneSkyLocalization.Config;
class Localise : BuildCommand
{
private void ExportProjectToDirectory(OneSkyService oneSkyService, ProjectGroup projectGroup, string ProjectName)
{
var project = GetProject(oneSkyService, projectGroup.Name, ProjectName);
var file = project.UploadedFiles.FirstOrDefault(f => f.Filename == (ProjectName + ".po"));
//Export
if (file != null)
{
ExportFileToDirectory(file, new DirectoryInfo(CmdEnv.LocalRoot + "/Engine/Content/Localization/" + ProjectName), project.EnabledCultures);
}
}
private int OneSkyDownloadedPOChangeList = 0;
public override void ExecuteBuild()
{
var EditorExe = CombinePaths(CmdEnv.LocalRoot, @"Engine/Binaries/Win64/UE4Editor-Cmd.exe");
if (P4Enabled)
{
LogConsole("Sync necessary content to head revision");
P4.Sync(P4Env.BuildRootP4 + "/Engine/Config/...");
P4.Sync(P4Env.BuildRootP4 + "/Engine/Content/...");
P4.Sync(P4Env.BuildRootP4 + "/Engine/Source/...");
LogConsole("Localize from label {0}", P4Env.LabelToSync);
}
OneSkyConfigData OneSkyConfig = OneSkyConfigHelper.Find("OneSkyConfig_EpicGames");
var oneSkyService = new OneSkyService(OneSkyConfig.ApiKey, OneSkyConfig.ApiSecret);
var projectGroup = GetProjectGroup(oneSkyService, "Unreal Engine");
// Create changelist for backed up POs from OneSky.
if (P4Enabled)
{
OneSkyDownloadedPOChangeList = P4.CreateChange(P4Env.Client, "OneSky downloaded PO backup.");
}
// Export all text from OneSky
ExportProjectToDirectory(oneSkyService, projectGroup, "Engine");
ExportProjectToDirectory(oneSkyService, projectGroup, "Editor");
ExportProjectToDirectory(oneSkyService, projectGroup, "EditorTutorials");
ExportProjectToDirectory(oneSkyService, projectGroup, "PropertyNames");
ExportProjectToDirectory(oneSkyService, projectGroup, "ToolTips");
ExportProjectToDirectory(oneSkyService, projectGroup, "Category");
ExportProjectToDirectory(oneSkyService, projectGroup, "Keywords");
// Submit changelist for backed up POs from OneSky.
if (P4Enabled)
{
int SubmittedChangeList;
P4.Submit(OneSkyDownloadedPOChangeList, out SubmittedChangeList);
}
// Setup editor arguments for SCC.
string EditorArguments = String.Empty;
if (P4Enabled)
{
EditorArguments = String.Format("-SCCProvider={0} -P4Port={1} -P4User={2} -P4Client={3} -P4Passwd={4}", "Perforce", P4Env.P4Port, P4Env.User, P4Env.Client, P4.GetAuthenticationToken());
}
else
{
EditorArguments = String.Format("-SCCProvider={0}", "None");
}
// Setup commandlet arguments for SCC.
string CommandletSCCArguments = String.Empty;
if (P4Enabled) { CommandletSCCArguments += (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " ") + "-EnableSCC"; }
if (!AllowSubmit) { CommandletSCCArguments += (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " ") + "-DisableSCCSubmit"; }
// Setup commandlet arguments with configurations.
var CommandletArgumentSets = new string[]
{
String.Format("-config={0}", @"./Config/Localization/Engine.ini") + (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " " + CommandletSCCArguments),
String.Format("-config={0}", @"./Config/Localization/Editor.ini") + (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " " + CommandletSCCArguments),
String.Format("-config={0}", @"./Config/Localization/EditorTutorials.ini") + (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " " + CommandletSCCArguments),
String.Format("-config={0}", @"./Config/Localization/PropertyNames.ini") + (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " " + CommandletSCCArguments),
String.Format("-config={0}", @"./Config/Localization/ToolTips.ini") + (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " " + CommandletSCCArguments),
String.Format("-config={0}", @"./Config/Localization/Category.ini") + (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " " + CommandletSCCArguments),
String.Format("-config={0}", @"./Config/Localization/Keywords.ini") + (string.IsNullOrEmpty(CommandletSCCArguments) ? "" : " " + CommandletSCCArguments),
};
// Execute commandlet for each set of arguments.
foreach (var CommandletArguments in CommandletArgumentSets)
{
LogConsole("Localization for {0} {1}", EditorArguments, CommandletArguments);
LogConsole("Running UE4Editor to generate localization data");
string Arguments = String.Format("-run=GatherText {0} {1}", EditorArguments, CommandletArguments);
var RunResult = Run(EditorExe, Arguments);
if (RunResult.ExitCode != 0)
{
throw new AutomationException("Error while executing localization commandlet '{0}'", Arguments);
}
}
// Upload all text to OneSky
UploadDirectoryToProject(GetProject(oneSkyService, "Unreal Engine", "Engine"), new DirectoryInfo(CmdEnv.LocalRoot + "/Engine/Content/Localization/Engine"), "*.po");
UploadDirectoryToProject(GetProject(oneSkyService, "Unreal Engine", "Editor"), new DirectoryInfo(CmdEnv.LocalRoot + "/Engine/Content/Localization/Editor"), "*.po");
UploadDirectoryToProject(GetProject(oneSkyService, "Unreal Engine", "EditorTutorials"), new DirectoryInfo(CmdEnv.LocalRoot + "/Engine/Content/Localization/EditorTutorials"), "*.po");
UploadDirectoryToProject(GetProject(oneSkyService, "Unreal Engine", "PropertyNames"), new DirectoryInfo(CmdEnv.LocalRoot + "/Engine/Content/Localization/PropertyNames"), "*.po");
UploadDirectoryToProject(GetProject(oneSkyService, "Unreal Engine", "ToolTips"), new DirectoryInfo(CmdEnv.LocalRoot + "/Engine/Content/Localization/ToolTips"), "*.po");
UploadDirectoryToProject(GetProject(oneSkyService, "Unreal Engine", "Category"), new DirectoryInfo(CmdEnv.LocalRoot + "/Engine/Content/Localization/Category"), "*.po");
UploadDirectoryToProject(GetProject(oneSkyService, "Unreal Engine", "Keywords"), new DirectoryInfo(CmdEnv.LocalRoot + "/Engine/Content/Localization/Keywords"), "*.po");
}
private static ProjectGroup GetProjectGroup(OneSkyService oneSkyService, string GroupName)
{
var launcherGroup = oneSkyService.ProjectGroups.FirstOrDefault(g => g.Name == GroupName);
if (launcherGroup == null)
{
launcherGroup = new ProjectGroup(GroupName, "en");
oneSkyService.ProjectGroups.Add(launcherGroup);
}
return launcherGroup;
}
private static OneSky.Project GetProject(OneSkyService oneSkyService, string GroupName, string ProjectName, string ProjectDescription = "")
{
var launcherGroup = GetProjectGroup(oneSkyService, GroupName);
OneSky.Project appProject = launcherGroup.Projects.FirstOrDefault(p => p.Name == ProjectName);
if (appProject == null)
{
ProjectType projectType = oneSkyService.ProjectTypes.First(pt => pt.Code == "website");
appProject = new OneSky.Project(ProjectName, ProjectDescription, projectType);
launcherGroup.Projects.Add(appProject);
}
return appProject;
}
private void ExportFileToDirectory(UploadedFile file, DirectoryInfo destination, IEnumerable<string> cultures)
{
foreach (var culture in cultures)
{
var cultureDirectory = new DirectoryInfo(Path.Combine(destination.FullName, culture));
if (!cultureDirectory.Exists)
{
cultureDirectory.Create();
}
using (var memoryStream = new MemoryStream())
{
var exportFile = new FileInfo(Path.Combine(cultureDirectory.FullName, file.Filename));
var exportTranslationState = file.ExportTranslation(culture, memoryStream).Result;
if (exportTranslationState == UploadedFile.ExportTranslationState.Success)
{
memoryStream.Position = 0;
using (Stream fileStream = File.OpenWrite(exportFile.FullName))
{
memoryStream.CopyTo(fileStream);
Console.WriteLine("[SUCCESS] Exporting: " + exportFile.FullName + " Locale: " + culture);
}
FileInfo exportFileCopy = new FileInfo(Path.Combine(exportFile.DirectoryName, Path.GetFileNameWithoutExtension(exportFile.Name) + "_FromOneSky" + exportFile.Extension));
// Add/check out backed up POs from OneSky.
if (P4Enabled)
{
UE4Build.AddBuildProductsToChangelist(OneSkyDownloadedPOChangeList, new List<string>() {exportFileCopy.FullName} );
}
File.Copy(exportFile.FullName, exportFileCopy.FullName, true);
}
else if (exportTranslationState == UploadedFile.ExportTranslationState.NoContent)
{
Console.WriteLine("[WARNING] Exporting: " + exportFile.FullName + " Locale: " + culture + " has no translations!");
}
else
{
Console.WriteLine("[FAILED] Exporting: " + exportFile.FullName + " Locale: " + culture);
}
}
}
}
static void UploadFilesToProjectForLocale(OneSky.Project project, string[] files, string localeName)
{
foreach (var currentFile in files)
{
using (var fileStream = File.OpenRead(currentFile))
{
// Read the BOM
var bom = new byte[3];
fileStream.Read(bom, 0, 3);
//We want to ignore the utf8 BOM
if (bom[0] != 0xef || bom[1] != 0xbb || bom[2] != 0xbf)
{
fileStream.Position = 0;
}
Console.WriteLine("Uploading: " + currentFile + " Locale: " + localeName);
var uploadedFile = project.Upload(Path.GetFileName(currentFile), fileStream, localeName).Result;
if (uploadedFile == null)
{
Console.WriteLine("[FAILED] Uploading: " + currentFile + " Locale: " + localeName);
}
else
{
Console.WriteLine("[SUCCESS] Uploading: " + currentFile + " Locale: " + localeName);
}
}
}
}
static void UploadDirectoryToProject(OneSky.Project project, DirectoryInfo directory, string fileExtension)
{
DirectoryInfo[] cultureDirectories = directory.GetDirectories("*", SearchOption.TopDirectoryOnly);
// Upload, synchronously, the base culture POs.
DirectoryInfo nativeCultureDirectory = Array.Find(cultureDirectories, d => { return string.Equals(d.Name, project.BaseCultureName, StringComparison.InvariantCultureIgnoreCase); });
if (nativeCultureDirectory != null)
{
string[] files = Directory.GetFiles(nativeCultureDirectory.FullName, fileExtension, SearchOption.AllDirectories);
UploadFilesToProjectForLocale(project, files.Where((FilePath) => { return !FilePath.Contains("_FromOneSky"); }).ToArray(), nativeCultureDirectory.Name);
}
// Upload all other POs asynchronously.
foreach (var foreignCultureDirectory in Array.FindAll(cultureDirectories, d => { return d != nativeCultureDirectory; }))
{
string[] files = Directory.GetFiles(foreignCultureDirectory.FullName, fileExtension, SearchOption.AllDirectories);
UploadFilesToProjectForLocale(project, files.Where((FilePath) => { return !FilePath.Contains("_FromOneSky");}).ToArray(), foreignCultureDirectory.Name);
}
}
}