private void SaveProvisioningTemplateInternal(ClientContext context, GetProvisioningTemplateJob job, Boolean globalRepository = true) { // Fix the job filename if it is missing the .pnp extension if (!job.FileName.ToLower().EndsWith(".pnp")) { job.FileName += ".pnp"; } // Get a reference to the target web site Web web = context.Web; context.Load(web, w => w.Url); context.ExecuteQueryRetry(); // Prepare the support variables ClientContext repositoryContext = null; Web repositoryWeb = null; // Define whether we need to use the global infrastructural repository or the local one if (globalRepository) { // Get a reference to the global repository web site and context repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext( PnPPartnerPackSettings.InfrastructureSiteUrl); } else { // Get a reference to the local repository web site and context repositoryContext = web.Context.GetSiteCollectionContext(); } using (repositoryContext) { repositoryWeb = repositoryContext.Site.RootWeb; repositoryContext.Load(repositoryWeb, w => w.Url); repositoryContext.ExecuteQueryRetry(); // Configure the XML SharePoint provider for the Infrastructural Site Collection XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider(job.FileName, new SharePointConnector(repositoryContext, repositoryWeb.Url, PnPPartnerPackConstants.PnPProvisioningTemplates)); ProvisioningTemplateCreationInformation ptci = new ProvisioningTemplateCreationInformation(web); ptci.FileConnector = provider.Connector; ptci.IncludeAllTermGroups = job.IncludeAllTermGroups; ptci.IncludeSearchConfiguration = job.IncludeSearchConfiguration; ptci.IncludeSiteCollectionTermGroup = job.IncludeSiteCollectionTermGroup; ptci.IncludeSiteGroups = job.IncludeSiteGroups; ptci.PersistBrandingFiles = job.PersistComposedLookFiles; // We do intentionally remove taxonomies and search, which are not supported // in the AppOnly Authorization model // For further details, see the PnP Partner Pack documentation ptci.HandlersToProcess ^= Handlers.TermGroups; ptci.HandlersToProcess ^= Handlers.SearchSettings; // Extract the current template ProvisioningTemplate templateToSave = web.GetProvisioningTemplate(ptci); templateToSave.Description = job.Description; templateToSave.DisplayName = job.Title; // Save template image preview in folder Microsoft.SharePoint.Client.Folder templatesFolder = repositoryWeb.GetFolderByServerRelativeUrl(PnPPartnerPackConstants.PnPProvisioningTemplates); repositoryContext.Load(templatesFolder, f => f.ServerRelativeUrl, f => f.Name); repositoryContext.ExecuteQueryRetry(); // If there is a preview image if (job.TemplateImageFile != null) { // Determine the preview image file name String previewImageFileName = job.FileName.ToLower().Replace(".pnp", "_preview.png"); // Save the preview image inside the Open XML package provider.Connector.SaveFileStream(previewImageFileName, job.TemplateImageFile.ToStream()); // And store URL in the XML file templateToSave.ImagePreviewUrl = String.Format("{0}{1}/{2}/{3}/{4}", repositoryWeb.Url.ToLower().StartsWith("https") ? "pnps" : "pnp", repositoryWeb.Url.Substring(repositoryWeb.Url.IndexOf("://")), templatesFolder.Name, job.FileName, previewImageFileName); } // And save it on the file system provider.SaveAs(templateToSave, job.FileName.ToLower().Replace(".pnp", ".xml")); Microsoft.SharePoint.Client.File templateFile = templatesFolder.GetFile(job.FileName); ListItem item = templateFile.ListItemAllFields; item[PnPPartnerPackConstants.ContentTypeIdField] = PnPPartnerPackConstants.PnPProvisioningTemplateContentTypeId; item[PnPPartnerPackConstants.TitleField] = job.Title; item[PnPPartnerPackConstants.PnPProvisioningTemplateScope] = job.Scope.ToString(); item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl] = job.SourceSiteUrl; item.Update(); repositoryContext.ExecuteQueryRetry(); } }
/// <summary> /// Upload the specific file to the destination folder /// </summary> /// <param name="checkIn"></param> /// <param name="destinationFolder"></param> /// <param name="fileNameWithPath"></param> /// <returns></returns> private bool UploadFileToSharePointFolder(Microsoft.SharePoint.Client.Folder destinationFolder, string directoryPath) { // Retrieve the files in the directory var filesInDirectPath = System.IO.Directory.GetFiles(directoryPath, "*", System.IO.SearchOption.TopDirectoryOnly); if (filesInDirectPath.Count() > 0) { // Upload the file LogVerbose("Uploading directory {0} files", directoryPath); // For each file in the source folder being evaluated, call the UploadFile function to upload the file to the appropriate location foreach (var fileNameWithPath in filesInDirectPath) { try { var fileExists = false; var fileTags = string.Empty; var fileInfo = new System.IO.FileInfo(fileNameWithPath); // Notify the operator that the file is being uploaed to a specific location LogVerbose("Uploading file {0} to {1}", fileInfo.Name, destinationFolder.Name); try { var fileInFolder = destinationFolder.GetFile(fileInfo.Name); if (fileInFolder != null) { fileExists = true; LogVerbose("File {0} exists in the destination folder. Skip uploading file.....", fileInfo.Name); } } catch (Exception ex) { LogError(ex, "Failed check file {0} existance test.", fileInfo.Name); } if (!fileExists) { try { if (this.MetadataList.Any(md => md.FullPath == fileInfo.FullName)) { var distinctTags = this.MetadataList.Where(md => md.FullPath == fileInfo.FullName).Select(s => s.Tag).Distinct(); fileTags = string.Join(@";", distinctTags); } } catch (Exception ex) { LogDebugging("Failed to pull metadata from CSV file {0}", ex.Message); } using (var stream = new System.IO.FileStream(fileNameWithPath, System.IO.FileMode.Open)) { var creationInfo = new Microsoft.SharePoint.Client.FileCreationInformation(); creationInfo.Overwrite = true; creationInfo.ContentStream = stream; creationInfo.Url = fileInfo.Name; var uploadStatus = destinationFolder.Files.Add(creationInfo); if (!uploadStatus.IsPropertyAvailable("ListItemAllFields")) { this.ClientContext.Load(uploadStatus, w => w.ListItemAllFields); this.ClientContext.ExecuteQuery(); } if (!string.IsNullOrEmpty(fileTags)) { uploadStatus.ListItemAllFields["_Source"] = fileTags; } uploadStatus.ListItemAllFields[ConstantsListFields.Field_Modified] = fileInfo.LastWriteTime; uploadStatus.ListItemAllFields.SystemUpdate(); if (this.CheckIn) { this.ClientContext.Load(uploadStatus); this.ClientContext.ExecuteQuery(); if (uploadStatus.CheckOutType != Microsoft.SharePoint.Client.CheckOutType.None) { uploadStatus.CheckIn("Checked in by Administrator", Microsoft.SharePoint.Client.CheckinType.MajorCheckIn); } } this.ClientContext.Load(uploadStatus); this.ClientContext.ExecuteQuery(); } } } catch (Exception ex) { LogError(ex, "Failed in UploadFileToSharePointFolder destination {0} and file {1}", destinationFolder, fileNameWithPath); } } return(true); // Has Files } return(false); // No Files in Directory }
private void SaveProvisioningTemplateInternal(ClientContext context, GetProvisioningTemplateJob job, Boolean globalRepository = true) { // Fix the job filename if it is missing the .pnp extension if (!job.FileName.ToLower().EndsWith(".pnp")) { job.FileName += ".pnp"; } // Get the Access Token from the current context //var accessToken = "Bearer " + context.GetAccessToken(); var accessToken = context.GetAccessToken(); Console.WriteLine("Bearer " + accessToken); // Get a reference to the target web site Web web = context.Web; context.Load(web, w => w.Url, w => w.ServerRelativeUrl); context.ExecuteQueryRetry(); // Prepare the support variables ClientContext repositoryContext = null; Web repositoryWeb = null; // Define whether we need to use the global infrastructural repository or the local one if (globalRepository) { // Get a reference to the global repository web site and context repositoryContext = PnPPartnerPackContextProvider.GetAppOnlyClientContext( PnPPartnerPackSettings.InfrastructureSiteUrl); } else { // Get a reference to the local repository web site and context repositoryContext = web.Context.GetSiteCollectionContext(); } using (repositoryContext) { repositoryWeb = repositoryContext.Site.RootWeb; repositoryContext.Load(repositoryWeb, w => w.Url); repositoryContext.ExecuteQueryRetry(); // Configure the XML SharePoint provider for the Infrastructural Site Collection XMLTemplateProvider provider = new XMLOpenXMLTemplateProvider(job.FileName, new SharePointConnector(repositoryContext, repositoryWeb.Url, PnPPartnerPackConstants.PnPProvisioningTemplates)); ProvisioningTemplateCreationInformation ptci = new ProvisioningTemplateCreationInformation(web); ptci.FileConnector = provider.Connector; ptci.IncludeAllTermGroups = job.IncludeAllTermGroups; ptci.IncludeSearchConfiguration = job.IncludeSearchConfiguration; ptci.IncludeSiteCollectionTermGroup = job.IncludeSiteCollectionTermGroup; ptci.IncludeSiteGroups = job.IncludeSiteGroups; ptci.PersistBrandingFiles = job.PersistComposedLookFiles; // We do intentionally remove taxonomies and search, which are not supported // in the AppOnly Authorization model // For further details, see the PnP Partner Pack documentation ptci.HandlersToProcess ^= Handlers.TermGroups; ptci.HandlersToProcess ^= Handlers.SearchSettings; // Extract the current template ProvisioningTemplate templateToSave = web.GetProvisioningTemplate(ptci); templateToSave.Description = job.Description; templateToSave.DisplayName = job.Title; if (job.PersistComposedLookFiles) { // Create Theme Entity object ThemeEntity themeEntity = web.GetCurrentComposedLook(); foreach (var p in themeEntity.GetType().GetProperties().Where(p => p.GetGetMethod().GetParameters().Count() == 0)) { string propName = p.Name; string propValue = Convert.ToString(p.GetValue(themeEntity, null)); if (propName == "Theme") { propName = "ColorFile"; } else if (propName == "Font") { propName = "FontFile"; } else if (propName == "BackgroundImage") { propValue = "PlaceHolderValue"; } else if (propName == "Name" && String.IsNullOrEmpty(propValue)) { propValue = "CustomTheme"; } string fileName = propValue.Substring(propValue.LastIndexOf("/") + 1); string relativeURL = propValue.Substring(0, propValue.LastIndexOf("/") + 1); // Update template Files if (propName != "Name" && propName != "IsCustomComposedLook" && !String.IsNullOrEmpty(propValue)) { var property = templateToSave.ComposedLook.GetType().GetProperty(propName); try { string folderPath = ""; Stream fileStream = null; if (propName == "BackgroundImage") { if (job.templateBackgroundImgFile != null) { folderPath = "{site}/SiteAssets"; fileName = job.FileName.ToLower().Replace(".pnp", ".png"); fileStream = job.templateBackgroundImgFile.ToStream(); Console.WriteLine("fileName: " + fileName); Console.WriteLine("fileStream: " + fileStream); templateToSave.ComposedLook.BackgroundFile = String.Format("{{sitecollection}}/SiteAssets/{0}", fileName); } } else if (propName.Contains("MasterPage")) { folderPath = "{masterpagecatalog}"; var strUrl = String.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}{2}')/$value", web.Url, web.ServerRelativeUrl, propValue); fileStream = HttpHelper.MakeGetRequestForStream(strUrl, "application/octet-stream", accessToken); property.SetValue(templateToSave.ComposedLook, String.Format("{{masterpagecatalog}}/{0}", fileName), new object[] { }); } else { folderPath = "{themecatalog}/15"; var strUrl = String.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}{2}')/$value", web.Url, web.ServerRelativeUrl, propValue); fileStream = HttpHelper.MakeGetRequestForStream(strUrl, "application/octet-stream", accessToken); property.SetValue(templateToSave.ComposedLook, String.Format("{{themecatalog}}/15/{0}", fileName), new object[] { }); } Console.WriteLine("Saving files: {0}, {1}", fileName, fileStream); provider.Connector.SaveFileStream(fileName, fileStream); Console.WriteLine("File Paths: {0}, {1}", fileName, folderPath); templateToSave.Files.Add(new OfficeDevPnP.Core.Framework.Provisioning.Model.File { Src = fileName, Folder = folderPath, Overwrite = true, }); Console.WriteLine("Files saved: {0}, {1}", fileName, folderPath); } catch (Exception ex) { Console.WriteLine(ex); } } else if (propName == "Name") { var property = templateToSave.ComposedLook.GetType().GetProperty(propName); property.SetValue(templateToSave.ComposedLook, fileName, new object[] { }); } } if (job.templateAltCSSFile != null) { //TODO: Add handling for native Alternate CSS //web.AlternateCssUrl; string folderPath = "{site}/SiteAssets"; string fileName = job.FileName.ToLower().Replace(".pnp", ".css"); Stream fileStream = job.templateAltCSSFile.ToStream(); provider.Connector.SaveFileStream(fileName, fileStream); templateToSave.WebSettings = new WebSettings { AlternateCSS = String.Format("{{sitecollection}}/SiteAssets/{0}", fileName), }; Console.WriteLine("File Paths: {0}, {1}", fileName, folderPath); templateToSave.Files.Add(new OfficeDevPnP.Core.Framework.Provisioning.Model.File { Src = fileName, Folder = folderPath, Overwrite = true, }); } } // Save template image preview in folder Microsoft.SharePoint.Client.Folder templatesFolder = repositoryWeb.GetFolderByServerRelativeUrl(PnPPartnerPackConstants.PnPProvisioningTemplates); repositoryContext.Load(templatesFolder, f => f.ServerRelativeUrl, f => f.Name); repositoryContext.ExecuteQueryRetry(); // If there is a preview image if (job.TemplateImageFile != null) { // Determine the preview image file name String previewImageFileName = job.FileName.ToLower().Replace(".pnp", "_preview.png"); // Save the preview image inside the Open XML package provider.Connector.SaveFileStream(previewImageFileName, job.TemplateImageFile.ToStream()); // And store URL in the XML file templateToSave.ImagePreviewUrl = String.Format("{0}{1}/{2}/{3}/{4}", repositoryWeb.Url.ToLower().StartsWith("https") ? "pnps" : "pnp", repositoryWeb.Url.Substring(repositoryWeb.Url.IndexOf("://")), templatesFolder.Name, job.FileName, previewImageFileName); } // And save it on the file system provider.SaveAs(templateToSave, job.FileName.ToLower().Replace(".pnp", ".xml")); Microsoft.SharePoint.Client.File templateFile = templatesFolder.GetFile(job.FileName); ListItem item = templateFile.ListItemAllFields; item[PnPPartnerPackConstants.ContentTypeIdField] = PnPPartnerPackConstants.PnPProvisioningTemplateContentTypeId; item[PnPPartnerPackConstants.TitleField] = job.Title; item[PnPPartnerPackConstants.PnPProvisioningTemplateScope] = job.Scope.ToString(); item[PnPPartnerPackConstants.PnPProvisioningTemplateSourceUrl] = job.SourceSiteUrl; item.Update(); repositoryContext.ExecuteQueryRetry(); } }