public FileScanner(string startDir, Database database, Logger logger, string name, BackendBase[] backends, string fileIgnorePattern, HashSet<string> ignoredFiles, HashSet<string> ignoredFolders) {
     this.Database = database;
     this.treeTraverser = new TreeTraverser(startDir, fileIgnorePattern, ignoredFiles, ignoredFolders);
     this.fileDatabase = new FileDatabase(database);
     this.backends = backends;
     foreach (BackendBase backend in this.backends) {
         backend.CopyProgress += new BackendBase.CopyProgressEventHandler(Backend_CopyProgress);
     }
     this.Logger = logger;
     this.Name = name;
 }
 public FileScanner(string startDir, Database database, Logger logger, string name, BackendBase[] backends, string fileIgnorePattern, HashSet <string> ignoredFiles, HashSet <string> ignoredFolders)
 {
     this.Database      = database;
     this.treeTraverser = new TreeTraverser(startDir, fileIgnorePattern, ignoredFiles, ignoredFolders);
     this.fileDatabase  = new FileDatabase(database);
     this.backends      = backends;
     foreach (BackendBase backend in this.backends)
     {
         backend.CopyProgress += new BackendBase.CopyProgressEventHandler(Backend_CopyProgress);
     }
     this.Logger = logger;
     this.Name   = name;
 }
 public FolderEntry(TreeTraverser parent, int level, string relPath)
 {
     this.parent     = parent;
     this.Level      = level;
     this.RelPath    = relPath;
     this.attributes = new Lazy <FileAttributes>(() => {
         try {
             return(new DirectoryInfo(this.FullPath).Attributes);
         }
         catch (IOException e) { throw new BackupOperationException(this.RelPath, e.Message); }
         catch (UnauthorizedAccessException e) { throw new BackupOperationException(this.RelPath, e.Message); }
     });
 }
        public override IEnumerable <EntityRecord> ListFilesFolders()
        {
            // Just use a TreeTraverser here
            TreeTraverser treeTraverser = new TreeTraverser(this.Dest);

            foreach (TreeTraverser.FolderEntry folder in treeTraverser.ListFolders())
            {
                yield return(new EntityRecord(folder.RelPath, Entity.Folder));

                foreach (TreeTraverser.FileEntry file in folder.GetFiles())
                {
                    yield return(new EntityRecord(file.RelPath, Entity.File));
                }
            }
        }
        public override void PurgeFiles(IEnumerable <string> filesIn, IEnumerable <string> foldersIn, PurgeProgressHandler handler = null)
        {
            HashSet <string> files   = new HashSet <string>(filesIn);
            HashSet <string> folders = new HashSet <string>(foldersIn);
            // Just use a TreeTraverser here
            TreeTraverser treeTraverser = new TreeTraverser(this.Dest);

            foreach (TreeTraverser.FolderEntry folder in treeTraverser.ListFolders())
            {
                try {
                    if (folders.Contains(folder.RelPath))
                    {
                        if (handler != null && !handler(Entity.Folder, folder.RelPath, false))
                        {
                            return;
                        }
                        foreach (TreeTraverser.FileEntry file in folder.GetFiles())
                        {
                            if (!files.Contains(file.RelPath))
                            {
                                File.Delete(file.FullPath);
                                if (handler != null && !handler(Entity.File, file.RelPath, true))
                                {
                                    return;
                                }
                            }
                            else
                            {
                                if (handler != null && !handler(Entity.File, file.RelPath, false))
                                {
                                    return;
                                }
                            }
                        }
                    }
                    else
                    {
                        Directory.Delete(folder.FullPath);
                        if (handler != null && !handler(Entity.Folder, folder.RelPath, true))
                        {
                            return;
                        }
                    }
                }
                // Don't yet have a way of logging from in here
                catch (BackupOperationException) { }
            }
        }
 public void Populate(string startDir, string ignoreRules) {
     // Get rid of anything there before
     this.tree.Nodes.Clear();
     // aaand start again!
     TreeTraverser treeTraverser = new TreeTraverser(startDir, ignoreRules);
     TreeNodeTri node;
     TreeTraverser.FolderEntry root = treeTraverser.ListFolders(0).First();
     foreach (TreeTraverser.FolderEntry folder in root.GetFolders()) {
         node = new TreeNodeTri(folder, this.tree.ImageList, this.IgnoredFiles, this.IgnoredFolders, this.tree);
         node.Populate();
         this.tree.Nodes.Add(node);
     }
     foreach (TreeTraverser.FileEntry file in root.GetFiles()) {
         this.tree.Nodes.Add(new TreeNodeTri(file, this.tree.ImageList, this.IgnoredFiles, this.IgnoredFolders, this.tree));
     }
 }
 public FileEntry(TreeTraverser parent, string relPath)
 {
     this.parent       = parent;
     this.RelPath      = relPath;
     this.lastModified = new Lazy <DateTime>(() => {
         try {
             return(File.GetLastWriteTimeUtc(this.FullPath));
         }
         catch (IOException e) { throw new BackupOperationException(this.RelPath, e.Message); }
         catch (UnauthorizedAccessException e) { throw new BackupOperationException(this.RelPath, e.Message); }
     });
     this.attributes = new Lazy <FileAttributes>(() => {
         try {
             return(new FileInfo(this.FullPath).Attributes);
         }
         catch (IOException e) { throw new BackupOperationException(this.RelPath, e.Message); }
         catch (UnauthorizedAccessException e) { throw new BackupOperationException(this.RelPath, e.Message); }
     });
 }
        public void Populate(string startDir, string ignoreRules)
        {
            // Get rid of anything there before
            this.tree.Nodes.Clear();
            // aaand start again!
            TreeTraverser treeTraverser = new TreeTraverser(startDir, ignoreRules);
            TreeNodeTri   node;

            TreeTraverser.FolderEntry root = treeTraverser.ListFolders(0).First();
            foreach (TreeTraverser.FolderEntry folder in root.GetFolders())
            {
                node = new TreeNodeTri(folder, this.tree.ImageList, this.IgnoredFiles, this.IgnoredFolders, this.tree);
                node.Populate();
                this.tree.Nodes.Add(node);
            }
            foreach (TreeTraverser.FileEntry file in root.GetFiles())
            {
                this.tree.Nodes.Add(new TreeNodeTri(file, this.tree.ImageList, this.IgnoredFiles, this.IgnoredFolders, this.tree));
            }
        }
 public FileEntry(TreeTraverser parent, string relPath) {
     this.parent = parent;
     this.RelPath = relPath;
     this.lastModified = new Lazy<DateTime>(() => {
         try {
             return File.GetLastWriteTimeUtc(this.FullPath);
         }
         catch (IOException e) { throw new BackupOperationException(this.RelPath, e.Message); }
         catch (UnauthorizedAccessException e) { throw new BackupOperationException(this.RelPath, e.Message); }
     });
     this.attributes = new Lazy<FileAttributes>(() => {
         try {
             return new FileInfo(this.FullPath).Attributes;
         }
         catch (IOException e) { throw new BackupOperationException(this.RelPath, e.Message); }
         catch (UnauthorizedAccessException e) { throw new BackupOperationException(this.RelPath, e.Message); }
     });
 }
 public FolderEntry(TreeTraverser parent, int level, string relPath) {
     this.parent = parent;
     this.Level = level;
     this.RelPath = relPath;
     this.attributes = new Lazy<FileAttributes>(() => {
         try {
             return new DirectoryInfo(this.FullPath).Attributes;
         }
         catch (IOException e) { throw new BackupOperationException(this.RelPath, e.Message); }
         catch (UnauthorizedAccessException e) { throw new BackupOperationException(this.RelPath, e.Message); }
     });
 }
Beispiel #11
0
 private int addFolder(TreeTraverser.FolderEntry folder) {
     foreach (BackendBase backend in this.backends) {
         this.reportBackupAction(new BackupActionItem(null, folder.RelPath, BackupActionEntity.Folder, BackupActionOperation.Add, backend.Name));
         backend.CreateFolder(folder.RelPath, folder.Attributes);
         this.Logger.Info("{0}: Added folder: {1}", backend.Name, folder.RelPath);
     }
     int insertedId = this.fileDatabase.AddFolder(folder.RelPath);
     return insertedId;
 } 
            public TreeNodeTri(TreeTraverser.FileEntry fileEntry, ImageList imageList, HashSet<string> ignoredFiles, HashSet<string> ignoredFolders, TreeView parentTree, CheckedState defaultState=CheckedState.Checked)
                    : base(fileEntry.Filename) {

                this.imageList = imageList;

                if (ignoredFiles.Contains(fileEntry.FullPath))
                    this.State = CheckedState.Unchecked;
                else
                    this.State = defaultState;
                this.StateImageIndex = (int)this.State;

                this.ignoredFiles = ignoredFiles;
                this.ignoredFolders = ignoredFolders;
                this.parentTree = parentTree;

                this.fileEntry = fileEntry;
                
                if (!imageList.Images.ContainsKey(fileEntry.Extension)) {
                    Icon icon = Icon.ExtractAssociatedIcon(fileEntry.FullPath);
                    imageList.Images.Add(fileEntry.Extension, icon);
                }
                this.ImageKey = fileEntry.Extension;
                this.SelectedImageKey = fileEntry.Extension;
            }
            public TreeNodeTri(TreeTraverser.FolderEntry folderEntry, ImageList imageList, HashSet<string> ignoredFiles, HashSet<string> ignoredFolders, TreeView parentTree, CheckedState defaultState=CheckedState.Checked)
                    : base(folderEntry.Name) {

                this.imageList = imageList;
                if (ignoredFolders.Contains(folderEntry.FullPath)) {
                    this.State = CheckedState.Unchecked;
                    // No children yet to update
                }
                else
                    this.State = defaultState;
                this.StateImageIndex = (int)this.State;

                this.ignoredFiles = ignoredFiles;
                this.ignoredFolders = ignoredFolders;
                this.parentTree = parentTree;

                this.folderEntry = folderEntry;

                this.ImageIndex = 0;
                this.SelectedImageIndex = 0;
            }
        public override void PurgeFiles(IEnumerable<string> filesIn, IEnumerable<string> foldersIn, PurgeProgressHandler handler=null) {
            HashSet<string> files = new HashSet<string>(filesIn);
            HashSet<string> folders = new HashSet<string>(foldersIn);
            // Just use a TreeTraverser here
            TreeTraverser treeTraverser = new TreeTraverser(this.Dest);

            foreach (TreeTraverser.FolderEntry folder in treeTraverser.ListFolders()) {
                try {
                    if (folders.Contains(folder.RelPath)) {
                        if (handler != null && !handler(Entity.Folder, folder.RelPath, false))
                            return;
                        foreach (TreeTraverser.FileEntry file in folder.GetFiles()) {
                            if (!files.Contains(file.RelPath)) {
                                File.Delete(file.FullPath);
                                if (handler != null && !handler(Entity.File, file.RelPath, true))
                                    return;
                            }
                            else {
                                if (handler != null && !handler(Entity.File, file.RelPath, false))
                                    return;
                            }
                        }
                    }
                    else {
                        Directory.Delete(folder.FullPath);
                        if (handler != null && !handler(Entity.Folder, folder.RelPath, true))
                            return;
                    }
                }
                // Don't yet have a way of logging from in here
                catch (BackupOperationException) { }
            }
        }
        public override IEnumerable<EntityRecord> ListFilesFolders() {
            // Just use a TreeTraverser here
            TreeTraverser treeTraverser = new TreeTraverser(this.Dest);

            foreach(TreeTraverser.FolderEntry folder in treeTraverser.ListFolders()) {
                yield return new EntityRecord(folder.RelPath, Entity.Folder);
                foreach (TreeTraverser.FileEntry file in folder.GetFiles()) {
                    yield return new EntityRecord(file.RelPath, Entity.File);
                }
            }
        }
Beispiel #16
0
 private void checkFolder(TreeTraverser.FolderEntry folder) {
     foreach (BackendBase backend in this.backends) {
         if (!backend.FolderExists(folder.RelPath)) {
             this.reportBackupAction(new BackupActionItem(null, folder.RelPath, BackupActionEntity.Folder, BackupActionOperation.Add, backend.Name));
             backend.CreateFolder(folder.RelPath, folder.Attributes);
             this.Logger.Info("{0}: Folder missing from backend, so re-creating: {1}", backend.Name, folder.RelPath);
         }
     }
 }
Beispiel #17
0
 private void testFile(TreeTraverser.FileEntry file, string fileMD5) {
     foreach (BackendBase backend in this.backends) {
         if (!backend.TestFile(file.RelPath, file.LastModified, fileMD5)) {
             // Aha! File's gone missing from the backend
             this.reportBackupAction(new BackupActionItem(null, file.RelPath, BackupActionEntity.File, BackupActionOperation.Add, backend.Name));
             if (!this.createFromAlternate(file, fileMD5, true, backend)) {
                 if (backend.CreateFile(file.RelPath, file.FullPath, file.LastModified, fileMD5, file.Attributes))
                     this.Logger.Info("{0}: File on backend missing or modified, so re-creating: {1}", backend.Name, file.RelPath);
             }
         }
         else
             this.reportBackupAction(new BackupActionItem(null, file.RelPath, BackupActionEntity.File, BackupActionOperation.Nothing));
     }
 }
Beispiel #18
0
        private void updatefile(int fileId, TreeTraverser.FileEntry file, string remoteMD5) {
            this.reportBackupAction(new BackupActionItem(null, file.RelPath, BackupActionEntity.File, BackupActionOperation.Hash));
            // Only copy if the file has actually changed
            string fileMD5 = file.GetMD5((percent) => {
                this.reportBackupAction(new BackupActionItem(null, file.RelPath, BackupActionEntity.File, BackupActionOperation.Hash, null, percent));
                return !this.Cancelled;
            });
            if (this.Cancelled)
                return;

            if (remoteMD5 == fileMD5) {
                foreach (BackendBase backend in this.backends) {
                    backend.TouchFile(file.RelPath, file.LastModified);
                }
                //this.Logger.Info("File mtime changed, but file unchanged. Touching: {0}", file);
                return;
            }

            foreach (BackendBase backend in this.backends) {
                if (this.createFromAlternate(file, fileMD5, true, backend))
                    continue;

                this.reportBackupAction(new BackupActionItem(null, file.RelPath, BackupActionEntity.File, BackupActionOperation.Update, backend.Name));
                if (backend.CreateFile(file.RelPath, file.FullPath, file.LastModified, fileMD5, file.Attributes))
                    this.Logger.Info("{0}: Updated file: {1}", backend.Name, file.RelPath);
                else
                    this.Logger.Info("{0}: Skipped file {1} (mtime changed but file up-to-date)", backend.Name, file.RelPath);
            }
            // But update the last modified time either way
            this.fileDatabase.UpdateFile(fileId, file.LastModified, fileMD5);
        }
Beispiel #19
0
        private void addFile(int folderId, TreeTraverser.FileEntry file) {
            string fileMD5 = file.GetMD5((percent) => {
                this.reportBackupAction(new BackupActionItem(null, file.RelPath, BackupActionEntity.File, BackupActionOperation.Hash, null, percent));
                return !this.Cancelled;
            });
            if (this.Cancelled)
                return;

            foreach (BackendBase backend in this.backends) {
                // Search for alternates
                if (this.createFromAlternate(file, fileMD5, false, backend))
                    continue;
                this.reportBackupAction(new BackupActionItem(null, file.RelPath, BackupActionEntity.File, BackupActionOperation.Add, backend.Name));
                backend.CreateFile(file.RelPath, file.FullPath, file.LastModified, fileMD5, file.Attributes);
                this.Logger.Info("{0}: Added file: {1}", backend.Name, file.RelPath);
            }
            this.fileDatabase.AddFile(folderId, file.RelPath, file.LastModified, fileMD5);
        }
Beispiel #20
0
        private bool createFromAlternate(TreeTraverser.FileEntry file, string fileMD5, bool update, BackendBase backend) {
            // if update is true, we're updating the dest file. otherwise we're adding it
            // Return true if we made use of an alternate, or false if we did nothing
            string logAction = update ? "Updated" : "Added";

            FileDatabase.FileRecord[] alternates = this.fileDatabase.SearchForAlternates(fileMD5).ToArray();
            if (alternates.Length == 0)
                return false;

            // Now, each alternate may not in fact exist on the backend, or may be changed. We can't assume stuff like this
            // So, loop through them all, and attempt to use it. Bail after the first successful one

            bool foundGoodAlternate = false;

            foreach (FileDatabase.FileRecord alternate in alternates) {
                // First, does it even exist on the backend? Skip to the next one if not
                if (!backend.TestFile(alternate.Path, file.LastModified, fileMD5))
                    continue;

                // Next: Is is a copy or a move?
                if (this.treeTraverser.FileExists(alternate.Path)) {
                    // It's a copy
                    this.reportBackupAction(new BackupActionItem(alternate.Path, file.RelPath, BackupActionEntity.File, BackupActionOperation.Copy, backend.Name));
                    if (backend.CreateFromAlternateCopy(file.RelPath, alternate.Path))
                        this.Logger.Info("{0}: {1} file: {2} from alternate {3} (copy)", backend.Name, logAction, file.RelPath, alternate.Path);
                    else {
                        backend.CreateFile(file.RelPath, file.FullPath, file.LastModified, fileMD5, file.Attributes);
                        this.Logger.Info("{0}: {1} file: {2} (backend refused alternate {3})", backend.Name, logAction, file.RelPath, alternate.Path);
                    }
                }
                else {
                    // It's a move
                    this.reportBackupAction(new BackupActionItem(alternate.Path, file.RelPath, BackupActionEntity.File, BackupActionOperation.Move, backend.Name));
                    backend.CreateFromAlternateMove(file.RelPath, alternate.Path);
                    this.Logger.Info("{0}: {1} file: {2} from alternate {3} (move)", backend.Name, logAction, file.RelPath, alternate.Path);
                    this.fileDatabase.DeleteFile(alternate.Id);
                }

                // We're all golden
                foundGoodAlternate = true;
                break;
            }

            return foundGoodAlternate;
        }