Moved to ADO2024 PI#

Ran SortCodeMethods
This commit is contained in:
2024-10-11 09:15:32 -07:00
parent 3d114918e4
commit b6d8d4c52f
58 changed files with 25064 additions and 1423 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,236 @@
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240106
{
private record Record(string Key, Dictionary<string, string> KeyValuePairs);
private static Dictionary<string, Dictionary<string, string>> GetKeyValuePairs(List<Record> collection, bool replaceFound)
{
Dictionary<string, Dictionary<string, string>> results = [];
if (replaceFound)
{
foreach ((string key, Dictionary<string, string> keyValuePairs) in collection)
_ = results.TryAdd(key, keyValuePairs);
}
else
{
foreach ((string key, Dictionary<string, string> keyValuePairs) in collection.OrderBy(l => l.Key))
_ = results.TryAdd(key, keyValuePairs);
}
return results;
}
private static Dictionary<int, Host> GetHosts(string jsonl)
{
Dictionary<int, Host> results = [];
int id;
string json = $"[{File.ReadAllText(jsonl).Replace("\r\n", ",")}]";
Host[] hosts = JsonSerializer.Deserialize(json, HostSourceGenerationContext.Default.HostArray) ?? throw new NullReferenceException(nameof(json));
foreach (Host host in hosts)
{
if (host.Id is null)
continue;
if (host.Hyphen is not null and nameof(host.Hyphen))
continue;
if (!int.TryParse(host.Id, out id))
throw new NotSupportedException($"{host.Id} is not a number");
if (results.ContainsKey(id))
throw new NotSupportedException($"Id {id} is not unique!");
results.Add(id, host);
}
return results;
}
private static int? GetHeaderLine(string[] lines)
{
int? headerLine = null;
for (int i = 0; i < lines.Length - 1; i++)
{
if (!lines[i].Contains('\t'))
continue;
headerLine = i;
}
return headerLine;
}
private static Dictionary<string, Dictionary<string, string>> GetKeyValuePairs(int keyIndex, int keyLength, string replace, string[] headers, string[] lines, int headerLine)
{
Dictionary<string, Dictionary<string, string>> results;
string? key;
Record record;
bool replaceFound = false;
List<Record> collection = [];
Dictionary<string, string> keyValuePairs;
for (int i = headerLine + 1; i < lines.Length; i++)
{
key = null;
keyValuePairs = [];
for (int j = 0; j < headers.Length; j++)
{
if (j > 0)
i++;
if (lines.Length <= i)
{
keyValuePairs.Clear();
break;
}
if (j == keyIndex)
{
key = lines[i];
if (key.Length != keyLength)
{
keyValuePairs.Clear();
break;
}
}
if (lines[i] != replace)
_ = keyValuePairs.TryAdd(headers[j], lines[i]);
else
{
if (!replaceFound)
replaceFound = true;
_ = keyValuePairs.TryAdd(headers[j], lines[i]);
j++;
_ = keyValuePairs.TryAdd(headers[j], lines[i]);
}
}
if (keyValuePairs.Count != headers.Length)
continue;
key ??= "-";
record = new(key, keyValuePairs);
collection.Add(record);
}
results = GetKeyValuePairs(collection, replaceFound);
return results;
}
private static ReadOnlyCollection<string> GetIpAddressAndVerify(ILogger<Worker> logger, string key, Dictionary<string, Dictionary<string, string>> keyValuePairs, Dictionary<int, Host> hosts, string filter)
{
List<string> results = [];
int id;
bool found;
Host? host;
string text;
string? ipAddress;
StringBuilder stringBuilder = new();
foreach (KeyValuePair<string, Dictionary<string, string>> keyValuePair in keyValuePairs)
{
found = false;
if (keyValuePair.Key.StartsWith(filter))
continue;
if (!keyValuePair.Value.TryGetValue(key, out ipAddress))
throw new NotSupportedException($"{key} isn't present!");
if (ipAddress == "0.0.0.0")
continue;
results.Add(ipAddress);
_ = stringBuilder.Clear();
foreach (KeyValuePair<string, string> keyValue in keyValuePair.Value)
_ = stringBuilder.AppendLine(keyValue.Value);
text = stringBuilder.ToString();
if (!int.TryParse(ipAddress.Split('.')[^1], out id))
throw new NotSupportedException($"{ipAddress} isn't valid!");
if (!hosts.TryGetValue(id, out host))
throw new NotSupportedException($"{id} isn't valid!");
foreach (KeyValuePair<string, string> keyValue in keyValuePair.Value)
{
if (keyValue.Value != host.Hyphen)
continue;
found = true;
}
if (!found)
throw new NotSupportedException($"{host}{Environment.NewLine}{text} doesn't match!");
if (text.Contains("Unknown", StringComparison.InvariantCultureIgnoreCase))
logger.LogWarning($"{text} contains Unknown and should be {host.Device}!");
}
return new(results);
}
private static void WriteAppendToHostConfFile(FileInfo fileInfo, string hostConfFile, Dictionary<int, Host> hosts, ReadOnlyCollection<string> ipAddress)
{
int id;
Host host;
string ip;
string line;
List<int> distinct = [];
List<string> lines = [$"# {fileInfo.LastWriteTime.Ticks}"];
string firstSegmentsOfIpAddress = string.Join('.', ipAddress[0].Split('.').Take(3));
foreach (KeyValuePair<int, Host> keyValuePair in hosts)
{
host = keyValuePair.Value;
if (host.Hyphen is not null and nameof(host.Hyphen))
continue;
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Hyphen.Length != 17)
throw new NotSupportedException($"{host.Id} is Null or not 17");
if (!int.TryParse(host.Id, out id))
throw new NotSupportedException($"{host.Id} is not a number");
if (distinct.Contains(id))
throw new NotSupportedException($"{id} is not distinct!");
distinct.Add(id);
ip = ipAddress.Contains($"{firstSegmentsOfIpAddress}.{id}") ? $"{firstSegmentsOfIpAddress}.{id}" : $"# {firstSegmentsOfIpAddress}.{id}";
line = $"{ip} {host.Name} # https://{host.Name} | {host.Colon} | {host.Hyphen} | {host.Device} |";
lines.Add(line);
}
lines.Add($"# {fileInfo.LastWriteTime.Ticks}");
File.AppendAllLines(hostConfFile, lines);
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Dictionary<string, Dictionary<string, string>>))]
private partial class DictionaryDictionarySourceGenerationContext : JsonSerializerContext
{
}
internal static void TextToJson(ILogger<Worker> logger, List<string> args)
{
string json;
string[] lines;
int? headerLine;
FileInfo fileInfo;
string key = args[7];
string filter = args[10];
string replace = args[5];
int keyIndex = int.Parse(args[3]);
int keyLength = int.Parse(args[4]);
ReadOnlyCollection<string> ipAddress;
string[] headers = args[6].Split(',');
string jsonl = Path.Combine(args[0], args[8]);
string hostConfFile = Path.Combine(args[0], args[9]);
string[] txtFiles = Directory.GetFiles(args[0], args[2]);
Dictionary<string, Dictionary<string, string>> keyValuePairs;
if (!File.Exists(jsonl))
throw new NotSupportedException($"{args[8]} doesn't exist!");
Dictionary<int, Host> hosts = GetHosts(jsonl);
if (hosts.Count == 0)
throw new NotSupportedException($"{args[8]} isn't valid!");
foreach (string txtFile in txtFiles)
{
lines = File.ReadAllLines(txtFile);
if (lines.Length == 0)
continue;
headerLine = GetHeaderLine(lines);
if (headerLine is null)
continue;
fileInfo = new(txtFile);
keyValuePairs = GetKeyValuePairs(keyIndex, keyLength, replace, headers, lines, headerLine.Value);
if (keyValuePairs.Count == 0)
continue;
ipAddress = GetIpAddressAndVerify(logger, key, keyValuePairs, hosts, filter);
if (ipAddress.Count == 0)
continue;
json = JsonSerializer.Serialize(keyValuePairs, DictionaryDictionarySourceGenerationContext.Default.DictionaryStringDictionaryStringString);
logger.LogInformation("Writing output file...");
File.WriteAllText($"{fileInfo.FullName}-{fileInfo.LastWriteTime.Ticks}.json", json);
WriteAppendToHostConfFile(fileInfo, hostConfFile, hosts, ipAddress);
File.WriteAllLines(txtFile, [string.Empty, string.Empty, lines[^1]]);
}
}
}

View File

@ -0,0 +1,50 @@
using DiscUtils.Iso9660;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240107
{
private static void DirectoryToISO(ILogger<Worker> logger, string destinationDirectory, bool mapOnly, string directory)
{
byte[] bytes = [];
string relativePath;
string directoryName = Path.GetFileName(directory);
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
IEnumerable<string> files = Directory.EnumerateFiles(directory, "*", new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
foreach (string file in files)
{
relativePath = Path.GetRelativePath(directory, file).Replace(';', '_');
if (!mapOnly)
_ = builder.AddFile(relativePath, file);
else
_ = builder.AddFile(relativePath, bytes);
}
logger.LogInformation(destinationDirectory);
builder.Build(Path.Combine(destinationDirectory, $"{directoryName}.iso"));
logger.LogInformation(directoryName);
}
internal static void DirectoryToISO(ILogger<Worker> logger, List<string> args)
{
string sourceDirectory = args[0];
int directories = int.Parse(args[2]);
string destinationDirectory = args[3];
logger.LogInformation(sourceDirectory);
if (sourceDirectory == "C:/ProgramData")
{
sourceDirectory = destinationDirectory;
destinationDirectory = Path.GetDirectoryName(destinationDirectory) ?? throw new NotSupportedException();
}
bool mapOnly = sourceDirectory.Length == 2;
if (!Directory.Exists(destinationDirectory))
_ = Directory.CreateDirectory(destinationDirectory);
string[] subDirectories = directories == 1 ? [sourceDirectory] : Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
if (subDirectories.Length != directories)
throw new Exception($"{directories} != {subDirectories.Length}");
foreach (string directory in subDirectories)
DirectoryToISO(logger, destinationDirectory, mapOnly, directory);
}
}

View File

@ -0,0 +1,299 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240108
{
private record Method(string Name,
int ParameterCount,
int StartLine,
int EndLine,
int FirstUsedLine);
[GeneratedRegex(@"(?<method>[A-Z]{1}[A-Za-z_0-9]*)\(")]
private static partial Regex CSharpMethodName();
[GeneratedRegex(@"\s[a-zA-Z_]*,")]
private static partial Regex CSharpParameter();
[GeneratedRegex(@"\b(public|private|internal|protected)\s\b(static)?\s?\b(partial)?\s?\b(async)?\s?[[\]<,>?a-zA-Z()\s]*\s[A-Z]{1}[a-zA-Z_]+\(.*\)")]
private static partial Regex CSharpMethodLine();
private static string? GetName(string line)
{
string? result;
Match match = CSharpMethodName().Match(line);
if (!match.Success)
result = null;
else
result = match.Groups["method"].Value;
return result;
}
private static int GetStartLine(string[] lines, int i)
{
int result = i;
string line;
for (int j = i - 1; j > -1; j--)
{
line = lines[j].Trim();
if (!line.StartsWith('[') && !line.StartsWith("/// "))
break;
result--;
}
return result;
}
private static int GetParameterCount(string line, string search)
{
int result;
string after = line.Split(search)[^1];
if (after.StartsWith(')'))
result = 0;
else
{
string[] segments = CSharpParameter().Split(after);
result = segments.Length;
}
return result;
}
private static int GetLineBlockCount(string line, bool isLinq)
{
int result = 0;
bool ignore = false;
for (int i = 0; i < line.Length; i++)
{
if (line[i] == '\'')
i++;
else if (!isLinq && !ignore && line[i] == '{')
result++;
else if (!isLinq && !ignore && line[i] == '}')
result--;
else if (isLinq && !ignore && line[i] == ';')
result--;
else if (i > 0 && line[i] == '"' && line[i - 1] != '\\')
ignore = !ignore;
}
return result;
}
private static int? GetFirstUsedLine(string[] lines, int i, string search, string searchNot, string searchWrap, string searchDelegate, string searchConstructor, int parameterCount)
{
int? result = null;
string[] segments;
string[] afterSegments;
string lastSegmentBeforeDot;
for (int j = 0; j < lines.Length; j++)
{
if (j == i)
continue;
segments = lines[j].Split(search);
if (segments.Length == 1)
{
segments = lines[j].Split(searchNot);
if (segments.Length == 1)
{
segments = lines[j].Split(searchWrap);
if (segments.Length == 1)
{
if (!lines[j].EndsWith(searchDelegate))
{
segments = lines[j].Split(searchConstructor);
if (segments.Length == 1)
continue;
}
}
}
}
if (lines[j].EndsWith(searchDelegate))
{
result = j;
break;
}
else
{
lastSegmentBeforeDot = segments[^1].Split(").")[0];
if (parameterCount == 0)
{
if (lastSegmentBeforeDot.Contains(','))
continue;
}
else
{
afterSegments = lastSegmentBeforeDot.Split(',');
if (afterSegments.Length != parameterCount)
continue;
}
result = j;
break;
}
}
return result;
}
private static ReadOnlyCollection<int> GetMethodLines(ReadOnlyCollection<Method> methods)
{
List<int> results = [];
foreach (Method method in methods)
{
for (int i = method.StartLine; i < method.EndLine + 1; i++)
results.Add(i);
}
return new(results);
}
private static ReadOnlyCollection<Method> GetMethods(string cSharpFile, ILogger<Worker> logger, string[] lines)
{
List<Method> results = [];
int blocks;
bool isLinq;
int endLine;
string line;
string? name;
int startLine;
string search;
string innerLine;
string searchNot;
string searchWrap;
int parameterCount;
int? firstUsedLine;
string searchDelegate;
string lineSegmentFirst;
string searchConstructor;
for (int i = 0; i < lines.Length; i++)
{
line = lines[i].Trim();
if (string.IsNullOrEmpty(line))
continue;
if (line.Length < 5)
continue;
if (line.EndsWith(','))
continue;
if (!CSharpMethodLine().Match(line).Success)
continue;
name = GetName(line);
search = $" {name}(";
searchNot = $"!{name}(";
searchWrap = $"({name}(";
searchDelegate = $" += {name};";
if (string.IsNullOrEmpty(name))
continue;
blocks = 0;
startLine = GetStartLine(lines, i);
searchConstructor = $"{name.ToLower()} = new(";
parameterCount = GetParameterCount(line, search);
isLinq = lines[i + 1].Trim() != "{";
if (isLinq)
blocks++;
for (int j = i + 1; j < lines.Length; j++)
{
innerLine = lines[j].Trim();
if (isLinq && string.IsNullOrEmpty(innerLine))
{
if (line.EndsWith(';'))
blocks--;
}
blocks += GetLineBlockCount(innerLine, isLinq);
if (blocks == 0)
{
endLine = j;
if (lines.Length > j + 1 && string.IsNullOrEmpty(lines[j + 1].Trim()))
endLine++;
firstUsedLine = GetFirstUsedLine(lines, i, search, searchNot, searchWrap, searchDelegate, searchConstructor, parameterCount);
if (firstUsedLine is null)
{
lineSegmentFirst = line.Split(search)[0];
if (!lines[i - 1].Trim().StartsWith("[Obsolete"))
{
if (lineSegmentFirst.StartsWith("private"))
logger.LogWarning("<{cSharpFileName}> {name} with {parameterCount} parameter(s) <{line}>", Path.GetFileName(cSharpFile), name, parameterCount, lineSegmentFirst);
else
logger.LogInformation("<{cSharpFileName}> {name} with {parameterCount} parameter(s) <{line}>", Path.GetFileName(cSharpFile), name, parameterCount, lineSegmentFirst);
}
break;
}
if (j > lines.Length - 2)
throw new Exception();
results.Add(new(name, parameterCount, startLine, endLine, firstUsedLine.Value));
break;
}
}
}
return new(results.OrderBy(l => l.FirstUsedLine).ToArray());
}
private static bool WriteAllLines(string cSharpFile, string[] lines, ReadOnlyCollection<Method> methods)
{
bool result;
List<string> results = [];
ReadOnlyCollection<int> methodLines = GetMethodLines(methods);
int minMethodLines = methodLines.Min();
for (int i = 0; i < minMethodLines; i++)
results.Add(lines[i]);
foreach (Method method in methods)
{
for (int i = method.StartLine; i < method.EndLine + 1; i++)
results.Add(lines[i]);
}
for (int i = minMethodLines; i < lines.Length; i++)
{
if (methodLines.Contains(i))
continue;
results.Add(lines[i]);
}
string text = File.ReadAllText(cSharpFile);
string join = string.Join(Environment.NewLine, results);
if (join == text)
result = false;
else
{
result = true;
File.WriteAllText(cSharpFile, join);
}
return result;
}
private static bool SortFile(ILogger<Worker> logger, string cSharpFile, string[] lines)
{
bool result;
ReadOnlyCollection<Method> methods = GetMethods(cSharpFile, logger, lines);
if (methods.Count == 0)
result = false;
else
result = WriteAllLines(cSharpFile, lines, methods);
return result;
}
internal static void SortCodeMethods(ILogger<Worker> logger, List<string> args, CancellationToken cancellationToken)
{
bool result = false;
bool check;
string[] lines;
bool usePathCombine = true;
long ticks = DateTime.Now.Ticks;
logger.LogInformation("{ticks}", ticks);
string directory = Path.GetFullPath(args[2]);
string repositoryDirectory = Path.GetFullPath(args[0]);
string[] cSharpFiles = Directory.GetFiles(directory, "*.cs", SearchOption.AllDirectories);
ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles = Helpers.HelperGit.GetOthersModifiedAndDeletedExcludingStandardFiles(repositoryDirectory, usePathCombine, cancellationToken);
for (int i = 0; i < 10; i++)
{
foreach (string cSharpFile in cSharpFiles)
{
if (!gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(cSharpFile))
continue;
lines = File.ReadAllLines(cSharpFile);
check = SortFile(logger, cSharpFile, lines);
if (check && !result)
result = true;
}
if (!result)
break;
}
}
}

View File

@ -0,0 +1,83 @@
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240129
{
private record Record([property: JsonPropertyName("Part Name")] string? PartName,
[property: JsonPropertyName("Part Revision")] string? PartRevision,
[property: JsonPropertyName("Test Name")] string? TestName,
[property: JsonPropertyName("Description")] string? Description,
[property: JsonPropertyName("Lot Number")] string? LotNumber,
[property: JsonPropertyName("Job Name")] string? JobName,
[property: JsonPropertyName("Process Name")] string? ProcessName,
[property: JsonPropertyName("Reasonable Limit (Upper)")] double? ReasonableLimitUpper,
[property: JsonPropertyName("Alarm Reasonable Limit (Upper)")] double? AlarmReasonableLimitUpper,
[property: JsonPropertyName("Specification Limit (Upper)")] double? SpecificationLimitUpper,
[property: JsonPropertyName("Alarm Specification Limit (Upper)")] double? AlarmSpecificationLimitUpper,
[property: JsonPropertyName("Warning Limit (Upper)")] double? WarningLimitUpper,
[property: JsonPropertyName("Alarm Warning Limit (Upper)")] double? AlarmWarningLimitUpper,
[property: JsonPropertyName("Specification Limit (Target)")] double? SpecificationLimitTarget,
[property: JsonPropertyName("Warning Limit (Lower)")] double? WarningLimitLower,
[property: JsonPropertyName("Alarm Warning Limit (Lower)")] double? AlarmWarningLimitLower,
[property: JsonPropertyName("Specification Limit (Lower)")] double? SpecificationLimitLower,
[property: JsonPropertyName("Alarm Specification Limit (Lower)")] double? AlarmSpecificationLimitLower,
[property: JsonPropertyName("Reasonable Limit (Lower)")] double? ReasonableLimitLower,
[property: JsonPropertyName("Alarm Reasonable Limit (Lower)")] double? AlarmReasonableLimitLower,
[property: JsonPropertyName("Original Test Name")] string? OriginalTestName,
[property: JsonPropertyName("Test Id")] int? TestId,
[property: JsonPropertyName("count")] int? Count);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Record[]))]
private partial class Helper20240129RecordCollectionSourceGenerationContext : JsonSerializerContext
{
}
private static List<string> GetLines(Record[] records)
{
List<string> lines = [];
lines.Add($"{nameof(Record.PartName)}\t{nameof(Record.PartRevision)}\t{nameof(Record.TestName)}\t{nameof(Record.Description)}\t{nameof(Record.LotNumber)}\t{nameof(Record.JobName)}\t{nameof(Record.ProcessName)}\t{nameof(Record.ReasonableLimitUpper)}\t{nameof(Record.AlarmReasonableLimitUpper)}\t{nameof(Record.SpecificationLimitUpper)}\t{nameof(Record.AlarmSpecificationLimitUpper)}\t{nameof(Record.WarningLimitUpper)}\t{nameof(Record.AlarmWarningLimitUpper)}\t{nameof(Record.SpecificationLimitTarget)}\t{nameof(Record.WarningLimitLower)}\t{nameof(Record.AlarmWarningLimitLower)}\t{nameof(Record.SpecificationLimitLower)}\t{nameof(Record.AlarmSpecificationLimitLower)}\t{nameof(Record.ReasonableLimitLower)}\t{nameof(Record.AlarmReasonableLimitLower)}\t{nameof(Record.OriginalTestName)}\t{nameof(Record.TestId)}\t{nameof(Record.Count)}");
foreach (Record record in records)
lines.Add($"{record.PartName}\t{record.PartRevision}\t{record.TestName}\t{record.Description}\t{record.LotNumber}\t{record.JobName}\t{record.ProcessName}\t{record.ReasonableLimitUpper}\t{record.AlarmReasonableLimitUpper}\t{record.SpecificationLimitUpper}\t{record.AlarmSpecificationLimitUpper}\t{record.WarningLimitUpper}\t{record.AlarmWarningLimitUpper}\t{record.SpecificationLimitTarget}\t{record.WarningLimitLower}\t{record.AlarmWarningLimitLower}\t{record.SpecificationLimitLower}\t{record.AlarmSpecificationLimitLower}\t{record.ReasonableLimitLower}\t{record.AlarmReasonableLimitLower}\t{record.OriginalTestName}\t{record.TestId}\t{record.Count}");
return lines;
}
private static void ConvertAndWrite(string pattern, string sourceDirectory)
{
long ticks;
string json;
string fileName;
string checkFile;
Record[]? records;
List<string> lines;
string[] files = Directory.GetFiles(sourceDirectory, pattern, SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
ticks = DateTime.Now.Ticks;
json = File.ReadAllText(file);
fileName = Path.GetFileName(file);
checkFile = Path.Combine(sourceDirectory, $"{fileName}.{ticks}.tsv");
records = JsonSerializer.Deserialize(json, Helper20240129RecordCollectionSourceGenerationContext.Default.RecordArray);
if (records is null)
continue;
lines = GetLines(records);
File.WriteAllLines(checkFile, lines);
checkFile = Path.Combine(sourceDirectory, $"{fileName}.{ticks}.done");
File.Move(file, checkFile);
Thread.Sleep(100);
}
}
internal static void JsonToTsv(ILogger<Worker> logger, List<string> args)
{
string pattern = args[2];
string sourceDirectory = args[0];
logger.LogInformation(sourceDirectory);
ConvertAndWrite(pattern, sourceDirectory);
}
}

View File

@ -0,0 +1,58 @@
using Microsoft.Extensions.Logging;
using System.Globalization;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240305
{
private static void TryArchiveFiles(string sourceDirectory, string pattern, string archiveDirectory, string days)
{
string checkFile;
FileInfo fileInfo;
string weekOfYear;
string checkDirectory;
string[] directorySegments;
Calendar calendar = new CultureInfo("en-US").Calendar;
DateTime dateTime = DateTime.Now.AddDays(-int.Parse(days));
string[] sourceDirectorySegments = sourceDirectory.Split('/');
// DirectoryInfo directoryInfo = new(Path.GetFullPath(sourceDirectory));
// IEnumerable<FileInfo> fileInfoCollection = directoryInfo.EnumerateFiles(pattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
string[] files = Directory.GetFiles(sourceDirectory, pattern, SearchOption.AllDirectories);
if (!sourceDirectory.StartsWith('\\') && sourceDirectorySegments.Length < 2)
throw new Exception("Can't be root drive!");
// foreach (FileInfo fileInfo in fileInfoCollection)
foreach (string file in files)
{
fileInfo = new FileInfo(file);
if (string.IsNullOrEmpty(fileInfo.DirectoryName) || fileInfo.LastWriteTime > dateTime)
continue;
directorySegments = fileInfo.DirectoryName.Split(Path.DirectorySeparatorChar);
if (directorySegments.Length < sourceDirectorySegments.Length)
continue;
weekOfYear = $"{fileInfo.CreationTime.Year}_Week_{calendar.GetWeekOfYear(fileInfo.CreationTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
// checkDirectory = string.Concat(archiveDirectory, Path.DirectorySeparatorChar, weekOfYear, Path.DirectorySeparatorChar, string.Join(Path.DirectorySeparatorChar, directorySegments.Skip(sourceDirectorySegments.Length)));
checkDirectory = string.Concat(archiveDirectory, Path.DirectorySeparatorChar, weekOfYear);
for (int i = sourceDirectorySegments.Length; i < directorySegments.Length; i++)
checkDirectory = string.Concat(checkDirectory, Path.DirectorySeparatorChar, directorySegments[i]);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, fileInfo.Name);
if (File.Exists(checkFile))
continue;
// File.WriteAllText(checkFile, string.Empty);
File.Move(fileInfo.FullName, checkFile);
}
}
internal static void ArchiveFiles(ILogger<Worker> logger, List<string> args)
{
string days = args[4];
string pattern = args[2];
string sourceDirectory = args[0];
string archiveDirectory = Path.GetFullPath(args[3]);
logger.LogInformation(sourceDirectory);
TryArchiveFiles(sourceDirectory, pattern, archiveDirectory, days);
}
}

View File

@ -0,0 +1,151 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240403
{
private record DynamicHostConfigurationProtocolConfiguration(string[] Columns,
string Directory,
string Ignore,
int KeyIndex,
string Pattern,
string Primary);
private static void AlertIfNewDeviceIsConnected(DynamicHostConfigurationProtocolConfiguration dynamicHostConfigurationProtocolConfiguration, ILogger<Worker> logger)
{
string[] files = Directory.GetFiles(dynamicHostConfigurationProtocolConfiguration.Directory, dynamicHostConfigurationProtocolConfiguration.Pattern, SearchOption.TopDirectoryOnly);
string? match = GetMatch(dynamicHostConfigurationProtocolConfiguration, files);
if (string.IsNullOrEmpty(match))
throw new NotSupportedException($"{dynamicHostConfigurationProtocolConfiguration.Primary} doesn't exist!");
ReadOnlyDictionary<string, int> keyToCounts = GetKeyToCounts(dynamicHostConfigurationProtocolConfiguration, files);
foreach (KeyValuePair<string, int> keyToCount in keyToCounts)
{
if (keyToCount.Value < 2)
continue;
logger.LogInformation("{Key}: {Count}", keyToCount.Key, keyToCount.Value);
}
ReadOnlyDictionary<string, ReadOnlyDictionary<string, ReadOnlyCollection<string>>> keyValuePairs = GetKeyValuePairs(dynamicHostConfigurationProtocolConfiguration, files);
foreach (KeyValuePair<string, ReadOnlyDictionary<string, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs)
{
if (!keyValuePair.Key.EndsWith(dynamicHostConfigurationProtocolConfiguration.Primary))
continue;
}
}
internal static void AlertIfNewDeviceIsConnected(ILogger<Worker> logger, List<string> args)
{
string ignore = args[6];
string pattern = args[2];
string primary = args[3];
string keyIndex = args[5];
string directory = args[0];
logger.LogInformation(directory);
string[] columns = args[4].Split('|');
DynamicHostConfigurationProtocolConfiguration dynamicHostConfigurationProtocolConfiguration = new(columns, directory, ignore, int.Parse(keyIndex), pattern, primary);
AlertIfNewDeviceIsConnected(dynamicHostConfigurationProtocolConfiguration, logger);
}
private static string? GetMatch(DynamicHostConfigurationProtocolConfiguration dynamicHostConfigurationProtocolConfiguration, string[] files)
{
string? result = null;
foreach (string file in files)
{
if (file.EndsWith(dynamicHostConfigurationProtocolConfiguration.Primary))
result = file;
}
return result;
}
private static ReadOnlyDictionary<string, int> GetKeyToCounts(DynamicHostConfigurationProtocolConfiguration dynamicHostConfigurationProtocolConfiguration, string[] files)
{
Dictionary<string, int> results = [];
bool check;
string key;
string[] lines;
string[] segments;
List<int>? collection;
Dictionary<string, List<int>> keyValuePairs = [];
int columnsLength = dynamicHostConfigurationProtocolConfiguration.Columns.Length;
foreach (string file in files)
{
check = false;
lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (line.Length < 3 || line[0] != '|' || line[^1] != '|')
continue;
segments = line.Split('|');
if (segments.Length != columnsLength)
continue;
key = segments[dynamicHostConfigurationProtocolConfiguration.KeyIndex].Trim();
if (!check)
{
if (!key.StartsWith('-') || !key.EndsWith('-'))
continue;
check = true;
continue;
}
if (key == dynamicHostConfigurationProtocolConfiguration.Ignore)
break;
if (!keyValuePairs.TryGetValue(key, out collection))
{
keyValuePairs.Add(key, []);
if (!keyValuePairs.TryGetValue(key, out collection))
throw new Exception();
}
collection.Add(1);
}
}
foreach (KeyValuePair<string, List<int>> keyValuePair in keyValuePairs.OrderByDescending(l => l.Value.Count))
results.Add(keyValuePair.Key, keyValuePair.Value.Count);
return new(results);
}
private static ReadOnlyDictionary<string, ReadOnlyDictionary<string, ReadOnlyCollection<string>>> GetKeyValuePairs(DynamicHostConfigurationProtocolConfiguration dynamicHostConfigurationProtocolConfiguration, string[] files)
{
ReadOnlyDictionary<string, ReadOnlyDictionary<string, ReadOnlyCollection<string>>> results;
bool check;
string key;
string[] lines;
string[] segments;
List<string> keys = [];
Dictionary<string, ReadOnlyCollection<string>> keyValuePairs;
Dictionary<string, ReadOnlyDictionary<string, ReadOnlyCollection<string>>> fileTo = [];
int columnsLength = dynamicHostConfigurationProtocolConfiguration.Columns.Length;
foreach (string file in files)
{
keys.Clear();
check = false;
keyValuePairs = [];
lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (line.Length < 3 || line[0] != '|' || line[^1] != '|')
continue;
segments = line.Split('|');
if (segments.Length != columnsLength)
continue;
key = segments[dynamicHostConfigurationProtocolConfiguration.KeyIndex].Trim();
if (!check)
{
if (!key.StartsWith('-') || !key.EndsWith('-'))
continue;
check = true;
continue;
}
if (key == dynamicHostConfigurationProtocolConfiguration.Ignore)
break;
if (keys.Contains(key))
throw new NotSupportedException($"{key}: is a duplicate!");
keys.Add(key);
keyValuePairs.Add(key, new(segments.Select(l => l.Trim()).ToArray()));
}
fileTo.Add(Path.GetFullPath(file), new(keyValuePairs));
}
results = new(fileTo);
return results;
}
}

View File

@ -0,0 +1,96 @@
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240404
{
private record MetaData(int DeviceId,
string DeviceType,
int DeviceNumber,
string DescriptionName,
string DescriptionTest,
string Frequency,
string Date);
private record CommaSeparatedValuesConfiguration(int Columns,
string Directory,
int TestIndex,
int RegularExpressionGroupCount,
string RegularExpressionPattern,
string SearchPattern);
private static void ParseCSV(CommaSeparatedValuesConfiguration commaSeparatedValuesConfiguration, ILogger<Worker> logger)
{
string line;
string test;
string[] lines;
string[] columns;
MetaData? metaData;
string fileNameWithoutExtension;
string[] files = Directory.GetFiles(commaSeparatedValuesConfiguration.Directory, commaSeparatedValuesConfiguration.SearchPattern, SearchOption.TopDirectoryOnly);
logger.LogInformation(files.Length.ToString());
foreach (string file in files)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
metaData = GetMetaData(commaSeparatedValuesConfiguration, fileNameWithoutExtension);
if (metaData is null)
continue;
lines = File.ReadAllLines(file);
if (lines.Length < 2)
continue;
line = lines[0];
columns = line.Split('"');
if (columns.Length != commaSeparatedValuesConfiguration.Columns)
continue;
test = columns[commaSeparatedValuesConfiguration.TestIndex].Trim().Trim('"');
if (test.IndexOf(metaData.DescriptionTest, 0, StringComparison.CurrentCultureIgnoreCase) == -1)
continue;
for (int i = 1; i < lines.Length; i++)
{
line = lines[i];
if (line.Length < 1)
continue;
columns = line.Split(',').Select(l => l.Trim().Trim('"')).ToArray();
if (columns.Length != commaSeparatedValuesConfiguration.Columns)
continue;
}
}
}
internal static void ParseCSV(ILogger<Worker> logger, List<string> args)
{
string directory = args[0];
string regularExpressionPattern = args[2];
string regularExpressionGroupCount = args[3];
string searchPattern = args[4];
string columns = args[5];
string testIndex = args[6];
logger.LogInformation(directory);
CommaSeparatedValuesConfiguration commaSeparatedValuesConfiguration = new(int.Parse(columns), directory, int.Parse(testIndex), int.Parse(regularExpressionGroupCount), regularExpressionPattern, searchPattern);
ParseCSV(commaSeparatedValuesConfiguration, logger);
}
private static MetaData? GetMetaData(CommaSeparatedValuesConfiguration commaSeparatedValuesConfiguration, string fileNameWithoutExtension)
{
MetaData? result;
Match match = Regex.Match(fileNameWithoutExtension, commaSeparatedValuesConfiguration.RegularExpressionPattern);
if (!match.Success || match.Groups.Count != commaSeparatedValuesConfiguration.RegularExpressionGroupCount)
result = null;
else
{
int deviceId = int.Parse(match.Groups["DeviceId"].Value);
int deviceNumber = int.Parse(match.Groups["DeviceNumber"].Value);
result = new(deviceId,
match.Groups["DeviceType"].Value,
deviceNumber,
match.Groups["DescriptionName"].Value,
match.Groups["DescriptionTest"].Value,
match.Groups["Frequency"].Value,
match.Groups["Date"].Value);
}
return result;
}
}

View File

@ -0,0 +1,91 @@
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240409
{
internal record FsSize( // cSpell:disable
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("object")] string Object,
[property: JsonPropertyName("pmon")] string PMon,
[property: JsonPropertyName("unit")] string Unit,
[property: JsonPropertyName("timeresolution")] string TimeResolution,
[property: JsonPropertyName("aggr")] string Aggr,
[property: JsonPropertyName("data")] List<double[]> Data
); // cSpell:restore
[JsonSourceGenerationOptions(WriteIndented = true, AllowTrailingCommas = true)]
[JsonSerializable(typeof(FsSize))]
internal partial class FsSizeSourceGenerationContext : JsonSerializerContext
{
}
internal static void MonA(ILogger<Worker> logger, List<string> args)
{
string url;
FsSize? fsSize;
string[] segments;
Task<string> json;
string jsonSection;
string urlBase = args[3];
string selector = args[6];
string urlPartA = args[4];
string urlPartC = args[5];
string directory = args[0];
string aggregation = args[8];
int skip = int.Parse(args[7]);
string searchPattern = args[2];
string fileNameWithoutExtension;
string[] ignore = args[9].Split(',');
Task<HttpResponseMessage> httpResponseMessage;
string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
HttpClient httpClient = new(new HttpClientHandler { UseCookies = false }) { BaseAddress = new Uri(urlBase) };
logger.LogInformation("{directory} has {files}(s)", directory, files.Length);
foreach (string file in files)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
if (ignore.Contains(fileNameWithoutExtension))
continue;
url = $"{httpClient.BaseAddress}{urlPartA}{fileNameWithoutExtension}{urlPartC}";
httpResponseMessage = httpClient.GetAsync(url);
httpResponseMessage.Wait();
if (!httpResponseMessage.Result.IsSuccessStatusCode)
{
logger.LogWarning("{StatusCode} for {url}", httpResponseMessage.Result.StatusCode, url);
continue;
}
json = httpResponseMessage.Result.Content.ReadAsStringAsync();
json.Wait();
if (json.Result.Length < 3)
{
logger.LogInformation("{Size} | {Julian} | {PMon} | {FileNameWithoutExtension}", -1, -1, "{}", fileNameWithoutExtension);
continue;
}
segments = json.Result.Split($"\"{fileNameWithoutExtension}{selector}");
if (segments.Length < 2)
{
logger.LogInformation("{Size} | {Julian} | {PMon} | {FileNameWithoutExtension}", -1, -1, selector, fileNameWithoutExtension);
continue;
}
for (int i = 1; i < segments.Length; i++)
{
jsonSection = segments[i][skip..][..^1];
fsSize = JsonSerializer.Deserialize(jsonSection, FsSizeSourceGenerationContext.Default.FsSize);
if (fsSize is null)
continue;
if (fsSize.Aggr != aggregation)
continue;
if (fsSize.Data.Count == 0 || fsSize.Data[0].Length == 0)
{
logger.LogInformation("{Size} | {Julian} | {PMon} | {FileNameWithoutExtension}", -1, -1, nameof(FsSize.Data), fileNameWithoutExtension);
continue;
}
logger.LogInformation("{Size} | {Julian} | {PMon} | {FileNameWithoutExtension}", fsSize.Data[0][1].ToString().PadLeft(20, '0'), fsSize.Data[0][0], fsSize.PMon, fileNameWithoutExtension);
}
}
}
}

View File

@ -0,0 +1,62 @@
using File_Folder_Helper.Helpers;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240417
{
private static void RunCommand(ILogger<Worker> logger, string directory, string commandFileName, List<string> files, int before, CancellationToken cancellationToken)
{
bool usePathCombine = false;
string command = $"npx eclint fix {string.Join(' ', files)}";
string output = HelperNPM.RunCommand(commandFileName, command, directory);
logger.LogInformation(output);
if (output.Contains("error", StringComparison.OrdinalIgnoreCase))
{
Environment.ExitCode = 2;
logger.LogCritical("Setting exit code {ExitCode}", Environment.ExitCode);
throw new Exception(output);
}
ReadOnlyCollection<string> afterGitOthersModifiedAndDeletedExcludingStandardFiles = HelperGit.GetOthersModifiedAndDeletedExcludingStandardFiles(directory, usePathCombine, cancellationToken);
int after = afterGitOthersModifiedAndDeletedExcludingStandardFiles.Count;
if (before != after)
{
List<string> fileNames = [];
foreach (string file in afterGitOthersModifiedAndDeletedExcludingStandardFiles)
{
if (file.Contains(' '))
continue;
if (files.Contains(file))
continue;
fileNames.Add(Path.GetFileName(file));
}
Environment.ExitCode = 1;
throw new Exception($"Files were modified exiting with exit code {Environment.ExitCode}!{Environment.NewLine}{string.Join(Environment.NewLine, fileNames)}");
}
}
internal static void FilteredRunCommand(ILogger<Worker> logger, List<string> args, CancellationToken cancellationToken)
{
List<string> files = [];
string directory = args[0];
bool usePathCombine = false;
string commandFileName = args[2];
ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles = HelperGit.GetOthersModifiedAndDeletedExcludingStandardFiles(directory, usePathCombine, cancellationToken);
int before = gitOthersModifiedAndDeletedExcludingStandardFiles.Count;
foreach (string file in gitOthersModifiedAndDeletedExcludingStandardFiles)
{
if (file.Contains(' '))
{
logger.LogInformation("Skipping <{File}>", file);
continue;
}
files.Add(file);
}
logger.LogInformation("{directory} has {files} file(s)", directory, before);
if (files.Count > 0)
RunCommand(logger, directory, commandFileName, files, before, cancellationToken);
}
}

View File

@ -0,0 +1,93 @@
using Microsoft.Extensions.Logging;
using System.Text;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240426
{
private static void Write(string toA, string toB, string matchA, string matchB, string file, List<string> lines)
{
StringBuilder stringBuilder = new();
foreach (string line in lines)
_ = stringBuilder.AppendLine(line.Replace(matchB, toB));
string checkFile = file.Replace(matchA, toA);
_ = Directory.CreateDirectory(Path.GetDirectoryName(checkFile) ?? throw new NullReferenceException());
if (!File.Exists(checkFile))
File.WriteAllText(checkFile, stringBuilder.ToString());
}
private static void UpdateTestFiles(ILogger<Worker> logger, string to, string match, string staticDirectoryName, List<string> files)
{
List<string> lines;
string directoryName;
string fistLineCheck;
string lastLineCheck = "#endif";
foreach (string file in files)
{
directoryName = Path.GetFileName(Path.GetDirectoryName(file) ?? throw new NullReferenceException(nameof(directoryName)));
if (directoryName == staticDirectoryName)
continue;
lines = File.ReadAllLines(file).ToList();
if (directoryName == match)
Write(to, to.Replace('.', '_'), match, match.Replace('.', '_'), file, lines);
if (lines.Count < 3)
continue;
fistLineCheck = $"#if {directoryName.Replace('.', '_')}";
if (lines[0].StartsWith("#if true") || lines[0].StartsWith(fistLineCheck))
continue;
for (int i = lines.Count - 1; i > 0; i--)
{
if (!string.IsNullOrEmpty(lines[i]))
break;
lines.RemoveAt(i);
}
if (lines[^1].StartsWith(lastLineCheck))
continue;
if (lines.All(l => string.IsNullOrEmpty(l) || l.StartsWith("//")))
continue;
lines.Add(lastLineCheck);
lines.Insert(0, fistLineCheck);
File.WriteAllText(file, string.Join(Environment.NewLine, lines));
logger.LogDebug(file);
}
}
private static void UpdateProjectTests(ILogger<Worker> logger, string to, string match, string searchPattern, string staticDirectoryName, string extractDirectoryName, string createSelfDescriptionDirectoryName, string sourceCodeDirectory)
{
List<string> files = [];
List<string> knownDirectories = [];
knownDirectories.AddRange(Directory.GetDirectories(sourceCodeDirectory, createSelfDescriptionDirectoryName, SearchOption.AllDirectories));
knownDirectories.AddRange(Directory.GetDirectories(sourceCodeDirectory, extractDirectoryName, SearchOption.AllDirectories));
knownDirectories.AddRange(Directory.GetDirectories(sourceCodeDirectory, staticDirectoryName, SearchOption.AllDirectories));
foreach (string knownDirectory in knownDirectories)
files.AddRange(Directory.GetFiles(knownDirectory, searchPattern, SearchOption.AllDirectories));
logger.LogInformation("{directory} has {files} file(s)", sourceCodeDirectory, files.Count);
UpdateTestFiles(logger, to, match, staticDirectoryName, files);
}
internal static void UpdateTests(ILogger<Worker> logger, List<string> args)
{
string to = args[9];
string match = args[8];
string searchPattern = args[7];
string[] sourceCodeDirectories;
string staticDirectoryName = args[6];
string extractDirectoryName = args[5];
string sourceCodeDirectoryName = args[3];
string directory = Path.GetFullPath(args[0]);
string createSelfDescriptionDirectoryName = args[4];
string systemVolumeInformation = Path.Combine(directory, args[2]);
string[] subDirectories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string subDirectory in subDirectories)
{
if (subDirectory == systemVolumeInformation)
continue;
sourceCodeDirectories = Directory.GetDirectories(subDirectory, sourceCodeDirectoryName, SearchOption.AllDirectories);
if (sourceCodeDirectories.Length != 1)
continue;
UpdateProjectTests(logger, to, match, searchPattern, staticDirectoryName, extractDirectoryName, createSelfDescriptionDirectoryName, sourceCodeDirectories[0]);
}
}
}

View File

@ -0,0 +1,146 @@
using File_Folder_Helper.Helpers;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.ADO2024.PI1;
internal static partial class Helper20240427
{
internal record Asset( // cSpell:disable
[property: JsonPropertyName("id")] string? Id,
[property: JsonPropertyName("deviceAssetId")] string? DeviceAssetId,
[property: JsonPropertyName("ownerId")] string? OwnerId,
[property: JsonPropertyName("deviceId")] string? DeviceId,
[property: JsonPropertyName("type")] string? Type,
[property: JsonPropertyName("originalPath")] string? OriginalPath,
[property: JsonPropertyName("previewPath")] string? PreviewPath,
[property: JsonPropertyName("fileCreatedAt")] DateTime? FileCreatedAt,
[property: JsonPropertyName("fileModifiedAt")] DateTime? FileModifiedAt,
[property: JsonPropertyName("isFavorite")] bool? IsFavorite,
[property: JsonPropertyName("duration")] object? Duration,
[property: JsonPropertyName("thumbnailPath")] string? ThumbnailPath,
[property: JsonPropertyName("encodedVideoPath")] string? EncodedVideoPath,
[property: JsonPropertyName("checksum")] string? Checksum,
[property: JsonPropertyName("isVisible")] bool? IsVisible,
[property: JsonPropertyName("livePhotoVideoId")] object? LivePhotoVideoId,
[property: JsonPropertyName("updatedAt")] DateTime? UpdatedAt,
[property: JsonPropertyName("createdAt")] DateTime? CreatedAt,
[property: JsonPropertyName("isArchived")] bool? IsArchived,
[property: JsonPropertyName("originalFileName")] string? OriginalFileName,
[property: JsonPropertyName("sidecarPath")] string? SidecarPath,
[property: JsonPropertyName("isReadOnly")] bool? IsReadOnly,
[property: JsonPropertyName("thumbhash")] string? Thumbhash,
[property: JsonPropertyName("isOffline")] bool? IsOffline,
[property: JsonPropertyName("libraryId")] string? LibraryId,
[property: JsonPropertyName("isExternal")] bool? IsExternal,
[property: JsonPropertyName("deletedAt")] DateTime? DeletedAt,
[property: JsonPropertyName("localDateTime")] DateTime? LocalDateTime,
[property: JsonPropertyName("stackId")] object? StackId); // cSpell:restore
[JsonSourceGenerationOptions(WriteIndented = true, AllowTrailingCommas = true)]
[JsonSerializable(typeof(List<Asset>))]
internal partial class AssetCollectionSourceGenerationContext : JsonSerializerContext
{
}
private static string? MoveAsset(string home, string originalFileName, string lastVarDirectoryName, string path)
{
string? result;
string checkFile;
string sourceFile;
int? match = null;
string checkDirectory = home;
string sourceDirectory = home;
string originalFileNameWithoutExtension = Path.GetFileNameWithoutExtension(originalFileName);
ReadOnlyCollection<string> directoryNames = HelperDirectory.GetDirectoryNames(path);
for (int i = 0; i < directoryNames.Count; i++)
{
if (directoryNames[i] != lastVarDirectoryName)
continue;
match = i;
break;
}
if (match is null)
result = null;
else
{
string[] fileNameSegments = directoryNames[^1].Split('-');
foreach (string directory in directoryNames.Skip(match.Value + 1).Take(directoryNames.Count - match.Value - 2))
sourceDirectory = Path.Combine(sourceDirectory, directory);
if (!Directory.Exists(sourceDirectory))
result = null;
else
{
sourceFile = Path.Combine(sourceDirectory, directoryNames[^1]);
if (!File.Exists(sourceFile))
result = null;
else
{
foreach (string directory in directoryNames.Skip(match.Value + 1).Take(directoryNames.Count - match.Value - 2))
checkDirectory = Path.Combine(checkDirectory, directory);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, $"{originalFileNameWithoutExtension}{fileNameSegments[^1]}");
if (File.Exists(checkFile))
result = null;
else
{
File.Move(sourceFile, checkFile);
result = checkFile;
}
}
}
}
return result;
}
private static void MoveAssets(ILogger<Worker> logger, string var, string home, string pictures, List<Asset> assets)
{
string? checkFile;
ReadOnlyCollection<string> varDirectoryNames = HelperDirectory.GetDirectoryNames(home);
string lastVarDirectoryName = varDirectoryNames[^1];
foreach (Asset asset in assets)
{
if (asset.OriginalFileName is null)
continue;
if (asset.Type is null or not "IMAGE")
continue;
if (asset.PreviewPath is null || !asset.PreviewPath.StartsWith(var))
continue;
if (asset.ThumbnailPath is null || !asset.ThumbnailPath.StartsWith(var))
continue;
if (asset.OriginalPath is null || !asset.OriginalPath.StartsWith(pictures))
continue;
checkFile = MoveAsset(home, asset.OriginalFileName, lastVarDirectoryName, asset.PreviewPath);
if (checkFile is null)
continue;
checkFile = MoveAsset(home, asset.OriginalFileName, lastVarDirectoryName, asset.ThumbnailPath);
if (checkFile is null)
continue;
logger.LogDebug("<{OriginalFileName}> moved.", asset.OriginalFileName);
}
}
#pragma warning restore IDE0055, IDE0059, IDE0060, IDE2000, CS0168
internal static void Immich(Models.AppSettings appSettings, ILogger<Worker> logger, List<string> args)
{
string var = args[5];
string home = args[6];
string query = args[3];
string jsonFile = args[4];
string pictures = args[7];
string directory = args[0];
logger.LogInformation(query);
string databasePassword = args[2];
string json = File.ReadAllText(Path.Combine(directory, jsonFile));
List<Asset> assets = JsonSerializer.Deserialize(json, AssetCollectionSourceGenerationContext.Default.ListAsset) ?? throw new NullReferenceException();
string encryptedPassword = RijndaelEncryption.Encrypt(databasePassword, appSettings.Company);
MoveAssets(logger, var, home, pictures, assets);
logger.LogInformation("Encrypted Password: [{EncryptedPassword}]", encryptedPassword);
}
}