private async Task SyncPlatforms() { using (ProvisioningAppDBContext context = GetContext()) { // Find the platforms file ITemplateFile file = (await _cloneProvider.GetAsync(SYSTEM_PATH, WriteLog)).FindFile(PLATFORMS_NAME); if (file == null) { throw new InvalidOperationException($"Cannot find file {PLATFORMS_NAME}"); } // Deserialize the json var platforms = await file.DownloadAsJsonAsync(new { platforms = new[] { new { id = "", displayName = "" } } }); var existingDbPlatforms = context.Platforms.ToDictionary(c => c.Id, StringComparer.OrdinalIgnoreCase); foreach (var platform in platforms.platforms) { // Update platform, if already exists if (existingDbPlatforms.TryGetValue(platform.id, out Platform dbPlatform)) { dbPlatform.DisplayName = platform.displayName; context.Entry(dbPlatform).State = EntityState.Modified; } else { // Add new platform dbPlatform = new Platform { Id = platform.id, DisplayName = platform.displayName, }; context.Entry(dbPlatform).State = EntityState.Added; } existingDbPlatforms.Remove(platform.id); } // Remove exceed platforms var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbPlatform in existingDbPlatforms) { await context.Entry(dbPlatform.Value).Collection(p => p.Packages).LoadAsync(); foreach (var dbPackage in dbPlatform.Value.Packages.ToArray()) { objectStateManager.ChangeRelationshipState(dbPlatform.Value, dbPackage, p => p.Packages, EntityState.Deleted); } context.Entry(dbPlatform.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task SyncCategories() { using (ProvisioningAppDBContext context = GetContext()) { // Find the category file ITemplateFile file = (await _cloneProvider.GetAsync(SYSTEM_PATH, WriteLog)).FindFile(CATEGORIES_NAME); if (file == null) { throw new InvalidOperationException($"Cannot find file {CATEGORIES_NAME}"); } // Deserialize the json var categories = await file.DownloadAsJsonAsync(new { categories = new[] { new { id = "", displayName = "" } } }); var existingDbCategories = context.Categories.ToDictionary(c => c.Id, StringComparer.OrdinalIgnoreCase); foreach (var category in categories.categories) { // Update category, if already exists if (existingDbCategories.TryGetValue(category.id, out Category dbCategory)) { dbCategory.DisplayName = category.displayName; context.Entry(dbCategory).State = EntityState.Modified; } else { // Add new category dbCategory = new Category { Id = category.id, DisplayName = category.displayName }; context.Entry(dbCategory).State = EntityState.Added; } existingDbCategories.Remove(category.id); } // Remove exceed categories var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbCategory in existingDbCategories) { await context.Entry(dbCategory.Value).Collection(d => d.Packages).LoadAsync(); foreach (var dbPackage in dbCategory.Value.Packages.ToArray()) { objectStateManager.ChangeRelationshipState(dbCategory.Value, dbPackage, d => d.Packages, EntityState.Deleted); } context.Entry(dbCategory.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task SyncFirstReleaseTenants() { using (ProvisioningAppDBContext context = GetContext()) { // Find the category file ITemplateFile file = (await _cloneProvider.GetAsync(SYSTEM_PATH, WriteLog)).FindFile(TENANTS_NAME); if (file == null) { throw new InvalidOperationException($"Cannot find file {TENANTS_NAME}"); } // Deserialize the json var tenantsList = await file.DownloadAsJsonAsync(new { tenants = new[] { new { id = "", tenantName = "", referenceOwner = "" } } }); var existingDbTenants = context.Tenants.ToDictionary(t => t.Id, StringComparer.OrdinalIgnoreCase); foreach (var tenant in tenantsList.tenants) { // Update tenant, if already exists if (existingDbTenants.TryGetValue(tenant.id, out Tenant dbTenant)) { dbTenant.TenantName = tenant.tenantName; dbTenant.ReferenceOwner = tenant.referenceOwner; context.Entry(dbTenant).State = EntityState.Modified; } else { // Add new tenant dbTenant = new Tenant { Id = tenant.id, TenantName = tenant.tenantName, ReferenceOwner = tenant.referenceOwner }; context.Entry(dbTenant).State = EntityState.Added; } existingDbTenants.Remove(tenant.id); } // Remove exceed categories var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbTenant in existingDbTenants) { context.Entry(dbTenant.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task SyncContentPages() { using (ProvisioningAppDBContext context = GetContext()) { // Find the content pages files var files = await _cloneProvider.GetAsync(CONTENT_PATH, WriteLog); if (files == null || files.Count() == 0) { throw new InvalidOperationException($"Cannot find files in folder {CONTENT_PATH}"); } // Consider system pages only var existingDbContentPages = context.ContentPages .ToList() .Where(cp => cp.Id.StartsWith("system", StringComparison.InvariantCultureIgnoreCase)) .ToDictionary(cp => cp.Id, StringComparer.OrdinalIgnoreCase); foreach (ITemplateFile file in files) { // Get the file content String fileContent = await GetHtmlContentAsync(CONTENT_PATH, file.Path.Substring(file.Path.LastIndexOf('/') + 1)); // Update Content Page, if already exists if (existingDbContentPages.TryGetValue(file.Path, out ContentPage dbContentPage)) { dbContentPage.Content = fileContent; context.Entry(dbContentPage).State = EntityState.Modified; } else { // Add new Content Page dbContentPage = new ContentPage { Id = file.Path, Content = fileContent, }; context.Entry(dbContentPage).State = EntityState.Added; } existingDbContentPages.Remove(file.Path); } // Remove leftover pages var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbContentPage in existingDbContentPages) { context.Entry(dbContentPage.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task <DomainModel.Package> GetPackageAsync(ITemplateFolder folder, ProvisioningAppDBContext context) { var items = await _cloneProvider.GetAsync(folder.Path, WriteLog); // Read settings file ITemplateFile settingsFile = items.OfType <ITemplateFile>().FindFile(SETTINGS_NAME); if (settingsFile == null) { WriteLog($"Cannot find file {SETTINGS_NAME}"); return(null); } #region Prepare the settings file and its outline var settings = await settingsFile.DownloadAsJsonAsync(new TemplateSettings()); #endregion // Read the package file ITemplateFile packageFile = items.FindFile(settings.packageFile); if (packageFile == null) { WriteLog($"Cannot find file {settings.packageFile}"); return(null); } #region Fix the Preview Image URLs // Fix the URLs in the metadata settings if (settings?.metadata?.displayInfo?.previewImages != null) { int previewImagesCount = settings.metadata.displayInfo.previewImages.Length; for (var n = 0; n < previewImagesCount; n++) { var previewImageUrl = settings.metadata.displayInfo.previewImages[n].url; settings.metadata.displayInfo.previewImages[n].url = ChangeUri(packageFile.DownloadUri, previewImageUrl); } } if (settings?.metadata?.displayInfo?.detailItemCategories != null) { int detailItemCategoriesCount = settings.metadata.displayInfo.detailItemCategories.Length; for (var n = 0; n < detailItemCategoriesCount; n++) { if (settings.metadata.displayInfo.detailItemCategories[n].items != null) { var detailItemCategoryItemsCount = settings.metadata.displayInfo.detailItemCategories[n].items.Length; for (var m = 0; m < detailItemCategoryItemsCount; m++) { var detailItemCategoryItemPreviewImageUrl = settings.metadata.displayInfo.detailItemCategories[n].items[m].previewImage; if (!String.IsNullOrEmpty(detailItemCategoryItemPreviewImageUrl)) { settings.metadata.displayInfo.detailItemCategories[n].items[m].previewImage = ChangeUri(packageFile.DownloadUri, detailItemCategoryItemPreviewImageUrl); } } } } } #endregion var package = new DomainModel.Package { Id = !string.IsNullOrEmpty(settings.templateId) ? new Guid(settings.templateId) : Guid.NewGuid(), PackageUrl = packageFile.DownloadUri.ToString(), // New properties for Wave2 Promoted = settings.promoted, Preview = settings.preview, TimesApplied = 0, PropertiesMetadata = JsonConvert.SerializeObject(settings.metadata), // New properties for Wave 5 Abstract = settings.@abstract, SortOrder = settings.sortOrder, SortOrderPromoted = settings.sortOrderPromoted, RepositoryRelativeUrl = folder.Path, MatchingSiteBaseTemplateId = settings.matchingSiteBaseTemplateId, ForceNewSite = settings.forceNewSite, Visible = settings.visible, PageTemplateId = settings.metadata?.displayInfo?.pageTemplateId, // New properties for Wave 12 DisplayName = settings.metadata?.displayInfo?.siteTitle, ForceExistingSite = settings.forceExistingSite, }; // Read the instructions.md and the provisioning.md files String instructionsContent = await GetHtmlContentAsync(folder.Path, INSTRUCTIONS_NAME); String provisioningContent = await GetHtmlContentAsync(folder.Path, PROVISIONING_NAME); package.Instructions = instructionsContent; package.ProvisionRecap = provisioningContent; // Read any pre-requirement content files var preRequirementContents = items.FindFiles(i => i.Path.ToLower().Contains("prerequirement-") && i.Path.EndsWith(".md", StringComparison.InvariantCultureIgnoreCase)); // Process content for pre-requirements, if any if (preRequirementContents != null) { // Get the existing content pages for the current folder var existingDbContentPages = context.ContentPages .ToList() .Where(cp => cp.Id.StartsWith(folder.Path, StringComparison.InvariantCultureIgnoreCase)) .ToDictionary(cp => cp.Id, StringComparer.OrdinalIgnoreCase); foreach (var prc in preRequirementContents) { // Get the file content String fileContent = await GetHtmlContentAsync(folder.Path, prc.Path.Substring(prc.Path.LastIndexOf('/') + 1)); // Update Content Page, if already exists if (existingDbContentPages.TryGetValue(prc.Path, out ContentPage dbContentPage)) { dbContentPage.Content = fileContent; context.Entry(dbContentPage).State = EntityState.Modified; } else { // Add new Content Page dbContentPage = new ContentPage { Id = prc.Path, Content = fileContent, }; context.Entry(dbContentPage).State = EntityState.Added; } existingDbContentPages.Remove(prc.Path); } // Remove leftover content pages, if any var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbContentPage in existingDbContentPages) { context.Entry(dbContentPage.Value).State = EntityState.Deleted; } } // Find the categories to apply if (settings.categories != null && settings.categories.Length > 0) { var dbCategories = settings.categories.Select(c => { Category dbCategory = context.Categories.Find(c); if (dbCategory == null) { WriteLog($"Cannot find category with id {c}"); } return(dbCategory); }).ToArray(); package.Categories.AddRange(dbCategories); } // Find the platforms to apply if (settings.platforms != null && settings.platforms.Length > 0) { var dbPlatforms = settings.platforms.Select(p => { Platform dbPlatform = context.Platforms.Find(p); if (dbPlatform == null) { WriteLog($"Cannot find platform with id {p}"); } return(dbPlatform); }).ToArray(); package.TargetPlatforms.AddRange(dbPlatforms); } // Find then author and fill her/his information await FillAuthorAsync(package, packageFile.Path); // Open the package and set info await FillPackageAsync(package, packageFile); return(package); }
private async Task SyncTemplatesAsync(string path, PackageType type) { using (ProvisioningAppDBContext context = GetContext()) { var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; // Find packages inside folder IEnumerable <ITemplateItem> items = await _cloneProvider.GetAsync(path, WriteLog); var packages = await FindPackagesAsync(items, context); var existingDbPackages = context.Packages .Include(c => c.Categories) .Include(c => c.TargetPlatforms) // .Where(p => p.PackageType == type) .ToDictionary(c => c.Id); foreach (DomainModel.Package package in packages) { package.PackageType = type; // Update package, if already exists if (existingDbPackages.TryGetValue(package.Id, out DomainModel.Package dbPackage)) { // Copy info into existing item dbPackage.DisplayName = package.DisplayName; dbPackage.Author = package.Author; dbPackage.AuthorLink = package.AuthorLink; dbPackage.Description = package.Description; dbPackage.ImagePreviewUrl = package.ImagePreviewUrl; dbPackage.PackageUrl = package.PackageUrl; dbPackage.Version = package.Version; // New properties for Wave2 dbPackage.Promoted = package.Promoted; dbPackage.Preview = package.Preview; dbPackage.PropertiesMetadata = package.PropertiesMetadata; // Keep times applied from the DB // dbPackage.TimesApplied = package.TimesApplied; // New properties for Wave 4 dbPackage.Instructions = package.Instructions; dbPackage.ProvisionRecap = package.ProvisionRecap; // New properties for Wave 5 dbPackage.SortOrder = package.SortOrder; dbPackage.SortOrderPromoted = package.SortOrderPromoted; dbPackage.RepositoryRelativeUrl = package.RepositoryRelativeUrl; dbPackage.Abstract = package.Abstract; // New properties for Wave 6 dbPackage.ForceNewSite = package.ForceNewSite; dbPackage.MatchingSiteBaseTemplateId = package.MatchingSiteBaseTemplateId; // New properties for Wave 7 dbPackage.Visible = package.Visible; // New properties for Wave 8 dbPackage.PackageProperties = package.PackageProperties; // Wave 12 - Allowed to move from one type to another dbPackage.PackageType = package.PackageType; dbPackage.ForceExistingSite = package.ForceExistingSite; context.Entry(dbPackage).State = EntityState.Modified; // Add new categories foreach (var c in package.Categories.Except(dbPackage.Categories).ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage, c, d => d.Categories, EntityState.Added); } // Remove old categories foreach (var c in dbPackage.Categories.Except(package.Categories).ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage, c, d => d.Categories, EntityState.Deleted); } // Add new platforms foreach (var c in package.TargetPlatforms.Except(dbPackage.TargetPlatforms).ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage, c, d => d.TargetPlatforms, EntityState.Added); } // Remove old platforms foreach (var c in dbPackage.TargetPlatforms.Except(package.TargetPlatforms).ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage, c, d => d.TargetPlatforms, EntityState.Deleted); } existingDbPackages.Remove(dbPackage.Id); } else { // Add new package context.Entry(package).State = EntityState.Added; } } // Remove leftover packages from current category foreach (var dbPackage in existingDbPackages.Where(p => p.Value.PackageType == type)) { await context.Entry(dbPackage.Value).Collection(d => d.Categories).LoadAsync(); foreach (var dbCategory in dbPackage.Value.Categories.ToArray()) { objectStateManager.ChangeRelationshipState(dbPackage.Value, dbCategory, d => d.Categories, EntityState.Deleted); } context.Entry(dbPackage.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }
private async Task SyncPageTemplates() { using (ProvisioningAppDBContext context = GetContext()) { // Find the category file var pageTemplatesFolders = await _cloneProvider.GetAsync(PAGE_TEMPLATES_PATH, WriteLog); if (pageTemplatesFolders == null || pageTemplatesFolders.Count() == 0) { throw new InvalidOperationException($"Cannot find Page Template folders in folder {PAGE_TEMPLATES_PATH}"); } var existingDbPageTemplates = context.PageTemplates.ToDictionary(cp => cp.Id, StringComparer.OrdinalIgnoreCase); foreach (ITemplateFolder pageTemplateFolder in pageTemplatesFolders) { // Prepare content variables String htmlContent = null; String cssContent = null; // Get the page template folder content files var pageTemplateFiles = await _cloneProvider.GetAsync(pageTemplateFolder.Path, WriteLog); if (pageTemplateFiles == null || pageTemplateFiles.Count() == 0) { throw new InvalidOperationException($"Cannot find template files in Page Template folder {pageTemplateFolder.Path}"); } foreach (ITemplateFile pageTemplateFile in pageTemplateFiles) { // If the content file is an HTML file if (pageTemplateFile.Path.EndsWith(".html", StringComparison.InvariantCultureIgnoreCase)) { // Set the HTML content htmlContent = await GetFileContentAsync(pageTemplateFolder.Path, pageTemplateFile.Path.Substring(pageTemplateFile.Path.LastIndexOf('/') + 1)); } else if (pageTemplateFile.Path.EndsWith(".css", StringComparison.InvariantCultureIgnoreCase)) { // Set the CSS content cssContent = await GetFileContentAsync(pageTemplateFolder.Path, pageTemplateFile.Path.Substring(pageTemplateFile.Path.LastIndexOf('/') + 1)); } if (!String.IsNullOrEmpty(htmlContent) && !String.IsNullOrEmpty(cssContent)) { // If we have both HTML and CSS content, just break the foreach loop break; } } // Update Page Template, if already exists if (existingDbPageTemplates.TryGetValue(pageTemplateFolder.Path, out PageTemplate dbPageTemplate)) { dbPageTemplate.Html = htmlContent; dbPageTemplate.Css = cssContent; context.Entry(dbPageTemplate).State = EntityState.Modified; } else { // Add new Content Page dbPageTemplate = new PageTemplate { Id = pageTemplateFolder.Path, Html = htmlContent, Css = cssContent, }; context.Entry(dbPageTemplate).State = EntityState.Added; } existingDbPageTemplates.Remove(pageTemplateFolder.Path); } // Remove exceed categories var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager; foreach (var dbPageTemplate in existingDbPageTemplates) { context.Entry(dbPageTemplate.Value).State = EntityState.Deleted; } await context.SaveChangesAsync(); } }