/// <summary> /// Verifies the need for a data upgrade, and performs it when needed. /// </summary> private void VerifyAndPerformUpgradeForPages() { // Load file lines // Parse first line (if any) with old (v2) algorithm // If parsing is successful, then the file must be converted // Conversion consists in removing the 'Status' field and properly modifying permissions of pages host.LogEntry("Upgrading pages format from 2.0 to 3.0", LogEntryType.General, null, this); //string[] lines = File.ReadAllLines(GetFullPath(PagesFile)); string[] lines = File.ReadAllText(GetFullPath(PagesFile)).Replace("\r", "").Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); if(lines.Length > 0) { LocalPageInfo[] pages = new LocalPageInfo[lines.Length]; char[] oldStylePermissions = new char[lines.Length]; char[] splitter = new char[] { '|' }; for(int i = 0; i < lines.Length; i++) { string[] fields = lines[i].Split(splitter, StringSplitOptions.RemoveEmptyEntries); // Structure in version 1.0 // PageName|PageFile // Structure in version 2.0 // PageName|PageFile|Status|DateTime // Use default values (status and date/time were not available in earlier versions) DateTime creationDateTime = new DateTime(2000, 1, 1); // Default to Normal oldStylePermissions[i] = 'N'; if(fields.Length == 2) { // Version 1.0 // Use the Date/Time of the file FileInfo fi = new FileInfo(GetFullPathForPageContent(fields[1])); creationDateTime = fi.CreationTime; } if(fields.Length >= 3) { // Might be version 2.0 switch(fields[2].ToLowerInvariant()) { case "locked": oldStylePermissions[i] = 'L'; break; case "public": oldStylePermissions[i] = 'P'; break; case "normal": oldStylePermissions[i] = 'N'; break; default: try { // If this succeeded, then it's Version 3.0, not 2.0 (at least for this line) creationDateTime = DateTime.Parse(fields[2]); } catch { // Use the Date/Time of the file FileInfo fi = new FileInfo(GetFullPathForPageContent(fields[1])); creationDateTime = fi.CreationTime; } break; } if(fields.Length == 4) { // Version 2.0 creationDateTime = DateTime.Parse(fields[3]); } } pages[i] = new LocalPageInfo(fields[0], this, creationDateTime, fields[1]); pages[i].FullName = pages[i].FullName.Replace(".", "_"); // TODO: host.UpdateContentForPageRename(oldName, newName); } // Setup permissions for single pages for(int i = 0; i < oldStylePermissions.Length; i++) { if(oldStylePermissions[i] != 'N') { // Need to set permissions emulating old-style behavior host.UpgradePageStatusToAcl(pages[i], oldStylePermissions[i]); } } string backupFile = GetFullPath(Path.GetFileNameWithoutExtension(PagesFile) + "_v2" + Path.GetExtension(PagesFile)); File.Copy(GetFullPath(PagesFile), backupFile); // Re-dump pages so that old format data is discarded DumpPages(pages); } }
/// <summary> /// Find a free Message ID for a Page. /// </summary> /// <param name="page">The Page.</param> /// <returns>The Message ID.</returns> private int GetFreeMessageID(LocalPageInfo page) { lock(this) { if(!File.Exists(GetFullPathForMessages(page.File))) return 0; int result = 0; string data = File.ReadAllText(GetFullPathForMessages(page.File)).Replace("\r", ""); string[] lines = data.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); int idx, tmp; for(int i = 0; i < lines.Length; i++) { idx = lines[i].IndexOf('|'); tmp = int.Parse(lines[i].Substring(0, idx)); if(tmp > result) result = tmp; } result++; return result; } }
/// <summary> /// Adds a Page. /// </summary> /// <param name="nspace">The target namespace (<c>null</c> for the root).</param> /// <param name="name">The Page Name.</param> /// <param name="creationDateTime">The creation Date/Time.</param> /// <returns>The correct PageInfo object or null.</returns> /// <remarks>This method should <b>not</b> create the content of the Page.</remarks> /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="name"/> is empty.</exception> public PageInfo AddPage(string nspace, string name, DateTime creationDateTime) { if(name == null) throw new ArgumentNullException("name"); if(name.Length == 0) throw new ArgumentException("Name cannot be empty", "name"); lock(this) { if(!NamespaceExists(nspace)) return null; if(PageExists(new PageInfo(NameTools.GetFullName(nspace, name), this, DateTime.Now))) return null; LocalPageInfo result = new LocalPageInfo(NameTools.GetFullName(nspace, name), this, creationDateTime, GetNamespacePartialPathForPageContent(nspace) + name + ".cs"); BackupPagesFile(); // Structure // Namespace.Page|File|CreationDateTime File.AppendAllText(GetFullPath(PagesFile), result.FullName + "|" + result.File + "|" + creationDateTime.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss") + "\r\n"); //File.Create(GetFullPathForPageContent(result.File)).Close(); // Empty content file might cause problems with backups File.WriteAllText(GetFullPathForPageContent(result.File), "--\r\n--|1900/01/01 0:00:00|\r\n##PAGE##\r\n--"); pagesCache = null; return result; } }
private string GetDraftFullPath(LocalPageInfo page) { /*return GetFullPathForPageDrafts(GetNamespacePartialPathForPageContent(NameTools.GetNamespace(page.FullName)) + page.File);*/ return GetFullPathForPageDrafts(page.File); }