diff --git a/Program.cs b/Program.cs index 96a59f6..caa80f4 100644 --- a/Program.cs +++ b/Program.cs @@ -5,6 +5,7 @@ global using DTLib.Filesystem; global using File = DTLib.Filesystem.File; global using Directory = DTLib.Filesystem.Directory; using DTLib.Ben.Demystifier; +using DTLib.Extensions; using SyncDirectory.Storage; Console.InputEncoding = Encoding.UTF8; @@ -18,7 +19,10 @@ try "SyncDirectory-data-debug" #endif ); - storage.CreateSnapshot("tmp", "tmp"); + var s1=storage.CreateSnapshot("tmp", "tmp"); + var s2=storage.CreateSnapshot("tmp2", "tmp2"); + var diff = DirectorySnapshotDiff.Diff(s1, s2); + Console.WriteLine(diff.FileDiffs.MergeToString('\n')); } catch (Exception ex) { diff --git a/Storage/DirectorySnapshot.cs b/Storage/DirectorySnapshot.cs index f22b4b7..0056b8a 100644 --- a/Storage/DirectorySnapshot.cs +++ b/Storage/DirectorySnapshot.cs @@ -1,4 +1,5 @@ -using System.Collections.Immutable; +using System.Collections; +using System.Collections.Immutable; using System.Globalization; using System.Linq; using DTLib; @@ -10,8 +11,11 @@ public record DirectorySnapshot( string Name, IOPath Path, DateTime SnapshotTimeUTC, - IReadOnlyCollection Files) + FileSnapshot[] Files) { + public Lazy> PathMap = new(() => + new Dictionary(Files.ToDictionary(f=>f.Path.Str))); + public static DirectorySnapshot Parse(DtsodV23 dtsod) => new DirectorySnapshot( dtsod["name"], @@ -22,7 +26,7 @@ public record DirectorySnapshot( CultureInfo.InvariantCulture), ((List)dtsod["files"]) .Select(fd=>FileSnapshot.Parse((DtsodV23)fd)) - .ToImmutableList() + .ToArray() ); public DtsodV23 ToDtsod() => @@ -38,10 +42,7 @@ public record DirectorySnapshot( { var fileSnapshots = new List(); foreach (var filePath in Directory.GetAllFiles(dirPath)) - { - fileSnapshots.Add(FileSnapshot.Create(filePath)); - } - - return new DirectorySnapshot(name, dirPath, DateTime.UtcNow, fileSnapshots); + fileSnapshots.Add(FileSnapshot.Create(filePath, dirPath)); + return new DirectorySnapshot(name, dirPath, DateTime.UtcNow, fileSnapshots.ToArray()); } } \ No newline at end of file diff --git a/Storage/DirectorySnapshotDiff.cs b/Storage/DirectorySnapshotDiff.cs new file mode 100644 index 0000000..f166aed --- /dev/null +++ b/Storage/DirectorySnapshotDiff.cs @@ -0,0 +1,28 @@ +using System.Linq; + +namespace SyncDirectory.Storage; + +public record DirectorySnapshotDiff(ICollection FileDiffs) +{ + public static DirectorySnapshotDiff Diff(DirectorySnapshot firstLocal, DirectorySnapshot secondLocal) + { + List files = new(); + foreach (var file in secondLocal.Files) + { + if(firstLocal.PathMap.Value.TryGetValue(file.Path.Str, out var filePrev)) + { + files.Add(new FileSnapshotDiff(file, + file.ModifyTimeUTC == filePrev.ModifyTimeUTC ? FileStatus.Unchanged : FileStatus.Modified)); + } + else files.Add(new FileSnapshotDiff(file, FileStatus.Created)); + } + + foreach (var filePrev in firstLocal.Files) + { + if(!secondLocal.PathMap.Value.ContainsKey(filePrev.Path.Str)) + files.Add(new FileSnapshotDiff(filePrev, FileStatus.Deleted)); + } + + return new DirectorySnapshotDiff(files); + } +} \ No newline at end of file diff --git a/Storage/FileSnapshot.cs b/Storage/FileSnapshot.cs index 67e3910..e4d0284 100644 --- a/Storage/FileSnapshot.cs +++ b/Storage/FileSnapshot.cs @@ -10,13 +10,19 @@ public record FileSnapshot( DateTime ModifyTimeUTC, DateTime SnapshotTimeUTC) { - public static FileSnapshot Create(IOPath filePath) + /// + /// Creates new FileSnapshot from an exnsting file + /// + /// baseDirPath+filePathInBaseDir + /// will be removed from fullFilePath in the rezult FileSnapshot.Path + /// + public static FileSnapshot Create(IOPath fullFilePath, IOPath baseDirPath) { - var creationTime = System.IO.File.GetCreationTimeUtc(filePath.Str); - var modifyTime = System.IO.File.GetLastWriteTimeUtc(filePath.Str); + var creationTime = System.IO.File.GetCreationTimeUtc(fullFilePath.Str); + var modifyTime = System.IO.File.GetLastWriteTimeUtc(fullFilePath.Str); // sometimes LastWriteTime can be less then CreationTime when unpacking archives var latest = modifyTime > creationTime ? modifyTime : creationTime; - return new FileSnapshot(filePath, FileSize.Get(filePath), latest, DateTime.UtcNow); + return new FileSnapshot(fullFilePath.RemoveBase(baseDirPath), FileSize.Get(fullFilePath), latest, DateTime.UtcNow); } public static FileSnapshot Parse(DtsodV23 dtsod) => diff --git a/Storage/FileSnapshotDiff.cs b/Storage/FileSnapshotDiff.cs new file mode 100644 index 0000000..3e8f840 --- /dev/null +++ b/Storage/FileSnapshotDiff.cs @@ -0,0 +1,6 @@ +namespace SyncDirectory.Storage; + +public record FileSnapshotDiff(FileSnapshot File, FileStatus Status) +{ + +} \ No newline at end of file diff --git a/Storage/FileStatus.cs b/Storage/FileStatus.cs new file mode 100644 index 0000000..bedc08f --- /dev/null +++ b/Storage/FileStatus.cs @@ -0,0 +1,9 @@ +namespace SyncDirectory.Storage; + +public enum FileStatus +{ + Unchanged, + Created, + Modified, + Deleted, +} \ No newline at end of file