diff --git a/.gitignore b/.gitignore
index c25fee1..507d8b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
[Ll]og/
[Ll]ogs/
[Pp]ublish/
+data/
# IDE files
.vs/
diff --git a/ParadoxSaveParser.Lib/ParadoxSaveParser.Lib.csproj b/ParadoxSaveParser.Lib/ParadoxSaveParser.Lib.csproj
index 9c490a9..595335a 100644
--- a/ParadoxSaveParser.Lib/ParadoxSaveParser.Lib.csproj
+++ b/ParadoxSaveParser.Lib/ParadoxSaveParser.Lib.csproj
@@ -6,8 +6,4 @@
enable
-
-
-
-
diff --git a/ParadoxSaveParser.WebAPI/PathHelper.cs b/ParadoxSaveParser.WebAPI/PathHelper.cs
index ad0ccc1..e853ca3 100644
--- a/ParadoxSaveParser.WebAPI/PathHelper.cs
+++ b/ParadoxSaveParser.WebAPI/PathHelper.cs
@@ -4,9 +4,9 @@ namespace ParadoxSaveParser.WebAPI;
public static class PathHelper
{
-
public const string DATA_DIR = "data";
public static string SAVES_DIR = Path.Join(DATA_DIR, "saves");
public static string GetMetaFilePath(string save_id) => Path.Join(SAVES_DIR, save_id + ".meta.json");
public static string GetEU4SaveFilePath(string save_id) => Path.Join(SAVES_DIR, save_id + ".eu4");
+ public static string GetParsedSaveFilePath(string save_id) => Path.Join(SAVES_DIR, save_id + ".parsed.json");
}
\ No newline at end of file
diff --git a/ParadoxSaveParser.WebAPI/Program.cs b/ParadoxSaveParser.WebAPI/Program.cs
index f78f030..a30e99f 100644
--- a/ParadoxSaveParser.WebAPI/Program.cs
+++ b/ParadoxSaveParser.WebAPI/Program.cs
@@ -1,13 +1,14 @@
global using System;
+global using System.IO;
+global using System.Text.Json;
+global using System.Threading.Tasks;
+global using DTLib.Demystifier;
+global using ParadoxSaveParser.Lib;
using System.Collections.Concurrent;
-using System.IO;
using System.Linq;
-using System.Text.Json;
-using DTLib.Demystifier;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
-using ParadoxSaveParser.Lib;
namespace ParadoxSaveParser.WebAPI;
@@ -21,6 +22,8 @@ public class Program
var builder = WebApplication.CreateBuilder(args);
_app = builder.Build();
+ Directory.CreateDirectory(PathHelper.DATA_DIR);
+ Directory.CreateDirectory(PathHelper.SAVES_DIR);
foreach (var metaFilePath in Directory.GetFiles(PathHelper.SAVES_DIR, "*.meta.json", SearchOption.TopDirectoryOnly))
{
using var metaFile = File.Open(metaFilePath, FileMode.Open, FileAccess.Read);
@@ -35,40 +38,53 @@ public class Program
}
_app.UseHttpsRedirection();
- _app.MapPost("/parse/eu4", (HttpContext httpContext) =>
- {
- var remoteFile = httpContext.Request.Form.Files.FirstOrDefault();
- if(remoteFile is null || !remoteFile.FileName.EndsWith(".eu4"))
- throw new Exception($"Invalid file format: {remoteFile?.FileName}");
-
- string saveId = Guid.NewGuid().ToString();
- string metaFilePath = PathHelper.GetMetaFilePath(saveId);
- if (File.Exists(metaFilePath))
- {
- httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
- throw new Exception($"Guid collision! file {metaFilePath} already exists.");
- }
-
- var meta = new SaveFileMetadata
- {
- id = saveId,
- game = Game.EU4,
- status = SaveFileProcessingStatus.Initialized,
- };
- if (!_saveMetadataStorage.TryAdd(saveId, meta))
- {
- throw new Exception($"Guid collision! Can't create metadata with id {saveId}");
- }
-
- BeginEU4SaveParse(remoteFile, meta);
- return meta;
- });
-
+ _app.MapGet("/getSaveStatus", GetSaveStatusHandler);
+ _app.MapPost("/parseSave/eu4", ParseSaveEU4Handler);
_app.Run();
}
- private static async void BeginEU4SaveParse(IFormFile remoteFile, SaveFileMetadata meta)
+ private static async Task GetSaveStatusHandler(HttpContext httpContext)
{
+ httpContext.Request.Query.TryGetValue("id", out var ids);
+ string? id = ids.FirstOrDefault();
+ if (string.IsNullOrEmpty(id))
+ {
+ throw new BadHttpRequestException("No id provided",
+ StatusCodes.Status400BadRequest);
+ }
+
+ if (!_saveMetadataStorage.TryGetValue(id, out var meta))
+ {
+ throw new BadHttpRequestException($"Save with {id} not found",
+ StatusCodes.Status400BadRequest);
+ }
+
+ await httpContext.Response.WriteAsJsonAsync(meta);
+ }
+
+ private static async Task ParseSaveEU4Handler(HttpContext httpContext)
+ {
+ var remoteFile = httpContext.Request.Form.Files.FirstOrDefault();
+ if (remoteFile is null || !remoteFile.FileName.EndsWith(".eu4"))
+ {
+ throw new BadHttpRequestException($"Invalid file format: {remoteFile?.FileName}",
+ StatusCodes.Status400BadRequest);
+ }
+
+ string saveId = Guid.NewGuid().ToString();
+ string metaFilePath = PathHelper.GetMetaFilePath(saveId);
+ if (File.Exists(metaFilePath))
+ {
+ httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
+ throw new BadHttpRequestException($"Guid collision! file {metaFilePath} already exists.", StatusCodes.Status500InternalServerError);
+ }
+
+ var meta = new SaveFileMetadata { id = saveId, game = Game.EU4, status = SaveFileProcessingStatus.Initialized, };
+ if (!_saveMetadataStorage.TryAdd(saveId, meta))
+ {
+ throw new BadHttpRequestException($"Guid collision! Can't create metadata with id {saveId}", StatusCodes.Status500InternalServerError);
+ }
+
try
{
meta.status = SaveFileProcessingStatus.Uploading;
@@ -76,22 +92,29 @@ public class Program
await using var saveFile = File.Open(saveFilePath, FileMode.CreateNew, FileAccess.ReadWrite);
await using (var remoteStream = remoteFile.OpenReadStream())
{
+ await Task.Delay(50000);
await remoteStream.CopyToAsync(saveFile);
}
meta.status = SaveFileProcessingStatus.Parsing;
saveFile.Seek(0, SeekOrigin.Begin);
var parser = new ParserEU4(saveFile);
- //var result = parser.Parse();
+ var result = parser.Parse();
meta.status = SaveFileProcessingStatus.SavingResults;
- // save
+ string resultFilePath = PathHelper.GetParsedSaveFilePath(meta.id);
+ await using var resultFile = File.Open(resultFilePath, FileMode.CreateNew, FileAccess.Write);
+ await JsonSerializer.SerializeAsync(resultFile, result);
meta.status = SaveFileProcessingStatus.Done;
+ meta.SaveToFile();
}
catch (Exception ex)
{
meta.status = SaveFileProcessingStatus.Error;
string errorMesage = ex.ToStringDemystified();
+ meta.errorMesage = errorMesage;
_app.Logger.Log(LogLevel.Error, "EU4SaveParse Error: {errorMesage}", errorMesage);
}
+
+ await httpContext.Response.WriteAsJsonAsync(meta);
}
}
\ No newline at end of file
diff --git a/ParadoxSaveParser.WebAPI/Properties/launchSettings.json b/ParadoxSaveParser.WebAPI/Properties/launchSettings.json
index 44a68c4..360984c 100644
--- a/ParadoxSaveParser.WebAPI/Properties/launchSettings.json
+++ b/ParadoxSaveParser.WebAPI/Properties/launchSettings.json
@@ -12,8 +12,6 @@
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
- "launchBrowser": true,
- "launchUrl": "/",
"applicationUrl": "http://localhost:5226",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@@ -22,8 +20,6 @@
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
- "launchBrowser": true,
- "launchUrl": "/",
"applicationUrl": "https://localhost:7032;http://localhost:5226",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@@ -31,8 +27,6 @@
},
"IIS Express": {
"commandName": "IISExpress",
- "launchBrowser": true,
- "launchUrl": "/",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
diff --git a/ParadoxSaveParser.WebAPI/SaveFileMetadata.cs b/ParadoxSaveParser.WebAPI/SaveFileMetadata.cs
index e21eb37..13a534b 100644
--- a/ParadoxSaveParser.WebAPI/SaveFileMetadata.cs
+++ b/ParadoxSaveParser.WebAPI/SaveFileMetadata.cs
@@ -1,5 +1,6 @@
using System.IO;
using System.Text.Json;
+using System.Text.Json.Serialization;
namespace ParadoxSaveParser.WebAPI;
@@ -16,9 +17,15 @@ public enum Game
public class SaveFileMetadata
{
public required string id { get; init; }
+
+ [JsonConverter(typeof(JsonStringEnumConverter))]
public required Game game { get; init; }
+
+ [JsonConverter(typeof(JsonStringEnumConverter))]
public required SaveFileProcessingStatus status { get; set; }
+
+ [JsonIgnore]
public string? errorMesage { get; set; }
private static readonly JsonSerializerOptions _jsonOptions = new() { WriteIndented = true };
diff --git a/ParadoxSaveParser.sln b/ParadoxSaveParser.sln
index 8f93e34..fbc158a 100644
--- a/ParadoxSaveParser.sln
+++ b/ParadoxSaveParser.sln
@@ -4,6 +4,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParadoxSaveParser.WebAPI",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParadoxSaveParser.Lib", "ParadoxSaveParser.Lib\ParadoxSaveParser.Lib.csproj", "{53ED0135-9513-4DE2-9187-CF2899F179B3}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionFolder", "SolutionFolder", "{F1D312F1-0620-4E35-8D78-9A2808CDE12C}"
+ ProjectSection(SolutionItems) = preProject
+ .gitignore = .gitignore
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU