/***************************************************/ /**** Public Methods ****/ /***************************************************/ public IEnumerable <object> Read(FileDirRequest fdr, PullConfig pullConfig) { // Copy for immutability in UI FileDirRequest fdrCopy = BH.Engine.Base.Query.ShallowClone(fdr); // Recursively walk the directories to retrieve File and Directory Info. List <IFSInfo> output = new List <IFSInfo>(); List <FSFile> files = new List <FSFile>(); List <FSDirectory> dirs = new List <FSDirectory>(); WildcardPattern wildcardPattern = null; if (!Modify.ProcessFileDirRequest(fdrCopy, out wildcardPattern)) { return(null); } int retrievedFiles = 0, retrievedDirs = 0; WalkDirectories(files, dirs, fdrCopy, ref retrievedFiles, ref retrievedDirs, pullConfig.IncludeHiddenFiles, pullConfig.IncludeSystemFiles, wildcardPattern); output.AddRange(dirs); output.AddRange(files); // If a sort order is applied, sort separately files and dirs, // then return the maxItems of each of those. if (fdrCopy.SortOrder != SortOrder.Default) { output = Query.SortOrder(output, fdrCopy.SortOrder); files = output.OfType <FSFile>().Take(fdrCopy.MaxFiles == -1 ? output.Count : fdrCopy.MaxFiles).ToList(); dirs = output.OfType <FSDirectory>().Take(fdrCopy.MaxDirectories == -1 ? output.Count : fdrCopy.MaxDirectories).ToList(); } if (fdrCopy.IncludeFileContents) { files.ForEach(f => ReadAndAddContent(f)); } output = new List <IFSInfo>(); if (fdrCopy.SortOrder != SortOrder.Default && fdrCopy.SortOrder != SortOrder.ByName) { output.AddRange(files); output.AddRange(dirs); } else { output.AddRange(dirs); output.AddRange(files); } return(output); }
/***************************************************/ /*** Methods ***/ /***************************************************/ public static oM.Adapters.File.FileRequest ToFileRequest(this FileDirRequest fdr) { return(new FileRequest() { Location = fdr.Location, IncludeFileContents = fdr.IncludeFileContents, SearchSubdirectories = fdr.SearchSubdirectories, MaxFiles = fdr.MaxFiles, MaxNesting = fdr.MaxNesting, }); }
public static bool ProcessFileDirRequest(this FileDirRequest fdr, out WildcardPattern wildcardPattern) { wildcardPattern = null; if (WildcardPattern.ContainsWildcardCharacters(fdr.Location)) { if (WildcardPattern.ContainsWildcardCharacters(fdr.Location)) { string allButLastSegment = fdr.Location.Remove(fdr.Location.Count() - Path.GetFileName(fdr.Location).Count()); if (WildcardPattern.ContainsWildcardCharacters(allButLastSegment)) { BH.Engine.Base.Compute.RecordError("Wildcards are only allowed in the last segment of the path."); return(false); } else { wildcardPattern = new WildcardPattern(Path.GetFileName(fdr.Location)); } } if (fdr.IncludeDirectories) { BH.Engine.Base.Compute.RecordWarning($"The usage of Wildcards is limited to file retrievals: " + $"\ncannot have `{nameof(FileDirRequest)}.{nameof(fdr.IncludeDirectories)}` set to true while a Wildcard is specified in the path." + $"\nDefaulting `{nameof(fdr.IncludeDirectories)}` to false and continuing."); fdr.IncludeDirectories = false; } if (fdr.IncludeFileContents) { BH.Engine.Base.Compute.RecordNote($"Note that `{nameof(fdr.IncludeFileContents)}` works only for BHoM-serialized JSON files."); } } return(true); }
private void WalkDirectories(List <FSFile> files, List <FSDirectory> dirs, FileDirRequest fdr, ref int filesCount, ref int dirsCount, bool inclHidFiles = false, bool inclSysFiles = false, WildcardPattern wildcardPattern = null) { // Recursion stop condition. if (fdr.MaxNesting == 0) { return; } // Look in directory and, if requested, recursively in subdirectories. if (string.IsNullOrWhiteSpace(fdr.Location)) { BH.Engine.Base.Compute.RecordError($"Missing parameter {nameof(fdr.Location)} from the request."); return; } System.IO.DirectoryInfo selectedDir = new System.IO.DirectoryInfo(fdr.Location.IFullPath()); System.IO.DirectoryInfo[] dirArray = new System.IO.DirectoryInfo[] { }; // Check if the location points to a single file. // To point to a single file, the location must not be a wildcard (therefore wildcardPattern must be null) // and it must have an extension. bool isSingleFile = Path.HasExtension(selectedDir.FullName) && wildcardPattern == null; if (!isSingleFile) // If the location points to a directory, populate the list of folders there. { dirArray = selectedDir.GetDirectories(); } else // if the location points to a single file, the selected directory is its parent. { selectedDir = new System.IO.DirectoryInfo(Path.GetDirectoryName(selectedDir.FullName)); } foreach (System.IO.DirectoryInfo di in dirArray) { oM.Adapters.File.FSDirectory bhomDir = ReadDirectory(di.FullName, inclHidFiles, inclSysFiles); if (bhomDir == null) { continue; } bhomDir.ParentDirectory = di.Parent.ToFiling(); if (fdr.Exclusions != null && fdr.Exclusions.Contains(bhomDir)) { continue; } if (fdr.IncludeDirectories && wildcardPattern == null) { if (fdr.SortOrder != SortOrder.Default || !MaxItemsReached(fdr.MaxDirectories, dirsCount)) { // The limit in number of item retrieved in WalkDirectories applies only if there is no sortOrder applied. // If a sortOrder is applied, the maxItems must be applied after the sorting is done (outside of WalkDirectories) // Check exclusions if (fdr.Exclusions != null && fdr.Exclusions.Contains(bhomDir)) { continue; } // Check Wildcard matches - DISABLED: only allow wildcards in filename. Too complicated otherwise. //if (!wildcardPattern?.IsMatch(bhomDir.Name) ?? false) // continue; dirs.Add(bhomDir); dirsCount += 1; } } // Recurse if requested, and if the limits are not exceeded. if (fdr.SearchSubdirectories == true && !MaxItemsReached(fdr.MaxFiles, filesCount, fdr.MaxDirectories, dirsCount)) { FileDirRequest fdrRecurse = BH.Engine.Base.Query.ShallowClone(fdr); fdrRecurse.Location = bhomDir.IFullPath(); fdrRecurse.MaxNesting -= 1; WalkDirectories(files, dirs, fdrRecurse, ref filesCount, ref dirsCount, inclHidFiles, inclSysFiles, wildcardPattern); } } if (fdr.IncludeFiles) { System.IO.FileInfo[] fileInfos = new System.IO.FileInfo[1]; try { if (isSingleFile) { fileInfos[0] = new FileInfo(fdr.Location.IFullPath()); } else { fileInfos = selectedDir.GetFiles("*.*"); } } // This is thrown if one of the files requires permissions greater than the application provides. catch (UnauthorizedAccessException e) { // Write out the message and continue. BH.Engine.Base.Compute.RecordNote(e.Message); } foreach (var fi in fileInfos) { if (fdr.SortOrder != SortOrder.Default || !MaxItemsReached(fdr.MaxFiles, filesCount)) { // The limit in number of item retrieved in WalkDirectories applies only if there is no sortOrder applied. // If a sortOrder is applied, the maxItems must be applied after the sorting is done (outside of WalkDirectories) // Check exclusions if (fdr.Exclusions != null && fdr.Exclusions.Contains(fi.ToFiling())) { continue; } // Check Wildcard matches if (!wildcardPattern?.IsMatch(fi.Name) ?? false) { continue; } // When reading the file, do not retrieve content. // Content must be retrieved after WalkDirectories has run. // This is because additional filtering might be done later. oM.Adapters.File.FSFile omFile = ReadFile(fi.FullName, false, inclHidFiles, inclSysFiles); if (omFile != null) { files.Add(omFile); filesCount += 1; } } else { break; } } } }