public void RetrievingSeiyuuInformationWorksCorrectly() { // arrange const int seiyuuId = 40; var fixture = new RequestProcessorFixture(); var document = new HtmlDocument(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", $"{seiyuuId}.html"); using (var htmlFile = File.Open(examplePath, FileMode.Open)) { document.Load(htmlFile); } fixture.PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.SeiyuuUrl(seiyuuId))) .ReturnsAsync(new HtmlDocumentRetrievalWrapper(HttpStatusCode.OK, true, document)); var sut = fixture.Instance; // act var retrievalWrapper = sut.DoSeiyuuRetrieval(seiyuuId).Result; // assert retrievalWrapper.ResponseStatusCode.Should().Be(HttpStatusCode.OK); retrievalWrapper.Success.Should().BeTrue(); retrievalWrapper.ResponseData.Id.Should().Be(seiyuuId); retrievalWrapper.ResponseData.Name.Should().Be("Mamiko Noto"); retrievalWrapper.ResponseData.ErrorOccured.Should().BeFalse(); }
/// <summary> /// Retrieve a Seiyuu from MAL /// </summary> /// <param name="seiyuuId"></param> /// <returns></returns> public async Task <RetrievalWrapper <Seiyuu> > DoSeiyuuRetrieval(int seiyuuId) { var seiyuu = new Seiyuu { Id = seiyuuId }; try { var seiyuuResponse = await _pageRetriever.RetrieveHtmlPageAsync(MalRouteBuilder.SeiyuuUrl(seiyuuId)); if (seiyuuResponse.ResponseStatusCode == null) { throw seiyuuResponse.Exception; } var seiyuuDoc = seiyuuResponse.Document; seiyuu .RetrieveName(seiyuuDoc) .RetrieveGivenName(seiyuuDoc) .RetrieveFamilyName(seiyuuDoc) .RetrieveBirthday(seiyuuDoc) .RetrieveAdditionalInformation(seiyuuDoc) .RetrieveWebsite(seiyuuDoc) .RetrieveRoles(seiyuuDoc); return(new RetrievalWrapper <Seiyuu>(seiyuuResponse.ResponseStatusCode.Value, seiyuuResponse.Success, seiyuu)); } catch (Exception exception) { seiyuu.ErrorOccured = true; seiyuu.ErrorMessage = exception.Message; return(new RetrievalWrapper <Seiyuu>(exception, seiyuu)); } }
public void FailedHttpRetrievalDoesNotCauseAnException() { // arrange const int malId = 13127; var fixture = new RequestProcessorFixture(); var document = new HtmlDocument(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", $"{malId}.html"); using (var htmlFile = File.Open(examplePath, FileMode.Open)) { document.Load(htmlFile); } fixture.PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeUrl(malId))) .ReturnsAsync(new HtmlDocumentRetrievalWrapper(HttpStatusCode.NotFound, true, document)); var sut = fixture.Instance; var act = new Action(() => sut.GetAnime(malId).Wait()); // act // assert act.ShouldNotThrow <Exception>(); }
public void RetrievingListCorrectlyRetrievesUserInformation() { // arrange const string user = "******"; var fixture = new ListRetrievalWorkerFixture(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", "UserList.xml"); var data = File.ReadAllText(examplePath); fixture.PageRetrieverMock .Setup(t => t.RetrieveDocumentAsStringAsync(MalRouteBuilder.UserListUrl(user))) .ReturnsAsync(new StringRetrievalWrapper(HttpStatusCode.OK, true, data)); var sut = fixture.Instance; // act var result = sut.RetrieveUserListAsync(user).Result; // assert result.Info.Should().NotBeNull(); result.Info.UserId.Should().Be("112255"); result.Info.Username.Should().Be("Test"); result.Info.Watching.Should().Be(47); result.Info.Completed.Should().Be(490); result.Info.OnHold.Should().Be(2); result.Info.Dropped.Should().Be(23); result.Info.PlanToWatch.Should().Be(886); result.Info.DaysWatching.Should().Be(93.98); }
/// <summary> /// Parse the node data for Related items into a list of <see cref="Related"/> items /// </summary> /// <param name="node">Node that should be processed</param> /// <returns>List of related anime</returns> private static IEnumerable <Related> ParseRelatedNodeData(HtmlNode node) { var relatedShows = new List <Related>(); var linkNodes = node .ChildNodes[1] .ChildNodes .Where(x => x.Name == "a") .ToList(); foreach (var link in linkNodes) { var url = MalRouteBuilder.MalCleanUrl(link.Attributes["href"].Value); int id; int.TryParse(url.Split('/')[4], out id); relatedShows.Add(new Related { Id = id, Title = link.InnerText, Url = url }); } return(relatedShows); }
public void RetrievingAnimeCorrectlyRetrievesTheSynopsis() { // arrange const int animeId = 11757; var fixture = new RequestProcessorFixture(animeId); var document = new HtmlDocument(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", $"{animeId}LoggedIn.html"); using (var htmlFile = File.Open(examplePath, FileMode.Open)) { document.Load(htmlFile); } fixture.PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeUrl(animeId))) .ReturnsAsync(new HtmlDocumentRetrievalWrapper(HttpStatusCode.OK, true, document)); var sut = fixture.Instance; // act var result = sut.GetAnime(animeId).Result; // assert result.ResponseData.Synopsis.Should().NotBeNullOrEmpty(); }
public void RetrievingAnimeWithUsernameAndPasswordPopulatesTheUserFields() { // arrange const int animeId = 11757; var fixture = new RequestProcessorFixture(animeId); const string user = "******"; const string pass = "******"; var document = new HtmlDocument(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", $"{animeId}LoggedIn.html"); using (var htmlFile = File.Open(examplePath, FileMode.Open)) { document.Load(htmlFile); } fixture.PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeUrl(animeId), user, pass)) .ReturnsAsync(new HtmlDocumentRetrievalWrapper(HttpStatusCode.OK, true, document)); var sut = fixture.Instance; // act var result = sut.GetAnime(animeId, user, pass).Result; // assert fixture.PageRetrieverMock.Verify(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeCharacterUrl(animeId)), Times.Once); result.ResponseData.UserScore.Should().Be(10); result.ResponseData.UserWatchedEpisodes.Should().Be(25); result.ResponseData.UserWatchedStatus.Should().Be("Completed"); }
/// <summary> /// Create a <see cref="Roles"/> instance and populate it with anime data /// </summary> /// <param name="roleNodes">Nodes containing role information</param> /// <returns>Role instance with populated anime data</returns> private static Roles CreateRoleAndPopulateWithAnimeInformation(IReadOnlyList <HtmlNode> roleNodes) { var role = new Roles { AnimeUrl = MalRouteBuilder.MalCleanUrl(roleNodes[0] .ChildNodes["div"] .ChildNodes["a"] ?.Attributes["href"] .Value) }; int id; int.TryParse(role.AnimeUrl.Split('/')[4], out id); role.AnimeId = id; var animeImg = roleNodes[0] .ChildNodes["div"] .ChildNodes["a"] ?.ChildNodes["img"]; role.AnimePicUrl = (animeImg?.Attributes["data-src"] ?? animeImg?.Attributes["src"])?.Value; role.AnimeTitle = roleNodes[1] .ChildNodes["a"] ?.InnerText; return(role); }
public void CredentialVerificationRespondsCorrectly(bool validResult, HttpStatusCode statusCode) { // arrange const string user = "******"; const string pass = "******"; var fixture = new RequestProcessorFixture(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", "ValidUser.xml"); var data = File.ReadAllText(examplePath); if (validResult) { fixture.PageRetrieverMock.Setup( t => t.RetrieveDocumentAsStringAsync(MalRouteBuilder.VerifyCredentialsUrl(), user, pass)) .ReturnsAsync(new StringRetrievalWrapper(HttpStatusCode.OK, true, data)); } else { fixture.PageRetrieverMock.Setup( t => t.RetrieveDocumentAsStringAsync(MalRouteBuilder.VerifyCredentialsUrl(), user, pass)) .ReturnsAsync(new StringRetrievalWrapper(HttpStatusCode.Unauthorized, false, "Invalid credentials")); } var sut = fixture.Instance; // act var result = sut.VerifyCredentials(user, pass).Result; // assert result.ResponseStatusCode.Should().Be(statusCode); result.Success.Should().Be(validResult); }
public void LoadingCharacterInformationWorksCorrectly() { // arrange const int characterId = 36828; var fixture = new RequestProcessorFixture(); var document = new HtmlDocument(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", $"{characterId}.html"); using (var htmlFile = File.Open(examplePath, FileMode.Open)) { document.Load(htmlFile); } fixture.PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeCharacterUrl(characterId))) .ReturnsAsync(new HtmlDocumentRetrievalWrapper(HttpStatusCode.OK, true, document)); var sut = fixture.Instance; // act var retrievalWrapper = sut.DoCharacterRetrieval(characterId).Result; // assert retrievalWrapper.Success.Should().BeTrue(); retrievalWrapper.ResponseStatusCode.Should().Be(HttpStatusCode.OK); retrievalWrapper.ResponseData.Name.Should().Be("Asuna Yuuki (結城 明日奈 / アスナ)"); retrievalWrapper.ResponseData.Id.Should().Be(characterId); }
/// <summary> /// Populate a <see cref="Roles"/> with character information /// </summary> /// <param name="role">Role instance that should be populated</param> /// <param name="roleNodes">Nodes containing role information</param> private static Roles PopulateRoleWithCharacterInformation(this Roles role, IReadOnlyList <HtmlNode> roleNodes) { role.CharacterName = roleNodes[2] .ChildNodes["a"] .InnerText .Trim(); role.CharacterUrl = MalRouteBuilder.MalCleanUrl(roleNodes[2] .ChildNodes["a"] .Attributes["href"] .Value); int id; int.TryParse(role.CharacterUrl.Split('/')[4], out id); role.CharacterId = id; role.RoleType = roleNodes[2] .ChildNodes["div"] .InnerText .Replace(" ", "") .Trim(); var charImage = roleNodes[3] .ChildNodes["div"] .ChildNodes["a"] .ChildNodes["img"]; role.CharacterPic = (charImage?.Attributes["data-src"] ?? charImage?.Attributes["src"])?.Value; return(role); }
/// <summary> /// Populate Seiyuu information for a character /// </summary> /// <param name="character">Character to which the Seiyuu information should be added</param> /// <param name="seiyuuInfoNodes">HtmlNodes containing the Seiyuu information</param> /// <returns>Character instance</returns> private static CharacterInformation PopulateSeiyuu(this CharacterInformation character, IEnumerable <HtmlNode> seiyuuInfoNodes) { foreach (var detail in seiyuuInfoNodes) { var picNode = detail.ChildNodes[3] .ChildNodes["div"] .ChildNodes["a"] .ChildNodes["img"]; var tmpSeiyuu = new SeiyuuInformation { Language = detail.ChildNodes["td"].ChildNodes["small"].InnerText, Name = detail.ChildNodes["td"].ChildNodes["a"].InnerText, Url = MalRouteBuilder.MalCleanUrl(detail.ChildNodes["td"].ChildNodes["a"].Attributes["href"].Value), PictureUrl = (picNode.Attributes["data-src"] ?? picNode.Attributes["src"])?.Value }; int id; if (int.TryParse(tmpSeiyuu.Url.Split('/')[4], out id)) { tmpSeiyuu.Id = id; } character.Seiyuu.Add(tmpSeiyuu); } return(character); }
public void UpdatingExistingAnimeWorksCorrectly() { // arrange const string url = "http://localhost:8654"; const string path = "/api/animelist/update/0.xml"; MalRouteBuilder.AdjustRoot(url); var httpMock = HttpMockRepository.At(url); httpMock.Stub(t => t.Post(path)) .OK(); var animeDummy = new Mock <AnimeUpdate>(); var userAnimeDummy = new UserListAnime(); const string user = "******"; const string pass = "******"; var fixture = new DataPushWorkerFixture(); var userListDummy = new UserList(); fixture.ListRetrievalWorkerMock.Setup(t => t.RetrieveUserListAsync(user)) .ReturnsAsync(userListDummy); userAnimeDummy.SeriesId = 0; userListDummy.Anime.Add(userAnimeDummy); var sut = fixture.Instance; // act var result = sut.PushAnimeDetailsToMal(animeDummy.Object, user, pass).Result; // assert result.Success.Should().BeTrue(); result.ResponseStatusCode.Should().Be(HttpStatusCode.OK); httpMock.AssertWasCalled(x => x.Post(path)); }
public async Task IfAnimeDoesNotExistAnErrorIsPassedBackToTheCaller() { // arrange const int malId = 13127; var fixture = new RequestProcessorFixture(); var document = new HtmlDocument(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", $"{malId}.html"); using (var htmlFile = File.Open(examplePath, FileMode.Open)) { document.Load(htmlFile); } fixture.PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeUrl(malId))) .ReturnsAsync(new HtmlDocumentRetrievalWrapper(HttpStatusCode.NotFound, true, document)); var sut = fixture.Instance; // act var result = await sut.GetAnime(malId); // assert result.ResponseStatusCode.Should().Be(HttpStatusCode.NotFound); result.Success.Should().BeFalse(); }
/// <summary> /// Verify user credentials /// </summary> /// <param name="username">Username</param> /// <param name="password">Password</param> /// <returns>True - Credentials are valid, otherwise false</returns> public async Task <DataPushResponseWrapper> VerifyCredentials(string username, string password) { var page = await _pageRetriever.RetrieveDocumentAsStringAsync(MalRouteBuilder.VerifyCredentialsUrl(), username, password); if (page.ResponseStatusCode == null) { return(new DataPushResponseWrapper(page.Exception)); } return(new DataPushResponseWrapper(page.ResponseStatusCode.Value, page.Success)); }
public RequestProcessorFixture(int malId) : this() { var characterDocument = new HtmlDocument(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", $"{malId}CharacterInfo.html"); using (var htmlFile = File.Open(examplePath, FileMode.Open)) { characterDocument.Load(htmlFile); } PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeCharacterUrl(malId))) .ReturnsAsync(new HtmlDocumentRetrievalWrapper(HttpStatusCode.OK, true, characterDocument)); }
/// <summary> /// Retrieve character's seiyuu /// </summary> /// <param name="character">Character instance to populate</param> /// <param name="doc">Html document from which data should be pulled</param> /// <returns>Character instance</returns> public static Character RetrieveSeiyuu(this Character character, HtmlDocument doc) { var tables = doc.DocumentNode .SelectNodes("//table") .Skip(3); foreach (var table in tables) { var seiyuu = new SeiyuuInformation(); var info = table .ChildNodes["tr"] .ChildNodes .Where(x => x.Name == "td") .ToList(); seiyuu.PictureUrl = info[0] .ChildNodes["div"] .ChildNodes["a"] .ChildNodes["img"] .Attributes["src"] .Value; seiyuu.Name = info[1] .ChildNodes["a"] .InnerText; seiyuu.Url = MalRouteBuilder.MalCleanUrl(info[1] .ChildNodes["a"] .Attributes["href"] .Value); int id; if (int.TryParse(seiyuu.Url.Split('/')[4], out id)) { seiyuu.Id = id; } character.Seiyuu.Add(seiyuu); } return(character); }
public void LoadingInvalidDataCorrectlyMarksTheItemAsError() { // arrange const int animeId = 11757; var fixture = new RequestProcessorFixture(animeId); fixture.PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeUrl(animeId))) .Throws(new Exception("Cannot load")); var sut = fixture.Instance; // act var result = sut.GetAnime(animeId).Result; // assert result.Exception.Should().NotBeNull(); result.ResponseData.ErrorOccured.Should().BeTrue(); result.ResponseData.ErrorMessage.Should().Be("Cannot load"); }
public void LoadingSeiyuuWithErrorCorrectlyMarksAsBroken() { // arrange const int seiyuuId = 40; var fixture = new RequestProcessorFixture(); fixture.PageRetrieverMock .Setup(t => t.RetrieveHtmlPageAsync(MalRouteBuilder.SeiyuuUrl(seiyuuId))) .Throws(new Exception("Cannot load")); var sut = fixture.Instance; // act var retrievalWrapper = sut.DoSeiyuuRetrieval(seiyuuId).Result; // assert retrievalWrapper.Exception.Should().NotBeNull(); retrievalWrapper.ResponseData.ErrorOccured.Should().BeTrue(); retrievalWrapper.ResponseData.ErrorMessage.Should().Be("Cannot load"); }
/// <summary> /// Push update/add details to MAL /// </summary> /// <param name="details">Update details</param> /// <param name="username">Username for authentication</param> /// <param name="password">Password for authentication</param> /// <param name="isupdate">Indicate if this is an update or an add</param> /// <returns>True - Update succeeded, otherwise false</returns> private async Task <DataPushResponseWrapper> UpdateAnimeDetails(AnimeUpdate details, string username, string password, bool isupdate = false) { try { var url = isupdate ? MalRouteBuilder.UpdateAnime(details.AnimeId) : MalRouteBuilder.AddAnime(details.AnimeId); var client = _httpClientFactory.GetHttpClient(username, password); var result = await client.PostAsync(url, new FormUrlEncodedContent(new[] { new KeyValuePair <string, string>("data", _xmlHelper.SerializeData(details)) })); return(new DataPushResponseWrapper(result.StatusCode, result.IsSuccessStatusCode)); } catch (Exception exception) { return(new DataPushResponseWrapper(exception)); } }
/// <summary> /// Create a new Character instance from HtmlNodes /// </summary> /// <param name="nodes">HtmlNodes containing the character information</param> /// <returns>Character instance</returns> private static CharacterInformation CreateCharacter(IList <HtmlNode> nodes) { var picLocation = nodes[0] .ChildNodes["div"] .ChildNodes["a"] .ChildNodes["img"]; var url = MalRouteBuilder.MalCleanUrl(nodes[1].ChildNodes["a"].Attributes["href"].Value); int id; int.TryParse(url.Split('/')[4], out id); return(new CharacterInformation { CharacterPicture = (picLocation.Attributes["data-src"] ?? picLocation.Attributes["src"])?.Value, CharacterName = nodes[1].ChildNodes["a"].InnerText, CharacterUrl = url, CharacterType = nodes[1].ChildNodes["div"].InnerText, Id = id }); }
public void RetrievingListCorrectlyRetrievesAnimeInformation() { // arrange const string user = "******"; var fixture = new ListRetrievalWorkerFixture(); var path = AppDomain.CurrentDomain.BaseDirectory; var examplePath = Path.Combine(path, "PageExamples", "UserList.xml"); var data = File.ReadAllText(examplePath); fixture.PageRetrieverMock .Setup(t => t.RetrieveDocumentAsStringAsync(MalRouteBuilder.UserListUrl(user))) .ReturnsAsync(new StringRetrievalWrapper(HttpStatusCode.OK, true, data)); var sut = fixture.Instance; // act var result = sut.RetrieveUserListAsync(user).Result; // assert result.Anime.Count.Should().Be(2); }
/// <summary> /// Retrieve information about shows in a specific season /// </summary> /// <param name="year">Year for which season data should be retrieved</param> /// <param name="season">Season for which data should be retrieved</param> /// <returns>Collection of show for the selected season</returns> public async Task <RetrievalWrapper <SeasonShowCollection> > GetSeasonData(int year, Seasons season) { var collectionWrapper = new SeasonShowCollection(); try { var doc = await _pageRetriever.RetrieveHtmlPageAsync(MalRouteBuilder.SeasonUrl(year, season)); if (doc.ResponseStatusCode == null) { throw doc.Exception; } var links = doc.Document.DocumentNode .SelectNodes("//a[@class='link-title']"); foreach (var link in links) { var url = link.Attributes["href"].Value; var idString = url.Split('/')[4]; int id; int.TryParse(idString, out id); var title = link.InnerHtml; var tmpData = new SeasonData { Id = id, Title = title }; collectionWrapper.SeasonShows.Add(tmpData); } return(new RetrievalWrapper <SeasonShowCollection>(doc.ResponseStatusCode.Value, doc.Success, collectionWrapper)); } catch (Exception exception) { return(new RetrievalWrapper <SeasonShowCollection>(exception, collectionWrapper)); } }
/// <summary> /// Retrieve a Character from MAL /// </summary> /// <param name="characterId">Character Id</param> /// <returns>Populated Character</returns> public async Task <RetrievalWrapper <Character> > DoCharacterRetrieval(int characterId) { var character = new Character { Id = characterId, Url = MalRouteBuilder.AnimeCharacterUrl(characterId) }; try { var characterResponse = await _pageRetriever.RetrieveHtmlPageAsync(character.Url); if (characterResponse.ResponseStatusCode == null) { throw characterResponse.Exception; } var characterDoc = characterResponse.Document; character .RetrieveCharacterName(characterDoc) .RetrieveCharacterImage(characterDoc) .RetrieveFavoriteCount(characterDoc) .RetrieveBiography(characterDoc) .RetrieveAnimeography(characterDoc) .RetrieveMangaograhy(characterDoc) .RetrieveSeiyuu(characterDoc); return(new RetrievalWrapper <Character>(characterResponse.ResponseStatusCode.Value, characterResponse.Success, character)); } catch (Exception exception) { character.ErrorOccured = true; character.ErrorMessage = exception.Message; return(new RetrievalWrapper <Character>(exception, character)); } }
/// <summary> /// Parse rows containing Ography /// </summary> /// <param name="ographyNodes">Nodes that should be parsed for ography details</param> /// <returns>List of ography items</returns> private static List <Ography> ParseOgraphy(IEnumerable <HtmlNode> ographyNodes) { var results = new List <Ography>(); foreach (var row in ographyNodes) { var tmpEntry = new Ography(); var cells = row.ChildNodes .Where(x => x.Name == "td") .ToList(); tmpEntry.ImageUrl = cells .First(x => x.FirstChild.Name == "div") .FirstChild .ChildNodes["a"] .ChildNodes["img"] .Attributes["src"] .Value; var details = cells .First(x => x.FirstChild.Name == "a") .FirstChild; tmpEntry.Url = MalRouteBuilder.MalCleanUrl(details.Attributes["href"].Value); tmpEntry.Name = details.InnerText; int id; if (int.TryParse(tmpEntry.Url.Split('/')[4], out id)) { tmpEntry.Id = id; } results.Add(tmpEntry); } return(results); }
/// <summary> /// Retrieve a user's MAL list /// </summary> /// <param name="username">User's username</param> /// <returns>Mal list</returns> public async Task <UserList> RetrieveUserListAsync(string username) { var userList = new UserList(); var retrievalWrapper = await _pageRetriever.RetrieveDocumentAsStringAsync(MalRouteBuilder.UserListUrl(username)); try { var xml = XDocument.Parse(retrievalWrapper.RetrievedBody); var userInfo = xml.Root?.Element("myinfo"); var userAnime = xml.Root?.Elements("anime").ToList(); if (userInfo == null || userAnime.Count == 0) { throw new Exception("Failed to retrieve or parse User's My Anime List"); } var xmlInfoSerializer = new XmlSerializer(typeof(UserListInformation)); var info = (UserListInformation)xmlInfoSerializer.Deserialize(userInfo.CreateReader()); userList.Info = info; var xmlAnimeSerializer = new XmlSerializer(typeof(UserListAnime)); foreach (var item in userAnime) { var anime = (UserListAnime)xmlAnimeSerializer.Deserialize(item.CreateReader()); userList.Anime.Add(anime); } } catch (Exception exception) { userList.ErrorOccured = true; userList.ErrorMessage = exception.Message; } return(userList); }
/// <summary> /// Retrieve an anime from MAL /// </summary> /// <param name="id">MAL Id</param> /// <param name="loginDetails">Username and password for retrieving user information. Pass null to retrieve pulbic page</param> /// <returns>Anime instance</returns> private async Task <RetrievalWrapper <Anime> > DoAnimeRetrieval(int id, Tuple <string, string> loginDetails) { var anime = new Anime(); try { var animePageTask = loginDetails == null ? _pageRetriever.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeUrl(id)) : _pageRetriever.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeUrl(id), loginDetails.Item1, loginDetails.Item2); var characterTask = _pageRetriever.RetrieveHtmlPageAsync(MalRouteBuilder.AnimeCharacterUrl(id)); var animeResponse = await animePageTask; if (animeResponse.ResponseStatusCode == null) { throw animeResponse.Exception; } if (!new HttpResponseMessage(animeResponse.ResponseStatusCode.Value) .IsSuccessStatusCode) { anime.ErrorOccured = true; anime.ErrorMessage = $"Status code {animeResponse.ResponseStatusCode.Value} does not indicate success"; return(new RetrievalWrapper <Anime>(animeResponse.ResponseStatusCode.Value, false, anime)); } var characterResponse = await characterTask; var animeDoc = animeResponse.Document; var characterDoc = characterResponse.Document; anime .RetrieveAnimeId(animeDoc) .RetrieveAnimeTitle(animeDoc) .RetrieveAlternativeTitles(animeDoc) .RetrieveSynopsis(animeDoc) .RetrieveImage(animeDoc) .RetrieveType(animeDoc) .RetrieveEpisodes(animeDoc) .RetrieveStatus(animeDoc) .RetrieveAirDates(animeDoc) .RetrieveRating(animeDoc) .RetrieveRank(animeDoc) .RetrievePopularity(animeDoc) .RetrieveScore(animeDoc) .RetrieveMemberCount(animeDoc) .RetrieveFavotireCount(animeDoc) .RetrieveGenres(animeDoc) .RetrieveInfoUrls(animeDoc) .RetrieveRelatedAnime(animeDoc) .PopulateCharacterAndSeiyuuInformation(characterDoc); if (loginDetails != null) { anime .RetrieveUserScore(animeDoc) .RetrieveUserEpisode(animeDoc) .RetrieveUserStatus(animeDoc); } // TODO - Add sanity check return(new RetrievalWrapper <Anime>(animeResponse.ResponseStatusCode.Value, animeResponse.Success, anime)); } catch (Exception exception) { anime.ErrorOccured = true; anime.ErrorMessage = exception.Message; return(new RetrievalWrapper <Anime>(exception, anime)); } }