247 lines
9.8 KiB
C#
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
|
|
}
|
|
}
|