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

📄 pages.cs

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

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

namespace ScrewTurn.Wiki {

    /// <summary>
    /// Allows access to the Pages.
    /// </summary>
    public class Pages {

		private static Pages instance = null;

		/// <summary>
		/// Gets or sets the singleton instance of the Pages object.
		/// </summary>
		public static Pages Instance {
			get { return instance; }
			set { instance = value; }
		}

		private List<PageInfo> pages = null; // Sorted
		private List<CategoryInfo> categories = null; // Sorted

        /// <summary>
        /// Initializes a new instance of the <b>Pages</b> class.
        /// </summary>
        public Pages() {
            pages = new List<PageInfo>();
			categories = new List<CategoryInfo>();
            Load();
        }

		/// <summary>
		/// Loads Pages and Categories from all the Providers.
		/// </summary>
        public void Load() {
            lock(pages) {
				IPagesStorageProvider[] provs = Collectors.PagesProviderCollector.AllProviders;
				for(int i = 0; i < provs.Length; i++) {
					LoadFrom(provs[i], false);
				}
                
				// Sort is very important for binary search
                pages.Sort(new PageNameComparer());
				categories.Sort(new CategoryNameComparer());
            }
        }

		/// <summary>
		/// Loads Pages and Categories from a specific Provider.
		/// </summary>
		/// <param name="provider">The Provider.</param>
		/// <param name="autosort">If true, the global pages list is sorted after the operation.</param>
		public void LoadFrom(IPagesStorageProvider provider, bool autosort) {
			lock(pages) lock(categories) {
				pages.AddRange(provider.AllPages);
				categories.AddRange(provider.AllCategories);
				if(autosort) {
					pages.Sort(new PageNameComparer());
					categories.Sort(new CategoryNameComparer());
				}
			}
		}

		/// <summary>
		/// Unloads all the data provided by the specified Provider.
		/// </summary>
		/// <param name="provider">The Provider.</param>
		public void UnloadFrom(IPagesStorageProvider provider) {
			lock(pages) {
				lock(categories) {
					List<PageInfo> pagesToRemove = new List<PageInfo>();
					List<CategoryInfo> catsToRemove = new List<CategoryInfo>();
					for(int i = 0; i < pages.Count; i++) {
						if(pages[i].Provider == provider) pagesToRemove.Add(pages[i]);
					}
					for(int i = 0; i < pagesToRemove.Count; i++) {
						pages.Remove(pagesToRemove[i]);
					}
					for(int i = 0; i < categories.Count; i++) {
						if(categories[i].Provider == provider) catsToRemove.Add(categories[i]);
					}
					for(int i = 0; i < catsToRemove.Count; i++) {
						categories.Remove(catsToRemove[i]);
					}
					Content.InvalidateAll();
					Content.PseudoCache.Clear();
				}
			}
		}

		/// <summary>
		/// Reloads all the Pages and Categories managed by the specified provider.
		/// </summary>
		/// <param name="provider">The Provider.</param>
		public void ReloadFrom(IPagesStorageProvider provider) {
			lock(pages) {
				lock(categories) {
					List<PageInfo> pagesToRemove = new List<PageInfo>();
					List<CategoryInfo> catsToRemove = new List<CategoryInfo>();
					for(int i = 0; i < pages.Count; i++) {
						if(pages[i].Provider == provider) pagesToRemove.Add(pages[i]);
					}
					for(int i = 0; i < pagesToRemove.Count; i++) {
						pages.Remove(pagesToRemove[i]);
					}
					for(int i = 0; i < categories.Count; i++) {
						if(categories[i].Provider == provider) catsToRemove.Add(categories[i]);
					}
					for(int i = 0; i < catsToRemove.Count; i++) {
						categories.Remove(catsToRemove[i]);
					}
					LoadFrom(provider, true);
					Content.InvalidateAll();
					Content.PseudoCache.Clear();
				}
			}
		}

		/// <summary>
		/// Reloads the Pages cache.
		/// </summary>
		public void Reload() {
			lock(pages) {
				pages.Clear();
			}
			lock(categories) {
				categories.Clear();
			}
			Load();
		}

		#region Pages

		/// <summary>
        /// Finds a Page.
        /// </summary>
        /// <param name="name">The Name of the Page to find (case <b>unsensitive</b>).</param>
        /// <returns>The Page Info, if any, null otherwise.</returns>
        public PageInfo FindPage(string name) {
			if(name == null || name.Length == 0) return null;
            lock(pages) {
				int idx = pages.BinarySearch(new PageInfo(name, null, PageStatus.Normal, DateTime.Now), new PageNameComparer());
				if(idx >= 0) return pages[idx];
            }
            return null;
        }

		/// <summary>
		/// Finds a Page in a specific Provider.
		/// </summary>
		/// <param name="name">The Name of the Page to find (case <b>unsensitive</b>).</param>
		/// <param name="provider">The Provider.</param>
		/// <returns>The Page Info, if any, null otherwise.</returns>
		public PageInfo FindPage(string name, IPagesStorageProvider provider) {
			if(name == null || name.Length == 0) return null;
			lock(pages) {
				int idx = pages.BinarySearch(new PageInfo(name, null, PageStatus.Normal, DateTime.Now), new PageNameComparer());
				if(idx >= 0 && pages[idx].Provider == provider) return pages[idx];
			}
			return null;
		}

		/// <summary>
		/// Gets the Backups/Revisions of a Page.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <returns>The list of available Backups/Revision numbers.</returns>
		public List<int> GetBackups(PageInfo page) {
			return page.Provider.GetBackups(page);
		}

		/// <summary>
		/// Gets the Content of a Page Backup.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <param name="revision">The Backup/Revision number.</param>
		/// <returns>The Content of the Backup.</returns>
		public PageContent GetBackupContent(PageInfo page, int revision) {
			return page.Provider.GetBackupContent(page, revision);
		}

		private void Backup(PageInfo page) {
			int kept = Settings.KeptBackupNumber;

			if(kept != 0) { // This avoids creating a backup that would be deleted
				bool done = page.Provider.Backup(page);
				if(done) Log.LogEntry("Backup created for " + page.Name, EntryType.General, "SYSTEM");
				else {
					Log.LogEntry("Backup failed for " + page.Name, EntryType.Error, "SYSTEM");
					return;
				}
			}

			List<int> backups = page.Provider.GetBackups(page);
			if(kept >= 0) {
				if(backups.Count > kept) {
					page.Provider.DeleteBackups(page, backups.Count - kept - 1);
				}
			}
		}

		/// <summary>
		/// Deletes all the Page Backups.
		/// </summary>
		/// <param name="page">The Page.</param>
		public bool DeleteBackups(PageInfo page) {
			return page.Provider.DeleteBackups(page, -1);
		}

		/// <summary>
		/// Deletes a part of the Page Backups.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <param name="firstToDelete">The first backup to be deleted (this backup and older backups are deleted).</param>
		public bool DeleteBackups(PageInfo page, int firstToDelete) {
			bool done = page.Provider.DeleteBackups(page, firstToDelete);
			if(done) {
				Log.LogEntry("Backups (0-" + firstToDelete.ToString() + ") deleted for " + page.Name, EntryType.General, "SYSTEM");
			}
			else {
				Log.LogEntry("Backups (0-" + firstToDelete.ToString() + ") deletion failed for " + page.Name, EntryType.Error, "SYSTEM");
			}
			return done;
		}

		/// <summary>
		/// Performs the rollpack of a Page.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <param name="version">The revision to rollback the Page to.</param>
		public bool Rollback(PageInfo page, int version) {
			bool done = page.Provider.RollbackPage(page, version);

			if(done) {
				Content.Invalidate(page);
				Log.LogEntry("Rollback executed for " + page.Name + " at revision " + version.ToString(), EntryType.General, "SYSTEM");
				RecentChanges.Instance.AddChange(page.Name, Content.GetPageContent(page, false).Title, DateTime.Now, SessionFacade.Username, Change.PageRolledBack, "");
				return true;
			}
			else {
				Log.LogEntry("Rollback failed for " + page.Name + " at revision " + version.ToString(), EntryType.Error, "SYSTEM");
				return false;
			}
        }

		/// <summary>
		/// Creates a new Page.
		/// </summary>
		/// <param name="name">The Page name.</param>
		/// <returns>True if the Page has been created successfully.</returns>
        public bool CreatePage(string name) {
			return CreatePage(name, Collectors.PagesProviderCollector.GetProvider(Settings.DefaultPagesProvider));
        }

		/// <summary>
		/// Creates a new Page.
		/// </summary>
		/// <param name="name">The Page name.</param>
		/// <returns>True if the Page has been created successfully.</returns>
		public bool CreatePage(string name, IPagesStorageProvider provider) {
			if(FindPage(name) != null) return false;

			PageInfo newPage = provider.AddPage(name, DateTime.Now);

			if(newPage != null) {
				lock(pages) {
					pages.Add(newPage);
					pages.Sort(new PageNameComparer());
				}
				Content.InvalidateAll();
				Content.PseudoCache.Clear();
				Log.LogEntry("Page " + name + " created", EntryType.General, "SYSTEM");
				return true;
			}
			else {
				Log.LogEntry("Page creation failed for " + name, EntryType.Error, "SYSTEM");
				return false;
			}
		}

		/// <summary>
		/// Sets the Status of a Page.
		/// </summary>
		/// <param name="page">The Page to set the status of.</param>
		/// <param name="status">The Status.</param>
		/// <returns>True if the Status has been set successfully.</returns>
		public bool SetPageStatus(PageInfo page, PageStatus status) {
			PageInfo newPage = page.Provider.SetStatus(page, status);
			if(newPage != null) {
				lock(pages) {
					pages.Remove(page);
					pages.Add(newPage);
					pages.Sort(new PageNameComparer());
				}
				Log.LogEntry("Page Status changed to " + status.ToString() + " for " + page.Name, EntryType.General, "SYSTEM");
			}
			else Log.LogEntry("Page Status change failed for " + page.Name + " (" + status.ToString() + ")", EntryType.Error, "SYSTEM");
			return newPage != null;
		}

        /// <summary>
        /// Deletes a Page.
        /// </summary>
        /// <param name="page">The Page to delete.</param>
        public bool DeletePage(PageInfo page) {
			string title = Content.GetPageContent(page, false).Title;

			bool done = page.Provider.RemovePage(page);

			if(done) {
				lock(pages) {
					lock(categories) {
						ReloadFrom(page.Provider);
						pages.Sort(new PageNameComparer());
						categories.Sort(new CategoryNameComparer());
					}
				}
				// Remove the deleted page from the Breadcrumbs Trail and Redirections list
				SessionFacade.Breadcrumbs.RemovePage(page);
				Redirections.Instance.WipePageOut(page);
				// Cleanup Cache
				Content.Invalidate(page);
				Content.PseudoCache.Clear();
				Log.LogEntry("Page " + page.Name + " deleted", EntryType.General, "SYSTEM");
				RecentChanges.Instance.AddChange(page.Name, title, DateTime.Now, SessionFacade.Username, Change.PageDeleted, "");
				return true;
			}
			else {
				Log.LogEntry("Page deletion failed for " + page.Name, EntryType.Error, "SYSTEM");
				return false;
			}
        }

        /// <summary>
        /// Renames a Page.
        /// </summary>
        /// <param name="page">The Page to rename.</param>
        /// <param name="name">The new name.</param>
        public bool RenamePage(PageInfo page, string name) {
			if(FindPage(name) != null) return false;

			string title = Content.GetPageContent(page, false).Title;

			PageInfo pg = page.Provider.RenamePage(page, name);
			if(pg != null) {
				lock(pages) {
					lock(categories) {
						ReloadFrom(page.Provider);
						pages.Sort(new PageNameComparer());
						categories.Sort(new CategoryNameComparer());
					}
				}
				SessionFacade.Breadcrumbs.RemovePage(page);
				Redirections.Instance.Clear();
				Content.InvalidateAll();
				Content.PseudoCache.Clear();
				Log.LogEntry("Page " + page.Name + " renamed to " + name, EntryType.General, "SYSTEM");
				RecentChanges.Instance.AddChange(page.Name, title, DateTime.Now, SessionFacade.Username, Change.PageRenamed, "");
				return true;
			}
			else {
				Log.LogEntry("Page rename failed for " + page.Name + " (" + name + ")", EntryType.Error, "SYSTEM");
				return false;
			}
        }

		/// <summary>
		/// Modifies a Page.
		/// </summary>
		/// <param name="page">The Page to modify.</param>
		/// <param name="title">The Title of the Page.</param>
		/// <param name="username">The Username of the user who modified the Page.</param>
		/// <param name="dateTime">The Date/Time of the modification.</param>
		/// <param name="comment">The comment of the editor, about this revision.</param>
		/// <param name="content">The Content.</param>
		/// <param name="backup">A value specifying whether or not backup the Page.</param>
		/// <returns>True if the Page has been modified successfully.</returns>
		public bool ModifyPage(PageInfo page, string title, string username, DateTime dateTime, string comment, string content, bool backup) {
			StringBuilder sb = new StringBuilder(content);
			sb.Replace("~~~~", "Ё(" + username + "," + dateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss") + ")Ё");
			content = sb.ToString();

			bool done = page.Provider.ModifyPage(page, title, username, dateTime, comment, content, backup);
			if(done) {
				// Because of transclusion, it is necessary to clear the whole cache
				//Content.Invalidate(page);
				Content.InvalidateAll();
				Log.LogEntry("Page Content updated for " + page.Name, EntryType.General, "SYSTEM");
				RecentChanges.Instance.AddChange(page.Name, title, dateTime, username, Change.PageUpdated, comment);
			}
			else Log.LogEntry("Page Content update failed for " + page.Name, EntryType.Error, "SYSTEM");

⌨️ 快捷键说明

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