예제 #1
0
            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;
            }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
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));
         }
     }
 }
예제 #6
0
        public void Backup()
        {
            this.Cancelled       = false;
            this.WarningOccurred = false;

            FileDatabase.FolderStatus folderStatus;
            int newFolderLevel = -1;
            int prevLevel      = -1;
            int curFolderId    = -1;
            IEnumerable <TreeTraverser.FileEntry> files;

            FileDatabase.FileStatus fileStatus;

            // Do all the additions, then go through and do the deletions separately
            // This gives us a change to do renames, and makes sure that we empty folders before deleting them

            foreach (TreeTraverser.FolderEntry folder in this.treeTraverser.ListFolders())
            {
                if (this.Cancelled)
                {
                    break;
                }

                // files might not get assigned, so assign it now
                files = new TreeTraverser.FileEntry[0];

                try {
                    if (newFolderLevel >= 0 && folder.Level > newFolderLevel)
                    {
                        // Just automatically add it, as a parent somewhere is new
                        curFolderId = this.addFolder(folder);
                    }
                    else
                    {
                        newFolderLevel = -1;
                        folderStatus   = this.fileDatabase.InspectFolder(folder.RelPath);

                        switch (folderStatus.FolderModStatus)
                        {
                        case FileDatabase.FolderModStatus.New:
                            newFolderLevel = folder.Level;
                            curFolderId    = this.addFolder(folder);
                            break;

                        case FileDatabase.FolderModStatus.Unmodified:
                            curFolderId = folderStatus.Id;
                            this.checkFolder(folder);
                            break;
                        }
                    }
                    // Check for files in this folder
                    files = folder.GetFiles();
                }
                catch (BackupOperationException e) { this.handleOperationException(e); }

                foreach (TreeTraverser.FileEntry file in files)
                {
                    if (this.Cancelled)
                    {
                        break;
                    }

                    try {
                        fileStatus = this.fileDatabase.InspectFile(curFolderId, file.RelPath, file.LastModified);

                        switch (fileStatus.FileModStatus)
                        {
                        case FileDatabase.FileModStatus.New:
                            this.addFile(curFolderId, file);
                            break;

                        case FileDatabase.FileModStatus.Newer:
                        case FileDatabase.FileModStatus.Older:
                            this.updatefile(fileStatus.Id, file, fileStatus.MD5);
                            break;

                        case FileDatabase.FileModStatus.Unmodified:
                            // We don't think anything's changed... but make sure the file exists on the backends
                            this.testFile(file, fileStatus.MD5);
                            break;
                        }
                    }
                    catch (BackupOperationException e) { this.handleOperationException(e); }
                }

                prevLevel = folder.Level;
            }

            if (this.Cancelled)
            {
                return;
            }

            // Now we look for file deletions
            IEnumerable <FileDatabase.FileRecord> recordedFiles = this.fileDatabase.RecordedFiles();

            foreach (FileDatabase.FileRecord fileToCheck in recordedFiles)
            {
                if (this.Cancelled)
                {
                    break;
                }
                if (!this.treeTraverser.FileExists(fileToCheck.Path))
                {
                    this.deleteFile(fileToCheck.Id, fileToCheck.Path);
                }
            }

            if (this.Cancelled)
            {
                return;
            }

            // And finally folder deletions
            foreach (FileDatabase.FolderRecord folderToCheck in this.fileDatabase.RecordedFolders())
            {
                if (this.Cancelled)
                {
                    break;
                }
                try {
                    if (!this.treeTraverser.FolderExists(folderToCheck.Path))
                    {
                        this.deleteFolder(folderToCheck.Id, folderToCheck.Path);
                    }
                }
                catch (BackupOperationException e) { this.handleOperationException(e); }
            }
        }
예제 #7
0
            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;
            }
예제 #8
0
        public void Backup() {
            this.Cancelled = false;
            this.WarningOccurred = false;

            FileDatabase.FolderStatus folderStatus;
            int newFolderLevel = -1;
            int prevLevel = -1;
            int curFolderId = -1;
            IEnumerable<TreeTraverser.FileEntry> files;
            FileDatabase.FileStatus fileStatus;

            // Do all the additions, then go through and do the deletions separately
            // This gives us a change to do renames, and makes sure that we empty folders before deleting them

            foreach (TreeTraverser.FolderEntry folder in this.treeTraverser.ListFolders()) {
                if (this.Cancelled)
                    break;

                // files might not get assigned, so assign it now
                files = new TreeTraverser.FileEntry[0];

                try {
                    if (newFolderLevel >= 0 && folder.Level > newFolderLevel) {
                        // Just automatically add it, as a parent somewhere is new
                        curFolderId = this.addFolder(folder);
                    }
                    else {
                        newFolderLevel = -1;
                        folderStatus = this.fileDatabase.InspectFolder(folder.RelPath);

                        switch (folderStatus.FolderModStatus) {
                            case FileDatabase.FolderModStatus.New:
                                newFolderLevel = folder.Level;
                                curFolderId = this.addFolder(folder);
                                break;
                            case FileDatabase.FolderModStatus.Unmodified:
                                curFolderId = folderStatus.Id;
                                this.checkFolder(folder);
                                break;
                        }
                    }
                    // Check for files in this folder
                    files = folder.GetFiles();
                }
                catch (BackupOperationException e) { this.handleOperationException(e); }

                foreach (TreeTraverser.FileEntry file in files) {
                    if (this.Cancelled)
                        break;

                    try {
                        fileStatus = this.fileDatabase.InspectFile(curFolderId, file.RelPath, file.LastModified);

                        switch (fileStatus.FileModStatus) {
                            case FileDatabase.FileModStatus.New:
                                this.addFile(curFolderId, file);
                                break;
                            case FileDatabase.FileModStatus.Newer:
                            case FileDatabase.FileModStatus.Older:
                                this.updatefile(fileStatus.Id, file, fileStatus.MD5);
                                break;
                            case FileDatabase.FileModStatus.Unmodified:
                                // We don't think anything's changed... but make sure the file exists on the backends
                                this.testFile(file, fileStatus.MD5);
                                break;
                        }
                    }
                    catch (BackupOperationException e) { this.handleOperationException(e); }
                }

                prevLevel = folder.Level;
            }

            if (this.Cancelled)
                return;

            // Now we look for file deletions
            IEnumerable<FileDatabase.FileRecord> recordedFiles = this.fileDatabase.RecordedFiles();
            foreach (FileDatabase.FileRecord fileToCheck in recordedFiles) {
                if (this.Cancelled)
                    break;
                if (!this.treeTraverser.FileExists(fileToCheck.Path)) {
                    this.deleteFile(fileToCheck.Id, fileToCheck.Path);
                }
            }

            if (this.Cancelled)
                return;

            // And finally folder deletions
            foreach (FileDatabase.FolderRecord folderToCheck in this.fileDatabase.RecordedFolders()) {
                if (this.Cancelled)
                    break;
                try {
                    if (!this.treeTraverser.FolderExists(folderToCheck.Path)) {
                        this.deleteFolder(folderToCheck.Id, folderToCheck.Path);
                    }
                }
                catch (BackupOperationException e) { this.handleOperationException(e); }
            }
        }