public void DeleteGlobalResources(AppManifestBase manifest) { var globalResources = string.Empty; globalResources = MapGlobalResources(manifest, globalResources); DeleteGlobalResourcesCustomAction(manifest.ManifestName, globalResources); }
private byte[] GetFileFromStorage(AppManifestBase manifest, FileCreator fileCreator) { byte[] file; if (manifest.StorageType == StorageTypes.FileSystem) { file = Utility.GetFile(fileCreator.RelativeFilePath, fileCreator.IsBinary, manifest.BaseFilePath); } else { var pfc = fileCreator as ProvisioningFileCreator; if (pfc == null) { var storageInfo = manifest.GetAzureStorageInfo(); var blobStorage = new BlobStorage(storageInfo.Account, storageInfo.AccountKey, storageInfo.Container); file = blobStorage.DownloadToByteArray(fileCreator.Url); } else { var storageInfo = pfc.GetAzureStorageInfo(); var blobStorage = new BlobStorage(storageInfo.Account, storageInfo.AccountKey, storageInfo.Container); file = blobStorage.DownloadToByteArray(fileCreator.Url); } } return(file); }
public void ProvisionAll(ClientContext ctx, Web web, AppManifestBase manifest) { try { Folders = manifest.Folders; CreateFolders(ctx, web); Creators = manifest.FileCreators; switch (manifest.StorageType) { case StorageTypes.AzureStorage: case StorageTypes.FileSystem: ProvisionFromStorage(ctx, web, manifest); break; case StorageTypes.Assembly: default: throw new InvalidOperationException("Storage type is invalid."); } } catch (Exception ex) { Trace.TraceError("Error creating files " + web.Url + " | " + "manifest=" + manifest.ManifestName + " | " + ex); throw; } }
public static AppManifestBase GetManifestFromAzureStorage(string storageAccount, string accountKey, string container, string manifestName = "manifest.json") { //Get or create the container var blobStorage = new BlobStorage(storageAccount, accountKey, container); var manifestJson = string.Empty; //Load or create a new manifest AppManifestBase appManifest; try { manifestJson = blobStorage.DownloadText(manifestName); } catch { // ignored } if (string.IsNullOrEmpty(manifestJson)) { appManifest = new AppManifestBase(); } else { var js = new JavaScriptSerializer(); appManifest = (AppManifestBase)js.Deserialize(manifestJson, typeof(AppManifestBase)); } //Set the storage info appManifest.SetAzureStorageInfo(storageAccount, accountKey, container); return(appManifest); }
public void Provision(AppManifestBase manifest, int sequence) { _sequence = sequence; var hasResources = true; var hasCustomListForms = false; if ((manifest.ClientGlobalRuntimeResources == null || manifest.ClientGlobalRuntimeResources.Count == 0) && (manifest.ClientPageRuntimeResources == null || manifest.ClientPageRuntimeResources.Count == 0)) { hasResources = false; } if (manifest.ContentTypeCreators != null && manifest.ContentTypeCreators.Count > 0) { foreach (var creator in manifest.ContentTypeCreators.Values) { if (!String.IsNullOrEmpty(creator.DisplayFormUrl) || !String.IsNullOrEmpty(creator.EditFormUrl) || !String.IsNullOrEmpty(creator.NewFormUrl)) { hasCustomListForms = true; break; } } } if (!hasResources && !hasCustomListForms) { OnNotify(ProvisioningNotificationLevels.Verbose, "No resources or custom list forms found. Skipping."); return; } var globalResources = string.Empty; var pageResources = string.Empty; var contentTypeActions = string.Empty; globalResources = MapGlobalResources(manifest, globalResources); pageResources = MapPageResources(manifest, pageResources); contentTypeActions = MapContentTypeActions(manifest, contentTypeActions); if (pageResources != string.Empty || contentTypeActions != string.Empty) { var settingsUrl = "/_catalogs/IQApps/scripts/" + manifest.ManifestName + "/settings.js"; var appSettingsJs = string.Format(_appSettingsJsWrapper, pageResources, contentTypeActions); var appSettings = string.Format(_globalScript, settingsUrl, "true", "false"); globalResources = appSettings + globalResources; CreateSettingsJs(settingsUrl, manifest.ManifestName, appSettingsJs); } if (globalResources != string.Empty) { CreateGlobalResourcesCustomAction(manifest.ManifestName, globalResources); } }
public void ProvisionLookAndFeel(AppManifestBase manifest, ClientContext ctx, Web web) { if (manifest.LookAndFeel == null) { return; } ValuesToApply valuesToApply = GetValuesToApply(manifest.LookAndFeel, web); //Update the current composed look if there is one UpdateCurrentComposedLook(valuesToApply, ctx, web); //Then override the current look based on what the branding properties are actually set to, if needed ApplyBranding(valuesToApply, ctx, web); }
private string MapPageResources(AppManifestBase manifest, string pageResources) { if (manifest.ClientPageRuntimeResources != null && manifest.ClientPageRuntimeResources.Count > 0) { foreach (var resource in manifest.ClientPageRuntimeResources) { var scripts = string.Empty; var styles = string.Empty; if (resource.Value.Scripts != null) { foreach (var pageScript in resource.Value.Scripts) { //_pageScript = "{{url:{0}, wait:{1} }}" var script = string.Format(_pageScript, pageScript.PrependWebServerRelativeUrl ? "settings.serverRelativeUrl + '" + pageScript.Url + "'" : "'" + pageScript.Url + "'", pageScript.Wait.ToString().ToLower()); if (scripts == string.Empty) { scripts = script; } else { scripts += "," + script; } } } if (resource.Value.StyleSheets != null) { foreach (var pageStyle in resource.Value.StyleSheets) { var style = (pageStyle.PrependWebServerRelativeUrl ? "settings.serverRelativeUrl + '" + pageStyle.Url + "'" : "'" + pageStyle.Url + "'"); if (styles == string.Empty) { styles = style; } else { styles += "," + style; } } } //private string _pageResource = "pages[\"{0}\"] = {{ scripts: [ {1} ], styles: [ {2} ] }}"; var pageResource = string.Format(_pageResource, resource.Key, scripts, styles); pageResources += pageResource; OnNotify(ProvisioningNotificationLevels.Verbose, "Mapped resource: " + resource.Key); } } return(pageResources); }
public static void SaveManifestToAzureStorage(AppManifestBase appManifest) { var azureStorageInfo = appManifest.GetAzureStorageInfo(); if (azureStorageInfo == null) { return; } var blobStorage = new BlobStorage(azureStorageInfo.Account, azureStorageInfo.AccountKey, azureStorageInfo.Container); var js = new JavaScriptSerializer(); var json = js.Serialize(appManifest); blobStorage.UploadText(json, "manifest.json"); }
public static void SaveManifestToFileSystem(AppManifestBase appManifest) { if (string.IsNullOrEmpty(appManifest.BaseFilePath)) { return; } if (!appManifest.BaseFilePath.EndsWith(@"\")) { appManifest.BaseFilePath += @"\"; } var js = new JavaScriptSerializer(); var json = js.Serialize(appManifest); File.WriteAllText(appManifest.BaseFilePath + "manifest.json", json, new System.Text.UTF8Encoding()); }
private string MapGlobalResources(AppManifestBase manifest, string globalResources) { if (manifest.ClientGlobalRuntimeResources != null && manifest.ClientGlobalRuntimeResources.Count > 0) { foreach (var resource in manifest.ClientGlobalRuntimeResources) { if (resource.Value.ResourceType == ResourceTypes.Script) { globalResources += string.Format(_globalScript, resource.Value.Url, resource.Value.Wait.ToString().ToLower(), (!resource.Value.PrependWebServerRelativeUrl).ToString().ToLower()); } else { globalResources += string.Format(_globalStyle, resource.Value.Url, (!resource.Value.PrependWebServerRelativeUrl).ToString().ToLower()); } OnNotify(ProvisioningNotificationLevels.Verbose, "Mapped resource: " + resource.Key); } } return(globalResources); }
public static void SaveManifestToAzureStorage(AppManifestBase appManifest, string fileName = "manifest.json") { var azureStorageInfo = appManifest.GetAzureStorageInfo(); if (azureStorageInfo == null) { return; } if (string.IsNullOrEmpty(fileName)) { fileName = "manifest.json"; } var blobStorage = new BlobStorage(azureStorageInfo.Account, azureStorageInfo.AccountKey, azureStorageInfo.Container); var js = new JavaScriptSerializer(); var json = js.Serialize(appManifest); blobStorage.UploadText(json, fileName); }
private string MapContentTypeActions(AppManifestBase manifest, string contentTypeActions) { if (manifest.ContentTypeCreators != null) { foreach (var creator in manifest.ContentTypeCreators) { if (!String.IsNullOrEmpty(creator.Value.DisplayFormUrl) || !String.IsNullOrEmpty(creator.Value.EditFormUrl) || !String.IsNullOrEmpty(creator.Value.NewFormUrl) || !String.IsNullOrEmpty(creator.Value.BaseViewUrl)) { var creatorValue = creator.Value; var mapping = "settings.contentTypeActions['" + creator.Key + "']={"; //TODO: Fix naming differences if (!String.IsNullOrEmpty(creatorValue.DisplayFormUrl)) { string properties; if (creatorValue.DisplayFormIsDialog) { properties = "url: settings.serverRelativeUrl + '" + creatorValue.DisplayFormUrl + "',"; properties += "isDialog: true," + (!string.IsNullOrEmpty(creatorValue.DisplayFormDialogTitle) ? "title: '" + creatorValue.DisplayFormDialogTitle + "'," : string.Empty) + (creatorValue.DisplayFormDialogHeight != null ? "height: " + creatorValue.DisplayFormDialogHeight + "," : string.Empty) + (creatorValue.DisplayFormDialogWidth != null ? "width: " + creatorValue.DisplayFormDialogWidth + "," : string.Empty); } else { properties = "url: settings.serverRelativeUrl + '" + creatorValue.DisplayFormUrl + "'"; } mapping = AddToMapping(mapping, "DisplayUrl:{" + properties + "}"); } if (!String.IsNullOrEmpty(creatorValue.EditFormUrl)) { string properties; if (creatorValue.EditFormIsDialog) { properties = "url: settings.serverRelativeUrl + '" + creatorValue.EditFormUrl + "',"; properties += "isDialog: true," + (!string.IsNullOrEmpty(creatorValue.EditFormDialogTitle) ? "title: '" + creatorValue.EditFormDialogTitle + "'," : string.Empty) + (creatorValue.EditFormDialogHeight != null ? "height: " + creatorValue.EditFormDialogHeight + "," : string.Empty) + (creatorValue.EditFormDialogWidth != null ? "width: " + creatorValue.EditFormDialogWidth + "," : string.Empty); } else { properties = "url: settings.serverRelativeUrl + '" + creatorValue.EditFormUrl + "'"; } mapping = AddToMapping(mapping, "EditUrl:{" + properties + "}"); } if (!String.IsNullOrEmpty(creatorValue.BaseViewUrl)) { mapping = AddToMapping(mapping, "BaseViewUrl: settings.serverRelativeUrl + '" + creatorValue.BaseViewUrl + "'"); } if (!String.IsNullOrEmpty(creatorValue.NewFormUrl)) { string properties; if (creatorValue.NewFormIsDialog) { properties = "url: settings.serverRelativeUrl + '" + creatorValue.NewFormUrl + "',"; properties += "isDialog: true," + (!string.IsNullOrEmpty(creatorValue.NewFormDialogTitle) ? "title: '" + creatorValue.NewFormDialogTitle + "'," : string.Empty) + (creatorValue.NewFormDialogHeight != null ? "height: " + creatorValue.NewFormDialogHeight + "," : string.Empty) + (creatorValue.NewFormDialogWidth != null ? "width: " + creatorValue.NewFormDialogWidth + "," : string.Empty); } else { properties = "url: settings.serverRelativeUrl + '" + creatorValue.NewFormUrl + "'"; } mapping = AddToMapping(mapping, "NewUrl:{" + properties + "}"); } mapping += "}"; if (contentTypeActions == string.Empty) { contentTypeActions = mapping; } else { contentTypeActions += "," + mapping; } OnNotify(ProvisioningNotificationLevels.Verbose, "Mapped custom UI for content type: " + creator.Key); } } } return(contentTypeActions); }
private void ProvisionFromStorage(ClientContext ctx, Web web, AppManifestBase manifest) { List wikiPagesLibrary = null; List publishingPagesLibrary = null; if (Creators != null && Creators.Count > 0) { foreach (var fileCreator in Creators.Values) { try { if (!FileExists(fileCreator, ctx, web, fileCreator.ForceOverwrite)) { if ((fileCreator.ContentType != null && fileCreator.ContentType == "Wiki Page") || (fileCreator.ContentTypeId != null && fileCreator.ContentTypeId.StartsWith(WikiPageContentTypeId))) { OnNotify(ProvisioningNotificationLevels.Verbose, "Creating wiki page " + fileCreator.Url); if (wikiPagesLibrary == null) { wikiPagesLibrary = web.Lists.GetByTitle(fileCreator.List); ctx.Load(wikiPagesLibrary.RootFolder, f => f.ServerRelativeUrl); ctx.ExecuteQueryRetry(); } var fileUrl = fileCreator.Url; if (web.ServerRelativeUrl != "/") { fileUrl = web.ServerRelativeUrl + fileUrl; } fileCreator.File = wikiPagesLibrary.RootFolder.Files.AddTemplateFile(fileUrl, TemplateFileType.WikiPage); ctx.Load(fileCreator.File, f => f.ServerRelativeUrl); ctx.ExecuteQueryRetry(); fileCreator.AddWikiOrPublishingPageWebParts(ctx, web, WikiPageContentFieldName); fileCreator.Created = true; } else if (fileCreator.ContentTypeId != null && fileCreator.ContentTypeId.StartsWith(PublishingPageContentTypeId)) { OnNotify(ProvisioningNotificationLevels.Verbose, "Creating publishing page " + fileCreator.Url); if (publishingPagesLibrary == null) { publishingPagesLibrary = web.Lists.GetByTitle(fileCreator.List); ctx.Load(publishingPagesLibrary.RootFolder, f => f.ServerRelativeUrl); ctx.ExecuteQueryRetry(); } var fileUrl = fileCreator.Url; if (web.ServerRelativeUrl != "/") { fileUrl = web.ServerRelativeUrl + fileUrl; } var pageName = fileCreator.ListItemFieldValues.Find(p => p.FieldName == "FileLeafRef")?.Value; var pageLayout = fileCreator.ListItemFieldValues.Find(p => p.FieldName == "PublishingPageLayout")?.Value; if (string.IsNullOrEmpty(pageName) || string.IsNullOrEmpty(pageLayout) || !pageLayout.Contains(", ")) { OnNotify(ProvisioningNotificationLevels.Verbose, $"Invalid publishing page data for {fileCreator.Url}! Skipping"); } else { try { pageLayout = pageLayout.Split(',')[0].Replace("{@WebUrl}", web.ServerRelativeUrl); var pageLayoutListItem = web.GetFileByServerRelativeUrl(pageLayout).ListItemAllFields; ctx.Load(pageLayoutListItem); PublishingPageInformation publishingPageInfo = new PublishingPageInformation() { Name = pageName, Folder = publishingPagesLibrary.RootFolder, PageLayoutListItem = pageLayoutListItem }; PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(ctx, web); fileCreator.File = publishingWeb.AddPublishingPage(publishingPageInfo).ListItem.File; ctx.Load(fileCreator.File, f => f.ServerRelativeUrl); ctx.ExecuteQueryRetry(); fileCreator.AddWikiOrPublishingPageWebParts(ctx, web, PublishingPageContentFieldName); fileCreator.Created = true; } catch { OnNotify(ProvisioningNotificationLevels.Verbose, $"Invalid publishing page data for {fileCreator.Url}! Unable to find page layout at {pageLayout}. If the page layout is in the manifest, ensure that it appears before the pages that depend on it. Skipping"); } } } else if ((fileCreator.ContentType != null && fileCreator.ContentType == "Web Part Page") || (fileCreator.ContentTypeId != null && fileCreator.ContentTypeId.StartsWith(BasicPageContentTypeId))) { OnNotify(ProvisioningNotificationLevels.Verbose, "Creating web part page " + fileCreator.Url); var file = GetFileFromStorage(manifest, fileCreator); file = fileCreator.PrepareFile(file, ctx, web, true); fileCreator.File = UploadFile(ctx, web, fileCreator.List, file, fileCreator.Url); ctx.Load(fileCreator.File, f => f.ServerRelativeUrl); ctx.ExecuteQueryRetry(); fileCreator.AddWebPartPageWebParts(ctx, web); fileCreator.Created = true; } else { OnNotify(ProvisioningNotificationLevels.Verbose, "Creating file " + fileCreator.Url); var file = GetFileFromStorage(manifest, fileCreator); if (!fileCreator.IsBinary) { file = fileCreator.PrepareFile(file, ctx, web, fileCreator.ContentType != null && fileCreator.ContentType == "Workflow"); } fileCreator.File = UploadFile(ctx, web, fileCreator.List, file, fileCreator.Url); ctx.Load(fileCreator.File, f => f.ServerRelativeUrl); fileCreator.Created = true; } } } catch (Exception ex) { OnNotify(ProvisioningNotificationLevels.Normal, "Error creating file " + fileCreator.RelativeFilePath + " | " + ex); Trace.TraceError("Error creating file " + fileCreator.RelativeFilePath + " | " + ex); throw; } } if (!ctx.Web.IsPropertyAvailable("AppInstanceId")) { ctx.Load(ctx.Web, w => w.AppInstanceId); ctx.ExecuteQueryRetry(); } if (ctx.Web.AppInstanceId == default(Guid)) { ApplySecurity(ctx); } foreach (var key in Creators.Keys) { OnNotify(ProvisioningNotificationLevels.Verbose, "Setting properties for " + Creators[key].Url); Creators[key].SetProperties(ctx, web); } ctx.ExecuteQueryRetry(); } }