Beispiel #1
0
        /// <summary>
        /// Try to get the rating to add it as a tag.
        /// </summary>
        /// <param name="doc"></param>
        protected void GetRating(Supremes.Nodes.Element doc, string selector)
        {
            Supremes.Nodes.Element element = doc.Select(selector).First;

            if (element == null)
            {
                return;
            }

            element = element.NextElementSibling;

            while (element != null)
            {
                string text = element.Text;
                element = element.NextElementSibling;

                if (!text.StartsWith(RATING))
                {
                    continue;
                }

                string rating = text.Replace(RATING, "");

                if (!string.IsNullOrEmpty(rating))
                {
                    this.AddTag(rating.ToLower(), "rating");
                }
            }
        }
Beispiel #2
0
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            Supremes.Nodes.Element tagList = doc.Select("#tag-sidebar").First;

            if (tagList == null)
            {
                return(false);
            }

            // Get tags
            this.AddTags(tagList, "copyright", "series");
            this.AddTags(tagList, "character", "character");
            this.AddTags(tagList, "artist", "creator");
            this.AddTags(tagList, "general");

            // Get rating
            if (Properties.Settings.Default.AddRating)
            {
                this.GetRating(doc, "#stats li");
            }

            // Get informations
            Supremes.Nodes.Elements statsLis    = doc.Select("#stats li");
            Supremes.Nodes.Element  highresLink = doc.Select("#highres").First;
            Supremes.Nodes.Element  pngLink     = doc.Select("#png").First;

            foreach (Supremes.Nodes.Element li in statsLis)
            {
                if (li.Text.StartsWith("Size: "))
                {
                    this.parseResolution(li.Text.Substring(li.Text.IndexOf(' ') + 1));
                }
            }

            if (pngLink != null)
            {
                this.GetFullImageUrlAndSizeFromLink(pngLink);
            }
            else if (highresLink != null)
            {
                this.GetFullImageUrlAndSizeFromLink(highresLink);
            }

            // Checks if the image is deleted
            Supremes.Nodes.Elements statusNotices = doc.Select(".status-notice");

            foreach (Supremes.Nodes.Element statusNotice in statusNotices)
            {
                if (statusNotice.Text.Contains("This post was deleted."))
                {
                    this.unavailable = true;

                    break;
                }
            }

            return(true);
        }
Beispiel #3
0
        /*
         * ============================================
         * Private
         * ============================================
         */

        /// <summary>
        /// Add tags for a certain category.
        /// </summary>
        /// <param name="tagList"></param>
        /// <param name="type"></param>
        /// <param name="nameSpace"></param>
        private void AddTags(Supremes.Nodes.Element tagSidebar, string type, string nameSpace = null)
        {
            Supremes.Nodes.Elements tagItems = tagSidebar.Select("li.tag-type-" + type + " > a");

            foreach (Supremes.Nodes.Element tagItem in tagItems)
            {
                this.AddTag(tagItem.Text, nameSpace);
            }
        }
Beispiel #4
0
        /*
         * ============================================
         * Private
         * ============================================
         */

        /// <summary>
        /// Add tags for a certain category.
        /// </summary>
        /// <param name="tagList"></param>
        /// <param name="type"></param>
        /// <param name="nameSpace"></param>
        private void AddTags(Supremes.Nodes.Element tagList, string color, string nameSpace = null)
        {
            Supremes.Nodes.Elements searchTags = tagList.Select("li[class=\"" + color + "\"] > a");

            foreach (Supremes.Nodes.Element searchTag in searchTags)
            {
                this.AddTag(searchTag.Text, nameSpace);
            }
        }
        /*
         * ============================================
         * Private
         * ============================================
         */

        /// <summary>
        /// Add tags for a certain category.
        /// </summary>
        /// <param name="tagList"></param>
        /// <param name="type"></param>
        /// <param name="nameSpace"></param>
        private void AddTags(Supremes.Nodes.Element tagList, string category, string nameSpace = null)
        {
            Supremes.Nodes.Elements searchTags = tagList.Select("ul." + category + "-tag-list a.search-tag");

            foreach (Supremes.Nodes.Element searchTag in searchTags)
            {
                this.AddTag(searchTag.Text, nameSpace);
            }
        }
        /*
         * ============================================
         * Private
         * ============================================
         */

        /// <summary>
        /// Add tags for a certain category.
        /// </summary>
        /// <param name="tagList"></param>
        /// <param name="type"></param>
        /// <param name="nameSpace"></param>
        private void AddTags(Supremes.Nodes.Element tagList, string nameSpace = null)
        {
            if (tagList == null)
            {
                return;
            }

            Supremes.Nodes.Elements searchTags = tagList.Select("span > a");

            foreach (Supremes.Nodes.Element searchTag in searchTags)
            {
                this.AddTag(searchTag.Text, nameSpace);
            }
        }
Beispiel #7
0
        /*
         * ============================================
         * Private
         * ============================================
         */

        /// <summary>
        /// Add tags for a certain category.
        /// </summary>
        /// <param name="tagList"></param>
        /// <param name="type"></param>
        /// <param name="nameSpace"></param>
        private void AddTags(Supremes.Nodes.Element tagList, string category, string nameSpace = null)
        {
            Supremes.Nodes.Elements searchTags = tagList.Select("li.tag-type-" + category + " > a");

            foreach (Supremes.Nodes.Element searchTag in searchTags)
            {
                if (searchTag.Text == "?")
                {
                    continue;
                }

                this.AddTag(searchTag.Text, nameSpace);
            }
        }
        /// <summary>
        /// Extract the full image URL and the image size from a link element.
        /// </summary>
        /// <param name="link"></param>
        private void GetFullImageUrlAndSizeFromLink(Supremes.Nodes.Element link)
        {
            this.full = link.Attr("href");

            string linkText = link.Text;

            linkText = linkText.Replace(" JPG", "");

            int start = linkText.LastIndexOf('(');
            int end   = linkText.LastIndexOf(')');

            if (start > 0 && end > start)
            {
                this.size = this.KbOrMbToBytes(linkText.Substring(start + 1, end - start - 1));
            }
        }
Beispiel #9
0
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            Supremes.Nodes.Element tagList = doc.Select("div._2nerN > div._3UK_f").First;

            if (tagList == null)
            {
                return(false);
            }

            Supremes.Nodes.Elements tagItems = tagList.Select("a.Q-jc6 > span._2ohCe");

            foreach (Supremes.Nodes.Element tagItem in tagItems)
            {
                if (tagItem != null)
                {
                    this.AddTag(tagItem.Text);
                }
            }

            return(true);
        }
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            Supremes.Nodes.Element tagList = doc.Select("#illust_area div.lg_box_tag").First;

            if (tagList == null)
            {
                return(false);
            }

            Supremes.Nodes.Elements tagItems = tagList.Select("a.tag");

            foreach (Supremes.Nodes.Element tagItem in tagItems)
            {
                if (tagItem != null)
                {
                    this.AddTag(tagItem.Text);
                }
            }

            return(true);
        }
Beispiel #11
0
        /*
         * ============================================
         * Private
         * ============================================
         */

        /// <summary>
        /// Access and parse the Github latest release page to extract informations.
        /// </summary>
        /// <returns></returns>
        private bool Retrieve()
        {
            Supremes.Nodes.Document doc = Supremes.Dcsoup.Parse(new Uri(this.GithubLatestUrl), 5000);

            if (doc == null)
            {
                return(false);
            }

            Supremes.Nodes.Element tag       = doc.Select("div.release-meta > ul.tag-references a.css-truncate > span.css-truncate-target").First;
            Supremes.Nodes.Element changelog = doc.Select("div.release-body div.markdown-body").First;

            if (tag == null || changelog == null)
            {
                this.ParseErrorMessage();

                return(false);
            }

            short release;

            // Release number is prefixed with 'r'
            if (!short.TryParse(tag.Text.Remove(1), out release))
            {
                this.ParseErrorMessage();

                return(false);
            }

            // Not a newer release
            if (release <= Constants.RELEASE)
            {
                return(false);
            }

            this.Release   = release;
            this.Changelog = changelog.Text;

            return(true);
        }
Beispiel #12
0
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            Supremes.Nodes.Element postTags = doc.Select("#post_tags > ul.tags").First;

            if (postTags == null)
            {
                return(false);
            }

            // Get tags
            this.AddTags(postTags, "");
            this.AddTags(postTags, "green", "series");
            this.AddTags(postTags, "blue", "character");
            this.AddTags(postTags, "orange", "creator");

            // Get informations
            Supremes.Nodes.Element postContent   = doc.Select("#content .post_content").First;
            Supremes.Nodes.Element fullImageLink = doc.Select("#big_preview_cont > a").First;

            if (postContent != null)
            {
                int    resolutionStartIndex = postContent.Text.IndexOf(RESOLUTION) + RESOLUTION.Length;
                int    resolutionEndIndex   = postContent.Text.IndexOf(" ", resolutionStartIndex);
                string resolution           = postContent.Text.Substring(resolutionStartIndex, resolutionEndIndex - resolutionStartIndex);

                int    sizeStartIndex = postContent.Text.IndexOf(SIZE) + SIZE.Length;
                int    sizeEndIndex   = postContent.Text.IndexOf(" ", sizeStartIndex);
                string size           = postContent.Text.Substring(sizeStartIndex, sizeEndIndex - sizeStartIndex);

                this.parseResolution(resolution);
                this.size = this.KbOrMbToBytes(size);
            }

            if (fullImageLink != null)
            {
                this.full = URL + fullImageLink.Attr("href");
            }

            return(true);
        }
Beispiel #13
0
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            Supremes.Nodes.Element tagSidebar = doc.Select("#tag-sidebar").First;

            // Get tags
            if (tagSidebar != null)
            {
                this.AddTags(tagSidebar, "copyright", "series");
                this.AddTags(tagSidebar, "character", "character");
                this.AddTags(tagSidebar, "artist", "creator");
                this.AddTags(tagSidebar, "medium", "meta");
                this.AddTags(tagSidebar, "general");
            }

            // Get details
            Supremes.Nodes.Element stats = doc.Select("#stats > ul").First;

            if (stats != null)
            {
                Supremes.Nodes.Elements listItems = stats.Select("li");

                foreach (Supremes.Nodes.Element li in listItems)
                {
                    string content = li.Html;

                    if (content == null)
                    {
                        continue;
                    }

                    content = content.Trim();

                    if (content.StartsWith("Original:"))
                    {
                        Supremes.Nodes.Element full = li.Select("a").First;

                        int space = full.Text.IndexOf(' ');

                        if (full != null)
                        {
                            string size       = full.Text.Substring(space + 1);
                            string dimensions = full.Text.Substring(0, space);

                            size = size.Substring(1, size.Length - 2);
                            string[] parts = dimensions.Split('x');

                            this.full = full.Attr("href");
                            this.size = this.KbOrMbToBytes(size);

                            if (parts.Length == 2)
                            {
                                int.TryParse(parts[0], out this.width);
                                int.TryParse(parts[1], out this.height);
                            }
                        }
                    }
                    else if (content.StartsWith("Rating:"))
                    {
                        this.rating = content.Substring("Rating: ".Length);
                    }
                }
            }

            return(true);
        }
Beispiel #14
0
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            Supremes.Nodes.Element tagList = doc.Select("#tag-list").First;

            if (tagList == null)
            {
                return(false);
            }

            // Get tags
            this.AddTags(tagList, "copyright", "series");
            this.AddTags(tagList, "character", "character");
            this.AddTags(tagList, "artist", "creator");
            this.AddTags(tagList, "general");
            this.AddTags(tagList, "metadata", "meta");

            // Get rating
            if (Properties.Settings.Default.AddRating)
            {
                this.GetRating(doc, "#tag-list li");
            }

            // Get informations
            Supremes.Nodes.Elements lis = tagList.Select("li");

            foreach (Supremes.Nodes.Element li in lis)
            {
                string content = li.Html;

                if (content == null)
                {
                    continue;
                }

                content = content.Trim();

                if (content.Length < 1)
                {
                    continue;
                }

                if (content.StartsWith("Size:"))
                {
                    int end = content.IndexOf('<');

                    if (end > SIZE_SUBSTR_START)
                    {
                        content = content.Substring(SIZE_SUBSTR_START, end - SIZE_SUBSTR_START);
                        string[] parts = content.Trim().Split('x');

                        if (parts.Length == 2)
                        {
                            int.TryParse(parts[0], out this.width);
                            int.TryParse(parts[1], out this.height);
                        }
                    }
                }

                Supremes.Nodes.Element link = li.Select("> a").First;

                if (link != null && link.Text == "Original image")
                {
                    this.full = link.Attr("href");
                }
            }

            return(true);
        }
Beispiel #15
0
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            Supremes.Nodes.Element tagList = doc.Select("#tag-list").First;

            if (tagList == null)
            {
                return(false);
            }

            // Get tags
            this.AddTags(tagList, "copyright", "series");
            this.AddTags(tagList, "character", "character");
            this.AddTags(tagList, "artist", "creator");
            this.AddTags(tagList, "general");
            this.AddTags(tagList, "meta", "meta");

            // Get rating
            if (Properties.Settings.Default.AddRating)
            {
                this.GetRating(doc, "#post-information li");
            }

            // Get informations
            Supremes.Nodes.Element informations = doc.Select("#post-information").First;

            if (informations != null)
            {
                Supremes.Nodes.Elements listItems = informations.Select("ul li");

                foreach (Supremes.Nodes.Element li in listItems)
                {
                    string content = li.Html;

                    if (content == null)
                    {
                        continue;
                    }

                    content = content.Trim();

                    if (content.StartsWith("Size:"))
                    {
                        Supremes.Nodes.Element full = li.Select("a").First;

                        int start = 0;
                        int end   = 0;

                        if (full != null && full.Text != "»")
                        {
                            end       = full.Text.LastIndexOf(' ');
                            this.full = full.Attr("href");

                            if (end > 0)
                            {
                                this.size = this.KbOrMbToBytes(full.Text.Substring(0, end));
                            }
                        }

                        start = content.LastIndexOf('(');
                        end   = content.LastIndexOf(')');

                        if (start > 0 && end > start)
                        {
                            this.parseResolution(content.Substring(start + 1, end - start - 1));
                        }
                    }
                    else if (content.StartsWith("Rating:"))
                    {
                        this.rating = content.Substring("Rating:".Length);
                    }
                    else if (content.StartsWith("Source:"))
                    {
                        Supremes.Nodes.Element link = li.Select("a").First;

                        if (link != null)
                        {
                            this.source = link.Attr("href");
                        }
                    }
                }
            }

            // Checks if the image is deleted
            Supremes.Nodes.Element postNoticeDeleted = doc.Select(".post-notice-deleted").First;
            Supremes.Nodes.Element postNoticeBanned  = doc.Select(".post-notice-banned").First;

            if (postNoticeDeleted != null || postNoticeBanned != null)
            {
                this.unavailable = true;
            }

            return(true);
        }
Beispiel #16
0
        /// <summary>
        /// Get general informations fro mthe page about this anime (type, episodes, premiered, studio).
        /// </summary>
        private bool GetInformations()
        {
            Supremes.Nodes.Document animeDoc = null;

            // Search for the anime
            try {
                animeDoc = Supremes.Dcsoup.Parse(new Uri(this.animeUrl), 5000);
            } catch {
                return(false);
            }

            Supremes.Nodes.Elements sidebar = animeDoc.Select("div#content td.borderClass > div.js-scrollfix-bottom");
            Supremes.Nodes.Element  h2      = sidebar.Select("h2").First;

            // There's 3 h2 elements in the sidebar: "Alternative Titles", "Information" and "Statistics"
            Supremes.Nodes.Element nextDiv = h2.NextElementSibling;

            while (nextDiv != null)
            {
                Supremes.Nodes.Elements spans = nextDiv.Select("span.dark_text");
                Supremes.Nodes.Element  span  = spans.First;

                if (span == null)
                {
                    nextDiv = nextDiv.NextElementSibling;
                    continue;
                }

                string text = span.Text.Trim();

                if (text.Length == 0)
                {
                    nextDiv = nextDiv.NextElementSibling;

                    continue;
                }

                if (text == "Type:")
                {
                    this.type = this.GetValue(nextDiv, text);
                }
                if (text == "Episodes:")
                {
                    this.episodes = this.GetValue(nextDiv, text);

                    if (this.episodes == "Unknown")
                    {
                        this.episodes = "0";
                    }
                }
                if (text == "Premiered:")
                {
                    string premiered = this.GetValue(nextDiv, text);

                    if (premiered != "?")
                    {
                        string[] parts = premiered.Split(' ');

                        this.seasonal = parts[0];
                        this.year     = parts[1];
                    }
                }
                if (text == "Studios:")
                {
                    this.studios = this.GetValue(nextDiv, text);

                    if (this.studios == "None found, add some")
                    {
                        this.studios = null;
                    }
                }

                if (text == "Source:")
                {
                    this.source = this.GetValue(nextDiv, text);
                }

                if (text == "Genres:")
                {
                    Supremes.Nodes.Elements aElements = nextDiv.Select("a");
                    this.genres = new string[aElements.Count];

                    for (int i = 0; i < this.genres.Length; i++)
                    {
                        this.genres[i] = aElements[i].Attr("title");
                    }
                }

                nextDiv = nextDiv.NextElementSibling;
            }

            return(true);
        }
Beispiel #17
0
 private string GetValue(Supremes.Nodes.Element nextDiv, string text)
 {
     return(nextDiv.Text.Replace(text + " ", "").Trim());
 }
Beispiel #18
0
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            Supremes.Nodes.Elements tagRows = doc.Select("ul#tags li");

            if (tagRows == null)
            {
                return(false);
            }

            // Get tags
            foreach (Supremes.Nodes.Element tagRow in tagRows)
            {
                Supremes.Nodes.Elements link = tagRow.Select("a");

                if (link == null)
                {
                    continue;
                }

                if (tagRow.Text.Length < 1)
                {
                    continue;
                }

                string value = link.Text.Replace(tagRow.Text, "").Trim();

                if (value.Length < 1)
                {
                    continue;
                }

                string nameSpace = tagRow.Text.Replace(value, "").Trim();

                switch (nameSpace)
                {
                case "Artiste":
                    nameSpace = "creator";
                    break;

                case "Studio":
                    nameSpace = "series";
                    break;

                case "Game":
                    nameSpace = "series";
                    break;

                case "Character":
                    nameSpace = "character";
                    break;

                case "Source":
                    nameSpace = "series";
                    break;

                default:
                    nameSpace = null;
                    break;
                }

                this.AddTag(value.ToLower(), nameSpace);
            }

            // Get informations
            Supremes.Nodes.Element  imageLink    = doc.Select("#large > a.preview").First;
            Supremes.Nodes.Element  imageElement = doc.Select("#large > img").First;
            Supremes.Nodes.Elements paragraphs   = doc.Select("#large > p");

            if (imageLink != null)
            {
                this.full = imageLink.Attr("href");
            }
            else if (imageElement != null)
            {
                this.full = imageElement.Attr("src");
            }

            Regex resolutionnRegex = new Regex(@"\d+x\d+", RegexOptions.Compiled | RegexOptions.IgnoreCase);

            foreach (Supremes.Nodes.Element paragraph in paragraphs)
            {
                MatchCollection resolutionMatches = resolutionnRegex.Matches(paragraph.OwnText);

                if (resolutionMatches.Count == 1)
                {
                    GroupCollection groups = resolutionMatches[0].Groups;
                    this.parseResolution(groups[0].Value);
                }

                Supremes.Nodes.Element span = paragraph.Select("> span").First;

                if (span != null && !string.IsNullOrWhiteSpace(span.OwnText))
                {
                    this.size = this.KbOrMbToBytes(span.OwnText);
                }
            }

            return(true);
        }
        /*
         * ============================================
         * Protected
         * ============================================
         */

        override protected bool Parse(Supremes.Nodes.Document doc)
        {
            if (string.IsNullOrEmpty(this.Url))
            {
                return(false);
            }

            string url = this.Url;

            if (url.EndsWith("/"))
            {
                url = url.Substring(0, url.Length - 1);
            }

            int    lastSlash = url.LastIndexOf('/');
            string imageId   = url.Substring(lastSlash + 1);

            Supremes.Nodes.Element tagList       = doc.Select("#quicktag1_" + imageId).First;
            Supremes.Nodes.Element seriesList    = doc.Select("#quicktag2_" + imageId).First;
            Supremes.Nodes.Element characterList = doc.Select("#quicktag4_" + imageId).First;
            Supremes.Nodes.Element artistList    = doc.Select("#quicktag3_" + imageId).First;

            // Get tags
            this.AddTags(tagList);
            this.AddTags(seriesList, "series");
            this.AddTags(characterList, "character");
            this.AddTags(artistList, "creator");

            // Get rating
            if (Properties.Settings.Default.AddRating)
            {
                Supremes.Nodes.Element rating = doc.Select("#rating" + imageId).First;

                if (rating != null && rating.Text != "N/A")
                {
                    this.AddTag(rating.Text, "rating");
                }
            }

            // Get informations
            Supremes.Nodes.Element imageBlock = doc.Select("#content .image_block").First;

            if (imageBlock == null)
            {
                return(true);
            }

            Supremes.Nodes.Element  imageLink = imageBlock.Select(".thumb > a.thumb_image[href]").First;
            Supremes.Nodes.Elements metas     = imageBlock.Select(".meta > dl").Select("> *");

            if (imageLink != null)
            {
                this.full = URL + imageLink.Attr("href");
            }

            for (byte i = 0; i < metas.Count; i += 2)
            {
                if (i + 1 >= metas.Count)
                {
                    break;
                }

                Supremes.Nodes.Element dt = metas[i];
                Supremes.Nodes.Element dd = metas[i + 1];

                if (dt.Text == "File size:")
                {
                    this.size = this.KbOrMbToBytes(dd.Text);
                }
                else if (dt.Text == "Dimensions:")
                {
                    string dimensions = dd.Text;

                    if (dimensions.Contains("("))
                    {
                        dimensions = dimensions.Substring(0, dimensions.IndexOf(" "));
                    }

                    this.parseResolution(dimensions);
                }
            }

            return(true);
        }
Beispiel #20
0
        /// <summary>
        /// Parse HTML responded by SauceNAO.
        /// </summary>
        private void ParseResponseHtml(string html)
        {
            Supremes.Nodes.Document doc;

            try {
                doc = Supremes.Dcsoup.Parse(html, "utf-8");
            } catch {
                return;
            }

            Supremes.Nodes.Element  yourImage = doc.Select("#yourimage > a > img").First;
            Supremes.Nodes.Elements results   = doc.Select("#middle > .result");

            if (yourImage != null)
            {
                this.uploadedImageUrl = "https://saucenao.com/" + yourImage.Attr("src");
            }

            if (results.Count < 1)
            {
                // Check if search limit was exceeded
                Supremes.Nodes.Element strong = doc.Select("strong").First;

                if (strong != null && strong.Text == "Daily Search Limit Exceeded.")
                {
                    this.dailyLimitExceeded = true;
                }

                return;
            }

            foreach (Supremes.Nodes.Element result in results)
            {
                Supremes.Nodes.Element resultcontent = result.Select(".resultcontent").First;

                if (resultcontent == null)
                {
                    continue;
                }

                List <Tag> resultTags = new List <Tag>();

                Supremes.Nodes.Elements sourceLinks          = result.Select(".resultmiscinfo > a");
                Supremes.Nodes.Element  resultimage          = result.Select(".resultimage img").First;
                Supremes.Nodes.Element  resultsimilarityinfo = result.Select(".resultsimilarityinfo").First;
                Supremes.Nodes.Element  originalSourceLink   = resultcontent.Select(".resultcontentcolumn a").First;

                // Get preview image
                string previewUrl = resultimage.Attr("src");

                if (previewUrl == BLOCKED_GIF)
                {
                    previewUrl = resultimage.Attr("data-src");
                }

                // Get tags provided by SauceNAO
                Supremes.Nodes.Element  resulttitle          = resultcontent.Select(".resulttitle").First;
                Supremes.Nodes.Elements resultcontentcolumns = resultcontent.Select(".resultcontentcolumn");
                Supremes.Nodes.Elements originalSourceLinks  = resultcontent.Select(".resultcontentcolumn a");

                // Title or creator tag
                if (resulttitle != null)
                {
                    string titleText = resulttitle.Text;
                    string nameSpace = this.titleTagNamespace.Namespace;

                    if (titleText.StartsWith("Creator:") && this.creatorTagNamespace.Enabled)
                    {
                        titleText = titleText.Replace("Creator:", "");
                        nameSpace = this.creatorTagNamespace.Namespace;

                        resultTags.Add(new Tag(titleText.Trim(), nameSpace)
                        {
                            Source = Enum.TagSource.SearchEngine
                        });
                    }
                    else if (this.titleTagNamespace.Enabled)
                    {
                        resultTags.Add(new Tag(titleText.Trim(), nameSpace)
                        {
                            Source = Enum.TagSource.SearchEngine
                        });
                    }
                }

                foreach (Supremes.Nodes.Element resultcontentcolumn in resultcontentcolumns)
                {
                    string contentHtml = resultcontentcolumn.Html;

                    // Get material tag
                    if (this.materialTagNamespace.Enabled)
                    {
                        int materialPos = contentHtml.IndexOf("<strong>Material: </strong>");

                        if (materialPos >= 0)
                        {
                            string materialHtml = contentHtml.Substring(materialPos);
                            materialHtml = materialHtml.Replace("<strong>Material: </strong>", "");
                            materialHtml = materialHtml.Replace("<br>", "");

                            resultTags.Add(new Tag(materialHtml.Trim(), this.materialTagNamespace.Namespace)
                            {
                                Source = Enum.TagSource.SearchEngine
                            });
                        }
                    }

                    // Get character tags
                    if (this.characterTagNamespace.Enabled)
                    {
                        int charactersPos = contentHtml.IndexOf("<strong>Characters: </strong>");

                        if (charactersPos >= 0)
                        {
                            string charactersHtml = contentHtml.Replace("<strong>Characters: </strong>", "").Trim();
                            charactersHtml = charactersHtml.Replace("<br>", "");
                            string[] characterNames = charactersHtml.Split('\n');

                            foreach (string characterName in characterNames)
                            {
                                if (!string.IsNullOrWhiteSpace(characterName))
                                {
                                    resultTags.Add(new Tag(characterName.Trim(), this.characterTagNamespace.Namespace)
                                    {
                                        Source = Enum.TagSource.SearchEngine
                                    });
                                }
                            }
                        }
                    }
                }

                // Source links
                foreach (Supremes.Nodes.Element sourceLink in originalSourceLinks)
                {
                    string url = sourceLink.Attr("href");

                    // Not a pixiv URL
                    if (!url.StartsWith("https://www.pixiv.net"))
                    {
                        continue;
                    }

                    int questionMarkIndex = url.IndexOf('?');

                    // No query string
                    if (questionMarkIndex < 1)
                    {
                        continue;
                    }

                    // Get query string
                    string queryString = url.Substring(questionMarkIndex + 1);

                    // Parse query string
                    string[] parts = queryString.Split('&');

                    foreach (string part in parts)
                    {
                        string[] keyValue = part.Split('=');

                        string key   = keyValue[0];
                        string value = keyValue[1];

                        if (key == "illust_id")
                        {
                            if (this.pixivIllustIdNamespace.Enabled)
                            {
                                resultTags.Add(new Tag(value, this.pixivIllustIdNamespace.Namespace)
                                {
                                    Source = Enum.TagSource.SearchEngine
                                });
                            }
                        }
                        else if (key == "id")
                        {
                            if (this.pixivMemberIdNamespace.Enabled)
                            {
                                resultTags.Add(new Tag(value, this.pixivMemberIdNamespace.Namespace)
                                {
                                    Source = Enum.TagSource.SearchEngine
                                });
                            }

                            if (this.pixivMemberNameNamespace.Enabled)
                            {
                                resultTags.Add(new Tag(sourceLink.Text, this.pixivMemberNameNamespace.Namespace)
                                {
                                    Source = Enum.TagSource.SearchEngine
                                });
                            }
                        }
                    }
                }

                // There were no booru links for this result but we have the link to pixiv/etc
                if (sourceLinks.Count == 0 && originalSourceLink != null)
                {
                    this.AddMatch(
                        originalSourceLink.Attr("href"),
                        previewUrl,
                        resultsimilarityinfo.Text,
                        resultTags
                        );

                    continue;
                }

                // We have booru links for this result
                foreach (Supremes.Nodes.Element sourceLink in sourceLinks)
                {
                    this.AddMatch(
                        sourceLink.Attr("href"),
                        previewUrl,
                        resultsimilarityinfo.Text,
                        resultTags,
                        originalSourceLink != null ? originalSourceLink.Attr("href") : null
                        );
                }
            }
        }