コード例 #1
0
        public async Task <AnimeStaffData> GetCharStaffData(bool force = false)
        {
            if (!_animeMode)
            {
                throw new InvalidOperationException("Umm you said it's going to be manga...");
            }
            var output = force
                ? new AnimeStaffData()
                : await DataCache.RetrieveData <AnimeStaffData>($"staff_{_animeId}", "AnimeDetails", 7) ??
                         new AnimeStaffData();

            if (output.AnimeCharacterPairs.Count > 0 || output.AnimeStaff.Count > 0)
            {
                return(output);
            }

            var raw = await GetRequestResponse();

            if (string.IsNullOrEmpty(raw))
            {
                return(null);
            }

            var doc = new HtmlDocument();

            doc.LoadHtml(raw);

            try
            {
                var             mainContainer = doc.FirstOfDescendantsWithClass("div", "js-scrollfix-bottom-rel");
                List <HtmlNode> charTables    = new List <HtmlNode>();
                List <HtmlNode> staffTables   = new List <HtmlNode>();
                bool            nowStaff      = false;
                int             headerCount   = 0;
                foreach (var node in mainContainer.ChildNodes)
                {
                    if (!nowStaff)
                    {
                        if (node.Name == "table")
                        {
                            charTables.Add(node);
                        }
                        else if (node.Name == "h2")
                        {
                            headerCount++;
                            if (headerCount == 2)
                            {
                                nowStaff = true;
                            }
                        }
                    }
                    else
                    {
                        if (node.Name == "table")
                        {
                            staffTables.Add(node);
                        }
                    }
                }
                int i = 0;
                foreach (var table in charTables)
                {
                    try
                    {
                        var current = new AnimeCharacterStaffModel();

                        var imgs  = table.Descendants("img").ToList();
                        var infos = table.Descendants("td").ToList(); //2nd is character 4th is person

                        //character
                        var img = imgs[0].Attributes["data-src"].Value;
                        if (!img.Contains("questionmark"))
                        {
                            img = Regex.Replace(img, @"\/r\/\d+x\d+", "");
                            current.AnimeCharacter.ImgUrl = img.Substring(0, img.IndexOf('?'));
                        }

                        current.AnimeCharacter.FromAnime = _animeMode;
                        current.AnimeCharacter.ShowId    = _animeId.ToString();
                        current.AnimeCharacter.Name      =
                            WebUtility.HtmlDecode(imgs[0].Attributes["alt"].Value.Replace(",", ""));
                        current.AnimeCharacter.Id    = infos[1].ChildNodes[1].Attributes["href"].Value.Split('/')[4];
                        current.AnimeCharacter.Notes = infos[1].ChildNodes[3].InnerText.Trim();

                        //voiceactor
                        try
                        {
                            img = imgs[1].Attributes["data-src"].Value;
                            if (!img.Contains("questionmark"))
                            {
                                img = Regex.Replace(img, @"\/r\/\d+x\d+", "");
                                current.AnimeStaffPerson.ImgUrl = img.Substring(0, img.IndexOf('?'));
                            }
                            current.AnimeStaffPerson.Name  = WebUtility.HtmlDecode(imgs[1].Attributes["alt"].Value.Replace(",", ""));
                            current.AnimeStaffPerson.Id    = infos[3].ChildNodes[1].Attributes["href"].Value.Split('/')[4];
                            current.AnimeStaffPerson.Notes = infos[3].ChildNodes[4].InnerText.Trim();
                        }
                        catch (Exception)
                        {
                            //no voice actor
                            current.AnimeStaffPerson.Name      = "Unknown";
                            current.AnimeStaffPerson.IsUnknown = true;
                        }


                        output.AnimeCharacterPairs.Add(current);
                        if (i++ > 30)
                        {
                            break;
                        }
                    }
                    catch (Exception)
                    {
                        //oddities
                    }
                }
                i = 0;
                foreach (var staffRow in staffTables)
                {
                    try
                    {
                        var current = new AnimeStaffPerson();
                        var imgs    = staffRow.Descendants("img").ToList();
                        var info    = staffRow.Descendants("td").Last(); //we want last

                        var img = imgs[0].Attributes["data-src"].Value;
                        if (!img.Contains("questionmark"))
                        {
                            img            = Regex.Replace(img, @"\/r\/\d+x\d+", "");
                            current.ImgUrl = img.Substring(0, img.IndexOf('?'));
                        }
                        var link = info.Descendants("a").First();
                        current.Name  = WebUtility.HtmlDecode(link.InnerText.Trim().Replace(",", ""));
                        current.Id    = link.Attributes["href"].Value.Split('/')[4];
                        current.Notes = staffRow.FirstOfDescendantsWithClass("div", "spaceit_pad").InnerText.Trim();

                        output.AnimeStaff.Add(current);
                        if (i++ > 30)
                        {
                            break;
                        }
                    }
                    catch (Exception)
                    {
                        //what can I say?
                    }
                }
            }
            catch (Exception)
            {
                //mysteries of html
            }


            DataCache.SaveData(output, $"staff_{_animeId}", "AnimeDetails");

            return(output);
        }
コード例 #2
0
 private async void NavigatePersonWebPage(AnimeStaffPerson person)
 {
     ResourceLocator.SystemControlsLauncherService.LaunchUri(
         new Uri($"https://myanimelist.net/people/{person.Id}"));
 }
コード例 #3
0
ファイル: ProfileQuery.cs プロジェクト: Latawiec/MALClient
        public async Task <ProfileData> GetProfileData(bool force = false, bool updateFavsOnly = false)
        {
            ProfileData possibleData = null;

            if (!force)
            {
                possibleData = await DataCache.RetrieveProfileData(_userName);
            }
            if (possibleData != null)
            {
                return(possibleData);
            }
            var raw = !updateFavsOnly
                ? await(await (await MalHttpContextProvider.GetHttpContextAsync()).GetAsync($"/profile/{_userName}")).Content.ReadAsStringAsync()
                : await GetRequestResponse();

            var doc = new HtmlDocument();

            doc.LoadHtml(raw);
            var current = new ProfileData {
                User = { Name = _userName }
            };

            #region Recents
            try
            {
                var i = 1;
                foreach (
                    var recentNode in
                    doc.DocumentNode.Descendants("div")
                    .Where(
                        node =>
                        node.Attributes.Contains("class") &&
                        node.Attributes["class"].Value ==
                        HtmlClassMgr.ClassDefs["#Profile:recentUpdateNode:class"]))
                {
                    if (i <= 3)
                    {
                        current.RecentAnime.Add(
                            int.Parse(
                                recentNode.Descendants("a").First().Attributes["href"].Value.Substring(8).Split('/')[2]));
                    }
                    else
                    {
                        current.RecentManga.Add(
                            int.Parse(
                                recentNode.Descendants("a").First().Attributes["href"].Value.Substring(8).Split('/')[2]));
                    }
                    i++;
                }
            }
            catch (Exception)
            {
                //no recents
            }

            #endregion

            #region FavChar

            try
            {
                foreach (
                    var favCharNode in
                    doc.DocumentNode.Descendants("ul")
                    .First(
                        node =>
                        node.Attributes.Contains("class") &&
                        node.Attributes["class"].Value ==
                        HtmlClassMgr.ClassDefs["#Profile:favCharacterNode:class"])
                    .Descendants("li"))
                {
                    var curr        = new AnimeCharacter();
                    var imgNode     = favCharNode.Descendants("a").First();
                    var styleString = imgNode.Attributes["style"].Value.Substring(22);
                    curr.ImgUrl = styleString.Replace("/r/80x120", "");
                    curr.ImgUrl = curr.ImgUrl.Substring(0, curr.ImgUrl.IndexOf('?'));
                    var infoNode = favCharNode.Descendants("div").Skip(1).First();
                    var nameNode = infoNode.Descendants("a").First();
                    curr.Name = nameNode.InnerText.Trim();
                    curr.Id   = nameNode.Attributes["href"].Value.Substring(9).Split('/')[2];
                    var originNode = infoNode.Descendants("a").Skip(1).First();
                    curr.Notes     = originNode.InnerText.Trim();
                    curr.ShowId    = originNode.Attributes["href"].Value.Split('/')[2];
                    curr.FromAnime = originNode.Attributes["href"].Value.Split('/')[1] == "anime";
                    current.FavouriteCharacters.Add(curr);
                }
            }
            catch (Exception)
            {
                //no favs
            }

            #endregion

            #region FavManga

            try
            {
                foreach (
                    var favMangaNode in
                    doc.DocumentNode.Descendants("ul")
                    .First(
                        node =>
                        node.Attributes.Contains("class") &&
                        node.Attributes["class"].Value ==
                        HtmlClassMgr.ClassDefs["#Profile:favMangaNode:class"])
                    .Descendants("li"))
                {
                    current.FavouriteManga.Add(
                        int.Parse(
                            favMangaNode.Descendants("a").First().Attributes["href"].Value.Substring(9).Split('/')[2
                            ]));
                }
            }
            catch (Exception)
            {
                //no favs
            }

            #endregion

            #region FavAnime

            try
            {
                foreach (
                    var favAnimeNode in
                    doc.DocumentNode.Descendants("ul")
                    .First(
                        node =>
                        node.Attributes.Contains("class") &&
                        node.Attributes["class"].Value ==
                        HtmlClassMgr.ClassDefs["#Profile:favAnimeNode:class"])
                    .Descendants("li"))
                {
                    current.FavouriteAnime.Add(
                        int.Parse(
                            favAnimeNode.Descendants("a").First().Attributes["href"].Value.Substring(9).Split('/')[2
                            ]));
                }
            }
            catch (Exception)
            {
                //no favs
            }

            #endregion

            #region FavPpl

            try
            {
                foreach (
                    var favPersonNode in
                    doc.DocumentNode.Descendants("ul")
                    .First(
                        node =>
                        node.Attributes.Contains("class") &&
                        node.Attributes["class"].Value ==
                        HtmlClassMgr.ClassDefs["#Profile:favPeopleNode:class"])
                    .Descendants("li"))
                {
                    var curr        = new AnimeStaffPerson();
                    var aElems      = favPersonNode.Descendants("a");
                    var styleString = aElems.First().Attributes["style"].Value.Substring(22);
                    curr.ImgUrl = styleString.Replace("/r/80x120", "");
                    curr.ImgUrl = curr.ImgUrl.Substring(0, curr.ImgUrl.IndexOf('?'));

                    curr.Name = aElems.Skip(1).First().InnerText.Trim();
                    curr.Id   = aElems.Skip(1).First().Attributes["href"].Value.Substring(9).Split('/')[2];

                    current.FavouritePeople.Add(curr);
                }
            }
            catch (Exception)
            {
                //no favs
            }

            #endregion

            #region Stats
            if (!updateFavsOnly)
            {
                try
                {
                    var animeStats   = doc.FirstOfDescendantsWithClass("div", "stats anime");
                    var generalStats = animeStats.Descendants("div").First().Descendants("div");
                    current.AnimeDays = float.Parse(generalStats.First().InnerText.Substring(5).Trim());
                    current.AnimeMean = float.Parse(generalStats.Last().InnerText.Substring(11).Trim());
                    var i = 0;

                    #region AnimeStats

                    foreach (
                        var htmlNode in
                        animeStats.FirstOfDescendantsWithClass("ul", "stats-status fl-l").Descendants("li"))
                    {
                        switch (i)
                        {
                        case 0:
                            current.AnimeWatching =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;

                        case 1:
                            current.AnimeCompleted =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;

                        case 2:
                            current.AnimeOnHold =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;

                        case 3:
                            current.AnimeDropped =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;

                        case 4:
                            current.AnimePlanned =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;
                        }
                        i++;
                    }
                    //left stats done now right
                    i = 0;
                    foreach (
                        var htmlNode in animeStats.FirstOfDescendantsWithClass("ul", "stats-data fl-r").Descendants("li"))
                    {
                        switch (i)
                        {
                        case 0:
                            current.AnimeTotal =
                                int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim().Replace(",", ""));
                            break;

                        case 1:
                            current.AnimeRewatched =
                                int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim().Replace(",", ""));
                            break;

                        case 2:
                            current.AnimeEpisodes =
                                int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim().Replace(",", ""));
                            break;
                        }
                        i++;
                    }
                    //we are done with anime

                    #endregion

                    i                 = 0;
                    animeStats        = doc.FirstOfDescendantsWithClass("div", "stats manga");
                    generalStats      = animeStats.Descendants("div").First().Descendants("div");
                    current.MangaDays = float.Parse(generalStats.First().InnerText.Substring(5).Trim());
                    current.MangaMean = float.Parse(generalStats.Last().InnerText.Substring(11).Trim());

                    #region MangaStats

                    foreach (
                        var htmlNode in
                        animeStats.FirstOfDescendantsWithClass("ul", "stats-status fl-l").Descendants("li"))
                    {
                        switch (i)
                        {
                        case 0:
                            current.MangaReading =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;

                        case 1:
                            current.MangaCompleted =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;

                        case 2:
                            current.MangaOnHold =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;

                        case 3:
                            current.MangaDropped =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;

                        case 4:
                            current.MangaPlanned =
                                int.Parse(htmlNode.Descendants("span").First().InnerText.Trim().Replace(",", ""));
                            break;
                        }
                        i++;
                    }
                    //left stats done now right
                    i = 0;
                    foreach (
                        var htmlNode in animeStats.FirstOfDescendantsWithClass("ul", "stats-data fl-r").Descendants("li"))
                    {
                        switch (i)
                        {
                        case 0:
                            current.MangaTotal =
                                int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim().Replace(",", ""));
                            break;

                        case 1:
                            current.MangaReread =
                                int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim().Replace(",", ""));
                            break;

                        case 2:
                            current.MangaChapters =
                                int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim().Replace(",", ""));
                            break;

                        case 3:
                            current.MangaVolumes =
                                int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim().Replace(",", ""));
                            break;
                        }
                        i++;
                    }
                    //we are done with manga

                    #endregion
                }
                catch (Exception)
                {
                    //hatml
                }
            }

            #endregion

            #region LeftSideBar
            if (!updateFavsOnly)
            {
                try
                {
                    var sideInfo =
                        doc.FirstOfDescendantsWithClass("ul", "user-status border-top pb8 mb4").Descendants("li").ToList();
                    try
                    {
                        foreach (var htmlNode in sideInfo)
                        {
                            var left = WebUtility.HtmlDecode(htmlNode.FirstChild.InnerText);
                            if (left == "Supporter")
                            {
                                continue;
                            }
                            current.Details.Add(new Tuple <string, string>(left, WebUtility.HtmlDecode(htmlNode.LastChild.InnerText)));
                        }
                        //current.LastOnline = sideInfo[0].LastChild.InnerText;
                        //current.Gender = sideInfo[1].LastChild.InnerText;
                        //current.Birthday = sideInfo[2].LastChild.InnerText;
                        //current.Location = sideInfo[3].LastChild.InnerText;
                        //current.Joined = sideInfo[4].LastChild.InnerText;
                    }
                    catch (Exception)
                    {
                        //current.LastOnline = sideInfo[0].LastChild.InnerText;
                        //current.Joined = sideInfo[1].LastChild.InnerText;
                    }
                    current.User.ImgUrl =
                        doc.FirstOfDescendantsWithClass("div", "user-image mb8").Descendants("img").First().Attributes["src"
                        ]
                        .Value;
                }
                catch (Exception)
                {
                    //???
                }
            }

            #endregion

            #region Friends
            if (!updateFavsOnly)
            {
                try
                {
                    var friends = doc.FirstOfDescendantsWithClass("div", "user-friends pt4 pb12").Descendants("a");
                    foreach (var friend in friends)
                    {
                        var curr        = new MalUser();
                        var styleString = friend.Attributes["style"].Value.Substring(22);
                        curr.ImgUrl = styleString.Replace("/r/76x120", "");
                        curr.ImgUrl = curr.ImgUrl.Substring(0, curr.ImgUrl.IndexOf('?'));

                        curr.Name = friend.InnerText;
                        current.Friends.Add(curr);
                    }
                }
                catch (Exception)
                {
                    //
                }
            }

            #endregion

            #region Comments
            if (!updateFavsOnly)
            {
                try
                {
                    var commentBox = doc.FirstOfDescendantsWithClass("div", "user-comments mt24 pt24");
                    foreach (var comment in commentBox.WhereOfDescendantsWithClass("div", "comment clearfix"))
                    {
                        var curr = new MalComment();
                        curr.User.ImgUrl = comment.Descendants("img").First().Attributes["src"].Value;
                        var textBlock = comment.Descendants("div").First();
                        var header    = textBlock.Descendants("div").First();
                        curr.User.Name = header.ChildNodes[1].InnerText;
                        curr.Date      = header.ChildNodes[3].InnerText;
                        curr.Content   = WebUtility.HtmlDecode(textBlock.Descendants("div").Skip(1).First().InnerText.Trim());
                        var postActionNodes = comment.WhereOfDescendantsWithClass("a", "ml8");
                        var convNode        = postActionNodes.FirstOrDefault(node => node.InnerText.Trim() == "Conversation");
                        if (convNode != null)
                        {
                            curr.ComToCom = WebUtility.HtmlDecode(convNode.Attributes["href"].Value.Split('?').Last());
                        }
                        var deleteNode = postActionNodes.FirstOrDefault(node => node.InnerText.Trim() == "Delete");
                        if (deleteNode != null)
                        {
                            curr.CanDelete = true;
                            curr.Id        =
                                deleteNode.Attributes["onclick"].Value.Split(new char[] { '(', ')' },
                                                                             StringSplitOptions.RemoveEmptyEntries).Last();
                        }
                        foreach (var img in comment.Descendants("img").Skip(1))
                        {
                            if (img.Attributes.Contains("src"))
                            {
                                curr.Images.Add(img.Attributes["src"].Value);
                            }
                        }
                        current.Comments.Add(curr);
                    }
                }
                catch (Exception e)
                {
                    //no comments
                }
            }

            #endregion

            try
            {
                current.ProfileMemId = doc.DocumentNode.Descendants("input")
                                       .First(node => node.Attributes.Contains("name") && node.Attributes["name"].Value == "profileMemId")
                                       .Attributes["value"].Value;
            }
            catch (Exception)
            {
                //restricted
            }

            try
            {
                current.HtmlContent = doc.FirstOfDescendantsWithClass("div", "word-break").OuterHtml;
            }
            catch (Exception)
            {
                //
            }


            if (_userName == Credentials.UserName) //umm why do we need someone's favs?
            {
                FavouritesManager.ForceNewSet(FavouriteType.Anime, current.FavouriteAnime.Select(i => i.ToString()).ToList());
                FavouritesManager.ForceNewSet(FavouriteType.Manga, current.FavouriteManga.Select(i => i.ToString()).ToList());
                FavouritesManager.ForceNewSet(FavouriteType.Character, current.FavouriteCharacters.Select(i => i.Id).ToList());
                FavouritesManager.ForceNewSet(FavouriteType.Person, current.FavouritePeople.Select(i => i.Id).ToList());
            }


            if (!updateFavsOnly)
            {
                DataCache.SaveProfileData(_userName, current);
            }

            return(current);
        }
コード例 #4
0
        public async Task <CharacterDetailsData> GetCharacterDetails(bool force = false)
        {
            var possibleData = force ? null : await DataCache.RetrieveData <CharacterDetailsData>(_id.ToString(), "character_details", 30);

            if (possibleData != null)
            {
                return(possibleData);
            }

            var output = new CharacterDetailsData();
            var raw    = await GetRequestResponse();

            if (string.IsNullOrEmpty(raw))
            {
                return(output);
            }
            var doc = new HtmlDocument();

            doc.LoadHtml(raw);


            output.Id = _id;
            try
            {
                var columns    = doc.DocumentNode.Descendants("table").First().ChildNodes[1].ChildNodes.Where(node => node.Name == "td").ToList();
                var leftColumn = columns[0];
                var tables     = leftColumn.Descendants("table");
                foreach (var table in tables)
                {
                    foreach (var descendant in table.Descendants("tr"))
                    {
                        var links = descendant.Descendants("a").ToList();
                        if (links[0].Attributes["href"].Value.StartsWith("/anime"))
                        {
                            var curr = new AnimeLightEntry {
                                IsAnime = true
                            };
                            curr.Id = int.Parse(links[0].Attributes["href"].Value.Split('/')[2]);
                            var img = links[0].Descendants("img").First().Attributes["src"].Value;
                            if (!img.Contains("questionmark"))
                            {
                                img         = Regex.Replace(img, @"\/r\/\d+x\d+", "");
                                curr.ImgUrl = img.Substring(0, img.IndexOf('?'));
                            }
                            curr.Title = WebUtility.HtmlDecode(links[1].InnerText.Trim());
                            output.Animeography.Add(curr);
                        }
                        else
                        {
                            var curr = new AnimeLightEntry {
                                IsAnime = false
                            };
                            curr.Id = int.Parse(links[0].Attributes["href"].Value.Split('/')[2]);
                            var img = links[0].Descendants("img").First().Attributes["src"].Value;
                            if (!img.Contains("questionmark"))
                            {
                                img         = Regex.Replace(img, @"\/r\/\d+x\d+", "");
                                curr.ImgUrl = img.Substring(0, img.IndexOf('?'));
                            }
                            curr.Title = WebUtility.HtmlDecode(links[1].InnerText.Trim());
                            output.Mangaography.Add(curr);
                        }
                    }
                }
                var image = leftColumn.Descendants("img").First();
                if (image.Attributes.Contains("alt"))
                {
                    output.ImgUrl = image.Attributes["src"].Value;
                }

                output.Name     = WebUtility.HtmlDecode(doc.DocumentNode.Descendants("h1").First().InnerText).Trim().Replace("  ", " "); //because mal tends to leave two spaces there and there's pretty hardcore guy on github who can spot such things... props ;d
                output.Content  = output.SpoilerContent = "";
                output.Content += WebUtility.HtmlDecode(leftColumn.LastChild.InnerText.Trim()) + "\n\n";
                foreach (var node in columns[1].ChildNodes)
                {
                    if (node.Name == "#text")
                    {
                        output.Content += WebUtility.HtmlDecode(node.InnerText.Trim());
                    }
                    else if (node.Name == "br" && !output.Content.EndsWith("\n\n"))
                    {
                        output.Content += "\n";
                    }
                    else if (node.Name == "div" && node.Attributes.Contains("class") && node.Attributes["class"].Value == "spoiler")
                    {
                        output.SpoilerContent += WebUtility.HtmlDecode(node.InnerText.Trim()) + "\n\n";
                    }
                    else if (node.Name == "table")
                    {
                        foreach (var descendant in node.Descendants("tr"))
                        {
                            var current = new AnimeStaffPerson();
                            var img     = descendant.Descendants("img").First();
                            var imgUrl  = img.Attributes["src"].Value;
                            if (!imgUrl.Contains("questionmark"))
                            {
                                var pos = imgUrl.LastIndexOf("v");
                                if (pos != -1)
                                {
                                    imgUrl = imgUrl.Remove(pos, 1);
                                }
                            }
                            current.ImgUrl = imgUrl;
                            var info = descendant.Descendants("td").Last();
                            current.Id    = info.ChildNodes[0].Attributes["href"].Value.Split('/')[2];
                            current.Name  = WebUtility.HtmlDecode(info.ChildNodes[0].InnerText.Trim());
                            current.Notes = info.ChildNodes[2].InnerText;
                            output.VoiceActors.Add(current);
                        }
                    }
                }
                output.Content        = output.Content.Trim();
                output.SpoilerContent = output.SpoilerContent.Trim();
            }
            catch (Exception)
            {
                //html
            }

            DataCache.SaveData(output, _id.ToString(), "character_details");

            return(output);
        }
コード例 #5
0
        public async Task <ProfileData> GetProfileData(bool force = false, bool updateFavsOnly = false)
        {
            try
            {
                ProfileData possibleData = null;
                if (!force)
                {
                    possibleData = await DataCache.RetrieveProfileData(_userName);
                }
                if (possibleData != null)
                {
                    possibleData.Cached = true;
                    return(possibleData);
                }
                var raw = !updateFavsOnly
                    ? await(await (await ResourceLocator.MalHttpContextProvider.GetHttpContextAsync())
                            .GetAsync($"/profile/{_userName}")).Content.ReadAsStringAsync()
                    : await GetRequestResponse();

                var doc = new HtmlDocument();
                doc.LoadHtml(raw);
                var current = new ProfileData {
                    User = { Name = _userName }
                };

                #region Recents

                try
                {
                    var i = 1;
                    foreach (
                        var recentNode in
                        doc.DocumentNode.Descendants("div")
                        .Where(
                            node =>
                            node.Attributes.Contains("class") &&
                            node.Attributes["class"].Value ==
                            "statistics-updates di-b w100 mb8"))
                    {
                        if (i <= 3)
                        {
                            current.RecentAnime.Add(
                                int.Parse(
                                    recentNode.Descendants("a").First().Attributes["href"].Value.Substring(8)
                                    .Split('/')[2]));
                        }
                        else
                        {
                            current.RecentManga.Add(
                                int.Parse(
                                    recentNode.Descendants("a").First().Attributes["href"].Value.Substring(8)
                                    .Split('/')[2]));
                        }
                        i++;
                    }
                }
                catch (Exception)
                {
                    //no recents
                }

                #endregion

                #region FavChar

                try
                {
                    foreach (
                        var favCharNode in
                        doc.DocumentNode.Descendants("ul")
                        .First(
                            node =>
                            node.Attributes.Contains("class") &&
                            node.Attributes["class"].Value ==
                            "favorites-list characters")
                        .Descendants("li"))
                    {
                        var curr        = new AnimeCharacter();
                        var imgNode     = favCharNode.Descendants("a").First();
                        var styleString = imgNode.Attributes["style"].Value.Substring(22);
                        curr.ImgUrl = styleString.Replace("/r/80x120", "");
                        curr.ImgUrl = curr.ImgUrl.Substring(0, curr.ImgUrl.IndexOf('?'));
                        var infoNode = favCharNode.Descendants("div").Skip(1).First();
                        var nameNode = infoNode.Descendants("a").First();
                        curr.Name = nameNode.InnerText.Trim();
                        curr.Id   = nameNode.Attributes["href"].Value.Substring(9).Split('/')[2];
                        var originNode = infoNode.Descendants("a").Skip(1).First();
                        curr.Notes     = originNode.InnerText.Trim();
                        curr.ShowId    = originNode.Attributes["href"].Value.Split('/')[2];
                        curr.FromAnime = originNode.Attributes["href"].Value.Split('/')[1] == "anime";
                        current.FavouriteCharacters.Add(curr);
                    }
                }
                catch (Exception)
                {
                    //no favs
                }

                #endregion

                #region FavManga

                try
                {
                    foreach (
                        var favMangaNode in
                        doc.DocumentNode.Descendants("ul")
                        .First(
                            node =>
                            node.Attributes.Contains("class") &&
                            node.Attributes["class"].Value ==
                            "favorites-list manga")
                        .Descendants("li"))
                    {
                        current.FavouriteManga.Add(
                            int.Parse(
                                favMangaNode.Descendants("a").First().Attributes["href"].Value.Substring(9).Split('/')[2
                                ]));
                    }
                }
                catch (Exception)
                {
                    //no favs
                }

                #endregion

                #region FavAnime

                try
                {
                    foreach (
                        var favAnimeNode in
                        doc.DocumentNode.Descendants("ul")
                        .First(
                            node =>
                            node.Attributes.Contains("class") &&
                            node.Attributes["class"].Value ==
                            "favorites-list anime")
                        .Descendants("li"))
                    {
                        current.FavouriteAnime.Add(
                            int.Parse(
                                favAnimeNode.Descendants("a").First().Attributes["href"].Value.Substring(9).Split('/')[2
                                ]));
                    }
                }
                catch (Exception)
                {
                    //no favs
                }

                #endregion

                #region FavPpl

                try
                {
                    foreach (
                        var favPersonNode in
                        doc.DocumentNode.Descendants("ul")
                        .First(
                            node =>
                            node.Attributes.Contains("class") &&
                            node.Attributes["class"].Value ==
                            "favorites-list people")
                        .Descendants("li"))
                    {
                        var curr        = new AnimeStaffPerson();
                        var aElems      = favPersonNode.Descendants("a");
                        var styleString = aElems.First().Attributes["style"].Value.Substring(22);
                        curr.ImgUrl = styleString.Replace("/r/80x120", "");
                        curr.ImgUrl = curr.ImgUrl.Substring(0, curr.ImgUrl.IndexOf('?'));

                        curr.Name = aElems.Skip(1).First().InnerText.Trim();
                        curr.Id   = aElems.Skip(1).First().Attributes["href"].Value.Substring(9).Split('/')[2];

                        current.FavouritePeople.Add(curr);
                    }
                }
                catch (Exception)
                {
                    //no favs
                }

                #endregion

                #region Stats

                if (!updateFavsOnly)
                {
                    try
                    {
                        var animeStats   = doc.FirstOfDescendantsWithClass("div", "stats anime");
                        var generalStats = animeStats.Descendants("div").First().Descendants("div");
                        current.AnimeDays = float.Parse(generalStats.First().InnerText.Substring(5).Trim(),
                                                        NumberStyles.Any, CultureInfo.InvariantCulture);
                        current.AnimeMean = float.Parse(generalStats.Last().InnerText.Substring(11).Trim(),
                                                        NumberStyles.Any, CultureInfo.InvariantCulture);
                        var i = 0;

                        #region AnimeStats

                        foreach (
                            var htmlNode in
                            animeStats.FirstOfDescendantsWithClass("ul", "stats-status fl-l").Descendants("li"))
                        {
                            switch (i)
                            {
                            case 0:
                                current.AnimeWatching =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 1:
                                current.AnimeCompleted =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 2:
                                current.AnimeOnHold =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 3:
                                current.AnimeDropped =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 4:
                                current.AnimePlanned =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;
                            }
                            i++;
                        }
                        //left stats done now right
                        i = 0;
                        foreach (
                            var htmlNode in animeStats.FirstOfDescendantsWithClass("ul", "stats-data fl-r")
                            .Descendants("li"))
                        {
                            switch (i)
                            {
                            case 0:
                                current.AnimeTotal =
                                    int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 1:
                                current.AnimeRewatched =
                                    int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 2:
                                current.AnimeEpisodes =
                                    int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim()
                                              .Replace(",", ""));
                                break;
                            }
                            i++;
                        }
                        //we are done with anime

                        #endregion

                        i                 = 0;
                        animeStats        = doc.FirstOfDescendantsWithClass("div", "stats manga");
                        generalStats      = animeStats.Descendants("div").First().Descendants("div");
                        current.MangaDays = float.Parse(generalStats.First().InnerText.Substring(5).Trim(),
                                                        NumberStyles.Any, CultureInfo.InvariantCulture);
                        current.MangaMean = float.Parse(generalStats.Last().InnerText.Substring(11).Trim(),
                                                        NumberStyles.Any, CultureInfo.InvariantCulture);

                        #region MangaStats

                        foreach (
                            var htmlNode in
                            animeStats.FirstOfDescendantsWithClass("ul", "stats-status fl-l").Descendants("li"))
                        {
                            switch (i)
                            {
                            case 0:
                                current.MangaReading =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 1:
                                current.MangaCompleted =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 2:
                                current.MangaOnHold =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 3:
                                current.MangaDropped =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 4:
                                current.MangaPlanned =
                                    int.Parse(htmlNode.Descendants("span").First().InnerText.Trim()
                                              .Replace(",", ""));
                                break;
                            }
                            i++;
                        }
                        //left stats done now right
                        i = 0;
                        foreach (
                            var htmlNode in animeStats.FirstOfDescendantsWithClass("ul", "stats-data fl-r")
                            .Descendants("li"))
                        {
                            switch (i)
                            {
                            case 0:
                                current.MangaTotal =
                                    int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 1:
                                current.MangaReread =
                                    int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 2:
                                current.MangaChapters =
                                    int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim()
                                              .Replace(",", ""));
                                break;

                            case 3:
                                current.MangaVolumes =
                                    int.Parse(htmlNode.Descendants("span").Last().InnerText.Trim()
                                              .Replace(",", ""));
                                break;
                            }
                            i++;
                        }
                        //we are done with manga

                        #endregion
                    }
                    catch (Exception e)
                    {
                        //hatml
                    }
                }

                #endregion

                #region LeftSideBar

                if (!updateFavsOnly)
                {
                    try
                    {
                        var sideInfo =
                            doc.FirstOfDescendantsWithClass("ul", "user-status border-top pb8 mb4").Descendants("li")
                            .ToList();
                        try
                        {
                            foreach (var htmlNode in sideInfo)
                            {
                                var left = WebUtility.HtmlDecode(htmlNode.FirstChild.InnerText);
                                if (left == "Supporter")
                                {
                                    continue;
                                }
                                current.Details.Add(new Tuple <string, string>(left,
                                                                               WebUtility.HtmlDecode(htmlNode.LastChild.InnerText)));
                            }
                        }
                        catch (Exception)
                        {
                        }
                        current.User.ImgUrl =
                            doc.FirstOfDescendantsWithClass("div", "user-image mb8").Descendants("img").First()
                            .Attributes["src"].Value;
                    }
                    catch (Exception)
                    {
                        //???
                    }
                }

                #endregion

                #region Friends

                if (!updateFavsOnly)
                {
                    try
                    {
                        var friends = doc.FirstOfDescendantsWithClass("div", "user-friends pt4 pb12").Descendants("a");
                        foreach (var friend in friends)
                        {
                            var curr        = new MalUser();
                            var styleString = friend.Attributes["data-bg"].Value;
                            curr.ImgUrl = styleString.Replace("/r/76x120", "");
                            curr.ImgUrl = curr.ImgUrl.Substring(0, curr.ImgUrl.IndexOf('?'));

                            curr.Name = friend.InnerText;
                            current.Friends.Add(curr);
                        }
                    }
                    catch (Exception)
                    {
                        //
                    }
                }

                #endregion

                #region Comments

                if (!updateFavsOnly)
                {
                    try
                    {
                        var commentBox = doc.FirstOfDescendantsWithClass("div", "user-comments mt24 pt24");
                        foreach (var comment in commentBox.WhereOfDescendantsWithClass("div", "comment clearfix"))
                        {
                            var curr    = new MalComment();
                            var imgNode = comment.Descendants("img").First();
                            if (imgNode.Attributes.Contains("srcset"))
                            {
                                curr.User.ImgUrl = imgNode.Attributes["srcset"].Value.Split(',').Last()
                                                   .Replace("2x", "").Trim();
                            }
                            else if (imgNode.Attributes.Contains("data-src"))
                            {
                                curr.User.ImgUrl = imgNode.Attributes["data-src"].Value;
                            }


                            var textBlock = comment.Descendants("div").First();
                            var header    = textBlock.Descendants("div").First();
                            curr.User.Name = header.ChildNodes[1].InnerText;
                            curr.Date      = header.ChildNodes[3].InnerText;
                            curr.Content   =
                                WebUtility.HtmlDecode(textBlock.Descendants("div").Skip(1).First().InnerText.Trim());
                            var postActionNodes = comment.WhereOfDescendantsWithClass("a", "ml8");
                            var convNode        =
                                postActionNodes.FirstOrDefault(node => node.InnerText.Trim() == "Conversation");
                            if (convNode != null)
                            {
                                curr.ComToCom =
                                    WebUtility.HtmlDecode(convNode.Attributes["href"].Value.Split('?').Last());
                            }
                            var deleteNode = postActionNodes.FirstOrDefault(node => node.InnerText.Trim() == "Delete");
                            if (deleteNode != null)
                            {
                                curr.CanDelete = true;
                                curr.Id        =
                                    deleteNode.Attributes["onclick"].Value.Split(new char[] { '(', ')' },
                                                                                 StringSplitOptions.RemoveEmptyEntries).Last();
                            }
                            foreach (var img in comment.Descendants("img").Skip(1))
                            {
                                if (img.Attributes.Contains("src"))
                                {
                                    curr.Images.Add(img.Attributes["src"].Value);
                                }
                            }
                            current.Comments.Add(curr);
                        }
                    }
                    catch (Exception e)
                    {
                        //no comments
                    }
                }

                #endregion

                try
                {
                    current.ProfileMemId = doc.DocumentNode.Descendants("input")
                                           .First(node => node.Attributes.Contains("name") &&
                                                  node.Attributes["name"].Value == "profileMemId")
                                           .Attributes["value"].Value;
                }
                catch (Exception)
                {
                    //restricted
                }

                try
                {
                    current.HtmlContent = doc.FirstOfDescendantsWithClass("div", "profile-about-user js-truncate-inner").OuterHtml;
                }
                catch (Exception)
                {
                    //
                }


                if (_userName.Equals(Credentials.UserName, StringComparison.CurrentCultureIgnoreCase)) //umm why do we need someone's favs?
                {
                    FavouritesManager.ForceNewSet(FavouriteType.Anime,
                                                  current.FavouriteAnime.Select(i => i.ToString()).ToList());
                    FavouritesManager.ForceNewSet(FavouriteType.Manga,
                                                  current.FavouriteManga.Select(i => i.ToString()).ToList());
                    FavouritesManager.ForceNewSet(FavouriteType.Character,
                                                  current.FavouriteCharacters.Select(i => i.Id).ToList());
                    FavouritesManager.ForceNewSet(FavouriteType.Person,
                                                  current.FavouritePeople.Select(i => i.Id).ToList());
                }

                current.IsFriend =
                    doc.FirstOrDefaultOfDescendantsWithClass("a", "icon-user-function icon-remove js-user-function") != null;

                current.CanAddFriend =
                    doc.FirstOrDefaultOfDescendantsWithClass("a", "icon-user-function icon-request js-user-function") != null;

                if (!updateFavsOnly)
                {
                    DataCache.SaveProfileData(_userName, current);
                }
                return(current);
            }
            catch (Exception e)
            {
                ResourceLocator.TelemetryProvider.LogEvent($"Profile Query Crash: {_userName}, {e}");
                ResourceLocator.MessageDialogProvider.ShowMessageDialog(
                    "Hmm, you have encountered bug that'm hunting. I've just sent report to myself. If everything goes well it should be gone in next release :). Sorry for inconvenience!",
                    "Ooopsies!");
            }
            return(new ProfileData());
        }