⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pagesstorageprovider.cs

📁 YetAnotherForum.Net+ScrewTurnWiki中文完美汉化增强版
💻 CS
📖 第 1 页 / 共 3 页
字号:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ScrewTurn.Wiki.PluginFramework;

namespace ScrewTurn.Wiki {

	/// <summary>
	/// Implements a Pages Storage Provider.
	/// </summary>
	[Serializable]
	public class PagesStorageProvider : IPagesStorageProvider {

		/// <summary>
		/// Used as lock object for multithreaded operations.
		/// </summary>
		private object locker = new object();
		private object lockerDisc = new object();
		private ComponentInformation info = new ComponentInformation("Local Pages Provider", "ScrewTurn Software", "http://www.screwturn.eu");
		private IHost host;

		/// <summary>
		/// Initializes the Provider.
		/// </summary>
		/// <param name="host">The Host of the Provider.</param>
		/// <param name="config">The Configuration data, if any.</param>
		public void Init(IHost host, string config) {
			this.host = host;
		}

		/// <summary>
		/// Method invoked on shutdown.
		/// </summary>
		/// <remarks>This method might not be invoked in some cases.</remarks>
		public void Shutdown() { }

		/// <summary>
		/// Gets the Information about the Provider.
		/// </summary>
		public ComponentInformation Information {
			get { return info; }
		}

		/// <summary>
		/// Gets a value specifying whether the provider is read-only, i.e. it can only provide data and not store it.
		/// </summary>
		public bool ReadOnly {
			get { return false; }
		}

		/// <summary>
		/// Gets all the Pages.
		/// </summary>
		/// <remarks>The array is unsorted.</remarks>
		public PageInfo[] AllPages {
			get {
				string tmp;
				lock(locker) {
					tmp = Tools.LoadFile(Settings.PagesFile).Replace("\r", "");
				}
				string[] lines = tmp.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
				PageInfo[] result = new PageInfo[lines.Length];
				string[] fields;
				for(int i = 0; i < lines.Length; i++) {
					fields = lines[i].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
					// Structure
					// PageName|PageFile|Status(optional);
					PageStatus ps = PageStatus.Normal;
					DateTime creationDateTime = new DateTime(2000, 1, 1);
					if(fields.Length == 2) ps = PageStatus.Normal;
					if(fields.Length >= 3) {
						switch(fields[2].ToLower()) {
							case "locked":
								ps = PageStatus.Locked;
								break;
							case "public":
								ps = PageStatus.Public;
								break;
							case "normal":
								ps = PageStatus.Normal;
								break;
							default:
								try {
									creationDateTime = DateTime.Parse(fields[2]);
								}
								catch {
									// Use the Date/Time of the file
									FileInfo fi = new FileInfo(Settings.PagesDirectory + fields[1]);
									creationDateTime = fi.CreationTime;
								}
								break;
						}
					}
					if(fields.Length == 4) {
						creationDateTime = DateTime.Parse(fields[3]);
					}
					result[i] = new LocalPageInfo(fields[0], this, ps, creationDateTime, fields[1]);
				}
				return result;
			}
		}

		private bool PageExists(PageInfo page) {
			PageInfo[] pages = AllPages;
			PageNameComparer comp = new PageNameComparer();
			for(int i = 0; i < pages.Length; i++) {
				if(comp.Compare(pages[i], page) == 0) return true;
			}
			return false;
		}

		/// <summary>
		/// Gets all the Categories.
		/// </summary>
		/// <remarks>The array is unsorted.</remarks>
		public CategoryInfo[] AllCategories {
			get {
				string tmp;
				lock(locker) {
					tmp = Tools.LoadFile(Settings.CategoriesFile).Replace("\r", "");
				}
				string[] lines = tmp.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
				CategoryInfo[] result = new CategoryInfo[lines.Length];
				string[] fields;
				for(int i = 0; i < lines.Length; i++) {
					fields = lines[i].Split('|');
					CategoryInfo cat = new CategoryInfo(fields[0], this);
					List<string> pages = new List<string>();
					for(int k = 0; k < fields.Length - 1; k++) {
						if(PageExists(new PageInfo(fields[k + 1], this, PageStatus.Normal, DateTime.Now))) {
							pages.Add(fields[k + 1]);
						}
					}
					cat.Pages = pages.ToArray();
					result[i] = cat;
				}
				return result;
			}
		}

		private bool CategoryExists(CategoryInfo category) {
			CategoryInfo[] cats = AllCategories;
			CategoryNameComparer comp = new CategoryNameComparer();
			for(int i = 0; i < cats.Length; i++) {
				if(comp.Compare(cats[i], category) == 0) return true;
			}
			return false;
		}

		/// <summary>
		/// Adds a new Category.
		/// </summary>
		/// <param name="name">The Category name.</param>
		/// <returns>The correct CategoryInfo object.</returns>
		public CategoryInfo AddCategory(string name) {
			lock(locker) {
				Tools.AppendFile(Settings.CategoriesFile, "\r\n" + name);
				CategoryInfo[] cats = AllCategories;
				CategoryInfo res = new CategoryInfo(name, this);
				res.Pages = new string[0];
				return res;
			}
		}

		/// <summary>
		/// Renames a Category.
		/// </summary>
		/// <param name="category">The Category to rename.</param>
		/// <param name="newName">The new Name.</param>
		/// <returns>The correct CategoryInfo object.</returns>
		public CategoryInfo RenameCategory(CategoryInfo category, string newName) {
			lock(locker) {
				CategoryInfo[] cats = AllCategories;
				CategoryNameComparer comp = new CategoryNameComparer();
				for(int i = 0; i < cats.Length; i++) {
					if(comp.Compare(cats[i], category) == 0) {
						CategoryInfo tmp = new CategoryInfo(newName, this);
						tmp.Pages = cats[i].Pages;
						cats[i] = tmp;
						DumpCategories(cats);
						return tmp;
					}
				}
			}
			return null;
		}

		/// <summary>
		/// Removes a Category.
		/// </summary>
		/// <param name="category">The Category to remove.</param>
		/// <returns>True if the Category has been removed successfully.</returns>
		public bool RemoveCategory(CategoryInfo category) {
			lock(locker) {
				CategoryInfo[] cats = AllCategories;
				CategoryNameComparer comp = new CategoryNameComparer();
				for(int i = 0; i < cats.Length; i++) {
					if(comp.Compare(cats[i], category) == 0) {
						List<CategoryInfo> tmp = new List<CategoryInfo>(cats);
						tmp.Remove(tmp[i]);
						DumpCategories(tmp.ToArray());
						return true;
					}
				}
			}
			return false;
		}

		/// <summary>
		/// Merges two Categories.
		/// </summary>
		/// <param name="source">The source Category.</param>
		/// <param name="destination">The destination Category.</param>
		/// <returns>True if the Categories have been merged successfully.</returns>
		/// <remarks>The <b>destination</b> Category remains, while the <b>source</b> Category is deleted, and all its Pages re-binded in the <b>destination</b> Category.</remarks>
		public CategoryInfo MergeCategories(CategoryInfo source, CategoryInfo destination) {
			lock(locker) {
				CategoryInfo[] cats = AllCategories;
				int idx1 = -1, idx2 = -1;
				CategoryNameComparer comp = new CategoryNameComparer();
				for(int i = 0; i < cats.Length; i++) {
					if(comp.Compare(cats[i], source) == 0) idx1 = i;
					if(comp.Compare(cats[i], destination) == 0) idx2 = i;
					if(idx1 != -1 && idx2 != -1) break;
				}
				if(idx1 == -1 || idx2 == -1) return null;
				List<CategoryInfo> tmp = new List<CategoryInfo>(cats);
				List<string> newPages = new List<string>(cats[idx2].Pages);
				for(int i = 0; i < cats[idx1].Pages.Length; i++) {
					bool found = false;
					for(int k = 0; k < newPages.Count; k++) {
						if(newPages[k].ToLower().Equals(cats[idx1].Pages[i].ToLower())) {
							found = true;
							break;
						}
					}
					if(!found) {
						newPages.Add(cats[idx1].Pages[i]);
					}
				}
				tmp[idx2].Pages = newPages.ToArray();
				tmp.Remove(tmp[idx1]);
				DumpCategories(tmp.ToArray());
				CategoryInfo newCat = new CategoryInfo(destination.Name, this);
				newCat.Pages = newPages.ToArray();
				return newCat;
			}
		}

		/// <summary>
		/// Gets the Content of a Page.
		/// </summary>
		/// <param name="page">The Page to get the content of.</param>
		/// <returns>The Page Content.</returns>
		public PageContent GetContent(PageInfo page) {
			if(page == null) return null;
			return ExtractContent(Tools.LoadFile(Settings.PagesDirectory + ((LocalPageInfo)page).File), page);
		}

		private PageContent ExtractContent(string data, PageInfo pageInfo) {
			if(data == null) return null;
			// Structure
			// Page Title
			// Username|DateTime[|Comment] --- The comment is optional
			// ##PAGE##
			// Content...
			data = data.Replace("\r", "");
			string[] lines = data.Split('\n');
			string[] fields = lines[1].Split('|');
			int idx = data.IndexOf("##PAGE##") + 8 + 1;
			return new PageContent(pageInfo, lines[0], fields[0], DateTime.Parse(fields[1]), fields.Length == 3 ? Tools.UnescapeString(fields[2]) : "", data.Substring(idx));
		}

		/// <summary>
		/// Backups a Page.
		/// </summary>
		/// <param name="page">The Page to backup.</param>
		/// <returns>True if the Page has been backupped successfully.</returns>
		public bool Backup(PageInfo page) {
			List<int> backups = GetBackups(page);
			LocalPageInfo pg = (LocalPageInfo)page;
			int rev = (backups.Count > 0 ? backups[backups.Count - 1] + 1 : 0);
			File.Copy(Settings.PagesDirectory + pg.File,
				Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(rev) + Path.GetExtension(pg.File));
			return true;
		}

		/// <summary>
		/// Gets the Backup/Revision numbers of a Page.
		/// </summary>
		/// <param name="page">The Page to get the Backup of.</param>
		/// <returns>The list of Backup/Revision numbers.</returns>
		public List<int> GetBackups(PageInfo page) {
			string[] files = Directory.GetFiles(Settings.PagesDirectory, Path.GetFileNameWithoutExtension(((LocalPageInfo)page).File) + ".*.cs");
			List<int> result = new List<int>();
			for(int i = 0; i < files.Length; i++) {
				string num = Path.GetFileNameWithoutExtension(files[i]).Substring(page.Name.Length + 1);
				try {
					// If num is not actually a number, this would crash
					result.Add(int.Parse(num));
				}
				catch { }
			}
			return result;
		}

		/// <summary>
		/// Gets the Content of a Backup.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <param name="revision">The revision.</param>
		/// <returns>The content.</returns>
		public PageContent GetBackupContent(PageInfo page, int revision) {
			if(!PageExists(page)) return null;
			LocalPageInfo pg = (LocalPageInfo)page;
			string filename = Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(revision) + Path.GetExtension(pg.File);
			return ExtractContent(Tools.LoadFile(Settings.PagesDirectory + filename), page);
		}

		/// <summary>
		/// Forces to overwrite or create a Backup.
		/// </summary>
		/// <param name="content">The Backup content.</param>
		/// <param name="revision">The revision.</param>
		/// <returns>True if the Backup has been created successfully.</returns>
		public bool SetBackupContent(PageContent content, int revision) {
			StringBuilder sb = new StringBuilder();
			sb.Append(content.Title);
			sb.Append("\r\n");
			sb.Append(content.User);
			sb.Append("|");
			sb.Append(content.LastModified.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
			sb.Append("\r\n##PAGE##\r\n");
			sb.Append(content.Content);
			string filename = "";
			if(content.PageInfo is LocalPageInfo) {
				// Use local file
				LocalPageInfo pg = (LocalPageInfo)content.PageInfo;
				filename = Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(revision) + Path.GetExtension(pg.File);
			}
			else {
				filename = content.PageInfo.Name + "." + Tools.GetVersionString(revision) + ".cs";
			}
			Tools.WriteFile(Settings.PagesDirectory + filename, sb.ToString());
			return true;
		}

		/// <summary>
		/// Adds a new Page.
		/// </summary>
		/// <param name="name">The Name of the Page.</param>
		/// <param name="creationDateTime">The creation Date/Time.</param>
		/// <returns>The correct PageInfo object.</returns>
		public PageInfo AddPage(string name, DateTime creationDateTime) {
			if(PageExists(new PageInfo(name, this, PageStatus.Normal, DateTime.Now))) return null;
			lock(locker) {
				Tools.AppendFile(Settings.PagesFile, "\r\n" + name + "|" + name + ".cs" + "|NORMAL|" + creationDateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
				File.Create(Settings.PagesDirectory + name + ".cs").Close();
			}
			return new LocalPageInfo(name, this, PageStatus.Normal, creationDateTime, name + ".cs");
		}

		/// <summary>
		/// Renames a Page.
		/// </summary>
		/// <param name="page">The Page to rename.</param>
		/// <param name="newName">The new Name.</param>
		/// <returns>True if the Page has been renamed successfully.</returns>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -