195 lines
8.6 KiB
C#
195 lines
8.6 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using System.Collections.ObjectModel;
|
|
using System.Globalization;
|
|
using System.IO.Compression;
|
|
|
|
namespace File_Folder_Helper.Day;
|
|
|
|
internal static class Helper20231122
|
|
{
|
|
|
|
private record Record(string File, string FileName, string Equipment, string TimeStamp);
|
|
|
|
private static ReadOnlyCollection<Record> GetRecords(string sourceDirectory, string timestampFormat)
|
|
{
|
|
List<Record> results = [];
|
|
Record record;
|
|
string fileName;
|
|
string equipment;
|
|
string timestamp;
|
|
string[] segments;
|
|
string[] files = Directory.GetFiles(sourceDirectory, "*.pdsf", SearchOption.TopDirectoryOnly).ToArray();
|
|
foreach (string file in files)
|
|
{
|
|
fileName = Path.GetFileName(file);
|
|
segments = fileName.Split('_');
|
|
if (segments.Length != 2)
|
|
continue;
|
|
equipment = segments[0];
|
|
timestamp = segments[1].Split('.')[0];
|
|
if (timestamp.Length != timestampFormat.Length)
|
|
continue;
|
|
record = new(file, fileName, equipment, timestamp);
|
|
results.Add(record);
|
|
}
|
|
return new(results.OrderBy(l => l.TimeStamp).ToArray());
|
|
}
|
|
|
|
private static void WriteFile(string sourceDirectory, string[] columns, string equipment, List<List<string>> data, List<string> timestamps, string timestamp, DateTime dateTime)
|
|
{
|
|
List<string> lines = [];
|
|
string checkFile = Path.Combine(sourceDirectory, $"{equipment}-{timestamp}.tvs");
|
|
if (File.Exists(checkFile))
|
|
throw new NotSupportedException();
|
|
lines.Add($"timestamp\t{string.Join('\t', timestamps)}");
|
|
for (int i = 0; i < columns.Length; i++)
|
|
lines.Add($"{columns[i]}\t{string.Join('\t', data[i])}");
|
|
File.WriteAllLines(checkFile, lines);
|
|
File.SetLastWriteTime(checkFile, dateTime);
|
|
}
|
|
|
|
private static void ZipAndDeleteFiles(string sourceDirectory, string equipment, string timestamp, List<string> files, DateTime dateTime)
|
|
{
|
|
string checkFile = Path.Combine(sourceDirectory, $"{equipment}-{timestamp}.zip");
|
|
if (File.Exists(checkFile))
|
|
throw new NotSupportedException();
|
|
using ZipArchive zip = ZipFile.Open(checkFile, ZipArchiveMode.Create);
|
|
foreach (string file in files)
|
|
{
|
|
_ = zip.CreateEntryFromFile(file, Path.GetFileName(file));
|
|
File.Delete(file);
|
|
}
|
|
File.SetLastWriteTime(checkFile, dateTime);
|
|
}
|
|
|
|
private static void MoveFilesBack(string sourceDirectory, string parsedDirectory, List<string> parsedFiles)
|
|
{
|
|
foreach (string parsedFile in parsedFiles)
|
|
File.Move(parsedFile, Path.Combine(sourceDirectory, Path.GetFileName(parsedFile)));
|
|
if (parsedFiles.Count > 0)
|
|
Directory.Delete(parsedDirectory);
|
|
}
|
|
|
|
private static ReadOnlyDictionary<string, ReadOnlyCollection<Record>> GetEquipmentToRecords(string sourceDirectory, string timestampFormat)
|
|
{
|
|
Dictionary<string, ReadOnlyCollection<Record>> results = [];
|
|
List<Record>? collection;
|
|
Dictionary<string, List<Record>> keyValuePairs = [];
|
|
ReadOnlyCollection<Record> records = GetRecords(sourceDirectory, timestampFormat);
|
|
foreach (Record record in records)
|
|
{
|
|
if (!keyValuePairs.TryGetValue(record.Equipment, out collection))
|
|
{
|
|
keyValuePairs.Add(record.Equipment, []);
|
|
if (!keyValuePairs.TryGetValue(record.Equipment, out collection))
|
|
throw new NotSupportedException();
|
|
}
|
|
collection.Add(record);
|
|
}
|
|
foreach (KeyValuePair<string, List<Record>> keyValuePair in keyValuePairs)
|
|
results.Add(keyValuePair.Key, new(keyValuePair.Value));
|
|
return new(results);
|
|
}
|
|
|
|
private static void ParseProcessDataStandardFormatRecords(ILogger<Worker> logger, string sourceDirectory, string timestampFormat, string keyColumn, string missingKeyDirectory, string parsedDirectory, ReadOnlyCollection<Record> records)
|
|
{
|
|
string[] lines;
|
|
string[] values;
|
|
string[] columns;
|
|
DateTime dateTime;
|
|
string parsedFile;
|
|
int? keyColumnIndex;
|
|
string keyColumnValue;
|
|
string? lastColumn = null;
|
|
List<List<string>> data = [];
|
|
List<string> timestamps = [];
|
|
List<string> parsedFiles = [];
|
|
int? lastKeyColumnIndex = null;
|
|
string? lastKeyColumnValue = null;
|
|
foreach (Record record in records)
|
|
{
|
|
lines = File.ReadAllLines(record.File);
|
|
if (lines.Length != 15)
|
|
continue;
|
|
if (lines[6].Length < 1 || lines[6][0] != '"' || !lines[6].StartsWith("\"Time\""))
|
|
continue;
|
|
if (lines[8].Length < 1 || lines[8][0] != 'N' || lines[8] != "NUM_DATA_ROWS\t000000001")
|
|
continue;
|
|
keyColumnIndex = null;
|
|
columns = lines[6].Split('\t');
|
|
if (columns.Length < 3)
|
|
continue;
|
|
values = lines[7].Split('\t');
|
|
if (values.Length != columns.Length)
|
|
continue;
|
|
for (int i = 0; i < columns.Length; i++)
|
|
{
|
|
if (columns[i] != keyColumn)
|
|
continue;
|
|
keyColumnIndex = i;
|
|
break;
|
|
}
|
|
if (keyColumnIndex is null)
|
|
{
|
|
File.Move(record.File, Path.Combine(sourceDirectory, missingKeyDirectory, record.FileName));
|
|
continue;
|
|
}
|
|
keyColumnValue = values[keyColumnIndex.Value];
|
|
parsedFile = Path.Combine(parsedDirectory, record.FileName);
|
|
if ((lastColumn is not null && lines[6] != lastColumn) || (lastKeyColumnIndex is not null && keyColumnIndex.Value != lastKeyColumnIndex.Value) || (lastKeyColumnValue is not null && lastKeyColumnValue != keyColumnValue) || timestamps.Count > 12345)
|
|
{
|
|
if (!DateTime.TryParseExact(record.TimeStamp, timestampFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
|
throw new NotSupportedException();
|
|
WriteFile(sourceDirectory, columns, record.Equipment, data, timestamps, record.TimeStamp, dateTime);
|
|
ZipAndDeleteFiles(sourceDirectory, record.Equipment, record.TimeStamp, parsedFiles, dateTime);
|
|
Directory.Delete(parsedDirectory);
|
|
logger.LogInformation("{timestamp} triggered", record.TimeStamp);
|
|
parsedFiles.Clear();
|
|
break;
|
|
}
|
|
parsedFiles.Add(parsedFile);
|
|
File.Move(record.File, parsedFile);
|
|
timestamps.Add($"'{record.TimeStamp}");
|
|
for (int i = 0; i < columns.Length; i++)
|
|
data.Add([]);
|
|
for (int i = 0; i < columns.Length; i++)
|
|
data[i].Add(values[i]);
|
|
lastColumn = lines[6];
|
|
lastKeyColumnIndex = keyColumnIndex;
|
|
lastKeyColumnValue = keyColumnValue;
|
|
}
|
|
MoveFilesBack(sourceDirectory, parsedDirectory, parsedFiles);
|
|
}
|
|
|
|
private static void ParseProcessDataStandardFormatFiles(ILogger<Worker> logger, string sourceDirectory, string timestampFormat, string keyColumn, string missingKeyDirectory)
|
|
{
|
|
string parsedDirectory;
|
|
ReadOnlyDictionary<string, ReadOnlyCollection<Record>> equipmentToRecords = GetEquipmentToRecords(sourceDirectory, timestampFormat);
|
|
foreach (KeyValuePair<string, ReadOnlyCollection<Record>> keyValuePair in equipmentToRecords)
|
|
{
|
|
parsedDirectory = Path.Combine(sourceDirectory, DateTime.Now.Ticks.ToString());
|
|
if (!Directory.Exists(parsedDirectory))
|
|
_ = Directory.CreateDirectory(parsedDirectory);
|
|
ParseProcessDataStandardFormatRecords(logger, sourceDirectory, timestampFormat, keyColumn, missingKeyDirectory, parsedDirectory, keyValuePair.Value);
|
|
Thread.Sleep(100);
|
|
}
|
|
}
|
|
|
|
internal static void ProcessDataStandardFormat(ILogger<Worker> logger, List<string> args)
|
|
{
|
|
string keyColumn = args[3];
|
|
string sourceDirectory = args[0];
|
|
string timestampFormat = args[2];
|
|
if (!Directory.Exists(sourceDirectory))
|
|
throw new Exception(sourceDirectory);
|
|
string missingKeyDirectory = Path.Combine(sourceDirectory, "Missing-Key");
|
|
if (!Directory.Exists(missingKeyDirectory))
|
|
_ = Directory.CreateDirectory(missingKeyDirectory);
|
|
while (true)
|
|
{
|
|
ParseProcessDataStandardFormatFiles(logger, sourceDirectory, timestampFormat, keyColumn, missingKeyDirectory);
|
|
Thread.Sleep(5000);
|
|
}
|
|
}
|
|
|
|
} |