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()))); }
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(); } }
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); }