Bug in yml dotnet tool PackageReference arrangement RDS Blank Change int dotnet test nuget ^ [spcepiworld].[dbo].[evnt_inf] Assembly Version WS Result bug fix and Nuget bump, PSN, Reactor and Extra RDS rule OpenInsightApi and testRunTitle editorconfig bugs Fix Type serializerValue RDS oversight PropertyNameCaseInsensitive Save check for file already present NoWaitDirectory MoveArchive allow empty directory and continueOnError for clean files CreatePointerFile and more on NoWaitDirectory
334 lines
14 KiB
C#
334 lines
14 KiB
C#
using Adaptation.Shared;
|
|
using Adaptation.Shared.Metrology;
|
|
using Adaptation.Shared.Properties;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace Adaptation.FileHandlers.OpenInsightMetrologyViewer;
|
|
|
|
public class WSRequest
|
|
{
|
|
|
|
public long Id { get; set; }
|
|
public string AreaCountAvg { get; set; }
|
|
public string AreaCountMax { get; set; }
|
|
public string AreaCountMin { get; set; }
|
|
public string AreaCountStdDev { get; set; }
|
|
public string AreaTotalAvg { get; set; }
|
|
public string AreaTotalMax { get; set; }
|
|
public string AreaTotalMin { get; set; }
|
|
public string AreaTotalStdDev { get; set; }
|
|
public string Date { get; set; }
|
|
public string HazeAverageAvg { get; set; }
|
|
public string HazeAverageMax { get; set; }
|
|
public string HazeAverageMin { get; set; }
|
|
public string HazeAverageStdDev { get; set; }
|
|
public string HazeRegionAvg { get; set; }
|
|
public string HazeRegionMax { get; set; }
|
|
public string HazeRegionMin { get; set; }
|
|
public string HazeRegionStdDev { get; set; }
|
|
public string Layer { get; set; }
|
|
public string LotID { get; set; }
|
|
public string LPDCM2Avg { get; set; }
|
|
public string LPDCM2Max { get; set; }
|
|
public string LPDCM2Min { get; set; }
|
|
public string LPDCM2StdDev { get; set; }
|
|
public string LPDCountAvg { get; set; }
|
|
public string LPDCountMax { get; set; }
|
|
public string LPDCountMin { get; set; }
|
|
public string LPDCountStdDev { get; set; }
|
|
public string Operator { get; set; }
|
|
public string ParseErrorText { get; set; }
|
|
public string PSN { get; set; }
|
|
public string RDS { get; set; }
|
|
public string Reactor { get; set; }
|
|
public string Recipe { get; set; }
|
|
public string ScratchCountAvg { get; set; }
|
|
public string ScratchCountMax { get; set; }
|
|
public string ScratchCountMin { get; set; }
|
|
public string ScratchCountStdDev { get; set; }
|
|
public string ScratchTotalAvg { get; set; }
|
|
public string ScratchTotalMax { get; set; }
|
|
public string ScratchTotalMin { get; set; }
|
|
public string ScratchTotalStdDev { get; set; }
|
|
public string SumOfDefectsAvg { get; set; }
|
|
public string SumOfDefectsMax { get; set; }
|
|
public string SumOfDefectsMin { get; set; }
|
|
public string SumOfDefectsStdDev { get; set; }
|
|
public string Title { get; set; }
|
|
public string UniqueId { get; set; }
|
|
public string Zone { get; set; }
|
|
|
|
public string CellName { get; set; }
|
|
public string Data { get; set; }
|
|
#pragma warning disable IDE1006
|
|
public int i { get; set; }
|
|
public List<pcl.Detail> Details { get; protected set; }
|
|
|
|
[Obsolete("For json")] public WSRequest() { }
|
|
|
|
internal WSRequest(IFileRead fileRead, Logistics logistics, List<pcl.Description> descriptions)
|
|
{
|
|
if (fileRead is null)
|
|
{ }
|
|
i = -1;
|
|
Id = 0;
|
|
Zone = null;
|
|
Layer = null;
|
|
Title = null;
|
|
Data = "*Data*";
|
|
Details = new List<pcl.Detail>();
|
|
CellName = logistics.MesEntity;
|
|
pcl.Description x = descriptions[0];
|
|
//Header
|
|
{
|
|
AreaCountAvg = x.AreaCountAvg;
|
|
AreaCountMax = x.AreaCountMax;
|
|
AreaCountMin = x.AreaCountMin;
|
|
AreaCountStdDev = x.AreaCountStdDev;
|
|
AreaTotalAvg = x.AreaTotalAvg;
|
|
AreaTotalMax = x.AreaTotalMax;
|
|
AreaTotalMin = x.AreaTotalMin;
|
|
AreaTotalStdDev = x.AreaTotalStdDev;
|
|
Date = x.Date;
|
|
HazeAverageAvg = x.HazeAverageAvg;
|
|
HazeAverageMax = x.HazeAverageMax;
|
|
HazeAverageMin = x.HazeAverageMin;
|
|
HazeAverageStdDev = x.HazeAverageStdDev;
|
|
HazeRegionAvg = x.HazeRegionAvg;
|
|
HazeRegionMax = x.HazeRegionMax;
|
|
HazeRegionMin = x.HazeRegionMin;
|
|
HazeRegionStdDev = x.HazeRegionStdDev;
|
|
LotID = x.Lot;
|
|
LPDCM2Avg = x.LPDCM2Avg;
|
|
LPDCM2Max = x.LPDCM2Max;
|
|
LPDCM2Min = x.LPDCM2Min;
|
|
LPDCM2StdDev = x.LPDCM2StdDev;
|
|
LPDCountAvg = x.LPDCountAvg;
|
|
LPDCountMax = x.LPDCountMax;
|
|
LPDCountMin = x.LPDCountMin;
|
|
LPDCountStdDev = x.LPDCountStdDev;
|
|
ParseErrorText = x.ParseErrorText;
|
|
PSN = x.PSN;
|
|
RDS = x.RDS;
|
|
Reactor = x.Reactor;
|
|
Recipe = x.Recipe;
|
|
Operator = x.Employee;
|
|
ScratchCountAvg = x.ScratchCountAvg;
|
|
ScratchCountMax = x.ScratchCountMax;
|
|
ScratchCountMin = x.ScratchCountMin;
|
|
ScratchCountStdDev = x.ScratchCountStdDev;
|
|
ScratchTotalAvg = x.ScratchTotalAvg;
|
|
ScratchTotalMax = x.ScratchTotalMax;
|
|
ScratchTotalMin = x.ScratchTotalMin;
|
|
ScratchTotalStdDev = x.ScratchTotalStdDev;
|
|
SumOfDefectsAvg = x.SumOfDefectsAvg;
|
|
SumOfDefectsMax = x.SumOfDefectsMax;
|
|
SumOfDefectsMin = x.SumOfDefectsMin;
|
|
SumOfDefectsStdDev = x.SumOfDefectsStdDev;
|
|
UniqueId = x.UniqueId;
|
|
}
|
|
pcl.Detail detail;
|
|
foreach (pcl.Description description in descriptions)
|
|
{
|
|
detail = new pcl.Detail
|
|
{
|
|
Data = "*Data*",
|
|
i = -1,
|
|
Id = 0, //item.Id,
|
|
AreaCount = description.AreaCount,
|
|
AreaTotal = description.AreaTotal,
|
|
Bin1 = description.Bin1,
|
|
Bin2 = description.Bin2,
|
|
Bin3 = description.Bin3,
|
|
Bin4 = description.Bin4,
|
|
Bin5 = description.Bin5,
|
|
Bin6 = description.Bin6,
|
|
Bin7 = description.Bin7,
|
|
Bin8 = description.Bin8,
|
|
Comments = description.Comments,
|
|
Date = description.Date,
|
|
Diameter = description.Diameter,
|
|
Exclusion = description.Exclusion,
|
|
Gain = description.Gain,
|
|
HazeAverage = description.HazeAverage,
|
|
HazePeak = description.HazePeak,
|
|
HazeRegion = description.HazeRegion,
|
|
HazeRng = description.HazeRng,
|
|
HeaderUniqueId = description.HeaderUniqueId,
|
|
LPDCM2 = description.LPDCM2,
|
|
LPDCount = description.LPDCount,
|
|
Laser = description.Laser,
|
|
Mean = description.Mean,
|
|
Recipe = description.Recipe,
|
|
ScratchCount = description.ScratchCount,
|
|
ScratchTotal = description.ScratchTotal,
|
|
Slot = description.Slot,
|
|
Sort = description.Sort,
|
|
StdDev = description.StdDev,
|
|
SumOfDefects = description.SumOfDefects,
|
|
Thresh = description.Thresh,
|
|
Thruput = description.Thruput,
|
|
Title = null,
|
|
UniqueId = description.UniqueId
|
|
};
|
|
Details.Add(detail);
|
|
}
|
|
Date = logistics.DateTimeFromSequence.ToString();
|
|
if (UniqueId is null && Details.Any())
|
|
UniqueId = Details[0].HeaderUniqueId;
|
|
for (int i = 0; i < Details.Count; i++)
|
|
{
|
|
if (string.IsNullOrEmpty(Details[i].Bin1))
|
|
Details[i].Bin1 = null;
|
|
if (string.IsNullOrEmpty(Details[i].Bin2))
|
|
Details[i].Bin2 = null;
|
|
if (string.IsNullOrEmpty(Details[i].Bin3))
|
|
Details[i].Bin3 = null;
|
|
if (string.IsNullOrEmpty(Details[i].Bin4))
|
|
Details[i].Bin4 = null;
|
|
if (string.IsNullOrEmpty(Details[i].Bin5))
|
|
Details[i].Bin5 = null;
|
|
if (string.IsNullOrEmpty(Details[i].Bin6))
|
|
Details[i].Bin6 = null;
|
|
if (string.IsNullOrEmpty(Details[i].Bin7))
|
|
Details[i].Bin7 = null;
|
|
if (string.IsNullOrEmpty(Details[i].Bin8))
|
|
Details[i].Bin8 = null;
|
|
}
|
|
}
|
|
|
|
private static void UpdateDataPDF(List<pcl.Description> descriptions, string checkFileName)
|
|
{
|
|
string value;
|
|
string fullName;
|
|
object possiblePage;
|
|
object possibleString;
|
|
object possibleCOSArray;
|
|
java.util.List tokenList;
|
|
java.util.List arrayList;
|
|
java.io.OutputStream outputStream;
|
|
List<string> updateValues = new();
|
|
StringBuilder stringBuilder = new();
|
|
java.util.ListIterator tokenIterator;
|
|
java.util.ListIterator arrayIterator;
|
|
java.io.File file = new(checkFileName);
|
|
string reactorLoadLock = descriptions[0].Comments;
|
|
org.apache.pdfbox.pdmodel.common.PDStream pdStream;
|
|
org.apache.pdfbox.pdmodel.common.PDStream updatedStream;
|
|
org.apache.pdfbox.pdfparser.PDFStreamParser pdfStreamParser;
|
|
org.apache.pdfbox.pdfwriter.ContentStreamWriter contentStreamWriter;
|
|
org.apache.pdfbox.pdmodel.PDDocument pdDocument = org.apache.pdfbox.pdmodel.PDDocument.load(file);
|
|
org.apache.pdfbox.pdmodel.PDDocumentCatalog pdDocumentCatalog = pdDocument.getDocumentCatalog();
|
|
java.util.List pagesList = pdDocumentCatalog.getAllPages();
|
|
java.util.ListIterator pageIterator = pagesList.listIterator();
|
|
if (string.IsNullOrEmpty(descriptions[0].Lot) || string.IsNullOrEmpty(descriptions[0].Reactor) || descriptions[0].Lot.StartsWith(descriptions[0].Reactor))
|
|
fullName = string.Empty;
|
|
else
|
|
fullName = $"{descriptions[0].Reactor}-{descriptions[0].RDS}-{descriptions[0].PSN} ";
|
|
for (short i = 1; i < short.MaxValue; i++)
|
|
{
|
|
if (!pageIterator.hasNext())
|
|
break;
|
|
possiblePage = pageIterator.next();
|
|
if (possiblePage is not org.apache.pdfbox.pdmodel.PDPage page)
|
|
continue;
|
|
pdStream = page.getContents();
|
|
pdfStreamParser = new org.apache.pdfbox.pdfparser.PDFStreamParser(pdStream);
|
|
pdfStreamParser.parse();
|
|
tokenList = pdfStreamParser.getTokens();
|
|
tokenIterator = tokenList.listIterator();
|
|
for (short t = 1; i < short.MaxValue; t++)
|
|
{
|
|
if (!tokenIterator.hasNext())
|
|
break;
|
|
possibleCOSArray = tokenIterator.next();
|
|
if (possibleCOSArray is not org.apache.pdfbox.cos.COSArray cossArray)
|
|
continue;
|
|
_ = stringBuilder.Clear();
|
|
arrayList = cossArray.toList();
|
|
arrayIterator = arrayList.listIterator();
|
|
for (short a = 1; i < short.MaxValue; a++)
|
|
{
|
|
if (!arrayIterator.hasNext())
|
|
break;
|
|
possibleString = arrayIterator.next();
|
|
if (possibleString is not org.apache.pdfbox.cos.COSString cossString)
|
|
continue;
|
|
value = cossString.getString();
|
|
_ = stringBuilder.Append(value);
|
|
if (value != "]")
|
|
continue;
|
|
updateValues.Add(value);
|
|
value = stringBuilder.ToString();
|
|
if (value.Contains("[]"))
|
|
cossArray.setString(a - 1, string.Concat("*", fullName, reactorLoadLock, "]"));
|
|
else
|
|
cossArray.setString(a - 1, string.Concat(" {*", fullName, reactorLoadLock, "}]"));
|
|
}
|
|
}
|
|
if (updateValues.Any())
|
|
{
|
|
updatedStream = new org.apache.pdfbox.pdmodel.common.PDStream(pdDocument);
|
|
outputStream = updatedStream.createOutputStream();
|
|
contentStreamWriter = new org.apache.pdfbox.pdfwriter.ContentStreamWriter(outputStream);
|
|
contentStreamWriter.writeTokens(tokenList);
|
|
outputStream.close();
|
|
page.setContents(updatedStream);
|
|
}
|
|
}
|
|
if (updateValues.Any())
|
|
pdDocument.save(checkFileName);
|
|
pdDocument.close();
|
|
}
|
|
|
|
internal static void PostOpenInsightMetrologyViewerAttachments(IFileRead fileRead, Logistics logistics, string openInsightMetrologyViewerAPI, DateTime dateTime, string json, List<pcl.Description> descriptions, string matchDirectory)
|
|
{
|
|
if (dateTime == DateTime.MinValue)
|
|
{ }
|
|
string checkFileName;
|
|
if (string.IsNullOrEmpty(json))
|
|
{
|
|
WSRequest wsRequest = new(fileRead, logistics, descriptions);
|
|
(json, WS.Results wsResults) = WS.SendData(openInsightMetrologyViewerAPI, wsRequest);
|
|
if (!wsResults.Success)
|
|
throw new Exception(wsResults.ToString());
|
|
}
|
|
WS.Results metrologyWSRequest = JsonSerializer.Deserialize<WS.Results>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
long wsResultsHeaderID = metrologyWSRequest.HeaderID;
|
|
string[] pclFiles = Directory.GetFiles(matchDirectory, "*.pcl", SearchOption.TopDirectoryOnly);
|
|
if (pclFiles.Length != 1)
|
|
throw new Exception($"Invalid source file count for <{wsResultsHeaderID}>!{Environment.NewLine}{json}");
|
|
string sourceFileNameNoExt = Path.GetFileNameWithoutExtension(pclFiles[0]);
|
|
List<WS.Attachment> dataAttachments = new();
|
|
List<WS.Attachment> headerAttachments = new();
|
|
checkFileName = Path.Combine(matchDirectory, $"{sourceFileNameNoExt}_data.pdf");
|
|
if (!File.Exists(checkFileName))
|
|
throw new Exception("Header file doesn't exist!");
|
|
else
|
|
{
|
|
UpdateDataPDF(descriptions, checkFileName);
|
|
headerAttachments.Add(new WS.Attachment(descriptions[0].HeaderUniqueId, "Data.pdf", checkFileName));
|
|
}
|
|
foreach (pcl.Description description in descriptions)
|
|
{
|
|
checkFileName = Path.Combine(matchDirectory, $"{sourceFileNameNoExt}_{description.Slot.Replace('*', 's')}_image.pdf");
|
|
if (File.Exists(checkFileName))
|
|
dataAttachments.Add(new WS.Attachment(description.UniqueId, "Image.pdf", checkFileName));
|
|
else
|
|
{
|
|
checkFileName = Path.Combine(matchDirectory, $"{sourceFileNameNoExt}_{description.Slot.Replace('*', 's')}_data.pdf");
|
|
if (File.Exists(checkFileName))
|
|
dataAttachments.Add(new WS.Attachment(description.UniqueId, "Image.pdf", checkFileName));
|
|
}
|
|
}
|
|
if (dataAttachments.Count == 0 || dataAttachments.Count != descriptions.Count)
|
|
throw new Exception($"Invalid attachment count! {dataAttachments.Count} != {descriptions.Count}");
|
|
WS.AttachFiles(openInsightMetrologyViewerAPI, wsResultsHeaderID, headerAttachments, dataAttachments);
|
|
}
|
|
|
|
} |