diff --git a/PepApi.Core/Controllers/DrawingsController.cs b/PepApi.Core/Controllers/DrawingsController.cs index e330461..3eddf8c 100644 --- a/PepApi.Core/Controllers/DrawingsController.cs +++ b/PepApi.Core/Controllers/DrawingsController.cs @@ -1,5 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using PepApi.Core.Configuration; using PepApi.Core.Models; using PepLib.Data; using PepLib.IO; @@ -11,10 +13,12 @@ namespace PepApi.Core.Controllers; public class DrawingsController : ControllerBase { private readonly PepDB _db; + private readonly PepSettings _settings; - public DrawingsController(PepDB db) + public DrawingsController(PepDB db, IOptions settings) { _db = db; + _settings = settings.Value; } /// @@ -81,7 +85,7 @@ public class DrawingsController : ControllerBase /// /// Get a drawing by exact name. /// - [HttpGet("name/{name}")] + [HttpGet("by-name/{name}")] public async Task> GetDrawingByName(string name) { var drawing = await _db.Drawings @@ -161,10 +165,13 @@ public class DrawingsController : ControllerBase if (drawing == null) return NotFound(new { message = "Drawing not found in database" }); - var filePath = drawing.Path + drawing.File; + if (string.IsNullOrEmpty(_settings.DrawingsDirectory)) + return StatusCode(503, new { message = "DrawingsDirectory is not configured" }); + + var filePath = Path.Combine(_settings.DrawingsDirectory, drawing.File); if (!System.IO.File.Exists(filePath)) - return NotFound(new { message = "Drawing file not found on disk" }); + return NotFound(new { message = $"Drawing file not found: {drawing.File}" }); PepLib.Models.Drawing pep; try diff --git a/PepApi.Core/Controllers/NestsController.cs b/PepApi.Core/Controllers/NestsController.cs index dda6e0e..5d6b93e 100644 --- a/PepApi.Core/Controllers/NestsController.cs +++ b/PepApi.Core/Controllers/NestsController.cs @@ -101,7 +101,7 @@ public class NestsController : ControllerBase return File(bytes, mimeType, fileName); } - [HttpGet("{nestName}/download")] + [HttpGet("{nestName:regex(^(?!\\d{{4}}$).+)}/download")] public async Task DownloadFile(string nestName) { var filePath = await GetNestPathAsync(nestName); @@ -131,7 +131,7 @@ public class NestsController : ControllerBase return Ok(combined); } - [HttpGet("{nestName}/plates")] + [HttpGet("{nestName:regex(^(?!\\d{{4}}$).+)}/plates")] public async Task>> GetPlates(string nestName) { var nestFile = await GetNestPathAsync(nestName); @@ -346,13 +346,22 @@ public class NestsController : ControllerBase var pepPath = Path.Combine(_nestDirectory, nestName + ".pep"); if (System.IO.File.Exists(pepPath)) return pepPath; + + var pepMatch = FindFileByPrefix(_nestDirectory, nestName, ".pep"); + if (pepMatch != null) + return pepMatch; } // Older nests use .zip in year subdirectory - var zipPath = Path.Combine(_nestDirectory, year.Value.ToString(), nestName + ".zip"); + var yearDir = Path.Combine(_nestDirectory, year.Value.ToString()); + var zipPath = Path.Combine(yearDir, nestName + ".zip"); if (System.IO.File.Exists(zipPath)) return zipPath; + var zipMatch = FindFileByPrefix(yearDir, nestName, ".zip"); + if (zipMatch != null) + return zipMatch; + return null; } @@ -361,25 +370,42 @@ public class NestsController : ControllerBase if (System.IO.File.Exists(flatPepPath)) return flatPepPath; + var flatPepMatch = FindFileByPrefix(_nestDirectory, nestName, ".pep"); + if (flatPepMatch != null) + return flatPepMatch; + // Fall back to year-based directory lookup for older nests + var upperName = nestName.ToUpper(); var nestHeader = await _db.NestHeaders - .Where(n => n.NestName.ToUpper() == nestName.ToUpper() && n.DateProgrammed != null) + .Where(n => (n.NestName.ToUpper() == upperName || n.NestName.ToUpper().StartsWith(upperName + "-")) + && n.DateProgrammed != null) .OrderByDescending(n => n.DateProgrammed) .FirstOrDefaultAsync(); if (nestHeader == null) return null; + var fullName = nestHeader.NestName; var dbYear = nestHeader.DateProgrammed!.Value.Year; // Older nests used .zip extension - var yearZipPath = Path.Combine(_nestDirectory, dbYear.ToString(), nestName + ".zip"); + var yearZipPath = Path.Combine(_nestDirectory, dbYear.ToString(), fullName + ".zip"); if (System.IO.File.Exists(yearZipPath)) return yearZipPath; return null; } + private static string? FindFileByPrefix(string directory, string prefix, string extension) + { + if (!Directory.Exists(directory)) + return null; + + var pattern = prefix + "-*" + extension; + var matches = Directory.GetFiles(directory, pattern); + return matches.Length > 0 ? matches.Order().First() : null; + } + private async Task GetNestDetailsAsync(string nestFilePath) { var nest = Nest.Load(nestFilePath); diff --git a/PepMcp/PepTools.cs b/PepMcp/PepTools.cs index 55bef55..a3450ee 100644 --- a/PepMcp/PepTools.cs +++ b/PepMcp/PepTools.cs @@ -533,7 +533,7 @@ public class PepTools { try { - var response = await _httpClient.GetAsync($"/drawings/name/{Uri.EscapeDataString(name)}"); + var response = await _httpClient.GetAsync($"/drawings/by-name/{Uri.EscapeDataString(name)}"); if (!response.IsSuccessStatusCode) return $"Error: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}";