using System.Linq; using System.Net; using System.Reflection.Metadata; using ParadoxSaveParser.WebAPI.BackgroundTasks; using ParadoxSaveParser.WebAPI.Database; using ParadoxSaveParser.WebAPI.HttpHelpers; using ParadoxSaveParser.WebAPI.SaveDataFilters; namespace ParadoxSaveParser.WebAPI.Routes; public class UploadSaveHandler : RouteHandlerBase { private readonly BackgroundJobManager _bgJobManager; private readonly Dictionary _saveFilters; public UploadSaveHandler( CancellationToken cancelAllToken, BackgroundJobManager bgJobManager, Dictionary saveFilters) : base(cancelAllToken) { _bgJobManager = bgJobManager; _saveFilters = saveFilters; } public override async Task 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}'")); var gameStrOrError = RequestHelper.GetQueryValue(ctx, "game"); if (gameStrOrError.HasError) return await ReturnHelper.ResponseError(ctx, requestLogger, _cancelAllToken, gameStrOrError.Error!); if (!Enum.TryParse(gameStrOrError.Value, ignoreCase: true, out Game game)) return await ReturnHelper.ResponseError(ctx, requestLogger, _cancelAllToken, new ErrorMessage(HttpStatusCode.BadRequest, $"Invalid requested game: '{gameStrOrError.Value}'")); var meta = await Program.DB.CreateMetadata(game); var saveFilePath = meta.GetSaveFilePath(); await using (var saveFile = File.OpenWrite(saveFilePath)) { await using (var remoteStream = ctx.Request.InputStream) await remoteStream.CopyToAsync(saveFile, _cancelAllToken); } await Program.DB.UpdateMetadataStatus(meta, SaveFileProcessingStatus.Uploaded); _bgJobManager.StartNewParsingOperation(meta, _saveFilters[meta.game], _cancelAllToken); dynamic responseData = new { meta.id }; return await ReturnHelper.ResponseJson(ctx, requestLogger, _cancelAllToken, responseData); } }