Initialize
This commit is contained in:
60
Models/AppSettings.cs
Normal file
60
Models/AppSettings.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public record AppSettings(FileWatcherConfiguration FileWatcherConfiguration,
|
||||
SyncConfiguration SyncConfiguration)
|
||||
{
|
||||
|
||||
public static AppSettings Get(IConfigurationRoot configurationRoot)
|
||||
{
|
||||
AppSettings result;
|
||||
#pragma warning disable IL3050, IL2026
|
||||
FileWatcherConfiguration? fileWatcherConfiguration = configurationRoot.GetSection(nameof(FileWatcherConfiguration)).Get<FileWatcherConfiguration>();
|
||||
SyncConfiguration? syncConfiguration = configurationRoot.GetSection(nameof(SyncConfiguration)).Get<SyncConfiguration>();
|
||||
#pragma warning restore IL3050, IL2026
|
||||
if (fileWatcherConfiguration is null
|
||||
|| syncConfiguration is null
|
||||
|| fileWatcherConfiguration?.Company is null)
|
||||
{
|
||||
List<string> paths = [];
|
||||
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||
{
|
||||
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||
continue;
|
||||
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||
continue;
|
||||
paths.Add(physicalFileProvider.Root);
|
||||
}
|
||||
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||
}
|
||||
result = new(fileWatcherConfiguration,
|
||||
syncConfiguration);
|
||||
Verify(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void Verify(AppSettings appSettings)
|
||||
{
|
||||
if (appSettings.FileWatcherConfiguration.MaxDegreeOfParallelism > Environment.ProcessorCount)
|
||||
throw new Exception($"Environment.ProcessorCount must be larger or equal to {nameof(appSettings.FileWatcherConfiguration.MaxDegreeOfParallelism)}");
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(AppSettings))]
|
||||
internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
24
Models/FileWatcherConfiguration.cs
Normal file
24
Models/FileWatcherConfiguration.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public record FileWatcherConfiguration(string Company,
|
||||
string Helper,
|
||||
int MaxDegreeOfParallelism,
|
||||
string UniformResourceLocator)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, FileWatcherConfigurationSourceGenerationContext.Default.FileWatcherConfiguration);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(FileWatcherConfiguration))]
|
||||
internal partial class FileWatcherConfigurationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
4
Models/Get.cs
Normal file
4
Models/Get.cs
Normal file
@ -0,0 +1,4 @@
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public record Get(string? JSON,
|
||||
byte[]? Bytes);
|
13
Models/ISyncV1Controller.cs
Normal file
13
Models/ISyncV1Controller.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public interface ISyncV1Controller<T, TT>
|
||||
{
|
||||
|
||||
static string GetRouteName() => nameof(ISyncV1Controller<T, TT>)[1..^10];
|
||||
T Post();
|
||||
T Put(string path, TT formFiles);
|
||||
T Patch(string path, TT formFiles);
|
||||
T Get(string path, long? size, long? ticks);
|
||||
T Delete(string path, long size, long ticks);
|
||||
|
||||
}
|
15
Models/ISyncV1Repository.cs
Normal file
15
Models/ISyncV1Repository.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public interface ISyncV1Repository
|
||||
{
|
||||
|
||||
string Post(Stream stream);
|
||||
Get Get(string path, long? size, long? ticks);
|
||||
void Delete(string path, long size, long ticks);
|
||||
void Put(string path, string data, Stream stream);
|
||||
void Patch(string path, string data, Stream stream);
|
||||
|
||||
}
|
79
Models/Record.cs
Normal file
79
Models/Record.cs
Normal file
@ -0,0 +1,79 @@
|
||||
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<Record> GetCollection(SyncConfiguration syncConfiguration, string rightDirectory)
|
||||
{
|
||||
ReadOnlyCollection<Record> 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<Record> GetRecords(string rightDirectory, Matcher matcher)
|
||||
{
|
||||
List<Record> results = [];
|
||||
Record record;
|
||||
FileInfo fileInfo;
|
||||
string relativePath;
|
||||
ReadOnlyCollection<ReadOnlyCollection<string>> collection = GetFilesCollection(rightDirectory, "*", "*");
|
||||
foreach (ReadOnlyCollection<string> 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<ReadOnlyCollection<string>> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter)
|
||||
{
|
||||
List<ReadOnlyCollection<string>> 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();
|
||||
}
|
||||
|
||||
}
|
39
Models/RelativePath.cs
Normal file
39
Models/RelativePath.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public record RelativePath(string Path,
|
||||
Record[] Records)
|
||||
{
|
||||
|
||||
internal static RelativePath? Get(Stream stream)
|
||||
{
|
||||
RelativePath? result;
|
||||
string? json = GetJson(stream);
|
||||
result = string.IsNullOrEmpty(json) ? null : JsonSerializer.Deserialize<RelativePath>(json);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string? GetJson(Stream stream)
|
||||
{
|
||||
string? result;
|
||||
if (!stream.CanRead)
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
Task<string> task = new StreamReader(stream).ReadToEndAsync();
|
||||
result = task.Result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(RelativePath))]
|
||||
public partial class RelativePathSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
233
Models/Review.cs
Normal file
233
Models/Review.cs
Normal file
@ -0,0 +1,233 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public record Review(Segment[]? AreEqual,
|
||||
Segment[]? LeftSideIsNewer,
|
||||
Segment[]? LeftSideOnly,
|
||||
Segment[]? NotEqualBut,
|
||||
Record[]? Records,
|
||||
Segment[]? RightSideIsNewer,
|
||||
Segment[]? RightSideOnly)
|
||||
{
|
||||
|
||||
internal static Review Get(RelativePath relativePath, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
Review result;
|
||||
ReadOnlyCollection<Segment> areEqual = GetAreEqual(relativePath, records);
|
||||
ReadOnlyCollection<Segment> notEqualBut = GetNotEqualBut(relativePath, records);
|
||||
ReadOnlyCollection<Segment> leftSideOnly = GetLeftSideOnly(relativePath, records);
|
||||
ReadOnlyCollection<Segment> rightSideOnly = GetRightSideOnly(relativePath, records);
|
||||
ReadOnlyCollection<Segment> leftSideIsNewer = GetLeftSideIsNewer(relativePath, records);
|
||||
ReadOnlyCollection<Segment> rightSideIsNewer = GetRightSideIsNewer(relativePath, records);
|
||||
result = new(AreEqual: [.. areEqual],
|
||||
LeftSideIsNewer: [.. leftSideIsNewer],
|
||||
LeftSideOnly: [.. leftSideOnly],
|
||||
NotEqualBut: [.. notEqualBut],
|
||||
Records: null,
|
||||
RightSideIsNewer: [.. rightSideIsNewer],
|
||||
RightSideOnly: [.. rightSideOnly]);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetAreEqual(RelativePath relativePath, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
double totalSeconds;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(relativePath);
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
|
||||
{
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == relativePath.Path)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
|
||||
if (record.Size != r.Size || totalSeconds is > 2 or < -2)
|
||||
continue;
|
||||
segment = new(Left: r,
|
||||
LeftDirectory: checkDirectory,
|
||||
Right: record,
|
||||
RightDirectory: relativePath.Path);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(RelativePath relativePath) =>
|
||||
GetKeyValuePairs(relativePath.Records.AsReadOnly());
|
||||
|
||||
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(ReadOnlyCollection<Record> records)
|
||||
{
|
||||
Dictionary<string, Record> results = [];
|
||||
foreach (Record record in records)
|
||||
results.Add(record.RelativePath, record);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetNotEqualBut(RelativePath relativePath, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
double totalSeconds;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(relativePath);
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
|
||||
{
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == relativePath.Path)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
if (record.Size == r.Size)
|
||||
continue;
|
||||
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
|
||||
if (totalSeconds is >= 2 or <= -2)
|
||||
continue;
|
||||
segment = new(Left: r,
|
||||
LeftDirectory: checkDirectory,
|
||||
Right: record,
|
||||
RightDirectory: relativePath.Path);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetLeftSideOnly(RelativePath relativePath, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(relativePath);
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
|
||||
{
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == relativePath.Path)
|
||||
continue;
|
||||
if (keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
segment = new(Left: r,
|
||||
LeftDirectory: checkDirectory,
|
||||
Right: record,
|
||||
RightDirectory: relativePath.Path);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetRightSideOnly(RelativePath relativePath, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(records);
|
||||
foreach (Record r in relativePath.Records)
|
||||
{
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
|
||||
{
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == relativePath.Path)
|
||||
continue;
|
||||
if (keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
segment = new(Left: record,
|
||||
LeftDirectory: null,
|
||||
Right: r,
|
||||
RightDirectory: relativePath.Path);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetLeftSideIsNewer(RelativePath relativePath, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
double totalSeconds;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(relativePath);
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
|
||||
{
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == relativePath.Path)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
|
||||
if (totalSeconds is > -2)
|
||||
continue;
|
||||
segment = new(Left: r,
|
||||
LeftDirectory: checkDirectory,
|
||||
Right: record,
|
||||
RightDirectory: relativePath.Path);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Segment> GetRightSideIsNewer(RelativePath relativePath, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Segment> results = [];
|
||||
Record? record;
|
||||
Segment segment;
|
||||
double totalSeconds;
|
||||
string? checkDirectory = null;
|
||||
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(records);
|
||||
foreach (Record r in relativePath.Records)
|
||||
{
|
||||
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
|
||||
{
|
||||
checkDirectory = r.RelativePath;
|
||||
continue;
|
||||
}
|
||||
if (r.RelativePath == relativePath.Path)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
|
||||
continue;
|
||||
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
|
||||
if (totalSeconds is > -2)
|
||||
continue;
|
||||
segment = new(Left: record,
|
||||
LeftDirectory: null,
|
||||
Right: r,
|
||||
RightDirectory: relativePath.Path);
|
||||
results.Add(segment);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Review))]
|
||||
public partial class ReviewSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
14
Models/Segment.cs
Normal file
14
Models/Segment.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public record Segment(Record? Left,
|
||||
string? LeftDirectory,
|
||||
Record? Right,
|
||||
string RightDirectory);
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Segment))]
|
||||
public partial class SegmentSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
23
Models/SyncConfiguration.cs
Normal file
23
Models/SyncConfiguration.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FileExposer.Models;
|
||||
|
||||
public record SyncConfiguration(string ExcludePatternsFile,
|
||||
string IncludePatternsFile,
|
||||
int SecondThreshold)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, SyncConfigurationSourceGenerationContext.Default.SyncConfiguration);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(SyncConfiguration))]
|
||||
internal partial class SyncConfigurationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
87
Models/SyncV1Repository.cs
Normal file
87
Models/SyncV1Repository.cs
Normal file
@ -0,0 +1,87 @@
|
||||
namespace FileExposer.Models;
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
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);
|
||||
ReadOnlyCollection<Record> records = Record.GetCollection(_AppSettings.SyncConfiguration, directory);
|
||||
RelativePath relativePath = new(Path: path, Records: [.. records]);
|
||||
result = new (JSON: JsonSerializer.Serialize(relativePath, RelativePathSourceGenerationContext.Default.RelativePath), Bytes: null);
|
||||
}
|
||||
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();
|
||||
ReadOnlyCollection<Record> records = Record.GetCollection(_AppSettings.SyncConfiguration, relativePath.Path);
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user