예제 #1
0
        private IEnumerable <WikiPage> GetStoryLinksPageList(WikiSite site, string pageTitle)
        {
            var targetPage = new WikiPage(site, pageTitle);

            targetPage.RefreshAsync(PageQueryOptions.FetchContent | PageQueryOptions.ResolveRedirects).Wait(); //Load page content

            //Get page text
            var parser       = new WikitextParser();
            var wikiPageText = parser.Parse(targetPage.Content);

            IEnumerable <Template> templateList = new List <Template>();
            var header = wikiPageText.Lines.SelectMany(x => x.EnumDescendants().OfType <Heading>()).Where(y => HeadersToSearch.Contains(y.ToPlainText())).SingleOrDefault();

            if (header != null)
            {
                templateList = header.EnumDescendants().OfType <Template>();
            }
            else
            {
                templateList = wikiPageText.EnumDescendants().OfType <Template>();
            }
            var storyLinkTemplates = templateList.Where(template => template.Name.Equals("storylink"));

            return(storyLinkTemplates.Select(template => new WikiPage(site, template.Arguments.Single().Value.ToPlainText())));
        }
예제 #2
0
        public override void Execute()
        {
            SetJobStart();
            List <WikiPage> AlreadyUpdatedPages = new List <WikiPage>();
            List <WikiPage> NoUpdateNeededPages = new List <WikiPage>();

            try
            {
                using (var client = new WikiClient())
                {
                    var site           = _wikiAccessLogic.GetLoggedInWikiSite(WikiConfig, client, Log);
                    var parser         = new WikitextParser();
                    var wikiText       = parser.Parse(FromText);
                    var fromLinkTarget = wikiText.Lines.SelectMany(x => x.EnumDescendants().OfType <WikiLink>()).FirstOrDefault().Target.ToPlainText();
                    wikiText = parser.Parse(ToText);
                    var toLinkTarget = wikiText.Lines.SelectMany(x => x.EnumDescendants().OfType <WikiLink>()).FirstOrDefault().Target.ToPlainText();

                    var PageList          = GetBackLinksPageList(site, fromLinkTarget);
                    var storyLinkPageList = GetStoryLinksPageList(site, toLinkTarget);

                    //string filename = "";
                    //string diff = "";
                    //string filePath = "";
                    var folderName = Request.ID.ToString();
                    var folderPath = Path.Combine(Configuration["DiffDirectory"], folderName);
                    if (!Directory.Exists(folderPath))
                    {
                        Directory.CreateDirectory(folderPath);
                    }

                    foreach (WikiPage page in PageList)
                    {
                        Log.Information("Processing page {PageName}", page.Title);

                        IEnumerable <WikiLink> wikiLinks = null;

                        page.RefreshAsync(PageQueryOptions.FetchContent | PageQueryOptions.ResolveRedirects).Wait(); //Load page content

                        //Get page text
                        var beforeContent = page.Content;
                        var wikiPageText  = parser.Parse(beforeContent);

                        if (string.IsNullOrWhiteSpace(string.Join(' ', HeadersToSearch)))
                        {
                            throw new Exception("No continuity header specified");
                        }
                        else
                        {
                            //Get any wiki links under the header
                            var headers         = wikiPageText.EnumDescendants().OfType <Heading>();
                            var matchingHeaders = headers.Where(y => HeadersToSearch.Contains(y.ToPlainText()) || HeadersToSearch.Contains(y.ToString()));
                            //Need to handle cases like Armada Megatron where links are on cartoon/comic/whatever subpage. Look for subpage header based on media type, get subpage, add to Pages list and get links.
                            if (matchingHeaders.Any())
                            {
                                var contentNodes = GetContentBetweenHeaders(headers, matchingHeaders, wikiPageText);
                                wikiLinks = contentNodes.SelectMany(x => x.EnumDescendants().OfType <WikiLink>());
                            }
                            else
                            {
                                var templates = wikiPageText.Lines.SelectMany(x => x.EnumDescendants().OfType <Template>());

                                var mediaTemplate = templates.Where(template => template.Name.ToPlainText().Equals(GetTemplateNameByMedia(Media))).SingleOrDefault();

                                if (mediaTemplate != null || HasFileTemplateForMedia(templates, Media))
                                {
                                    wikiLinks = wikiPageText.Lines.SelectMany(x => x.EnumDescendants().OfType <WikiLink>());
                                }
                                else
                                {
                                    var mainTemplates = templates.Where(template => template.Name.ToPlainText().Equals("main"));
                                    if (mainTemplates.Any())
                                    {
                                        wikiLinks = GetMainTemplatePageLinks(mainTemplates, site);
                                    }
                                }
                            }
                        }
                        var matchingLinks = wikiLinks?.Where(link => CompareLinks(link.Target.ToString(), fromLinkTarget)).ToList();

                        if (matchingLinks == null || !matchingLinks.Any() || page.Title.Equals(Configuration["WikiRequestPage"], StringComparison.OrdinalIgnoreCase))
                        {
                            Request.Pages.RemoveAll(x => x.Name.Equals(page.Title, StringComparison.OrdinalIgnoreCase));
                            if (wikiLinks?.Where(link => CompareLinks(link.Target.ToString(), toLinkTarget)).Any() ?? false)
                            {
                                AlreadyUpdatedPages.Add(page);
                            }
                            else
                            {
                                NoUpdateNeededPages.Add(page);
                            }
                        }
                        else
                        {
                            foreach (WikiLink link in matchingLinks)
                            {
                                Log.Debug($"Link target starts: {link.Target}");
                                var newTarget = parser.Parse(ToText).Lines.SelectMany(x => x.EnumDescendants().OfType <WikiLink>()).FirstOrDefault().Target.ToPlainText();
                                if (link.Text == null)
                                {
                                    link.Text = new Run(new PlainText(link.Target.ToPlainText())); //Maintain original link text if the link had no custom text
                                }
                                link.Target = new Run(new PlainText(newTarget));
                                Log.Debug($"Link target ends: {link.Target}");
                            }
                            Log.Debug($"Content after: {wikiPageText}");


                            var afterContent = wikiPageText.ToString();

                            if (Request.Status != JobStatus.Approved) //Create diffs for approval
                            {
                                Log.Information("Generating diff for page {PageName}", page.Title);

                                Utilities.GenerateAndSaveDiff(beforeContent, afterContent, page.Title, Request.ID, Configuration["DiffDirectory"], folderName);

                                JobData.SaveWikiJobRequest(Request); //Save page list
                            }
                            else //Apply changes
                            {
                                Log.Information("Applying replacement for page {PageName}", page.Title);
                                var editMessage = $"{WikiConfig["Username"]} Text Replacement {FromText} => {ToText}";
                                ((TFWikiJobRetriever)Retriever).UpdatePageContent(afterContent, editMessage, page).Wait();
                            }
                        }

                        Thread.Sleep(1000 * _throttleSpeedInSeconds);
                    }
                }
                Thread.Sleep(1000);
            }
            catch (Exception ex)
            {
                Request.Status = JobStatus.Failed;
                Log.Error(ex, $"TextReplacementJob with ID: {Request.ID} failed.");
            }
            finally
            {
                SetJobEnd();
                SaveRequest();
            }
        }
예제 #3
0
        private IEnumerable <WikiLink> GetMainTemplatePageLinks(IEnumerable <Template> mainTemplates, WikiSite site)
        {
            Wikitext pageText = null;
            IEnumerable <WikiLink> wikiLinks = new List <WikiLink>();

            foreach (Template template in mainTemplates)
            {
                var linkedPage = new WikiPage(site, template.Arguments.First().ToString());
                Log.Information("Processing page {PageName}", linkedPage.Title);
                linkedPage.RefreshAsync(PageQueryOptions.FetchContent | PageQueryOptions.ResolveRedirects).Wait();
                if (linkedPage.Exists)
                {
                    pageText = new WikitextParser().Parse(linkedPage.Content);
                    var matchingPageHeaders = pageText.EnumDescendants().OfType <Heading>().Where(y => HeadersToSearch.Contains(y.ToPlainText()) || HeadersToSearch.Contains(y.ToString()));

                    if (matchingPageHeaders.Any())
                    {
                        wikiLinks = pageText.Lines.SelectMany(x => x.EnumDescendants().OfType <WikiLink>());
                        break;
                    }
                }
            }
            return(wikiLinks);
        }