Skip to content

Commit 86e5a1b

Browse files
add AccessProviders (to have a lower abstracted sync)
1 parent e2df39b commit 86e5a1b

3 files changed

Lines changed: 262 additions & 0 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using FileSyncLibNet.Commons;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Linq;
6+
7+
namespace FileSyncLibNet.AccessProviders
8+
{
9+
internal class FileIoAccessProvider : IAccessProvider
10+
{
11+
public string AccessPath { get; }
12+
public FileIoAccessProvider(string accessPath)
13+
{
14+
AccessPath = accessPath;
15+
}
16+
17+
public void CreateDirectory(string path)
18+
{
19+
Directory.CreateDirectory(Path.Combine(AccessPath, path));
20+
}
21+
22+
public FileInfo2 GetFileInfo(string path)
23+
{
24+
var fi = new FileInfo(Path.Combine(AccessPath, path));
25+
26+
return new FileInfo2(path, fi.Exists)
27+
{
28+
LastWriteTime = fi.Exists ? fi.LastWriteTime : DateTime.MinValue,
29+
Length = fi.Exists ? fi.Length : 0
30+
};
31+
}
32+
33+
public List<FileInfo2> GetFiles(DateTime minimumLastWriteTime, string pattern, string path = null, bool recursive = false, List<string> subfolders = null)
34+
{
35+
DirectoryInfo _di = new DirectoryInfo(AccessPath);
36+
List<FileInfo2> ret_val = new List<FileInfo2>();
37+
foreach (var dir in (subfolders != null && subfolders.Count > 0) ? _di.GetDirectories() : new[] { _di })
38+
{
39+
if (subfolders != null && subfolders.Count > 0 && !subfolders.Select(x => x.ToLower()).Contains(dir.Name.ToLower()))
40+
continue;
41+
var _fi = dir.EnumerateFiles(
42+
searchPattern: pattern,
43+
searchOption: recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
44+
45+
46+
ret_val.AddRange(_fi.Select(x => new FileInfo2(x.FullName.Substring(AccessPath.Length + 1), x.Exists) { Length = x.Length, LastWriteTime = x.LastWriteTime }).ToList());
47+
}
48+
return ret_val;
49+
}
50+
51+
public Stream GetStream(FileInfo2 file)
52+
{
53+
var realFilename = Path.Combine(AccessPath, file.Name);
54+
return File.OpenRead(realFilename);
55+
}
56+
57+
public void WriteFile(FileInfo2 file, Stream content)
58+
{
59+
var realFilename = Path.Combine(AccessPath, file.Name);
60+
Directory.CreateDirectory(Path.GetDirectoryName(realFilename));
61+
using (var stream = File.Create(realFilename))
62+
{
63+
content.CopyTo(stream);
64+
}
65+
File.SetLastWriteTime(realFilename, file.LastWriteTime);
66+
67+
}
68+
public void Delete(FileInfo2 fileInfo)
69+
{
70+
var realFilename = Path.Combine(AccessPath, fileInfo.Name);
71+
File.Delete(realFilename);
72+
}
73+
}
74+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using FileSyncLibNet.Commons;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
6+
namespace FileSyncLibNet.AccessProviders
7+
{
8+
internal interface IAccessProvider
9+
{
10+
void CreateDirectory(string path);
11+
List<FileInfo2> GetFiles(DateTime minimumLastWriteTime, string pattern, string path = null, bool recursive = false, List<string> subfolders = null);
12+
FileInfo2 GetFileInfo(string path);
13+
void Delete(FileInfo2 fileInfo);
14+
Stream GetStream(FileInfo2 file);
15+
void WriteFile(FileInfo2 file, Stream content);
16+
}
17+
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
using FileSyncLibNet.Commons;
2+
using Renci.SshNet;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Linq;
7+
using System.Net;
8+
using System.Text.RegularExpressions;
9+
10+
namespace FileSyncLibNet.AccessProviders
11+
{
12+
internal class ScpAccessProvider : IAccessProvider
13+
{
14+
string AccessPathUri { get; }
15+
NetworkCredential Credentials { get; }
16+
SftpClient ftpClient;
17+
public string AccessPath { get; private set; }
18+
19+
public ScpAccessProvider(string accessPath, NetworkCredential credentials)
20+
{
21+
AccessPathUri = accessPath;
22+
Credentials = credentials;
23+
//CreateClient();
24+
}
25+
void CreateClient()
26+
{
27+
var pattern = @"scp://(?:(?<user>[^@]+)@)?(?<host>[^:/]+)(?::(?<port>\d+))?(?<path>/.*)?";
28+
var match = Regex.Match(AccessPathUri, pattern);
29+
30+
31+
if (!match.Success)
32+
{
33+
throw new UriFormatException($"Unable to match scp pattern with given URL {AccessPathUri}, use format scp://host:port/path");
34+
}
35+
else
36+
{
37+
var user = match.Groups["user"].Value;
38+
var host = match.Groups["host"].Value;
39+
var port = int.Parse(match.Groups["port"].Success ? match.Groups["port"].Value : "22"); // Default SCP port
40+
AccessPath = match.Groups["path"].Value;
41+
if (AccessPath.StartsWith("/~"))
42+
AccessPath = AccessPath.Substring(1);
43+
44+
ftpClient = new SftpClient(host, port, Credentials.UserName, Credentials.Password);
45+
}
46+
}
47+
void EnsureConnected()
48+
{
49+
if (ftpClient == null)
50+
{
51+
CreateClient();
52+
}
53+
if (!ftpClient.IsConnected)
54+
{
55+
ftpClient.Connect();
56+
}
57+
}
58+
private void CreateDirectoryRecursive(SftpClient client, string path)
59+
{
60+
var dirs = path.Split('/');
61+
string currentPath = path.StartsWith("/") ? "/" : /*path.StartsWith("~") ? "~/" :*/ "";
62+
for (int i = 0; i < dirs.Length; i++)
63+
{
64+
if (dirs[i] == "~")
65+
continue;
66+
currentPath = (currentPath.EndsWith("/") ? currentPath : currentPath == "" ? dirs[i] : ((currentPath + "/")) + dirs[i]);
67+
if (!string.IsNullOrEmpty(currentPath) && currentPath != "/" && currentPath != "/~")
68+
if (!client.Exists(currentPath))
69+
client.CreateDirectory(currentPath);
70+
}
71+
}
72+
73+
74+
public void CreateDirectory(string path)
75+
{
76+
EnsureConnected();
77+
var realDir = System.IO.Path.Combine(AccessPath, path).Replace("\\", "/");
78+
CreateDirectoryRecursive(ftpClient, realDir);
79+
}
80+
81+
public FileInfo2 GetFileInfo(string path)
82+
{
83+
EnsureConnected();
84+
var realFilename = System.IO.Path.Combine(AccessPath, path).Replace("\\", "/");
85+
if (ftpClient.Exists(realFilename))
86+
{
87+
var fi = ftpClient.ListDirectory(realFilename);
88+
return new FileInfo2(path, true)
89+
{
90+
LastWriteTime = fi.First().LastWriteTime,
91+
Length = fi.First().Length
92+
};
93+
}
94+
else
95+
{
96+
return new FileInfo2(path, false)
97+
{
98+
LastWriteTime = DateTime.MinValue,
99+
Length = 0
100+
};
101+
}
102+
}
103+
104+
public bool MatchesPattern(string fileName, string pattern)
105+
{
106+
if (string.IsNullOrEmpty(pattern))
107+
return true;
108+
string regexPattern = "^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".") + "$";
109+
return Regex.IsMatch(fileName, regexPattern, RegexOptions.IgnoreCase);
110+
}
111+
112+
public List<FileInfo2> GetFiles(DateTime minimumLastWriteTime, string pattern, string path = null, bool recursive = false, List<string> subfolders = null)
113+
{
114+
EnsureConnected();
115+
string basePath = string.IsNullOrEmpty(path) ? AccessPath : path;
116+
List<FileInfo2> ret_val = new List<FileInfo2>();
117+
if (subfolders != null && subfolders.Count > 0)
118+
{
119+
foreach (string subfolder in subfolders)
120+
{
121+
var subPath = System.IO.Path.Combine(basePath, subfolder).Replace("\\", "/");
122+
ret_val.AddRange(GetFiles(minimumLastWriteTime, pattern, path: subPath, recursive: recursive));
123+
}
124+
}
125+
else
126+
{
127+
var files = ftpClient.ListDirectory(basePath);
128+
if (recursive)
129+
{
130+
foreach (var folder in files.Where(x => x.IsDirectory && !(x.Name == ".") && !(x.Name == "..")))
131+
{
132+
var subPath = System.IO.Path.Combine(folder.Name).Replace("\\", "/");
133+
ret_val.AddRange(GetFiles(minimumLastWriteTime, pattern, subPath, recursive));
134+
}
135+
}
136+
ret_val.AddRange(files.Where(x => MatchesPattern(x.Name, pattern)).Where(x => x.LastWriteTime >= minimumLastWriteTime && !x.IsDirectory).Select(x =>
137+
new FileInfo2($"{basePath.Substring(AccessPath.Length + 1)}/{x.Name}", exists: true) { LastWriteTime = x.LastWriteTime, Length = x.Length }).ToList());
138+
}
139+
return ret_val;
140+
}
141+
142+
public Stream GetStream(FileInfo2 file)
143+
{
144+
EnsureConnected();
145+
var subPath = System.IO.Path.Combine(AccessPath, file.Name).Replace("\\", "/");
146+
return ftpClient.OpenRead(subPath);
147+
}
148+
149+
public void WriteFile(FileInfo2 file, Stream content)
150+
{
151+
EnsureConnected();
152+
var filePath = System.IO.Path.Combine(AccessPath, file.Name).Replace("\\", "/");
153+
CreateDirectoryRecursive(ftpClient, filePath.Substring(0, filePath.LastIndexOf("/")));
154+
if (filePath.StartsWith("~/"))
155+
filePath = filePath.Substring(2);
156+
157+
using (var stream = ftpClient.Open(filePath, FileMode.Create))
158+
{
159+
160+
content.CopyTo(stream);
161+
}
162+
}
163+
164+
public void Delete(FileInfo2 fileInfo)
165+
{
166+
EnsureConnected();
167+
var filePath = System.IO.Path.Combine(AccessPath, fileInfo.Name).Replace("\\", "/");
168+
ftpClient.Delete(filePath);
169+
}
170+
}
171+
}

0 commit comments

Comments
 (0)