ParadoxSaveParser/ParadoxSaveParser.WebAPI/Routes/UploadSaveHandler.cs
2025-04-06 15:37:32 +05:00

60 lines
2.7 KiB
C#

using System.Linq;
using System.Net;
using ParadoxSaveParser.WebAPI.BackgroundTasks;
using ParadoxSaveParser.WebAPI.HttpHelpers;
namespace ParadoxSaveParser.WebAPI.Routes;
public class UploadSaveHandler : RouteHandlerBase
{
private readonly BackgroundJobManager _bgJobManager;
private readonly Dictionary<Game, ISearchExpression> _searchQueries;
public UploadSaveHandler(
CancellationToken cancelAllToken,
BackgroundJobManager bgJobManager,
Dictionary<Game, ISearchExpression> searchQueries)
: base(cancelAllToken)
{
_bgJobManager = bgJobManager;
_searchQueries = searchQueries;
}
public override async Task<HttpStatusCode> HandleRequest(
HttpListenerContext ctx, ContextLogger requestLogger)
{
string? contentType = ctx.Request.Headers.GetValues("Content-Type")?.FirstOrDefault();
if (contentType != "application/octet-stream")
return await ReturnHelper.ResponseError(ctx, requestLogger, _cancelAllToken,
new ErrorMessage(HttpStatusCode.BadRequest,
$"Invalid request Content-Type: '{contentType}'")
);
string saveId = Guid.NewGuid().ToString();
var metaFilePath = PathHelper.GetMetaFilePath(saveId);
if (File.Exists(metaFilePath))
return await ReturnHelper.ResponseError(ctx, requestLogger, _cancelAllToken,
new ErrorMessage(HttpStatusCode.InternalServerError,
$"Guid collision! file' {metaFilePath}' already exists.")
);
var meta = new SaveFileMetadata
{ id = saveId, game = Game.EU4, status = SaveFileProcessingStatus.Initialized };
if (!Program._saveMetadataStorage.TryAdd(saveId, meta))
return await ReturnHelper.ResponseError(ctx, requestLogger, _cancelAllToken,
new ErrorMessage(HttpStatusCode.InternalServerError,
$"Guid collision! Can't create metadata with id {saveId}")
);
meta.status = SaveFileProcessingStatus.Uploading;
var saveFilePath = PathHelper.GetSaveFilePath(meta.id);
await using var saveFile = File.OpenWrite(saveFilePath);
await using var remoteStream = ctx.Request.InputStream;
await remoteStream.CopyToAsync(saveFile, _cancelAllToken);
meta.status = SaveFileProcessingStatus.Uploaded;
_bgJobManager.StartNewParsingOperation(meta, _searchQueries[meta.game], _cancelAllToken);
dynamic responseData = new { saveId };
return await ReturnHelper.ResponseJson(ctx, requestLogger, _cancelAllToken, responseData);
}
}