237 lines
10 KiB
C#
237 lines
10 KiB
C#
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);
|
|
}
|
|
}
|
|
|
|
private static ReadOnlyDictionary<string, List<FileInfo>> GetKeyValuePairs(string directory, string searchPattern, string split)
|
|
{
|
|
string key;
|
|
List<FileInfo>? collection;
|
|
Dictionary<string, List<FileInfo>> results = [];
|
|
string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
|
FileInfo[] fileInfoCollection = files.Select(l => new FileInfo(l)).ToArray();
|
|
foreach (FileInfo fileInfo in fileInfoCollection.OrderBy(l => l.LastWriteTime))
|
|
{
|
|
key = fileInfo.Name.Split(split)[0];
|
|
if (!results.TryGetValue(key, out collection))
|
|
{
|
|
results.Add(key, []);
|
|
if (!results.TryGetValue(key, out collection))
|
|
throw new Exception();
|
|
}
|
|
collection.Add(fileInfo);
|
|
}
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
private static void DeleteFirst(string directory)
|
|
{
|
|
string checkFile;
|
|
FileInfo fileInfo;
|
|
ReadOnlyDictionary<string, List<FileInfo>> keyValuePairs = GetKeyValuePairs(directory, "*.tar", $"-{DateTime.Now.Year}-");
|
|
foreach (KeyValuePair<string, List<FileInfo>> keyValuePair in keyValuePairs)
|
|
{
|
|
if (keyValuePair.Value.Count < 3)
|
|
continue;
|
|
for (int i = 1; i < keyValuePair.Value.Count - 1; i++)
|
|
{
|
|
fileInfo = keyValuePair.Value[i];
|
|
checkFile = Path.Combine($"{fileInfo.Directory}-Delete", fileInfo.Name);
|
|
if (File.Exists(checkFile))
|
|
continue;
|
|
File.Move(fileInfo.FullName, checkFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
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]);
|
|
DeleteFirst(compareDirectory);
|
|
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);
|
|
}
|
|
}
|
|
|
|
} |