Skip to content

Commit 36c72f9

Browse files
add new WithSubfolder option to specify only a subset of folders within SourcePath
1 parent 71447e4 commit 36c72f9

5 files changed

Lines changed: 227 additions & 48 deletions

File tree

FileSyncJob/FileSyncJobOptions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.Extensions.Logging;
22
using System;
3+
using System.Collections.Generic;
34
using System.Net;
45

56
namespace FileSyncLibNet.FileSyncJob
@@ -12,11 +13,15 @@ public class FileSyncJobOptions : IFileSyncJobOptions
1213
public NetworkCredential Credentials { get; set; }
1314
public TimeSpan Interval { get; set; } = TimeSpan.Zero;
1415
public string SearchPattern { get; set; } = "*.*";
16+
public List<string> Subfolders { get; set; }
1517
public bool Recursive { get; set; } = true;
1618
public bool SyncDeleted { get; set; } = false;
1719
public FileSyncProvider FileSyncProvider { get; set; } = FileSyncProvider.FileIO;
1820

19-
public FileSyncJobOptions() { }
21+
public FileSyncJobOptions()
22+
{
23+
Subfolders = new List<string>();
24+
}
2025

2126
}
2227
}

FileSyncJob/FileSyncJobOptionsBuilder.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ public IFileSyncJobOptionsBuilderSetProperties WithSearchPattern(string searchPa
6969
jobOptions.SearchPattern = searchPattern;
7070
return this;
7171
}
72+
public IFileSyncJobOptionsBuilderSetProperties WithSubfolder(string subfolder)
73+
{
74+
jobOptions.Subfolders.Add(subfolder);
75+
return this;
76+
}
7277
public IFileSyncJobOptionsBuilderSetProperties WithInterval(TimeSpan interval)
7378
{
7479
jobOptions.Interval = interval;
@@ -118,6 +123,7 @@ public interface IFileSyncJobOptionsBuilderSetProperties : IFileSyncJobOptionsBu
118123
IFileSyncJobOptionsBuilderSetProperties WithCredentials(string username, string password);
119124
IFileSyncJobOptionsBuilderSetProperties WithCredentials(NetworkCredential networkCredential);
120125
IFileSyncJobOptionsBuilderSetProperties WithSearchPattern(string searchPattern);
126+
IFileSyncJobOptionsBuilderSetProperties WithSubfolder(string subfolder);
121127
IFileSyncJobOptionsBuilderSetProperties WithLogger(ILogger logger);
122128
IFileSyncJobOptionsBuilderSetProperties WithLogger(Action<string> loggerAction);
123129
}

FileSyncJob/IFileSyncJobOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.Extensions.Logging;
22
using System;
3+
using System.Collections.Generic;
34
using System.Net;
45

56
namespace FileSyncLibNet.FileSyncJob
@@ -13,6 +14,7 @@ public interface IFileSyncJobOptions
1314
ILogger Logger { get; set; }
1415
bool Recursive { get; set; }
1516
string SearchPattern { get; set; }
17+
List<string> Subfolders { get; set; }
1618
string SourcePath { get; set; }
1719
bool SyncDeleted { get; set; }
1820
}

SyncProviders/FileIOProvider.cs

Lines changed: 170 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
using FileSyncLibNet.FileSyncJob;
22
using Microsoft.Extensions.Logging;
33
using System;
4+
using System.Collections.Generic;
5+
using System.ComponentModel;
46
using System.Diagnostics;
57
using System.IO;
8+
using System.Linq;
69
using System.Net;
10+
using System.Threading;
711

812
namespace FileSyncLibNet.SyncProviders
913
{
@@ -22,38 +26,47 @@ public override void SyncSourceToDest()
2226
int copied = 0;
2327
int skipped = 0;
2428
DirectoryInfo _di = new DirectoryInfo(JobOptions.SourcePath);
25-
var _fi = _di.EnumerateFiles(
26-
searchPattern: JobOptions.SearchPattern,
27-
searchOption: JobOptions.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
2829
//Dateien ins Backup kopieren
2930
if (JobOptions.Credentials != null)
3031
{
31-
32-
}
3332

34-
foreach (FileInfo f in _fi)
33+
}
34+
35+
36+
foreach (var dir in JobOptions.Subfolders.Count > 0 ? _di.GetDirectories() : new[] {_di})
3537
{
36-
var relativeFilename = f.FullName.Substring(Path.GetFullPath(JobOptions.SourcePath).Length).TrimStart('\\');
37-
var remotefile = new FileInfo(Path.Combine(JobOptions.DestinationPath, relativeFilename));
38-
bool copy = !remotefile.Exists || remotefile.Length != f.Length || remotefile.LastWriteTime != f.LastWriteTime;
39-
if (copy)
38+
if (JobOptions.Subfolders.Count > 0 && !JobOptions.Subfolders.Select(x => x.ToLower()).Contains(dir.Name.ToLower()))
39+
continue;
40+
var _fi = dir.EnumerateFiles(
41+
searchPattern: JobOptions.SearchPattern,
42+
searchOption: JobOptions.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
43+
44+
45+
foreach (FileInfo f in _fi)
4046
{
41-
try
47+
48+
var relativeFilename = f.FullName.Substring(Path.GetFullPath(JobOptions.SourcePath).Length).TrimStart('\\');
49+
var remotefile = new FileInfo(Path.Combine(JobOptions.DestinationPath, relativeFilename));
50+
bool copy = !remotefile.Exists || remotefile.Length != f.Length || remotefile.LastWriteTime != f.LastWriteTime;
51+
if (copy)
4252
{
43-
logger.LogDebug("Copy {A}", relativeFilename);
44-
File.Copy(f.FullName, remotefile.FullName, true);
45-
copied++;
53+
try
54+
{
55+
logger.LogDebug("Copy {A}", relativeFilename);
56+
File.Copy(f.FullName, remotefile.FullName, true);
57+
copied++;
58+
}
59+
catch (Exception exc)
60+
{
61+
logger.LogError(exc, "Exception copying {A}", relativeFilename);
62+
}
4663
}
47-
catch(Exception exc)
64+
else
4865
{
49-
logger.LogError(exc, "Exception copying {A}", relativeFilename);
66+
skipped++;
67+
logger.LogTrace("Skip {A}", relativeFilename);
5068
}
5169
}
52-
else
53-
{
54-
skipped++;
55-
logger.LogTrace("Skip {A}", relativeFilename);
56-
}
5770
}
5871
sw.Stop();
5972
logger.LogInformation("{A} files copied, {B} files skipped in {C}s", copied, skipped, sw.ElapsedMilliseconds / 1000.0);
@@ -74,7 +87,142 @@ void CopyFileWithBuffer(FileInfo source, FileInfo destination)
7487
//destination.Attributes = source.Attributes;
7588

7689
}
77-
90+
void EnsureAccess()
91+
{
92+
//#region Backup
93+
//if (!string.IsNullOrWhiteSpace(einst.BasicSettings["BackupPath"]))
94+
//{
95+
// //Dateien sichern:
96+
// bool useCredentials = ((string)einst.BasicSettings["BackupPath"]).StartsWith(@"\\");
97+
// string backupTarget = einst.BasicSettings["BackupPath"];
98+
99+
// if (backupTarget.StartsWith(@"\\")) //Netzwerk
100+
// {
101+
// try
102+
// {
103+
// //Probe network access:
104+
// bool accesible = false;
105+
// bool writeable = false;
106+
// try
107+
// {
108+
// DirectoryInfo di = new DirectoryInfo(backupTarget);
109+
// while (di != null && !di.Exists)
110+
// {
111+
// di = di.Parent;
112+
// }
113+
// if (di != null && di.Exists)
114+
// accesible = true;
115+
// if (accesible)
116+
// {
117+
// Directory.CreateDirectory(backupTarget);
118+
// File.WriteAllText(backupTarget + "\\hri_write_probing", "probing write access");
119+
// try
120+
// {
121+
// File.Delete(backupTarget + "\\hri_write_probing");
122+
// }
123+
// catch (Exception exc)
124+
// {
125+
// log.LogWarning(exc, "Exception when deleting 'hri_write_probing' file, assuming writable");
126+
// }
127+
// writeable = true;
128+
// }
129+
// }
130+
// catch { }
131+
// if (!accesible || !writeable)
132+
// {
133+
// DirectoryInfo di = new DirectoryInfo(backupTarget);
134+
// string netpath = di.Root.FullName;
135+
136+
// if (accesible) //Change credentials..
137+
// {
138+
// NetworkShare.CancelExistingConnection(netpath);
139+
// }
140+
141+
// string username = ((string)Einstellungen.BasicSettings["NetworkCredentials"]).Split(':')[0];
142+
// string password = ((string)Einstellungen.BasicSettings["NetworkCredentials"]).Split(':')[1];
143+
// NetworkCredential networkCredential = new NetworkCredential(username, password);
144+
// NetworkShare net = null;
145+
// try { net = new NetworkShare(netpath, networkCredential, true); }
146+
// catch (Win32Exception exception) { log.LogInformation("Backup: Fehler beim herstellen einer Netzwerkverbindung zu " + netpath + ":\r\n" + exception.ToString()); }
147+
// }
148+
// }
149+
// catch (Exception e)
150+
// {
151+
// log.LogError("backuptimer_tick", e);
152+
// log.LogInformation("Backup: Fehler beim Zugriff auf Netzlaufwerk:\r\n" + e.ToString());
153+
// }
154+
155+
// }
156+
// //else //Filesystem
157+
// {
158+
// try
159+
// {
160+
// //Beim Netzlaufwerk versuchen es erneut zu verbinden
161+
// string drive = backupTarget.Split(':')[0];
162+
// //if (!Map(drive + ":"))
163+
// // log.LogInformation("Fehler beim mappen des Laufwerkes " + drive + ": - Bitte Einstellungen überprüfen");
164+
// bool canWrite = true;
165+
// if (!Directory.Exists(backupTarget))
166+
// {
167+
// try
168+
// {
169+
// Directory.CreateDirectory(backupTarget);
170+
// }
171+
// catch { log.LogInformation($"Konnte nicht auf Backuppfad {backupTarget} schreiben"); canWrite = false; }
172+
// }
173+
// if (canWrite)
174+
// foreach (string folder in new string[] { "HriFFTLog", "HriShockLog", "HriLog", "HriDebugLog", "HRI" })
175+
// {
176+
// string _path = Path.Combine(ProductionDataPath, folder);
177+
// if (!Directory.Exists(_path))
178+
// Directory.CreateDirectory(_path);
179+
// string destPath = Path.Combine(backupTarget, folder);
180+
// if (Directory.Exists(backupTarget))
181+
// if (!Directory.Exists(destPath))
182+
// Directory.CreateDirectory(destPath);
183+
// DirectoryInfo _di = new DirectoryInfo(_path);
184+
// FileInfo[] _fi = _di.GetFiles();
185+
// //Dateien ins Backup kopieren
186+
// foreach (FileInfo f in _fi)
187+
// {
188+
// bool copy = false;
189+
// string remotefilename = Path.Combine(destPath, f.Name);
190+
// if (!File.Exists(remotefilename))
191+
// {
192+
// copy = true;
193+
// }
194+
// else
195+
// {
196+
// FileInfo remoteFile = new FileInfo(remotefilename);
197+
// if (remoteFile.Length != f.Length)
198+
// copy = true;
199+
// }
200+
// if (copy)
201+
// {
202+
// File.Copy(f.FullName, remotefilename, true);
203+
// Thread.Sleep(15);
204+
// }
205+
// else
206+
// {
207+
// Thread.Sleep(5);
208+
// }
209+
// }
210+
// }
211+
212+
213+
// }
214+
// catch (Exception e)
215+
// {
216+
// log.LogError("backuptimer_tick", e);
217+
// log.LogInformation("Fehler beim erstellen des Backups!\r\n" + e.ToString());
218+
// }
219+
// }
220+
//}
221+
//#endregion
222+
223+
224+
}
225+
78226

79227

80228

SyncProviders/SmbLibProvider.cs

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,42 +55,60 @@ public SmbLibProvider(IFileSyncJobOptions options)
5555

5656
public override void SyncSourceToDest()
5757
{
58-
DirectoryInfo _di = new DirectoryInfo(JobOptions.SourcePath);
59-
var _fi = _di.EnumerateFiles(
60-
searchPattern: JobOptions.SearchPattern,
61-
searchOption: JobOptions.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
6258
//Dateien ins Backup kopieren
6359
if (JobOptions.Credentials != null)
6460
{
6561
ConnectToShare(Server, Share, JobOptions.Credentials.Domain, JobOptions.Credentials.UserName, JobOptions.Credentials.Password);
6662
}
67-
if (JobOptions.SyncDeleted)
63+
64+
DirectoryInfo _di = new DirectoryInfo(JobOptions.SourcePath);
65+
66+
foreach (var dir in JobOptions.Subfolders.Count > 0 ? _di.GetDirectories() : new[] { _di })
6867
{
69-
var remoteFiles = ListFiles(DestinationPath, true);
70-
foreach (var file in remoteFiles)
68+
if (JobOptions.Subfolders.Count > 0 && !JobOptions.Subfolders.Select(x => x.ToLower()).Contains(dir.Name.ToLower()))
69+
continue;
70+
71+
72+
73+
var _fi = dir.EnumerateFiles(
74+
searchPattern: JobOptions.SearchPattern,
75+
searchOption: JobOptions.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
76+
77+
if (JobOptions.SyncDeleted)
7178
{
72-
var realFilePath = file.Substring(file.IndexOf(DestinationPath) + DestinationPath.Length).Trim('\\').Replace('/', '\\');
73-
if (!_fi.Any(x => x.FullName.Replace('/', '\\').EndsWith(realFilePath)))
74-
DeleteFile(file);
79+
var remoteFiles = ListFiles(DestinationPath, true);
80+
foreach (var file in remoteFiles)
81+
{
82+
var realFilePath = file.Substring(file.IndexOf(DestinationPath) + DestinationPath.Length).Trim('\\').Replace('/', '\\');
83+
if (!_fi.Any(x => x.FullName.Replace('/', '\\').EndsWith(realFilePath)))
84+
DeleteFile(file);
85+
}
7586
}
76-
}
77-
foreach (FileInfo f in _fi)
78-
{
79-
bool copy = false;
80-
var relativeFilename = f.FullName.Substring(Path.GetFullPath(JobOptions.SourcePath).Length);
81-
var remotefile = Path.Combine(DestinationPath, relativeFilename.TrimStart('\\', '/')).Replace('/', '\\');
82-
var exists = FileExists(remotefile, out long size);
83-
copy = !exists || size != f.Length;
84-
if (copy)
87+
foreach (FileInfo f in _fi)
8588
{
86-
logger.LogDebug("Copy {A}", relativeFilename);
87-
//File.Copy(f.FullName, remotefile.FullName, true);
88-
//CopyFileWithBuffer(f, remotefile);
89-
WriteFile(f.FullName, remotefile);
89+
bool copy = false;
90+
var relativeFilename = f.FullName.Substring(Path.GetFullPath(JobOptions.SourcePath).Length);
91+
var remotefile = Path.Combine(DestinationPath, relativeFilename.TrimStart('\\', '/')).Replace('/', '\\');
92+
var exists = FileExists(remotefile, out long size);
93+
copy = !exists || size != f.Length;
94+
if (copy)
95+
{
96+
logger.LogDebug("Copy {A}", relativeFilename);
97+
//File.Copy(f.FullName, remotefile.FullName, true);
98+
//CopyFileWithBuffer(f, remotefile);
99+
try
100+
{
101+
WriteFile(f.FullName, remotefile);
102+
}
103+
catch (Exception exc)
104+
{
105+
logger.LogError(exc, "Exception in WriteFile for {A}", relativeFilename);
106+
}
90107

108+
}
109+
else
110+
logger.LogDebug("Skip {A}", relativeFilename);
91111
}
92-
else
93-
logger.LogDebug("Skip {A}", relativeFilename);
94112
}
95113
}
96114

0 commit comments

Comments
 (0)