Ejemplo n.º 1
0
        private void AddAvailableLinkedFieldsInUIContext(object obj)
        {
            string fieldName = obj as string;

            if (!string.IsNullOrEmpty(fieldName))
            {
                AvailableFields.Add(fieldName);
            }
        }
Ejemplo n.º 2
0
        public override async Task <AGame> LoadGame()
        {
            var id = ID;

            var url = $"{Consts.Root}{id}";

            Link = url;

            var web      = new HtmlWeb();
            var document = await web.LoadFromWebAsync(url);

            if (document == null)
            {
                throw new Exception($"Could not load from {url}");
            }

            var node = document.DocumentNode;

            #region Name

            var nameNode =
                node.SelectSingleNode(
                    "//div[@class='product-name mdl-cell mdl-cell--order-0 mdl-cell--12-col']");
            if (!IsNull(nameNode, "Name"))
            {
                if (TryGetInnerText(nameNode, "h1[@class='h1']", "Name", out var sName))
                {
                    Name = sName;
                    AvailableFields.Add(MetadataField.Name);
                    LogFound("Name", sName);
                }
            }
            else
            {
                return(null);
            }

            #endregion

            #region Product Media

            var productMediaNode =
                node.SelectSingleNode(
                    "//div[@class='product-img-box mdl-cell mdl-cell--order-2 mdl-cell--order-1-tablet mdl-cell--order-1-desktop mdl-cell--12-col mdl-cell--7-col-tablet mdl-cell--8-col-desktop']");
            if (!IsNull(productMediaNode, "Product Media"))
            {
                #region Images

                var imageMediaNode =
                    productMediaNode.SelectSingleNode(productMediaNode.XPath +
                                                      "/div[@class='slick-wrapper']/div[@class='slick-media']");
                if (!IsNull(imageMediaNode, "Image Media"))
                {
                    var imageNodes =
                        imageMediaNode.SelectNodes(imageMediaNode.XPath + "/div[@class='item product-image']/img");
                    if (!IsNullOrEmpty(imageNodes, "Image Nodes"))
                    {
                        var temp = imageNodes.Select(x =>
                        {
                            var dataLazy = x.GetValue("data-lazy");
                            return(dataLazy);
                        }).NotNull().ToList();

                        if (temp.Count > 0)
                        {
                            Images = temp;
                            AvailableFields.Add(MetadataField.BackgroundImage);
                            LogFound("Images", Images);
                        }
                    }
                }

                #endregion

                #region Description

                var descriptionNode = productMediaNode.SelectSingleNode(
                    productMediaNode.XPath +
                    "/div[@class='product-collateral mdl-grid']/div[@class='mdl-cell mdl-cell--12-col']/div[@class='mdl-tabs mdl-js-tabs']/div[@id='tab-description']");
                if (!IsNull(descriptionNode, "Description"))
                {
                    //TODO: clean this up, inner HTML is kinda funky
                    var innerHtml = descriptionNode.InnerHtml.DecodeString();
                    if (!innerHtml.IsEmpty())
                    {
                        Description = innerHtml;
                        AvailableFields.Add(MetadataField.Description);
                        LogFound("Description", null);
                    }
                }

                #endregion
            }

            #endregion

            #region Product Details

            var productDetailsNode =
                node.SelectSingleNode(
                    "//div[@class='product-shop mdl-cell mdl-cell--order-1 mdl-cell--order-2-tablet mdl-cell--order-2-desktop mdl-cell--12-col mdl-cell--5-col-tablet mdl-cell--4-col-desktop']");
            if (!IsNull(productDetailsNode, "Product Details"))
            {
                #region Cover Image

                var coverImageNode = productDetailsNode.SelectSingleNode(
                    productDetailsNode.XPath +
                    "/div[@class='product-shop-inner']/div[@class='product-package-img']/img[@class='product-image-boxart']");
                if (!IsNull(coverImageNode, "Cover Image"))
                {
                    var src = coverImageNode.GetValue("src");
                    if (!src.IsEmpty())
                    {
                        CoverImage = src;
                        AvailableFields.Add(MetadataField.CoverImage);
                        LogFound("Cover Image", src);
                    }
                }

                #endregion

                #region Game Info

                var gameInfoNode =
                    productDetailsNode.SelectSingleNode(productDetailsNode.XPath +
                                                        "/div[@class='product-shop-inner additional-info']");
                if (!IsNull(gameInfoNode, "Game Info"))
                {
                    #region Studio

                    var studioNode = gameInfoNode.SelectSingleNode(
                        gameInfoNode.XPath + "//div[@class='rTableRow studio']/div[@class='rTableCell data']/a");
                    if (!IsNull(studioNode, "Studio"))
                    {
                        var href = studioNode.GetValue("href");
                        var name = studioNode.InnerText.DecodeString();

                        if (!href.IsEmpty() && !name.IsEmpty())
                        {
                            var link = new Link(name, href);
                            AvailableFields.Add(MetadataField.Developers);
                            Studio = link;
                            LogFound("Developer", $"{name}: {href}");
                        }
                    }

                    #endregion

                    #region Publisher

                    var publisherNode = gameInfoNode.SelectSingleNode(
                        gameInfoNode.XPath + "//div[@class='rTableRow publisher']/div[@class='rTableCell data']/a");
                    if (!IsNull(publisherNode, "Studio"))
                    {
                        var href = publisherNode.GetValue("href");
                        var name = publisherNode.InnerText.DecodeString();

                        if (!href.IsEmpty() && !name.IsEmpty())
                        {
                            var link = new Link(name, href);
                            AvailableFields.Add(MetadataField.Publishers);
                            Publisher = link;
                            LogFound("Publisher", $"{name}: {href}");
                        }
                    }

                    #endregion

                    #region Release Date

                    var releaseDateNode = gameInfoNode.SelectSingleNode(
                        gameInfoNode.XPath + "//div[@class='rTableRow release-date']/div[@class='rTableCell data']");
                    if (!IsNull(releaseDateNode, "Release Date"))
                    {
                        var sDate = releaseDateNode.InnerText.DecodeString();
                        if (!sDate.IsEmpty())
                        {
                            if (DateTime.TryParse(sDate, out var releaseDate))
                            {
                                ReleaseDate = releaseDate;
                                AvailableFields.Add(MetadataField.ReleaseDate);
                                LogFound("Release Date", sDate);
                            }
                        }
                    }

                    var adultContentNode = gameInfoNode.SelectSingleNode(gameInfoNode.XPath + "//div[@class='rTableRow product-content adult']");
                    if (!IsNull(adultContentNode, "Adult Content Rating"))
                    {
                        HasAdultRating = true;
                        AvailableFields.Add(MetadataField.AgeRating);
                        LogFound("Adult Content Rating", null);
                    }

                    #endregion
                }

                #endregion

                #region Game Additional Meta

                var gameMetaNode = productDetailsNode.SelectSingleNode(
                    productDetailsNode.XPath +
                    "/div[@class='product-shop-inner meta mdl-cell--hide-phone']/div[@class='rTable']");
                if (!IsNull(gameMetaNode, "Game Meta"))
                {
                    var linkNodes = gameMetaNode.SelectNodes(
                        gameMetaNode.XPath + "/div[@class='rTableRow links']/div[@class='rTableCell data']/a");
                    if (!IsNullOrEmpty(linkNodes, "Links"))
                    {
                        List <Link> temp = linkNodes.Select(x =>
                        {
                            var href = x.GetValue("href");
                            var name = x.InnerText.DecodeString();

                            if (!href.IsEmpty() && !name.IsEmpty())
                            {
                                return(new Link(name, href));
                            }
                            else
                            {
                                return(null);
                            }
                        }).NotNull().ToList();

                        if (temp.Count > 0)
                        {
                            AdditionalLinks = temp;
                            LogFound("Additional Links", temp);
                        }
                    }
                }

                #endregion
            }

            #endregion

            return(this);
        }
Ejemplo n.º 3
0
        public override async Task <AGame> LoadGame()
        {
            Link = $"https://f95zone.to/threads/{ID}";

            var web      = new HtmlWeb();
            var document = await web.LoadFromWebAsync(Link);

            if (document == null)
            {
                throw new Exception($"Could not load from {Link}");
            }

            var node = document.DocumentNode;

            var headerNode = node.SelectSingleNode("//div[@class='pageContent']/div[@class='uix_headerInner']");

            if (IsNull(headerNode, "Header"))
            {
                return(null);
            }

            var titleNode = headerNode.SelectSingleNode("div[@class='p-title ']/h1[@class='p-title-value']");

            if (IsNull(titleNode, "Title"))
            {
                return(null);
            }

            #region Labels

            var labels = titleNode.SelectNodes("a[@class='labelLink']");
            if (!IsNullOrEmpty(labels, "Labels"))
            {
                List <string> temp = labels.Select(x =>
                {
                    if (!TryGetInnerText(x, "span", "Label Text", out var labelText))
                    {
                        return(null);
                    }

                    var start  = 0;
                    var length = labelText.Length;

                    if (labelText[0] == '[')
                    {
                        start = 1;
                        length--;
                    }

                    if (labelText[labelText.Length - 1] == ']')
                    {
                        length--;
                    }

                    return(labelText.Substring(start, length));
                }).NotNull().ToList();

                if (temp.Count > 0)
                {
                    Labels = temp;
                    AvailableFields.Add(MetadataField.Tags);
                    LogFound("Labels", Labels);
                }
            }

            #endregion

            #region Name

            var name = titleNode.DecodeInnerText();
            if (!IsEmpty(name, "Name"))
            {
                if (Labels != null && Labels.Count > 0)
                {
                    var last = Labels.Last();
                    var i    = name.IndexOf(last, StringComparison.OrdinalIgnoreCase);
                    name = name.Substring(i + last.Length + 1).TrimStart();
                }

                var lastStartingBracket = name.LastIndexOf('[');
                var lastClosingBracket  = name.LastIndexOf(']');

                if (lastStartingBracket != -1 && lastClosingBracket != -1)
                {
                    Developer = name.Substring(lastStartingBracket + 1, lastClosingBracket - lastStartingBracket - 1);
                    AvailableFields.Add(MetadataField.Developers);
                    AvailableFields.Add(MetadataField.Publishers);
                }

                Name = name.Substring(0, lastStartingBracket).Trim();
                AvailableFields.Add(MetadataField.Name);
                LogFound("Name", Name);
            }

            #endregion

            #region Genres

            var tags = headerNode.SelectNodes("div[@class='p-description']/ul[@class='listInline listInline--bullet']/li[@class='groupedTags']/a[@class='tagItem']");
            if (!IsNullOrEmpty(tags, "Tags"))
            {
                List <string> temp = tags.Select(x => x.DecodeInnerText()).NotNull().ToList();

                if (temp.Count > 0)
                {
                    Genres = temp;
                    AvailableFields.Add(MetadataField.Genres);
                    LogFound("Genres", Genres);
                }
            }

            #endregion

            #region Release Date

            var dateNode =
                headerNode.SelectSingleNode(
                    "div[@class='p-description']/ul[@class='listInline listInline--bullet']/li[2]");
            if (!IsNull(dateNode, "Date"))
            {
                var timeNode = dateNode.SelectSingleNode("a[@class='u-concealed']/time");
                if (!IsNull(timeNode, "Date Time"))
                {
                    var sDateTime = timeNode.GetValue("datetime");
                    if (!sDateTime.IsEmpty())
                    {
                        if (DateTime.TryParse(sDateTime, out var dateTime))
                        {
                            ReleaseDate = dateTime;
                            AvailableFields.Add(MetadataField.ReleaseDate);
                            LogFound("Release Date", sDateTime);
                        }
                    }
                }
            }

            #endregion

            #region Ratings

            var ratingNode =
                node.SelectSingleNode(
                    "//div[@class='pageContent']/div[@class='uix_headerInner--opposite']/div[@class='p-title-pageAction']/span[@class='ratingStarsRow ']/span[@class='ratingStars bratr-rating ']");
            if (!IsNull(ratingNode, "Rating"))
            {
                var sRating = ratingNode.GetValue("title");
                if (!sRating.IsEmpty())
                {
                    if (TryParseRating(sRating, out var rating))
                    {
                        Rating = rating;
                        AvailableFields.Add(MetadataField.CommunityScore);
                        LogFound("Ratings", sRating);
                    }
                    else
                    {
                        Logger.Debug($"Unable to parse rating \"{sRating}\"");
                    }
                }
                else
                {
                    Logger.Debug("Rating Node Value is empty!");
                }
            }

            #endregion

            #region Cover Image

            var coverImageNode = headerNode.ParentNode.ParentNode;
            if (!IsNull(coverImageNode, "Cover Image"))
            {
                var style = coverImageNode.GetValue("style").DecodeString();
                if (!style.IsEmpty())
                {
                    var lastStartingBracket = style.LastIndexOf('(');
                    var lastClosingBracket  = style.LastIndexOf(')');

                    if (lastStartingBracket != -1 && lastClosingBracket != -1)
                    {
                        //+2, -2 because ('URL') -> URL
                        var sCoverImage = style.Substring(lastStartingBracket + 2, lastClosingBracket - lastStartingBracket - 2);
                        if (Uri.TryCreate(sCoverImage, UriKind.Absolute, out var coverImage))
                        {
                            if (Images == null)
                            {
                                Images = new List <Uri>();
                            }
                            Images.Add(coverImage);
                            AvailableFields.Add(MetadataField.CoverImage);
                            AvailableFields.Add(MetadataField.BackgroundImage);
                            LogFound("Cover Image", null);
                        }
                    }
                }
            }

            #endregion

            #region Body

            var bodyNode = node.SelectSingleNode("//div[@class='p-body-pageContent']/div[@class='block block--messages']/div[@class='block-container lbContainer']/div[@class='block-body js-replyNewMessageContainer']/article/div[@class='message-inner']/div[@class='message-cell message-cell--main']/div/div[@class='message-content js-messageContent']/div/article/div[@class='bbWrapper']");
            if (IsNull(bodyNode, "Body"))
            {
                return(this);
            }
            {
                #region Images

                var imageNodes = bodyNode.SelectNodes(bodyNode.XPath + "//img[@class='bbImage ']");
                if (!IsNullOrEmpty(imageNodes, "Body - Images"))
                {
                    List <Uri> temp = imageNodes.Select(x =>
                    {
                        var parent = x.ParentNode;
                        if (!parent.Name.Equals("a", StringComparison.OrdinalIgnoreCase))
                        {
                            var src = x.GetValue("src");
                            if (src.IsEmpty())
                            {
                                return(null);
                            }

                            return(!Uri.TryCreate(src, UriKind.Absolute, out var uriResult)
                                ? null
                                : uriResult);
                        }
                        else
                        {
                            var href = parent.GetValue("href");
                            if (href.IsEmpty())
                            {
                                return(null);
                            }

                            return(!Uri.TryCreate(href, UriKind.Absolute, out var uriResult)
                                ? null
                                : uriResult);
                        }
                    }).NotNull().ToList();

                    if (temp.Count > 0)
                    {
                        if (Images == null)
                        {
                            Images = temp;
                        }
                        else
                        {
                            Images.AddRange(temp);
                        }
                        if (!AvailableFields.Contains(MetadataField.CoverImage))
                        {
                            AvailableFields.Add(MetadataField.CoverImage);
                        }
                        if (!AvailableFields.Contains(MetadataField.BackgroundImage))
                        {
                            AvailableFields.Add(MetadataField.BackgroundImage);
                        }

                        LogFound("Images", Images);
                    }
                }

                #endregion

                #region Description

                var innerText = bodyNode.InnerText.DecodeString();

                var overviewList = new List <string>
                {
                    "Overview",
                    "About this game"
                };

                Tuple <int, string> selectedOverview = overviewList.Select(x =>
                {
                    var y     = $"{x}:";
                    var index = innerText.IndexOf(y, StringComparison.OrdinalIgnoreCase);
                    if (index != -1)
                    {
                        return(Tuple.Create(index, y));
                    }

                    y     = x;
                    index = innerText.IndexOf(y, StringComparison.OrdinalIgnoreCase);
                    return(Tuple.Create(index, y));
                }).FirstOrDefault(x => x.Item1 != -1);

                if (selectedOverview == null)
                {
                    return(this);
                }
                {
                    var description    = innerText.Substring(selectedOverview.Item1 + selectedOverview.Item2.Length);
                    var linksInfoIndex = description.IndexOf("You must be registered to see the links", StringComparison.OrdinalIgnoreCase);
                    description = description.Substring(0, linksInfoIndex);

                    var infoList = new List <string>
                    {
                        "Thread Updated",
                        "Updated",
                        "Release Date",
                        "Developer / Publisher",
                        "Developer",
                        "Publisher",
                        "Censorship",
                        "Version",
                        "Operating System",
                        "Platform",
                        "Language",
                        "Alternative version",
                        "Sidestory",
                        "Same Series",
                        "Prequel",
                        "Sequel",
                        "Changelog",
                        "Genre",
                        "Cheat",
                        "OS",
                    };

                    infoList.Select(x => $"{x}:").Do(x =>
                    {
                        var index = description.IndexOf(x, StringComparison.OrdinalIgnoreCase);
                        if (index == -1)
                        {
                            return;
                        }

                        description = description.Substring(0, index);
                    });

                    description = description.Trim();
                    if (description.IsEmpty())
                    {
                        return(this);
                    }

                    Description = description;
                    AvailableFields.Add(MetadataField.Description);
                    LogFound("Description", null);
                }

                #endregion
            }

            #endregion

            return(this);
        }