Update Subtasks In Markdown Files
Better ISO support Only reviewing Files when comparing Extracted sections from UpdateSubTasksInMarkdownFiles
This commit is contained in:
383
ADO2024/PI4/Helper-2024-12-17.cs
Normal file
383
ADO2024/PI4/Helper-2024-12-17.cs
Normal file
@ -0,0 +1,383 @@
|
||||
using DiscUtils.Iso9660;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Renci.SshNet;
|
||||
using Renci.SshNet.Sftp;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace File_Folder_Helper.ADO2024.PI4;
|
||||
|
||||
internal static partial class Helper20241217
|
||||
{
|
||||
|
||||
private record Record(string Directory, Job? Job, string Path);
|
||||
private record Job(string AlternatePath, string Directory, string Extension, File[] Files, int FilesCount, double FilesTotalLength, int Keep, Target[] Targets);
|
||||
private record SecureShell(string Host, string Key, string Path, bool Required, string User);
|
||||
private record ServerMessageBlock(string Path, bool Required);
|
||||
private record Target(SecureShell? SecureShell, ServerMessageBlock? ServerMessageBlock);
|
||||
private record File(long LastWriteTicks, long Length, string RelativePath);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Job))]
|
||||
private partial class JobSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(File[]))]
|
||||
private partial class FilesSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
private static IEnumerable<Record> GetRecords(string directory, string searchPattern)
|
||||
{
|
||||
Job? job;
|
||||
string json;
|
||||
Record record;
|
||||
string fileName;
|
||||
string directoryName;
|
||||
IEnumerable<string> files = Directory.EnumerateFiles(directory, searchPattern, new EnumerationOptions { IgnoreInaccessible = true, RecurseSubdirectories = true });
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileName = Path.GetFileName(file);
|
||||
directoryName = Path.GetDirectoryName(file) ?? throw new Exception();
|
||||
if (!fileName.StartsWith('.'))
|
||||
{
|
||||
System.IO.File.Move(file, Path.Combine(directoryName, $".{fileName}"));
|
||||
continue;
|
||||
}
|
||||
json = System.IO.File.ReadAllText(file);
|
||||
job = JsonSerializer.Deserialize(json, JobSourceGenerationContext.Default.Job);
|
||||
record = new(directoryName, job, file);
|
||||
yield return record;
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<File> GetFiles(string directory, string searchPattern, string[] ignoreFileNames)
|
||||
{
|
||||
List<File> results = [];
|
||||
File file;
|
||||
string relativePath;
|
||||
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
|
||||
FileInfo[] fileInfoCollection = files.Select(l => new FileInfo(l)).ToArray();
|
||||
foreach (FileInfo fileInfo in fileInfoCollection)
|
||||
{
|
||||
if (fileInfo.Name == searchPattern)
|
||||
continue;
|
||||
if (ignoreFileNames.Any(l => l == fileInfo.Name))
|
||||
continue;
|
||||
if (!string.IsNullOrEmpty(fileInfo.LinkTarget))
|
||||
continue;
|
||||
relativePath = Path.GetRelativePath(directory, fileInfo.FullName).Replace(';', '_');
|
||||
if (relativePath.StartsWith(".."))
|
||||
relativePath = relativePath[3..];
|
||||
file = new(fileInfo.LastWriteTime.Ticks, fileInfo.Length, relativePath);
|
||||
results.Add(file);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<File> GetFiles(string searchPattern, string[] ignoreFileNames, Record record) =>
|
||||
GetFiles(record.Directory, searchPattern, ignoreFileNames);
|
||||
|
||||
private static string? GetJsonIfNotEqual(string searchPattern, string[] ignoreFileNames, Record record, Job job, ReadOnlyCollection<File> files)
|
||||
{
|
||||
string? result;
|
||||
string? jsonNew;
|
||||
string? jsonOld;
|
||||
string fileName;
|
||||
int ignoreCount = 0;
|
||||
double filesTotalLengthNew = 0;
|
||||
File[] filesArray = files.ToArray();
|
||||
double filesTotalLengthOld = job.FilesTotalLength;
|
||||
foreach (File file in files)
|
||||
filesTotalLengthNew += file.Length;
|
||||
Job jobNew = new(job.AlternatePath,
|
||||
record.Directory,
|
||||
job.Extension,
|
||||
filesArray,
|
||||
files.Count,
|
||||
filesTotalLengthNew,
|
||||
job.Keep,
|
||||
job.Targets);
|
||||
result = JsonSerializer.Serialize(jobNew, JobSourceGenerationContext.Default.Job);
|
||||
if (filesTotalLengthNew != filesTotalLengthOld)
|
||||
{
|
||||
filesTotalLengthOld = 0;
|
||||
foreach (File file in job.Files)
|
||||
{
|
||||
fileName = Path.GetFileName(file.RelativePath);
|
||||
if (fileName == searchPattern || ignoreFileNames.Any(l => l == fileName))
|
||||
{
|
||||
ignoreCount += 1;
|
||||
continue;
|
||||
}
|
||||
if (file.Length == 0)
|
||||
{
|
||||
ignoreCount += 1;
|
||||
continue;
|
||||
}
|
||||
filesTotalLengthOld += file.Length;
|
||||
}
|
||||
}
|
||||
if (filesTotalLengthNew != filesTotalLengthOld || files.Count != (job.Files.Length - ignoreCount))
|
||||
{
|
||||
jsonNew = null;
|
||||
jsonOld = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonNew = JsonSerializer.Serialize((from l in filesArray orderby l.RelativePath.Length, l.RelativePath select l).ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
||||
jsonOld = JsonSerializer.Serialize((from l in job.Files orderby l.RelativePath.Length, l.RelativePath where l.RelativePath != searchPattern select l).ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(jsonNew) && !string.IsNullOrEmpty(jsonOld) && jsonNew == jsonOld)
|
||||
result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void WriteISO(Record record, ReadOnlyCollection<File> files, string path, string directoryName)
|
||||
{
|
||||
CDBuilder builder = new() { UseJoliet = true, VolumeIdentifier = directoryName.Length < 25 ? directoryName : directoryName[..25] };
|
||||
foreach (File file in files)
|
||||
_ = builder.AddFile(file.RelativePath, Path.Combine(record.Directory, file.RelativePath));
|
||||
builder.Build(path);
|
||||
}
|
||||
|
||||
private static void WriteZIP(Record record, ReadOnlyCollection<File> files, string path)
|
||||
{
|
||||
using ZipArchive zip = ZipFile.Open(path, ZipArchiveMode.Create);
|
||||
string directoryEntry;
|
||||
List<string> directoryEntries = [];
|
||||
foreach (File file in files)
|
||||
{
|
||||
directoryEntry = Path.GetDirectoryName(file.RelativePath) ?? throw new Exception();
|
||||
if (!directoryEntries.Contains(directoryEntry))
|
||||
continue;
|
||||
directoryEntries.Add(directoryEntry);
|
||||
_ = zip.CreateEntry(file.RelativePath);
|
||||
}
|
||||
foreach (File file in files)
|
||||
_ = zip.CreateEntryFromFile(Path.Combine(record.Directory, file.RelativePath), file.RelativePath);
|
||||
}
|
||||
|
||||
private static void WriteExtension(Record record, Job job, ReadOnlyCollection<File> files, string path)
|
||||
{
|
||||
string directoryName = Path.GetFileName(record.Directory);
|
||||
if (job.Extension.Equals(".iso", StringComparison.OrdinalIgnoreCase))
|
||||
WriteISO(record, files, path, directoryName);
|
||||
else if (job.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase))
|
||||
WriteZIP(record, files, path);
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static void PushTo(Job job, SecureShell secureShell, string path)
|
||||
{
|
||||
string remotePath = string.Concat(secureShell.Path, '/', Path.GetFileName(path));
|
||||
using SftpClient client = new(secureShell.Host, secureShell.User, new PrivateKeyFile(secureShell.Key));
|
||||
client.Connect();
|
||||
if (job.Files.Length == 0)
|
||||
{
|
||||
string directoryName = Path.GetDirectoryName(secureShell.Path) ?? throw new Exception();
|
||||
try
|
||||
{ client.CreateDirectory(Path.GetDirectoryName(directoryName) ?? throw new Exception()); }
|
||||
catch (Exception) { }
|
||||
try
|
||||
{ client.CreateDirectory(directoryName); }
|
||||
catch (Exception) { }
|
||||
try
|
||||
{ client.CreateDirectory(secureShell.Path); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
using FileStream fileStream = System.IO.File.OpenRead(path);
|
||||
client.UploadFile(fileStream, remotePath);
|
||||
}
|
||||
|
||||
private static void PushTo(ServerMessageBlock serverMessageBlock, string path)
|
||||
{
|
||||
string remotePath = Path.Combine(serverMessageBlock.Path, Path.GetFileName(path));
|
||||
System.IO.File.Copy(path, remotePath);
|
||||
}
|
||||
|
||||
private static void PushTo(string directory, string path)
|
||||
{
|
||||
string remotePath = Path.Combine(directory, Path.GetFileName(path));
|
||||
System.IO.File.Copy(path, remotePath);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Exception> PushTo(Job job, string path)
|
||||
{
|
||||
List<Exception> results = [];
|
||||
foreach (Target target in job.Targets)
|
||||
{
|
||||
if (target.SecureShell is not null)
|
||||
{
|
||||
try
|
||||
{ PushTo(job, target.SecureShell, path); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (target.SecureShell.Required)
|
||||
results.Add(ex);
|
||||
}
|
||||
}
|
||||
else if (target.ServerMessageBlock is not null)
|
||||
{
|
||||
try
|
||||
{ PushTo(target.ServerMessageBlock, path); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (target.ServerMessageBlock.Required)
|
||||
results.Add(ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void DeleteOld(Job job, SecureShell secureShell, string path)
|
||||
{
|
||||
List<string> results = [];
|
||||
using SftpClient client = new(secureShell.Host, secureShell.User, new PrivateKeyFile(secureShell.Key));
|
||||
client.Connect();
|
||||
foreach (ISftpFile file in client.ListDirectory(secureShell.Path))
|
||||
{
|
||||
if (file.Name == path)
|
||||
continue;
|
||||
if (!file.Name.EndsWith(job.Extension, StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
results.Add(file.FullName);
|
||||
}
|
||||
for (int i = job.Keep - 1; i < results.Count; i++)
|
||||
client.DeleteFile(results[i]);
|
||||
}
|
||||
|
||||
private static void DeleteOld(Job job, ServerMessageBlock serverMessageBlock, string path)
|
||||
{
|
||||
List<string> results = [];
|
||||
string[] files = Directory.GetFiles(serverMessageBlock.Path, $"*{job.Extension}", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
if (file == path)
|
||||
continue;
|
||||
results.Add(file);
|
||||
}
|
||||
for (int i = job.Keep - 1; i < results.Count; i++)
|
||||
System.IO.File.Delete(results[i]);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Exception> DeleteOld(Job job, string path)
|
||||
{
|
||||
List<Exception> results = [];
|
||||
foreach (Target target in job.Targets)
|
||||
{
|
||||
if (target.SecureShell is not null)
|
||||
{
|
||||
try
|
||||
{ DeleteOld(job, target.SecureShell, path); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (target.SecureShell.Required)
|
||||
results.Add(ex);
|
||||
}
|
||||
}
|
||||
else if (target.ServerMessageBlock is not null)
|
||||
{
|
||||
try
|
||||
{ DeleteOld(job, target.ServerMessageBlock, path); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (target.ServerMessageBlock.Required)
|
||||
results.Add(ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void Verify(string searchPattern, string[] ignoreFileNames)
|
||||
{
|
||||
List<Target> targets = [
|
||||
new(new SecureShell("free.file.sync.root", "C:/Users/phares/.ssh/id_ed25519", "\\home", true, "root"), null),
|
||||
new(null, new ServerMessageBlock("\\\\mesfs.infineon.com\\EC_APC\\DEV", true))
|
||||
];
|
||||
string directory = Path.Combine(Environment.CurrentDirectory, ".vscode", "helper");
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
ReadOnlyCollection<File> files = GetFiles(directory, searchPattern, ignoreFileNames);
|
||||
double filesTotalLength = 0;
|
||||
foreach (File file in files)
|
||||
filesTotalLength += file.Length;
|
||||
Job job = new(
|
||||
"C:/Users/phares",
|
||||
directory,
|
||||
"*.iso",
|
||||
files.ToArray(),
|
||||
files.Count,
|
||||
filesTotalLength,
|
||||
3,
|
||||
targets.ToArray());
|
||||
string json = JsonSerializer.Serialize(job, JobSourceGenerationContext.Default.Job);
|
||||
System.IO.File.WriteAllText(Path.Combine(directory, "verify.json"), json);
|
||||
}
|
||||
|
||||
internal static void Backup(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string path;
|
||||
string? json;
|
||||
string directoryName;
|
||||
ReadOnlyCollection<File> files;
|
||||
string searchPattern = args[2];
|
||||
ReadOnlyCollection<Exception> exceptions;
|
||||
string[] ignoreFileNames = args[3].Split('|');
|
||||
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||
logger.LogInformation("Searching <{sourceDirectory}> with search pattern {searchPattern}", args[0], searchPattern);
|
||||
if (Debugger.IsAttached)
|
||||
Verify(searchPattern, ignoreFileNames);
|
||||
IEnumerable<Record> records = GetRecords(sourceDirectory, searchPattern);
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (record.Job is null || record.Job.Targets.Length == 0 || string.IsNullOrEmpty(record.Job.Extension))
|
||||
continue;
|
||||
logger.LogInformation("Searching <{directory}>", record.Directory);
|
||||
files = GetFiles(searchPattern, ignoreFileNames, record);
|
||||
json = GetJsonIfNotEqual(searchPattern, ignoreFileNames, record, record.Job, files);
|
||||
if (string.IsNullOrEmpty(json))
|
||||
continue;
|
||||
directoryName = Path.GetFileName(record.Directory);
|
||||
path = Path.Combine(record.Directory, $"{directoryName}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss-fff}{record.Job.Extension}");
|
||||
logger.LogInformation("Writing <{directory}> extension", record.Directory);
|
||||
WriteExtension(record, record.Job, files, path);
|
||||
logger.LogInformation("Pushing <{directory}> extension", record.Directory);
|
||||
exceptions = PushTo(record.Job, path);
|
||||
if (exceptions.Count != 0)
|
||||
{
|
||||
foreach (Exception exception in exceptions)
|
||||
logger.LogError(exception, exception.Message);
|
||||
PushTo(record.Job.AlternatePath, path);
|
||||
}
|
||||
System.IO.File.WriteAllText(record.Path, json);
|
||||
System.IO.File.Delete(path);
|
||||
logger.LogInformation("Deleting old <{directory}> extension", record.Directory);
|
||||
exceptions = DeleteOld(record.Job, path);
|
||||
if (exceptions.Count != 0)
|
||||
{
|
||||
foreach (Exception exception in exceptions)
|
||||
logger.LogError(exception, exception.Message);
|
||||
}
|
||||
}
|
||||
if (Debugger.IsAttached && records.Count() == 0)
|
||||
{
|
||||
files = GetFiles(sourceDirectory, searchPattern, ignoreFileNames);
|
||||
json = JsonSerializer.Serialize(files.ToArray(), FilesSourceGenerationContext.Default.FileArray);
|
||||
System.IO.File.WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".json"), json);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
195
ADO2024/PI4/Helper-2024-12-24.cs
Normal file
195
ADO2024/PI4/Helper-2024-12-24.cs
Normal file
@ -0,0 +1,195 @@
|
||||
using File_Folder_Helper.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
#if ShellProgressBar
|
||||
using ShellProgressBar;
|
||||
#endif
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace File_Folder_Helper.ADO2024.PI4;
|
||||
|
||||
internal static partial class Helper20241224
|
||||
{
|
||||
|
||||
private static readonly HttpClient _HttpClient = new();
|
||||
|
||||
private record Record(Uri URI, string Path, DateTime LastModified);
|
||||
|
||||
private static ReadOnlyCollection<NginxFileSystem>? GetRecursiveCollection(string host, string page)
|
||||
{
|
||||
List<NginxFileSystem>? results;
|
||||
Uri uri = new($"https://{host}/{page}");
|
||||
string format = NginxFileSystem.GetFormat();
|
||||
TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local;
|
||||
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
|
||||
taskHttpResponseMessage.Wait();
|
||||
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
taskString.Wait();
|
||||
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
|
||||
if (nginxFileSystems is null)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
results = [];
|
||||
NginxFileSystem nginxFileSystem;
|
||||
ReadOnlyCollection<NginxFileSystem>? directory;
|
||||
for (int i = 0; i < nginxFileSystems.Length; i++)
|
||||
{
|
||||
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
|
||||
if (nginxFileSystem.Type == "file")
|
||||
results.Add(nginxFileSystem);
|
||||
else
|
||||
{
|
||||
directory = GetRecursiveCollection(host, $"{page}/{nginxFileSystem.Name}");
|
||||
if (directory is null)
|
||||
continue;
|
||||
results.AddRange(directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results?.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<NginxFileSystem>? GetCollection(string format, TimeZoneInfo timeZoneInfo, Uri uri)
|
||||
{
|
||||
List<NginxFileSystem>? results;
|
||||
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(uri);
|
||||
taskHttpResponseMessage.Wait();
|
||||
if (!taskHttpResponseMessage.Result.IsSuccessStatusCode)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
taskString.Wait();
|
||||
NginxFileSystem[]? nginxFileSystems = JsonSerializer.Deserialize(taskString.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
|
||||
if (nginxFileSystems is null)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
results = [];
|
||||
NginxFileSystem nginxFileSystem;
|
||||
for (int i = 0; i < nginxFileSystems.Length; i++)
|
||||
{
|
||||
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
|
||||
results.Add(nginxFileSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results?.AsReadOnly();
|
||||
}
|
||||
|
||||
private static Record? CompareFile(string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem)
|
||||
{
|
||||
Record? result;
|
||||
if (nginxFileSystem.LastModified is null || nginxFileSystem.Length is null)
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}/{nginxFileSystem.Name}");
|
||||
FileInfo fileInfo = new($"{compareDirectory}\\{string.Join('\\', directoryNames)}\\{nginxFileSystem.Name}");
|
||||
if (!fileInfo.Exists || fileInfo.Length != nginxFileSystem.Length.Value)
|
||||
result = new(uri, fileInfo.FullName, nginxFileSystem.LastModified.Value);
|
||||
else
|
||||
{
|
||||
double totalSeconds = new TimeSpan(fileInfo.LastWriteTime.Ticks - nginxFileSystem.LastModified.Value.Ticks).TotalSeconds;
|
||||
if (totalSeconds is < 2 and > -2)
|
||||
result = null;
|
||||
else
|
||||
result = new(uri, fileInfo.FullName, nginxFileSystem.LastModified.Value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> CompareDirectory(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory, NginxFileSystem nginxFileSystem)
|
||||
{
|
||||
ReadOnlyCollection<Record> results;
|
||||
List<string> collection = directoryNames.ToList();
|
||||
collection.Add(nginxFileSystem.Name);
|
||||
results = GetRecord(format, timeZoneInfo, host, collection.AsReadOnly(), compareDirectory);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecord(string format, TimeZoneInfo timeZoneInfo, string host, ReadOnlyCollection<string> directoryNames, string compareDirectory)
|
||||
{
|
||||
List<Record> results = [];
|
||||
Uri uri = new($"https://{host}/{string.Join('/', directoryNames)}");
|
||||
ReadOnlyCollection<NginxFileSystem>? nginxFileSystems = GetCollection(format, timeZoneInfo, uri);
|
||||
if (nginxFileSystems is not null)
|
||||
{
|
||||
NginxFileSystem nginxFileSystem;
|
||||
ReadOnlyCollection<Record> records;
|
||||
string checkDirectory = $"{compareDirectory}\\{string.Join('\\', directoryNames)}";
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
for (int i = 0; i < nginxFileSystems.Count; i++)
|
||||
{
|
||||
nginxFileSystem = NginxFileSystem.Get(format, timeZoneInfo, uri, nginxFileSystems[i]);
|
||||
if (nginxFileSystem.Type == "file")
|
||||
{
|
||||
Record? record = CompareFile(host, directoryNames, compareDirectory, nginxFileSystem);
|
||||
if (record is not null)
|
||||
results.Add(record);
|
||||
}
|
||||
else
|
||||
{
|
||||
records = CompareDirectory(format, timeZoneInfo, host, directoryNames, compareDirectory, nginxFileSystem);
|
||||
foreach (Record record in records)
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void Download(Record record)
|
||||
{
|
||||
Task<HttpResponseMessage> taskHttpResponseMessage = _HttpClient.GetAsync(record.URI);
|
||||
taskHttpResponseMessage.Wait();
|
||||
if (taskHttpResponseMessage.Result.IsSuccessStatusCode)
|
||||
{
|
||||
Task<string> taskString = taskHttpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
taskString.Wait();
|
||||
File.WriteAllText(record.Path, taskString.Result);
|
||||
File.SetLastWriteTime(record.Path, record.LastModified);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Compare(ILogger<Worker> logger, List<string> args)
|
||||
{
|
||||
string host = args[2];
|
||||
string rootDirectoryName = args[3];
|
||||
string format = NginxFileSystem.GetFormat();
|
||||
TimeZoneInfo timeZoneInfo = TimeZoneInfo.Local;
|
||||
string compareDirectory = Path.GetFullPath(args[0]);
|
||||
logger.LogInformation("Comparing files on {host}", host);
|
||||
ReadOnlyCollection<Record> records = GetRecord(format, timeZoneInfo, host, new([rootDirectoryName]), compareDirectory);
|
||||
#if ShellProgressBar
|
||||
ProgressBar progressBar = new(records.Count, "Downloading", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
|
||||
#endif
|
||||
foreach (Record record in records)
|
||||
{
|
||||
#if ShellProgressBar
|
||||
progressBar.Tick();
|
||||
#endif
|
||||
Download(record);
|
||||
}
|
||||
#if ShellProgressBar
|
||||
progressBar.Dispose();
|
||||
#endif
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
ReadOnlyCollection<NginxFileSystem>? recursiveCollection = GetRecursiveCollection(host, rootDirectoryName);
|
||||
string? json = recursiveCollection is null ? null : JsonSerializer.Serialize(recursiveCollection.ToArray(), NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
File.WriteAllText(Path.Combine(Environment.CurrentDirectory, ".vscode", "helper", ".json"), json);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user