using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using Microsoft.Extensions.FileSystemGlobbing; namespace FileExposer.Models; public record Record(string RelativePath, long Size, long Ticks) { internal static ReadOnlyCollection GetCollection(SyncConfiguration syncConfiguration, string rightDirectory) { ReadOnlyCollection results; Matcher matcher = new(); string excludePatternsFile = Path.Combine(rightDirectory, syncConfiguration.ExcludePatternsFile); string includePatternsFile = Path.Combine(rightDirectory, syncConfiguration.IncludePatternsFile); matcher.AddIncludePatterns(!File.Exists(includePatternsFile) ? ["*"] : File.ReadAllLines(includePatternsFile)); matcher.AddExcludePatterns(!File.Exists(excludePatternsFile) ? ["System Volume Information"] : File.ReadAllLines(excludePatternsFile)); results = GetRecords(rightDirectory, matcher); return results; } private static ReadOnlyCollection GetRecords(string rightDirectory, Matcher matcher) { List results = []; Record record; FileInfo fileInfo; string relativePath; ReadOnlyCollection> collection = GetFilesCollection(rightDirectory, "*", "*"); foreach (ReadOnlyCollection c in collection) { foreach (string f in c) { if (!matcher.Match(rightDirectory, f).HasMatches) continue; fileInfo = new(f); if (fileInfo.Length == 0) continue; relativePath = Path.GetRelativePath(rightDirectory, fileInfo.FullName); record = new(RelativePath: relativePath, Size: fileInfo.Length, Ticks: fileInfo.LastWriteTime.ToUniversalTime().Ticks); results.Add(record); } } return results.AsReadOnly(); } private static ReadOnlyCollection> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter) { List> results = []; string[] files; if (!fileSearchFilter.Contains('*')) fileSearchFilter = string.Concat('*', fileSearchFilter); if (!directorySearchFilter.Contains('*')) directorySearchFilter = string.Concat('*', directorySearchFilter); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); results.Add(Directory.GetFiles(directory, fileSearchFilter, SearchOption.TopDirectoryOnly).AsReadOnly()); string[] directories = Directory.GetDirectories(directory, directorySearchFilter, SearchOption.TopDirectoryOnly); foreach (string innerDirectory in directories) { try { files = Directory.GetFiles(innerDirectory, fileSearchFilter, SearchOption.AllDirectories); if (files.Length == 0) continue; results.Add(files.AsReadOnly()); } catch (UnauthorizedAccessException) { continue; } } return results.AsReadOnly(); } }