using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.IO; using System.Linq; using System.Security; using System.Security.Permissions; using System.Security.Principal; using System.Web; namespace Disco.Web.Models.InitialConfig { public class FileStoreModel { public FileStoreModel() { DirectoryModel = FileStoreModel.FileStoreDirectoryModel.DirectoryRoots(); } [Required(), CustomValidation(typeof(FileStoreModel), "DirectoryPermissionRequired")] public string FileStoreLocation { get; set; } public FileStoreDirectoryModel DirectoryModel { get; set; } public void ExpandDirectoryModel() { if (!string.IsNullOrWhiteSpace(FileStoreLocation)) { var branches = this.FileStoreLocation.ToUpper().Split(Path.DirectorySeparatorChar); var branchesCase = this.FileStoreLocation.Split(Path.DirectorySeparatorChar); FileStoreDirectoryModel branchModel; FileStoreDirectoryModel branchParent = this.DirectoryModel; for (int i = 0; i < branches.Length; i++) { var branch = branches[i]; if (branchParent.SubDirectories.TryGetValue(branch, out branchModel)) { branchModel.ExpandSubDirectories(); } else { // Drive Letter doesn't exist if (branchParent.Path == null) break; // New branchModel = FileStoreDirectoryModel.FromNew(branchesCase[i], Path.Combine(branchParent.Path, branchesCase[i])); branchParent.SubDirectories.Add(branchModel.Name.ToUpper(), branchModel); } branchParent = branchModel; } } } public static ValidationResult DirectoryPermissionRequired(object value, ValidationContext validationContext) { var instance = validationContext.ObjectInstance as FileStoreModel; if (instance != null && !string.IsNullOrEmpty(instance.FileStoreLocation)) { var stringValue = value as string; DirectoryInfo info = new DirectoryInfo(stringValue); if (!info.Exists) { // Try and Create try { info.Create(); } catch (Exception ex) { return new ValidationResult(string.Format("Unable to Create Directory '{0}'; [{1}] {2}", info.FullName, ex.GetType().Name, ex.Message)); } } } return ValidationResult.Success; } public class FileStoreDirectoryModel { public string Name { get; set; } public string Path { get; set; } public bool IsNew { get; set; } public bool Selectable { get; set; } public Dictionary SubDirectories { get; set; } internal static FileStoreDirectoryModel FromInfo(DirectoryInfo info) { return new FileStoreDirectoryModel() { Name = info.Name, Path = info.FullName, IsNew = false, Selectable = (info.Root.Name != info.Name) }; } internal static FileStoreDirectoryModel FromNew(string Name, string FullPath) { return new FileStoreDirectoryModel() { Name = Name, Path = FullPath, IsNew = true, Selectable = true, SubDirectories = new Dictionary() }; } internal static FileStoreDirectoryModel FromInfo(DriveInfo info) { return new FileStoreDirectoryModel() { Name = info.Name.Substring(0, 2), Path = info.RootDirectory.Name, IsNew = false, Selectable = false }; } internal static FileStoreDirectoryModel FromPath(string DirectoryPath, bool ExpandSubDirectories) { DirectoryInfo info = new DirectoryInfo(DirectoryPath); if (info.Exists) { var fsd = FromInfo(info); if (ExpandSubDirectories) fsd.ExpandSubDirectories(); return fsd; } else return null; } internal static FileStoreDirectoryModel DirectoryRoots() { var root = new FileStoreDirectoryModel() { Name = "ROOT", Path = null, IsNew = false, Selectable = false, SubDirectories = new Dictionary() }; foreach (var driveInfo in DriveInfo.GetDrives()) { if (driveInfo.DriveType == DriveType.Fixed) root.SubDirectories.Add(driveInfo.Name.Substring(0, 2).ToUpper(), FileStoreDirectoryModel.FromInfo(driveInfo)); } return root; } internal void ExpandSubDirectories() { if (this.SubDirectories == null) { this.SubDirectories = new Dictionary(); if (!this.IsNew) { var dirInfo = new DirectoryInfo(Path); if (dirInfo.Exists) { foreach (var subDir in dirInfo.EnumerateDirectories()) { this.SubDirectories.Add(subDir.Name.ToUpper(), FileStoreDirectoryModel.FromInfo(subDir)); } } else { this.IsNew = true; } } } } } } }