Exemplo n.º 1
0
        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();
        }
Exemplo n.º 2
0
        /// <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));
            }
        }
Exemplo n.º 3
0
        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>();
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 6
0
        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();
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
        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("&nbsp;", "")
                            .Trim();

            var charImage = roleNodes[3]
                            .ChildNodes["div"]
                            .ChildNodes["a"]
                            .ChildNodes["img"];

            role.CharacterPic = (charImage?.Attributes["data-src"] ?? charImage?.Attributes["src"])?.Value;

            return(role);
        }
Exemplo n.º 12
0
        /// <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);
        }
Exemplo n.º 13
0
        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));
        }
Exemplo n.º 14
0
        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();
        }
Exemplo n.º 15
0
        /// <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));
        }
Exemplo n.º 16
0
            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));
            }
Exemplo n.º 17
0
        /// <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);
        }
Exemplo n.º 18
0
        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");
        }
Exemplo n.º 19
0
        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");
        }
Exemplo n.º 20
0
        /// <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));
            }
        }
Exemplo n.º 21
0
        /// <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
            });
        }
Exemplo n.º 22
0
        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);
        }
Exemplo n.º 23
0
        /// <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));
            }
        }
Exemplo n.º 24
0
        /// <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));
            }
        }
Exemplo n.º 25
0
        /// <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);
        }
Exemplo n.º 26
0
        /// <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);
        }
Exemplo n.º 27
0
        /// <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));
            }
        }