public static DreamMessage BuildDeletedPageContents(uint pageid) { ArchiveBE page = DbUtils.CurrentSession.Archive_GetPageHeadById(pageid); if (page == null) { throw new PageArchiveLogicNotFoundException(pageid); } //HACKHACKHACK MaxM: Copy data to a PageBE object since parser will not work on an ArchiveBE. ArchiveBE needs to go away. PageBE tempP = new PageBE(); tempP.Title = page.Title; tempP.SetText(page.Text); tempP.ContentType = page.ContentType; ParserResult parserResult = DekiXmlParser.Parse(tempP, ParserMode.VIEW_NO_EXECUTE); // TODO (steveb): this code is almost identical to the one in "GET:pages/{pageid}/contents"; consider merging // post process tail DekiXmlParser.PostProcessParserResults(parserResult); // wrap the result in a content tag and return it to the user XDoc result = new XDoc("content").Attr("type", parserResult.ContentType); foreach (XDoc entry in parserResult.Content.Elements) { if (entry.HasName("body")) { result.Start("body").Attr("target", entry["@target"].AsText).Value(entry.ToInnerXHtml()).End(); } else { result.Elem(entry.Name, entry.ToInnerXHtml()); } } // check if we hit a snag, which is indicated by a plain-text response if ((parserResult.ContentType == MimeType.TEXT.FullType) && (page.ContentType != MimeType.TEXT.FullType)) { // something happened during parsing return(new DreamMessage(DreamStatus.NonAuthoritativeInformation, null, result)); } else { return(DreamMessage.Ok(result)); } }
internal static DekiResource GetPageDiffSummary(PageBE page, string before, string beforeMime, string after, string afterMime, int maxDelta) { ParserResult beforeDoc = DekiXmlParser.Parse(page, beforeMime, page.Language, before, ParserMode.EDIT, false, -1, null, null); ParserResult afterDoc = DekiXmlParser.Parse(page, afterMime, page.Language, after, ParserMode.EDIT, false, -1, null, null); Tuplet <ArrayDiffKind, XDocDiff.Token>[] diff = XDocDiff.Diff(beforeDoc.MainBody, afterDoc.MainBody, maxDelta); if (diff == null) { return(DekiResources.PAGE_DIFF_TOO_LARGE()); } // create change summary int added; int removed; int attributes; int structural; return(GetChangeSummary(diff, out added, out removed, out attributes, out structural)); }
private static void RestorePageRevisionsForPage(ArchiveBE[] archivedRevs, Title newTitle, uint transactionId, bool minorChange, DateTime utcTimestamp) { // add the most recent archive entry to the pages table // NOTE: this will preserve the page id if it was saved with the archive or create a new page id if it is not available ArchiveBE mostRecentArchiveRev = archivedRevs[archivedRevs.Length - 1]; PageBE restoredPage = null; if (0 < archivedRevs.Length) { restoredPage = new PageBE(); restoredPage.Title = newTitle; restoredPage.Revision = mostRecentArchiveRev.Revision; restoredPage.MinorEdit = mostRecentArchiveRev.MinorEdit; bool conflict; PageBL.Save(restoredPage, null, mostRecentArchiveRev.Comment, mostRecentArchiveRev.Text, mostRecentArchiveRev.ContentType, mostRecentArchiveRev.Title.DisplayName, mostRecentArchiveRev.Language, -1, null, mostRecentArchiveRev.TimeStamp, mostRecentArchiveRev.LastPageId, false, false, null, false, out conflict); RecentChangeBL.AddRestorePageRecentChange(utcTimestamp, restoredPage, DekiContext.Current.User, DekiResources.UNDELETED_ARTICLE(restoredPage.Title.AsPrefixedUserFriendlyPath()), minorChange, transactionId); } // add all other archive entries to the old table // NOTE: this will preserve the old ids if they were saved with the archive or create new old ids if not available for (int i = 0; i < archivedRevs.Length - 1; i++) { ArchiveBE archivedRev = archivedRevs[i]; PageBE currentPage = new PageBE(); currentPage.Title = newTitle; if (i < archivedRevs.Length - 1) { ParserResult parserResult = DekiXmlParser.ParseSave(currentPage, archivedRev.ContentType, currentPage.Language, archivedRev.Text, -1, null, false, null); currentPage.SetText(parserResult.BodyText); currentPage.ContentType = parserResult.ContentType; currentPage.UserID = archivedRev.UserID; currentPage.TimeStamp = archivedRev.TimeStamp; currentPage.MinorEdit = archivedRev.MinorEdit; currentPage.Comment = archivedRev.Comment; currentPage.Language = archivedRev.Language; currentPage.IsHidden = archivedRev.IsHidden; currentPage.Revision = archivedRev.Revision; currentPage.ID = restoredPage.ID; PageBL.InsertOld(currentPage, archivedRev.OldId); } } }
internal static XDoc CreateProfilerDoc(TimeSpan elapsed, PageBE basePage, DekiContext context, IDekiDataSession session) { var profiler = new XDoc("profiler") .Attr("elapsed", elapsed.TotalSeconds.ToString("###,0.00##")) .Attr("id", context.Instance.Id) .Attr("path", basePage.Title.AsPrefixedDbPath()); var history = DekiXmlParser.GetParseState().ProfilerHistory; // show profiling for rendered pages profiler.Start("rendered-content"); foreach (var pageHistory in history) { profiler.Start("page") .Attr("wikiid", pageHistory.PageId) .Attr("path", pageHistory.PagePath) .Attr("elapsed", pageHistory.Elapsed.TotalSeconds.ToString("###,0.00##")) .Attr("mode", pageHistory.Mode.ToString().ToLowerInvariant()); foreach (var functionHistory in from function in pageHistory.Functions group function by function.Location into functionByLocation select new { Function = functionByLocation.First(), Count = functionByLocation.Count(), TotalSeconds = functionByLocation.Sum(f => f.Elapsed.TotalSeconds) } ) { profiler.Start("function") .Attr("name", functionHistory.Function.FunctionName) .Attr("elapsed", functionHistory.TotalSeconds.ToString("###,0.00##")) .Attr("count", functionHistory.Count) .Attr("location", functionHistory.Function.Location) .End(); } profiler.End(); } profiler.End(); // show summary for function profiling profiler.Start("functions-summary"); foreach (var functionHistory in from pageHistory in history from function in pageHistory.Functions group function by function.FunctionName into functionByName let totalSeconds = functionByName.Sum(f => f.Elapsed.TotalSeconds) orderby totalSeconds descending select new { Function = functionByName.First(), Count = functionByName.Count(), TotalSeconds = totalSeconds, MaxSeconds = functionByName.Max(f => f.Elapsed.TotalSeconds) } ) { profiler.Start("function") .Attr("name", functionHistory.Function.FunctionName) .Attr("elapsed", functionHistory.TotalSeconds.ToString("###,0.00##")) .Attr("average", (functionHistory.TotalSeconds / functionHistory.Count).ToString("###,0.00##")) .Attr("max", functionHistory.MaxSeconds.ToString("###,0.00##")) .Attr("count", functionHistory.Count) .End(); } profiler.End(); // show summary for page profiling profiler.Start("pages-summary"); foreach (var pageHistory in from page in history group page by page.PageId.ToString() + page.Mode into pageByIdAndMode let totalSeconds = pageByIdAndMode.Sum(p => p.Elapsed.TotalSeconds) orderby totalSeconds descending select new { Page = pageByIdAndMode.First(), Count = pageByIdAndMode.Count(), TotalSeconds = totalSeconds, MaxSeconds = pageByIdAndMode.Max(p => p.Elapsed.TotalSeconds) } ) { profiler.Start("page") .Attr("id", pageHistory.Page.PageId) .Attr("path", pageHistory.Page.PagePath) .Attr("elapsed", pageHistory.TotalSeconds.ToString("###,0.00##")) .Attr("average", (pageHistory.TotalSeconds / pageHistory.Count).ToString("###,0.00##")) .Attr("max", pageHistory.MaxSeconds.ToString("###,0.00##")) .Attr("count", pageHistory.Count) .Attr("mode", pageHistory.Page.Mode.ToString().ToLowerInvariant()) .End(); } profiler.End(); // show summary for query operations var dbprofiler = GetSessionProfiler(session); if (dbprofiler != null) { var dbhistory = dbprofiler.History; profiler.Start("db-summary") .Attr("elapsed", dbhistory.Sum(p => p.Elapsed.TotalSeconds).ToString("###,0.00##")) .Attr("count", dbhistory.Count); foreach (var dbsummary in from dbentry in dbhistory group dbentry by dbentry.Function into dbentryByName let totalSeconds = dbentryByName.Sum(f => f.Elapsed.TotalSeconds) orderby totalSeconds descending select new { Query = dbentryByName.First(), Count = dbentryByName.Count(), TotalSeconds = totalSeconds, MaxSeconds = dbentryByName.Max(f => f.Elapsed.TotalSeconds) } ) { profiler.Start("query") .Attr("name", dbsummary.Query.Function) .Attr("elapsed", dbsummary.TotalSeconds.ToString("###,0.00##")) .Attr("average", (dbsummary.TotalSeconds / dbsummary.Count).ToString("###,0.00##")) .Attr("max", dbsummary.MaxSeconds.ToString("###,0.00##")) .Attr("count", dbsummary.Count) .End(); } profiler.End(); } // add data stats Dictionary <string, string> stats; var sessionStats = session as IDekiDataStats; if (sessionStats != null) { profiler.Start("data-stats"); stats = sessionStats.GetStats(); if (stats != null) { foreach (var pair in stats) { profiler.Start("entry").Attr("name", pair.Key).Attr("value", pair.Value).End(); } } profiler.End(); } // add misc. statistics stats = DekiContext.Current.Stats; if (stats.Count > 0) { profiler.Start("misc-stats"); foreach (var pair in stats) { profiler.Start("entry").Attr("name", pair.Key).Attr("value", pair.Value).End(); } profiler.End(); } return(profiler); }
public static DekiScriptEnv CreateEnvironment(PageBE page) { DekiScriptEnv commonEnv = DekiContext.Current.Instance.CreateEnvironment(); // need to strip the config value back out for Deki commonEnv.Vars["config"] = new DekiScriptMap(); // initialize environment DekiScriptEnv env = commonEnv; DekiContext deki = DekiContext.Current; DekiInstance instance = deki.Instance; // add site variables env.Vars.AddNativeValueAt("site.name", instance.SiteName); env.Vars.AddNativeValueAt("site.hostname", deki.UiUri.Uri.HostPort); env.Vars.AddNativeValueAt("site.api", deki.ApiUri.SchemeHostPortPath); env.Vars.AddNativeValueAt("site.language", instance.SiteLanguage); env.Vars.AddNativeValueAt("site.uri", deki.UiUri.Uri.ToString()); env.Vars.AddNativeValueAt("site.pagecount", deki.Deki.PropertyAt("$sitepagecount")); env.Vars.AddNativeValueAt("site.usercount", deki.Deki.PropertyAt("$siteusercount")); env.Vars.AddNativeValueAt("site.homepage", deki.Deki.PropertyAt("$page", DekiContext.Current.Instance.HomePageId, true)); env.Vars.AddNativeValueAt("site.feed", deki.ApiUri.At("site", "feed").ToString()); env.Vars.AddNativeValueAt("site.tags", deki.Deki.PropertyAt("$sitetags")); env.Vars.AddNativeValueAt("site.users", deki.Deki.PropertyAt("$siteusers")); env.Vars.AddNativeValueAt("site.id", DekiScriptExpression.Constant(instance.Id)); env.Vars.AddNativeValueAt("site.timezone", DekiScriptExpression.Constant(instance.SiteTimezone)); // add page variables env.Vars.Add("page", deki.Deki.PropertyAt("$page", page.ID, true)); // add user variables env.Vars.Add("user", deki.Deki.PropertyAt("$user", (deki.User != null) ? deki.User.ID : 0)); // add instance functions & properties bool hasUnsafeContentPermission = DekiXmlParser.PageAuthorCanExecute(); foreach (var service in instance.RunningServices.ExtensionServices) { if (service != null) { var extension = service.Extension; if (extension != null) { if (hasUnsafeContentPermission || !extension.IsProtected) { var functions = extension.Functions; if (functions != null) { foreach (var function in functions) { env.Vars.AddNativeValueAt(function.Name.ToLowerInvariant(), function.Uri); } } else { _log.WarnFormat("CreateEnvironment - null functions (id: {0})", service.ServiceId); } } } else { _log.WarnFormat("CreateEnvironment - null extension (id: {0})", service.ServiceId); } } else { _log.Warn("CreateEnvironment - null service"); } } return(env); }