using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Phares.Shared; using ShellProgressBar; using System.Text; using View_by_Distance.Move.By.Id.Models; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Methods; namespace View_by_Distance.Move.By.Id; public class MoveById { private readonly AppSettings _AppSettings; private readonly string _WorkingDirectory; private readonly IsEnvironment _IsEnvironment; private readonly Configuration _Configuration; private readonly IConfigurationRoot _ConfigurationRoot; private readonly Property.Models.Configuration _PropertyConfiguration; public MoveById(List args, ILogger logger, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console) { if (isSilent) { } if (console is null) { } _AppSettings = appSettings; _IsEnvironment = isEnvironment; _WorkingDirectory = workingDirectory; _ConfigurationRoot = configurationRoot; Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot); Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration); _PropertyConfiguration = propertyConfiguration; _Configuration = configuration; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; string? comparePathRoot = Path.GetDirectoryName(appSettings.ComparePathsFile); if (comparePathRoot is null || comparePathRoot == propertyConfiguration.RootDirectory) throw new Exception("Nested isn't allowed!"); logger?.LogInformation(propertyConfiguration.RootDirectory); Property.Models.Configuration.Verify(propertyConfiguration, requireExist: false); Verify(); string json = File.ReadAllText(appSettings.ComparePathsFile); MatchNginx[]? matchNginxCollection = System.Text.Json.JsonSerializer.Deserialize(json); if (matchNginxCollection is null) throw new NullReferenceException(nameof(matchNginxCollection)); if (matchNginxCollection.Length != 0) { List lines = MoveFilesByIdInDirectories(options, matchNginxCollection); File.WriteAllLines($"D:/Tmp/Phares/{DateTime.Now.Ticks}.tsv", lines); if (comparePathRoot != Path.GetPathRoot(matchNginxCollection[0].ConvertedPath)) _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(comparePathRoot); } } private void Verify() { if (_AppSettings is null) { } if (_IsEnvironment is null) { } if (_Configuration is null) { } if (_ConfigurationRoot is null) { } if (_WorkingDirectory is null) { } } private static List GetAllFiles(MatchNginx[] matchNginxCollection) { List allFiles = []; string[] files; string directoryName; ReadOnlySpan span; foreach (MatchNginx matchNginx in matchNginxCollection) { if (matchNginx.ConvertedPath.Length < 6) continue; directoryName = Path.GetFileName(matchNginx.ConvertedPath); if (matchNginx.ConvertedPath.Contains("!---")) span = "0"; else span = matchNginx.ConvertedPath.AsSpan(matchNginx.ConvertedPath.Length - 5, 3); if (directoryName.Length == 1 && int.TryParse(span, out int age)) continue; if (File.Exists(matchNginx.ConvertedPath)) continue; files = Directory.GetFiles(matchNginx.ConvertedPath, "*", SearchOption.AllDirectories); if (files.All(l => l.EndsWith(".id"))) { foreach (string file in files) File.Delete(file); continue; } allFiles.AddRange(files); } return allFiles; } private List GetToDoCollection(ProgressBar progressBar, List allFiles) { List results = []; int? id; string? message; string[] matches; FilePath filePath; FileHolder fileHolder; bool isIgnoreExtension; const string jpeg = ".jpeg"; bool isValidImageFormatExtension; ASCIIEncoding asciiEncoding = new(); foreach (string file in allFiles) { progressBar.Tick(); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file); filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null); if (fileHolder.ExtensionLowered == ".id" || fileHolder.DirectoryFullPath is null) continue; if (allFiles.Contains($"{fileHolder.FullName}.id")) continue; isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered); if (!isIgnoreExtension && !isValidImageFormatExtension) { if (fileHolder.ExtensionLowered == jpeg) continue; if (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null) continue; } (_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding); if (id is null) continue; matches = (from l in allFiles where l.Contains($"{id}{fileHolder.ExtensionLowered}") select l).ToArray(); if (matches.Length == 0) continue; results.Add(fileHolder.FullName); results.AddRange(matches); } return results; } private static void CreateDirectories(List directories) { foreach (string directory in directories) { if (Directory.Exists(directory)) continue; _ = Directory.CreateDirectory(directory); } } private List MoveFilesByIdInDirectories(ProgressBarOptions options, MatchNginx[] matchNginxCollection) { List results = []; string moveTo; string? directory; string message = "Moving allFiles"; List distinctDirectories = []; List allFiles = GetAllFiles(matchNginxCollection); ProgressBar progressBar = new(allFiles.Count, message, options); List toDoCollection = GetToDoCollection(progressBar, allFiles); progressBar.Dispose(); List<(string, string)> moveCollection = []; foreach (string file in toDoCollection) { moveTo = $"{_AppSettings.MoveTo}{file[1..]}"; directory = Path.GetDirectoryName(moveTo); if (directory is null) continue; moveCollection.Add(new(file, moveTo)); if (distinctDirectories.Contains(directory)) continue; distinctDirectories.Add(directory); } CreateDirectories(distinctDirectories); foreach ((string from, string to) in moveCollection) { if (File.Exists(to)) continue; File.Move(from, to); } return results; } }