Added backup/restore functionality.
This commit is contained in:
parent
5d7e8c3c4a
commit
74981f98aa
11 changed files with 860 additions and 5 deletions
|
@ -16,5 +16,5 @@ using System.Reflection;
|
|||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("3.0.5.613")]
|
||||
[assembly: AssemblyFileVersion("3.0.5.613")]
|
||||
[assembly: AssemblyVersion("3.0.5.614")]
|
||||
[assembly: AssemblyFileVersion("3.0.5.614")]
|
673
BackupRestore/BackupRestore.cs
Normal file
673
BackupRestore/BackupRestore.cs
Normal file
|
@ -0,0 +1,673 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ScrewTurn.Wiki.PluginFramework;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Collections;
|
||||
using ScrewTurn.Wiki.AclEngine;
|
||||
using Ionic.Zip;
|
||||
using System.IO;
|
||||
|
||||
namespace ScrewTurn.Wiki.BackupRestore {
|
||||
|
||||
/// <summary>
|
||||
/// Implements a Backup and Restore procedure for settings storage providers.
|
||||
/// </summary>
|
||||
public static class BackupRestore {
|
||||
|
||||
private const string BACKUP_RESTORE_UTILITY_VERSION = "1.0";
|
||||
|
||||
private static VersionFile generateVersionFile(string backupName) {
|
||||
return new VersionFile() {
|
||||
BackupRestoreVersion = BACKUP_RESTORE_UTILITY_VERSION,
|
||||
WikiVersion = typeof(BackupRestore).Assembly.GetName().Version.ToString(),
|
||||
BackupName = backupName
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backups all the providers (excluded global settings storage provider).
|
||||
/// </summary>
|
||||
/// <param name="backupZipFileName">The name of the zip file where to store the backup file.</param>
|
||||
/// <param name="plugins">The available plugins.</param>
|
||||
/// <param name="settingsStorageProvider">The settings storage provider.</param>
|
||||
/// <param name="pagesStorageProviders">The pages storage providers.</param>
|
||||
/// <param name="usersStorageProviders">The users storage providers.</param>
|
||||
/// <param name="filesStorageProviders">The files storage providers.</param>
|
||||
/// <returns><c>true</c> if the backup has been succesfull.</returns>
|
||||
public static bool BackupAll(string backupZipFileName, string[] plugins, ISettingsStorageProviderV30 settingsStorageProvider, IPagesStorageProviderV30[] pagesStorageProviders, IUsersStorageProviderV30[] usersStorageProviders, IFilesStorageProviderV30[] filesStorageProviders) {
|
||||
string tempPath = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempPath);
|
||||
|
||||
using(ZipFile backupZipFile = new ZipFile(backupZipFileName)) {
|
||||
|
||||
// Find all namespaces
|
||||
List<string> namespaces = new List<string>();
|
||||
foreach(IPagesStorageProviderV30 pagesStorageProvider in pagesStorageProviders) {
|
||||
foreach(NamespaceInfo ns in pagesStorageProvider.GetNamespaces()) {
|
||||
namespaces.Add(ns.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// Backup settings storage provider
|
||||
string zipSettingsBackup = Path.Combine(tempPath, "SettingsBackup-" + settingsStorageProvider.GetType().FullName + ".zip");
|
||||
BackupSettingsStorageProvider(zipSettingsBackup, settingsStorageProvider, namespaces.ToArray(), plugins);
|
||||
backupZipFile.AddFile(zipSettingsBackup, "");
|
||||
|
||||
// Backup pages storage providers
|
||||
foreach(IPagesStorageProviderV30 pagesStorageProvider in pagesStorageProviders) {
|
||||
string zipPagesBackup = Path.Combine(tempPath, "PagesBackup-" + pagesStorageProvider.GetType().FullName + ".zip");
|
||||
BackupPagesStorageProvider(zipPagesBackup, pagesStorageProvider);
|
||||
backupZipFile.AddFile(zipPagesBackup, "");
|
||||
}
|
||||
|
||||
// Backup users storage providers
|
||||
foreach(IUsersStorageProviderV30 usersStorageProvider in usersStorageProviders) {
|
||||
string zipUsersProvidersBackup = Path.Combine(tempPath, "UsersBackup-" + usersStorageProvider.GetType().FullName + ".zip");
|
||||
BackupUsersStorageProvider(zipUsersProvidersBackup, usersStorageProvider);
|
||||
backupZipFile.AddFile(zipUsersProvidersBackup, "");
|
||||
}
|
||||
|
||||
// Backup files storage providers
|
||||
foreach(IFilesStorageProviderV30 filesStorageProvider in filesStorageProviders) {
|
||||
string zipFilesProviderBackup = Path.Combine(tempPath, "FilesBackup-" + filesStorageProvider.GetType().FullName + ".zip");
|
||||
BackupFilesStorageProvider(zipFilesProviderBackup, filesStorageProvider, pagesStorageProviders);
|
||||
backupZipFile.AddFile(zipFilesProviderBackup, "");
|
||||
}
|
||||
backupZipFile.Save();
|
||||
}
|
||||
|
||||
Directory.Delete(tempPath, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backups the specified settings provider.
|
||||
/// </summary>
|
||||
/// <param name="zipFileName">The zip file name where to store the backup.</param>
|
||||
/// <param name="settingsStorageProvider">The source settings provider.</param>
|
||||
/// <param name="knownNamespaces">The currently known page namespaces.</param>
|
||||
/// <param name="knownPlugins">The currently known plugins.</param>
|
||||
/// <returns><c>true</c> if the backup file has been succesfully created.</returns>
|
||||
public static bool BackupSettingsStorageProvider(string zipFileName, ISettingsStorageProviderV30 settingsStorageProvider, string[] knownNamespaces, string[] knownPlugins) {
|
||||
SettingsBackup settingsBackup = new SettingsBackup();
|
||||
|
||||
// Settings
|
||||
settingsBackup.Settings = (Dictionary<string, string>)settingsStorageProvider.GetAllSettings();
|
||||
|
||||
// Plugins Status and Configuration
|
||||
Dictionary<string, bool> pluginsStatus = new Dictionary<string, bool>();
|
||||
Dictionary<string, string> pluginsConfiguration = new Dictionary<string, string>();
|
||||
foreach(string plugin in knownPlugins) {
|
||||
pluginsStatus[plugin] = settingsStorageProvider.GetPluginStatus(plugin);
|
||||
pluginsConfiguration[plugin] = settingsStorageProvider.GetPluginConfiguration(plugin);
|
||||
}
|
||||
settingsBackup.PluginsStatus = pluginsStatus;
|
||||
settingsBackup.PluginsConfiguration = pluginsConfiguration;
|
||||
|
||||
// Metadata
|
||||
List<MetaData> metadataList = new List<MetaData>();
|
||||
// Meta-data (global)
|
||||
metadataList.Add(new MetaData() {
|
||||
Item = MetaDataItem.AccountActivationMessage,
|
||||
Tag = null,
|
||||
Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.AccountActivationMessage, null)
|
||||
});
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.PasswordResetProcedureMessage, Tag = null, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.PasswordResetProcedureMessage, null) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.LoginNotice, Tag = null, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.LoginNotice, null) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.PageChangeMessage, Tag = null, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.PageChangeMessage, null) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.DiscussionChangeMessage, Tag = null, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.DiscussionChangeMessage, null) });
|
||||
// Meta-data (ns-specific)
|
||||
List<string> namespacesToProcess = new List<string>();
|
||||
namespacesToProcess.Add("");
|
||||
namespacesToProcess.AddRange(knownNamespaces);
|
||||
foreach(string nspace in namespacesToProcess) {
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.EditNotice, Tag = nspace, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.EditNotice, nspace) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.Footer, Tag = nspace, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.Footer, nspace) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.Header, Tag = nspace, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.Header, nspace) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.HtmlHead, Tag = nspace, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.HtmlHead, nspace) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.PageFooter, Tag = nspace, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.PageFooter, nspace) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.PageHeader, Tag = nspace, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.PageHeader, nspace) });
|
||||
metadataList.Add(new MetaData() { Item = MetaDataItem.Sidebar, Tag = nspace, Content = settingsStorageProvider.GetMetaDataItem(MetaDataItem.Sidebar, nspace) });
|
||||
}
|
||||
settingsBackup.Metadata = metadataList;
|
||||
|
||||
// RecentChanges
|
||||
settingsBackup.RecentChanges = settingsStorageProvider.GetRecentChanges().ToList();
|
||||
|
||||
// OutgoingLinks
|
||||
settingsBackup.OutgoingLinks = (Dictionary<string, string[]>)settingsStorageProvider.GetAllOutgoingLinks();
|
||||
|
||||
// ACLEntries
|
||||
AclEntry[] aclEntries = settingsStorageProvider.AclManager.RetrieveAllEntries();
|
||||
settingsBackup.AclEntries = new List<AclEntryBackup>(aclEntries.Length);
|
||||
foreach(AclEntry aclEntry in aclEntries) {
|
||||
settingsBackup.AclEntries.Add(new AclEntryBackup() {
|
||||
Action = aclEntry.Action,
|
||||
Resource = aclEntry.Resource,
|
||||
Subject = aclEntry.Subject,
|
||||
Value = aclEntry.Value
|
||||
});
|
||||
}
|
||||
|
||||
JavaScriptSerializer javascriptSerializer = new JavaScriptSerializer();
|
||||
javascriptSerializer.MaxJsonLength = javascriptSerializer.MaxJsonLength * 10;
|
||||
|
||||
string tempDir = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
FileStream tempFile = File.Create(Path.Combine(tempDir, "Settings.json"));
|
||||
byte[] buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(settingsBackup));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
|
||||
tempFile = File.Create(Path.Combine(tempDir, "Version.json"));
|
||||
buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(generateVersionFile("Settings")));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
|
||||
List<string> plugins = settingsStorageProvider.ListPluginAssemblies().ToList();
|
||||
foreach(string pluginFileName in plugins) {
|
||||
tempFile = File.Create(Path.Combine(tempDir, pluginFileName));
|
||||
buffer = settingsStorageProvider.RetrievePluginAssembly(pluginFileName);
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
}
|
||||
|
||||
using(ZipFile zipFile = new ZipFile()) {
|
||||
zipFile.AddDirectory(tempDir, "");
|
||||
zipFile.Save(zipFileName);
|
||||
}
|
||||
Directory.Delete(tempDir, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backups the pages storage provider.
|
||||
/// </summary>
|
||||
/// <param name="zipFileName">The zip file name where to store the backup.</param>
|
||||
/// <param name="pagesStorageProvider">The pages storage provider.</param>
|
||||
/// <returns><c>true</c> if the backup file has been succesfully created.</returns>
|
||||
public static bool BackupPagesStorageProvider(string zipFileName, IPagesStorageProviderV30 pagesStorageProvider) {
|
||||
JavaScriptSerializer javascriptSerializer = new JavaScriptSerializer();
|
||||
javascriptSerializer.MaxJsonLength = javascriptSerializer.MaxJsonLength * 10;
|
||||
|
||||
string tempDir = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
List<NamespaceInfo> nspaces = new List<NamespaceInfo>(pagesStorageProvider.GetNamespaces());
|
||||
nspaces.Add(null);
|
||||
List<NamespaceBackup> namespaceBackupList = new List<NamespaceBackup>(nspaces.Count);
|
||||
foreach(NamespaceInfo nspace in nspaces) {
|
||||
|
||||
// Backup categories
|
||||
CategoryInfo[] categories = pagesStorageProvider.GetCategories(nspace);
|
||||
List<CategoryBackup> categoriesBackup = new List<CategoryBackup>(categories.Length);
|
||||
foreach(CategoryInfo category in categories) {
|
||||
// Add this category to the categoriesBackup list
|
||||
categoriesBackup.Add(new CategoryBackup() {
|
||||
FullName = category.FullName,
|
||||
Pages = category.Pages
|
||||
});
|
||||
}
|
||||
|
||||
// Backup NavigationPaths
|
||||
NavigationPath[] navigationPaths = pagesStorageProvider.GetNavigationPaths(nspace);
|
||||
List<NavigationPathBackup> navigationPathsBackup = new List<NavigationPathBackup>(navigationPaths.Length);
|
||||
foreach(NavigationPath navigationPath in navigationPaths) {
|
||||
navigationPathsBackup.Add(new NavigationPathBackup() {
|
||||
FullName = navigationPath.FullName,
|
||||
Pages = navigationPath.Pages
|
||||
});
|
||||
}
|
||||
|
||||
// Add this namespace to the namespaceBackup list
|
||||
namespaceBackupList.Add(new NamespaceBackup() {
|
||||
Name = nspace == null ? "" : nspace.Name,
|
||||
DefaultPageFullName = nspace == null ? "" : nspace.DefaultPage.FullName,
|
||||
Categories = categoriesBackup,
|
||||
NavigationPaths = navigationPathsBackup
|
||||
});
|
||||
|
||||
// Backup pages (one json file for each page containing a maximum of 100 revisions)
|
||||
PageInfo[] pages = pagesStorageProvider.GetPages(nspace);
|
||||
foreach(PageInfo page in pages) {
|
||||
PageContent pageContent = pagesStorageProvider.GetContent(page);
|
||||
PageBackup pageBackup = new PageBackup();
|
||||
pageBackup.FullName = page.FullName;
|
||||
pageBackup.CreationDateTime = page.CreationDateTime;
|
||||
pageBackup.LastModified = pageContent.LastModified;
|
||||
pageBackup.Content = pageContent.Content;
|
||||
pageBackup.Comment = pageContent.Comment;
|
||||
pageBackup.Description = pageContent.Description;
|
||||
pageBackup.Keywords = pageContent.Keywords;
|
||||
pageBackup.Title = pageContent.Title;
|
||||
pageBackup.User = pageContent.User;
|
||||
pageBackup.LinkedPages = pageContent.LinkedPages;
|
||||
pageBackup.Categories = (from c in pagesStorageProvider.GetCategoriesForPage(page)
|
||||
select c.FullName).ToArray();
|
||||
|
||||
// Backup the 100 most recent versions of the page
|
||||
List<PageRevisionBackup> pageContentBackupList = new List<PageRevisionBackup>();
|
||||
int[] revisions = pagesStorageProvider.GetBackups(page);
|
||||
for(int i = 0; i < Math.Min(revisions.Length, 100); i++) {
|
||||
PageContent pageRevision = pagesStorageProvider.GetBackupContent(page, revisions[i]);
|
||||
PageRevisionBackup pageContentBackup = new PageRevisionBackup() {
|
||||
Revision = revisions[i],
|
||||
Content = pageRevision.Content,
|
||||
Comment = pageRevision.Comment,
|
||||
Description = pageRevision.Description,
|
||||
Keywords = pageRevision.Keywords,
|
||||
Title = pageRevision.Title,
|
||||
User = pageRevision.User,
|
||||
LastModified = pageRevision.LastModified
|
||||
};
|
||||
pageContentBackupList.Add(pageContentBackup);
|
||||
}
|
||||
pageBackup.Revisions = pageContentBackupList;
|
||||
|
||||
// Backup draft of the page
|
||||
PageContent draft = pagesStorageProvider.GetDraft(page);
|
||||
if(draft != null) {
|
||||
pageBackup.Draft = new PageRevisionBackup() {
|
||||
Content = draft.Content,
|
||||
Comment = draft.Comment,
|
||||
Description = draft.Description,
|
||||
Keywords = draft.Keywords,
|
||||
Title = draft.Title,
|
||||
User = draft.User,
|
||||
LastModified = draft.LastModified
|
||||
};
|
||||
}
|
||||
|
||||
// Backup all messages of the page
|
||||
List<MessageBackup> messageBackupList = new List<MessageBackup>();
|
||||
foreach(Message message in pagesStorageProvider.GetMessages(page)) {
|
||||
messageBackupList.Add(BackupMessage(message));
|
||||
}
|
||||
pageBackup.Messages = messageBackupList;
|
||||
|
||||
FileStream tempFile = File.Create(Path.Combine(tempDir, page.FullName + ".json"));
|
||||
byte[] buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(pageBackup));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
}
|
||||
}
|
||||
FileStream tempNamespacesFile = File.Create(Path.Combine(tempDir, "Namespaces.json"));
|
||||
byte[] namespacesBuffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(namespaceBackupList));
|
||||
tempNamespacesFile.Write(namespacesBuffer, 0, namespacesBuffer.Length);
|
||||
tempNamespacesFile.Close();
|
||||
|
||||
// Backup content templates
|
||||
ContentTemplate[] contentTemplates = pagesStorageProvider.GetContentTemplates();
|
||||
List<ContentTemplateBackup> contentTemplatesBackup = new List<ContentTemplateBackup>(contentTemplates.Length);
|
||||
foreach(ContentTemplate contentTemplate in contentTemplates) {
|
||||
contentTemplatesBackup.Add(new ContentTemplateBackup() {
|
||||
Name = contentTemplate.Name,
|
||||
Content = contentTemplate.Content
|
||||
});
|
||||
}
|
||||
FileStream tempContentTemplatesFile = File.Create(Path.Combine(tempDir, "ContentTemplates.json"));
|
||||
byte[] contentTemplateBuffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(contentTemplatesBackup));
|
||||
tempContentTemplatesFile.Write(contentTemplateBuffer, 0, contentTemplateBuffer.Length);
|
||||
tempContentTemplatesFile.Close();
|
||||
|
||||
// Backup Snippets
|
||||
Snippet[] snippets = pagesStorageProvider.GetSnippets();
|
||||
List<SnippetBackup> snippetsBackup = new List<SnippetBackup>(snippets.Length);
|
||||
foreach(Snippet snippet in snippets) {
|
||||
snippetsBackup.Add(new SnippetBackup() {
|
||||
Name = snippet.Name,
|
||||
Content = snippet.Content
|
||||
});
|
||||
}
|
||||
FileStream tempSnippetsFile = File.Create(Path.Combine(tempDir, "Snippets.json"));
|
||||
byte[] snippetBuffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(snippetsBackup));
|
||||
tempSnippetsFile.Write(snippetBuffer, 0, snippetBuffer.Length);
|
||||
tempSnippetsFile.Close();
|
||||
|
||||
FileStream tempVersionFile = File.Create(Path.Combine(tempDir, "Version.json"));
|
||||
byte[] versionBuffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(generateVersionFile("Pages")));
|
||||
tempVersionFile.Write(versionBuffer, 0, versionBuffer.Length);
|
||||
tempVersionFile.Close();
|
||||
|
||||
using(ZipFile zipFile = new ZipFile()) {
|
||||
zipFile.AddDirectory(tempDir, "");
|
||||
zipFile.Save(zipFileName);
|
||||
}
|
||||
Directory.Delete(tempDir, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Backup a message with a recursive function to backup all its replies.
|
||||
private static MessageBackup BackupMessage(Message message) {
|
||||
MessageBackup messageBackup = new MessageBackup() {
|
||||
Id = message.ID,
|
||||
Subject = message.Subject,
|
||||
Body = message.Body,
|
||||
DateTime = message.DateTime,
|
||||
Username = message.Username
|
||||
};
|
||||
List<MessageBackup> repliesBackup = new List<MessageBackup>(message.Replies.Length);
|
||||
foreach(Message reply in message.Replies) {
|
||||
repliesBackup.Add(BackupMessage(reply));
|
||||
}
|
||||
messageBackup.Replies = repliesBackup;
|
||||
return messageBackup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backups the users storage provider.
|
||||
/// </summary>
|
||||
/// <param name="zipFileName">The zip file name where to store the backup.</param>
|
||||
/// <param name="usersStorageProvider">The users storage provider.</param>
|
||||
/// <returns><c>true</c> if the backup file has been succesfully created.</returns>
|
||||
public static bool BackupUsersStorageProvider(string zipFileName, IUsersStorageProviderV30 usersStorageProvider) {
|
||||
JavaScriptSerializer javascriptSerializer = new JavaScriptSerializer();
|
||||
javascriptSerializer.MaxJsonLength = javascriptSerializer.MaxJsonLength * 10;
|
||||
|
||||
string tempDir = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
// Backup users
|
||||
UserInfo[] users = usersStorageProvider.GetUsers();
|
||||
List<UserBackup> usersBackup = new List<UserBackup>(users.Length);
|
||||
foreach(UserInfo user in users) {
|
||||
usersBackup.Add(new UserBackup() {
|
||||
Username = user.Username,
|
||||
Active = user.Active,
|
||||
DateTime = user.DateTime,
|
||||
DisplayName = user.DisplayName,
|
||||
Email = user.Email,
|
||||
Groups = user.Groups,
|
||||
UserData = usersStorageProvider.RetrieveAllUserData(user)
|
||||
});
|
||||
}
|
||||
FileStream tempFile = File.Create(Path.Combine(tempDir, "Users.json"));
|
||||
byte[] buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(usersBackup));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
|
||||
// Backup UserGroups
|
||||
UserGroup[] userGroups = usersStorageProvider.GetUserGroups();
|
||||
List<UserGroupBackup> userGroupsBackup = new List<UserGroupBackup>(userGroups.Length);
|
||||
foreach(UserGroup userGroup in userGroups) {
|
||||
userGroupsBackup.Add(new UserGroupBackup() {
|
||||
Name = userGroup.Name,
|
||||
Description = userGroup.Description
|
||||
});
|
||||
}
|
||||
|
||||
tempFile = File.Create(Path.Combine(tempDir, "Groups.json"));
|
||||
buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(userGroupsBackup));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
|
||||
tempFile = File.Create(Path.Combine(tempDir, "Version.json"));
|
||||
buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(generateVersionFile("Users")));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
|
||||
|
||||
using(ZipFile zipFile = new ZipFile()) {
|
||||
zipFile.AddDirectory(tempDir, "");
|
||||
zipFile.Save(zipFileName);
|
||||
}
|
||||
Directory.Delete(tempDir, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backups the files storage provider.
|
||||
/// </summary>
|
||||
/// <param name="zipFileName">The zip file name where to store the backup.</param>
|
||||
/// <param name="filesStorageProvider">The files storage provider.</param>
|
||||
/// <param name="pagesStorageProviders">The pages storage providers.</param>
|
||||
/// <returns><c>true</c> if the backup file has been succesfully created.</returns>
|
||||
public static bool BackupFilesStorageProvider(string zipFileName, IFilesStorageProviderV30 filesStorageProvider, IPagesStorageProviderV30[] pagesStorageProviders) {
|
||||
JavaScriptSerializer javascriptSerializer = new JavaScriptSerializer();
|
||||
javascriptSerializer.MaxJsonLength = javascriptSerializer.MaxJsonLength * 10;
|
||||
|
||||
string tempDir = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
DirectoryBackup directoriesBackup = BackupDirectory(filesStorageProvider, tempDir, null);
|
||||
FileStream tempFile = File.Create(Path.Combine(tempDir, "Files.json"));
|
||||
byte[] buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(directoriesBackup));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
|
||||
|
||||
// Backup Pages Attachments
|
||||
string[] pagesWithAttachment = filesStorageProvider.GetPagesWithAttachments();
|
||||
foreach(string pageWithAttachment in pagesWithAttachment) {
|
||||
PageInfo pageInfo = FindPageInfo(pageWithAttachment, pagesStorageProviders);
|
||||
if(pageInfo != null) {
|
||||
string[] attachments = filesStorageProvider.ListPageAttachments(pageInfo);
|
||||
List<AttachmentBackup> attachmentsBackup = new List<AttachmentBackup>(attachments.Length);
|
||||
foreach(string attachment in attachments) {
|
||||
FileDetails attachmentDetails = filesStorageProvider.GetPageAttachmentDetails(pageInfo, attachment);
|
||||
attachmentsBackup.Add(new AttachmentBackup() {
|
||||
Name = attachment,
|
||||
PageFullName = pageWithAttachment,
|
||||
LastModified = attachmentDetails.LastModified,
|
||||
Size = attachmentDetails.Size
|
||||
});
|
||||
using(MemoryStream stream = new MemoryStream()) {
|
||||
filesStorageProvider.RetrievePageAttachment(pageInfo, attachment, stream, false);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
byte[] tempBuffer = new byte[stream.Length];
|
||||
stream.Read(tempBuffer, 0, (int)stream.Length);
|
||||
|
||||
DirectoryInfo dir = Directory.CreateDirectory(Path.Combine(tempDir, Path.Combine("__attachments", pageInfo.FullName)));
|
||||
tempFile = File.Create(Path.Combine(dir.FullName, attachment));
|
||||
tempFile.Write(tempBuffer, 0, tempBuffer.Length);
|
||||
tempFile.Close();
|
||||
}
|
||||
}
|
||||
tempFile = File.Create(Path.Combine(tempDir, Path.Combine("__attachments", Path.Combine(pageInfo.FullName, "Attachments.json"))));
|
||||
buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(attachmentsBackup));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
}
|
||||
}
|
||||
|
||||
tempFile = File.Create(Path.Combine(tempDir, "Version.json"));
|
||||
buffer = Encoding.Unicode.GetBytes(javascriptSerializer.Serialize(generateVersionFile("Files")));
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
|
||||
using(ZipFile zipFile = new ZipFile()) {
|
||||
zipFile.AddDirectory(tempDir, "");
|
||||
zipFile.Save(zipFileName);
|
||||
}
|
||||
Directory.Delete(tempDir, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static PageInfo FindPageInfo(string pageWithAttachment, IPagesStorageProviderV30[] pagesStorageProviders) {
|
||||
foreach(IPagesStorageProviderV30 pagesStorageProvider in pagesStorageProviders) {
|
||||
PageInfo pageInfo = pagesStorageProvider.GetPage(pageWithAttachment);
|
||||
if(pageInfo != null) return pageInfo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DirectoryBackup BackupDirectory(IFilesStorageProviderV30 filesStorageProvider, string zipFileName, string directory) {
|
||||
DirectoryBackup directoryBackup = new DirectoryBackup();
|
||||
|
||||
string[] files = filesStorageProvider.ListFiles(directory);
|
||||
List<FileBackup> filesBackup = new List<FileBackup>(files.Length);
|
||||
foreach(string file in files) {
|
||||
FileDetails fileDetails = filesStorageProvider.GetFileDetails(file);
|
||||
filesBackup.Add(new FileBackup() {
|
||||
Name = file,
|
||||
Size = fileDetails.Size,
|
||||
LastModified = fileDetails.LastModified
|
||||
});
|
||||
|
||||
FileStream tempFile = File.Create(Path.Combine(zipFileName.Trim('/').Trim('\\'), file.Trim('/').Trim('\\')));
|
||||
using(MemoryStream stream = new MemoryStream()) {
|
||||
filesStorageProvider.RetrieveFile(file, stream, false);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
byte[] buffer = new byte[stream.Length];
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
tempFile.Write(buffer, 0, buffer.Length);
|
||||
tempFile.Close();
|
||||
}
|
||||
}
|
||||
directoryBackup.Name = directory;
|
||||
directoryBackup.Files = filesBackup;
|
||||
|
||||
string[] directories = filesStorageProvider.ListDirectories(directory);
|
||||
List<DirectoryBackup> subdirectoriesBackup = new List<DirectoryBackup>(directories.Length);
|
||||
foreach(string d in directories) {
|
||||
subdirectoriesBackup.Add(BackupDirectory(filesStorageProvider, zipFileName, d));
|
||||
}
|
||||
directoryBackup.SubDirectories = subdirectoriesBackup;
|
||||
|
||||
return directoryBackup;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class SettingsBackup {
|
||||
public Dictionary<string, string> Settings { get; set; }
|
||||
public Dictionary<string, bool> PluginsStatus { get; set; }
|
||||
public Dictionary<string, string> PluginsConfiguration { get; set; }
|
||||
public List<MetaData> Metadata { get; set; }
|
||||
public List<RecentChange> RecentChanges { get; set; }
|
||||
public Dictionary<string, string[]> OutgoingLinks { get; set; }
|
||||
public List<AclEntryBackup> AclEntries { get; set; }
|
||||
}
|
||||
|
||||
internal class AclEntryBackup {
|
||||
public Value Value { get; set; }
|
||||
public string Subject { get; set; }
|
||||
public string Resource { get; set; }
|
||||
public string Action { get; set; }
|
||||
}
|
||||
|
||||
internal class MetaData {
|
||||
public MetaDataItem Item {get; set;}
|
||||
public string Tag {get; set;}
|
||||
public string Content {get; set;}
|
||||
}
|
||||
|
||||
internal class GlobalSettingsBackup {
|
||||
public Dictionary<string, string> Settings { get; set; }
|
||||
public List<string> pluginsFileNames { get; set; }
|
||||
}
|
||||
|
||||
internal class PageBackup {
|
||||
public String FullName { get; set; }
|
||||
public DateTime CreationDateTime { get; set; }
|
||||
public DateTime LastModified { get; set; }
|
||||
public string Content { get; set; }
|
||||
public string Comment { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string[] Keywords { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string User { get; set; }
|
||||
public string[] LinkedPages { get; set; }
|
||||
public List<PageRevisionBackup> Revisions { get; set; }
|
||||
public PageRevisionBackup Draft { get; set; }
|
||||
public List<MessageBackup> Messages { get; set; }
|
||||
public string[] Categories { get; set; }
|
||||
}
|
||||
|
||||
internal class PageRevisionBackup {
|
||||
public string Content { get; set; }
|
||||
public string Comment { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string[] Keywords { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string User { get; set; }
|
||||
public DateTime LastModified { get; set; }
|
||||
public int Revision { get; set; }
|
||||
}
|
||||
|
||||
internal class NamespaceBackup {
|
||||
public string Name { get; set; }
|
||||
public string DefaultPageFullName { get; set; }
|
||||
public List<CategoryBackup> Categories { get; set; }
|
||||
public List<NavigationPathBackup> NavigationPaths { get; set; }
|
||||
}
|
||||
|
||||
internal class CategoryBackup {
|
||||
public string FullName { get; set; }
|
||||
public string[] Pages { get; set; }
|
||||
}
|
||||
|
||||
internal class ContentTemplateBackup {
|
||||
public string Name { get; set; }
|
||||
public string Content { get; set; }
|
||||
}
|
||||
|
||||
internal class MessageBackup {
|
||||
public List<MessageBackup> Replies { get; set; }
|
||||
public int Id { get; set; }
|
||||
public string Subject { get; set; }
|
||||
public string Body { get; set; }
|
||||
public DateTime DateTime { get; set; }
|
||||
public string Username { get; set; }
|
||||
}
|
||||
|
||||
internal class NavigationPathBackup {
|
||||
public string FullName { get; set; }
|
||||
public string[] Pages { get; set; }
|
||||
}
|
||||
|
||||
internal class SnippetBackup {
|
||||
public string Name { get; set; }
|
||||
public string Content { get; set; }
|
||||
}
|
||||
|
||||
internal class UserBackup {
|
||||
public string Username { get; set; }
|
||||
public bool Active { get; set; }
|
||||
public DateTime DateTime { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string[] Groups { get; set; }
|
||||
public IDictionary<string, string> UserData { get; set; }
|
||||
}
|
||||
|
||||
internal class UserGroupBackup {
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
internal class DirectoryBackup {
|
||||
public List<FileBackup> Files { get; set; }
|
||||
public List<DirectoryBackup> SubDirectories { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
internal class FileBackup {
|
||||
public string Name { get; set; }
|
||||
public long Size { get; set; }
|
||||
public DateTime LastModified { get; set; }
|
||||
public string DirectoryName { get; set; }
|
||||
}
|
||||
|
||||
internal class VersionFile {
|
||||
public string BackupRestoreVersion { get; set; }
|
||||
public string WikiVersion { get; set; }
|
||||
public string BackupName { get; set; }
|
||||
}
|
||||
|
||||
internal class AttachmentBackup {
|
||||
public string Name { get; set; }
|
||||
public string PageFullName { get; set; }
|
||||
public DateTime LastModified { get; set; }
|
||||
public long Size { get; set; }
|
||||
}
|
||||
|
||||
}
|
76
BackupRestore/BackupRestore.csproj
Normal file
76
BackupRestore/BackupRestore.csproj
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{06320590-F6FC-4F8B-B3A2-2B5991676BE8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ScrewTurn.Wiki.BackupRestore</RootNamespace>
|
||||
<AssemblyName>ScrewTurn.Wiki.BackupRestore</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DocumentationFile>bin\Debug\ScrewTurn.Wiki.BackupRestore.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DocumentationFile>bin\Release\ScrewTurn.Wiki.BackupRestore.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Ionic.Zip.Reduced">
|
||||
<HintPath>..\References\Lib\DotNetZipLib-DevKit-v1.9\Ionic.Zip.Reduced.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\AssemblyVersion.cs">
|
||||
<Link>AssemblyVersion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="BackupRestore.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AclEngine\AclEngine.csproj">
|
||||
<Project>{44B0F4C1-8CDC-4272-B2A2-C0AF689CEB81}</Project>
|
||||
<Name>AclEngine</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PluginFramework\PluginFramework.csproj">
|
||||
<Project>{531A83D6-76F9-4014-91C5-295818E2D948}</Project>
|
||||
<Name>PluginFramework</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
18
BackupRestore/Properties/AssemblyInfo.cs
Normal file
18
BackupRestore/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ScrewTurn Wiki Backup Restore")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("b06902e4-3d04-4c40-928c-862bdcd83815")]
|
BIN
References/Lib/DotNetZipLib-DevKit-v1.9/Ionic.Zip.Reduced.dll
Normal file
BIN
References/Lib/DotNetZipLib-DevKit-v1.9/Ionic.Zip.Reduced.dll
Normal file
Binary file not shown.
33
References/Lib/DotNetZipLib-DevKit-v1.9/License.txt
Normal file
33
References/Lib/DotNetZipLib-DevKit-v1.9/License.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
Microsoft Public License (Ms-PL)
|
||||
|
||||
This license governs use of the accompanying software, the DotNetZip library ("the software"). If you use the software, you accept this license. If you do not accept the license, do not use the software.
|
||||
|
||||
1. Definitions
|
||||
|
||||
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
|
||||
|
||||
A "contribution" is the original software, or any additions or changes to the software.
|
||||
|
||||
A "contributor" is any person that distributes its contribution under this license.
|
||||
|
||||
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
|
||||
|
||||
2. Grant of Rights
|
||||
|
||||
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
|
||||
|
||||
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
|
||||
|
||||
3. Conditions and Limitations
|
||||
|
||||
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
|
||||
|
||||
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
|
||||
|
||||
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
|
||||
|
||||
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
|
||||
|
||||
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
|
||||
|
||||
|
|
@ -67,6 +67,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnfuddleTicketsPlugin", "Un
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingManagerPlugin", "RatingManagerPlugin\RatingManagerPlugin.csproj", "{B65C793F-62C4-4B81-95C4-3E4805E80411}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackupRestore", "BackupRestore\BackupRestore.csproj", "{06320590-F6FC-4F8B-B3A2-2B5991676BE8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -161,6 +163,10 @@ Global
|
|||
{B65C793F-62C4-4B81-95C4-3E4805E80411}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B65C793F-62C4-4B81-95C4-3E4805E80411}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B65C793F-62C4-4B81-95C4-3E4805E80411}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{06320590-F6FC-4F8B-B3A2-2B5991676BE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{06320590-F6FC-4F8B-B3A2-2B5991676BE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{06320590-F6FC-4F8B-B3A2-2B5991676BE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{06320590-F6FC-4F8B-B3A2-2B5991676BE8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -249,6 +249,9 @@
|
|||
<anthem:TextBox ID="txtSettingsDestinationConfig" runat="server" TextMode="MultiLine" CssClass="config" />
|
||||
</div>
|
||||
|
||||
<br /><br />
|
||||
<asp:Button ID="btnExport" runat="server" Text="Export" OnClick="btnExport_Click" meta:resourcekey="btnExportResource1" />
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
|
||||
</asp:Content>
|
||||
|
|
|
@ -6,6 +6,8 @@ using System.Web.UI;
|
|||
using System.Web.UI.WebControls;
|
||||
using ScrewTurn.Wiki.PluginFramework;
|
||||
using System.Net;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace ScrewTurn.Wiki {
|
||||
|
||||
|
@ -538,6 +540,38 @@ namespace ScrewTurn.Wiki {
|
|||
|
||||
#endregion
|
||||
|
||||
protected void btnExport_Click(object sender, EventArgs e) {
|
||||
Log.LogEntry("Data export requested.", EntryType.General, SessionFacade.GetCurrentUsername());
|
||||
|
||||
string tempDir = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
string zipFileName = Path.Combine(tempDir, "Backup.zip");
|
||||
|
||||
bool backupFileSucceded = BackupRestore.BackupRestore.BackupAll(zipFileName, Settings.Provider.ListPluginAssemblies(),
|
||||
Settings.Provider,
|
||||
(from p in Collectors.PagesProviderCollector.AllProviders where !p.ReadOnly select p).ToArray(),
|
||||
(from p in Collectors.UsersProviderCollector.AllProviders where IsUsersProviderFullWriteEnabled(p) select p).ToArray(),
|
||||
(from p in Collectors.FilesProviderCollector.AllProviders where !p.ReadOnly select p).ToArray());
|
||||
|
||||
FileInfo file = new FileInfo(zipFileName);
|
||||
Response.Clear();
|
||||
Response.AddHeader("content-type", GetMimeType(zipFileName));
|
||||
Response.AddHeader("content-disposition", "attachment;filename=Backup.zip");
|
||||
Response.AddHeader("content-length", file.Length.ToString());
|
||||
|
||||
Response.TransmitFile(zipFileName);
|
||||
Response.Flush();
|
||||
|
||||
Directory.Delete(tempDir, true);
|
||||
Log.LogEntry("Data export completed.", EntryType.General, SessionFacade.GetCurrentUsername());
|
||||
}
|
||||
|
||||
private string GetMimeType(string ext) {
|
||||
string mime = "";
|
||||
if(MimeTypes.Types.TryGetValue(ext, out mime)) return mime;
|
||||
else return "application/octet-stream";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detects whether a users storage provider fully supports writing to all managed data.
|
||||
/// </summary>
|
||||
|
|
10
WebApplication/AdminProviders.aspx.designer.cs
generated
10
WebApplication/AdminProviders.aspx.designer.cs
generated
|
@ -1,7 +1,6 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:2.0.50727.4927
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
|
@ -660,5 +659,14 @@ namespace ScrewTurn.Wiki {
|
|||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::Anthem.TextBox txtSettingsDestinationConfig;
|
||||
|
||||
/// <summary>
|
||||
/// btnExport control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Button btnExport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2676,6 +2676,10 @@
|
|||
<Project>{44B0F4C1-8CDC-4272-B2A2-C0AF689CEB81}</Project>
|
||||
<Name>AclEngine</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\BackupRestore\BackupRestore.csproj">
|
||||
<Project>{06320590-F6FC-4F8B-B3A2-2B5991676BE8}</Project>
|
||||
<Name>BackupRestore</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Core\Core.csproj">
|
||||
<Project>{C353A35C-86D0-4154-9500-4F88CAAB29C3}</Project>
|
||||
<Name>Core</Name>
|
||||
|
@ -2796,7 +2800,7 @@
|
|||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>52149</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>10043</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>
|
||||
</IISUrl>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue