public static void AddOtherReplaces(HTMLParser htmlParser, string pageURL, List <ReplaceInfo> replaceList) { HashSet <int> existingOffsets = new HashSet <int>(); foreach (ReplaceInfo replace in replaceList) { existingOffsets.Add(replace.Offset); } if (Environment.NewLine != "\n") { int offset = 0; while ((offset = htmlParser.PreprocessedHTML.IndexOf('\n', offset)) != -1) { replaceList.Add(new ReplaceInfo { Offset = offset, Length = 1, Type = ReplaceType.Other, Value = Environment.NewLine }); offset += 1; } } foreach (HTMLTag tag in htmlParser.FindStartTags("base")) { replaceList.Add( new ReplaceInfo { Offset = tag.Offset, Length = tag.Length, Type = ReplaceType.Other, Value = String.Empty }); } foreach (HTMLTag tag in htmlParser.FindStartTags("a", "img", "script", "link")) { bool isATag = tag.NameEquals("a"); bool isImgTag = tag.NameEquals("img"); bool isScriptTag = tag.NameEquals("script"); bool isLinkTag = tag.NameEquals("link"); bool usesHRefAttr = isATag || isLinkTag; bool usesSrcAttr = isImgTag || isScriptTag; if (usesHRefAttr || usesSrcAttr) { HTMLAttribute attribute = tag.GetAttribute(usesHRefAttr ? "href" : usesSrcAttr ? "src" : null); if (attribute != null && !existingOffsets.Contains(attribute.Offset)) { // Make attribute's URL absolute string newURL = GetAbsoluteURL(pageURL, HttpUtility.HtmlDecode(attribute.Value)); // For links to anchors on the current page, use just the fragment if (isATag && newURL != null && newURL.Length > pageURL.Length && newURL.StartsWith(pageURL, StringComparison.Ordinal) && newURL[pageURL.Length] == '#') { newURL = newURL.Substring(pageURL.Length); } if (newURL != null) { replaceList.Add( new ReplaceInfo { Offset = attribute.Offset, Length = attribute.Length, Type = ReplaceType.Other, Value = attribute.Name + "=\"" + HttpUtility.HtmlAttributeEncode(newURL) + "\"" }); } } } } }
private void CheckForUpdateThread() { string html; try { html = General.DownloadPageToString(General.ProgramURL); } catch { return; } Settings.LastUpdateCheck = DateTime.Now.Date; var htmlParser = new HTMLParser(html); HTMLTagRange labelLatestDivTagRange = htmlParser.CreateTagRange(Enumerable.FirstOrDefault(Enumerable.Where( htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "label-latest")))); if (labelLatestDivTagRange == null) return; HTMLTagRange versionSpanTagRange = htmlParser.CreateTagRange(Enumerable.FirstOrDefault(Enumerable.Where( htmlParser.FindStartTags(labelLatestDivTagRange, "span"), t => HTMLParser.ClassAttributeValueHas(t, "css-truncate-target")))); if (versionSpanTagRange == null) return; string latestStr = htmlParser.GetInnerHTML(versionSpanTagRange).Replace("v", ""); int latest = ParseVersionNumber(latestStr); if (latest == -1) return; int current = ParseVersionNumber(General.Version); if (!String.IsNullOrEmpty(Settings.LatestUpdateVersion)) { current = Math.Max(current, ParseVersionNumber(Settings.LatestUpdateVersion)); } if (latest > current) { lock (_startupPromptSync) { if (IsDisposed) return; Settings.LatestUpdateVersion = latestStr; Invoke(() => { if (MessageBox.Show(this, "A newer version of Chan Thread Watch is available. Would you like to open the Chan Thread Watch website?", "Newer Version Found", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { Process.Start(General.ProgramURL); } }); } } }
public static string GetRedirectUrl(string html, string currentPage) { try { HTMLParser parser = new HTMLParser(html); foreach (HTMLTag metaTag in parser.FindStartTags(parser.CreateTagRange(parser.FindStartTag("head")), "meta")) { if (!string.Equals(metaTag.GetAttributeValueOrEmpty("http-equiv"), "Refresh", StringComparison.OrdinalIgnoreCase)) { continue; } string metaContent = metaTag.GetAttributeValueOrEmpty("Content"); if (string.IsNullOrEmpty(metaContent)) { continue; } int currentPosition = 0; currentPosition = GetNextNonWhiteSpaceCharacterPosition(metaContent, currentPosition); StringBuilder timeString = new StringBuilder(); while (metaContent.Length > currentPosition && (metaContent[currentPosition] >= 48 && metaContent[currentPosition] <= 57 || metaContent[currentPosition] == 46)) { timeString.Append(metaContent[currentPosition++]); } int time; int.TryParse(timeString.ToString(), out time); if (time < 0) { return(null); } currentPosition = GetNextNonWhiteSpaceCharacterPosition(metaContent, currentPosition); if (!IsCharacterMatch(metaContent[currentPosition++], '\u003B')) { return(null); } currentPosition = GetNextNonWhiteSpaceCharacterPosition(metaContent, currentPosition); if (!IsCharacterMatch(metaContent[currentPosition++], '\u0055')) { return(null); } if (!IsCharacterMatch(metaContent[currentPosition++], '\u0052')) { return(null); } if (!IsCharacterMatch(metaContent[currentPosition++], '\u004C')) { return(null); } currentPosition = GetNextNonWhiteSpaceCharacterPosition(metaContent, currentPosition); if (!IsCharacterMatch(metaContent[currentPosition++], '\u003D')) { return(null); } currentPosition = GetNextNonWhiteSpaceCharacterPosition(metaContent, currentPosition); char quote = new char(); if (IsCharacterMatch(metaContent[currentPosition], '\u0027') || IsCharacterMatch(metaContent[currentPosition], '\u0022')) { quote = metaContent[currentPosition++]; } string redirectUrl = metaContent.Substring(currentPosition); if (!string.IsNullOrEmpty(quote.ToString())) { redirectUrl = redirectUrl.TrimEnd(quote); } redirectUrl = redirectUrl.TrimEnd('\u0020', '\u0009', '\u000A', '\u000C', '\u000D'); redirectUrl = redirectUrl.Replace('\u0009', '\0').Replace('\u000A', '\0').Replace('\u000D', '\0'); redirectUrl = GetAbsoluteURL(currentPage, redirectUrl); return(redirectUrl); } return(null); } catch { return(null); } }
public override void ResurrectDeadPosts(HTMLParser previousParser) { if (previousParser == null) return; List<ReplaceInfo> replaceList = new List<ReplaceInfo>(); Dictionary<string, HTMLTagRange> newPostContainers = new Dictionary<string, HTMLTagRange>(); foreach (HTMLTagRange postContainerTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(_htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "postContainer")), t => _htmlParser.CreateTagRange(t)), r => r != null)) { newPostContainers.Add(postContainerTagRange.StartTag.GetAttributeValue("id"), postContainerTagRange); } HTMLTagRange lastExistingPostContainerTagRange = null; foreach (HTMLTagRange previousPostContainerTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(previousParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "postContainer")), t => previousParser.CreateTagRange(t)), r => r != null)) { HTMLTagRange tempTagRange; if (!newPostContainers.TryGetValue(previousPostContainerTagRange.StartTag.GetAttributeValue("id"), out tempTagRange)) { int offset = lastExistingPostContainerTagRange != null ? lastExistingPostContainerTagRange.EndOffset : Enumerable.FirstOrDefault(Enumerable.Where(_htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "thread"))).EndOffset; replaceList.Add( new ReplaceInfo { Offset = offset, Length = previousPostContainerTagRange.Length, Type = ReplaceType.DeadPost, Tag = previousPostContainerTagRange.StartTag.GetAttributeValue("id"), Value = previousParser.GetHTML(previousPostContainerTagRange) }); } else { lastExistingPostContainerTagRange = tempTagRange; } } StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { General.WriteReplacedString(_htmlParser.PreprocessedHTML, replaceList, sw); } _htmlParser = new HTMLParser(sb.ToString()); }
public void SetHTMLParser(HTMLParser htmlParser) { _htmlParser = htmlParser; }
public virtual void ResurrectDeadPosts(HTMLParser previousParser) { }
public override void ResurrectDeadPosts(HTMLParser previousParser, List<ReplaceInfo> replaceList) { if (previousParser == null) return; List<ReplaceInfo> tempReplaceList = new List<ReplaceInfo>(); Dictionary<string, HTMLTagRange> newPostContainers = new Dictionary<string, HTMLTagRange>(); Dictionary<string, HTMLTagRange> resurrectedPostContainers = new Dictionary<string, HTMLTagRange>(); foreach (HTMLTagRange postContainerTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(_htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "postContainer")), t => _htmlParser.CreateTagRange(t)), r => r != null)) { newPostContainers.Add(postContainerTagRange.StartTag.GetAttributeValue("id"), postContainerTagRange); } HTMLTagRange lastExistingPostContainerTagRange = null; foreach (HTMLTagRange previousPostContainerTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(previousParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "postContainer")), t => previousParser.CreateTagRange(t)), r => r != null)) { HTMLTagRange tempTagRange; if (!newPostContainers.TryGetValue(previousPostContainerTagRange.StartTag.GetAttributeValue("id"), out tempTagRange)) { int offset = lastExistingPostContainerTagRange != null ? lastExistingPostContainerTagRange.EndOffset : Enumerable.FirstOrDefault(Enumerable.Where(_htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "thread"))).EndOffset; HTMLTag inputTag = previousParser.FindTag(false, previousPostContainerTagRange, "input"); string value = previousParser.GetHTML(previousPostContainerTagRange); if (!value.Contains("<strong style=\"color: #FF0000\">[Deleted]</strong>")) { value = value.Insert(inputTag.EndOffset - previousPostContainerTagRange.Offset, "<strong style=\"color: #FF0000\">[Deleted]</strong>"); } tempReplaceList.Add( new ReplaceInfo { Offset = offset, Length = 0, Type = ReplaceType.DeadPost, Tag = previousPostContainerTagRange.StartTag.GetAttributeValue("id"), Value = value }); resurrectedPostContainers.Add(previousPostContainerTagRange.StartTag.GetAttributeValue("id"), previousPostContainerTagRange); } else { lastExistingPostContainerTagRange = tempTagRange; } } StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { General.WriteReplacedString(_htmlParser.PreprocessedHTML, tempReplaceList, sw); } _htmlParser = new HTMLParser(sb.ToString()); tempReplaceList.Clear(); foreach (HTMLTagRange deadLinkTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(_htmlParser.FindStartTags("span"), t => HTMLParser.ClassAttributeValueHas(t, "deadlink")), t => _htmlParser.CreateTagRange(t)), r => r != null)) { string deadLinkInnerHTML = HttpUtility.HtmlDecode(_htmlParser.GetInnerHTML(deadLinkTagRange)); if (deadLinkInnerHTML.Contains(">>>")) continue; string deadLinkID = deadLinkInnerHTML.Substring(2); if (resurrectedPostContainers.ContainsKey("pc" + deadLinkID)) { tempReplaceList.Add( new ReplaceInfo { Offset = deadLinkTagRange.Offset, Length = deadLinkTagRange.Length, Type = ReplaceType.DeadLink, Tag = "pc" + deadLinkID, Value = "<a class=\"quotelink\" href=\"#p" + deadLinkID + "\">>>" + deadLinkID + "</a>" }); } } sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { General.WriteReplacedString(_htmlParser.PreprocessedHTML, tempReplaceList, sw); } _htmlParser = new HTMLParser(sb.ToString()); if (replaceList == null) return; foreach (HTMLTagRange postContainerTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(_htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "postContainer")), t => _htmlParser.CreateTagRange(t)), r => r != null)) { if (!resurrectedPostContainers.ContainsKey(postContainerTagRange.StartTag.GetAttributeValue("id"))) continue; HTMLTagRange fileTextDivTagRange = _htmlParser.CreateTagRange(Enumerable.FirstOrDefault(Enumerable.Where( _htmlParser.FindStartTags(postContainerTagRange, "div"), t => HTMLParser.ClassAttributeValueHas(t, "fileText")))); if (fileTextDivTagRange == null) continue; HTMLTagRange fileThumbLinkTagRange = _htmlParser.CreateTagRange(Enumerable.FirstOrDefault(Enumerable.Where( _htmlParser.FindStartTags(postContainerTagRange, "a"), t => HTMLParser.ClassAttributeValueHas(t, "fileThumb")))); if (fileThumbLinkTagRange == null) continue; HTMLTag fileTextLinkStartTag = _htmlParser.FindStartTag(fileTextDivTagRange, "a"); if (fileTextLinkStartTag == null) continue; HTMLTag fileThumbImageTag = _htmlParser.FindStartTag(fileThumbLinkTagRange, "img"); if (fileThumbImageTag == null) continue; HTMLAttribute attribute = fileTextLinkStartTag.GetAttribute("href"); if (attribute != null) { replaceList.Add( new ReplaceInfo { Offset = attribute.Offset, Length = attribute.Length, Type = ReplaceType.ImageLinkHref, Tag = String.Empty, Value = "href=\"" + HttpUtility.HtmlAttributeEncode(attribute.Value) + "\"" }); } attribute = fileThumbLinkTagRange.StartTag.GetAttribute("href"); if (attribute != null) { replaceList.Add( new ReplaceInfo { Offset = attribute.Offset, Length = attribute.Length, Type = ReplaceType.ImageLinkHref, Tag = String.Empty, Value = "href=\"" + HttpUtility.HtmlAttributeEncode(attribute.Value) + "\"" }); } attribute = fileThumbImageTag.GetAttribute("src"); if (attribute != null) { replaceList.Add( new ReplaceInfo { Offset = attribute.Offset, Length = attribute.Length, Type = ReplaceType.ImageSrc, Tag = String.Empty, Value = "src=\"" + HttpUtility.HtmlAttributeEncode(attribute.Value) + "\"" }); } } }
public virtual void ResurrectDeadPosts(HTMLParser previousParser, List<ReplaceInfo> replaceList) { }
public override string GetThreadName() { if (HasSlug()) { return GetThreadName(Settings.SlugType); } if (Settings.UseSlug == true) { try { HTMLParser parser = new HTMLParser(General.DownloadPageToString(_url)); HTMLTag canonicalLinkTag = Enumerable.FirstOrDefault(Enumerable.Where(parser.FindStartTags(parser.CreateTagRange(parser.FindStartTag("head")), "link"), t => t.GetAttributeValueOrEmpty("rel").Equals("canonical"))); return GetThreadName(canonicalLinkTag.GetAttributeValueOrEmpty("href"), Settings.SlugType); } catch { return GetThreadID(); } } return GetThreadID(); }
public override void ResurrectDeadPosts(HTMLParser previousParser, List<ReplaceInfo> replaceList) { if (previousParser == null) return; List<ReplaceInfo> tempReplaceList = new List<ReplaceInfo>(); Dictionary<string, HTMLTagRange> newPosts = new Dictionary<string, HTMLTagRange>(); Dictionary<string, HTMLTagRange> resurrectedPosts = new Dictionary<string, HTMLTagRange>(); foreach (HTMLTagRange postTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(_htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "post")), t => _htmlParser.CreateTagRange(t)), r => r != null)) { newPosts.Add(postTagRange.StartTag.GetAttributeValue("id"), postTagRange); } HTMLTagRange lastExistingPostTagRange = null; foreach (HTMLTagRange previousPostTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(previousParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "post")), t => previousParser.CreateTagRange(t)), r => r != null)) { HTMLTagRange tempTagRange; if (!newPosts.TryGetValue(previousPostTagRange.StartTag.GetAttributeValue("id"), out tempTagRange)) { int offset = lastExistingPostTagRange != null ? lastExistingPostTagRange.EndOffset : Enumerable.FirstOrDefault(Enumerable.Where(_htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "thread"))).EndOffset; HTMLTag inputTag = previousParser.FindStartTag(previousPostTagRange, "input"); string value = previousParser.GetHTML(previousPostTagRange); if (!value.Contains("<strong style=\"color: #FF0000\">[Deleted]</strong> ")) { value = value.Insert(inputTag.EndOffset - previousPostTagRange.Offset, "<strong style=\"color: #FF0000\">[Deleted]</strong> "); } tempReplaceList.Add( new ReplaceInfo { Offset = offset, Length = 0, Type = ReplaceType.DeadPost, Tag = previousPostTagRange.StartTag.GetAttributeValue("id"), Value = value.Insert(0, "<br/>") }); resurrectedPosts.Add(previousPostTagRange.StartTag.GetAttributeValue("id"), previousPostTagRange); } else { lastExistingPostTagRange = tempTagRange; } } StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { General.WriteReplacedString(_htmlParser.PreprocessedHTML, tempReplaceList, sw); } _htmlParser = new HTMLParser(sb.ToString()); if (replaceList == null) return; foreach (HTMLTagRange postTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(_htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "has-file")), t => _htmlParser.CreateTagRange(t)), r => r != null)) { if (!resurrectedPosts.ContainsKey(postTagRange.StartTag.GetAttributeValue("id"))) continue; bool isOP = HTMLParser.ClassAttributeValueHas(postTagRange.StartTag, "op"); HTMLTagRange threadDivTagRange = _htmlParser.CreateTagRange(Enumerable.FirstOrDefault(Enumerable.Where( _htmlParser.FindStartTags("div"), t => HTMLParser.ClassAttributeValueHas(t, "thread")))); HTMLTagRange filesDivTagRange = _htmlParser.CreateTagRange(Enumerable.FirstOrDefault(Enumerable.Where( _htmlParser.FindStartTags(isOP ? threadDivTagRange : postTagRange, "div"), t => HTMLParser.ClassAttributeValueHas(t, "files")))); foreach (HTMLTagRange fileDivTagRange in Enumerable.Where(Enumerable.Select(Enumerable.Where(_htmlParser.FindStartTags(filesDivTagRange, "div"), t => HTMLParser.ClassAttributeValueHas(t, "file")), t => _htmlParser.CreateTagRange(t)), r => r != null)) { HTMLTagRange fileInfoParagraphTagRange = _htmlParser.CreateTagRange(Enumerable.FirstOrDefault(Enumerable.Where( _htmlParser.FindStartTags(fileDivTagRange, "p"), t => HTMLParser.ClassAttributeValueHas(t, "fileinfo")))); if (fileInfoParagraphTagRange == null) continue; HTMLTagRange fileThumbLinkTagRange = _htmlParser.CreateTagRange(Enumerable.FirstOrDefault(Enumerable.Where( _htmlParser.FindStartTags(fileDivTagRange, "a"), t => t.GetAttributeValueOrEmpty("target") == "_blank"))); if (fileThumbLinkTagRange == null) continue; HTMLTag fileInfoLinkStartTag = _htmlParser.FindStartTag(fileInfoParagraphTagRange, "a"); if (fileInfoLinkStartTag == null) continue; HTMLTag fileThumbImageTag = _htmlParser.FindStartTag(fileThumbLinkTagRange, "img"); if (fileThumbImageTag == null) continue; HTMLAttribute attribute = fileInfoLinkStartTag.GetAttribute("href"); if (attribute != null) { replaceList.Add( new ReplaceInfo { Offset = attribute.Offset, Length = attribute.Length, Type = ReplaceType.ImageLinkHref, Tag = String.Empty, Value = "href=\"" + General.HtmlAttributeEncode(attribute.Value, false) + "\"" }); } attribute = fileThumbLinkTagRange.StartTag.GetAttribute("href"); if (attribute != null) { replaceList.Add( new ReplaceInfo { Offset = attribute.Offset, Length = attribute.Length, Type = ReplaceType.ImageLinkHref, Tag = String.Empty, Value = "href=\"" + General.HtmlAttributeEncode(attribute.Value, false) + "\"" }); } attribute = fileThumbImageTag.GetAttribute("src"); if (attribute != null) { replaceList.Add( new ReplaceInfo { Offset = attribute.Offset, Length = attribute.Length, Type = ReplaceType.ImageSrc, Tag = String.Empty, Value = "src=\"" + General.HtmlAttributeEncode(attribute.Value, false) + "\"" }); } } } }