59 lines
1.8 KiB
C#
59 lines
1.8 KiB
C#
using System.Text.Json;
|
|
using PlotLine.Data;
|
|
using PlotLine.Models;
|
|
|
|
namespace PlotLine.Services;
|
|
|
|
public interface IProjectExportService
|
|
{
|
|
Task<ProjectBackupResult?> ExportAsync(int projectId);
|
|
}
|
|
|
|
public sealed class ProjectExportService(IProjectBackupRepository backups, ILogger<ProjectExportService> logger) : IProjectExportService
|
|
{
|
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
|
{
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
WriteIndented = true
|
|
};
|
|
|
|
public async Task<ProjectBackupResult?> ExportAsync(int projectId)
|
|
{
|
|
var backup = await backups.GetProjectBackupAsync(projectId);
|
|
if (backup?.Project is null)
|
|
{
|
|
logger.LogWarning("Project backup export requested for missing project {ProjectID}.", projectId);
|
|
return null;
|
|
}
|
|
|
|
var json = JsonSerializer.Serialize(backup, JsonOptions);
|
|
var fileName = BuildFileName(backup.Project.ProjectName, backup.ExportedAtUtc);
|
|
|
|
logger.LogInformation("Project backup export generated for project {ProjectID} with {ByteCount} JSON bytes.", projectId, json.Length);
|
|
|
|
return new ProjectBackupResult
|
|
{
|
|
FileName = fileName,
|
|
ContentType = "application/json",
|
|
Json = json
|
|
};
|
|
}
|
|
|
|
private static string BuildFileName(string projectName, DateTime exportedAtUtc)
|
|
{
|
|
var safeTitle = new string(projectName
|
|
.Select(c => Path.GetInvalidFileNameChars().Contains(c) ? '_' : c)
|
|
.ToArray())
|
|
.Trim();
|
|
|
|
safeTitle = string.Join("_", safeTitle.Split(' ', StringSplitOptions.RemoveEmptyEntries));
|
|
|
|
if (string.IsNullOrWhiteSpace(safeTitle))
|
|
{
|
|
safeTitle = "PlotWeaver_Project";
|
|
}
|
|
|
|
return $"{safeTitle}_{exportedAtUtc:yyyy-MM-dd_HHmm}.plotweaver";
|
|
}
|
|
}
|