feat: add ?save=true param to chart v2 — saves JPEG to disk (ChartSettings paths in appsettings)

This commit is contained in:
2026-05-27 18:45:39 +02:00
parent 1b4e8c2096
commit 4611f3c376
2 changed files with 52 additions and 4 deletions

View File

@@ -22,15 +22,18 @@ public class ChartController : ControllerBase
private readonly IChartDataService _chartDataService; private readonly IChartDataService _chartDataService;
private readonly IChartDataServiceV2 _chartDataServiceV2; private readonly IChartDataServiceV2 _chartDataServiceV2;
private readonly ILogger<ChartController> _logger; private readonly ILogger<ChartController> _logger;
private readonly IConfiguration _configuration;
public ChartController( public ChartController(
IChartDataService chartDataService, IChartDataService chartDataService,
IChartDataServiceV2 chartDataServiceV2, IChartDataServiceV2 chartDataServiceV2,
ILogger<ChartController> logger) ILogger<ChartController> logger,
IConfiguration configuration)
{ {
_chartDataService = chartDataService; _chartDataService = chartDataService;
_chartDataServiceV2 = chartDataServiceV2; _chartDataServiceV2 = chartDataServiceV2;
_logger = logger; _logger = logger;
_configuration = configuration;
} }
[HttpGet("{isin}")] [HttpGet("{isin}")]
@@ -91,7 +94,8 @@ public class ChartController : ControllerBase
string isin, string isin,
[FromQuery] int width = 1100, [FromQuery] int width = 1100,
[FromQuery] int height = 700, [FromQuery] int height = 700,
[FromQuery] string format = "png") [FromQuery] string format = "png",
[FromQuery] bool save = false)
{ {
if (string.IsNullOrWhiteSpace(isin)) if (string.IsNullOrWhiteSpace(isin))
return BadRequest("ISIN non valido."); return BadRequest("ISIN non valido.");
@@ -117,8 +121,17 @@ public class ChartController : ControllerBase
|| format.Equals("jpg", StringComparison.OrdinalIgnoreCase) || format.Equals("jpg", StringComparison.OrdinalIgnoreCase)
|| format.Equals("jpeg", StringComparison.OrdinalIgnoreCase); || format.Equals("jpeg", StringComparison.OrdinalIgnoreCase);
// Alias codificato (necessario sia per jpgEnc che per il salvataggio su disco)
string? alias = isJpegEnc ? await _chartDataServiceV2.GetChartAliasAsync(isin) : null;
byte[] imgBytes = SkiaChartRendererV2.RenderToPng(chartData, width, height, jpeg: isJpeg); byte[] imgBytes = SkiaChartRendererV2.RenderToPng(chartData, width, height, jpeg: isJpeg);
// ── Salvataggio su disco (solo se ?save=true) ─────────────────
if (save && isJpeg)
{
await SaveChartToDiskAsync(isin, alias, imgBytes, isJpegEnc);
}
if (format.Equals("pdf", StringComparison.OrdinalIgnoreCase)) if (format.Equals("pdf", StringComparison.OrdinalIgnoreCase))
{ {
byte[] pdfBytes = WrapPngInPdf(imgBytes); byte[] pdfBytes = WrapPngInPdf(imgBytes);
@@ -128,8 +141,6 @@ public class ChartController : ControllerBase
if (isJpegEnc) if (isJpegEnc)
{ {
// Nome file codificato da SP rpt_CertificatesChartsAlias (come vecchio jpgEnc DevExpress)
string? alias = await _chartDataServiceV2.GetChartAliasAsync(isin);
string fileName = string.IsNullOrEmpty(alias) ? $"chart_v2_{isin}" : alias; string fileName = string.IsNullOrEmpty(alias) ? $"chart_v2_{isin}" : alias;
Response.Headers.Append("Content-Disposition", $"inline; filename={fileName}.jpg"); Response.Headers.Append("Content-Disposition", $"inline; filename={fileName}.jpg");
return File(imgBytes, "image/jpeg"); return File(imgBytes, "image/jpeg");
@@ -151,6 +162,39 @@ public class ChartController : ControllerBase
} }
} }
/// <summary>
/// Salva il JPEG su disco nei percorsi configurati in appsettings.json (ChartSettings).
/// format=jpg/jpeg → SavePath/{isin}.jpg
/// format=jpgEnc → SavePathEnc/{alias}.jpg
/// Errori di I/O vengono loggati senza interrompere la risposta HTTP.
/// </summary>
private async Task SaveChartToDiskAsync(string isin, string? alias, byte[] imgBytes, bool isEnc)
{
try
{
string key = isEnc ? "ChartSettings:SavePathEnc" : "ChartSettings:SavePath";
string? folder = _configuration[key];
if (string.IsNullOrEmpty(folder))
{
_logger.LogWarning("Salvataggio grafico saltato: chiave {Key} non configurata in appsettings", key);
return;
}
Directory.CreateDirectory(folder);
string fileName = isEnc && !string.IsNullOrEmpty(alias) ? $"{alias}.jpg" : $"{isin}.jpg";
string fullPath = Path.Combine(folder, fileName);
await System.IO.File.WriteAllBytesAsync(fullPath, imgBytes);
_logger.LogInformation("Grafico salvato su disco: {Path}", fullPath);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Impossibile salvare il grafico su disco per {Isin}", isin);
}
}
private static byte[] WrapPngInPdf(byte[] pngBytes) private static byte[] WrapPngInPdf(byte[] pngBytes)
{ {
var doc = new PdfDocument(); var doc = new PdfDocument();

View File

@@ -29,5 +29,9 @@
} }
} }
}, },
"ChartSettings": {
"SavePath": "C:\\inetpub\\wwwroot\\smart-roots.net\\Images\\Charts",
"SavePathEnc": "C:\\inetpub\\wwwroot\\smart-roots.net\\Images\\Charts\\encoded"
},
"AllowedHosts": "*" "AllowedHosts": "*"
} }