internal void PersistFile(Web web, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, string folderPath, string fileName, Boolean decodeFileName = false) { if (creationInfo.FileConnector != null) { SharePointConnector connector = new SharePointConnector(web.Context, web.Url, "dummy"); Uri u = new Uri(web.Url); if (folderPath.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1) { folderPath = folderPath.Replace(u.PathAndQuery, ""); } using (Stream s = connector.GetFileStream(fileName, folderPath)) { if (s != null) { creationInfo.FileConnector.SaveFileStream(decodeFileName ? HttpUtility.UrlDecode(fileName) : fileName, s); } } } else { WriteWarning("No connector present to persist homepage.", ProvisioningMessageType.Error); scope.LogError("No connector present to persist homepage"); } }
public void SharePointConnectorGetFile1Test() { SharePointConnector spConnector = new SharePointConnector(); spConnector.Parameters.Add(AzureStorageConnector.CONNECTIONSTRING, TestCommon.DevSiteUrl); spConnector.Parameters.Add(AzureStorageConnector.CONTAINER, testContainerSecure); spConnector.Parameters.Add(SharePointConnector.CLIENTCONTEXT, TestCommon.CreateClientContext()); string file = spConnector.GetFile("ProvisioningTemplate-2015-03-Sample-01.xml"); Assert.IsNotNull(file); string file2 = spConnector.GetFile("Idonotexist.xml"); Assert.IsNull(file2); }
public void SharePointConnectorDelete1Test() { SharePointConnector spConnector = new SharePointConnector(TestCommon.CreateClientContext(), TestCommon.DevSiteUrl, testContainer); // upload file using (var fileStream = System.IO.File.OpenRead(@".\resources\office365.png")) { spConnector.SaveFileStream("blabla.png", fileStream); } // delete the file spConnector.DeleteFile("blabla.png"); // read the file using (var bytes = spConnector.GetFileStream("blabla.png")) { Assert.IsNull(bytes); } // file will be deleted at end of test }
internal void PersistFile(Web web, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, string folderPath, string fileName, Boolean decodeFileName = false) { if (creationInfo.FileConnector != null) { SharePointConnector connector = new SharePointConnector(web.Context, web.Url, "dummy"); if (folderPath.StartsWith( web.ServerRelativeUrl, StringComparison.OrdinalIgnoreCase ) ) { folderPath = folderPath.Substring(web.ServerRelativeUrl.Length); } using (Stream s = connector.GetFileStream(fileName, folderPath)) { if (s != null) { creationInfo.FileConnector.SaveFileStream(decodeFileName ? HttpUtility.UrlDecode(fileName) : fileName, s); } } } else { WriteWarning("No connector present to persist homepage.", ProvisioningMessageType.Error); scope.LogError("No connector present to persist homepage"); } }
public void SharePointConnectorGetFileBytes2Test() { SharePointConnector spConnector = new SharePointConnector(); spConnector.Parameters.Add(AzureStorageConnector.CONNECTIONSTRING, TestCommon.DevSiteUrl); spConnector.Parameters.Add(AzureStorageConnector.CONTAINER, testContainerSecure); spConnector.Parameters.Add(SharePointConnector.CLIENTCONTEXT, TestCommon.CreateClientContext()); using (var bytes = spConnector.GetFileStream("custombg.jpg", String.Format("{0}/sub1", testContainerSecure))) { Assert.IsTrue(bytes.Length > 0); } string file2 = spConnector.GetFile("Idonotexist.xml", String.Format("{0}/sub1", testContainerSecure)); Assert.IsNull(file2); }
public void SharePointConnectorGetFileBytes1Test() { SharePointConnector spConnector = new SharePointConnector(TestCommon.CreateClientContext(), TestCommon.DevSiteUrl, testContainer); using (var bytes = spConnector.GetFileStream("office365.png")) { Assert.IsTrue(bytes.Length > 0); } using (var bytes2 = spConnector.GetFileStream("Idonotexist.xml")) { Assert.IsNull(bytes2); } }
public void SharePointConnectorGetFiles3Test() { SharePointConnector spConnector = new SharePointConnector(TestCommon.CreateClientContext(), TestCommon.DevSiteUrl, testContainerSecure); var files = spConnector.GetFiles(String.Format("{0}/sub1/sub11", testContainerSecure)); Assert.IsTrue(files.Count > 0); }
public void SharePointConnectorGetFiles1Test() { SharePointConnector spConnector = new SharePointConnector(TestCommon.CreateClientContext(), TestCommon.DevSiteUrl, testContainerSecure); var files = spConnector.GetFiles(); Assert.IsTrue(files.Count > 0); }
protected override void ExecuteCmdlet() { SelectedWeb.EnsureProperty(w => w.Url); ProvisioningTemplate provisioningTemplate; FileConnectorBase fileConnector; if (MyInvocation.BoundParameters.ContainsKey("Path")) { bool templateFromFileSystem = !Path.ToLower().StartsWith("http"); string templateFileName = System.IO.Path.GetFileName(Path); if (templateFromFileSystem) { if (!System.IO.Path.IsPathRooted(Path)) { Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); } if (!string.IsNullOrEmpty(ResourceFolder)) { if (!System.IO.Path.IsPathRooted(ResourceFolder)) { ResourceFolder = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, ResourceFolder); } } var fileInfo = new FileInfo(Path); fileConnector = new FileSystemConnector(fileInfo.DirectoryName, ""); } else { Uri fileUri = new Uri(Path); var webUrl = Microsoft.SharePoint.Client.Web.WebUrlFromFolderUrlDirect(ClientContext, fileUri); var templateContext = ClientContext.Clone(webUrl.ToString()); var library = Path.ToLower().Replace(templateContext.Url.ToLower(), "").TrimStart('/'); var idx = library.IndexOf("/", StringComparison.Ordinal); library = library.Substring(0, idx); // This syntax creates a SharePoint connector regardless we have the -InputInstance argument or not fileConnector = new SharePointConnector(templateContext, templateContext.Url, library); } // If we don't have the -InputInstance parameter, we load the template from the source connector Stream stream = fileConnector.GetFileStream(templateFileName); var isOpenOfficeFile = IsOpenOfficeFile(stream); XMLTemplateProvider provider; if (isOpenOfficeFile) { provider = new XMLOpenXMLTemplateProvider(new OpenXMLConnector(templateFileName, fileConnector)); templateFileName = templateFileName.Substring(0, templateFileName.LastIndexOf(".", StringComparison.Ordinal)) + ".xml"; } else { if (templateFromFileSystem) { provider = new XMLFileSystemTemplateProvider(fileConnector.Parameters[FileConnectorBase.CONNECTIONSTRING] + "", ""); } else { throw new NotSupportedException("Only .pnp package files are supported from a SharePoint library"); } } provisioningTemplate = provider.GetTemplate(templateFileName, TemplateProviderExtensions); if (provisioningTemplate == null) { // If we don't have the template, raise an error and exit WriteError(new ErrorRecord(new Exception("The -Path parameter targets an invalid repository or template object."), "WRONG_PATH", ErrorCategory.SyntaxError, null)); return; } if (isOpenOfficeFile) { provisioningTemplate.Connector = provider.Connector; } else { if (ResourceFolder != null) { var fileSystemConnector = new FileSystemConnector(ResourceFolder, ""); provisioningTemplate.Connector = fileSystemConnector; } else { provisioningTemplate.Connector = provider.Connector; } } } else { if (MyInvocation.BoundParameters.ContainsKey("GalleryTemplateId")) { provisioningTemplate = GalleryHelper.GetTemplate(GalleryTemplateId); } else { provisioningTemplate = InputInstance; } if (ResourceFolder != null) { var fileSystemConnector = new FileSystemConnector(ResourceFolder, ""); provisioningTemplate.Connector = fileSystemConnector; } else { if (Path != null) { if (!System.IO.Path.IsPathRooted(Path)) { Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); } } else { Path = SessionState.Path.CurrentFileSystemLocation.Path; } var fileInfo = new FileInfo(Path); fileConnector = new FileSystemConnector(fileInfo.DirectoryName, ""); provisioningTemplate.Connector = fileConnector; } } if (Parameters != null) { foreach (var parameter in Parameters.Keys) { if (provisioningTemplate.Parameters.ContainsKey(parameter.ToString())) { provisioningTemplate.Parameters[parameter.ToString()] = Parameters[parameter].ToString(); } else { provisioningTemplate.Parameters.Add(parameter.ToString(), Parameters[parameter].ToString()); } } } var applyingInformation = new ProvisioningTemplateApplyingInformation(); if (MyInvocation.BoundParameters.ContainsKey("Handlers")) { applyingInformation.HandlersToProcess = Handlers; } if (MyInvocation.BoundParameters.ContainsKey("ExcludeHandlers")) { foreach (var handler in (Handlers[])Enum.GetValues(typeof(Handlers))) { if (!ExcludeHandlers.Has(handler) && handler != Handlers.All) { Handlers = Handlers | handler; } } applyingInformation.HandlersToProcess = Handlers; } if (ExtensibilityHandlers != null) { applyingInformation.ExtensibilityHandlers = ExtensibilityHandlers.ToList(); } applyingInformation.ProgressDelegate = (message, step, total) => { WriteProgress(new ProgressRecord(0, $"Applying template to {SelectedWeb.Url}", message) { PercentComplete = (100 / total) * step }); }; applyingInformation.MessagesDelegate = (message, type) => { if (type == ProvisioningMessageType.Warning) { WriteWarning(message); } }; applyingInformation.OverwriteSystemPropertyBagValues = OverwriteSystemPropertyBagValues; SelectedWeb.ApplyProvisioningTemplate(provisioningTemplate, applyingInformation); WriteProgress(new ProgressRecord(0, $"Applying template to {SelectedWeb.Url}", " ") { RecordType = ProgressRecordType.Completed }); }
protected override void ExecuteCmdlet() { SelectedWeb.EnsureProperty(w => w.Url); bool templateFromFileSystem = !Path.ToLower().StartsWith("http"); FileConnectorBase fileConnector; string templateFileName = System.IO.Path.GetFileName(Path); if (templateFromFileSystem) { if (!System.IO.Path.IsPathRooted(Path)) { Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); } FileInfo fileInfo = new FileInfo(Path); fileConnector = new FileSystemConnector(fileInfo.DirectoryName, ""); } else { Uri fileUri = new Uri(Path); var webUrl = Microsoft.SharePoint.Client.Web.WebUrlFromFolderUrlDirect(ClientContext, fileUri); var templateContext = ClientContext.Clone(webUrl.ToString()); string library = Path.ToLower().Replace(templateContext.Url.ToLower(), "").TrimStart('/'); int idx = library.IndexOf("/"); library = library.Substring(0, idx); fileConnector = new SharePointConnector(templateContext, templateContext.Url, library); } XMLTemplateProvider provider; ProvisioningTemplate provisioningTemplate; Stream stream = fileConnector.GetFileStream(templateFileName); var isOpenOfficeFile = ApplyProvisioningTemplate.IsOpenOfficeFile(stream); if (isOpenOfficeFile) { provider = new XMLOpenXMLTemplateProvider(new OpenXMLConnector(templateFileName, fileConnector)); templateFileName = templateFileName.Substring(0, templateFileName.LastIndexOf(".", StringComparison.Ordinal)) + ".xml"; } else { if (templateFromFileSystem) { provider = new XMLFileSystemTemplateProvider(fileConnector.Parameters[FileConnectorBase.CONNECTIONSTRING] + "", ""); } else { throw new NotSupportedException("Only .pnp package files are supported from a SharePoint library"); } } provisioningTemplate = provider.GetTemplate(templateFileName, TemplateProviderExtensions); if (provisioningTemplate == null) return; GetProvisioningTemplate.SetTemplateMetadata(provisioningTemplate, TemplateDisplayName, TemplateImagePreviewUrl, TemplateProperties); provider.SaveAs(provisioningTemplate, templateFileName, TemplateProviderExtensions); }
public void SharePointConnectorGetFileFromWebRootFolder() { SharePointConnector spConnector = new SharePointConnector(); spConnector.Parameters.Add(SharePointConnector.CONNECTIONSTRING, TestCommon.DevSiteUrl); spConnector.Parameters.Add(SharePointConnector.CLIENTCONTEXT, TestCommon.CreateClientContext()); string file = spConnector.GetFile("TestDefault.aspx"); Assert.IsNotNull(file); }
public override ProvisioningTemplate CreateEntities(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { // Load object if not there bool executeQueryNeeded = false; if (!web.IsObjectPropertyInstantiated("AlternateCssUrl")) { web.Context.Load(web); executeQueryNeeded = true; } if (!web.IsObjectPropertyInstantiated("Url")) { web.Context.Load(web); executeQueryNeeded = true; } if (executeQueryNeeded) { web.Context.ExecuteQuery(); } // Information coming from the site template.ComposedLook.AlternateCSS = Tokenize(web.AlternateCssUrl, web.Url); template.ComposedLook.MasterPage = Tokenize(web.MasterUrl, web.Url); template.ComposedLook.SiteLogo = Tokenize(web.SiteLogoUrl, web.Url); var theme = web.GetCurrentComposedLook(); if (theme != null) { template.ComposedLook.Name = theme.Name; if (theme.IsCustomComposedLook) { if (creationInfo.PersistComposedLookFiles && creationInfo.FileConnector != null) { Site site = (web.Context as ClientContext).Site; if (!site.IsObjectPropertyInstantiated("Url")) { web.Context.Load(site); web.Context.ExecuteQueryRetry(); } // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy"); // to get files from theme catalog we need a connector linked to the root site SharePointConnector spConnectorRoot; if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase)) { spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy"); } else { spConnectorRoot = spConnector; } // Download the theme/branding specific files DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.AlternateCssUrl); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.SiteLogoUrl); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font); } template.ComposedLook.BackgroundFile = Tokenize(theme.BackgroundImage, web.Url); template.ComposedLook.ColorFile = Tokenize(theme.Theme, web.Url); template.ComposedLook.FontFile = Tokenize(theme.Font, web.Url); // Create file entries for the custom theme files if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.SiteLogo)); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } else { template.ComposedLook.BackgroundFile = ""; template.ComposedLook.ColorFile = ""; template.ComposedLook.FontFile = ""; } } else { template.ComposedLook = null; } return template; }
private void DownLoadFile(SharePointConnector reader, SharePointConnector readerRoot, FileConnectorBase writer, string webUrl, string asset) { // No file passed...leave if (String.IsNullOrEmpty(asset)) { return; } SharePointConnector readerToUse; Model.File f = GetComposedLookFile(asset); // Strip the /sites/root part from /sites/root/lib/folder structure Uri u = new Uri(webUrl); if (f.Folder.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1) { f.Folder = f.Folder.Replace(u.PathAndQuery, ""); } // in case of a theme catalog we need to use the root site reader as that list only exists on root site level if (f.Folder.IndexOf("/_catalogs/theme", StringComparison.InvariantCultureIgnoreCase) > -1) { readerToUse = readerRoot; } else { readerToUse = reader; } using (Stream s = readerToUse.GetFileStream(f.Src, f.Folder)) { if (s != null) { // if we've found the file use the provided writer to persist the downloaded file writer.SaveFileStream(f.Src, s); } } }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // Load object if not there #if !CLIENTSDKV15 web.EnsureProperties(w => w.Url, w => w.MasterUrl, w => w.AlternateCssUrl, w => w.SiteLogoUrl); #else web.EnsureProperties(w => w.Url, w => w.MasterUrl); #endif // Information coming from the site template.ComposedLook.MasterPage = Tokenize(web.MasterUrl, web.Url); #if !CLIENTSDKV15 template.ComposedLook.AlternateCSS = Tokenize(web.AlternateCssUrl, web.Url); template.ComposedLook.SiteLogo = Tokenize(web.SiteLogoUrl, web.Url); #else template.ComposedLook.AlternateCSS = null; template.ComposedLook.SiteLogo = null; #endif scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look); Site site = (web.Context as ClientContext).Site; if (!site.IsObjectPropertyInstantiated("Url")) { web.Context.Load(site); web.Context.ExecuteQueryRetry(); } SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy"); // to get files from theme catalog we need a connector linked to the root site SharePointConnector spConnectorRoot; if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase)) { spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy"); } else { spConnectorRoot = spConnector; } // Check if we have composed look info in the property bag, if so, use that, otherwise try to detect the current composed look if (web.PropertyBagContainsKey("_PnP_ProvisioningTemplateComposedLookInfo")) { scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Using_ComposedLookInfoFromPropertyBag); try { var composedLook = JsonConvert.DeserializeObject<ComposedLook>(web.GetPropertyBagValueString("_PnP_ProvisioningTemplateComposedLookInfo", "")); if (composedLook.Name == null || composedLook.BackgroundFile == null || composedLook.FontFile == null || composedLook.MasterPage == null || composedLook.SiteLogo == null) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_ComposedLookInfoFailedToDeserialize); throw new JsonSerializationException(); } template.ComposedLook = composedLook; if (creationInfo != null && creationInfo.PersistComposedLookFiles && creationInfo.FileConnector != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment // Download the theme/branding specific files #if !CLIENTSDKV15 DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.AlternateCssUrl, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.SiteLogoUrl, scope); #endif TokenParser parser = new TokenParser(web, template); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.BackgroundFile), scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.ColorFile), scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.FontFile), scope); } // Create file entries for the custom theme files if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.SiteLogo)); } } catch (JsonSerializationException) { // cannot deserialize the object, fall back to composed look detection template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot); } } else { template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot); } if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
private ProvisioningTemplate DetectComposedLook(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, SharePointConnector spConnector, SharePointConnector spConnectorRoot) { var theme = web.GetCurrentComposedLook(); if (theme != null) { if (creationInfo != null) { // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl"); } template.ComposedLook.Name = theme.Name; if (theme.IsCustomComposedLook) { if (creationInfo != null && creationInfo.PersistComposedLookFiles && creationInfo.FileConnector != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment // Download the theme/branding specific files #if !CLIENTSDKV15 DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.AlternateCssUrl, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.SiteLogoUrl, scope); #endif DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font, scope); } template.ComposedLook.BackgroundFile = FixFileUrl(Tokenize(theme.BackgroundImage, web.Url)); template.ComposedLook.ColorFile = FixFileUrl(Tokenize(theme.Theme, web.Url)); template.ComposedLook.FontFile = FixFileUrl(Tokenize(theme.Font, web.Url)); // Create file entries for the custom theme files if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.SiteLogo)); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } else { template.ComposedLook.BackgroundFile = ""; template.ComposedLook.ColorFile = ""; template.ComposedLook.FontFile = ""; } } else { template.ComposedLook = null; } return template; }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look); // Ensure that we have URL property loaded for web and site web.EnsureProperty(w => w.Url); Site site = (web.Context as ClientContext).Site; site.EnsureProperty(s => s.Url); SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy"); // to get files from theme catalog we need a connector linked to the root site SharePointConnector spConnectorRoot; if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase)) { spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy"); } else { spConnectorRoot = spConnector; } // Check if we have composed look info in the property bag, if so, use that, otherwise try to detect the current composed look if (web.PropertyBagContainsKey("_PnP_ProvisioningTemplateComposedLookInfo")) { scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Using_ComposedLookInfoFromPropertyBag); try { var composedLook = JsonConvert.DeserializeObject<ComposedLook>(web.GetPropertyBagValueString("_PnP_ProvisioningTemplateComposedLookInfo", "")); if (composedLook.Name == null || composedLook.BackgroundFile == null || composedLook.FontFile == null) { scope.LogError(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_ComposedLookInfoFailedToDeserialize); throw new JsonSerializationException(); } composedLook.BackgroundFile = Tokenize(composedLook.BackgroundFile, web.Url); composedLook.FontFile = Tokenize(composedLook.FontFile, web.Url); composedLook.ColorFile = Tokenize(composedLook.ColorFile, web.Url); template.ComposedLook = composedLook; if (!web.IsSubSite() && creationInfo != null && creationInfo.PersistBrandingFiles && creationInfo.FileConnector != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment TokenParser parser = new TokenParser(web, template); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.BackgroundFile), scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.ColorFile), scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, parser.ParseString(composedLook.FontFile), scope); } // Create file entries for the custom theme files if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { var f = GetComposedLookFile(template.ComposedLook.BackgroundFile); f.Folder = Tokenize(f.Folder, web.Url); template.Files.Add(f); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { var f = GetComposedLookFile(template.ComposedLook.ColorFile); f.Folder = Tokenize(f.Folder, web.Url); template.Files.Add(f); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { var f = GetComposedLookFile(template.ComposedLook.FontFile); f.Folder = Tokenize(f.Folder, web.Url); template.Files.Add(f); } } catch (JsonSerializationException) { // cannot deserialize the object, fall back to composed look detection template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot); } } else { template = DetectComposedLook(web, template, creationInfo, scope, spConnector, spConnectorRoot); } if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
private void DownLoadFile(SharePointConnector reader, SharePointConnector readerRoot, FileConnectorBase writer, Web web, string asset, PnPMonitoredScope scope) { // No file passed...leave if (String.IsNullOrEmpty(asset)) { return; } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_DownLoadFile_Downloading_asset___0_, asset); ; SharePointConnector readerToUse; Model.File f = GetComposedLookFile(asset, null); if (f.Folder.StartsWith(web.ServerRelativeUrl, StringComparison.OrdinalIgnoreCase)) { f.Folder = f.Folder.Substring(web.ServerRelativeUrl.Length); } // in case of a theme catalog we need to use the root site reader as that list only exists on root site level if (f.Folder.IndexOf("/_catalogs/theme", StringComparison.InvariantCultureIgnoreCase) > -1) { readerToUse = readerRoot; } else { readerToUse = reader; } using (Stream s = readerToUse.GetFileStream(f.Src, f.Folder)) { if (s != null) { writer.SaveFileStream(f.Src, s); } } }
private ProvisioningTemplate DetectComposedLook(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateCreationInformation creationInfo, PnPMonitoredScope scope, SharePointConnector spConnector, SharePointConnector spConnectorRoot) { var theme = web.GetCurrentComposedLook(); if (theme != null) { if (creationInfo != null) { // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl"); } template.ComposedLook.Name = theme.Name; if (theme.IsCustomComposedLook) { // Set the URL pointers to files template.ComposedLook.BackgroundFile = FixFileUrl(TokenizeUrl(theme.BackgroundImage, parser)); template.ComposedLook.ColorFile = FixFileUrl(TokenizeUrl(theme.Theme, parser)); template.ComposedLook.FontFile = FixFileUrl(TokenizeUrl(theme.Font, parser)); // Download files if this is root site, since theme files are only stored there if (!web.IsSubSite() && creationInfo != null && creationInfo.PersistBrandingFiles && creationInfo.FileConnector != null) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment // Download the theme/branding specific files DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web, theme.BackgroundImage, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web, theme.Theme, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web, theme.Font, scope); } // Create file entries for the custom theme files, but only if it's a root site // If it's root site we do not extract or set theme files, since those are in the root of the site collection if (!web.IsSubSite()) { if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile, template.Connector)); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile, template.Connector)); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile, template.Connector)); } } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } else { template.ComposedLook.BackgroundFile = ""; template.ComposedLook.ColorFile = ""; template.ComposedLook.FontFile = ""; } } else { template.ComposedLook = null; } return template; }
public void SharePointConnectorSaveStream1Test() { SharePointConnector spConnector = new SharePointConnector(TestCommon.CreateClientContext(), TestCommon.DevSiteUrl, testContainer); long byteCount = 0; using (var fileStream = System.IO.File.OpenRead(@".\resources\office365.png")) { byteCount = fileStream.Length; spConnector.SaveFileStream("blabla.png", fileStream); } //read the file using (var bytes = spConnector.GetFileStream("blabla.png")) { Assert.IsTrue(byteCount == bytes.Length); } // file will be deleted at end of test }
public void SharePointConnectorSaveStream3Test() { // first save SharePointConnector spConnector = new SharePointConnector(TestCommon.CreateClientContext(), TestCommon.DevSiteUrl, testContainer); using (var fileStream = System.IO.File.OpenRead(@".\resources\office365.png")) { spConnector.SaveFileStream("blabla.png", String.Format("{0}/sub1/sub11", testContainerSecure), fileStream); } // overwrite file long byteCount = 0; using (var fileStream = System.IO.File.OpenRead(@".\resources\custombg.jpg")) { byteCount = fileStream.Length; spConnector.SaveFileStream("blabla.png", String.Format("{0}/sub1/sub11", testContainerSecure), fileStream); } //read the file using (var bytes = spConnector.GetFileStream("blabla.png", String.Format("{0}/sub1/sub11", testContainerSecure))) { Assert.IsTrue(byteCount == bytes.Length); } // file will be deleted at end of test }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // Load object if not there #if !CLIENTSDKV15 web.EnsureProperties(w => w.Url, w => w.MasterUrl, w => w.AlternateCssUrl, w => w.SiteLogoUrl); #else web.EnsureProperties(w => w.Url, w => w.MasterUrl); #endif // Information coming from the site template.ComposedLook.MasterPage = Tokenize(web.MasterUrl, web.Url); #if !CLIENTSDKV15 template.ComposedLook.AlternateCSS = Tokenize(web.AlternateCssUrl, web.Url); template.ComposedLook.SiteLogo = Tokenize(web.SiteLogoUrl, web.Url); #else template.ComposedLook.AlternateCSS = null; template.ComposedLook.SiteLogo = null; #endif scope.LogInfo(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Retrieving_current_composed_look); var theme = web.GetCurrentComposedLook(); if (theme != null) { if (creationInfo != null) { // Don't exclude the DesignPreviewThemedCssFolderUrl property bag, if any creationInfo.PropertyBagPropertiesToPreserve.Add("DesignPreviewThemedCssFolderUrl"); } template.ComposedLook.Name = theme.Name; if (theme.IsCustomComposedLook) { if (creationInfo != null && creationInfo.PersistComposedLookFiles && creationInfo.FileConnector != null) { Site site = (web.Context as ClientContext).Site; if (!site.IsObjectPropertyInstantiated("Url")) { web.Context.Load(site); web.Context.ExecuteQueryRetry(); } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_ExtractObjects_Creating_SharePointConnector); // Let's create a SharePoint connector since our files anyhow are in SharePoint at this moment SharePointConnector spConnector = new SharePointConnector(web.Context, web.Url, "dummy"); // to get files from theme catalog we need a connector linked to the root site SharePointConnector spConnectorRoot; if (!site.Url.Equals(web.Url, StringComparison.InvariantCultureIgnoreCase)) { spConnectorRoot = new SharePointConnector(web.Context.Clone(site.Url), site.Url, "dummy"); } else { spConnectorRoot = spConnector; } // Download the theme/branding specific files DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.AlternateCssUrl, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, web.SiteLogoUrl, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.BackgroundImage, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Theme, scope); DownLoadFile(spConnector, spConnectorRoot, creationInfo.FileConnector, web.Url, theme.Font, scope); } template.ComposedLook.BackgroundFile = FixFileUrl(Tokenize(theme.BackgroundImage, web.Url)); template.ComposedLook.ColorFile = FixFileUrl(Tokenize(theme.Theme, web.Url)); template.ComposedLook.FontFile = FixFileUrl(Tokenize(theme.Font, web.Url)); // Create file entries for the custom theme files if (!string.IsNullOrEmpty(template.ComposedLook.BackgroundFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.BackgroundFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.ColorFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.ColorFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.FontFile)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.FontFile)); } if (!string.IsNullOrEmpty(template.ComposedLook.SiteLogo)) { template.Files.Add(GetComposedLookFile(template.ComposedLook.SiteLogo)); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } else { template.ComposedLook.BackgroundFile = ""; template.ComposedLook.ColorFile = ""; template.ComposedLook.FontFile = ""; } } else { template.ComposedLook = null; } if (creationInfo != null && creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return template; }
public void SharePointConnectorDeleteFromWebRootFolder() { SharePointConnector spConnector = new SharePointConnector(); spConnector.Parameters.Add(SharePointConnector.CONNECTIONSTRING, TestCommon.DevSiteUrl); spConnector.Parameters.Add(SharePointConnector.CLIENTCONTEXT, TestCommon.CreateClientContext()); // upload file using (var fileStream = System.IO.File.OpenRead(@".\resources\testdefault.aspx")) { spConnector.SaveFileStream("blabla.aspx", string.Empty, fileStream); } // delete the file spConnector.DeleteFile("blabla.aspx"); // read the file using (var bytes = spConnector.GetFileStream("blabla.aspx")) { Assert.IsNull(bytes); } }
public void SharePointConnectorGetFile2Test() { SharePointConnector spConnector = new SharePointConnector(TestCommon.CreateClientContext(), TestCommon.DevSiteUrl, testContainerSecure); string file = spConnector.GetFile("ProvisioningTemplate-2015-03-Sample-01.xml", String.Format("{0}/sub1/sub11", testContainerSecure)); Assert.IsNotNull(file); string file2 = spConnector.GetFile("Idonotexist.xml", String.Format("{0}/sub1/sub11", testContainerSecure)); Assert.IsNull(file2); }
private void DownLoadFile(SharePointConnector reader, SharePointConnector readerRoot, FileConnectorBase writer, string webUrl, string asset, PnPMonitoredScope scope) { // No file passed...leave if (String.IsNullOrEmpty(asset)) { return; } scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ComposedLooks_DownLoadFile_Downloading_asset___0_, asset); ; SharePointConnector readerToUse; Model.File f = GetComposedLookFile(asset); // Strip the /sites/root part from /sites/root/lib/folder structure Uri u = new Uri(webUrl); if (f.Folder.IndexOf(u.PathAndQuery, StringComparison.InvariantCultureIgnoreCase) > -1) { f.Folder = f.Folder.Replace(u.PathAndQuery, ""); } // in case of a theme catalog we need to use the root site reader as that list only exists on root site level if (f.Folder.IndexOf("/_catalogs/theme", StringComparison.InvariantCultureIgnoreCase) > -1) { readerToUse = readerRoot; } else { readerToUse = reader; } using (Stream s = readerToUse.GetFileStream(f.Src, f.Folder)) { if (s != null) { writer.SaveFileStream(f.Src, s); } } }
protected override void ExecuteCmdlet() { SelectedWeb.EnsureProperty(w => w.Url); bool templateFromFileSystem = !Path.ToLower().StartsWith("http"); FileConnectorBase fileConnector; string templateFileName = System.IO.Path.GetFileName(Path); if (templateFromFileSystem) { if (!System.IO.Path.IsPathRooted(Path)) { Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); } if (!string.IsNullOrEmpty(ResourceFolder)) { if (!System.IO.Path.IsPathRooted(ResourceFolder)) { ResourceFolder = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, ResourceFolder); } } FileInfo fileInfo = new FileInfo(Path); fileConnector = new FileSystemConnector(fileInfo.DirectoryName, ""); } else { Uri fileUri = new Uri(Path); var webUrl = Microsoft.SharePoint.Client.Web.WebUrlFromFolderUrlDirect(this.ClientContext, fileUri); var templateContext = this.ClientContext.Clone(webUrl.ToString()); string library = Path.ToLower().Replace(templateContext.Url.ToLower(), "").TrimStart('/'); int idx = library.IndexOf("/"); library = library.Substring(0, idx); fileConnector = new SharePointConnector(templateContext, templateContext.Url, library); } XMLTemplateProvider provider = null; ProvisioningTemplate provisioningTemplate = null; Stream stream = fileConnector.GetFileStream(templateFileName); var isOpenOfficeFile = IsOpenOfficeFile(stream); if (isOpenOfficeFile) { provider = new XMLOpenXMLTemplateProvider(new OpenXMLConnector(templateFileName, fileConnector)); templateFileName = templateFileName.Substring(0, templateFileName.LastIndexOf(".")) + ".xml"; } else { if (templateFromFileSystem) { provider = new XMLFileSystemTemplateProvider(fileConnector.Parameters[FileConnectorBase.CONNECTIONSTRING] + "", ""); } else { throw new NotSupportedException("Only .pnp package files are supported from a SharePoint library"); } } provisioningTemplate = provider.GetTemplate(templateFileName, TemplateProviderExtensions); if (provisioningTemplate == null) return; if (isOpenOfficeFile) { provisioningTemplate.Connector = provider.Connector; } else { if (ResourceFolder != null) { var fileSystemConnector = new FileSystemConnector(ResourceFolder, ""); provisioningTemplate.Connector = fileSystemConnector; } else { provisioningTemplate.Connector = provider.Connector; } } if (Parameters != null) { foreach (var parameter in Parameters.Keys) { if (provisioningTemplate.Parameters.ContainsKey(parameter.ToString())) { provisioningTemplate.Parameters[parameter.ToString()] = Parameters[parameter].ToString(); } else { provisioningTemplate.Parameters.Add(parameter.ToString(), Parameters[parameter].ToString()); } } } var applyingInformation = new ProvisioningTemplateApplyingInformation(); if (this.MyInvocation.BoundParameters.ContainsKey("Handlers")) { applyingInformation.HandlersToProcess = Handlers; } if (this.MyInvocation.BoundParameters.ContainsKey("ExcludeHandlers")) { foreach (var handler in (OfficeDevPnP.Core.Framework.Provisioning.Model.Handlers[])Enum.GetValues(typeof(Handlers))) { if (!ExcludeHandlers.Has(handler) && handler != Handlers.All) { Handlers = Handlers | handler; } } applyingInformation.HandlersToProcess = Handlers; } if (ExtensibilityHandlers != null) { applyingInformation.ExtensibilityHandlers = ExtensibilityHandlers.ToList<ExtensibilityHandler>(); } applyingInformation.ProgressDelegate = (message, step, total) => { WriteProgress(new ProgressRecord(0, string.Format("Applying template to {0}", SelectedWeb.Url), message) { PercentComplete = (100 / total) * step }); }; applyingInformation.MessagesDelegate = (message, type) => { if (type == ProvisioningMessageType.Warning) { WriteWarning(message); } }; applyingInformation.OverwriteSystemPropertyBagValues = OverwriteSystemPropertyBagValues; SelectedWeb.ApplyProvisioningTemplate(provisioningTemplate, applyingInformation); }