@@ -16,14 +16,20 @@ public class FolderSync
1616 private static string backupRoot ;
1717 [ NotNull ]
1818 private static string logFilePath ;
19- private static List < FileProps > sourceFileList ;
20- private static List < FileProps > backupFileList ;
19+
2120
2221 public static void Main ( string [ ] args )
2322 {
2423 IConfiguration config = new ConfigurationBuilder ( ) . AddCommandLine ( args ) . Build ( ) ;
2524 ParseArgs ( config ) ;
2625 InitalSync ( ) ;
26+ CheckForMissingDirs ( ) ;
27+ CheckForMoodifiedFiles ( ) ;
28+ CheckForCopiesInSource ( ) ;
29+ CheckForMissingFiles ( ) ;
30+ CheckForDeletedFiles ( ) ;
31+ CheckForDeletedDirs ( ) ;
32+ CheckForMovedFiles ( ) ;
2733 // Sync();
2834 }
2935
@@ -104,72 +110,162 @@ private static void InitalSync()
104110 }
105111 }
106112
107- private static void Sync ( )
113+ private static void CheckForMissingDirs ( )
108114 {
109- sourceFileList = new List < FileProps > ( ) ;
110- backupFileList = new List < FileProps > ( ) ;
111- string [ ] sourceFiles = Directory . GetFiles ( sourceRoot , "*" , SearchOption . AllDirectories ) ;
112- foreach ( string file in sourceFiles )
113- sourceFileList . Add ( new FileProps ( file , sourceRoot ) ) ;
115+ string [ ] sourceDirs = Directory . GetDirectories ( sourceRoot , "*" , SearchOption . AllDirectories ) . OrderBy ( s => s ) . ToArray ( ) ;
116+ string [ ] destDirs = Directory . GetDirectories ( backupRoot , "*" , SearchOption . AllDirectories ) . OrderBy ( s => s ) . ToArray ( ) ;
114117
115- string [ ] destFiles = Directory . GetFiles ( backupRoot , "*" , SearchOption . AllDirectories ) ;
116- foreach ( string file in destFiles )
117- backupFileList . Add ( new FileProps ( file , backupRoot ) ) ;
118+ if ( sourceDirs == destDirs )
119+ return ;
118120
119- // if (sourceFileList.Count == 0 && backupFileList.Count > 0) // If the source folder is empty, delete all files in the backup folder
120- // {
121- // foreach (var file in backupFileList)
122- // {
123- // File.Delete(file.GetAbsoluteFilePath);
124- // Log(file.GetFileName, file.GetAbsolutePath, Actions.deleted);
125- // }
126- // }
121+ foreach ( var dir in sourceDirs ) // Make sure the folders that are in the source are also in the backup
122+ {
123+ string backupDir = dir . Replace ( sourceRoot , backupRoot ) ;
124+ if ( ! Directory . Exists ( backupDir ) )
125+ {
126+ Directory . CreateDirectory ( backupDir ) ;
127+ Log ( backupDir , Actions . created ) ;
128+ }
129+ }
130+ }
131+
132+ private static void CheckForMoodifiedFiles ( )
133+ {
134+ List < FileProps > sourceFileList = GetAllFilesInDirectory ( sourceRoot ) ;
135+ List < FileProps > backupFileList = GetAllFilesInDirectory ( backupRoot ) ;
127136
128- foreach ( var file in sourceFileList )
137+ foreach ( var sourceFile in sourceFileList )
129138 {
130- var matchingSourceFiles = sourceFileList . FindAll ( source => source . IsFileCopied ( file . GetFileName , file . GetMD5Code , file . GetRelativePath ) ) ;
131- if ( matchingSourceFiles . Count > 0 ) // An exact copy of the file exists in a different directory
139+ var backup = backupFileList . Find ( backup => backup . IsFileModified ( sourceFile . GetRelativeFilePath , sourceFile . GetMD5Code ) ) ;
140+ if ( backup != null )
132141 {
133- foreach ( var matchingSourceFile in matchingSourceFiles )
142+ EditFile ( sourceFile , backup ) ;
143+ }
144+ }
145+ }
146+
147+ private static void EditFile ( FileProps sourceFile , FileProps backupFile )
148+ {
149+ string fullBackupPath = backupFile . GetAbsoluteFilePath ;
150+ File . Delete ( backupFile . GetAbsoluteFilePath ) ;
151+ File . Copy ( sourceFile . GetAbsoluteFilePath , fullBackupPath ) ;
152+ Log ( sourceFile . GetFileName , backupFile . GetAbsolutePath , Actions . edited ) ;
153+ }
154+
155+ private static void CheckForMovedFiles ( )
156+ {
157+ List < FileProps > sourceFileList = GetAllFilesInDirectory ( sourceRoot ) ;
158+ List < FileProps > backupFileList = GetAllFilesInDirectory ( backupRoot ) ;
159+
160+ foreach ( var sourceFile in sourceFileList )
161+ {
162+ var backup = backupFileList . Find ( backup => backup . IsFileMoved ( sourceFile . GetRelativeFilePath , sourceFile . GetMD5Code ) ) ;
163+ if ( backup != null )
164+ {
165+ MoveFile ( sourceFile , backup ) ;
166+ }
167+ }
168+ }
169+
170+ private static void MoveFile ( FileProps sourceFile , FileProps backupFile )
171+ {
172+ string newFile = Path . Combine ( backupRoot , sourceFile . GetRelativeFilePath ) ;
173+ File . Move ( backupFile . GetAbsoluteFilePath , newFile ) ;
174+ Log ( sourceFile . GetFileName , newFile , Actions . moved ) ;
175+ }
176+
177+ private static void CheckForCopiesInSource ( )
178+ {
179+ List < FileProps > sourceFileList = GetAllFilesInDirectory ( sourceRoot ) ;
180+ List < FileProps > backupFileList = GetAllFilesInDirectory ( backupRoot ) ;
181+
182+ foreach ( var sourceFile in sourceFileList )
183+ {
184+ var matches = sourceFileList . Where ( source => source . IsFileCopied ( sourceFile . GetFileName , sourceFile . GetMD5Code , sourceFile . GetRelativePath ) ) . ToList ( ) ;
185+ if ( matches . Count > 0 )
186+ {
187+ foreach ( var match in matches )
134188 {
135- var match = backupFileList . Find ( backup => backup . IsFileTheSame ( file . GetRelativeFilePath , file . GetMD5Code ) ) ; // See if the copy is already backed up
136- if ( match == null )
189+ var backup = backupFileList . Find ( backup => backup . IsFileTheSame ( match . GetRelativeFilePath , match . GetMD5Code ) ) ;
190+ if ( backup == null )
137191 {
138- CreateCopyFile ( file , Actions . copied ) ;
139- continue ;
192+ CopyFile ( match ) ;
140193 }
141194 }
142195 }
143- var matchingBackupFile = backupFileList . Find ( backup => backup . IsFileTheSame ( file . GetRelativeFilePath , file . GetMD5Code ) ) ;
144- if ( matchingBackupFile == null ) // if no match of the file is found, create a backup
196+ }
197+ }
198+
199+ private static void CopyFile ( FileProps file )
200+ {
201+ string newFile = Path . Combine ( backupRoot , file . GetRelativeFilePath ) ;
202+ File . Copy ( file . GetAbsoluteFilePath , newFile ) ; //
203+ Log ( file . GetFileName , newFile , Actions . copied ) ;
204+ }
205+
206+ private static void CheckForMissingFiles ( )
207+ {
208+ List < FileProps > sourceFileList = GetAllFilesInDirectory ( sourceRoot ) ;
209+ List < FileProps > backupFileList = GetAllFilesInDirectory ( backupRoot ) ;
210+
211+ foreach ( var sourceFile in sourceFileList )
212+ {
213+ var backup = backupFileList . Find ( backup => backup . IsFileTheSame ( sourceFile . GetRelativeFilePath , sourceFile . GetMD5Code ) ) ;
214+ if ( backup == null )
145215 {
146- CreateCopyFile ( file , Actions . created ) ;
147- continue ;
216+ CreateFile ( sourceFile ) ;
148217 }
149218 }
219+ }
220+
221+ private static void CreateFile ( FileProps file )
222+ {
223+ string newFile = Path . Combine ( backupRoot , file . GetRelativeFilePath ) ;
224+ File . Copy ( file . GetAbsoluteFilePath , newFile ) ; //
225+ Log ( file . GetFileName , newFile , Actions . created ) ;
226+ }
227+
228+ private static void CheckForDeletedFiles ( )
229+ {
230+ List < FileProps > sourceFileList = GetAllFilesInDirectory ( sourceRoot ) ;
231+ List < FileProps > backupFileList = GetAllFilesInDirectory ( backupRoot ) ;
150232
151- foreach ( var file in backupFileList )
233+ foreach ( var backupFile in backupFileList )
152234 {
153- var matchingSourceFile = sourceFileList . Find ( source => source . IsFileTheSame ( file . GetRelativeFilePath , file . GetMD5Code ) ) ;
154- if ( matchingSourceFile == null ) // the file was deleted
235+ var source = sourceFileList . Find ( source => source . IsFileTheSame ( backupFile . GetRelativeFilePath , backupFile . GetMD5Code ) ) ;
236+ if ( source == null )
155237 {
156- File . Delete ( file . GetAbsoluteFilePath ) ;
157- Log ( file . GetFileName , file . GetAbsolutePath , Actions . deleted ) ;
238+ DeleteFile ( backupFile ) ;
158239 }
159240 }
241+ }
160242
243+ private static void DeleteFile ( FileProps file )
244+ {
245+ File . Delete ( file . GetAbsoluteFilePath ) ;
246+ Log ( file . GetFileName , file . GetAbsolutePath , Actions . deleted ) ;
161247 }
162248
163- private static void CreateCopyFile ( FileProps file , Actions action )
249+ private static void CheckForDeletedDirs ( )
164250 {
165- string newFile = Path . Combine ( backupRoot , file . GetRelativeFilePath ) ;
166- File . Copy ( file . GetAbsoluteFilePath , newFile ) ; //
167- Log ( file . GetFileName , newFile , action ) ;
251+ string [ ] sourceDirs = Directory . GetDirectories ( sourceRoot , "*" , SearchOption . AllDirectories ) . OrderBy ( s => s ) . ToArray ( ) ;
252+ string [ ] destDirs = Directory . GetDirectories ( backupRoot , "*" , SearchOption . AllDirectories ) . OrderBy ( s => s ) . ToArray ( ) ;
253+
254+ for ( int i = destDirs . Length - 1 ; i >= 0 ; -- i )
255+ {
256+ string correspondingSourceDir = destDirs [ i ] . Replace ( backupRoot , sourceRoot ) ;
257+ if ( ! Directory . Exists ( correspondingSourceDir ) )
258+ {
259+ Directory . Delete ( destDirs [ i ] , true ) ;
260+ Log ( destDirs [ i ] , Actions . deleted ) ;
261+ }
262+ }
168263 }
169264
170- private static void EditFile ( FileProps file , Actions action )
265+ private static List < FileProps > GetAllFilesInDirectory ( string root )
171266 {
172-
267+ string [ ] files = Directory . GetFiles ( root , "*" , SearchOption . AllDirectories ) . OrderBy ( s => s ) . ToArray ( ) ;
268+ return files . Select ( file => new FileProps ( file , root ) ) . ToList ( ) ;
173269 }
174270
175271 enum Actions
0 commit comments