private async Task <IEnumerable <RecipeDescriptor> > HarvestRecipesAsync(ExtensionDescriptor extension) { var recipeLocation = _fileSystem.Combine(extension.Location, extension.Id, "Recipes"); var recipeOptions = _recipeOptions.Value; List <RecipeDescriptor> recipeDescriptors = new List <RecipeDescriptor>(); foreach (var recipeFileExtension in recipeOptions.RecipeFileExtensions) { var fileMatcher = new Matcher(System.StringComparison.OrdinalIgnoreCase); fileMatcher.AddInclude(recipeFileExtension.Key); var recipeFiles = _fileSystem.ListFiles(recipeLocation, fileMatcher); recipeDescriptors.AddRange(await recipeFiles.InvokeAsync(recipeFile => { var recipeParser = _recipeParsers.First(x => x.GetType() == recipeFileExtension.Value); using (var stream = recipeFile.CreateReadStream()) { var recipe = recipeParser.ParseRecipe(stream); recipe.Location = recipeFile.PhysicalPath.Replace(_fileSystem.RootPath, "").TrimStart(System.IO.Path.DirectorySeparatorChar); return(Task.FromResult(recipe)); } }, Logger)); } return(recipeDescriptors); }
private List <ExtensionDescriptor> AvailableExtensionsInFolder(string path, string extensionType, string manifestName, bool manifestIsOptional) { var localList = new List <ExtensionDescriptor>(); if (string.IsNullOrEmpty(path)) { return(localList); } if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Start looking for extensions in '{0}'...", path); } var subfolders = _fileSystem.ListDirectories(path); foreach (var subfolder in subfolders) { var extensionId = subfolder.Name; var manifestPath = _fileSystem.Combine(path, extensionId, manifestName); try { var descriptor = GetExtensionDescriptor(path, extensionId, extensionType, manifestPath, manifestIsOptional); if (descriptor == null) { continue; } if (descriptor.Path != null && !descriptor.Path.IsValidUrlSegment()) { _logger.LogError("The module '{0}' could not be loaded because it has an invalid Path ({1}). It was ignored. The Path if specified must be a valid URL segment. The best bet is to stick with letters and numbers with no spaces.", extensionId, descriptor.Path); continue; } if (descriptor.Path == null) { descriptor.Path = descriptor.Name.IsValidUrlSegment() ? descriptor.Name : descriptor.Id; } localList.Add(descriptor); } catch (Exception ex) { // Ignore invalid module manifests _logger.LogError(string.Format("The module '{0}' could not be loaded. It was ignored.", extensionId), ex); } } if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Done looking for extensions in '{0}': {1}", path, string.Join(", ", localList.Select(d => d.Id))); } return(localList); }
public static IOrchardFileSystem GetExtensionFileProvider( this IOrchardFileSystem parentFileSystem, ExtensionDescriptor extensionDescriptor, ILogger logger) { var subPath = parentFileSystem.Combine(extensionDescriptor.Location, extensionDescriptor.Id); return(parentFileSystem .GetSubPathFileProvider(subPath, logger)); }
public void Discover(ShapeTableBuilder builder) { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Start discovering shapes"); } var harvesterInfos = _harvesters.Select(harvester => new { harvester, subPaths = harvester.SubPaths() }); var activeFeatures = _featureManager.GetEnabledFeaturesAsync().Result; var activeExtensions = Once(activeFeatures); var hits = activeExtensions.Select(extensionDescriptor => { if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Start discovering candidate views filenames"); } var matcher = new Matcher(); foreach(var extension in _shapeTemplateViewEngines.SelectMany(x => x.TemplateFileExtensions)) { matcher.AddInclude(string.Format("*.{0}", extension)); } var pathContexts = harvesterInfos.SelectMany(harvesterInfo => harvesterInfo.subPaths.Select(subPath => { var basePath = _fileSystem.Combine(extensionDescriptor.Location, extensionDescriptor.Id); var virtualPath = _fileSystem.Combine(basePath, subPath); var files = _fileSystem.ListFiles(virtualPath, matcher).ToReadOnlyCollection(); return new { harvesterInfo.harvester, basePath, subPath, virtualPath, files }; })).ToList(); if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Done discovering candidate views filenames"); } var fileContexts = pathContexts.SelectMany(pathContext => _shapeTemplateViewEngines.SelectMany(ve => { return pathContext.files.Select( file => new { fileName = Path.GetFileNameWithoutExtension(file.Name), fileVirtualPath = "~/" + _fileSystem.Combine(pathContext.virtualPath, file.Name), pathContext }); })); var shapeContexts = fileContexts.SelectMany(fileContext => { var harvestShapeInfo = new HarvestShapeInfo { SubPath = fileContext.pathContext.subPath, FileName = fileContext.fileName, TemplateVirtualPath = fileContext.fileVirtualPath }; var harvestShapeHits = fileContext.pathContext.harvester.HarvestShape(harvestShapeInfo); return harvestShapeHits.Select(harvestShapeHit => new { harvestShapeInfo, harvestShapeHit, fileContext }); }); return shapeContexts.Select(shapeContext => new { extensionDescriptor, shapeContext }).ToList(); }).SelectMany(hits2 => hits2); foreach (var iter in hits) { // templates are always associated with the namesake feature of module or theme var hit = iter; var featureDescriptors = iter.extensionDescriptor.Features.Where(fd => fd.Id == hit.extensionDescriptor.Id); foreach (var featureDescriptor in featureDescriptors) { if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Binding {0} as shape [{1}] for feature {2}", hit.shapeContext.harvestShapeInfo.TemplateVirtualPath, iter.shapeContext.harvestShapeHit.ShapeType, featureDescriptor.Id); } builder.Describe(iter.shapeContext.harvestShapeHit.ShapeType) .From(new Feature { Descriptor = featureDescriptor }) .BoundAs( hit.shapeContext.harvestShapeInfo.TemplateVirtualPath, shapeDescriptor => displayContext => RenderAsync(shapeDescriptor, displayContext, hit.shapeContext.harvestShapeInfo, hit.shapeContext.harvestShapeHit)); } } if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Done discovering shapes"); } }
/// <summary> /// Combine a set of virtual paths into a virtual path relative to "~/App_Data" /// </summary> public string Combine(params string[] paths) { return(_fileSystem.Combine(paths)); }