363 lines
14 KiB
C#
363 lines
14 KiB
C#
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<string, DB.Profile> Profiles { get; } = new Dictionary<string, DB.Profile>();
|
|
private Dictionary<string, DB.FolderGroup> FolderGroups { get; } = new Dictionary<string, DB.FolderGroup>();
|
|
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<string, TreeNode> PrimaryTreeNodes { get; set; } = new Dictionary<string, TreeNode>();
|
|
|
|
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<FileSnapshot>();
|
|
|
|
files.AddRange(ActiveSnapshotForPrimaryTree.Files.Values.Where(x => x.Status == FileSnapshot.FileStatus.PendingInsert || x.Status == FileSnapshot.FileStatus.PendingUpdate));
|
|
|
|
foreach(var file in files)
|
|
{
|
|
var path = file.ParentFolder.FullPath.Remove(0, folderGroup.Path.Length + 1);
|
|
var newFilePath = Path.Combine(profile.DefaultNewContentFolder, 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);
|
|
}
|
|
}
|
|
|
|
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<string, Folder> 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<FileInfo>();
|
|
|
|
//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<FileInfo>();
|
|
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<Folder> ProcessFileFolders(FileSnapshot file)
|
|
{
|
|
var folders = new List<Folder>();
|
|
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<FileInfo> ScanDirectory(DirectoryInfo dir)
|
|
{
|
|
var files = new List<FileInfo>();
|
|
|
|
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<DB.FileSnapshot> GetFileSnapshots(string path)
|
|
{
|
|
var dir = new DirectoryInfo(path);
|
|
var profile = GetActiveProfile();
|
|
var folderGroup = GetActiveFolderGroup();
|
|
|
|
var snapshots = new List<DB.FileSnapshot>();
|
|
|
|
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();
|
|
}
|
|
}
|
|
}
|