Download SSL Certificates Sort Subtasks of Markdown files Test BioRad EAF CopyDirectories json to Markdown Sort Day 2024 Q2 GitRemoteRemove Handle directoryInfo.LinkTarget better Remove StartAt Handle directoryInfo.LinkTarget
206 lines
9.0 KiB
C#
206 lines
9.0 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using System.Collections.ObjectModel;
|
|
|
|
namespace File_Folder_Helper.Day;
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
} |