/// <summary> /// Turns message into editable bbcode /// </summary> /// <param name="id"></param> /// <returns></returns> public static async Task<string> GetMessageBbcode(string id) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var data = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("msg_id", id), new KeyValuePair<string, string>("csrf_token", client.Token), }; var requestContent = new FormUrlEncodedContent(data); var response = await client.PostAsync( $"/includes/ajax.inc.php?t=85", requestContent); if (!response.IsSuccessStatusCode) return null; return JsonConvert.DeserializeObject<MessageBbcodeResponse>(await response.Content.ReadAsStringAsync()) .message; } catch (Exception) { return null; } }
public async Task <List <MalMessageModel> > GetSentMessages(int page = 1) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); string path = $"/mymessages.php?go=sent"; var res = await client.GetAsync(path); var body = await res.Content.ReadAsStringAsync(); var output = new List <MalMessageModel>(); var doc = new HtmlDocument(); doc.LoadHtml(body); output.AddRange( doc.WhereOfDescendantsWithClass("div", "message read spot2 clearfix") .Select(ParseOutboxHtmlToMalMessage)); return(output); } catch (WebException) { MalHttpContextProvider.ErrorMessage("Messages"); } return(new List <MalMessageModel>()); }
/// <summary> /// Creates message in a topic /// </summary> /// <param name="id">Id of the topic</param> /// <param name="message"></param> /// <returns></returns> public static async Task<bool> CreateMessage(string id, string message) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var data = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("msg_text", message), new KeyValuePair<string, string>("csrf_token", client.Token), new KeyValuePair<string, string>("submit", "Submit") }; var requestContent = new FormUrlEncodedContent(data); var response = await client.PostAsync( $"/forum/?action=message&topic_id={id}", requestContent); //var response = // await client.PostAsync( // $"/forum/?action=message&topic_id=1586126", requestContent); return response.IsSuccessStatusCode; } catch (Exception) { return false; } }
public static async Task <bool> SendComment(string username, string userId, string comment) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var contentPairs = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("profileMemId", userId), new KeyValuePair <string, string>("commentText", comment), new KeyValuePair <string, string>("profileUsername", username), new KeyValuePair <string, string>("csrf_token", client.Token), new KeyValuePair <string, string>("commentSubmit", "Submit Comment") }; var content = new FormUrlEncodedContent(contentPairs); var response = await client.PostAsync("/addcomment.php", content); return(response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.SeeOther); } catch (WebException) { MalHttpContextProvider.ErrorMessage("Messages"); return(false); } }
/// <summary> /// When we send new message we don't really know its id so we have to pull it. /// Once we have that we will be able to pull thread id. /// </summary> public async Task <string> GetFirstSentMessageId() { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var res = await client.GetAsync("/mymessages.php?go=sent"); var body = await res.Content.ReadAsStringAsync(); try { var doc = new HtmlDocument(); doc.LoadHtml(body); //?go=read&id=8473147&f=1 var id = doc.FirstOfDescendantsWithClass("div", "message read spot2 clearfix") .Descendants("a") .Skip(1) .First() .Attributes["href"].Value.Split('=')[2]; return(id.Substring(0, id.Length - 2)); } catch (Exception) { return("0"); } } catch (WebException) { MalHttpContextProvider.ErrorMessage("Messages"); } return("0"); }
private async Task InitPlacements() { var client = await MalHttpContextProvider.GetHttpContextAsync(); var raw = await(await client.GetAsync("")).Content.ReadAsStringAsync(); var doc = new HtmlDocument(); doc.LoadHtml(raw); try { _animePlacement = doc.FirstOfDescendantsWithId("div", "v-auto-recommendation-personalized_anime").Attributes[ "data-placement"].Value; } catch (Exception) { //not present } try { _mangaPlacement = doc.FirstOfDescendantsWithId("div", "v-auto-recommendation-personalized_manga").Attributes[ "data-placement"].Value; } catch (Exception) { //not present } if (_animePlacement == null && _mangaPlacement == null) { throw new Exception(); } }
public async Task <List <MalMessageModel> > GetMessages(int page = 1) { var client = await MalHttpContextProvider.GetHttpContextAsync(); string path = $"/mymessages.php?go=&show={page*20 - 20}"; var res = await client.GetAsync(path); var body = await res.Content.ReadAsStringAsync(); var output = new List <MalMessageModel>(); if (body.Contains("You have 0 messages")) { return(output); } var doc = new HtmlDocument(); doc.LoadHtml(body); output.AddRange( doc.WhereOfDescendantsWithClass("div", "message unread spot1 clearfix") .Select(msgNode => ParseInboxHtmlToMalMessage(msgNode, false))); output.AddRange( doc.WhereOfDescendantsWithClass("div", "message read spot1 clearfix") .Select(msgNode => ParseInboxHtmlToMalMessage(msgNode, true))); return(output); }
/// <summary> /// Change topic watching status. /// </summary> /// <param name="id"></param> /// <returns>Returns null when failed, true when topic is being watched and false when it's not.</returns> public static async Task<bool?> ToggleTopicWatching(string id) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var data = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("topic_id", id), new KeyValuePair<string, string>("timestamp", $"{DateTime.Now.ToLocalTime():ddd MMM dd yyyy hh:mm:ss \"GMT\"K} ({TimeZoneInfo.Local.StandardName})"), new KeyValuePair<string, string>("csrf_token", client.Token), }; var requestContent = new FormUrlEncodedContent(data); var response = await client.PostAsync( "/includes/ajax.inc.php?t=69", requestContent); if (!response.IsSuccessStatusCode) return null; return (await response.Content.ReadAsStringAsync()) == "Watching"; }
public async Task <List <AnimePersonalizedRecommendationData> > GetPersonalizedRecommendations(bool force = false) { var possibleData = force ? null : await DataCache.RetrieveData <List <AnimePersonalizedRecommendationData> >("personalized_suggestions", _anime? "Anime" : "Manga", 1); if (possibleData?.Any() ?? false) { return(possibleData); } if (_animePlacement == null && _mangaPlacement == null) { try { await InitPlacements(); } catch (Exception) { return(new List <AnimePersonalizedRecommendationData>()); } } var client = await MalHttpContextProvider.GetHttpContextAsync(); var raw = await(await client.GetAsync( $"/auto_recommendation/personalized_suggestions.json?placement={(_anime ? _animePlacement : _mangaPlacement)}")) .Content.ReadAsStringAsync(); var data = JsonConvert.DeserializeObject <List <AnimePersonalizedRecommendationData> >(raw) ?? new List <AnimePersonalizedRecommendationData>(); DataCache.SaveData(data, "personalized_suggestions", _anime ? "Anime" : "Manga"); return(data); }
/// <summary> /// Send reply message. /// </summary> /// <returns></returns> public async Task <bool> SendMessage(string subject, string message, string targetUser, string threadId, string replyId) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var contentPairs = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("subject", subject), new KeyValuePair <string, string>("message", message), new KeyValuePair <string, string>("csrf_token", client.Token), new KeyValuePair <string, string>("sendmessage", "Send Message") }; var content = new FormUrlEncodedContent(contentPairs); var response = await client.PostAsync( $"/mymessages.php?go=send&replyid={replyId}&threadid={threadId}&toname={targetUser}", content); return(response.IsSuccessStatusCode); } catch (Exception) { MalHttpContextProvider.ErrorMessage("Messages"); return(false); } }
public static async Task <bool> SendCommentReply(string userId, string comment) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var contentPairs = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("profileMemId", userId), new KeyValuePair <string, string>("commentText", comment), new KeyValuePair <string, string>("area", "2"), new KeyValuePair <string, string>("csrf_token", client.Token), new KeyValuePair <string, string>("commentSubmit", "1") }; var content = new FormUrlEncodedContent(contentPairs); var response = await client.PostAsync("/addcomment.php", content); //edit comment function - not sure what it does // /includes/ajax.inc.php?t=73 //com id - token //id = 31985758 & csrf_token = dfsdfsd //client.PostAsync("/includes/ajax.inc.php?t=73") return(response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.SeeOther); } catch (WebException) { MalHttpContextProvider.ErrorMessage("Messages"); return(false); } }
public static async Task<bool> DeleteComment(string id) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var data = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("msgId", id), new KeyValuePair<string, string>("csrf_token", client.Token), }; var requestContent = new FormUrlEncodedContent(data); var response = await client.PostAsync( "/includes/ajax.inc.php?t=84", requestContent); return response.IsSuccessStatusCode; } catch (Exception) { return false; } }
private static async Task<Tuple<bool,string>> CreateNewTopic(string title, string message, string endpoint, string question = null, List<string> answers = null) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var data = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("topic_title", title), new KeyValuePair<string, string>("msg_text", message), new KeyValuePair<string, string>("csrf_token", client.Token), new KeyValuePair<string, string>("submit", "Submit") }; if (!string.IsNullOrEmpty(question) && answers != null) { if (answers.Count > 0) { data.Add(new KeyValuePair<string, string>("pollQuestion", question)); data.AddRange(answers.Select(answer => new KeyValuePair<string, string>("pollOption[]", answer))); } } var requestContent = new FormUrlEncodedContent(data); var response = await client.PostAsync(endpoint, requestContent); //var response = // await client.PostAsync( // "/forum/?action=post&club_id=73089", requestContent); if (!response.IsSuccessStatusCode) return new Tuple<bool, string>(false,null); try { var resp = await response.Content.ReadAsStringAsync(); if(resp.Contains("badresult")) return new Tuple<bool, string>(false,null); var doc = new HtmlDocument(); doc.LoadHtml(resp); var wrapper = doc.FirstOfDescendantsWithId("div", "contentWrapper"); var matches = Regex.Match(wrapper.InnerHtml, @"topicid=(\d+)"); return new Tuple<bool, string>(true,matches.Groups[1].Value); } catch (Exception) { return new Tuple<bool, string>(true,null); } } catch (Exception) { return new Tuple<bool, string>(false, null); } }
public async Task <List <MalMessageModel> > GetMessagesInThread(MalMessageModel msg) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var response = await client.GetAsync($"/mymessages.php?go=read&id={msg.Id}&threadid={msg.ThreadId}"); var raw = await response.Content.ReadAsStringAsync(); var doc = new HtmlDocument(); doc.LoadHtml(raw); var output = new List <MalMessageModel>(); foreach ( var msgHistoryNode in doc.FirstOfDescendantsWithClass("table", "pmessage-message-history").Descendants("tr")) { var current = new MalMessageModel(); var tds = msgHistoryNode.Descendants("td").ToList(); current.Content = WebUtility.HtmlDecode(tds[2].InnerText.Trim()); if (string.IsNullOrEmpty(current.Content)) { continue; } try { foreach (var img in msgHistoryNode.Descendants("img")) { current.Images.Add(img.Attributes["src"].Value); } } catch (Exception e) { //no images } current.Subject = msg.Subject; current.Date = tds[0].InnerText.Trim(); current.Sender = tds[1].InnerText.Trim(); output.Add(current); } return(output); } catch (Exception) { MalHttpContextProvider.ErrorMessage("Messages"); } return(new List <MalMessageModel>()); }
public async Task <List <MalComment> > GetComments() { var raw = await(await MalHttpContextProvider.GetHttpContextAsync()).GetAsync($"/profile/{_userName}"); var doc = new HtmlDocument(); doc.LoadHtml(await raw.Content.ReadAsStringAsync()); var output = new List <MalComment>(); 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(); } output.Add(curr); } } catch (Exception) { //no comments } await Task.Run(async() => { var data = await DataCache.RetrieveProfileData(_userName); if (data != null) { data.Comments = output; } DataCache.SaveProfileData(_userName, data); }); return(output); }
public async Task <MalMessageModel> GetMessageDetails(MalMessageModel msg, bool sentMessage) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var response = await client.GetAsync($"/mymessages.php?go=read&id={msg.Id}{(sentMessage ? "&f=1" : "")}"); var raw = await response.Content.ReadAsStringAsync(); var doc = new HtmlDocument(); doc.LoadHtml(raw); var msgNode = doc.FirstOfDescendantsWithClass("td", "dialog-text"); var msgContent = msgNode.ChildNodes.Skip(3) .Where(node => node.NodeType == HtmlNodeType.Text) .Aggregate("", (current, textNode) => current + textNode.InnerText); msg.Content = WebUtility.HtmlDecode(msgContent.Trim()); var ids = doc.FirstOfDescendantsWithClass("input", "inputButton btn-middle flat").Attributes["onclick"].Value .Split('='); try { foreach (var img in msgNode.Descendants("img")) { msg.Images.Add(img.Attributes["src"].Value); } } catch (Exception e) { //no images } msg.ThreadId = ids[4].Substring(0, ids[3].IndexOf('&')); msg.ReplyId = ids[3].Substring(0, ids[3].IndexOf('&')); return(msg); } catch (WebException) { MalHttpContextProvider.ErrorMessage("Messages"); } return(new MalMessageModel()); }
public static async Task <List <MalMessageModel> > GetComToComMessages(string path) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var response = await client.GetAsync($"/comtocom.php?{path}"); var doc = new HtmlDocument(); doc.LoadHtml(await response.Content.ReadAsStringAsync()); var output = new List <MalMessageModel>(); foreach (var commentBox in doc.FirstOfDescendantsWithId("div", "content").ChildNodes.Where(node => node.Name == "div").Skip(1)) { try { var current = new MalMessageModel(); current.Content = WebUtility.HtmlDecode(commentBox.FirstOfDescendantsWithClass("div", "spaceit").InnerText).Trim(); current.Date = commentBox.Descendants("small").First().InnerText.Trim(new[] { '|', ' ' }); current.Sender = WebUtility.HtmlDecode(commentBox.Descendants("a").Skip(1).First().InnerText.Trim()); foreach (var img in commentBox.Descendants("img").Skip(1)) { if (img.Attributes.Contains("src")) { current.Images.Add(img.Attributes["src"].Value); } } output.Add(current); } catch (Exception) { //html } } output.Reverse(); return(output); } catch (WebException) { MalHttpContextProvider.ErrorMessage("Messages"); return(new List <MalMessageModel>()); } }
public static async Task <ForumBoardContent> GetSearchResults(string query, ForumBoards?searchScope) { var scope = searchScope == null ? -1 : (int)searchScope; var output = new ForumBoardContent { Pages = 0 }; if (query.Length > 2) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var resp = await client.GetAsync($"/forum/search?q={query}&u=&uloc=1&loc={scope}"); var doc = new HtmlDocument(); doc.LoadHtml(await resp.Content.ReadAsStringAsync()); var s = await resp.Content.ReadAsStringAsync(); var topicContainer = doc.DocumentNode.Descendants("table") .First( node => node.Attributes.Contains("id") && node.Attributes["id"].Value == "forumTopics"); foreach (var topicRow in topicContainer.Descendants("tr").Skip(1)) //skip forum table header { try { output.ForumTopicEntries.Add(ParseTopicRow(topicRow)); } catch (Exception) { // } } } catch (Exception e) { // } } return(output); }
/// <summary> /// Moves needed cookies to globaly used client by WebViews control, web view authentication in other words. /// </summary> /// <returns></returns> public static async Task InitializeContextForWebViews(bool mobile) { if (_webViewsInitialized) { return; } _webViewsInitialized = true; var filter = new HttpBaseProtocolFilter(); var httpContext = await MalHttpContextProvider.GetHttpContextAsync(); var cookies = httpContext.Handler.CookieContainer.GetCookies(new Uri(MalHttpContextProvider.MalBaseUrl)); if (mobile) { filter.CookieManager.SetCookie(new HttpCookie("view", "myanimelist.net", "/") { Value = "sp" }); } foreach (var cookie in cookies.Cast <Cookie>()) { try { var newCookie = new HttpCookie(cookie.Name, cookie.Domain, cookie.Path) { Value = cookie.Value }; filter.CookieManager.SetCookie(newCookie); } catch (Exception) { var msg = new MessageDialog("Authorization failed while rewriting cookies, I don't know why this is happenning and after hours of debugging it fixed itself after reinstall. :(", "Something went wrong™"); await msg.ShowAsync(); } } filter.AllowAutoRedirect = true; Windows.Web.Http.HttpClient client = new Windows.Web.Http.HttpClient(filter); //use globaly by webviews }
public static async Task <ForumBoardContent> GetWatchedTopics() { var output = new ForumBoardContent { Pages = 0 }; try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var resp = await client.GetAsync("/forum/?action=viewstarred"); var doc = new HtmlDocument(); doc.LoadHtml(await resp.Content.ReadAsStringAsync()); var topicContainer = doc.DocumentNode.Descendants("table") .First( node => node.Attributes.Contains("id") && node.Attributes["id"].Value == "forumTopics"); foreach (var topicRow in topicContainer.Descendants("tr").Skip(1)) //skip forum table header { try { output.ForumTopicEntries.Add(ParseTopicRow(topicRow, 1)); } catch (Exception) { // } } } catch (Exception) { // } return(output); }
public static async Task <bool> DeleteComment(string id) { try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var contentPairs = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("id", id), new KeyValuePair <string, string>("csrf_token", client.Token), }; var content = new FormUrlEncodedContent(contentPairs); var response = await client.PostAsync("/includes/ajax.inc.php?t=78 ", content); return(response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.SeeOther); } catch (WebException) { MalHttpContextProvider.ErrorMessage("Messages"); return(false); } }
public void Include(MalHttpContextProvider vm) { var vm1 = new MalHttpContextProvider(); }
private async void LoadMore(bool force = false) { LoadingVisibility = true; if (force) { if (DisplaySentMessages) { Outbox = new List <MalMessageModel>(); } else { _loadedPages = 1; Inbox = new List <MalMessageModel>(); } } if (!DisplaySentMessages) { try { if (!_skipLoading) { _loadedSomething = true; try { Inbox.AddRange(await AccountMessagesManager.GetMessagesAsync(_loadedPages++)); } catch (WebException) { MalHttpContextProvider.ErrorMessage("Messages"); } } _skipLoading = false; MessageIndex.Clear(); MessageIndex.AddRange(Inbox); LoadMorePagesVisibility = true; } catch (ArgumentOutOfRangeException) { LoadMorePagesVisibility = false; } } else { try { if (Outbox.Count == 0) { Outbox = await AccountMessagesManager.GetSentMessagesAsync(); } MessageIndex.Clear(); MessageIndex.AddRange(Outbox); LoadMorePagesVisibility = false; } catch (Exception) { MalHttpContextProvider.ErrorMessage("Messages"); } } LoadingVisibility = false; }
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); }
/// <summary> /// Returns tons of data about topic. /// </summary> /// <param name="topicId">Self explanatory</param> /// <param name="page">Page starting from 1</param> /// <param name="lastpage">Override page to last page?</param> /// <param name="messageId"></param> /// <param name="force">Forces cache ignore</param> /// <returns></returns> public static async Task<ForumTopicData> GetTopicData(string topicId,int page,bool lastpage = false,long? messageId = null,bool force = false) { if(!force && !lastpage && messageId == null && topicId != null && CachedMessagesDictionary.ContainsKey(topicId)) if (CachedMessagesDictionary[topicId].ContainsKey(page)) return CachedMessagesDictionary[topicId][page]; try { var client = await MalHttpContextProvider.GetHttpContextAsync(); var response = await client.GetAsync( lastpage ? $"/forum/?topicid={topicId}&goto=lastpost" : messageId != null ? $"/forum/message/{messageId}?goto=topic" : $"/forum/?topicid={topicId}&show={(page - 1) * 50}"); if ((lastpage || messageId != null) && response.StatusCode == HttpStatusCode.RedirectMethod) { response = await client.GetAsync(response.Headers.Location); } var doc = new HtmlDocument(); doc.Load(await response.Content.ReadAsStreamAsync()); var foundMembers = new Dictionary<string,MalForumUser>(); var output = new ForumTopicData {Id = topicId}; if (messageId != null && messageId != -1) output.TargetMessageId = messageId.ToString(); try { var pager = doc.FirstOfDescendantsWithClass("div", "fl-r pb4"); var lastLinkNode = pager.Descendants("a").LastOrDefault(node => node.InnerText.Contains("Last")); if (lastLinkNode != null) { output.AllPages = (int.Parse(lastLinkNode .Attributes["href"] .Value.Split('=').Last()) / 50) + 1; } else { var nodes = pager.ChildNodes.Where(node => !string.IsNullOrWhiteSpace(node.InnerText) && node.InnerText != "»"); output.AllPages = int.Parse(nodes.Last().InnerText.Replace("[","").Replace("]","").Trim()); } } catch (Exception) { output.AllPages = 1; } if(!lastpage) try { var pageNodes = doc.FirstOfDescendantsWithClass("div", "fl-r pb4").ChildNodes.Where(node => node.Name != "a"); output.CurrentPage = int.Parse( pageNodes.First(node => Regex.IsMatch(node.InnerText.Trim(), @"\[.*\]")) .InnerText.Replace("[", "").Replace("]", "").Trim()); } catch (Exception e) { output.CurrentPage = output.AllPages; } else { output.CurrentPage = output.AllPages; } output.Title = WebUtility.HtmlDecode(doc.FirstOrDefaultOfDescendantsWithClass("h1", "forum_locheader")?.InnerText.Trim()); if (output.Title == null) { output.Title = WebUtility.HtmlDecode(doc.FirstOrDefaultOfDescendantsWithClass("h1", "forum_locheader icon-forum-locked")?.InnerText.Trim()); if (output.Title != null) { output.IsLocked = true; } } foreach (var bradcrumb in doc.FirstOfDescendantsWithClass("div", "breadcrumb").ChildNodes.Where(node => node.Name == "div")) { output.Breadcrumbs.Add(new ForumBreadcrumb { Name = WebUtility.HtmlDecode(bradcrumb.InnerText.Trim()), Link = bradcrumb.Descendants("a").First().Attributes["href"].Value }); } if (topicId == null) //in case of redirection { var uri = response.RequestMessage.RequestUri.AbsoluteUri; output.TargetMessageId = uri.Split('#').Last().Replace("msg", ""); var pos = uri.IndexOf('&'); if (pos != -1) { uri = uri.Substring(0, pos); topicId = uri.Split('=').Last(); } output.Id = topicId; } foreach (var row in doc.WhereOfDescendantsWithClass("div", "forum_border_around")) { var current = new ForumMessageEntry {TopicId = topicId}; current.Id = row.Attributes["id"].Value.Replace("forumMsg", ""); var divs = row.ChildNodes.Where(node => node.Name == "div").ToList(); var headerDivs = divs[0].Descendants("div").ToList(); current.CreateDate = WebUtility.HtmlDecode(headerDivs[2].InnerText.Trim()); current.MessageNumber = WebUtility.HtmlDecode(headerDivs[1].InnerText.Trim()); var tds = row.Descendants("tr").First().ChildNodes.Where(node => node.Name == "td").ToList(); var posterName = WebUtility.HtmlDecode(tds[0].Descendants("strong").First().InnerText.Trim()); if (foundMembers.ContainsKey(posterName)) { current.Poster = foundMembers[posterName]; } else { var poster = new MalForumUser(); poster.MalUser.Name = posterName; poster.Title = WebUtility.HtmlDecode(tds[0].FirstOrDefaultOfDescendantsWithClass("div", "custom-forum-title")?.InnerText.Trim()); poster.MalUser.ImgUrl = tds[0].Descendants("img") .FirstOrDefault( node => node.Attributes.Contains("src") && node.Attributes["src"].Value.Contains("useravatars"))?.Attributes["src"].Value; if (tds[0].ChildNodes[1].ChildNodes.Count == 10) { poster.Status = tds[0].ChildNodes[1].ChildNodes[5].InnerText.Trim(); poster.Joined = tds[0].ChildNodes[1].ChildNodes[7].InnerText.Trim(); poster.Posts = tds[0].ChildNodes[1].ChildNodes[9].InnerText.Trim(); } else if (tds[0].ChildNodes[1].ChildNodes.Count == 11) { poster.Status = tds[0].ChildNodes[1].ChildNodes[6].InnerText.Trim(); poster.Joined = tds[0].ChildNodes[1].ChildNodes[8].InnerText.Trim(); poster.Posts = tds[0].ChildNodes[1].ChildNodes[10].InnerText.Trim(); } else { poster.Status = tds[0].ChildNodes[1].ChildNodes[2].InnerText.Trim(); poster.Joined = tds[0].ChildNodes[1].ChildNodes[4].InnerText.Trim(); poster.Posts = tds[0].ChildNodes[1].ChildNodes[6].InnerText.Trim(); } try { poster.SignatureHtml = tds[1].FirstOfDescendantsWithClass("div", "sig").OuterHtml; } catch (Exception) { //no signature } foundMembers.Add(posterName,poster); current.Poster = poster; } current.EditDate = WebUtility.HtmlDecode(tds[1].Descendants("em").FirstOrDefault()?.InnerText.Trim()); current.HtmlContent = tds[1].Descendants("div") .First( node => node.Attributes.Contains("id") && node.Attributes["id"].Value == $"message{current.Id}") .OuterHtml; var actions = row.FirstOfDescendantsWithClass("div", "postActions"); current.CanEdit = actions.ChildNodes[0].ChildNodes.Any(node => node.InnerText?.Contains("Edit") ?? false); current.CanDelete = actions.ChildNodes[0].ChildNodes.Any(node => node.InnerText?.Contains("Delete") ?? false); output.Messages.Add(current); } if (!CachedMessagesDictionary.ContainsKey(topicId)) CachedMessagesDictionary.Add(topicId, new Dictionary<int, ForumTopicData> { {output.CurrentPage, output} }); else { if (CachedMessagesDictionary[topicId].ContainsKey(output.CurrentPage)) CachedMessagesDictionary[topicId][output.CurrentPage] = output; else CachedMessagesDictionary[topicId].Add(output.CurrentPage, output); } return output; } catch (Exception) { return new ForumTopicData(); } }