namespace FileExposer.Models; using System; using System.Collections.ObjectModel; using System.IO; using System.Text.Json; using System.Threading.Tasks; using Microsoft.Extensions.FileSystemGlobbing; public class SyncV1Repository(AppSettings appSettings) : ISyncV1Repository { private readonly string _RepositoryName = nameof(SyncV1Repository)[..^10]; private readonly AppSettings _AppSettings = appSettings; void ISyncV1Repository.Delete(string path, long size, long ticks) { FileInfo fileInfo = Verify(path, size, ticks); if (fileInfo.FullName != path) throw new Exception("Path must match!"); File.Delete(path); } Get ISyncV1Repository.Get(string path, long? size, long? ticks) { Get result; if (string.IsNullOrEmpty(path)) throw new Exception("Path mush be set!"); if (size is not null && ticks is not null) { FileInfo fileInfo = Verify(path, size.Value, ticks.Value); result = new(JSON: null, Bytes: File.ReadAllBytes(fileInfo.FullName)); } else { if (File.Exists(path)) throw new Exception("Must pass size and ticks when passing a file!"); string directory = Path.GetFullPath(path); string excludePatternsFile = Path.Combine(directory, _AppSettings.SyncConfiguration.ExcludePatternsFile); string includePatternsFile = Path.Combine(directory, _AppSettings.SyncConfiguration.IncludePatternsFile); Matcher matcher = GetMatcher(excludePatternsFile, includePatternsFile); ReadOnlyCollection records = Record.GetRecords(matcher, directory); RelativePath relativePath = new(LeftDirectory: path, Records: [.. records], RightDirectory: null); result = new(JSON: JsonSerializer.Serialize(relativePath, RelativePathSourceGenerationContext.Default.RelativePath), Bytes: null); } return result; } private static Matcher GetMatcher(string excludePatternsFile, string includePatternsFile) { Matcher result = new(); result.AddIncludePatterns(!File.Exists(includePatternsFile) ? ["*"] : File.ReadAllLines(includePatternsFile)); result.AddExcludePatterns(!File.Exists(excludePatternsFile) ? ["System Volume Information"] : File.ReadAllLines(excludePatternsFile)); return result; } private FileInfo Verify(string path, long size, long ticks) { FileInfo fileInfo = new(path); if (fileInfo.Length != size) throw new Exception("Size must match!"); TimeSpan timeSpan = new(fileInfo.LastWriteTime.ToUniversalTime().Ticks - ticks); if (Math.Abs(timeSpan.TotalSeconds) > _AppSettings.SyncConfiguration.SecondThreshold) throw new Exception("Ticks must be within the threshold!"); return fileInfo; } string ISyncV1Repository.Post(Stream stream) { string result; RelativePath? relativePath = RelativePath.Get(stream) ?? throw new MissingFieldException(); string directory = Path.GetFullPath(relativePath.LeftDirectory); string excludePatternsFile = Path.Combine(directory, _AppSettings.SyncConfiguration.ExcludePatternsFile); string includePatternsFile = Path.Combine(directory, _AppSettings.SyncConfiguration.IncludePatternsFile); Matcher matcher = GetMatcher(excludePatternsFile, includePatternsFile); ReadOnlyCollection records = Record.GetRecords(matcher, directory); if (records.Count == 0) throw new Exception("No source records"); Review review = Review.Get(relativePath, records); result = JsonSerializer.Serialize(review, ReviewSourceGenerationContext.Default.Review); return result; } void ISyncV1Repository.Patch(string path, string data, Stream stream) { string st = "d:/Tmp/phares/VisualStudioCode/z-include-patterns - Copy C.nsv"; FileStream fileStream = new(st, FileMode.Truncate); Task task = stream.CopyToAsync(fileStream); task.Wait(); fileStream.Dispose(); } void ISyncV1Repository.Put(string path, string data, Stream stream) { string st = "d:/Tmp/phares/VisualStudioCode/z-include-patterns - Copy C.nsv"; FileStream fileStream = new(st, FileMode.CreateNew); Task task = stream.CopyToAsync(fileStream); task.Wait(); fileStream.Dispose(); } }