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

📄 pagesstorageprovider.cs

📁 YetAnotherForum.Net+ScrewTurnWiki中文完美汉化增强版
💻 CS
📖 第 1 页 / 共 3 页
字号:
		public PageInfo RenamePage(PageInfo page, string newName) {
			if(PageExists(new PageInfo(newName, this, PageStatus.Normal, DateTime.Now))) return null;

			lock(locker) {
				PageInfo[] pages = AllPages;
				bool found = false;
				int idx = -1;
				PageNameComparer comp = new PageNameComparer();
				CategoryInfo[] tmp = Pages.Instance.GetCategoriesPerPage(page);
				string[] cats = new string[tmp.Length];
				for(int i = 0; i < tmp.Length; i++) {
					cats[i] = tmp[i].Name;
				}
				for(int i = 0; i < pages.Length; i++) {
					if(comp.Compare(pages[i], page) == 0) {
						pages[i].Name = newName;
						File.Copy(Settings.PagesDirectory + ((LocalPageInfo)pages[i]).File,
							Settings.PagesDirectory + newName + Path.GetExtension(((LocalPageInfo)pages[i]).File));
						File.Delete(Settings.PagesDirectory + ((LocalPageInfo)pages[i]).File);
						((LocalPageInfo)pages[i]).File = newName + Path.GetExtension(((LocalPageInfo)pages[i]).File);
						found = true;
						idx = i;
						break;
					}
				}
				if(found) {
					DumpPages(pages);
					RenameBackups(page, newName);
					Rebind(pages[idx], cats);
					return pages[idx];
				}
				else return null;
			}
		}

		private void RenameBackups(PageInfo page, string newName) {
			List<int> backups = GetBackups(page);
			LocalPageInfo pg = (LocalPageInfo)page;
			for(int i = 0; i < backups.Count; i++) {
				File.Copy(Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(backups[i]).ToString() + Path.GetExtension(pg.File),
					Settings.PagesDirectory + newName + "." + Tools.GetVersionString(backups[i]).ToString() + Path.GetExtension(pg.File), false);
				File.Delete(Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(backups[i]).ToString() + Path.GetExtension(pg.File));
			}
		}

		/// <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 PageInfo SetStatus(PageInfo page, PageStatus status) {
			lock(locker) {
				PageInfo[] pages = AllPages;
				PageNameComparer comp = new PageNameComparer();
				for(int i = 0; i < pages.Length; i++) {
					if(comp.Compare(pages[i], page) == 0) {
						PageInfo tmp = new LocalPageInfo(page.Name, this, status, page.CreationDateTime, ((LocalPageInfo)page).File);
						pages[i] = tmp;
						DumpPages(pages);
						return tmp;
					}
				}
			}
			return null;
		}

		/// <summary>
		/// Modifies the Content of a Page.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <param name="title">The Title of the Page.</param>
		/// <param name="username">The Username.</param>
		/// <param name="dateTime">The Date/Time.</param>
		/// <param name="comment">The comment of the editor, about this revision.</param>
		/// <param name="content">The Page Content.</param>
		/// <param name="backup">A value specifying whether or not to create a backup of 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) {
			if(!PageExists(page)) return false;

			if(backup) Backup(page);

			StringBuilder sb = new StringBuilder();
			sb.Append(title);
			sb.Append("\r\n");
			sb.Append(username);
			sb.Append("|");
			sb.Append(dateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
			if(comment.Length > 0) {
				sb.Append("|");
				sb.Append(Tools.EscapeString(comment));
			}
			sb.Append("\r\n##PAGE##\r\n");
			sb.Append(content);

			Tools.WriteFile(Settings.PagesDirectory + ((LocalPageInfo)page).File, sb.ToString());
			return true;
		}

		/// <summary>
		/// Performs the rollback of a Page to a specified revision.
		/// </summary>
		/// <param name="page">The Page to rollback.</param>
		/// <param name="revision">The Revision to rollback the Page to.</param>
		/// <returns>True if the roolback succeeded.</returns>
		/// <remarks>All the newer backups are deleted.</remarks>
		public bool RollbackPage(PageInfo page, int revision) {
			if(!PageExists(page)) return false;

			List<int> backups = GetBackups(page);
			if(!backups.Contains(revision)) return false;

			// Operations
			// - Copy the content of the specified revision into the page file
			// - Delete specified revision and all the newer revisions
			
			LocalPageInfo pg = (LocalPageInfo)page;
			File.Copy(Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(revision) + Path.GetExtension(pg.File),
				Settings.PagesDirectory + pg.File, true);

			int idx = backups.IndexOf(revision);

			for(int i = backups.Count - 1; i >= idx; i--) {
				File.Delete(Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(backups[i]) + Path.GetExtension(pg.File));
			}

			return true;
		}

		/// <summary>
		/// Deletes the Backups of a Page, up to a specified revision.
		/// </summary>
		/// <param name="page">The Page to delete the backups of.</param>
		/// <param name="revision">The newest revision to delete (newer revision are kept) or -1 to delete all the Backups.</param>
		/// <returns>True if the deletion succeeded.</returns>
		public bool DeleteBackups(PageInfo page, int revision) {
			lock(locker) {
				List<int> backups = GetBackups(page);
				if(backups.Count == 0) return true;

				int idx = (revision != -1 ? backups.IndexOf(revision) : backups[backups.Count - 1]);

				// Operations
				// - Delete old beckups, from 0 to revision
				// - Rename newer backups starting from 0

				LocalPageInfo pg = (LocalPageInfo)page;

				for(int i = 0; i <= idx; i++) {
					File.Delete(Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(backups[i]) + Path.GetExtension(pg.File));
				}

				if(revision != -1) {
					for(int i = revision + 1; i < backups.Count; i++) {
						File.Copy(Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(backups[i]) + Path.GetExtension(pg.File),
							Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(backups[i] - revision - 1) + Path.GetExtension(pg.File));
						File.Delete(Settings.PagesDirectory + Path.GetFileNameWithoutExtension(pg.File) + "." + Tools.GetVersionString(backups[i]) + Path.GetExtension(pg.File));
					}
				}
			}
			return true;
		}

		/// <summary>
		/// Removes a Page.
		/// </summary>
		/// <param name="page">The Page to remove.</param>
		/// <returns>True if the Page has been removed successfully.</returns>
		public bool RemovePage(PageInfo page) {
			lock(locker) {
				List<PageInfo> pages = new List<PageInfo>(AllPages);
				PageNameComparer comp = new PageNameComparer();
				for(int i = 0; i < pages.Count; i++) {
					if(comp.Compare(pages[i], page) == 0) {
						pages.Remove(pages[i]);
						DumpPages(pages.ToArray());
						DeleteBackups(page, -1);
						try {
							File.Delete(Settings.PagesDirectory + ((LocalPageInfo)page).File);
							File.Delete(Settings.MessagesDirectory + ((LocalPageInfo)page).File);
						}
						catch { }
						return true;
					}
				}
			}
			return false;
		}

		/// <summary>
		/// Binds a Page with one or more Categories.
		/// </summary>
		/// <param name="page">The Page to bind.</param>
		/// <param name="categories">The Categories to bind the Page with.</param>
		/// <returns>True if the binding succeeded.</returns>
		/// <remarks>After a successful operation, the Page is binded with all and only the categories passed as argument.</remarks>
		public bool Rebind(PageInfo page, string[] categories) {
			lock(locker) {
				if(!PageExists(page)) return false;

				CategoryInfo[] cats = AllCategories;

				// Operations:
				// - Remove the Page from every Category
				// - For each specified category, add (if needed) the Page
				List<string> pages;
				CategoryNameComparer catComp = new CategoryNameComparer();
				for(int i = 0; i < cats.Length; i++) {
					pages = new List<string>(cats[i].Pages);
					int idx = Contains(pages, page.Name);
					if(idx != -1) pages.Remove(pages[idx]);
					cats[i].Pages = pages.ToArray();
				}
				for(int i = 0; i < cats.Length; i++) {
					for(int k = 0; k < categories.Length; k++) {
						if(catComp.Compare(cats[i], new CategoryInfo(categories[k], this)) == 0) {
							pages = new List<string>(cats[i].Pages);
							pages.Add(page.Name);
							cats[i].Pages = pages.ToArray();
						}
					}
				}
				DumpCategories(cats);
			}
			return true;
		}

		private int Contains(List<string> pages, string page) {
			PageNameComparer comp = new PageNameComparer();
			for(int i = 0; i < pages.Count; i++) {
				if(pages[i].ToLower().Equals(page.ToLower())) return i;
			}
			return -1;
		}

		private void DumpPages(PageInfo[] pages) {
			StringBuilder sb = new StringBuilder();
			for(int i = 0; i < pages.Length; i++) {
				sb.Append(pages[i].Name);
				sb.Append("|");
				sb.Append(((LocalPageInfo)pages[i]).File);
				switch(pages[i].Status) {
					case PageStatus.Normal:
						sb.Append("|NORMAL");
						break;
					case PageStatus.Locked:
						sb.Append("|LOCKED");
						break;
					case PageStatus.Public:
						sb.Append("|PUBLIC");
						break;
				}
				sb.Append("|");
				sb.Append(pages[i].CreationDateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
				if(i != pages.Length - 1) sb.Append("\r\n");
			}
			Tools.WriteFile(Settings.PagesFile, sb.ToString());
		}

		private void DumpCategories(CategoryInfo[] categories) {
			StringBuilder sb = new StringBuilder();
			for(int i = 0; i < categories.Length; i++) {
				sb.Append(categories[i].Name);
				if(categories[i].Pages.Length > 0) {
					for(int k = 0; k < categories[i].Pages.Length; k++) {
						sb.Append("|");
						sb.Append(categories[i].Pages[k]);
					}
				}
				sb.Append("\r\n");
			}
			Tools.WriteFile(Settings.CategoriesFile, sb.ToString());
		}

		/// <summary>
		/// Gets the Page Messages.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <returns>The list of the <b>first-level</b> Messages, containing the replies properly nested.</returns>
		public Message[] GetMessages(PageInfo page) {
			LocalPageInfo pg = (LocalPageInfo)page;

			// Shortcut
			if(!File.Exists(Settings.MessagesDirectory + pg.File)) return new Message[0];

			string data;
			lock(lockerDisc) {
				data = Tools.LoadFile(Settings.MessagesDirectory + pg.File).Replace("\r", "");
			}

			string[] lines = data.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

			List<Message> result = new List<Message>();

			// Structure
			// ID|Username|Subject|DateTime|ParentID|Body

			// This algorithm DOES not handle replies that are stored BEFORE their parent,
			// so every reply MUST be stored anywhere but AFTER its parent
			// (the message tree should be stored depht-first; new messages can be appended at the end of the file)

			string[] fields;
			int id, parent;
			string username, subject, body;
			DateTime dateTime;
			for(int i = 0; i < lines.Length; i++) {
				fields = lines[i].Split('|');
				id = int.Parse(fields[0]);
				username = fields[1];
				subject = Tools.UnescapeString(fields[2]);
				dateTime = DateTime.Parse(fields[3]);
				parent = int.Parse(fields[4]);
				body = Tools.UnescapeString(fields[5]);
				if(parent != -1) {
					// Find parent
					Message p = FindMessage(result, parent);
					if(p == null) {
						// Add as top-level message
						result.Add(new Message(id, username, subject, dateTime, body));
					}
					else {
						// Add to parent's replies
						p.Replies.Add(new Message(id, username, subject, dateTime, body));
					}
				}
				else {
					// Add as top-level message
					result.Add(new Message(id, username, subject, dateTime, body));
				}
			}

			return result.ToArray();
		}

		/// <summary>
		/// Gets the total number of Messages in a Page Discussion.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <returns>The number of messages.</returns>
		public int GetMessageCount(PageInfo page) {
			LocalPageInfo pg = (LocalPageInfo)page;
			if(!File.Exists(Settings.MessagesDirectory + pg.File)) return 0;
			string data = Tools.LoadFile(Settings.MessagesDirectory + pg.File).Replace("\r", "");
			return data.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Length;
		}

		/// <summary>
		/// Finds a Message in a Message tree.
		/// </summary>
		/// <param name="messages">The Message tree.</param>
		/// <param name="id">The ID of the Message to find.</param>
		/// <returns>The Message or null.</returns>
		/// <remarks>The method is recursive.</remarks>
		private Message FindMessage(List<Message> messages, int id) {
			Message result = null;
			for(int i = 0; i < messages.Count; i++) {
				if(messages[i].ID == id) {
					result = messages[i];
				}
				if(result == null) {
					result = FindMessage(messages[i].Replies, id);
				}
				if(result != null) break;
			}
			return result;
		}

		/// <summary>
		/// Adds a new Message to a Page.

⌨️ 快捷键说明

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