using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; namespace DataOrganizer { public partial class FileViewer : Form { private Dictionary Profiles { get; } = new Dictionary(); private Dictionary FolderGroups { get; } = new Dictionary(); private string CurrentNamingPattern { get; set; } = string.Empty; private ContextMenu PrimaryTreeContextMenu { get; set; } = new ContextMenu(); //Copy to default new content location, set new naming rules etc.. private Snapshot ActiveSnapshotForPrimaryTree { get; set; } private Dictionary PrimaryTreeNodes { get; set; } = new Dictionary(); public FileViewer() { InitializeComponent(); var db = new DB(); var profiles = db.GetProfiles(); foreach(var profile in profiles) { ProfileComboBox.Items.Add(profile.Name); Profiles.Add(profile.Name, profile); } ProfileComboBox.SelectedIndexChanged += ProfileComboBox_SelectedIndexChanged; RootFolderComboBox.SelectedIndexChanged += SelectedFolderComboBox_SelectedIndexChanged; PrimaryFilesTreeView.NodeMouseClick += PrimaryFilesTreeView_NodeMouseClick; FolderSelectButton.Click += FolderSelectButton_Click1; CommitScanResultsButton.Click += CommitScanResultsButton_Click; MoveModifiedFilesButton.Click += MoveModifiedFilesButton_Click; ProfileComboBox.SelectedIndex = 0; } private void MoveModifiedFilesButton_Click(object sender, EventArgs e) { var profile = GetActiveProfile(); var folderGroup = GetActiveFolderGroup(); var files = new List(); files.AddRange(ActiveSnapshotForPrimaryTree.Files.Values.Where(x => x.Status == FileSnapshot.FileStatus.PendingInsert || x.Status == FileSnapshot.FileStatus.PendingUpdate)); foreach(var file in files) { var path = Path.Combine(folderGroup.Name, file.ParentFolder.FullPath.Remove(0, folderGroup.Path.Length + 1)); var newFilePath = Path.Combine(profile.DefaultNewContentFolder, folderGroup.Name, file.PathNoRoot); Directory.CreateDirectory(Path.Combine(profile.DefaultNewContentFolder, path)); UpdateStatusStrip($"Moving {file.Name} to default location '{profile.DefaultNewContentFolder}'."); if(!File.Exists(newFilePath)) File.Copy(file.FullPath, newFilePath); } UpdateStatusStrip($"Finished copying file(s) Copied {files.Count} file(s)."); } private void CommitScanResultsButton_Click(object sender, EventArgs e) { throw new NotImplementedException(); } private void FolderSelectButton_Click1(object sender, EventArgs e) { WriteFilesToDb(GetActiveFolderGroup().Path); } private void PrimaryFilesTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if(ActiveSnapshotForPrimaryTree.Files.ContainsKey(e.Node.Name)) { var file = ActiveSnapshotForPrimaryTree.Files[e.Node.Name]; FileDetailsNameLabel.Text = $"Name: {file.Name}"; FileDetailsFullPathLabel.Text = $"Full Path: {file.FullPath}"; } } private void SelectedFolderComboBox_SelectedIndexChanged(object sender, EventArgs e) { var db = new DB(); var folderGroup = FolderGroups[RootFolderComboBox.Text]; CurrentNamingPattern = db.GetNamingPatternById(folderGroup.PatternId); var profile = Profiles[ProfileComboBox.Text]; PrimaryFilesTreeView.Nodes.Clear(); PrimaryTreeNodes.Clear(); var files = db.GetFilesForProfileByFolderGroup(profile.Id, folderGroup.Id); ActiveSnapshotForPrimaryTree = new Snapshot(files, folderGroup); foreach(var folder in ActiveSnapshotForPrimaryTree.Root.Folders) { PrimaryFilesTreeView.Nodes.Add(GetNodeFromSnapshot(folder)); } CommitScanResultsButton.Enabled = false; MoveModifiedFilesButton.Enabled = false; ScanResultsLabel.Text = string.Empty; } private TreeNode GetNodeFromSnapshot(KeyValuePair folder) { var node = new TreeNode(folder.Value.Name) { Name = folder.Key, ToolTipText = folder.Key }; var regex = new Regex(CurrentNamingPattern); foreach(var f in folder.Value.Folders) { var folderNode = GetNodeFromSnapshot(f); //PrimaryTreeNodes.Add(f.Key, folderNode); node.Nodes.Add(folderNode); if (folderNode.ForeColor == Color.Orange) { node.ForeColor = folderNode.ForeColor; node.ToolTipText = "Naming violations found!"; } } foreach(var file in folder.Value.Files) { var fileNode = new TreeNode(file.Value.Name) { Name = file.Key, ToolTipText = file.Key }; //PrimaryTreeNodes.Add(file.Key, fileNode); if (!regex.IsMatch(file.Value.Name)) fileNode.ForeColor = Color.Orange; node.Nodes.Add(fileNode); if(node.ForeColor != Color.Orange) node.ForeColor = fileNode.ForeColor; PrimaryTreeNodes.Add(file.Key, fileNode); } PrimaryTreeNodes.Add(folder.Key, node); return node; } private void ProfileComboBox_SelectedIndexChanged(object sender, EventArgs e) { var profile = Profiles[ProfileComboBox.Text]; RootFolderComboBox.Items.Clear(); PrimaryTreeNodes.Clear(); FolderGroups.Clear(); if (profile.FolderGroups.Count > 0) { foreach (var folder in profile.FolderGroups) { RootFolderComboBox.Items.Add(folder.Name); FolderGroups.Add(folder.Name, folder); } RootFolderComboBox.SelectedIndex = 0; } RootFolderComboBox.Enabled = true; CommitScanResultsButton.Enabled = false; MoveModifiedFilesButton.Enabled = false; ScanResultsLabel.Text = string.Empty; } private void FolderSelectButton_Click(object sender, EventArgs e) { //var folder = FolderGroups[RootFolderComboBox.Text]; //var profile = Profiles[ProfileComboBox.Text]; //var db = new DB(); //StatusLabel.Text = $"{db.GetNamingPatternById(folder.PatternId)}"; //StatusStrip.Refresh(); //PrimaryFilesTreeView.Nodes.Clear(); //var files = db.GetFilesForProfileByFolderGroup(profile.Id, folder.Id); //if (files.Count == 0) return; //var fileInfos = new List(); //foreach(var file in files) //{ // fileInfos.Add(new FileInfo(file.FullPath)); //} } private void ScanRootFolderButton_Click(object sender, EventArgs e) { CommitScanResultsButton.Enabled = false; MoveModifiedFilesButton.Enabled = false; var folderGroup = GetActiveFolderGroup(); var files = new List(); var rootFolder = new DirectoryInfo(folderGroup.Path); foreach (var dir in rootFolder.EnumerateDirectories()) files.AddRange(ScanDirectory(dir)); var snapShot = new Snapshot(files, folderGroup); ActiveSnapshotForPrimaryTree.MergeSnapshot(snapShot); var newFilesCount = 0; var modifiedFilesCount = 0; var deletedFilesCount = 0; foreach(var f in ActiveSnapshotForPrimaryTree.Files.Values.Where(x => x.Status == FileSnapshot.FileStatus.PendingInsert))//newFiles) { var newNode = new TreeNode(f.Name) { Name = f.FullPath, BackColor = Color.LightBlue, ToolTipText = "New File Found!" }; var folders = ProcessFileFolders(f); Folder previousFolder = null; foreach(var folder in folders) { var node = new TreeNode(folder.Name) { Name = folder.FullPath, BackColor = Color.LightBlue, ToolTipText = "New file found!" }; if (previousFolder == null && !PrimaryTreeNodes.ContainsKey(folder.FullPath)) PrimaryFilesTreeView.Nodes.Add(node); if (!PrimaryTreeNodes.ContainsKey(folder.FullPath)) { PrimaryTreeNodes.Add(folder.FullPath, node); if (previousFolder != null) PrimaryTreeNodes[previousFolder.FullPath].Nodes.Add(node); } previousFolder = folder; } if (!PrimaryTreeNodes.ContainsKey(f.FullPath)) { PrimaryTreeNodes.Add(f.FullPath, newNode); PrimaryTreeNodes[f.ParentFolder.FullPath].Nodes.Add(newNode); newFilesCount++; } } foreach(var f in ActiveSnapshotForPrimaryTree.Files.Where(x => x.Value.Status == FileSnapshot.FileStatus.PendingDelete)) { PrimaryTreeNodes[f.Key].BackColor = Color.Red; PrimaryTreeNodes[f.Key].ToolTipText = "This file has been deleted."; deletedFilesCount++; } foreach(var f in ActiveSnapshotForPrimaryTree.Files.Where(x => x.Value.Status == FileSnapshot.FileStatus.PendingUpdate)) { PrimaryTreeNodes[f.Key].BackColor = Color.DarkBlue; PrimaryTreeNodes[f.Key].ToolTipText = "This file has been modified."; modifiedFilesCount++; } ScanResultsLabel.Text = $"New Files: {newFilesCount}{Environment.NewLine}Modified Files: {modifiedFilesCount}{Environment.NewLine}Deleted Files: {deletedFilesCount}"; if(newFilesCount > 0 || modifiedFilesCount > 0) { CommitScanResultsButton.Enabled = true; MoveModifiedFilesButton.Enabled = true; } } private List ProcessFileFolders(FileSnapshot file) { var folders = new List(); Folder folder = file.ParentFolder; var folderGroup = GetActiveFolderGroup(); while(folder != null) { if(folder.FullPath != folderGroup.Path) folders.Add(folder); folder = folder.Parent; } folders.Reverse(); return folders; } private List ScanDirectory(DirectoryInfo dir) { var files = new List(); files.AddRange(dir.EnumerateFiles()); foreach (var folder in dir.EnumerateDirectories()) files.AddRange(ScanDirectory(folder)); return files; } private void WriteFilesToDb(string root) { var dir = new DirectoryInfo(root); var folder = FolderGroups[RootFolderComboBox.Text]; var profile = Profiles[ProfileComboBox.Text]; //var db = new DB(); //var pattern = db.GetNamingPatternById(folder.PatternId); WriteFilesInFolderToDb(dir.FullName, profile.Id, folder.Id, root); UpdateStatusStrip("Finished processing files."); } private void WriteFilesInFolderToDb(string path, int profileId, int folderId, string root) { var dir = new DirectoryInfo(path); var db = new DB(); var files = GetFileSnapshots(dir.FullName); if(files.Count > 0 ) db.InsertNewFileRecord(files, profileId, folderId, root); foreach(var d in dir.EnumerateDirectories()) { UpdateStatusStrip($"Processing {d.FullName}"); WriteFilesInFolderToDb(d.FullName, profileId, folderId, root); } } private List GetFileSnapshots(string path) { var dir = new DirectoryInfo(path); var profile = GetActiveProfile(); var folderGroup = GetActiveFolderGroup(); var snapshots = new List(); foreach(var file in dir.EnumerateFiles()) { snapshots.Add(new DB.FileSnapshot { PathNoRoot = file.FullName, Name = file.Name, CreationDate = file.CreationTimeUtc, ModifiedDate = file.LastWriteTimeUtc, ProfileId = profile.Id, RootFolderId = folderGroup.Id, Size = file.Length, PatternId = 0 //TODO: Add something that let's the user override the global pattern. }); } return snapshots; } private DB.Profile GetActiveProfile() { return Profiles[ProfileComboBox.Text]; } private DB.FolderGroup GetActiveFolderGroup() { return FolderGroups[RootFolderComboBox.Text]; } private void UpdateStatusStrip(string message) { StatusLabel.Text = message; StatusStrip.Refresh(); } } }