コード例 #1
0
        async ValueTask <IReadOnlyList <DiscordEmbedBuilder> > CheckRssListUpdates <TRss, TLe, TL>(
            MalUser dbUser, User user, DateTimeOffset lastUpdateDateTime, Action <string, DateTimeOffset, MalUser> dbUpdateAction,
            CancellationToken ct) where TRss : struct, IRssFeedType where TLe : class, IListEntry where TL : struct, IListType <TLe>
        {
            var rssUpdates = await this._client.GetRecentRssUpdatesAsync <TRss>(user.Username, ct).ConfigureAwait(false);

            var type    = new TRss().Type;
            var updates = rssUpdates.Where(update => update.PublishingDateTimeOffset > lastUpdateDateTime)
                          .Select(item => item.ToRecentUpdate(type)).OrderByDescending(u => u.UpdateDateTime).ToArray();

            if (!updates.Any())
            {
                return(Array.Empty <DiscordEmbedBuilder>());
            }

            var list = await this._client.GetLatestListUpdatesAsync <TLe, TL>(user.Username, ct).ConfigureAwait(false);

            foreach (var update in updates)
            {
                var latest = list.FirstOrDefault(entry => entry.Id == update.Id);
                if (latest == null)
                {
                    continue;
                }
                else
                {
                    dbUpdateAction(latest.GetHash().ToHashString(), update.UpdateDateTime, dbUser);
                    break;
                }
            }

            return(updates.Select(update => list.First(entry => entry.Id == update.Id)
                                  .ToDiscordEmbedBuilder(user, update.UpdateDateTime, dbUser.Features)).ToArray());
        }
コード例 #2
0
        private async Task <List <UserFeedEntryModel> > GetUserFeed(MalUser user)
        {
            try
            {
                var resp   = await new FeedQuery(user.Name).GetRequestResponse();
                var output = new List <UserFeedEntryModel>();

                var xmlDoc = XElement.Parse(resp);
                var nodes  = xmlDoc.Element("channel").Elements("item").Take(Settings.FeedsMaxEntries);
                foreach (var node in nodes)
                {
                    var current = new UserFeedEntryModel();
                    current.Date = DateTime.Parse(node.Element("pubDate").Value);
                    if (DateTime.UtcNow.Subtract(current.Date).TotalDays > Settings.FeedsMaxEntryAge)
                    {
                        continue;
                    }

                    current.User        = user;
                    current.Header      = node.Element("title").Value;
                    current.Link        = node.Element("link").Value;
                    current.Description = node.Element("description").Value;
                    var linkParts = current.Link.Substring(10).Split('/');
                    current.Id = int.Parse(linkParts[2]);
                    var pos = current.Header.LastIndexOf('-');
                    current.Title = current.Header.Substring(0, pos).Trim();
                    output.Add(current);
                }
                return(output);
            }
            catch (Exception)
            {
                return(null);
            }
        }
コード例 #3
0
 public void ResetStarredMessages(MalUser user)
 {
     if (_starredMessages.ContainsKey(user.Name.ToLower()))
     {
         _starredMessages.Remove(user.Name.ToLower());
         _updated = true;
     }
 }
コード例 #4
0
        private void MemberDataTemplateFling(View view1, int i, MalUser arg3)
        {
            var img = view1.FindViewById <ImageViewAsync>(Resource.Id.ProfilePageGeneralTabFriendItemImage);

            if (img.IntoIfLoaded(arg3.ImgUrl))
            {
                img.Visibility = ViewStates.Invisible;
            }
        }
コード例 #5
0
        public bool IsMessageStarred(string forumMessageId, MalUser poster)
        {
            var key = poster.Name.ToLower();

            if (_starredMessages.ContainsKey(key))
            {
                return(_starredMessages[key].Any(message => message.MessageId == forumMessageId));
            }
            return(false);
        }
コード例 #6
0
        public static async Task <MalUser?> GetUser(bool setSettings = true)
        {
            try {
                string data = await GetApi("https://api.myanimelist.net/v2/users/@me");

                if (data.IsClean())
                {
                    MalUser user = JsonConvert.DeserializeObject <MalUser>(data);
                    if (user.picture.Contains("?t="))
                    {
                        user.picture = user.picture[..user.picture.IndexOf("?")];
コード例 #7
0
        async Task <IReadOnlyList <DiscordEmbedBuilder> > CheckProfileListUpdatesAsync <TLe, TL>(
            MalUser dbUser, User user, int latestUpdateId, DateTimeOffset latestUpdateDateTime,
            Action <string, DateTimeOffset, MalUser> dbUpdateAction, CancellationToken ct)
            where TLe : class, IListEntry where TL : struct, IListType <TLe>
        {
            var listUpdates = await this._client.GetLatestListUpdatesAsync <TLe, TL>(user.Username, ct).ConfigureAwait(false);

            var lastListUpdate = listUpdates.First(u => u.Id == latestUpdateId);

            dbUpdateAction(lastListUpdate.GetHash().ToHashString(), latestUpdateDateTime, dbUser);

            return(new[] { lastListUpdate.ToDiscordEmbedBuilder(user, DateTimeOffset.Now, dbUser.Features) });
        }
コード例 #8
0
        public void UnstarForumMessage(string messageId, MalUser poster)
        {
            var key = poster.Name.ToLower();

            if (_starredMessages.ContainsKey(key))
            {
                _starredMessages[key].RemoveAt(
                    _starredMessages[key].FindIndex(message => message.MessageId == messageId));
                if (!_starredMessages[key].Any())
                {
                    _starredMessages.Remove(key);
                }
            }
            _updated = true;
        }
コード例 #9
0
        public static async Task <List <MalUser> > GetMoreUsers(string clubId)
        {
            var output = new List <MalUser>();

            try
            {
                var client = await ResourceLocator.MalHttpContextProvider.GetHttpContextAsync();


                var response =
                    await client.GetAsync($"/clubs.php?id={clubId}&action=view&t=members");

                if (!response.IsSuccessStatusCode)
                {
                    return(null);
                }

                var doc = new HtmlDocument();
                doc.LoadHtml(await response.Content.ReadAsStringAsync());

                foreach (var htmlNode in doc.DocumentNode.WhereOfDescendantsWithClass("td", "borderClass"))
                {
                    var current = new MalUser();

                    current.Name = WebUtility.HtmlDecode(htmlNode.InnerText.Trim());

                    try
                    {
                        current.ImgUrl = htmlNode.Descendants("img").First().Attributes["src"].Value
                                         .Replace("/thumbs", "").Replace("_thumb", "");
                    }
                    catch (Exception)
                    {
                        //picture
                    }

                    output.Add(current);
                }

                return(output);
            }
            catch (Exception)
            {
                return(null);
            }
        }
コード例 #10
0
        private View GetFriendTemplateDelegate(int i, MalUser malUser, View convertView)
        {
            var view = convertView;

            if (view == null)
            {
                view        = Activity.LayoutInflater.Inflate(Resource.Layout.ProfilePageGeneralTabFriendItem, null);
                view.Click += FriendButtonOnClick;
            }

            var img = (view as FrameLayout).FindViewById <ImageViewAsync>(Resource.Id.ProfilePageGeneralTabFriendItemImage);

            img.Into(malUser.ImgUrl);

            view.Tag = malUser.Wrap();

            return(view);
        }
コード例 #11
0
        private View GetTagItem(int i, MalUser s, View convertView)
        {
            var view = convertView;

            if (view == null)
            {
                view = MainActivity.CurrentContext.LayoutInflater.Inflate(Resource.Layout.PinnedUsersDialogItem, null);
                view.FindViewById <ImageButton>(Resource.Id.DeleteButton).Click +=
                    (sender, args) =>
                {
                    _dataStorageModule.StoredItems.Remove((sender as View).Tag.Unwrap <MalUser>());
                    if (ViewModelLocator.GeneralMain.CurrentMainPage == PageIndex.PageProfile)
                    {
                        ViewModelLocator.ProfilePage.RaisePropertyChanged("IsPinned");
                    }
                };

                view.SetOnClickListener(new OnClickListener(v =>
                {
                    ViewModelLocator.NavMgr.ResetMainBackNav();
                    ViewModelLocator.NavMgr.RegisterBackNav(PageIndex.PageAnimeList, null);
                    ViewModelLocator.GeneralMain.Navigate(
                        PageIndex.PageProfile,
                        new ProfilePageNavigationArgs {
                        TargetUser = v.Tag.Unwrap <MalUser>().Name
                    });

                    CleanupDialog();
                }));
            }
            var tag = s.Wrap();

            view.Tag = tag;
            view.FindViewById <ImageButton>(Resource.Id.DeleteButton).Tag = tag;
            view.FindViewById <TextView>(Resource.Id.Name).Text           = s.Name;
            view.FindViewById <ImageViewAsync>(Resource.Id.ProfileImg).Into(s.ImgUrl, new CircleTransformation());
            return(view);
        }
コード例 #12
0
 static void DbAnimeUpdateAction(string h, DateTimeOffset dto, MalUser u)
 {
     u.LastAnimeUpdateHash           = h;
     u.LastUpdatedAnimeListTimestamp = dto;
 }
コード例 #13
0
 private void MemberDataTemplateFull(View view1, int i, MalUser arg3)
 {
     view1.FindViewById <ImageViewAsync>(Resource.Id.ProfilePageGeneralTabFriendItemImage).Into(arg3.ImgUrl);
 }
コード例 #14
0
 static void DbMangaUpdateAction(string h, DateTimeOffset dto, MalUser u)
 {
     u.LastMangaUpdateHash           = h;
     u.LastUpdatedMangaListTimestamp = dto;
 }
コード例 #15
0
        public async Task <ProfileData> GetProfileData(bool force = false)
        {
            ProfileData possibleData = null;

            if (!force)
            {
                possibleData = await DataCache.RetrieveProfileData(_userName);
            }
            if (possibleData != null)
            {
                return(possibleData);
            }
            var raw = 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 FavCharacter();
                    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.OriginatingShowName = 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 FavPerson();
                    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
            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());
                int 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

            try
            {
                var sideInfo = doc.FirstOfDescendantsWithClass("ul", "user-status border-top pb8 mb4").Descendants("li").ToList();
                current.User.ImgUrl =
                    doc.FirstOfDescendantsWithClass("div", "user-image mb8").Descendants("img").First().Attributes["src"]
                    .Value;
                try
                {
                    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;
                }
            }
            catch (Exception)
            {
                //???
            }


            #endregion

            #region Friends

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

            #endregion

            #region Comments

            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());
                    current.Comments.Add(curr);
                }
            }
            catch (Exception)
            {
                //no comments
            }


            #endregion

            DataCache.SaveProfileData(_userName, current);

            return(current);
        }
コード例 #16
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());
        }
コード例 #17
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);
        }
コード例 #18
0
        public static async Task <MalClubDetails> GetClubDetails(string clubId, bool justComments = false)
        {
            try
            {
                var output = new MalClubDetails {
                    Id = clubId
                };
                var client = await ResourceLocator.MalHttpContextProvider.GetHttpContextAsync();


                var response =
                    await client.GetAsync($"/clubs.php?cid={clubId}");

                if (!response.IsSuccessStatusCode)
                {
                    return(null);
                }

                var doc = new HtmlDocument();
                doc.LoadHtml(await response.Content.ReadAsStringAsync());

                var mainFrame = doc.DocumentNode.Descendants("table").First();
                var rightBar  = mainFrame.ChildNodes[1].ChildNodes[3].ChildNodes[1];
                var rightDivs =
                    rightBar.ChildNodes.Where(node => node.Name == "div" && node.Attributes.Contains("class") &&
                                              (node.Attributes["class"].Value == "normal_header" ||
                                               node.Attributes["class"].Value == "spaceit_pad" ||
                                               node.Attributes["class"].Value == "borderClass"));
                var leftBar      = mainFrame.ChildNodes[1].ChildNodes[1].ChildNodes[1];
                var membersTable = leftBar.ChildNodes.First(node => node.Name == "table");

                if (!justComments)
                {
                    output.Name = WebUtility.HtmlDecode(doc.DocumentNode.Descendants("h1").First().InnerText);

                    output.DescriptionHtml = doc.FirstOfDescendantsWithClassContaining("div", "club-information-header")
                                             .ParentNode.ChildNodes
                                             .First(node => node.Attributes.Contains("class") &&
                                                    node.Attributes["class"].Value == "clearfix").InnerHtml;


                    try
                    {
                        output.ImgUrl = rightBar.Descendants("img")
                                        .First(node => node.Attributes.Contains("src") &&
                                               node.Attributes["src"].Value.Contains("/clubs/")).Attributes["src"].Value;
                    }
                    catch (Exception)
                    {
                        //image magic tajm
                    }
                    int mode = 0;
                    foreach (var rightDiv in rightDivs)
                    {
                        if (rightDiv.Attributes["class"].Value == "normal_header")
                        {
                            switch (WebUtility.HtmlDecode(rightDiv.InnerText.Trim()))
                            {
                            case "Club Stats":
                                mode = 0;
                                break;

                            case "Club Officers":
                                mode = 1;
                                break;

                            case "Anime Relations":
                                mode = 2;
                                break;

                            case "Manga Relations":
                                mode = 3;
                                break;

                            case "Character Relations":
                                mode = 4;
                                break;

                            default:
                                mode = -1;
                                break;
                            }
                            continue;
                        }

                        string[] innerTextTokens;
                        HtmlNode link = null;
                        switch (mode)
                        {
                        case 0:
                            if (rightDiv.InnerText.Contains("Pictures"))
                            {
                                continue;
                            }
                            innerTextTokens = WebUtility.HtmlDecode(rightDiv.InnerText.Trim()).Split(':');
                            output.GeneralInfo.Add((innerTextTokens[0], innerTextTokens[1]));
                            break;

                        case 1:
                            link = rightDiv.Descendants("a").First();
                            var    name = (WebUtility.HtmlDecode(link.InnerText.Trim()));
                            string role = null;
                            if (rightDiv.InnerText.Contains("(") && rightDiv.InnerText.Contains(")"))
                            {
                                role = rightDiv.InnerText.Replace(name, "").Replace("(", "").Replace(")", "")
                                       .Trim();
                            }

                            output.Officers.Add((name, string.IsNullOrEmpty(role) ? "Officer" : role));
                            break;

                        case 2:
                            link = rightDiv.Descendants("a").First();
                            output.AnimeRelations.Add(
                                (WebUtility.HtmlDecode(link.InnerText.Trim()), link.Attributes["href"].Value
                                 .Split('=')
                                 .Last()));
                            break;

                        case 3:
                            link = rightDiv.Descendants("a").First();
                            output.MangaRelations.Add(
                                (WebUtility.HtmlDecode(link.InnerText.Trim()), link.Attributes["href"].Value
                                 .Split('=')
                                 .Last()));
                            break;

                        case 4:
                            link = rightDiv.Descendants("a").First();
                            output.CharacterRelations.Add(
                                (WebUtility.HtmlDecode(link.InnerText.Trim()), link.Attributes["href"].Value
                                 .Split('=')
                                 .Last()));
                            break;

                        default:
                            continue;
                        }
                    }

                    output.IsPublic = !rightBar.InnerText.Contains("This is a private club.");
                    output.Joined   = rightBar.InnerText.Contains("Leave Club");



                    foreach (var member in membersTable.Descendants("td"))
                    {
                        var innerDivs = member.ChildNodes.Where(node => node.Name == "div").ToList();
                        var current   = new MalUser();
                        current.Name = WebUtility.HtmlDecode(innerDivs[0].InnerText.Trim());
                        try
                        {
                            current.ImgUrl = member.Descendants("img").First().Attributes["src"].Value
                                             .Replace("/thumbs", "").Replace("_thumb", "");
                        }
                        catch (Exception e)
                        {
                            //yes image again
                        }
                        output.MembersPeek.Add(current);
                    }
                }
                foreach (var htmlNode in leftBar.WhereOfDescendantsWithPartialId("div", "comment"))
                {
                    var current  = new MalClubComment();
                    var tds      = htmlNode.Descendants("td").Skip(1).First();
                    var firstDiv = WebUtility.HtmlDecode(tds.ChildNodes.FindFirst("div").InnerText.Trim()).Split('|')
                                   .Select(s => s.Trim()).ToList();

                    current.User.Name = firstDiv[0];
                    current.Date      = firstDiv[1];
                    current.Content   = WebUtility.HtmlDecode(tds.InnerText).Trim();
                    current.Content   = current.Content.Replace(current.Date, "");
                    current.Content   = current.Content.Substring(current.Content.IndexOf('|') + 1).Trim();
                    try
                    {
                        current.User.ImgUrl = htmlNode.FirstOfDescendantsWithClass("div", "picSurround")
                                              .Descendants("img").First().Attributes["src"].Value
                                              .Replace("/thumbs", "").Replace("_thumb", "");
                    }
                    catch (Exception e)
                    {
                        //yes image again
                    }
                    var delComment = htmlNode.Descendants("small").LastOrDefault();
                    if (delComment != null && !delComment.InnerText.Contains("|"))
                    {
                        var txt = delComment.Descendants("a").First().Attributes.First(attribute => attribute.Value.Contains("delComment")).Value
                                  .Replace("delComment", "");
                        var pos = txt.IndexOf(',');
                        current.Id = txt.Substring(0, pos - 1);

                        current.Content = current.Content.Substring(0, current.Content.Length - 6);
                    }
                    try
                    {
                        foreach (var image in htmlNode.WhereOfDescendantsWithClass("img", "userimg"))
                        {
                            current.Images.Add(image.Attributes["src"].Value);
                        }
                    }
                    catch (Exception)
                    {
                        //images strike
                    }
                    output.RecentComments.Add(current);
                }

                return(output);
            }
            catch (Exception)
            {
                //here we go again... meh... yes it's html you guessed right
                return(null);
            }
        }