JD2022-TU1/main/tools/modules/JD.Oasis.Module/ViewModel/ExportServiceEventsHandler.cs

247 lines
9.8 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using JD.LocalizationExport.Service.API;
using JD.LocalizationExport.Service.Model.Options;
using Microsoft.Win32;
using NUnit;
using Plume.Core.Logging;
using Plume.Perforce.Service.Api;
using Ubisoft.Perforce.Data;
namespace JD.Oasis.Module.ViewModel
{
public class ExportServiceEventsHandler : IDisposable
{
private readonly string _perforceCodeHost;
private readonly string _perforceDataHost;
private static readonly HttpClient Client = new HttpClient();
private readonly Dictionary<ExportType, ClientInfo> _perforceClientPerExportType;
private readonly ILocalizationExportService _exportService;
private readonly IPerforceService _perforceService;
private readonly ILogger _logger;
public ExportServiceEventsHandler(ILocalizationExportService exportService, IPerforceService perforceService, string dataServer, string codeServer, ILogger logger)
{
_exportService = exportService;
_perforceService = perforceService;
_logger = logger;
_perforceCodeHost = codeServer;
_perforceDataHost = dataServer;
_perforceClientPerExportType = new Dictionary<ExportType, ClientInfo>();
_exportService.ExportEvents.ExportStarted += ExportServiceEvents_ExportStarted;
_exportService.ExportEvents.ExportEnded += ExportServiceEvents_ExportEnded;
_exportService.ExportEvents.ExportFileStarted += ExportServiceEvents_ExportFileStarted;
_exportService.ExportEvents.ExportFileEnded += ExportServiceEvents_ExportFileEnded;
}
public string ConsoleChangelistName { get; } = "[UI][Update] Update of console localizations";
public string MCAChangelistName { get; } = "[UI][Update] Update of phone localizations";
#region Cleanup
public void Dispose()
{
_exportService.ExportEvents.ExportStarted -= ExportServiceEvents_ExportStarted;
_exportService.ExportEvents.ExportEnded -= ExportServiceEvents_ExportEnded;
_exportService.ExportEvents.ExportFileStarted -= ExportServiceEvents_ExportFileStarted;
_exportService.ExportEvents.ExportFileEnded -= ExportServiceEvents_ExportFileEnded;
}
#endregion
#region Public methods
public string RegisterExportTypeAndGetRootPath(ExportType exportType, ExportOptionsModel exportOptions, ExportRepositoryType repositoryType)
{
string repositoryRoot = null;
if (!string.IsNullOrEmpty(exportOptions.DestinationStream))
{
_perforceClientPerExportType[exportType] = GetClientFromStream(exportOptions.DestinationStream, repositoryType);
repositoryRoot = _perforceClientPerExportType[exportType].Root;
}
return repositoryRoot;
}
#endregion
#region Export events handlers
private Task ExportServiceEvents_ExportStarted(ExportType exportType)
{
Task returnTask = Task.CompletedTask;
bool hasFailed = false;
if (_perforceClientPerExportType.ContainsKey(exportType))
{
ClientInfo client = _perforceClientPerExportType[exportType];
ExportRepositoryType repositoryType = _exportService.ExportConfigs[exportType].RepositoryType;
string host = GetHostFromRepositoryType(repositoryType);
string userName = Environment.UserName;
string clientName = client.ClientName;
string changelistDescription = string.Empty;
switch (exportType)
{
case ExportType.Console:
changelistDescription = ConsoleChangelistName;
break;
case ExportType.MCA:
changelistDescription = MCAChangelistName;
break;
case ExportType.Online:
returnTask = Task.FromException(new ArgumentException("There shouldn't be a P4 client for the Online export type", nameof(exportType)));
hasFailed = true;
break;
default:
returnTask = Task.FromException(new ArgumentException("Unknown export type", nameof(exportType)));
hasFailed = true;
break;
}
if (!hasFailed)
{
if (_perforceService.Connect(host, userName, clientName))
{
_perforceService.CreateNewChangelist(changelistDescription);
}
else
{
returnTask = Task.FromException(new Exception($"Unable to connect on the server '{host}' with user '{userName}' on client '{clientName}'."));
}
}
}
return returnTask;
}
private Task ExportServiceEvents_ExportEnded(ExportType exportType)
{
_perforceService.Connection?.RevertChangelist(_perforceService.CurrentPendingChangelist.Change, Ubisoft.Perforce.Helper.RevertOptions.UnchangedOnly);
return Task.CompletedTask;
}
private async Task ExportServiceEvents_ExportFileStarted(ExportType exportType, string filePath, Uri requestUri = null)
{
if (requestUri == null && File.Exists(filePath) && _perforceService.Connection.IsSubmittedInDepot(filePath))
{
_perforceService.Connection.OpenForEdit(filePath, _perforceService.CurrentPendingChangelist.Change);
}
else if (requestUri != null && (requestUri.Scheme == Uri.UriSchemeHttp || requestUri.Scheme == Uri.UriSchemeHttps))
{
HttpResponseMessage response = await Client.GetAsync(requestUri);
response.EnsureSuccessStatusCode();
using (FileStream stream = File.Create(filePath))
{
await response.Content.CopyToAsync(stream);
}
}
}
private async Task ExportServiceEvents_ExportFileEnded(ExportType exportType, string filePath, Uri requestUri = null)
{
if (File.Exists(filePath))
{
if (requestUri == null)
{
List<string> changelistFilesList = _perforceService.CurrentPendingChangelist.FilesList;
string fileDepotPath = _perforceService.Connection.WhereOnDepot(filePath); // TODO: Works with new file? (new language)
if (!changelistFilesList.Contains(fileDepotPath)) // If file is not checked out, then mark it for add
{
_perforceService.Connection.OpenForAdd(filePath, _perforceService.CurrentPendingChangelist.Change);
_perforceService.Connection.MoveFileToChangelist(fileDepotPath, _perforceService.CurrentPendingChangelist.Change); // Just in case the file is already in another changelist
}
}
else if (requestUri.Scheme == Uri.UriSchemeHttp || requestUri.Scheme == Uri.UriSchemeHttps)
{
string fileName = Path.GetFileName(filePath);
string fileContent = File.ReadAllText(filePath);
_logger.Info("Uploading save to server...");
using (MultipartFormDataContent form = new MultipartFormDataContent())
{
StringContent fileContentParam = new StringContent(fileContent);
form.Add(fileContentParam, "file", fileName);
form.Add(new StringContent(Environment.UserName), "author");
HttpResponseMessage response = await Client.PostAsync(requestUri, form);
response.EnsureSuccessStatusCode();
}
_logger.Info("Save file uploaded");
}
}
}
#endregion
#region Perforce helpers
private ClientInfo GetClientFromStream(string streamName, ExportRepositoryType repositoryType)
{
string host = GetHostFromRepositoryType(repositoryType);
List<ClientInfo> clients = _perforceService.RetrieveClients(host, Environment.UserName)
.Where(client => Directory.Exists(client.Root) && client.Stream == streamName)
.ToList();
if (!clients.Any())
{
throw new Exception($"There are no workspaces on the stream '{streamName}' on your machine. Please choose another data stream for the export.");
}
ClientInfo selectedClient = clients[0];
if (clients.Count > 1)
{
_logger.Warn($"There are several workspaces for the stream '{streamName}' on your machine.");
_logger.Warn($"Selecting {selectedClient.ClientName}.");
}
return selectedClient;
}
private string GetHostFromRepositoryType(ExportRepositoryType repositoryType)
{
string host;
switch (repositoryType)
{
case ExportRepositoryType.Code:
host = _perforceCodeHost;
break;
case ExportRepositoryType.Data:
host = _perforceDataHost;
break;
default:
throw new Exception($"Unknown repository type {repositoryType}. Please fix it in {_exportService.ConfigPath}.");
}
return host;
}
#endregion
}
}