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

View File

@ -34,85 +34,85 @@ internal static class HelperDay
else if (args[1] == "Day-Helper-2023-12-22")
Day.Q42023.Helper20231222.ConvertId(logger, args);
else if (args[1] == "Day-Helper-2024-01-05")
Day.Q12024.Helper20240105.ConvertKeePassExport(logger, args);
ADO2024.PI1.Helper20240105.ConvertKeePassExport(logger, args);
else if (args[1] == "Day-Helper-2024-01-06")
Day.Q12024.Helper20240106.TextToJson(logger, args);
ADO2024.PI1.Helper20240106.TextToJson(logger, args);
else if (args[1] == "Day-Helper-2024-01-07")
Day.Q12024.Helper20240107.DirectoryToISO(logger, args);
ADO2024.PI1.Helper20240107.DirectoryToISO(logger, args);
else if (args[1] == "Day-Helper-2024-01-08")
Day.Q12024.Helper20240108.SortCodeMethods(logger, args, cancellationToken);
ADO2024.PI1.Helper20240108.SortCodeMethods(logger, args, cancellationToken);
else if (args[1] == "Day-Helper-2024-01-27")
logger.LogError("{arg} - has been migrated to Clipboard_Send_Keys", args[1]);
else if (args[1] == "Day-Helper-2024-01-29")
Day.Q12024.Helper20240129.JsonToTsv(logger, args);
ADO2024.PI1.Helper20240129.JsonToTsv(logger, args);
else if (args[1] == "Day-Helper-2024-03-05")
Day.Q12024.Helper20240305.ArchiveFiles(logger, args);
ADO2024.PI1.Helper20240305.ArchiveFiles(logger, args);
else if (args[1] == "Day-Helper-2024-04-03")
Day.Q22024.Helper20240403.AlertIfNewDeviceIsConnected(logger, args);
ADO2024.PI1.Helper20240403.AlertIfNewDeviceIsConnected(logger, args);
else if (args[1] == "Day-Helper-2024-04-04")
Day.Q22024.Helper20240404.ParseCSV(logger, args);
ADO2024.PI1.Helper20240404.ParseCSV(logger, args);
else if (args[1] == "Day-Helper-2024-04-09")
Day.Q22024.Helper20240409.MonA(logger, args);
ADO2024.PI1.Helper20240409.MonA(logger, args);
else if (args[1] == "Day-Helper-2024-04-17")
Day.Q22024.Helper20240417.FilteredRunCommand(logger, args, cancellationToken);
ADO2024.PI1.Helper20240417.FilteredRunCommand(logger, args, cancellationToken);
else if (args[1] == "Day-Helper-2024-04-26")
Day.Q22024.Helper20240426.UpdateTests(logger, args);
ADO2024.PI1.Helper20240426.UpdateTests(logger, args);
else if (args[1] == "Day-Helper-2024-04-27")
Day.Q22024.Helper20240427.Immich(appSettings, logger, args);
ADO2024.PI1.Helper20240427.Immich(appSettings, logger, args);
else if (args[1] == "Day-Helper-2024-04-29")
Day.Q22024.Helper20240429.GitConfigCleanUp(logger, args);
ADO2024.PI2.Helper20240429.GitConfigCleanUp(logger, args);
else if (args[1] == "Day-Helper-2024-05-10")
Day.Q22024.Helper20240510.PullIconsForBLM(logger, args);
ADO2024.PI2.Helper20240510.PullIconsForBLM(logger, args);
else if (args[1] == "Day-Helper-2024-05-13")
Day.Q22024.Helper20240513.PersonKeyToName(logger, args);
ADO2024.PI2.Helper20240513.PersonKeyToName(logger, args);
else if (args[1] == "Day-Helper-2024-05-17")
Day.Q22024.Helper20240517.SaveAmazon(logger, args);
ADO2024.PI2.Helper20240517.SaveAmazon(logger, args);
else if (args[1] == "Day-Helper-2024-05-18")
Day.Q22024.Helper20240518.PersonKeyToImmichImport(logger, args);
ADO2024.PI2.Helper20240518.PersonKeyToImmichImport(logger, args);
else if (args[1] == "Day-Helper-2024-05-19")
Day.Q22024.Helper20240519.FindReplaceDirectoryName(logger, args);
ADO2024.PI2.Helper20240519.FindReplaceDirectoryName(logger, args);
else if (args[1] == "Day-Helper-2024-05-20")
Day.Q22024.Helper20240520.IdentifierRename(logger, args);
ADO2024.PI2.Helper20240520.IdentifierRename(logger, args);
else if (args[1] == "Day-Helper-2024-06-23")
Day.Q22024.Helper20240623.UpdateSubTasksInMarkdownFiles(logger, args);
ADO2024.PI2.Helper20240623.UpdateSubTasksInMarkdownFiles(logger, args);
else if (args[1] == "Day-Helper-2024-06-24")
Day.Q22024.Helper20240624.MoveUpOneDirectory(logger, args);
ADO2024.PI2.Helper20240624.MoveUpOneDirectory(logger, args);
else if (args[1] == "Day-Helper-2024-07-11")
Day.Q32024.Helper20240711.GitRemoteRemove(logger, args);
ADO2024.PI2.Helper20240711.GitRemoteRemove(logger, args);
else if (args[1] == "Day-Helper-2024-07-18")
Day.Q32024.Helper20240718.JsonToMarkdown(logger, args);
ADO2024.PI2.Helper20240718.JsonToMarkdown(logger, args);
else if (args[1] == "Day-Helper-2024-07-24")
Day.Q32024.Helper20240724.CopyDirectories(logger, args);
ADO2024.PI2.Helper20240724.CopyDirectories(logger, args);
else if (args[1] == "Day-Helper-2024-07-28")
Day.Q32024.Helper20240728.DownloadSslCertificates(logger, args);
ADO2024.PI2.Helper20240728.DownloadSslCertificates(logger, args);
else if (args[1] == "Day-Helper-2024-08-05")
Day.Q32024.Helper20240805.RenameFiles(logger, args);
ADO2024.PI3.Helper20240805.RenameFiles(logger, args);
else if (args[1] == "Day-Helper-2024-08-06")
Day.Q32024.Helper20240806.ArchiveFiles(logger, args);
ADO2024.PI3.Helper20240806.ArchiveFiles(logger, args);
#if WorkItems
else if (args[1] == "Day-Helper-2024-08-09")
Day.Q32024.Helper20240809.CreateWorkItems(logger, args);
ADO2024.PI3.Helper20240809.CreateWorkItems(logger, args);
#endif
else if (args[1] == "Day-Helper-2024-08-20")
Day.Q32024.Helper20240820.MoveFilesWithSleep(logger, args);
ADO2024.PI3.Helper20240820.MoveFilesWithSleep(logger, args);
else if (args[1] == "Day-Helper-2024-08-22")
Day.Q32024.Helper20240822.ParseKanbn(logger, args);
ADO2024.PI3.Helper20240822.ParseKanbn(logger, args);
else if (args[1] == "Day-Helper-2024-08-28")
Day.Q32024.Helper20240828.MoveWaferCounterToArchive(logger, args);
ADO2024.PI3.Helper20240828.MoveWaferCounterToArchive(logger, args);
#if WorkItems
else if (args[1] == "Day-Helper-2024-08-30")
Day.Q32024.Helper20240830.CompareWorkItems(logger, args);
ADO2024.PI3.Helper20240830.CompareWorkItems(logger, args);
#endif
else if (args[1] == "Day-Helper-2024-09-10")
Day.Q32024.Helper20240910.MoveFilesToWeekOfYear(logger, args);
ADO2024.PI3.Helper20240910.MoveFilesToWeekOfYear(logger, args);
else if (args[1] == "Day-Helper-2024-09-11")
Day.Q32024.Helper20240911.WriteMarkdown(logger, args);
ADO2024.PI3.Helper20240911.WriteMarkdown(logger, args);
else if (args[1] == "Day-Helper-2024-09-16")
Day.Q32024.Helper20240916.DebugProxyPass(logger, args);
ADO2024.PI3.Helper20240916.DebugProxyPass(logger, args);
else if (args[1] == "Day-Helper-2024-09-25")
Day.Q32024.Helper20240925.DistinctTests(logger, args);
ADO2024.PI3.Helper20240925.DistinctTests(logger, args);
else if (args[1] == "Day-Helper-2024-10-02")
Day.Q42024.Helper20241002.ConvertInfinityQSProjectFiles(logger, args);
ADO2024.PI3.Helper20241002.ConvertInfinityQSProjectFiles(logger, args);
else
throw new Exception(appSettings.Company);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,236 +0,0 @@
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.Day.Q12024;
internal static partial class Helper20240106
{
private record Record(string Key, Dictionary<string, string> KeyValuePairs);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Dictionary<string, Dictionary<string, string>>))]
private partial class DictionaryDictionarySourceGenerationContext : JsonSerializerContext
{
}
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 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 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 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);
}
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

@ -1,50 +0,0 @@
using DiscUtils.Iso9660;
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.Day.Q12024;
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

@ -1,299 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.Day.Q12024;
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

@ -1,83 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q12024;
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

@ -1,58 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Globalization;
namespace File_Folder_Helper.Day.Q12024;
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

@ -1,151 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.Day.Q22024;
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

@ -1,96 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.Day.Q22024;
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

@ -1,91 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q22024;
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

@ -1,62 +0,0 @@
using File_Folder_Helper.Helpers;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.Day.Q22024;
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

@ -1,93 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Text;
namespace File_Folder_Helper.Day.Q22024;
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

@ -1,146 +0,0 @@
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.Day.Q22024;
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);
}
}

View File

@ -1,56 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Diagnostics;
namespace File_Folder_Helper.Day.Q22024;
internal static partial class Helper20240429
{
internal static void GitConfigCleanUp(ILogger<Worker> logger, List<string> args)
{
string[] files;
Process? process;
string? directory;
string standardError;
string ignoreError = args[5];
string searchPattern = args[3];
ProcessStartInfo processStartInfo;
string root = Path.GetFullPath(args[0]);
string[] removeRemotes = args[4].Split(',');
string systemVolumeInformation = Path.Combine(root, args[2]);
string[] subDirectories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly);
foreach (string subDirectory in subDirectories)
{
if (subDirectory == systemVolumeInformation)
continue;
files = Directory.GetFiles(subDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files)
{
directory = Path.GetDirectoryName(file);
if (directory is null)
continue;
foreach (string removeRemote in removeRemotes)
{
processStartInfo = new()
{
FileName = "git",
WorkingDirectory = directory,
Arguments = $"remote rm {removeRemote}",
RedirectStandardError = true
};
process = Process.Start(processStartInfo);
if (process is null)
continue;
#pragma warning disable IDE0058
process.WaitForExit(7000);
#pragma warning restore IDE0058
standardError = process.StandardError.ReadToEnd();
if (!standardError.Contains(ignoreError))
logger.LogInformation(standardError);
logger.LogInformation("for <{directoryName}> remote rm {removeRemote}", directory, removeRemote);
}
}
}
}
}

View File

@ -1,34 +0,0 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.Day.Q22024;
internal static partial class Helper20240510
{
internal static void PullIconsForBLM(ILogger<Worker> logger, List<string> args)
{
string fileName;
FileInfo fileInfo;
string searchPattern = args[4];
string sourceDirectory = args[3];
string root = Path.GetFullPath(args[0]);
string createDirectory = Path.Combine(root, args[2]);
if (!Directory.Exists(createDirectory))
_ = Directory.CreateDirectory(createDirectory);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
fileName = Path.GetFileName(file);
fileInfo = new(Path.Combine(createDirectory, fileName));
if (fileInfo.Exists && fileInfo.LastWriteTime == new FileInfo(file).LastWriteTime)
continue;
File.Copy(file, fileInfo.FullName, overwrite: true);
logger.LogInformation("<{fileName}> copied", fileName);
}
logger.LogWarning("What reactor is this near?");
string? reactor = Console.ReadLine();
if (!string.IsNullOrEmpty(reactor))
_ = Directory.CreateDirectory(Path.Combine(sourceDirectory, Environment.MachineName, reactor));
}
}

View File

@ -1,39 +0,0 @@
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace File_Folder_Helper.Day.Q22024;
internal static partial class Helper20240513
{
internal static void PersonKeyToName(ILogger<Worker> logger, List<string> args)
{
Person? person;
string directoryName;
string checkDirectory;
string root = Path.GetFullPath(args[0]);
string json = File.ReadAllText(args[2]);
Dictionary<string, Person> keyValuePairs = [];
string[] directories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly);
Dictionary<long, Person> people = JsonSerializer.Deserialize(json, PeopleSourceGenerationContext.Default.DictionaryInt64Person) ?? throw new NullReferenceException();
foreach (KeyValuePair<long, Person> keyValuePair in people)
{
if (keyValuePair.Value.Birth?.Note is null)
continue;
keyValuePairs.Add(keyValuePair.Value.Birth.Note, keyValuePair.Value);
}
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (!keyValuePairs.TryGetValue(directoryName, out person) || person.Name?.ForwardSlashFull is null)
continue;
checkDirectory = Path.Combine(root, $"{person.Name.ForwardSlashFull.Replace('/', '-')}{directoryName}-{person.Id}");
if (Directory.Exists(checkDirectory))
continue;
Directory.Move(directory, checkDirectory);
logger.LogInformation("<{directory}> was moved", directory);
}
}
}

View File

@ -1,334 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q22024;
internal static partial class Helper20240517
{
public record ContentSignature([property: JsonPropertyName("contentSignature")] string Value,
[property: JsonPropertyName("contentSignatureType")] string ContentSignatureType);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ContentSignature))]
public partial class ContentSignatureGenerationContext : JsonSerializerContext
{
}
public record Type([property: JsonPropertyName("count")] int Count,
[property: JsonPropertyName("match")] string Match,
[property: JsonPropertyName("searchData")] SearchData SearchData);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Type))]
public partial class TypeGenerationContext : JsonSerializerContext
{
}
public record ImageAmazon([property: JsonPropertyName("colorSpace")] string ColorSpace,
[property: JsonPropertyName("dateTime")] DateTime DateTime,
[property: JsonPropertyName("dateTimeDigitized")] DateTime DateTimeDigitized,
[property: JsonPropertyName("dateTimeOriginal")] DateTime DateTimeOriginal,
[property: JsonPropertyName("exposureMode")] string ExposureMode,
[property: JsonPropertyName("exposureProgram")] string ExposureProgram,
[property: JsonPropertyName("exposureTime")] string ExposureTime,
[property: JsonPropertyName("flash")] string Flash,
[property: JsonPropertyName("focalLength")] string FocalLength,
[property: JsonPropertyName("height")] int Height,
[property: JsonPropertyName("make")] string Make,
[property: JsonPropertyName("meteringMode")] string MeteringMode,
[property: JsonPropertyName("model")] string Model,
[property: JsonPropertyName("orientation")] string Orientation,
[property: JsonPropertyName("resolutionUnit")] string ResolutionUnit,
[property: JsonPropertyName("sensingMethod")] string SensingMethod,
[property: JsonPropertyName("sharpness")] string Sharpness,
[property: JsonPropertyName("software")] string Software,
[property: JsonPropertyName("subSecTime")] string SubSecTime,
[property: JsonPropertyName("subSecTimeDigitized")] string SubSecTimeDigitized,
[property: JsonPropertyName("subSecTimeOriginal")] string SubSecTimeOriginal,
[property: JsonPropertyName("whiteBalance")] string WhiteBalance,
[property: JsonPropertyName("width")] int Width,
[property: JsonPropertyName("apertureValue")] string ApertureValue);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ImageAmazon))]
public partial class ImageAmazonGenerationContext : JsonSerializerContext
{
}
public record ContentProperties([property: JsonPropertyName("contentDate")] DateTime ContentDate,
[property: JsonPropertyName("contentSignatures")] IReadOnlyList<ContentSignature> ContentSignatures,
[property: JsonPropertyName("contentType")] string ContentType,
[property: JsonPropertyName("extension")] string Extension,
[property: JsonPropertyName("image")] ImageAmazon Image,
[property: JsonPropertyName("md5")] string Md5,
[property: JsonPropertyName("size")] int Size,
[property: JsonPropertyName("version")] int Version);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ContentProperties))]
public partial class ContentPropertiesGenerationContext : JsonSerializerContext
{
}
public record XAccntParentMap();
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(XAccntParentMap))]
public partial class XAccntParentMapGenerationContext : JsonSerializerContext
{
}
public record Datum([property: JsonPropertyName("accessRuleIds")] IReadOnlyList<object> AccessRuleIds,
[property: JsonPropertyName("childAssetTypeInfo")] IReadOnlyList<object> ChildAssetTypeInfo,
[property: JsonPropertyName("contentProperties")] ContentProperties ContentProperties,
[property: JsonPropertyName("createdBy")] string CreatedBy,
[property: JsonPropertyName("createdDate")] DateTime CreatedDate,
[property: JsonPropertyName("eTagResponse")] string ETagResponse,
[property: JsonPropertyName("groupPermissions")] IReadOnlyList<object> GroupPermissions,
[property: JsonPropertyName("id")] string Id,
[property: JsonPropertyName("isRoot")] bool IsRoot,
[property: JsonPropertyName("isShared")] bool IsShared,
[property: JsonPropertyName("keywords")] IReadOnlyList<object> Keywords,
[property: JsonPropertyName("kind")] string Kind,
[property: JsonPropertyName("labels")] IReadOnlyList<object> Labels,
[property: JsonPropertyName("modifiedDate")] DateTime ModifiedDate,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("ownerId")] string OwnerId,
[property: JsonPropertyName("parentMap")] ParentMap ParentMap,
[property: JsonPropertyName("parents")] IReadOnlyList<string> Parents,
[property: JsonPropertyName("protectedFolder")] bool ProtectedFolder,
[property: JsonPropertyName("restricted")] bool Restricted,
[property: JsonPropertyName("status")] string Status,
[property: JsonPropertyName("subKinds")] IReadOnlyList<object> SubKinds,
[property: JsonPropertyName("transforms")] IReadOnlyList<string> Transforms,
[property: JsonPropertyName("version")] int Version,
[property: JsonPropertyName("xAccntParentMap")] XAccntParentMap XAccntParentMap,
[property: JsonPropertyName("xAccntParents")] IReadOnlyList<object> XAccntParents,
[property: JsonPropertyName("match")] bool? Match);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Datum))]
public partial class DatumGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Dictionary<string, Datum>))]
public partial class DictionaryDatumGenerationContext : JsonSerializerContext
{
}
public record LocationAmazon([property: JsonPropertyName("count")] int Count,
[property: JsonPropertyName("match")] string Match,
[property: JsonPropertyName("searchData")] SearchData SearchData);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(LocationAmazon))]
public partial class LocationAmazonGenerationContext : JsonSerializerContext
{
}
public record LocationInfo([property: JsonPropertyName("city")] string City,
[property: JsonPropertyName("country")] string Country,
[property: JsonPropertyName("countryIso3Code")] string CountryIso3Code,
[property: JsonPropertyName("state")] string State,
[property: JsonPropertyName("stateCode")] string StateCode);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(LocationInfo))]
public partial class LocationInfoGenerationContext : JsonSerializerContext
{
}
public record SearchData([property: JsonPropertyName("clusterName")] string ClusterName,
[property: JsonPropertyName("locationId")] string LocationId,
[property: JsonPropertyName("locationInfo")] LocationInfo LocationInfo,
[property: JsonPropertyName("thingId")] string ThingId);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(SearchData))]
public partial class SearchDataGenerationContext : JsonSerializerContext
{
}
public record AllPerson([property: JsonPropertyName("count")] int Count,
[property: JsonPropertyName("match")] string Match,
[property: JsonPropertyName("searchData")] SearchData SearchData);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(AllPerson))]
public partial class AllPersonGenerationContext : JsonSerializerContext
{
}
public record PersonAmazon([property: JsonPropertyName("count")] int Count,
[property: JsonPropertyName("match")] string Match,
[property: JsonPropertyName("searchData")] SearchData SearchData);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(PersonAmazon))]
public partial class PersonAmazonGenerationContext : JsonSerializerContext
{
}
public record ClusterId([property: JsonPropertyName("count")] int Count,
[property: JsonPropertyName("match")] string Match,
[property: JsonPropertyName("searchData")] SearchData SearchData);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ClusterId))]
public partial class ClusterIdGenerationContext : JsonSerializerContext
{
}
public record Thing([property: JsonPropertyName("count")] int Count,
[property: JsonPropertyName("match")] string Match,
[property: JsonPropertyName("searchData")] SearchData SearchData);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Thing))]
public partial class ThingGenerationContext : JsonSerializerContext
{
}
public record Time([property: JsonPropertyName("count")] int Count,
[property: JsonPropertyName("match")] string Match,
[property: JsonPropertyName("searchData")] SearchData SearchData);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Time))]
public partial class TimeGenerationContext : JsonSerializerContext
{
}
public record ParentMap([property: JsonPropertyName("FOLDER")] IReadOnlyList<string> FOLDER);
public record Aggregations([property: JsonPropertyName("allPeople")] IReadOnlyList<AllPerson> AllPeople,
[property: JsonPropertyName("clusterId")] IReadOnlyList<ClusterId> ClusterId,
[property: JsonPropertyName("location")] IReadOnlyList<LocationAmazon> Location,
[property: JsonPropertyName("people")] IReadOnlyList<PersonAmazon> People,
[property: JsonPropertyName("things")] IReadOnlyList<Thing> Things,
[property: JsonPropertyName("time")] IReadOnlyList<Time> Time,
[property: JsonPropertyName("type")] IReadOnlyList<Type> Type);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Aggregations))]
public partial class AggregationsGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ParentMap))]
public partial class ParentMapGenerationContext : JsonSerializerContext
{
}
public record RootAmazon([property: JsonPropertyName("aggregations")] Aggregations Aggregations,
[property: JsonPropertyName("count")] int Count,
[property: JsonPropertyName("data")] IReadOnlyList<Datum> Data);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(RootAmazon))]
public partial class RootAmazonGenerationContext : JsonSerializerContext
{
}
private static void SaveAmazon(string destination, string harFile)
{
string offset;
string personId;
RootAmazon amazon;
string? personName;
string personIdFile;
string personDirectory;
PersonAmazon personAmazon;
Dictionary<string, string> keyValuePairs = [];
ReadOnlyCollection<(string Url, string AggregationLine)> aggregationLines = GetAggregationLines(harFile);
foreach ((string url, string aggregationLine) in aggregationLines)
{
if (aggregationLine.Contains(",\"category\":\"allPeople\"}"))
continue;
amazon = JsonSerializer.Deserialize(aggregationLine, RootAmazonGenerationContext.Default.RootAmazon) ?? throw new Exception();
if (amazon.Aggregations?.People is null || amazon.Aggregations.People.Count < 1)
continue;
personAmazon = amazon.Aggregations.People[0];
if (!url.Contains(personAmazon.Match))
continue;
personDirectory = Path.Combine(destination, personAmazon.SearchData.ClusterName);
_ = Directory.CreateDirectory(personDirectory);
personIdFile = Path.Combine(personDirectory, $"000) {personAmazon.Match}.json");
_ = keyValuePairs.TryAdd(personAmazon.Match, personAmazon.SearchData.ClusterName);
SaveAmazon(amazon.Data, personIdFile);
}
foreach ((string url, string aggregationLine) in aggregationLines)
{
if (aggregationLine.Contains(",\"category\":\"allPeople\"}"))
continue;
amazon = JsonSerializer.Deserialize(aggregationLine, RootAmazonGenerationContext.Default.RootAmazon) ?? throw new Exception();
if (amazon.Aggregations?.People is not null && amazon.Aggregations.People.Count > 0)
continue;
if (!url.Contains("offset="))
continue;
offset = url.Split("offset=")[1];
if (!url.Contains("people%3A("))
continue;
personId = url.Split("people%3A(")[1].Split(')')[0];
if (!keyValuePairs.TryGetValue(personId, out personName))
continue;
personDirectory = Path.Combine(destination, personName);
_ = Directory.CreateDirectory(personDirectory);
personIdFile = Path.Combine(personDirectory, $"{offset.Split('&')[0]}) {personId}.json");
SaveAmazon(amazon.Data, personIdFile);
}
}
internal static void SaveAmazon(ILogger<Worker> logger, List<string> args)
{
string root = Path.GetFullPath(args[0]);
string destination = Path.GetFullPath(args[2]);
if (string.IsNullOrEmpty(root))
throw new NullReferenceException(nameof(root));
string[] harFiles = Directory.GetFiles(root, "*.har", SearchOption.TopDirectoryOnly);
foreach (string harFile in harFiles)
SaveAmazon(destination, harFile);
logger?.LogInformation("{harFiles} count", harFiles.Length);
}
private static void SaveAmazon(IReadOnlyList<Datum> data, string personIdFile)
{
string json;
Dictionary<string, Datum> keyValuePairs = [];
foreach (Datum datum in data)
_ = keyValuePairs.TryAdd(datum.Name.Split('.')[0], datum);
json = JsonSerializer.Serialize(keyValuePairs, DictionaryDatumGenerationContext.Default.DictionaryStringDatum);
File.WriteAllText(personIdFile, json);
}
private static ReadOnlyCollection<(string, string)> GetAggregationLines(string harFile)
{
List<(string, string)> results = [];
if (!File.Exists(harFile))
throw new Exception();
string lastUrl = string.Empty;
string text = "\"text\": \"{";
string[] lines = File.ReadAllLines(harFile);
foreach (string line in lines)
{
if (line.Contains("\"url\": \""))
lastUrl = line;
if (!line.Contains(text))
continue;
if (!line.Contains("aggregations"))
continue;
if (lastUrl.Contains("search?asset=NONE"))
continue;
results.Add(new(lastUrl, line.Trim()[(text.Length - 1)..^1].Replace("\\\"", "\"")));
lastUrl = string.Empty;
}
return new(results);
}
}

View File

@ -1,35 +0,0 @@
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace File_Folder_Helper.Day.Q22024;
internal static partial class Helper20240518
{
internal static void PersonKeyToImmichImport(ILogger<Worker> logger, List<string> args)
{
string name;
string birthDate;
string ownerId = args[5];
List<string> inserts = [];
string tableName = args[3];
string birthDateFormat = args[6];
string[] columns = args[4].Split(',');
string json = File.ReadAllText(args[2]);
string root = Path.GetFullPath(args[0]);
Dictionary<long, Person> people = JsonSerializer.Deserialize(json, PeopleSourceGenerationContext.Default.DictionaryInt64Person) ?? throw new NullReferenceException();
foreach (KeyValuePair<long, Person> keyValuePair in people)
{
if (keyValuePair.Value.Birth?.Note is null || keyValuePair.Value.Name?.ForwardSlashFull is null || keyValuePair.Value.Birth?.Date is null)
continue;
birthDate = keyValuePair.Value.Birth.Date.Value.ToString(birthDateFormat);
name = keyValuePair.Value.Name.ForwardSlashFull.Replace("/", string.Empty);
inserts.Add($"insert into \"{tableName}\" (\"{string.Join("\", \"", columns)}\") values ('{ownerId}', '{name}', '{birthDate}');");
}
string file = Path.Combine(root, $"{DateTime.Now.Ticks}.sql");
logger.LogInformation("<{file}> saved", file);
File.WriteAllLines(file, inserts);
}
}

View File

@ -1,80 +0,0 @@
using File_Folder_Helper.Helpers;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.Day.Q22024;
internal static partial class Helper20240519
{
private record Record(long Length, long Ticks);
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(string source, string[] sourceFiles)
{
Dictionary<string, Record> results = [];
string key;
Record? record;
FileInfo fileInfo;
int sourceLength = source.Length;
foreach (string sourceFile in sourceFiles)
{
fileInfo = new(sourceFile);
key = sourceFile[sourceLength..];
if (results.TryGetValue(key, out record))
throw new NotSupportedException();
results.Add(key, new(fileInfo.Length, fileInfo.LastWriteTime.Ticks));
}
return new(results);
}
internal static void FindReplaceDirectoryName(ILogger<Worker> logger, List<string> args)
{
string checkDirectory;
string replaceText = args[3];
string[] findTexts = args[2].Split(',');
string root = Path.GetFullPath(args[0]);
string[] directories = Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
checkDirectory = directory;
foreach (string findText in findTexts)
checkDirectory = checkDirectory.Replace(findText, replaceText);
if (checkDirectory == directory)
continue;
if (Directory.Exists(checkDirectory))
continue;
logger.LogInformation("<{directory}> to <{checkDirectory}>", directory, checkDirectory);
Directory.Move(directory, checkDirectory);
}
string key;
Record? record;
string checkFile;
FileInfo fileInfo;
string target = Path.GetFullPath(args[6]);
string source = Path.GetFullPath(args[4]);
string compare = Path.GetFullPath(args[5]);
string[] sourceFiles = Directory.GetFiles(source, "*", SearchOption.AllDirectories);
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(source, sourceFiles);
string[] compareFiles = Directory.GetFiles(compare, "*", SearchOption.AllDirectories);
int compareLength = compare.Length;
foreach (string compareFile in compareFiles)
{
fileInfo = new(compareFile);
key = compareFile[compareLength..];
if (!keyValuePairs.TryGetValue(key, out record))
continue;
if (fileInfo.Length != record.Length || fileInfo.LastWriteTime.Ticks != record.Ticks)
continue;
checkFile = $"{target}{key}";
checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new NotSupportedException();
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
if (File.Exists(checkFile))
continue;
logger.LogInformation("<{compareFile}> to <{checkFile}>", compareFile, checkFile);
File.Move(compareFile, checkFile);
}
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, compare);
}
}

View File

@ -1,160 +0,0 @@
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.Day.Q22024;
internal static partial class Helper20240520
{
private record RecordA(string Directory, string Extension, string SourceFile, Identifier Identifier);
private record RecordB(ReadOnlyDictionary<int, Identifier> IdTo, ReadOnlyDictionary<long, Identifier> LengthTo, ReadOnlyDictionary<string, Identifier> PaddedTo);
internal sealed record Identifier(int Id, long Length, string PaddedId, long Ticks)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Identifier))]
internal partial class IdentifierSourceGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Identifier[]))]
internal partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext
{
}
private static RecordB GetRecordB(string jsonFile)
{
RecordB result;
Dictionary<int, Identifier> idTo = [];
Dictionary<long, Identifier> lengthTo = [];
Dictionary<string, Identifier> paddedTo = [];
string? json = !File.Exists(jsonFile) ? null : File.ReadAllText(jsonFile);
Identifier[]? identifiers = json is null ? null : JsonSerializer.Deserialize(json, IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
if (identifiers is null && !string.IsNullOrEmpty(jsonFile))
throw new Exception($"Invalid {nameof(jsonFile)}");
if (identifiers is not null)
{
foreach (Identifier identifier in identifiers)
{
idTo.Add(identifier.Id, identifier);
paddedTo.Add(identifier.PaddedId, identifier);
if (lengthTo.ContainsKey(identifier.Length))
{
_ = lengthTo.Remove(identifier.Length);
continue;
}
lengthTo.Add(identifier.Length, identifier);
}
}
result = new(new(idTo), new(lengthTo), new(paddedTo));
return result;
}
internal static void IdentifierRename(ILogger<Worker> logger, List<string> args)
{
int id;
string key;
RecordA recordA;
string checkFile;
FileInfo fileInfo;
string checkDirectory;
Identifier? identifier;
string offset = args[5];
string option = args[7];
string jsonFile = args[4];
string fileNameWithoutExtension;
List<RecordA> recordACollection = [];
RecordB recordB = GetRecordB(jsonFile);
string deterministicHashCode = args[3];
string source = Path.GetFullPath(args[0]);
int intMinValueLength = int.Parse(args[2]);
string destination = Path.GetFullPath(args[6]);
bool isOffsetDeterministicHashCode = offset == deterministicHashCode;
string[] sourceFiles = Directory.GetFiles(source, "*", SearchOption.AllDirectories);
logger.LogInformation("Found {files}(s)", sourceFiles.Length);
int sourceLength = source.Length;
foreach (string sourceFile in sourceFiles)
{
fileInfo = new(sourceFile);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
if (fileInfo.Directory is null)
throw new NotSupportedException();
if (option == "Padded")
{
if (fileNameWithoutExtension.Length < intMinValueLength)
continue;
key = fileNameWithoutExtension;
if (recordB.PaddedTo.TryGetValue(key, out identifier))
{
recordACollection.Add(new($"{destination}{fileInfo.Directory.FullName[sourceLength..]}", fileInfo.Extension, fileInfo.FullName, identifier));
continue;
}
}
if (option == "Length")
{
if (recordB.LengthTo.TryGetValue(fileInfo.Length, out identifier))
{
checkDirectory = $"{destination}{fileInfo.Directory.FullName[sourceLength..]}";
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, $"{identifier.PaddedId}{fileInfo.Extension}");
if (File.Exists(checkFile))
continue;
File.Copy(fileInfo.FullName, checkFile);
logger.LogInformation("<{fileInfo.FullName}> was moved to <{checkFile}>", fileInfo.FullName, checkFile);
continue;
}
}
if (option == "Id")
{
if (int.TryParse(fileNameWithoutExtension, out id))
{
if (recordB.IdTo.TryGetValue(id, out identifier))
{
checkDirectory = $"{destination}{fileInfo.Directory.FullName[sourceLength..]}";
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, $"{identifier.PaddedId}{fileInfo.Extension}");
if (File.Exists(checkFile))
continue;
File.Move(fileInfo.FullName, checkFile);
logger.LogInformation("<{fileInfo.FullName}> was moved to <{checkFile}>", fileInfo.FullName, checkFile);
continue;
}
}
}
}
if (option == "Padded")
{
if (!isOffsetDeterministicHashCode)
recordACollection = (from l in recordACollection orderby l.Identifier.Ticks select l).ToList();
for (int i = 0; i < recordACollection.Count; i++)
{
recordA = recordACollection[i];
if (!Directory.Exists(recordA.Directory))
_ = Directory.CreateDirectory(recordA.Directory);
checkFile = Path.Combine(recordA.Directory, isOffsetDeterministicHashCode ? $"{recordA.Identifier.PaddedId}{recordA.Extension}" : $"{offset + i}{recordA.Identifier.PaddedId}{recordA.Extension}");
if (File.Exists(checkFile))
continue;
File.Move(recordA.SourceFile, checkFile);
logger.LogInformation("<{recordA.SourceFile}> was moved to <{checkFile}>", recordA.SourceFile, checkFile);
}
}
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, source);
}
}

View File

@ -1,206 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.Day.Q22024;
internal static partial class Helper20240623
{
private record SubTaskLine(string Text, bool Done, long? Ticks, int? Line);
private record Record(int? CodeInsidersLine, string File, string[] Lines, int? StopLine, int? SubTasksLine);
private static List<Record> GetRecords(string sourceDirectory, string searchPattern, string codeInsiders, string subTasks)
{
List<Record> results = [];
int? stopLine;
string[] lines;
int? subTasksLine;
int? codeInsidersLine;
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files)
{
stopLine = null;
subTasksLine = null;
codeInsidersLine = null;
lines = File.ReadAllLines(file);
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].StartsWith(codeInsiders) && lines[i][^1] == '"')
{
if (lines.Length > i + 1 && lines[i + 1] == "```")
codeInsidersLine = i;
}
if (lines[i] != subTasks)
continue;
subTasksLine = i;
if (codeInsidersLine is null)
break;
if (lines.Length > i)
{
for (int j = i + 1; j < lines.Length; j++)
{
if (lines[j].Length > 0 && lines[j][0] == '#')
{
stopLine = j;
break;
}
}
}
stopLine ??= lines.Length;
break;
}
results.Add(new(codeInsidersLine, file, lines, stopLine, subTasksLine));
}
return results;
}
private static ReadOnlyCollection<SubTaskLine> GetSubTasks(string subTasks, string[] tasks, bool? foundDone, string fallbackLine, FileInfo fileInfo)
{
List<SubTaskLine> results = [];
string line;
bool doneValue;
string? h1 = null;
bool foundSubTasks = false;
int tasksZeroLength = tasks[0].Length;
string[] lines = File.ReadAllLines(fileInfo.FullName);
for (int i = 0; i < lines.Length; i++)
{
line = lines[i];
if (line.StartsWith("# "))
h1 = line[2..];
if (!foundSubTasks && line == subTasks)
foundSubTasks = true;
if (!foundSubTasks)
continue;
if (line.Length <= tasksZeroLength || !line.StartsWith(tasks[0]) || line[tasksZeroLength] is not ' ' and not 'x' || line[tasksZeroLength + 1] != ']')
continue;
doneValue = foundDone is not null && foundDone.Value;
results.Add(new($" {line}", doneValue, fileInfo.LastWriteTime.Ticks, i));
}
doneValue = foundDone is not null && foundDone.Value;
if (h1 is null)
results.Add(new(fallbackLine, doneValue, fileInfo.LastWriteTime.Ticks, Line: null));
else
results.Add(new(foundDone is null || !foundDone.Value ? $"- [ ] {fileInfo.LastWriteTime.Ticks} ~~~ {h1}" : $"- [x] {fileInfo.LastWriteTime.Ticks} ~~~ {h1}", doneValue, fileInfo.LastWriteTime.Ticks, Line: 0));
return new(results);
}
internal static void UpdateSubTasksInMarkdownFiles(ILogger<Worker> logger, List<string> args)
{
int lineCheck;
bool doneValue;
bool? foundDone;
FileInfo fileInfo;
string[] newLines;
string[] segments;
List<string> lines;
string fallbackLine;
string[] indexLines;
string checkDirectory;
string done = args[7];
List<string> indexFiles;
string subTasks = args[3];
List<string> oldLines = [];
string indexFile = args[5];
string searchPattern = args[2];
string directoryFilter = args[8];
string[] tasks = args[6].Split(',');
string codeInsiders = $"{args[4]} \"";
List<SubTaskLine> allSubTaskLines = [];
ReadOnlyCollection<SubTaskLine> subTaskLines;
string sourceDirectory = Path.GetFullPath(args[0]);
List<Record> records = GetRecords(sourceDirectory, searchPattern, codeInsiders, subTasks);
foreach (Record record in from l in records orderby l.SubTasksLine is null, l.CodeInsidersLine is null select l)
{
if (record.SubTasksLine is null)
continue;
if (record.CodeInsidersLine is not null)
logger.LogInformation("<{file}> has [{subTasks}]", Path.GetFileNameWithoutExtension(record.File), subTasks);
else
{
logger.LogWarning("<{file}> has [{subTasks}] but doesn't have [{codeInsiders}]!", Path.GetFileNameWithoutExtension(record.File), subTasks, codeInsiders);
continue;
}
if (record.StopLine is null)
continue;
checkDirectory = record.Lines[record.CodeInsidersLine.Value][codeInsiders.Length..^1];
if (!Directory.Exists(checkDirectory))
{
logger.LogError("<{checkDirectory}> doesn't exist", Path.GetFileName(checkDirectory));
continue;
}
indexFiles = Directory.GetFiles(checkDirectory, indexFile, SearchOption.AllDirectories).ToList();
if (indexFiles.Count != 1)
{
for (int i = indexFiles.Count - 1; i > -1; i--)
{
if (!indexFiles[i].Contains(directoryFilter, StringComparison.CurrentCultureIgnoreCase))
indexFiles.RemoveAt(i);
}
if (indexFiles.Count != 1)
{
logger.LogError("<{checkDirectory}> doesn't have a [{indexFile}]", Path.GetFileName(checkDirectory), indexFile);
continue;
}
}
foundDone = null;
oldLines.Clear();
allSubTaskLines.Clear();
indexLines = File.ReadAllLines(indexFiles[0]);
checkDirectory = Path.GetDirectoryName(indexFiles[0]) ?? throw new Exception();
for (int i = 0; i < indexLines.Length; i++)
{
if (indexLines[i] == done)
foundDone = true;
segments = indexLines[i].Split(tasks[1]);
doneValue = foundDone is not null && foundDone.Value;
if (segments.Length > 2 || !segments[0].StartsWith(tasks[0]))
continue;
fallbackLine = foundDone is null || !foundDone.Value ? $"- [ ] {segments[0][tasks[0].Length..]}" : $"- [x] {segments[0][tasks[0].Length..]}";
fileInfo = new(Path.GetFullPath(Path.Combine(checkDirectory, segments[1][..^1])));
if (!fileInfo.Exists)
{
allSubTaskLines.Add(new(fallbackLine, doneValue, Ticks: null, Line: null));
continue;
}
subTaskLines = GetSubTasks(subTasks, tasks, doneValue, fallbackLine, fileInfo);
for (int j = subTaskLines.Count - 1; j >= 0; j--)
allSubTaskLines.Add(subTaskLines[j]);
}
if (allSubTaskLines.Count == 0)
continue;
lineCheck = 0;
for (int i = record.SubTasksLine.Value + 1; i < record.StopLine.Value - 1; i++)
oldLines.Add(record.Lines[i]);
if (allSubTaskLines.Any(l => l.Ticks is null))
newLines = (from l in allSubTaskLines select l.Text).ToArray();
else
newLines = (from l in allSubTaskLines orderby l.Done descending, l.Ticks, l.Line select l.Text).ToArray();
if (newLines.Length == oldLines.Count)
{
for (int i = 0; i < newLines.Length; i++)
{
if (newLines[i] != record.Lines[record.SubTasksLine.Value + 1 + i])
continue;
lineCheck++;
}
if (lineCheck == newLines.Length)
continue;
}
checkDirectory = Path.Combine(checkDirectory, DateTime.Now.Ticks.ToString());
_ = Directory.CreateDirectory(checkDirectory);
Thread.Sleep(500);
Directory.Delete(checkDirectory);
lines = record.Lines.ToList();
for (int i = record.StopLine.Value - 1; i > record.SubTasksLine.Value + 1; i--)
lines.RemoveAt(i);
if (record.StopLine.Value == record.Lines.Length && lines[^1].Length == 0)
lines.RemoveAt(lines.Count - 1);
for (int i = 0; i < newLines.Length; i++)
lines.Insert(record.SubTasksLine.Value + 1 + i, newLines[i]);
lines.Insert(record.SubTasksLine.Value + 1, string.Empty);
File.WriteAllLines(record.File, lines);
}
}
}

View File

@ -1,88 +0,0 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.Day.Q22024;
internal static partial class Helper20240624
{
private static void MoveUpOndDirectory(ILogger<Worker> logger, string sourceDirectory, string[] files)
{
string? match;
string checkFile;
FileInfo fileInfoA;
FileInfo fileInfoB;
string? checkDirectory;
List<string> deleteFiles = [];
Dictionary<string, string> keyValuePairs = [];
foreach (string file in files)
{
checkDirectory = Path.GetDirectoryName(Path.GetDirectoryName(file)) ?? throw new NotSupportedException();
checkFile = Path.Combine(checkDirectory, Path.GetFileName(file));
if (File.Exists(checkFile))
throw new NotSupportedException();
if (keyValuePairs.TryGetValue(checkFile, out match))
{
fileInfoA = new(file);
fileInfoB = new(match);
if (fileInfoA.Length != fileInfoB.Length)
throw new NotSupportedException("Files don't match!");
logger.LogWarning("<{file}> already exists!", file);
deleteFiles.Add(file);
continue;
}
keyValuePairs.Add(checkFile, file);
}
foreach (string file in deleteFiles)
File.Delete(file);
foreach (KeyValuePair<string, string> keyValuePair in keyValuePairs)
File.Move(keyValuePair.Value, keyValuePair.Key);
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
}
private static void Distinct(List<string> args, string sourceDirectory, string[] deleteMatchingIdsDirectoryNames, string[] files)
{
string fileName;
string directory;
List<string> distinct = [];
List<string> duplicate = [];
string[] keepMatchingIdsDirectoryNames = args[4].Split(',');
if (deleteMatchingIdsDirectoryNames.Length != keepMatchingIdsDirectoryNames.Length)
throw new NotSupportedException("Check arg lengths!");
string[] keepMatchingIdsDirectories = keepMatchingIdsDirectoryNames.Select(l => Path.Combine(sourceDirectory, l)).ToArray();
string[] deleteMatchingIdsDirectories = deleteMatchingIdsDirectoryNames.Select(l => Path.Combine(sourceDirectory, l)).ToArray();
foreach (string file in files)
{
fileName = Path.GetFileName(file);
if (distinct.Contains(fileName))
{
duplicate.Add(fileName);
continue;
}
distinct.Add(Path.GetFileName(file));
}
foreach (string file in files)
{
fileName = Path.GetFileName(file);
directory = Path.GetDirectoryName(file) ?? throw new NotSupportedException();
if (!duplicate.Contains(fileName))
continue;
if (deleteMatchingIdsDirectories.Contains(directory))
File.Move(file, $"{file}.del");
else if (!keepMatchingIdsDirectories.Contains(directory))
throw new NotSupportedException($"Missing <{Path.GetFileName(directory)}> as a directory for {fileName}");
}
}
internal static void MoveUpOneDirectory(ILogger<Worker> logger, List<string> args)
{
string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]);
string[] deleteMatchingIdsDirectoryNames = args[3].Split(',');
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
if (deleteMatchingIdsDirectoryNames.Length == 0)
MoveUpOndDirectory(logger, sourceDirectory, files);
else
Distinct(args, sourceDirectory, deleteMatchingIdsDirectoryNames, files);
}
}

View File

@ -1,146 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.ConvertExcelToJson;
public class FIBacklogMesa
{
[JsonConstructor]
public FIBacklogMesa(string req,
string submitted,
string requestor,
string assignedTo,
string secondResource,
string subject,
string systemS,
string priority,
string training,
string prioritySubset,
string status,
string definition,
string updates,
string estEffortDays,
string commitDate,
string reCommitDate,
string uATAsOf,
string cmpDate,
string f20,
string f21,
string f22,
string f23,
string f24,
string f25,
string f26,
string f27,
string f28,
string f29,
string f30,
string f31,
string f32,
string f33)
{
Req = req;
Submitted = submitted;
Requestor = requestor;
AssignedTo = assignedTo;
SecondResource = secondResource;
Subject = subject;
SystemS = systemS;
Priority = priority;
Training = training;
PrioritySubset = prioritySubset;
Status = status;
Definition = definition;
Updates = updates;
EstEffortDays = estEffortDays;
CommitDate = commitDate;
ReCommitDate = reCommitDate;
UATAsOf = uATAsOf;
CMPDate = cmpDate;
F20 = f20;
F21 = f21;
F22 = f22;
F23 = f23;
F24 = f24;
F25 = f25;
F26 = f26;
F27 = f27;
F28 = f28;
F29 = f29;
F30 = f30;
F31 = f31;
F32 = f32;
F33 = f33;
}
public string Req { get; set; } // { init; get; }
public string Submitted { get; set; } // { init; get; }
public string Requestor { get; set; } // { init; get; }
[JsonPropertyName("Assigned To")]
public string AssignedTo { get; set; } // { init; get; }
[JsonPropertyName("Second Resource")]
public string SecondResource { get; set; } // { init; get; }
[JsonPropertyName("Subject - from Requestor")]
public string Subject { get; set; } // { init; get; }
[JsonPropertyName("System(s)")]
public string SystemS { get; set; } // { init; get; }
public string Priority { get; set; } // { init; get; }
[JsonPropertyName("Spec/ECN/Training")]
public string Training { get; set; } // { init; get; }
[JsonPropertyName("Qual/Eff")]
public string PrioritySubset { get; set; } // { init; get; }
public string Status { get; set; } // { init; get; }
[JsonPropertyName("Definition - from FI")]
public string Definition { get; set; } // { init; get; }
public string Updates { get; set; } // { init; get; }
[JsonPropertyName("Est Effort _(days)")]
public string EstEffortDays { get; set; } // { init; get; }
[JsonPropertyName("Commit Date")]
public string CommitDate { get; set; } // { init; get; }
[JsonPropertyName("Re-Commit Date")]
public string ReCommitDate { get; set; } // { init; get; }
[JsonPropertyName("UAT as of")]
public string UATAsOf { get; set; } // { init; get; }
[JsonPropertyName("CMP _Date")]
public string CMPDate { get; set; } // { init; get; }
public string F20 { get; set; } // { init; get; }
public string F21 { get; set; } // { init; get; }
public string F22 { get; set; } // { init; get; }
public string F23 { get; set; } // { init; get; }
public string F24 { get; set; } // { init; get; }
public string F25 { get; set; } // { init; get; }
public string F26 { get; set; } // { init; get; }
public string F27 { get; set; } // { init; get; }
public string F28 { get; set; } // { init; get; }
public string F29 { get; set; } // { init; get; }
public string F30 { get; set; } // { init; get; }
public string F31 { get; set; } // { init; get; }
public string F32 { get; set; } // { init; get; }
public string F33 { get; set; } // { init; get; }
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
[JsonSerializable(typeof(FIBacklogMesa[]))]
internal partial class FIBacklogMesaCollectionSourceGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
[JsonSerializable(typeof(FIBacklogMesa))]
internal partial class FIBacklogMesaSourceGenerationContext : JsonSerializerContext
{
}
#endif

View File

@ -1,79 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240711
{
internal static void GitRemoteRemove(ILogger<Worker> logger, List<string> args)
{
string line;
string[] lines;
bool branchCheck;
bool remoteCheck;
string? directory;
string? parentDirectory;
string parentDirectoryName;
string branchName = args[8];
string searchPattern = args[2];
string remoteToAddUrl = args[6];
string remoteToRemove = args[3];
string remoteToAddName = args[5];
ReadOnlyCollection<string> messages;
string remoteToRemoveFilter = args[4];
string sourceDirectory = Path.GetFullPath(args[0]);
string lastRemoteSegment = remoteToRemove.Split('/')[^1];
string extension = args[7].Length > 2 ? args[7] : string.Empty;
string[] files = Directory.EnumerateFiles(sourceDirectory, searchPattern, new EnumerationOptions() { IgnoreInaccessible = true, RecurseSubdirectories = true, AttributesToSkip = FileAttributes.None }).ToArray();
logger.LogInformation("Found {files} file(s)", files.Length);
foreach (string file in files)
{
branchCheck = false;
remoteCheck = false;
lines = File.ReadAllLines(file);
for (int i = 0; i < lines.Length; i++)
{
line = lines[i];
if (!line.Contains(remoteToRemove))
continue;
if (!lines[i - 1].Contains(remoteToRemoveFilter))
continue;
remoteCheck = true;
break;
}
for (int i = 0; i < lines.Length; i++)
{
line = lines[i];
if (!line.Contains(branchName))
continue;
branchCheck = true;
break;
}
if (!remoteCheck)
continue;
directory = Path.GetDirectoryName(file);
if (directory is null)
continue;
parentDirectory = Path.GetDirectoryName(directory);
if (parentDirectory is null)
continue;
parentDirectoryName = Path.GetFileName(parentDirectory).ToLower();
messages = Helpers.HelperGit.RemoteRemove(parentDirectory, lastRemoteSegment, CancellationToken.None);
foreach (string message in messages)
logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.RemoteRemove), parentDirectoryName, message);
messages = Helpers.HelperGit.RemoteAdd(parentDirectory, remoteToAddName, $"{remoteToAddUrl}{parentDirectoryName}{extension}", CancellationToken.None);
foreach (string message in messages)
logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.RemoteAdd), parentDirectoryName, message);
if (!branchCheck)
continue;
try
{ messages = Helpers.HelperGit.PushBranch(parentDirectory, remoteToAddName, branchName, CancellationToken.None); }
catch (Exception ex)
{ messages = new([ex.Message]); }
foreach (string message in messages)
logger.LogInformation("{function} => {parentDirectoryName}: [{message}]", nameof(Helpers.HelperGit.PushBranch), parentDirectoryName, message);
}
}
}

View File

@ -1,84 +0,0 @@
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240718
{
private static Host[] GetHosts(ILogger<Worker> logger, string file)
{
Host[] results;
string lines = File.ReadAllText(file);
string json = $"[{lines.Replace("\r\n", ",")}]";
logger.LogDebug(lines);
results = JsonSerializer.Deserialize(json, HostSourceGenerationContext.Default.HostArray) ?? throw new NullReferenceException();
return results;
}
private static ReadOnlyCollection<string> GetLines(Host[] hosts, string title, string wired)
{
List<string> results = [$"# {title}", string.Empty, "```mermaid", "flowchart TB", $" subgraph {title}"];
int id;
string check;
List<int> distinct = [];
string newLine = $"{Environment.NewLine} ";
foreach (Host host in hosts)
{
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Hyphen.Length != 17)
continue;
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);
results.Add($" {id}(fa:{host.Type}{newLine}{host.Colon}{newLine}{host.Hyphen}{newLine}{host.Device}{newLine}https://{host.Name}/)");
}
results.Add(" end");
results.Add($" subgraph {title}");
foreach (Host host in from l in hosts orderby l.Location, l.Type, l.Line select l)
{
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Hyphen.Length != 17)
continue;
if (!int.TryParse(host.Id, out id))
throw new NotSupportedException($"{host.Id} is not a number");
check = host.Type == wired ? "-->" : "-.->";
results.Add($" {id} {check} |{id}| {host.Location}{host.Type}{host.Line}");
}
results.Add(" end");
results.Add($" subgraph {title}");
foreach (Host host in from l in hosts orderby l.Line, l.Location, l.Type select l)
{
if (host.Id is null || host.Hyphen is null || host.Device is null || host.Name is null || host.Line is null || host.Hyphen.Length != 17)
continue;
if (!int.TryParse(host.Id, out id))
throw new NotSupportedException($"{host.Id} is not a number");
check = host.Type == wired ? "-->" : "-.->";
results.Add($" {host.Location}{host.Type}{host.Line} {check} Line{host.Line}");
}
results.Add(" end");
results.Add("```");
return results.AsReadOnly();
}
internal static void JsonToMarkdown(ILogger<Worker> logger, List<string> args)
{
Host[] hosts;
string title = args[3];
string wired = args[4];
string extension = args[5];
string searchPattern = args[2];
ReadOnlyCollection<string> lines;
string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
hosts = GetHosts(logger, file);
lines = GetLines(hosts, title, wired);
File.WriteAllText($"{file}{extension}", string.Join(Environment.NewLine, lines));
}
}
}

View File

@ -1,206 +0,0 @@
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Text.Json;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240724
{
private record FileConnectorConfigurationSystem(string AlternateTargetFolder,
string FileAgeThreshold,
string[] SourceFileFilters,
string TargetFileLocation);
#pragma warning disable IDE0028, IDE0056, IDE0300, IDE0240, IDE0241
private static readonly HttpClient _HttpClient = new();
private static readonly string _StaticFileServer = "localhost:5054";
private static readonly FileConnectorConfigurationSystem _FileConnectorConfiguration = new(
"D:/Tmp/Phares/AlternateTargetFolder",
"000:20:00:01",
[".txt"],
"D:/Tmp/Phares/TargetFileLocation");
private static DateTime GetFileAgeThresholdDateTime(string fileAgeThreshold)
{
DateTime result = DateTime.Now;
string[] segments = fileAgeThreshold.Split(':');
for (int i = 0; i < segments.Length; i++)
{
result = i switch
{
0 => result.AddDays(double.Parse(segments[i]) * -1),
1 => result.AddHours(double.Parse(segments[i]) * -1),
2 => result.AddMinutes(double.Parse(segments[i]) * -1),
3 => result.AddSeconds(double.Parse(segments[i]) * -1),
_ => throw new Exception(),
};
}
return result;
}
private static string[] GetValidWeeks(DateTime fileAgeThresholdDateTime)
{
DateTime dateTime = DateTime.Now;
Calendar calendar = new CultureInfo("en-US").Calendar;
string weekOfYear = $"{dateTime:yyyy}_Week_{calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
string lastWeekOfYear = $"{fileAgeThresholdDateTime:yyyy}_Week_{calendar.GetWeekOfYear(fileAgeThresholdDateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
return new string[] { weekOfYear, lastWeekOfYear }.Distinct().ToArray();
}
private static string[] GetValidDays(DateTime fileAgeThresholdDateTime)
{
DateTime dateTime = DateTime.Now;
return new string[] { dateTime.ToString("yyyy-MM-dd"), fileAgeThresholdDateTime.ToString("yyyy-MM-dd") }.Distinct().ToArray();
}
private static ReadOnlyCollection<NginxFileSystem> GetDayNginxFileSystemCollection(DateTime fileAgeThresholdDateTime, string week, string day, string dayUrl, NginxFileSystem[] dayNginxFileSystemCollection)
{
List<NginxFileSystem> results = new();
DateTime dateTime;
string nginxFormat = "ddd, dd MMM yyyy HH:mm:ss zzz";
foreach (NginxFileSystem dayNginxFileSystem in dayNginxFileSystemCollection)
{
if (!DateTime.TryParseExact(dayNginxFileSystem.MTime.Replace("GMT", "+00:00"), nginxFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
continue;
if (dateTime < fileAgeThresholdDateTime)
continue;
results.Add(new(
Path.GetFullPath(Path.Combine(_FileConnectorConfiguration.TargetFileLocation, week, day, dayNginxFileSystem.Name)),
string.Concat(dayUrl, '/', dayNginxFileSystem.Name),
dateTime.ToString(),
dayNginxFileSystem.Size));
}
return results.AsReadOnly();
}
private static ReadOnlyCollection<NginxFileSystem> GetDayNginxFileSystemCollection(DateTime fileAgeThresholdDateTime)
{
#nullable enable
List<NginxFileSystem> results = new();
string dayUrl;
string dayJson;
string weekJson;
string checkWeek;
Task<HttpResponseMessage> task;
NginxFileSystem[]? dayNginxFileSystemCollection;
NginxFileSystem[]? weekNginxFileSystemCollection;
string[] days = GetValidDays(fileAgeThresholdDateTime);
string[] weeks = GetValidWeeks(fileAgeThresholdDateTime);
foreach (string week in weeks)
{
checkWeek = string.Concat("http://", _StaticFileServer, '/', week);
task = _HttpClient.GetAsync(checkWeek);
task.Wait();
if (!task.Result.IsSuccessStatusCode)
continue;
weekJson = _HttpClient.GetStringAsync(checkWeek).Result;
weekNginxFileSystemCollection = JsonSerializer.Deserialize(weekJson, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (weekNginxFileSystemCollection is null)
continue;
foreach (NginxFileSystem weekNginxFileSystem in weekNginxFileSystemCollection)
{
if (!(from l in days where weekNginxFileSystem.Name == l select false).Any())
continue;
dayUrl = string.Concat(checkWeek, '/', weekNginxFileSystem.Name);
dayJson = _HttpClient.GetStringAsync(dayUrl).Result;
dayNginxFileSystemCollection = JsonSerializer.Deserialize(dayJson, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
if (dayNginxFileSystemCollection is null)
continue;
results.AddRange(GetDayNginxFileSystemCollection(fileAgeThresholdDateTime, week, weekNginxFileSystem.Name, dayUrl, dayNginxFileSystemCollection));
}
}
return results.AsReadOnly();
#nullable disable
}
private static ReadOnlyCollection<Tuple<DateTime, FileInfo, FileInfo, string>> GetPossible()
{
List<Tuple<DateTime, FileInfo, FileInfo, string>> results = new();
DateTime dateTime;
FileInfo targetFileInfo;
FileInfo alternateFileInfo;
DateTime fileAgeThresholdDateTime = GetFileAgeThresholdDateTime(_FileConnectorConfiguration.FileAgeThreshold);
ReadOnlyCollection<NginxFileSystem> dayNginxFileSystemCollection = GetDayNginxFileSystemCollection(fileAgeThresholdDateTime);
foreach (NginxFileSystem nginxFileSystem in dayNginxFileSystemCollection)
{
targetFileInfo = new FileInfo(nginxFileSystem.Name);
if (targetFileInfo.Directory is null)
continue;
if (!Directory.Exists(targetFileInfo.Directory.FullName))
_ = Directory.CreateDirectory(targetFileInfo.Directory.FullName);
if (!DateTime.TryParse(nginxFileSystem.MTime, out dateTime))
continue;
if (targetFileInfo.Exists && targetFileInfo.LastWriteTime == dateTime)
continue;
alternateFileInfo = new(Path.Combine(_FileConnectorConfiguration.AlternateTargetFolder, nginxFileSystem.Name));
results.Add(new(dateTime, targetFileInfo, alternateFileInfo, nginxFileSystem.Type));
}
return (from l in results orderby l.Item1 select l).ToList().AsReadOnly();
}
private static void Test()
{
#nullable enable
if (_HttpClient is null)
throw new Exception();
if (string.IsNullOrEmpty(_StaticFileServer))
throw new Exception();
if (string.IsNullOrEmpty(_StaticFileServer))
{
ReadOnlyCollection<Tuple<DateTime, FileInfo, FileInfo, string>> possibleDownload = GetPossible();
if (possibleDownload.Count > 0)
{
string targetFileName = possibleDownload[0].Item4;
FileInfo targetFileInfo = possibleDownload[0].Item2;
FileInfo alternateFileInfo = possibleDownload[0].Item3;
DateTime matchNginxFileSystemDateTime = possibleDownload[0].Item1;
// if (alternateFileInfo.Exists)
// File.Delete(alternateFileInfo.FullName);
if (targetFileInfo.Exists)
File.Delete(targetFileInfo.FullName);
string targetJson = _HttpClient.GetStringAsync(targetFileName).Result;
File.WriteAllText(targetFileInfo.FullName, targetJson);
targetFileInfo.LastWriteTime = matchNginxFileSystemDateTime;
// File.Copy(targetFileInfo.FullName, alternateFileInfo.FullName);
File.AppendAllText(alternateFileInfo.FullName, targetJson);
}
}
#nullable disable
}
internal static void CopyDirectories(ILogger<Worker> logger, List<string> args)
{
Test();
string[] files;
Process process;
string checkDirectory;
string filter = args[3];
string replaceWith = args[4];
string searchPattern = args[2];
string sourceDirectory = Path.GetFullPath(args[0]);
string[] foundDirectories = Directory.GetDirectories(sourceDirectory, searchPattern, SearchOption.AllDirectories);
logger.LogInformation($"Found {foundDirectories.Length} directories");
foreach (string foundDirectory in foundDirectories)
{
if (!foundDirectory.Contains(filter))
continue;
logger.LogDebug(foundDirectory);
checkDirectory = foundDirectory.Replace(filter, replaceWith);
if (Directory.Exists(checkDirectory))
{
files = Directory.GetFiles(checkDirectory, "*", SearchOption.AllDirectories);
if (files.Length > 0)
continue;
Directory.Delete(checkDirectory);
}
process = Process.Start("cmd.exe", $"/c xCopy \"{foundDirectory}\" \"{checkDirectory}\" /S /E /I /H /Y");
process.WaitForExit();
}
}
}

View File

@ -1,64 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Diagnostics;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240728
{
internal static void DownloadSslCertificates(ILogger<Worker> logger, List<string> args)
{
string file;
Process? process;
string[] segments;
string standardError;
string standardOutput;
string argumentSegment;
string store = args[9];
string domain = args[2];
List<string> lines = [];
string logSegment = args[8];
string endCertificate = args[7];
string beginCertificate = args[6];
int waitForExit = int.Parse(args[5]);
string[] subdomains = args[3].Split(',');
string sourceDirectory = Path.GetFullPath(args[0]);
ProcessStartInfo processStartInfo = new()
{
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
FileName = args[4],
WorkingDirectory = sourceDirectory
};
foreach (string subdomain in subdomains)
{
argumentSegment = $"{subdomain}.{domain}:443 -servername {subdomain}.{domain}";
processStartInfo.Arguments = $"s_client -connect {subdomain}.{domain}:443 -servername {subdomain}.{domain}";
process = Process.Start(processStartInfo);
if (process is null)
continue;
_ = process.WaitForExit(waitForExit);
process.Kill(entireProcessTree: true);
standardOutput = process.StandardOutput.ReadToEnd();
if (!standardOutput.Contains(beginCertificate) || !standardOutput.Contains(endCertificate))
{
standardError = process.StandardError.ReadToEnd();
logger.LogWarning($"Error: {subdomain}{Environment.NewLine}{standardOutput}{Environment.NewLine}{standardError}");
continue;
}
segments = standardOutput.Split(beginCertificate);
if (segments.Length != 2)
break;
segments = segments[1].Split(endCertificate);
if (segments.Length != 2)
break;
lines.Add($"{logSegment} \"{store}\" {subdomain}.{domain}.cert");
file = Path.Combine(sourceDirectory, $"{subdomain}.{domain}.cert");
File.WriteAllText(file, $"{beginCertificate}{segments[0]}{endCertificate}{Environment.NewLine}");
}
File.WriteAllLines(Path.Combine(sourceDirectory, $"{DateTime.Now.Ticks}.txt"), lines);
}
}

View File

@ -1,93 +0,0 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240805
{
private static void RenameFiles(ILogger<Worker> logger, string sourceDirectory, string[] files, string[] lines, string globalSettingsFile)
{
string to;
string old;
string from;
string what;
string concat;
string checkFile;
string extension;
string[] matches;
string[] segments;
string environment;
List<string> distinct = [];
string globalSettingsLines = File.ReadAllText(globalSettingsFile);
foreach (string line in lines)
{
segments = line.Split('|');
if (segments.Length != 7)
{
logger.LogWarning("Wrong length!");
continue;
}
to = segments[5].Trim();
old = segments[1].Trim();
from = segments[4].Trim();
what = segments[3].Trim();
environment = segments[2].Trim();
concat = string.Concat(environment, '-', what, '-', from, '-', to);
if (distinct.Contains(concat))
{
logger.LogWarning("Not distinct <{concat}>!", concat);
continue;
}
distinct.Add(concat);
globalSettingsLines = globalSettingsLines.Replace(old, concat);
matches = (from l in files where l.Contains(old) select l).ToArray();
if (matches.Length != 1)
{
logger.LogWarning("matches == {matchesLength} <{concat}>!", matches.Length, concat);
continue;
}
extension = Path.GetExtension(matches[0]);
checkFile = Path.Combine(sourceDirectory, $"{concat}{extension}");
File.Move(matches[0], checkFile);
}
File.WriteAllText(globalSettingsFile, globalSettingsLines);
}
private static void RenameFiles(string find, string replace, string[] ignoreFileNames, string[] confFiles)
{
string checkFile;
foreach (string confFile in confFiles)
{
if (ignoreFileNames.Contains(confFile))
continue;
checkFile = confFile.Replace(find, replace);
if (File.Exists(checkFile))
continue;
File.Move(confFile, checkFile);
}
}
internal static void RenameFiles(ILogger<Worker> logger, List<string> args)
{
string find = args[6];
string replace = args[7];
string sourceDirectory = Path.GetFullPath(args[0]);
string globalSettingsFile = Path.GetFullPath(args[4]);
string[] files = Directory.GetFiles(sourceDirectory, args[2], SearchOption.TopDirectoryOnly);
string[] confFiles = Directory.GetFiles(sourceDirectory, $"*{find}", SearchOption.TopDirectoryOnly);
string[] ignoreFileNames = args[8].Split(',').Select(l => Path.Combine(sourceDirectory, l)).ToArray();
RenameFiles(find, replace, ignoreFileNames, confFiles);
string checkFile = Path.Combine(sourceDirectory, args[3]);
if (files.Length == 0 || !File.Exists(checkFile))
logger.LogWarning("No found!");
else
{
string[] lines = File.ReadAllLines(checkFile);
if (lines.Length == 0)
logger.LogWarning("No lines!");
else
RenameFiles(logger, sourceDirectory, files, lines, globalSettingsFile);
}
}
}

View File

@ -1,57 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Globalization;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240806
{
private static void TryArchiveFiles(string sourceDirectory, string pattern, string archiveDirectory, int minimumLength, int days)
{
string checkFile;
FileInfo fileInfo;
string weekOfYear;
string checkDirectory;
string[] directorySegments;
DateTime dateTime = DateTime.Now.AddDays(-days);
Calendar calendar = new CultureInfo("en-US").Calendar;
string[] sourceDirectorySegments = sourceDirectory.Split(Path.DirectorySeparatorChar);
string[] files = Directory.GetFiles(sourceDirectory, pattern, SearchOption.AllDirectories);
if (sourceDirectorySegments.Length < 1)
throw new Exception("Can't be root drive!");
foreach (string file in files)
{
fileInfo = new FileInfo(file);
if (string.IsNullOrEmpty(fileInfo.DirectoryName) || fileInfo.IsReadOnly || fileInfo.Length < minimumLength || fileInfo.LastWriteTime < dateTime)
continue;
directorySegments = fileInfo.DirectoryName.Split(Path.DirectorySeparatorChar);
if (directorySegments.Length < sourceDirectorySegments.Length)
continue;
weekOfYear = $"{fileInfo.LastWriteTime.Year}_Week_{calendar.GetWeekOfYear(fileInfo.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
checkDirectory = string.Concat(archiveDirectory, Path.DirectorySeparatorChar, weekOfYear);
for (int i = sourceDirectorySegments.Length; i < directorySegments.Length; i++)
checkDirectory = string.Concat(checkDirectory, Path.DirectorySeparatorChar, directorySegments[i]);
checkDirectory = string.Concat(checkDirectory, Path.DirectorySeparatorChar, fileInfo.LastWriteTime.ToString("yyyy-MM-dd"));
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, string.Concat(fileInfo.LastWriteTime.ToString("HH-mm-ss-fff"), "~", fileInfo.Name));
if (File.Exists(checkFile))
continue;
File.Move(fileInfo.FullName, checkFile);
}
}
internal static void ArchiveFiles(ILogger<Worker> logger, List<string> args)
{
string pattern = args[4];
int days = int.Parse(args[6]);
logger.LogInformation("Hello");
string sourceDirectory = args[0];
int minimumLength = int.Parse(args[5]);
int millisecondsDelay = int.Parse(args[2]);
string archiveDirectory = Path.GetFullPath(args[7]);
TryArchiveFiles(sourceDirectory, pattern, archiveDirectory, minimumLength, days);
Thread.Sleep(millisecondsDelay);
}
}

View File

@ -1,705 +0,0 @@
#if WorkItems
using File_Folder_Helper.Day.Q32024.ConvertExcelToJson;
using File_Folder_Helper.Day.Q32024.WorkItems;
using File_Folder_Helper.Models;
using Microsoft.Extensions.Logging;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using Microsoft.VisualStudio.Services.WebApi.Patch;
using Microsoft.VisualStudio.Services.WebApi.Patch.Json;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Web;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240809
{
private static void AddPatch(JsonPatchDocument document, string path, object value) =>
document.Add(new JsonPatchOperation { From = null, Operation = Operation.Add, Path = path, Value = value });
private static Dictionary<string, FIBacklogMesa> GetFIBacklogMesaCollection(string json)
{
Dictionary<string, FIBacklogMesa> results = [];
string key;
FIBacklogMesa[]? fiBacklogMesaCollection;
fiBacklogMesaCollection = JsonSerializer.Deserialize(json, FIBacklogMesaCollectionSourceGenerationContext.Default.FIBacklogMesaArray);
if (fiBacklogMesaCollection is null || fiBacklogMesaCollection.Length == 0)
throw new NullReferenceException();
foreach (FIBacklogMesa fiBacklogMesa in fiBacklogMesaCollection)
{
if (string.IsNullOrEmpty(fiBacklogMesa.Req))
continue;
if (string.IsNullOrEmpty(fiBacklogMesa.Submitted))
continue;
if (string.IsNullOrEmpty(fiBacklogMesa.Requestor))
continue;
key = $"{fiBacklogMesa.Req} - ";
if (results.ContainsKey(key))
continue;
results.Add(key, fiBacklogMesa);
}
return results;
}
private static string GetIds(HttpClient httpClient, string basePage, string api, string query)
{
StringBuilder result = new();
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, query));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
WIQL.Root? root = JsonSerializer.Deserialize(streamTask.Result, WIQL.WIQLRootSourceGenerationContext.Default.Root);
streamTask.Result.Dispose();
if (root is null || root.WorkItems is null)
throw new NullReferenceException(nameof(root));
foreach (WIQL.WorkItem workItem in root.WorkItems)
_ = result.Append(workItem.Id).Append(',');
if (result.Length > 0)
_ = result.Remove(result.Length - 1, 1);
return result.ToString();
}
private static ReadOnlyCollection<ValueWithReq> GetWorkItems(HttpClient httpClient, string basePage, string api, string sourceDirectory, string ids)
{
List<ValueWithReq> results = [];
int req;
string json;
string file;
Value? value;
string[] segments;
JsonElement[] jsonElements;
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems?ids={ids}"));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
JsonElement? result = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
if (result is null || result.Value.ValueKind != JsonValueKind.Object)
throw new NullReferenceException(nameof(result));
JsonProperty[] jsonProperties = result.Value.EnumerateObject().ToArray();
foreach (JsonProperty jsonProperty in jsonProperties)
{
if (jsonProperty.Value.ValueKind != JsonValueKind.Array)
continue;
jsonElements = jsonProperty.Value.EnumerateArray().ToArray();
foreach (JsonElement jsonElement in jsonElements)
{
json = jsonElement.GetRawText();
value = JsonSerializer.Deserialize(json, ValueSourceGenerationContext.Default.Value);
if (value is null)
continue;
segments = value.Fields.SystemTitle.Split('-');
if (segments.Length < 2)
continue;
if (!int.TryParse(segments[0], out req) || req == 0)
continue;
file = Path.Combine(sourceDirectory, $"{req}-{value.Id}.json");
File.WriteAllText(file, json);
results.Add(new(value, req, json));
}
}
return new(results);
}
private static ReadOnlyCollection<ValueWithReq> RemoveFrom(Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
List<ValueWithReq> results = [];
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
if (keyToFIBacklogMesa.Remove($"{valueWithReq.Req} - "))
continue;
results.Add(valueWithReq);
}
return new(results);
}
private static ReadOnlyCollection<Models.Comment> GetComments(HttpClient httpClient, string basePage, string api, string sourceDirectory, int req, int id)
{
List<Models.Comment> results = [];
string json;
string file;
Models.Comment? comment;
JsonElement[] jsonElements;
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems/{id}/comments?api-version=7.0-preview.3"));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
JsonElement? result = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
if (result is null || result.Value.ValueKind != JsonValueKind.Object)
throw new NullReferenceException(nameof(result));
JsonProperty[] jsonProperties = result.Value.EnumerateObject().ToArray();
foreach (JsonProperty jsonProperty in jsonProperties)
{
if (jsonProperty.Value.ValueKind != JsonValueKind.Array)
continue;
jsonElements = jsonProperty.Value.EnumerateArray().ToArray();
foreach (JsonElement jsonElement in jsonElements)
{
json = jsonElement.GetRawText();
comment = JsonSerializer.Deserialize(jsonElement, CommentSourceGenerationContext.Default.Comment);
if (comment is null || comment.WorkItemId is null || comment.Id is null)
continue;
file = Path.Combine(sourceDirectory, $"{req}-{id}-{comment.Id}-comments.json");
File.WriteAllText(file, json);
results.Add(comment);
}
}
return new(results);
}
private static void UpdateComment(HttpClient httpClient,
string basePage,
string api,
int id,
FIBacklogMesa fiBacklogMesa,
Models.Comment comment)
{
DateTime submittedDateTime;
if (!DateTime.TryParse(fiBacklogMesa.Submitted, out submittedDateTime))
submittedDateTime = DateTime.MinValue;
string updatesWithSubmitted = $"{fiBacklogMesa.Updates}<br>&nbsp;<br>{submittedDateTime:MM/dd/yyyy} - Submitted by {fiBacklogMesa.Requestor}";
string json = JsonSerializer.Serialize(new { text = updatesWithSubmitted });
StringContent stringContent = new(json, Encoding.UTF8, "application/json");
string requestUri = string.Concat(basePage, api, $"/workitems/{id}/comments/{comment.Id}?api-version=7.0-preview.3");
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.PatchAsync(requestUri, stringContent);
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
JsonElement? result = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
if (result is null || result.Value.ValueKind != JsonValueKind.Object)
throw new NullReferenceException(nameof(result));
}
private static void UpdateAllWorkItemsPharesComment(HttpClient httpClient,
string basePage,
string api,
string sourceDirectory,
Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa,
ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
string key;
FIBacklogMesa? fIBacklogMesa;
ReadOnlyCollection<Models.Comment> comments;
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
if (valueWithReq.Value.Fields.SystemCommentCount == 0)
continue;
key = $"{valueWithReq.Req} - ";
if (!keyToFIBacklogMesa.TryGetValue(key, out fIBacklogMesa))
continue;
comments = GetComments(httpClient, basePage, api, sourceDirectory, valueWithReq.Req, valueWithReq.Value.Id);
foreach (Models.Comment comment in comments)
{
if (comment.CreatedBy?.UniqueName is null || !comment.CreatedBy.UniqueName.Contains("Phares", StringComparison.CurrentCultureIgnoreCase))
continue;
UpdateComment(httpClient, basePage, api, valueWithReq.Value.Id, fIBacklogMesa, comment);
}
}
}
private static void UpdateIteration(HttpClient httpClient,
string basePage,
string api,
int id,
int rev)
{
string json = /*lang=json,strict*/ string.Concat("[ { \"op\": \"test\", \"path\": \"/rev\", \"value\": ", rev, " }, { \"op\": \"replace\", \"path\": \"/fields/System.IterationPath\", \"value\": \"ART SPS\" } ]");
StringContent stringContent = new(json, Encoding.UTF8, "application/json-patch+json");
string requestUri = string.Concat(basePage, api, $"/workitems/{id}?api-version=1.0");
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.PatchAsync(requestUri, stringContent);
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
JsonElement? result = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
if (result is null || result.Value.ValueKind != JsonValueKind.Object)
throw new NullReferenceException(nameof(result));
}
private static void UpdateAllFeaturesNotArtSPS(HttpClient httpClient,
string basePage,
string api,
ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
if (valueWithReq.Value.Fields.SystemIterationPath != "ART SPS\\2024")
continue;
UpdateIteration(httpClient, basePage, api, valueWithReq.Value.Id, valueWithReq.Value.Rev);
}
}
private static DateTime? GetCommitDate(FIBacklogMesa fiBacklogMesa)
{
DateTime? result;
DateTime dateTime;
DateTime minDateTime = DateTime.MinValue.AddYears(10);
string commitDate = fiBacklogMesa.CommitDate.Split(' ')[0];
if (string.IsNullOrEmpty(commitDate))
result = null;
else
{
if (DateTime.TryParseExact(commitDate, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
result = dateTime.AddHours(12).ToUniversalTime();
else
{
if (DateTime.TryParseExact(commitDate, "dd-MMM-yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
result = dateTime.AddHours(12).ToUniversalTime();
else
{
if (DateTime.TryParse(commitDate, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
result = dateTime.AddHours(12).ToUniversalTime();
else
result = null;
}
}
}
return result;
}
private static int GetPriority(FIBacklogMesa fiBacklogMesa)
{
int result;
if (string.IsNullOrEmpty(fiBacklogMesa.Priority) || !int.TryParse(fiBacklogMesa.Priority[..1], out int priority) || priority == 0 || priority > 3)
result = 4;
else
result = priority;
return result;
}
private static int? GetPrioritySubset(FIBacklogMesa fiBacklogMesa)
{
int? result;
if (string.IsNullOrEmpty(fiBacklogMesa.PrioritySubset) || !int.TryParse(fiBacklogMesa.PrioritySubset[..1], out int prioritySubset) || prioritySubset == 0 || prioritySubset > 3)
result = null;
else
result = prioritySubset;
return result;
}
private static string GetIterationPath(string project, DateTime submittedDateTime) =>
submittedDateTime.Year != 2024 ? project : string.Concat(project, "\\", submittedDateTime.Year);
private static string GetTitle(FIBacklogMesa fiBacklogMesa)
{
string result = $"{fiBacklogMesa.Req} - {fiBacklogMesa.Subject.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[0]}";
if (result.Length > 128)
result = result[..127];
return result;
}
private static string GetTitle(FIBacklogMesa fiBacklogMesa, ValueWithReq valueWithReq)
{
string result = $"{valueWithReq.Req} - {fiBacklogMesa.Subject.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[0]}";
if (result.Length > 128)
result = result[..127];
return result;
}
private static string? GetMappedState(FIBacklogMesa fiBacklogMesa) =>
fiBacklogMesa.Status == "CMP" ? "Closed" : fiBacklogMesa.Status == "UAT" ? "Resolved" : fiBacklogMesa.Status == "In process" ? "Active" : null;
private static JsonPatchDocument GetBugDocument(string project, string site, ReadOnlyDictionary<string, string> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, Task<WorkItem>? uatWorkItemTask, FIBacklogMesa fiBacklogMesa, DateTime submittedDateTime)
{
JsonPatchDocument result = [];
string title = GetTitle(fiBacklogMesa);
string iterationPath = GetIterationPath(project, submittedDateTime);
if (uatWorkItemTask?.Result.Id is not null)
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = uatWorkItemTask.Result.Url });
AddPatch(result, "/fields/System.AreaPath", string.Concat(project, "\\", site));
AddPatch(result, "/fields/System.IterationPath", iterationPath);
AddPatch(result, "/fields/System.Title", title);
AddPatch(result, "/fields/System.CreatedDate", submittedDateTime.AddHours(12).ToUniversalTime());
string? state = GetMappedState(fiBacklogMesa);
if (!string.IsNullOrEmpty(state))
AddPatch(result, "/fields/System.State", state);
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition))
AddPatch(result, "/fields/System.Description", $"{fiBacklogMesa.Subject}<br>&nbsp;<br>{fiBacklogMesa.Definition}");
if (assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
AddPatch(result, "/fields/System.AssignedTo", assignedToUser);
if (requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser))
AddPatch(result, "/fields/Custom.Requester", requestorUser);
return result;
}
private static JsonPatchDocument GetFeatureDocument(string project, string site, ReadOnlyDictionary<string, string> requestorNameToUser, ReadOnlyDictionary<string, string> assignedToNameToUser, List<string> tags, Task<WorkItem>? userStoryWorkItemTask, FIBacklogMesa fiBacklogMesa, DateTime submittedDateTime)
{
JsonPatchDocument result = [];
string title = GetTitle(fiBacklogMesa);
int priority = GetPriority(fiBacklogMesa);
string? state = GetMappedState(fiBacklogMesa);
int? prioritySubset = GetPrioritySubset(fiBacklogMesa);
if (prioritySubset is not null)
AddPatch(result, "/fields/Microsoft.VSTS.Common.TimeCriticality", prioritySubset);
string iterationPath = GetIterationPath(project, submittedDateTime);
if (userStoryWorkItemTask?.Result.Id is not null)
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = userStoryWorkItemTask.Result.Url });
AddPatch(result, "/fields/System.AreaPath", string.Concat(project, "\\", site));
if (tags.Count > 0)
{
AddPatch(result, "/fields/System.Tags", tags.Last());
tags.RemoveAt(tags.Count - 1);
}
AddPatch(result, "/fields/System.IterationPath", iterationPath);
AddPatch(result, "/fields/Microsoft.VSTS.Common.Priority", priority);
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition))
AddPatch(result, "/fields/System.Description", $"{fiBacklogMesa.Subject}<br>&nbsp;<br>{fiBacklogMesa.Definition}");
if (!string.IsNullOrEmpty(state))
AddPatch(result, "/fields/System.State", state);
if (!string.IsNullOrEmpty(fiBacklogMesa.EstEffortDays) && int.TryParse(fiBacklogMesa.EstEffortDays, out int estEffortDays) && estEffortDays != 0)
AddPatch(result, "/fields/Microsoft.VSTS.Scheduling.Effort", estEffortDays);
DateTime? dateTime = GetCommitDate(fiBacklogMesa);
if (dateTime is not null)
AddPatch(result, "/fields/Microsoft.VSTS.Scheduling.TargetDate", dateTime);
if (!string.IsNullOrEmpty(fiBacklogMesa.Updates))
AddPatch(result, "/fields/System.History", fiBacklogMesa.Updates);
AddPatch(result, "/fields/System.Title", title);
AddPatch(result, "/fields/System.CreatedDate", submittedDateTime.AddHours(12).ToUniversalTime());
if (assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
AddPatch(result, "/fields/System.AssignedTo", assignedToUser);
if (requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser))
AddPatch(result, "/fields/Custom.Requester", requestorUser);
// https://tfs.intra.infineon.com/tfs/ManufacturingIT/Mesa_FI/_apis/wit/workitemtypes/feature/fields?api-version=7.0
return result;
}
private static List<string> GetTags(FIBacklogMesa fiBacklogMesa)
{
List<string> results = [];
foreach (string tag in fiBacklogMesa.SystemS.Split('/'))
{
if (string.IsNullOrEmpty(tag.Trim()))
continue;
results.Add(tag.Trim());
}
return results;
}
private static List<string> GetTags(Fields fields)
{
List<string> results = [];
if (!string.IsNullOrEmpty(fields.SystemTags))
{
foreach (string tag in fields.SystemTags.Split(';'))
{
if (string.IsNullOrEmpty(tag.Trim()))
continue;
results.Add(tag.Trim());
}
}
return results;
}
private static void CreateWorkItem(WorkItemTrackingHttpClient workItemTrackingHttpClient, string project, string site, ReadOnlyDictionary<string, string> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, FIBacklogMesa fiBacklogMesa)
{
DateTime submittedDateTime;
JsonPatchDocument tagDocument;
Task<WorkItem>? workItem = null;
List<string> tags = GetTags(fiBacklogMesa);
bool isBugFix = fiBacklogMesa.Priority == "0 - BugFix";
if (assignedToNameToUser.Count > requestorNameToUser.Count)
throw new Exception();
if (!DateTime.TryParse(fiBacklogMesa.Submitted, out submittedDateTime))
submittedDateTime = DateTime.MinValue;
if (isBugFix)
{
Task<WorkItem>? uatWorkItemTask = null;
JsonPatchDocument bugDocument = GetBugDocument(project, site, requestorNameToUser, assignedToNameToUser, uatWorkItemTask, fiBacklogMesa, submittedDateTime);
workItem = workItemTrackingHttpClient.CreateWorkItemAsync(bugDocument, project, "Bug");
workItem.Wait();
}
if (!isBugFix)
{
Task<WorkItem>? userStoryWorkItemTask = null;
JsonPatchDocument featureDocument = GetFeatureDocument(project, site, requestorNameToUser, assignedToNameToUser, tags, userStoryWorkItemTask, fiBacklogMesa, submittedDateTime);
workItem = workItemTrackingHttpClient.CreateWorkItemAsync(featureDocument, project, "Feature");
workItem.Wait();
}
for (int i = tags.Count - 1; i > -1; i--)
{
if (workItem is null)
continue;
if (workItem.Result.Id is null)
throw new NotSupportedException();
tagDocument = [];
AddPatch(tagDocument, "/fields/System.Tags", tags[i]);
tags.RemoveAt(i);
workItem = workItemTrackingHttpClient.UpdateWorkItemAsync(tagDocument, workItem.Result.Id.Value);
workItem.Wait();
}
}
private static void KillTime(int loops)
{
for (int i = 1; i < loops; i++)
Thread.Sleep(500);
}
private static void Update(HttpClient httpClient, string basePage, string api, string query, HttpContent httpContent)
{
#if Windows
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.PatchAsync(string.Concat(basePage, api, query), httpContent);
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<string> stringTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync();
stringTask.Wait();
#endif
KillTime(30);
}
private static void Update(HttpClient httpClient, string basePage, string api, WorkItemTrackingHttpClient workItemTrackingHttpClient, string sync, ValueWithReq valueWithReq)
{
JsonPatchDocument result = [];
AddPatch(result, "/fields/System.Tags", sync);
Task<WorkItem> workItem = workItemTrackingHttpClient.UpdateWorkItemAsync(result, valueWithReq.Value.Id);
workItem.Wait();
if (result is null)
{
var payload = new
{
op = "replace",
path = "/fields/System.IterationPath",
value = "Mesa_FI"
};
string stringPayload = JsonSerializer.Serialize(payload);
HttpContent httpContent = new StringContent($"[{stringPayload}]", Encoding.UTF8, "application/json-patch+json");
Update(httpClient, basePage, api, $"/workitems/{valueWithReq.Value.Id}?api-version=1.0", httpContent);
}
}
private static int SetSyncTag(HttpClient httpClient,
string basePage,
string api,
WorkItemTrackingHttpClient workItemTrackingHttpClient,
ReadOnlyDictionary<string, string> assignedToNameToUser,
ReadOnlyDictionary<string, string> requestorNameToUser,
Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa,
ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
int result = 0;
string key;
string title;
int priority;
bool isBugFix;
string? state;
List<string> tags;
TimeSpan timeSpan;
DateTime? dateTime;
List<string> compareTags;
const string sync = "Sync";
FIBacklogMesa? fiBacklogMesa;
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
key = $"{valueWithReq.Req} - ";
if (!string.IsNullOrEmpty(key)) // Forced to skip logic
continue;
compareTags = GetTags(valueWithReq.Value.Fields);
if (compareTags.Contains(sync))
continue;
if (!keyToFIBacklogMesa.TryGetValue(key, out fiBacklogMesa))
continue;
tags = GetTags(fiBacklogMesa);
title = GetTitle(fiBacklogMesa, valueWithReq);
isBugFix = fiBacklogMesa.Priority == "0 - BugFix";
_ = requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser);
if (!string.IsNullOrEmpty(requestorUser) && (valueWithReq.Value.Fields.CustomRequester is null || !valueWithReq.Value.Fields.CustomRequester.UniqueName.Equals(requestorUser, StringComparison.CurrentCultureIgnoreCase)))
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
_ = assignedToNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? assignedToUser);
if (!string.IsNullOrEmpty(assignedToUser) && (valueWithReq.Value.Fields.SystemAssignedTo is null || !valueWithReq.Value.Fields.SystemAssignedTo.UniqueName.Equals(assignedToUser, StringComparison.CurrentCultureIgnoreCase)))
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if (valueWithReq.Value.Fields.SystemTitle != title)
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
foreach (string tag in tags)
{
if (compareTags.Contains(tag))
continue;
_ = tags.Remove(tag);
break;
}
if (tags.Count != compareTags.Count)
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if ((isBugFix && valueWithReq.Value.Fields.SystemWorkItemType != "Bug") || (!isBugFix && valueWithReq.Value.Fields.SystemWorkItemType == "Bug"))
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if (!isBugFix)
{
priority = GetPriority(fiBacklogMesa);
if (valueWithReq.Value.Fields.MicrosoftVSTSCommonPriority != priority)
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
}
state = GetMappedState(fiBacklogMesa);
if (!string.IsNullOrEmpty(state) && valueWithReq.Value.Fields.SystemState != state)
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if (!isBugFix && int.TryParse(fiBacklogMesa.EstEffortDays, out int estEffortDays) && valueWithReq.Value.Fields.MicrosoftVSTSSchedulingEffort != estEffortDays)
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
dateTime = GetCommitDate(fiBacklogMesa);
if (dateTime is not null)
{
timeSpan = new(valueWithReq.Value.Fields.MicrosoftVSTSSchedulingTargetDate.Ticks - dateTime.Value.Ticks);
if (timeSpan.Hours is > 32 or < -32)
{
result += 1;
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
}
}
return result;
}
private static void CreateWorkItems(HttpClient httpClient,
string sourceDirectory,
string basePage,
string api,
string query,
WorkItemTrackingHttpClient workItemTrackingHttpClient,
string project,
string site,
ReadOnlyDictionary<string, string> assignedToNameToUser,
ReadOnlyDictionary<string, string> requestorNameToUser,
string json)
{
int counter = 0;
string ids = GetIds(httpClient, basePage, api, query);
Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa = GetFIBacklogMesaCollection(json);
ReadOnlyCollection<ValueWithReq> valueWithReqCollection = string.IsNullOrEmpty(ids) ? new([]) : GetWorkItems(httpClient, basePage, api, sourceDirectory, ids);
int updated = SetSyncTag(httpClient, basePage, api, workItemTrackingHttpClient, assignedToNameToUser, requestorNameToUser, keyToFIBacklogMesa, valueWithReqCollection);
if (updated == 0)
{
UpdateAllFeaturesNotArtSPS(httpClient, basePage, api, valueWithReqCollection);
UpdateAllWorkItemsPharesComment(httpClient, basePage, api, sourceDirectory, keyToFIBacklogMesa, valueWithReqCollection);
ReadOnlyCollection<ValueWithReq> extra = RemoveFrom(keyToFIBacklogMesa, valueWithReqCollection);
foreach (KeyValuePair<string, FIBacklogMesa> keyValuePair in keyToFIBacklogMesa)
{
if (keyToFIBacklogMesa.Count == extra.Count)
break;
if (keyValuePair.Value.Status is "CMP" or "CNCL")
continue;
CreateWorkItem(workItemTrackingHttpClient, project, site, assignedToNameToUser, requestorNameToUser, keyValuePair.Value);
counter++;
}
}
}
private static void CreateWorkItems(ILogger<Worker> logger, string sourceDirectory, string api, string site, string query, string project, string basePage, string baseAddress, byte[] bytes, string[] assignedToNames, string[] requestorNames, string reportFullPath, MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue, WorkItemTrackingHttpClient workItemTrackingHttpClient, HttpClient httpClient)
{
string base64 = Convert.ToBase64String(bytes);
string json = File.ReadAllText(reportFullPath);
httpClient.DefaultRequestHeaders.Authorization = new("Basic", base64);
httpClient.DefaultRequestHeaders.Accept.Add(mediaTypeWithQualityHeaderValue);
ReadOnlyDictionary<string, string> requestorNameToUser = GetRequestorNameToUser(requestorNames);
ReadOnlyDictionary<string, string> assignedToNameToUser = GetAssignedToNameToUser(assignedToNames);
logger.LogInformation("{baseAddress}{basePage}/{project}{api}{query}", baseAddress, basePage, HttpUtility.HtmlEncode(project), api, query);
CreateWorkItems(httpClient, sourceDirectory, basePage, api, query, workItemTrackingHttpClient, project, site, new(assignedToNameToUser), new(requestorNameToUser), json);
}
private static ReadOnlyDictionary<string, string> GetAssignedToNameToUser(string[] assignedToNames)
{
Dictionary<string, string> results = [];
string[] segments;
foreach (string assignedToName in assignedToNames)
{
segments = assignedToName.Split('|');
if (segments.Length != 2)
continue;
results.Add(segments[0], segments[1]);
}
return new(results);
}
private static ReadOnlyDictionary<string, string> GetRequestorNameToUser(string[] requestorNames)
{
Dictionary<string, string> results = [];
string[] segments;
foreach (string requestorName in requestorNames)
{
segments = requestorName.Split('|');
if (segments.Length != 2)
continue;
results.Add(segments[0], segments[1]);
}
return new(results);
}
internal static void CreateWorkItems(ILogger<Worker> logger, List<string> args)
{
string api = args[6];
string pat = args[8];
string site = args[2];
string query = args[7];
string project = args[5];
string basePage = args[4];
string baseAddress = args[3];
string sourceDirectory = args[0];
VssBasicCredential credential = new("", pat);
string[] requestorNames = args[11].Split(',');
string[] assignedToNames = args[10].Split(',');
byte[] bytes = Encoding.ASCII.GetBytes($":{pat}");
string reportFullPath = Path.GetFullPath(Path.Combine(sourceDirectory, args[9]));
VssConnection connection = new(new(string.Concat(baseAddress, basePage)), credential);
MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue = new("application/json");
WorkItemTrackingHttpClient workItemTrackingHttpClient = connection.GetClient<WorkItemTrackingHttpClient>();
HttpClient httpClient = new(new HttpClientHandler() { UseDefaultCredentials = true }) { BaseAddress = new(baseAddress) };
CreateWorkItems(logger, sourceDirectory, api, site, query, project, basePage, baseAddress, bytes, assignedToNames, requestorNames, reportFullPath, mediaTypeWithQualityHeaderValue, workItemTrackingHttpClient, httpClient);
}
}
#endif

View File

@ -1,40 +0,0 @@
using Microsoft.Extensions.Logging;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240820
{
internal static void MoveFilesWithSleep(ILogger<Worker> logger, List<string> args)
{
string checkFile;
string checkDirectory;
int sleep = int.Parse(args[4]);
string searchPattern = args[3];
string sourceDirectory = args[0];
string destinationDirectory = args[2];
string source = Path.GetFullPath(sourceDirectory);
FileInfo[] collection = Directory.GetFiles(source, "*", SearchOption.TopDirectoryOnly).Select(l => new FileInfo(l)).ToArray();
string[] files = (from l in collection orderby l.LastWriteTime select l.FullName).ToArray();
logger.LogInformation("With search pattern '{SearchPattern}' found {files}", searchPattern, files.Length);
foreach (string file in files)
{
Thread.Sleep(500);
checkFile = file.Replace(source, destinationDirectory);
if (checkFile == file)
throw new NotSupportedException("Replace failed!");
checkDirectory = Path.GetDirectoryName(checkFile) ?? throw new NotSupportedException();
try
{
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
Thread.Sleep(sleep);
}
catch (Exception ex)
{ logger.LogInformation(ex, "Inner loop error!"); }
}
}
}

View File

@ -1,228 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240822
{
public record Record(string? Title, ReadOnlyCollection<string> Tags, string? Completed);
public record Root([property: JsonPropertyName("headings")] Heading[] Headings,
[property: JsonPropertyName("lanes")] Lane[] Lanes);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Root))]
internal partial class Helper20240822RootSourceGenerationContext : JsonSerializerContext
{
}
public record Welcome2([property: JsonPropertyName("headings")] Heading[] Headings,
[property: JsonPropertyName("lanes")] Lane[] Lanes);
public record Heading([property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("heading")] string HeadingHeading);
public record Lane([property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("columns")] Column[][] Columns);
public record Column([property: JsonPropertyName("id")] string Id,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("description")] string Description,
[property: JsonPropertyName("metadata")] Metadata? Metadata,
[property: JsonPropertyName("subTasks")] SubTask[]? SubTasks,
[property: JsonPropertyName("relations")] object[] Relations,
[property: JsonPropertyName("comments")] Comment[] Comments,
[property: JsonPropertyName("column")] string ColumnColumn,
[property: JsonPropertyName("workload")] long Workload,
[property: JsonPropertyName("progress")] long Progress,
[property: JsonPropertyName("remainingWorkload")] long RemainingWorkload,
[property: JsonPropertyName("dueData")] DueData DueData);
public record Comment([property: JsonPropertyName("text")] string Text,
[property: JsonPropertyName("date")] DateTimeOffset Date);
public record DueData([property: JsonPropertyName("completed")] bool Completed,
[property: JsonPropertyName("completedDate")] object CompletedDate,
[property: JsonPropertyName("dueDate")] DateTimeOffset DueDate,
[property: JsonPropertyName("overdue")] bool Overdue,
[property: JsonPropertyName("dueDelta")] long DueDelta,
[property: JsonPropertyName("dueMessage")] string DueMessage);
public record Metadata([property: JsonPropertyName("assigned")] string Assigned,
[property: JsonPropertyName("created")] DateTimeOffset Created,
[property: JsonPropertyName("progress")] long? Progress,
[property: JsonPropertyName("started")] DateTimeOffset? Started,
[property: JsonPropertyName("status")] string? Status,
[property: JsonPropertyName("tags")] string[]? Tags,
[property: JsonPropertyName("type")] string? Type,
[property: JsonPropertyName("updated")] DateTimeOffset Updated,
[property: JsonPropertyName("due")] DateTimeOffset? Due,
[property: JsonPropertyName("completed")] DateTimeOffset? Completed);
public record SubTask([property: JsonPropertyName("text")] string Text,
[property: JsonPropertyName("completed")] bool Completed);
private static ReadOnlyCollection<ReadOnlyCollection<Record>> GetRecords(Column[][] columnCollection)
{
List<ReadOnlyCollection<Record>> results = [];
bool check;
int subTasks;
Column column;
int completed;
List<Record> row;
string? subtasks;
List<string> tags;
for (int i = 0; i < int.MaxValue; i++)
{
row = [];
check = false;
foreach (Column[] columns in columnCollection)
{
if (columns.Length <= i)
row.Add(new(null, new([]), null));
else
{
tags = [];
subTasks = 0;
completed = 0;
column = columns[i];
if (!check)
check = true;
if (column.Metadata?.Tags is not null && column.Metadata.Tags.Length != 0)
{
foreach (string tag in column.Metadata.Tags)
tags.Add(tag);
}
if (column.SubTasks is not null && column.SubTasks.Length != 0)
{
foreach (SubTask subTask in column.SubTasks)
{
subTasks += 1;
if (subTask.Completed)
completed += 1;
}
}
subtasks = subTasks == 0 ? subtasks = null : $"{completed} / {subTasks}";
row.Add(new(column.Name, new(tags), subtasks));
}
}
if (!check)
break;
if (results.Count > 0)
{
if (results[0].Count != row.Count)
throw new Exception("Rows must match!");
}
results.Add(new(row));
}
return new(results);
}
private static void WriteFile(string destinationFile, Heading[] headings, ReadOnlyCollection<ReadOnlyCollection<Record>> recordCollection)
{
string title;
string completed;
List<string> lines =
[
"<html>",
"<head>",
"<style>",
":root {",
"color-scheme: light dark;",
"}",
"body {",
"color: light-dark(#333b3c, #efedea);",
"background-color: light-dark(#efedea, #333b3c);",
"}",
"td {",
"vertical-align: top;",
"}",
".title {",
"font-weight: bold;",
"}",
".complete {",
"font-size: small;",
"}",
".speech-bubble {",
"position: relative;",
"background: darkCyan;",
"border-radius: .4em;",
"}",
".speech-bubble:after {",
"content: '';",
"position: absolute;",
"bottom: 0;",
"left: 50%;",
"width: 0;",
"height: 0;",
"border: 2px solid transparent;",
"border-top-color: #00aabb;",
"border-bottom: 0;",
"margin-left: -2px;",
"margin-bottom: -2px;",
"}",
"</style>",
"</head>",
"<table border=\"1\">",
"<tr>"
];
foreach (Heading heading in headings)
lines.Add($"<th>{heading.Name}</th>");
lines.Add("</tr>");
foreach (ReadOnlyCollection<Record> records in recordCollection)
{
lines.Add("<tr>");
foreach (Record record in records)
{
lines.Add("<td>");
title = record.Title is null ? "&nbsp;" : record.Title;
completed = record.Completed is null ? "&nbsp;" : record.Completed;
lines.Add($"<div class=\"title\">{title}</div>");
lines.Add("<div>");
foreach (string tag in record.Tags)
lines.Add($"<span class=\"speech-bubble\">{tag}</span>");
lines.Add("</div>");
lines.Add($"<div class=\"completed\">{completed}</div>");
lines.Add("</td>");
}
lines.Add("</tr>");
}
lines.Add("</table>");
lines.Add("</html>");
File.WriteAllLines(destinationFile, lines);
}
private static void ParseKanbn(ILogger<Worker> logger, string destinationFile, string json)
{
Root? root = JsonSerializer.Deserialize(json, Helper20240822RootSourceGenerationContext.Default.Root);
if (root is null)
logger.LogInformation("<{root}> is null!", root);
else if (root.Lanes.Length != 1)
logger.LogInformation("{root.Lanes} != 1", root.Lanes.Length);
else if (root.Lanes[0].Columns.Length != root.Headings.Length)
logger.LogInformation("{root[0].Columns.Lanes} != {root.Headings}", root.Lanes[0].Columns.Length, root.Headings.Length);
else
{
ReadOnlyCollection<ReadOnlyCollection<Record>> recordCollection = GetRecords(root.Lanes[0].Columns);
WriteFile(destinationFile, root.Headings, recordCollection);
}
}
internal static void ParseKanbn(ILogger<Worker> logger, List<string> args)
{
string sourceDirectory = Path.GetFullPath(args[0]);
string sourceFile = Path.Combine(sourceDirectory, args[2]);
string destinationFile = Path.Combine(sourceDirectory, $"{DateTime.Now.Ticks}-{args[3]}");
if (!File.Exists(sourceFile))
logger.LogInformation("<{sourceFile}> doesn't exist!", sourceFile);
else
{
string json = File.ReadAllText(sourceFile);
ParseKanbn(logger, destinationFile, json);
}
}
}

View File

@ -1,248 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240828
{
public record HeaderCommon(DateTime Date,
string? Employee,
string? Layer,
string? MesEntity,
string? PSN,
string? Quantity,
string? RDS,
string? Reactor,
string? Recipe,
string? Zone);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(HeaderCommon))]
internal partial class HeaderCommonSourceGenerationContext : JsonSerializerContext
{
}
public record Record(string? CassetteId,
ReadOnlyCollection<string>? CassetteSegments,
DateTime? Date,
string? Employee,
ReadOnlyCollection<string>? EquipmentSegments,
int I,
string? LastDate,
ReadOnlyCollection<ReadOnlyCollection<string>>? Matches);
private static Record GetRecord(int i, string? lastDate, ReadOnlyCollection<ReadOnlyCollection<string>> matches)
{
Record result;
if (matches.Count != 4 || matches[0].Count != 3 || matches[3].Count != 3)
result = new Record(null, null, null, null, null, i, null, null);
else
{
string[] equipmentSegments = matches[1][2].Split('|');
if (equipmentSegments.Length != 2)
result = new Record(null, null, null, null, null, i, null, null);
else
{
string[] cassetteIdSegments = matches[3][2].Split('|');
if (cassetteIdSegments.Length <= 3)
result = new Record(null, null, null, null, null, i, null, null);
else
{
string cassetteId = Regex.Replace(cassetteIdSegments[2], @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0];
result = new Record(cassetteId,
new(cassetteIdSegments),
DateTime.Parse(matches[0][0]),
matches[0][1],
new(equipmentSegments),
i,
lastDate,
new(matches));
}
}
}
return result;
}
private static Record GetRecord(string[] lines, int i)
{
Record result;
int ii = i;
string line;
string[] segments;
string? lastDate = null;
List<ReadOnlyCollection<string>> matches = [];
for (int j = i; j >= 0; j--)
{
ii = j;
line = lines[j];
segments = line.Split(',');
if (segments.Length < 2)
continue;
lastDate ??= segments[0];
if (segments[0] != lastDate)
{
lastDate = segments[0];
break;
}
matches.Add(new(segments));
}
result = GetRecord(ii + 1, lastDate, new(matches));
return result;
}
private static ReadOnlyCollection<Record> GetRecords(string logDirectory, string logSearchPattern)
{
List<Record> results = [];
Record record;
string[] lines;
string[] logFiles = Directory.GetFiles(logDirectory, logSearchPattern, SearchOption.TopDirectoryOnly);
if (logFiles.Length > 0)
{ }
foreach (string logFile in new List<string>()) // logFiles)
{
lines = File.ReadAllLines(logFile);
for (int i = lines.Length - 1; i >= 0; i--)
{
record = GetRecord(lines, i);
i = record.I;
if (record.CassetteId is null || record.CassetteSegments is null || record.Date is null || record.Employee is null || record.EquipmentSegments is null || record.Matches is null)
{
if (i < 4)
break;
continue;
}
results.Add(record);
}
}
return new(results);
}
private static Dictionary<int, ReadOnlyCollection<Record>> GetKeyValuePairs(Dictionary<int, List<Record>> keyValuePairs)
{
Dictionary<int, ReadOnlyCollection<Record>> results = [];
foreach (KeyValuePair<int, List<Record>> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Key, new(keyValuePair.Value));
return new(results);
}
private static Dictionary<int, ReadOnlyCollection<Record>> GetKeyValuePairs(string logSearchPattern, string logDirectory)
{
Dictionary<int, ReadOnlyCollection<Record>> results;
int totalMinutes;
TimeSpan timeSpan;
List<Record>? collection;
Dictionary<int, List<Record>> keyValuePairs = [];
ReadOnlyCollection<Record> records = GetRecords(logDirectory, logSearchPattern);
foreach (Record record in records)
{
if (record.CassetteId is null || record.CassetteSegments is null || record.Date is null || record.Employee is null || record.EquipmentSegments is null || record.Matches is null)
continue;
timeSpan = TimeSpan.FromTicks(record.Date.Value.Ticks);
totalMinutes = (int)Math.Floor(timeSpan.TotalMinutes);
if (!keyValuePairs.TryGetValue(totalMinutes, out collection))
{
keyValuePairs.Add(totalMinutes, []);
if (!keyValuePairs.TryGetValue(totalMinutes, out collection))
throw new Exception();
}
collection.Add(record);
}
results = GetKeyValuePairs(keyValuePairs);
return results;
}
internal static void MoveWaferCounterToArchive(ILogger<Worker> logger, List<string> args)
{
string json;
string keyFile;
string? recipe;
string[] lines;
string checkFile;
string directory;
string? quantity;
string runDataSheet;
string checkDirectory;
HeaderCommon headerCommon;
string logDateFormat = args[3];
string wcSearchPattern = args[5];
string logSearchPattern = $"SKIP---{args[2]}";
string logDirectory = Path.GetFullPath(args[0]);
string sourceDirectory = Path.GetFullPath(args[4]);
string archiveDirectory = Path.GetFullPath(args[6]);
FileInfo[] collection = Directory.GetFiles(sourceDirectory, wcSearchPattern, SearchOption.AllDirectories).Select(l => new FileInfo(l)).ToArray();
logger.LogInformation("Found {collection}(s)", collection.Length);
foreach (FileInfo fileInfo in collection)
{
if (fileInfo.DirectoryName is null || !fileInfo.DirectoryName.Contains('-'))
continue;
lines = File.ReadAllLines(fileInfo.FullName);
recipe = lines.Length < 2 ? null : lines[1];
quantity = lines.Length < 1 ? null : lines[0];
keyFile = $"{fileInfo.FullName}.txt";
if (!File.Exists(keyFile))
continue;
lines = File.ReadAllLines(keyFile);
if (lines.Length != 1)
continue;
runDataSheet = Regex.Replace(lines[0], @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", ".").Split('\r')[0].Split('\n')[0];
directory = Path.Combine(fileInfo.DirectoryName, runDataSheet);
checkDirectory = Path.Combine(directory, fileInfo.LastWriteTime.Ticks.ToString());
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(directory, fileInfo.Name);
if (File.Exists(checkFile))
continue;
headerCommon = new(fileInfo.LastWriteTime, null, null, null, null, quantity, runDataSheet, null, recipe, null);
json = JsonSerializer.Serialize(headerCommon, HeaderCommonSourceGenerationContext.Default.HeaderCommon);
File.Move(fileInfo.FullName, checkFile);
File.Delete(keyFile);
checkFile = Path.Combine(checkDirectory, $"{fileInfo.Name}.json");
if (File.Exists(checkFile))
continue;
File.WriteAllText(checkFile, json);
Directory.SetLastWriteTime(checkDirectory, fileInfo.LastWriteTime);
}
Record record;
int totalMinutes;
string weekOfYear;
TimeSpan timeSpan;
ReadOnlyCollection<Record>? records;
Calendar calendar = new CultureInfo("en-US").Calendar;
Dictionary<int, ReadOnlyCollection<Record>> keyValuePairs = GetKeyValuePairs(logSearchPattern, logDirectory);
logger.LogInformation("Mapped {keyValuePairs}(s)", keyValuePairs.Count);
foreach (FileInfo fileInfo in collection)
{
if (fileInfo.DirectoryName is null || fileInfo.DirectoryName.Contains('-'))
continue;
timeSpan = TimeSpan.FromTicks(fileInfo.LastWriteTime.Ticks);
totalMinutes = (int)Math.Floor(timeSpan.TotalMinutes);
if (!keyValuePairs.TryGetValue(totalMinutes, out records))
continue;
if (records.Count != 1)
continue;
record = records[0];
if (record.CassetteId is null || record.CassetteSegments is null || record.Date is null || record.Employee is null || record.EquipmentSegments is null || record.Matches is null)
continue;
weekOfYear = $"{record.Date.Value.Year}_Week_{calendar.GetWeekOfYear(record.Date.Value, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
checkDirectory = Path.Combine(archiveDirectory,
string.Join('-', record.EquipmentSegments.Reverse()),
weekOfYear,
record.Date.Value.ToString("yyyy-MM-dd"),
record.CassetteId);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, fileInfo.Name);
if (File.Exists(checkFile))
continue;
File.Move(fileInfo.FullName, checkFile);
lines = record.Matches.Select(l => string.Join(',', l)).ToArray();
File.WriteAllLines($"{checkFile}.txt", lines);
}
}
}

View File

@ -1,236 +0,0 @@
#if WorkItems
using File_Folder_Helper.Day.Q32024.WorkItems;
using Microsoft.Extensions.Logging;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System.Collections.ObjectModel;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Web;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240830
{
public record WorkItem(string AreaPath,
string? AssignedTo,
int? BusinessValue,
DateTime ChangedDate,
DateTime? ClosedDate,
int CommentCount,
DateTime CreatedDate,
string Description,
float? Effort,
int Id,
string IterationPath,
int? Parent,
int? Priority,
object[] Relations,
string? Requester,
DateTime? ResolvedDate,
int Revision,
int? RiskReductionMinusOpportunityEnablement,
DateTime? StartDate,
string State,
string Tags,
DateTime? TargetDate,
float? TimeCriticality,
string Title,
string WorkItemType,
float? WeightedShortestJobFirst);
private static string GetIds(HttpClient httpClient, string basePage, string api, string query)
{
List<int> results = [];
StringBuilder result = new();
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, query));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
WIQL.Root? root = JsonSerializer.Deserialize(streamTask.Result, WIQL.WIQLRootSourceGenerationContext.Default.Root);
streamTask.Result.Dispose();
if (root is null || root.WorkItems is null)
throw new NullReferenceException(nameof(root));
foreach (WIQL.WorkItem workItem in root.WorkItems)
{
results.Add(workItem.Id);
if (results.Count > 199)
break;
}
foreach (int id in results)
_ = result.Append(id).Append(',');
if (result.Length > 0)
_ = result.Remove(result.Length - 1, 1);
return result.ToString();
}
private static void GetSingle(HttpClient httpClient, string basePage, string api, string targetFileLocation, int id)
{
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems/{id}?%24expand=1"));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
JsonElement? result = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
string file = Path.Combine(targetFileLocation, $"{-9}-{id}.json");
File.WriteAllText(file, result.ToString());
}
private static ReadOnlyCollection<ValueWithReq> GetWorkItems(HttpClient httpClient, string basePage, string api, string targetFileLocation, string ids)
{
List<ValueWithReq> results = [];
string json;
string file;
Value? value;
JsonElement[] jsonElements;
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems?ids={ids}&$expand=Relations"));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
JsonElement? result = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
if (result is null || result.Value.ValueKind != JsonValueKind.Object)
throw new NullReferenceException(nameof(result));
JsonProperty[] jsonProperties = result.Value.EnumerateObject().ToArray();
foreach (JsonProperty jsonProperty in jsonProperties)
{
if (jsonProperty.Value.ValueKind != JsonValueKind.Array)
continue;
jsonElements = jsonProperty.Value.EnumerateArray().ToArray();
foreach (JsonElement jsonElement in jsonElements)
{
json = jsonElement.GetRawText();
value = JsonSerializer.Deserialize(json, ValueSourceGenerationContext.Default.Value);
if (value is null)
continue;
if (value.Id == 120593)
GetSingle(httpClient, basePage, api, targetFileLocation, value.Id);
file = Path.Combine(targetFileLocation, $"{-1}-{value.Id}.json");
File.WriteAllText(file, json);
results.Add(new(value, -1, json));
}
}
return new(results);
}
private static ReadOnlyCollection<WorkItem> GetWorkItems(ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
List<WorkItem> results = [];
Fields fields;
WorkItem workItem;
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
fields = valueWithReq.Value.Fields;
workItem = new(fields.SystemAreaPath,
fields.SystemAssignedTo?.DisplayName,
fields.MicrosoftVSTSCommonBusinessValue == 0 ? null : fields.MicrosoftVSTSCommonBusinessValue,
fields.SystemChangedDate,
fields.MicrosoftVSTSCommonClosedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonClosedDate,
fields.SystemCommentCount,
fields.SystemCreatedDate,
fields.SystemDescription,
fields.MicrosoftVSTSSchedulingEffort == 0 ? null : fields.MicrosoftVSTSSchedulingEffort,
valueWithReq.Value.Id,
fields.SystemIterationPath,
fields.SystemParent == 0 ? null : fields.SystemParent,
fields.MicrosoftVSTSCommonPriority == 0 ? null : fields.MicrosoftVSTSCommonPriority,
valueWithReq.Value.Relations,
fields.CustomRequester?.DisplayName,
fields.MicrosoftVSTSCommonResolvedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonResolvedDate,
valueWithReq.Value.Rev,
fields.CustomRRminusOE == 0 ? null : fields.CustomRRminusOE,
fields.MicrosoftVSTSSchedulingStartDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingStartDate,
fields.SystemState,
fields.SystemTags,
fields.MicrosoftVSTSSchedulingTargetDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingTargetDate,
fields.MicrosoftVSTSCommonTimeCriticality == 0 ? null : fields.MicrosoftVSTSCommonTimeCriticality,
fields.SystemTitle,
fields.SystemWorkItemType,
fields.CustomWSJF == 0 ? null : fields.CustomWSJF);
results.Add(workItem);
}
return new(results);
}
private static void CompareWorkItems(WorkItemTrackingHttpClient workItemTrackingHttpClient,
string sourceDirectory,
string project,
string site,
ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
ArgumentNullException.ThrowIfNull(workItemTrackingHttpClient);
if (string.IsNullOrEmpty(project))
throw new ArgumentException($"'{nameof(project)}' cannot be null or empty.", nameof(project));
if (string.IsNullOrEmpty(sourceDirectory))
throw new ArgumentException($"'{nameof(sourceDirectory)}' cannot be null or empty.", nameof(site));
if (string.IsNullOrEmpty(site))
throw new ArgumentException($"'{nameof(site)}' cannot be null or empty.", nameof(site));
ReadOnlyCollection<WorkItem> workItems = GetWorkItems(valueWithReqCollection);
string file = Path.Combine(sourceDirectory, $"_.json");
string json = JsonSerializer.Serialize(workItems);
File.WriteAllText(file, json);
foreach (WorkItem workItem in workItems)
{
if (workItem is null)
{ }
}
// https://stackoverflow.com/questions/18153998/how-do-i-remove-all-html-tags-from-a-string-without-knowing-which-tags-are-in-it
}
private static void CompareWorkItems(HttpClient httpClient,
string targetFileLocation,
string basePage,
string api,
string query,
WorkItemTrackingHttpClient workItemTrackingHttpClient,
string project,
string site)
{
string ids = GetIds(httpClient, basePage, api, query);
ReadOnlyCollection<ValueWithReq> valueWithReqCollection = string.IsNullOrEmpty(ids) ? new([]) : GetWorkItems(httpClient, basePage, api, targetFileLocation, ids);
CompareWorkItems(workItemTrackingHttpClient, targetFileLocation, project, site, valueWithReqCollection);
}
private static void CompareWorkItems(ILogger<Worker> logger, string sourceDirectory, string api, string site, string query, string project, string basePage, string baseAddress, byte[] bytes, MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue, WorkItemTrackingHttpClient workItemTrackingHttpClient, HttpClient httpClient)
{
string base64 = Convert.ToBase64String(bytes);
httpClient.DefaultRequestHeaders.Authorization = new("Basic", base64);
httpClient.DefaultRequestHeaders.Accept.Add(mediaTypeWithQualityHeaderValue);
logger.LogInformation("{baseAddress}{basePage}/{project}{api}{query}", baseAddress, basePage, HttpUtility.HtmlEncode(project), api, query);
CompareWorkItems(httpClient, sourceDirectory, basePage, api, query, workItemTrackingHttpClient, project, site);
}
internal static void CompareWorkItems(ILogger<Worker> logger, List<string> args)
{
string api = args[6];
string pat = args[8];
string site = args[2];
string query = args[7];
string project = args[5];
string basePage = args[4];
string baseAddress = args[3];
string sourceDirectory = args[0];
VssBasicCredential credential = new("", pat);
byte[] bytes = Encoding.ASCII.GetBytes($":{pat}");
VssConnection connection = new(new(string.Concat(baseAddress, basePage)), credential);
MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue = new("application/json");
WorkItemTrackingHttpClient workItemTrackingHttpClient = connection.GetClient<WorkItemTrackingHttpClient>();
HttpClient httpClient = new(new HttpClientHandler() { UseDefaultCredentials = true }) { BaseAddress = new(baseAddress) };
CompareWorkItems(logger, sourceDirectory, api, site, query, project, basePage, baseAddress, bytes, mediaTypeWithQualityHeaderValue, workItemTrackingHttpClient, httpClient);
}
}
#endif

View File

@ -1,65 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Globalization;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240910
{
internal static void MoveFilesToWeekOfYear(ILogger<Worker> logger, List<string> args)
{
string day;
string year;
string yearB;
string yearC;
string checkFile;
FileInfo fileInfo;
string weekOfYear;
int weekOfYearValue;
string checkDirectory;
string searchPattern = args[2];
ReadOnlyCollection<string> directoryNames;
string sourceDirectory = Path.GetFullPath(args[0]);
Calendar calendar = new CultureInfo("en-US").Calendar;
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
logger.LogInformation("With search pattern '{SearchPattern}' found {files}", searchPattern, files.Length);
foreach (string file in files)
{
fileInfo = new(file);
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
continue;
checkDirectory = string.Empty;
year = $"{fileInfo.LastWriteTime:yyyy}";
yearB = $"{fileInfo.LastWriteTime:yyyy}_Year";
day = fileInfo.LastWriteTime.ToString("yyyy-MM-dd");
directoryNames = Helpers.HelperDirectory.GetDirectoryNames(fileInfo.DirectoryName);
weekOfYearValue = calendar.GetWeekOfYear(fileInfo.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
yearC = weekOfYearValue < 27 ? $"{fileInfo.LastWriteTime:yyyy}_Year_A" : $"{fileInfo.LastWriteTime:yyyy}_Year_Z";
weekOfYear = $"{fileInfo.LastWriteTime.Year}_Week_{weekOfYearValue:00}";
foreach (string directoryName in directoryNames)
{
if (directoryName == year || directoryName == yearB || directoryName == yearC || directoryName == weekOfYear || directoryName == day)
continue;
checkDirectory = Path.Combine(checkDirectory, directoryName);
}
if (string.IsNullOrEmpty(checkDirectory))
continue;
checkDirectory = Path.Combine(checkDirectory, yearC, weekOfYear, day);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, fileInfo.Name);
if (checkFile.Length > 256 || checkFile == fileInfo.FullName)
continue;
try
{
if (File.Exists(checkFile))
continue;
File.Move(fileInfo.FullName, checkFile);
}
catch (Exception ex)
{ logger.LogInformation(ex, $"Inner loop error <{fileInfo.FullName}>!"); }
}
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, sourceDirectory);
}
}

View File

@ -1,427 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240911
{
public record Attribute([property: JsonPropertyName("isLocked")] bool IsLocked,
[property: JsonPropertyName("name")] string Name);
public record Relation([property: JsonPropertyName("rel")] string Type,
[property: JsonPropertyName("url")] string URL,
[property: JsonPropertyName("attributes")] Attribute Attributes);
public record Record(WorkItem WorkItem, ReadOnlyDictionary<int, Record> Children);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Record))]
internal partial class RecordCommonSourceGenerationContext : JsonSerializerContext
{
}
public record WorkItem(string AreaPath,
string? AssignedTo,
int? BusinessValue,
DateTime ChangedDate,
DateTime? ClosedDate,
int CommentCount,
DateTime CreatedDate,
string Description,
float? Effort,
int Id,
string IterationPath,
int? Parent,
int? Priority,
Relation[] Relations,
string? Requester,
DateTime? ResolvedDate,
int Revision,
int? RiskReductionMinusOpportunityEnablement,
DateTime? StartDate,
string State,
string Tags,
DateTime? TargetDate,
float? TimeCriticality,
string Title,
string WorkItemType,
float? WeightedShortestJobFirst);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WorkItem))]
internal partial class WorkItemSourceGenerationContext : JsonSerializerContext
{
}
private static ReadOnlyDictionary<int, WorkItem> GetWorkItems(string filterDirectory, string[] files)
{
Dictionary<int, WorkItem> results = [];
string json;
WorkItem? workItem;
string? directoryName;
foreach (string file in files)
{
directoryName = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(directoryName))
continue;
if (!directoryName.EndsWith(filterDirectory))
continue;
json = File.ReadAllText(file);
workItem = JsonSerializer.Deserialize(json, WorkItemSourceGenerationContext.Default.WorkItem);
if (workItem is null)
continue;
results.Add(workItem.Id, workItem);
}
return new(results);
}
private static int? GetIdFromUrlIfChild(Relation relation)
{
int? result;
string[] segments = relation?.Attributes is null || relation.Attributes.Name != "Child" ? [] : relation.URL.Split('/');
if (segments.Length < 2)
result = null;
else
{
if (!int.TryParse(segments[^1], out int id))
result = null;
else
result = id;
}
return result;
}
private static Dictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> workItems, WorkItem workItem)
{
Dictionary<int, Record> results = [];
int? childId;
WorkItem? childWorkItem;
List<WorkItem> collection = [];
Dictionary<int, Record> keyValuePairs;
if (workItem.Relations is not null && workItem.Relations.Length > 0)
{
collection.Clear();
foreach (Relation relation in workItem.Relations)
{
childId = GetIdFromUrlIfChild(relation);
if (childId is null || !workItems.TryGetValue(childId.Value, out childWorkItem))
continue;
collection.Add(childWorkItem);
}
collection = (from l in collection orderby l.State != "Closed", l.Id select l).ToList();
foreach (WorkItem item in collection)
{
keyValuePairs = GetKeyValuePairs(workItems, item);
results.Add(item.Id, new(item, new(keyValuePairs)));
}
}
return results;
}
private static ReadOnlyDictionary<int, Record> GetWorkItemAndChildren(ReadOnlyDictionary<int, WorkItem> workItems)
{
Dictionary<int, Record> results = [];
Dictionary<int, Record> keyValuePairs;
foreach (KeyValuePair<int, WorkItem> keyValuePair in workItems)
{
keyValuePairs = GetKeyValuePairs(workItems, keyValuePair.Value);
results.Add(keyValuePair.Key, new(keyValuePair.Value, new(keyValuePairs)));
}
return new(results);
}
private static string GetClosed(WorkItem workItem)
{
string result = workItem.State != "Closed" ? "[ ]" : "[x]";
return result;
}
private static string GetLine(List<char> spaces, WorkItem workItem, KeyValuePair<int, Record> keyValuePair, bool condensed, bool sprintOnly) =>
sprintOnly ? $"\t- [ ] {workItem.IterationPath}" :
condensed ? $"{new string(spaces.Skip(1).ToArray())}- {GetClosed(workItem)} {keyValuePair.Key} - {workItem.Title}" :
$"{new string(spaces.Skip(1).ToArray())}- {GetClosed(workItem)} {keyValuePair.Key} - {workItem.Title} ~~~ {workItem.AssignedTo} - {workItem.IterationPath.Replace('\\', '-')} - {workItem.CreatedDate} --- {workItem.ClosedDate}";
private static void AppendLines(List<char> spaces, List<string> lines, Record record, bool condensed, bool sprintOnly)
{
string line;
spaces.Add('\t');
WorkItem workItem;
foreach (KeyValuePair<int, Record> keyValuePair in record.Children)
{
workItem = keyValuePair.Value.WorkItem;
line = GetLine(spaces, workItem, keyValuePair, condensed, sprintOnly).TrimEnd();
lines.Add(line);
AppendLines(spaces, lines, keyValuePair.Value, condensed, sprintOnly);
}
spaces.RemoveAt(0);
}
private static void AppendLines(string url, List<char> spaces, List<string> lines, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType)
{
List<string> results = [];
WorkItem workItem;
string? maxIterationPath;
List<string> distinct = [];
foreach (KeyValuePair<int, Record> keyValuePair in workItemAndChildren)
{
workItem = keyValuePair.Value.WorkItem;
// if (keyValuePair.Key != 109724)
// continue;
if (workItem.WorkItemType != workItemType)
continue;
results.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
if (keyValuePair.Value.Children.Count == 0)
results.Add(string.Empty);
else
{
AppendLines(spaces, results, keyValuePair.Value, condensed: true, sprintOnly: false);
results.Add(string.Empty);
distinct.Clear();
AppendLines(spaces, distinct, keyValuePair.Value, condensed: false, sprintOnly: true);
if (distinct.Count > 1)
{
results.Add($"## Distinct Iteration Path(s) - {workItem.WorkItemType} - {workItem.AssignedTo} - {workItem.Id} - {workItem.Title} - {workItem.IterationPath}");
results.Add(string.Empty);
results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
distinct.Sort();
distinct = (from l in distinct select l.Trim()).Distinct().ToList();
results.AddRange(distinct);
results.Add(string.Empty);
maxIterationPath = distinct.Max();
if (!string.IsNullOrEmpty(maxIterationPath) && maxIterationPath.Contains("] ") && maxIterationPath.Split(']')[1].Trim() != workItem.IterationPath)
{
results.Add($"### Sync to Distinct Max Iteration Path => {maxIterationPath} - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
}
}
results.Add($"## Extended - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
AppendLines(spaces, results, keyValuePair.Value, condensed: false, sprintOnly: false);
results.Add(string.Empty);
}
lines.AddRange(results);
results.Clear();
}
}
private static void WriteFiles(string destinationDirectory, string fileName, ReadOnlyCollection<string> lines)
{
string text = string.Join(Environment.NewLine, lines);
string markdownFile = Path.Combine(destinationDirectory, $"{fileName}.md");
string textOld = !File.Exists(markdownFile) ? string.Empty : File.ReadAllText(markdownFile);
if (text != textOld)
File.WriteAllText(markdownFile, text);
string html = CommonMark.CommonMarkConverter.Convert(text);
string htmlFile = Path.Combine(destinationDirectory, $"{fileName}.html");
string htmlOld = !File.Exists(htmlFile) ? string.Empty : File.ReadAllText(htmlFile);
if (html != htmlOld)
File.WriteAllText(htmlFile, html);
}
private static ReadOnlyCollection<WorkItem> FilterChildren(Record record, ReadOnlyCollection<string> workItemTypes)
{
List<WorkItem> results = [];
WorkItem workItem;
foreach (KeyValuePair<int, Record> keyValuePair in record.Children)
{
workItem = keyValuePair.Value.WorkItem;
if (!workItemTypes.Contains(workItem.WorkItemType))
continue;
results.Add(workItem);
}
return new(results);
}
private static string? GetMaxIterationPath(ReadOnlyCollection<WorkItem> workItems)
{
string? result;
List<string> results = [];
foreach (WorkItem workItem in workItems)
{
if (results.Contains(workItem.IterationPath))
continue;
results.Add(workItem.IterationPath);
}
result = results.Count == 0 ? null : results.Max();
return result;
}
private static void FeatureCheckIterationPath(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType)
{
WorkItem workItem;
string? maxIterationPath;
List<string> results = [];
ReadOnlyCollection<WorkItem> workItems;
foreach (KeyValuePair<int, Record> keyValuePair in workItemAndChildren)
{
workItem = keyValuePair.Value.WorkItem;
if (workItem.WorkItemType != workItemType)
continue;
results.Clear();
if (keyValuePair.Value.Children.Count == 0)
continue;
workItems = FilterChildren(keyValuePair.Value, workItemTypes);
maxIterationPath = GetMaxIterationPath(workItems);
if (string.IsNullOrEmpty(maxIterationPath) || workItem.IterationPath == maxIterationPath)
continue;
results.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
results.Add($"- [ ] {workItem.Id} => {workItem.IterationPath} != {maxIterationPath}");
results.Add(string.Empty);
lines.AddRange(results);
}
}
private static ReadOnlyCollection<int> GetIdsNotMatching(string tags, ReadOnlyCollection<WorkItem> workItems)
{
List<int> results = [];
string[] segments;
string[] parentTags = tags.Split(';');
foreach (WorkItem workItem in workItems)
{
segments = tags.Split(';');
if (segments.Length > 0 && parentTags.Any(l => segments.Contains(l)))
continue;
results.Add(workItem.Id);
}
return new(results);
}
private static void FeatureCheckTag(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType)
{
WorkItem workItem;
List<string> results = [];
ReadOnlyCollection<int> idsNotMatching;
ReadOnlyCollection<WorkItem> workItems;
foreach (KeyValuePair<int, Record> keyValuePair in workItemAndChildren)
{
workItem = keyValuePair.Value.WorkItem;
if (workItem.WorkItemType != workItemType)
continue;
results.Clear();
if (keyValuePair.Value.Children.Count == 0)
continue;
if (string.IsNullOrEmpty(workItem.Tags))
idsNotMatching = new([workItem.Id]);
else
{
workItems = FilterChildren(keyValuePair.Value, workItemTypes);
idsNotMatching = GetIdsNotMatching(workItem.Tags, workItems);
if (!string.IsNullOrEmpty(workItem.Tags) && idsNotMatching.Count == 0)
continue;
}
results.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
foreach (int id in idsNotMatching)
results.Add($"- [ ] {id} {nameof(workItem.Tags)} != {workItem.Tags}");
results.Add(string.Empty);
lines.AddRange(results);
}
}
private static ReadOnlyCollection<int> GetIdsNotMatching(int? priority, ReadOnlyCollection<WorkItem> workItems)
{
List<int> results = [];
foreach (WorkItem workItem in workItems)
{
if (workItem.Priority == priority)
continue;
results.Add(workItem.Id);
}
return new(results);
}
private static void FeatureCheckPriority(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType)
{
WorkItem workItem;
List<string> results = [];
ReadOnlyCollection<int> idsNotMatching;
ReadOnlyCollection<WorkItem> workItems;
foreach (KeyValuePair<int, Record> keyValuePair in workItemAndChildren)
{
workItem = keyValuePair.Value.WorkItem;
if (workItem.WorkItemType != workItemType)
continue;
results.Clear();
if (keyValuePair.Value.Children.Count == 0)
continue;
workItems = FilterChildren(keyValuePair.Value, workItemTypes);
idsNotMatching = GetIdsNotMatching(workItem.Priority, workItems);
if (idsNotMatching.Count == 0)
continue;
results.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
foreach (int id in idsNotMatching)
results.Add($"- [ ] {id} {nameof(workItem.Priority)} != {workItem.Priority}");
results.Add(string.Empty);
lines.AddRange(results);
}
}
internal static void WriteMarkdown(ILogger<Worker> logger, List<string> args)
{
string url = args[6];
List<char> spaces = [];
List<string> lines = [];
string searchPattern = args[2];
string filterDirectory = args[3];
string[] workItemTypes = args[4].Split('|');
string sourceDirectory = Path.GetFullPath(args[0]);
string destinationDirectory = Path.GetFullPath(args[5]);
if (!Directory.Exists(destinationDirectory))
_ = Directory.CreateDirectory(destinationDirectory);
ReadOnlyCollection<string> userStoryWorkItemTypes = new(["User Story"]);
ReadOnlyCollection<string> userStoryTaskWorkItemTypes = new(["User Story", "Task"]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} file(s)", searchPattern, files.Length);
ReadOnlyDictionary<int, WorkItem> workItems = GetWorkItems(filterDirectory, files);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} workItem(s)", searchPattern, workItems.Count);
ReadOnlyDictionary<int, Record> workItemAndChildren = GetWorkItemAndChildren(workItems);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} workItemAndChildren", searchPattern, workItemAndChildren.Count);
if (workItemAndChildren.Count == -1)
{
string json = JsonSerializer.Serialize(workItemAndChildren, RecordCommonSourceGenerationContext.Default.ReadOnlyDictionaryInt32Record);
File.WriteAllText(".json", json);
}
foreach (string workItemType in workItemTypes)
{
lines.Clear();
lines.Add("# WorkItems");
lines.Add(string.Empty);
AppendLines(url, spaces, lines, workItemAndChildren, workItemType);
WriteFiles(destinationDirectory, workItemType, new(lines));
}
{
lines.Clear();
string workItemType = "Feature";
lines.Add($"# {nameof(FeatureCheckIterationPath)}");
lines.Add(string.Empty);
FeatureCheckIterationPath(url, lines, userStoryTaskWorkItemTypes, workItemAndChildren, workItemType);
WriteFiles(destinationDirectory, $"{nameof(FeatureCheckIterationPath)}", new(lines));
}
{
lines.Clear();
string workItemType = "Feature";
lines.Add($"# {nameof(FeatureCheckTag)}");
lines.Add(string.Empty);
FeatureCheckTag(url, lines, userStoryWorkItemTypes, workItemAndChildren, workItemType);
WriteFiles(destinationDirectory, $"{nameof(FeatureCheckTag)}", new(lines));
}
{
lines.Clear();
string workItemType = "Feature";
lines.Add($"# {nameof(FeatureCheckPriority)}");
lines.Add(string.Empty);
FeatureCheckPriority(url, lines, userStoryWorkItemTypes, workItemAndChildren, workItemType);
WriteFiles(destinationDirectory, $"{nameof(FeatureCheckPriority)}", new(lines));
}
}
}

View File

@ -1,58 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240916
{
private static ReadOnlyCollection<string> Get(string searchPattern, string[] configFileLines)
{
List<string> results = [];
string[] segments;
foreach (string line in configFileLines)
{
if (line.Length < 2 || line[0] == '#')
continue;
segments = line.Split(searchPattern);
if (segments.Length < 2)
continue;
results.Add(segments[1].Split(';')[0]);
}
return results.AsReadOnly();
}
internal static void DebugProxyPass(ILogger<Worker> logger, List<string> args)
{
string debug;
string enable;
string[] lines;
string fileName;
string[] segments;
string configFile = args[3];
string searchPattern = args[2];
string searchPatternB = args[4];
string searchPatternC = args[5];
string sourceDirectory = Path.GetFullPath(args[0]);
string[] configFileLines = File.ReadAllLines(configFile);
ReadOnlyCollection<string> enabledSites = Get(searchPatternB, configFileLines);
logger.LogInformation("Found {files} file(s)", enabledSites.Count);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} file(s)", searchPattern, files.Length);
foreach (string file in files)
{
debug = string.Empty;
lines = File.ReadAllLines(file);
fileName = Path.GetFileName(file);
foreach (string line in lines)
{
segments = line.Split(searchPatternC);
if (segments.Length < 2)
continue;
debug = segments[1].Trim();
}
enable = enabledSites.Contains(fileName) ? string.Empty : "# ";
logger.LogInformation("{enable}{searchPatternB}{fileName}; # https://{fileName}.phares.duckddns.org # {debug}", enable, searchPatternB, fileName, fileName, debug);
}
}
}

View File

@ -1,65 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240925
{
public record Test(string Name,
long Value);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ReadOnlyCollection<Test>))]
internal partial class TestCollectionSourceGenerationContext : JsonSerializerContext
{
}
private static ReadOnlyCollection<Test> GetTests(string sourceDirectory, string searchPattern, string searchPatternB)
{
List<Test> results = [];
long test;
string[] lines;
string[] segments;
string[] segmentsB;
List<long> distinct = [];
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files)
{
lines = File.ReadAllLines(file);
foreach (string line in lines)
{
segments = line.Split(searchPatternB);
if (segments.Length < 2)
continue;
segmentsB = segments[1].Split(',');
if (segmentsB.Length < 2)
continue;
if (!long.TryParse(segmentsB[0], out test))
continue;
if (distinct.Contains(test))
continue;
distinct.Add(test);
results.Add(new(segmentsB[1].Trim('"'), test));
}
}
return (from l in results orderby l.Name.Length, l.Name select l).ToArray().AsReadOnly();
}
internal static void DistinctTests(ILogger<Worker> logger, List<string> args)
{
string searchPattern = args[2];
string searchPatternB = args[3];
string destinationDirectory = args[4];
string sourceDirectory = Path.GetFullPath(args[0]);
if (!Directory.Exists(destinationDirectory))
_ = Directory.CreateDirectory(destinationDirectory);
ReadOnlyCollection<Test> tests = GetTests(sourceDirectory, searchPattern, searchPatternB);
logger.LogInformation("Found {files} file(s)", tests.Count);
string json = JsonSerializer.Serialize(tests, TestCollectionSourceGenerationContext.Default.ReadOnlyCollectionTest);
string fileName = Path.Combine(destinationDirectory, ".json");
File.WriteAllText(fileName, json);
}
}

View File

@ -1,24 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
public class Column
{
[JsonConstructor]
public Column(
string referenceName,
string name,
string url
)
{
ReferenceName = referenceName;
Name = name;
Url = url;
}
public string ReferenceName { get; set; } // { init; get; }
public string Name { get; set; } // { init; get; }
public string Url { get; set; } // { init; get; }
}
#endif

View File

@ -1,24 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
public class Field
{
[JsonConstructor]
public Field(
string referenceName,
string name,
string url
)
{
ReferenceName = referenceName;
Name = name;
Url = url;
}
public string ReferenceName { get; set; } // { init; get; }
public string Name { get; set; } // { init; get; }
public string Url { get; set; } // { init; get; }
}
#endif

View File

@ -1,39 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
public class Root
{
[JsonConstructor]
public Root(
string queryType,
string queryResultType,
DateTime asOf,
Column[] columns,
SortColumn[] sortColumns,
WorkItem[] workItems
)
{
QueryType = queryType;
QueryResultType = queryResultType;
AsOf = asOf;
Columns = columns;
SortColumns = sortColumns;
WorkItems = workItems;
}
public string QueryType { get; set; } // { init; get; }
public string QueryResultType { get; set; } // { init; get; }
public DateTime AsOf { get; set; } // { init; get; }
public Column[] Columns { get; set; } // { init; get; }
public SortColumn[] SortColumns { get; set; } // { init; get; }
public WorkItem[] WorkItems { get; set; } // { init; get; }
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
[JsonSerializable(typeof(Root))]
internal partial class WIQLRootSourceGenerationContext : JsonSerializerContext
{
}
#endif

View File

@ -1,21 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
public class SortColumn
{
[JsonConstructor]
public SortColumn(
Field field,
bool descending
)
{
Field = field;
Descending = descending;
}
public Field Field { get; set; } // { init; get; }
public bool Descending { get; set; } // { init; get; }
}
#endif

View File

@ -1,21 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
public class WorkItem
{
[JsonConstructor]
public WorkItem(
int id,
string url
)
{
Id = id;
Url = url;
}
public int Id { get; set; } // { init; get; }
public string Url { get; set; } // { init; get; }
}
#endif

View File

@ -1,15 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class Avatar
{
[JsonConstructor]
public Avatar(
string href
) => Href = href;
public string Href { get; } // { init; get; }
}
#endif

View File

@ -1,29 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class CommentVersionRef
{
[JsonConstructor]
public CommentVersionRef(
int commentId,
int version,
string url
)
{
CommentId = commentId;
Version = version;
URL = url;
}
[JsonPropertyName("commentId")]
public int CommentId { get; } // { init; get; }
[JsonPropertyName("version")]
public int Version { get; } // { init; get; }
[JsonPropertyName("url")]
public string URL { get; } // { init; get; }
}
#endif

View File

@ -1,36 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class CustomRequester
{
[JsonConstructor]
public CustomRequester(
string descriptor,
string displayName,
string id,
string imageUrl,
Links links,
string uniqueName,
string url
)
{
Descriptor = descriptor;
DisplayName = displayName;
Id = id;
ImageUrl = imageUrl;
Links = links;
UniqueName = uniqueName;
Url = url;
}
[JsonPropertyName("descriptor")] public string Descriptor { get; }
[JsonPropertyName("displayName")] public string DisplayName { get; }
[JsonPropertyName("id")] public string Id { get; }
[JsonPropertyName("imageUrl")] public string ImageUrl { get; }
[JsonPropertyName("_links")] public Links Links { get; }
[JsonPropertyName("uniqueName")] public string UniqueName { get; }
[JsonPropertyName("url")] public string Url { get; }
}
#endif

View File

@ -1,101 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class Fields
{
[JsonConstructor]
public Fields(int customRRminusOE,
CustomRequester? customRequester,
float customWSJF,
int microsoftVSTSCommonBusinessValue,
DateTime microsoftVSTSCommonClosedDate,
int microsoftVSTSCommonPriority,
DateTime microsoftVSTSCommonResolvedDate,
DateTime microsoftVSTSCommonStateChangeDate,
float microsoftVSTSCommonTimeCriticality,
float? microsoftVSTSSchedulingEffort,
DateTime microsoftVSTSSchedulingStartDate,
DateTime microsoftVSTSSchedulingTargetDate,
string systemAreaPath,
SystemAssignedTo systemAssignedTo,
SystemChangedBy systemChangedBy,
DateTime systemChangedDate,
int systemCommentCount,
SystemCreatedBy systemCreatedBy,
DateTime systemCreatedDate,
string systemDescription,
string systemHistory,
string systemIterationPath,
int systemParent,
string systemReason,
string systemState,
string systemTags,
string systemTeamProject,
string systemTitle,
string systemWorkItemType)
{
CustomRequester = customRequester;
CustomRRminusOE = customRRminusOE;
CustomWSJF = customWSJF;
MicrosoftVSTSCommonBusinessValue = microsoftVSTSCommonBusinessValue;
MicrosoftVSTSCommonClosedDate = microsoftVSTSCommonClosedDate;
MicrosoftVSTSCommonPriority = microsoftVSTSCommonPriority;
MicrosoftVSTSCommonResolvedDate = microsoftVSTSCommonResolvedDate;
MicrosoftVSTSCommonStateChangeDate = microsoftVSTSCommonStateChangeDate;
MicrosoftVSTSCommonTimeCriticality = microsoftVSTSCommonTimeCriticality;
MicrosoftVSTSSchedulingEffort = microsoftVSTSSchedulingEffort;
MicrosoftVSTSSchedulingStartDate = microsoftVSTSSchedulingStartDate;
MicrosoftVSTSSchedulingTargetDate = microsoftVSTSSchedulingTargetDate;
SystemAreaPath = systemAreaPath;
SystemAssignedTo = systemAssignedTo;
SystemChangedBy = systemChangedBy;
SystemChangedDate = systemChangedDate;
SystemCommentCount = systemCommentCount;
SystemCreatedBy = systemCreatedBy;
SystemCreatedDate = systemCreatedDate;
SystemDescription = systemDescription;
SystemHistory = systemHistory;
SystemIterationPath = systemIterationPath;
SystemParent = systemParent;
SystemReason = systemReason;
SystemState = systemState;
SystemTags = systemTags;
SystemTeamProject = systemTeamProject;
SystemTitle = systemTitle;
SystemWorkItemType = systemWorkItemType;
}
[JsonPropertyName("Custom.Requester")] public CustomRequester? CustomRequester { get; } // { init; get; }
[JsonPropertyName("Custom.RRminusOE")] public int CustomRRminusOE { get; } // { init; get; }
[JsonPropertyName("Custom.WSJF")] public float CustomWSJF { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.BusinessValue")] public int MicrosoftVSTSCommonBusinessValue { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.ClosedDate")] public DateTime MicrosoftVSTSCommonClosedDate { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.Priority")] public int MicrosoftVSTSCommonPriority { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.ResolvedDate")] public DateTime MicrosoftVSTSCommonResolvedDate { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.StateChangeDate")] public DateTime MicrosoftVSTSCommonStateChangeDate { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.TimeCriticality")] public float MicrosoftVSTSCommonTimeCriticality { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Scheduling.Effort")] public float? MicrosoftVSTSSchedulingEffort { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Scheduling.StartDate")] public DateTime MicrosoftVSTSSchedulingStartDate { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Scheduling.TargetDate")] public DateTime MicrosoftVSTSSchedulingTargetDate { get; } // { init; get; }
[JsonPropertyName("System.AreaPath")] public string SystemAreaPath { get; } // { init; get; }
[JsonPropertyName("System.AssignedTo")] public SystemAssignedTo? SystemAssignedTo { get; } // { init; get; }
[JsonPropertyName("System.ChangedBy")] public SystemChangedBy SystemChangedBy { get; } // { init; get; }
[JsonPropertyName("System.ChangedDate")] public DateTime SystemChangedDate { get; } // { init; get; }
[JsonPropertyName("System.CommentCount")] public int SystemCommentCount { get; } // { init; get; }
[JsonPropertyName("System.CreatedBy")] public SystemCreatedBy SystemCreatedBy { get; } // { init; get; }
[JsonPropertyName("System.CreatedDate")] public DateTime SystemCreatedDate { get; } // { init; get; }
[JsonPropertyName("System.Description")] public string SystemDescription { get; } // { init; get; }
[JsonPropertyName("System.History")] public string SystemHistory { get; } // { init; get; }
[JsonPropertyName("System.IterationPath")] public string SystemIterationPath { get; } // { init; get; }
[JsonPropertyName("System.Parent")] public int SystemParent { get; } // { init; get; }
[JsonPropertyName("System.Reason")] public string SystemReason { get; } // { init; get; }
[JsonPropertyName("System.State")] public string SystemState { get; } // { init; get; }
[JsonPropertyName("System.Tags")] public string SystemTags { get; } // { init; get; }
[JsonPropertyName("System.TeamProject")] public string SystemTeamProject { get; } // { init; get; }
[JsonPropertyName("System.Title")] public string SystemTitle { get; } // { init; get; }
[JsonPropertyName("System.WorkItemType")] public string SystemWorkItemType { get; } // { init; get; }
}
#endif

View File

@ -1,15 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class Html
{
[JsonConstructor]
public Html(
string href
) => Href = href;
public string Href { get; } // { init; get; }
}
#endif

View File

@ -1,16 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class Links
{
[JsonConstructor]
public Links(
Avatar avatar
) => Avatar = avatar;
[JsonPropertyName("avatar")]
public Avatar Avatar { get; }
}
#endif

View File

@ -1,49 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class SystemAssignedTo
{
[JsonConstructor]
public SystemAssignedTo(
string displayName,
string url,
Links links,
string id,
string uniqueName,
string imageUrl,
string descriptor
)
{
DisplayName = displayName;
Url = url;
Links = links;
Id = id;
UniqueName = uniqueName;
ImageUrl = imageUrl;
Descriptor = descriptor;
}
[JsonPropertyName("displayName")]
public string DisplayName { get; }
[JsonPropertyName("url")]
public string Url { get; }
[JsonPropertyName("_links")]
public Links Links { get; }
[JsonPropertyName("id")]
public string Id { get; }
[JsonPropertyName("uniqueName")]
public string UniqueName { get; }
[JsonPropertyName("imageUrl")]
public string ImageUrl { get; }
[JsonPropertyName("descriptor")]
public string Descriptor { get; }
}
#endif

View File

@ -1,49 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class SystemChangedBy
{
[JsonConstructor]
public SystemChangedBy(
string displayName,
string url,
Links links,
string id,
string uniqueName,
string imageUrl,
string descriptor
)
{
DisplayName = displayName;
Url = url;
Links = links;
Id = id;
UniqueName = uniqueName;
ImageUrl = imageUrl;
Descriptor = descriptor;
}
[JsonPropertyName("displayName")]
public string DisplayName { get; }
[JsonPropertyName("url")]
public string Url { get; }
[JsonPropertyName("_links")]
public Links Links { get; }
[JsonPropertyName("id")]
public string Id { get; }
[JsonPropertyName("uniqueName")]
public string UniqueName { get; }
[JsonPropertyName("imageUrl")]
public string ImageUrl { get; }
[JsonPropertyName("descriptor")]
public string Descriptor { get; }
}
#endif

View File

@ -1,49 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class SystemCreatedBy
{
[JsonConstructor]
public SystemCreatedBy(
string displayName,
string url,
Links links,
string id,
string uniqueName,
string imageUrl,
string descriptor
)
{
DisplayName = displayName;
Url = url;
Links = links;
Id = id;
UniqueName = uniqueName;
ImageUrl = imageUrl;
Descriptor = descriptor;
}
[JsonPropertyName("displayName")]
public string DisplayName { get; }
[JsonPropertyName("url")]
public string Url { get; }
[JsonPropertyName("_links")]
public Links Links { get; }
[JsonPropertyName("id")]
public string Id { get; }
[JsonPropertyName("uniqueName")]
public string UniqueName { get; }
[JsonPropertyName("imageUrl")]
public string ImageUrl { get; }
[JsonPropertyName("descriptor")]
public string Descriptor { get; }
}
#endif

View File

@ -1,56 +0,0 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class Value
{
[JsonConstructor]
public Value(
int id,
int rev,
Fields fields,
object[] relations,
CommentVersionRef commentVersionRef,
string url
)
{
Id = id;
Rev = rev;
Fields = fields;
Relations = relations;
CommentVersionRef = commentVersionRef;
Url = url;
}
[JsonPropertyName("id")]
public int Id { get; }
[JsonPropertyName("rev")]
public int Rev { get; }
[JsonPropertyName("fields")]
public Fields Fields { get; }
[JsonPropertyName("relations")]
public object[] Relations { get; }
[JsonPropertyName("commentVersionRef")]
public CommentVersionRef CommentVersionRef { get; }
[JsonPropertyName("url")]
public string Url { get; }
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
[JsonSerializable(typeof(Value[]))]
internal partial class ValueCollectionSourceGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
[JsonSerializable(typeof(Value))]
internal partial class ValueSourceGenerationContext : JsonSerializerContext
{
}
#endif

View File

@ -1,21 +0,0 @@
#if WorkItems
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class ValueWithReq
{
public ValueWithReq(
Value value,
int req,
string json
)
{
Value = value;
Req = req;
Json = json;
}
public Value Value { get; set; } // { init; get; }
public int Req { get; set; } // { init; get; }
public string Json { get; set; } // { init; get; }
}
#endif

View File

@ -1,177 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q42024;
internal static partial class Helper20241002
{
public record Record(string? Calculation,
string Chart,
string Group,
string GroupId,
long Id,
string? RawCalculation,
string Test,
string TestId)
{
public static Record Get(Record record, string? calculation) =>
new(calculation,
record.Chart,
record.Group,
record.GroupId,
record.Id,
record.RawCalculation,
record.Test,
record.TestId);
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ReadOnlyCollection<Record>))]
internal partial class RecordCollectionSourceGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ReadOnlyDictionary<string, Record>))]
internal partial class RecordDictionarySourceGenerationContext : JsonSerializerContext
{
}
private static string? GetCalculation(string searchPatternC, string[] lines, int i, string id, long idValue)
{
string? result = null;
string line;
long check;
string[] segments;
string[] segmentsB;
for (int j = i + 1; j < lines.Length; j++)
{
line = lines[j];
if (!line.Contains(id))
break;
segments = line.Split(searchPatternC);
if (segments.Length < 2)
continue;
segmentsB = segments[1].Split('=');
if (segmentsB.Length < 2)
continue;
if (!long.TryParse(segmentsB[0], out check))
continue;
if (check != idValue)
break;
result = segmentsB[1];
}
return result;
}
private static ReadOnlyCollection<Record> GetRecords(string sourceDirectory, string searchPattern, string searchPatternB, string searchPatternC)
{
List<Record> results = [];
string id;
string line;
long idValue;
string[] lines;
string[] segments;
string[] segmentsB;
string[] segmentsC;
string? calculation;
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
foreach (string file in files)
{
lines = File.ReadAllLines(file);
for (int i = 0; i < lines.Length; i++)
{
line = lines[i];
segments = line.Split(searchPatternB);
if (segments.Length < 2)
continue;
segmentsB = segments[1].Split('=');
if (segmentsB.Length < 2)
continue;
if (!long.TryParse(segmentsB[0], out idValue))
continue;
id = segmentsB[0];
segmentsC = segments[1].Split(',');
if (segmentsC.Length < 4)
continue;
calculation = GetCalculation(searchPatternC, lines, i, id, idValue);
results.Add(new(null,
Path.GetFileName(file),
segmentsC[2].Trim('"'),
segmentsC[1],
idValue,
calculation,
segmentsC[4].Trim('"'),
segmentsC[3]));
}
}
return new(results);
}
private static string GetKey(Record record) =>
$"ch({record.Id + 1})";
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(ReadOnlyCollection<Record> records)
{
Dictionary<string, Record> results = [];
string key;
string? last = null;
foreach (Record record in records)
{
if (last is not null && record.Chart != last)
continue;
last = record.Chart;
key = GetKey(record);
if (results.ContainsKey(key))
continue;
results.Add(key, record);
}
return new(results);
}
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(ReadOnlyDictionary<string, Record> keyValuePairs)
{
Dictionary<string, Record> results = [];
Record result;
Record record;
string? calculation;
foreach (KeyValuePair<string, Record> keyValuePair in keyValuePairs)
{
record = keyValuePair.Value;
calculation = record.RawCalculation;
if (calculation is not null)
{
foreach (KeyValuePair<string, Record> kVP in keyValuePairs)
calculation = calculation.Replace(kVP.Key, $"%DCS(Value, {kVP.Value.Test})");
}
result = Record.Get(record, calculation);
results.Add(keyValuePair.Key, result);
}
return new(results);
}
internal static void ConvertInfinityQSProjectFiles(ILogger<Worker> logger, List<string> args)
{
string searchPattern = args[2];
string searchPatternB = args[3];
string searchPatternC = args[4];
string destinationDirectory = args[5];
string sourceDirectory = Path.GetFullPath(args[0]);
if (!Directory.Exists(destinationDirectory))
_ = Directory.CreateDirectory(destinationDirectory);
ReadOnlyCollection<Record> records = GetRecords(sourceDirectory, searchPattern, searchPatternB, searchPatternC);
logger.LogInformation("Found {records} records(s)", records.Count);
ReadOnlyDictionary<string, Record> collection = GetKeyValuePairs(records);
logger.LogInformation("Found {collection} collection(s)", collection.Count);
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(collection);
logger.LogInformation("Found {keyValuePairs}", keyValuePairs.Count);
string json = JsonSerializer.Serialize(keyValuePairs, RecordDictionarySourceGenerationContext.Default.ReadOnlyDictionaryStringRecord);
string fileName = Path.Combine(destinationDirectory, ".json");
File.WriteAllText(fileName, json);
}
}