NestReader opened .pep files with FileStream(path, FileMode.Open), which defaults to FileAccess.ReadWrite. The forge deployment bind-mounts /mnt/pep-nest read-only, so every read-only open was rejected with "Read-only file system" (EROFS) even though the code never writes. Pass FileAccess.Read/FileShare.Read explicitly, matching DrawingReader and ZipHelper elsewhere in PepLib.Core. Once that was fixed, a second pre-existing bug surfaced: GetNestDetailsAsync matched DB rows by NestName AND a literal Path comparison built from the container's local mount path. NestHeader.Path stores the original Windows UNC share path (e.g. \REMCOSRV0\pep nest\) from when PepApi ran directly against the network share, so the comparison can never match post-Docker. Match by NestName alone (ordered by most recent), consistent with the fallback lookup already used elsewhere in NestsController.
149 lines
4.2 KiB
C#
149 lines
4.2 KiB
C#
using PepLib.Models;
|
|
using System.Diagnostics;
|
|
using System.IO.Compression;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace PepLib.IO
|
|
{
|
|
public sealed class NestReader
|
|
{
|
|
public Nest Nest { get; private set; }
|
|
|
|
private readonly Dictionary<string, Stream> plates;
|
|
private readonly Dictionary<string, Stream> loops;
|
|
|
|
public NestReader()
|
|
: this(new Nest())
|
|
{
|
|
}
|
|
|
|
public NestReader(Nest nest)
|
|
{
|
|
Nest = nest;
|
|
plates = new Dictionary<string, Stream>();
|
|
loops = new Dictionary<string, Stream>();
|
|
}
|
|
|
|
public void Read(Stream stream)
|
|
{
|
|
const string plateExtensionPattern = "plate-\\d\\d\\d";
|
|
const string loopExtensionPattern = "loop-\\d\\d\\d";
|
|
|
|
using (var zip = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen: true))
|
|
{
|
|
foreach (var entry in zip.Entries)
|
|
{
|
|
using var entryStream = entry.Open();
|
|
var memstream = new MemoryStream();
|
|
entryStream.CopyTo(memstream);
|
|
memstream.Seek(0, SeekOrigin.Begin);
|
|
|
|
var extension = Path.GetExtension(entry.FullName);
|
|
|
|
switch (extension)
|
|
{
|
|
case ".report":
|
|
LoadReport(memstream);
|
|
memstream.Close();
|
|
continue;
|
|
|
|
case ".dwg-info":
|
|
LoadDrawingInfo(memstream);
|
|
memstream.Close();
|
|
continue;
|
|
|
|
default:
|
|
Debug.WriteLine("Unknown file: " + entry.FullName);
|
|
break;
|
|
}
|
|
|
|
if (Regex.IsMatch(extension, loopExtensionPattern))
|
|
loops.Add(entry.FullName, memstream);
|
|
else if (Regex.IsMatch(extension, plateExtensionPattern))
|
|
plates.Add(entry.FullName, memstream);
|
|
}
|
|
}
|
|
|
|
foreach (var loop in loops)
|
|
Nest.Loops.Add(ReadLoop(loop.Key, loop.Value));
|
|
|
|
Nest.ResolveLoops();
|
|
|
|
foreach (var plate in plates)
|
|
Nest.Plates.Add(ReadPlate(plate.Key, plate.Value));
|
|
}
|
|
|
|
public void Read(string nestFile)
|
|
{
|
|
if (!File.Exists(nestFile))
|
|
{
|
|
var msg = string.Format("File Not Found: {0}", nestFile);
|
|
throw new FileNotFoundException(msg);
|
|
}
|
|
|
|
Stream stream = null;
|
|
|
|
try
|
|
{
|
|
stream = new FileStream(nestFile, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
Read(stream);
|
|
}
|
|
finally
|
|
{
|
|
if (stream != null)
|
|
stream.Close();
|
|
}
|
|
}
|
|
|
|
private void LoadReport(Stream stream)
|
|
{
|
|
try
|
|
{
|
|
Nest.Report = Report.Load(stream);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Debug.WriteLine(exception.Message);
|
|
Debug.WriteLine(exception.StackTrace);
|
|
}
|
|
}
|
|
|
|
private void LoadDrawingInfo(Stream stream)
|
|
{
|
|
var buffer = new byte[2000];
|
|
|
|
while (stream.Read(buffer, 0, buffer.Length) > 0)
|
|
{
|
|
var name = Encoding.Default.GetString(buffer, 200, 200).Trim();
|
|
var qty = BitConverter.ToInt32(buffer, 432);
|
|
|
|
var drawing = new NestDrawing
|
|
{
|
|
Name = name,
|
|
QtyRequired = qty
|
|
};
|
|
|
|
Nest.Drawings.Add(drawing);
|
|
}
|
|
}
|
|
|
|
private Loop ReadLoop(string name, Stream stream)
|
|
{
|
|
var reader = new LoopReader();
|
|
reader.Read(name, stream);
|
|
|
|
return reader.Loop;
|
|
}
|
|
|
|
private Plate ReadPlate(string name, Stream stream)
|
|
{
|
|
var reader = new PlateReader();
|
|
reader.Read(name, stream, Nest);
|
|
|
|
return reader.Plate;
|
|
}
|
|
}
|
|
}
|
|
|