Пример #1
0
        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));
            }
        }
Пример #2
0
        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));
        }
Пример #3
0
        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);
                }
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }