示例#1
0
        static void Main(string[] args)
        {
            // No logging support for MalApi in .NET Core yet.
            // At this time there is no Common.Logging adapter for NLog that supports .NET core.
            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                api.UserAgent   = "MalApiExample";
                api.TimeoutInMs = 15000;

                MalUserLookupResults userLookup = api.GetAnimeListForUser("LordHighCaptain");
                foreach (MyAnimeListEntry listEntry in userLookup.AnimeList)
                {
                    Console.WriteLine("Rating for {0}: {1}", listEntry.AnimeInfo.Title, listEntry.Score);
                }

                Console.WriteLine();
                Console.WriteLine();

                RecentUsersResults recentUsersResults = api.GetRecentOnlineUsers();
                foreach (string user in recentUsersResults.RecentUsers)
                {
                    Console.WriteLine("Recent user: {0}", user);
                }

                Console.WriteLine();
                Console.WriteLine();

                int eurekaSevenID = 237;
                AnimeDetailsResults eurekaSeven = api.GetAnimeDetails(eurekaSevenID);
                Console.WriteLine("Eureka Seven genres: {0}", string.Join(", ", eurekaSeven.Genres));
            }
        }
示例#2
0
        public void IncorrectUsernameMangaChapterUpdateTest()
        {
            string username = System.Environment.GetEnvironmentVariable("MAL_USERNAME");

            username += "test";
            string password = System.Environment.GetEnvironmentVariable("MAL_PASSWORD");

            // Monster
            int mangaId = 1;

            MangaUpdate partialBaseInfo = new MangaUpdate()
            {
                Chapter = 1
            };

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                using (GetUserMangaDetailsTest helper = new GetUserMangaDetailsTest())
                {
                    Assert.Throws <MalApiRequestException>(() => helper.Login(username, password));

                    Assert.Throws <MalApiRequestException>(() => api.UpdateMangaForUser(mangaId, partialBaseInfo, username, password));
                }
            }
        }
示例#3
0
 public void GetAnimeListForNonexistentUserThrowsCorrectExceptionAsync()
 {
     using (MyAnimeListApi api = new MyAnimeListApi())
     {
         Assert.ThrowsAsync <MalUserNotFoundException>(() => api.GetAnimeListForUserAsync("oijsfjisfdjfsdojpfsdp"));
     }
 }
示例#4
0
        public void UpdateMangaForUserCanceled()
        {
            string username = System.Environment.GetEnvironmentVariable("MAL_USERNAME");
            string password = System.Environment.GetEnvironmentVariable("MAL_PASSWORD");

            // Monster
            int mangaId = 1;

            MangaUpdate updateInfo = new MangaUpdate()
            {
                Chapter          = 162,
                Volume           = 18,
                Status           = MangaCompletionStatus.Completed,
                Score            = 10,
                TimesReread      = 2,
                RereadValue      = 4, // high
                DateStart        = new DateTime(2017, 12, 10),
                DateFinish       = new DateTime(2017, 12, 15),
                Priority         = 1, // medium
                EnableDiscussion = 1,
                EnableRereading  = 1,
                Comments         = "test updated comment, test updated comment2",
                // ScanGroup = "scan_group_updated",
                Tags = "test updated tag, test updated tag 2"
            };

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                CancellationTokenSource tokenSource    = new CancellationTokenSource();
                Task <string>           userLookupTask =
                    api.UpdateMangaForUserAsync(mangaId, updateInfo, username, password, tokenSource.Token);
                tokenSource.Cancel();
                Assert.Throws <TaskCanceledException>(() => userLookupTask.GetAwaiter().GetResult());
            }
        }
示例#5
0
        static void Main(string[] args)
        {
            // MalApi uses the Common.Logging logging abstraction.
            // You can hook it up to any logging library that has a Common.Logging adapter.
            // See App.config for an example of hooking up MalApi to NLog.
            // Note that you will also need the appropriate NLog and Common.Logging.NLogXX packages installed.
            // Hooking up logging is not necessary but can be useful.
            // With the configuration in this example and with this example program, you will see lines like:

            // Logged from MalApi: Getting anime list for MAL user LordHighCaptain using URI https://myanimelist.net/malappinfo.php?status=all&type=anime&u=LordHighCaptain
            // Logged from MalApi: Successfully retrieved anime list for user LordHighCaptain

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                api.UserAgent   = "MalApiExample";
                api.TimeoutInMs = 15000;

                var animeUpdateInfo = new AnimeUpdate()
                {
                    Episode = 26,
                    Status  = AnimeCompletionStatus.Completed,
                    Score   = 9,
                };
                string userUpdateAnime = api.UpdateAnimeForUser(1, animeUpdateInfo, "user", "password");

                var mangaUpdateInfo = new MangaUpdate()
                {
                    Chapter = 20,
                    Volume  = 3,
                    Score   = 8,
                    Status  = MangaCompletionStatus.Completed
                };
                string userUpdateManga = api.UpdateMangaForUser(952, mangaUpdateInfo, "user", "password");



                MalUserLookupResults userLookup = api.GetAnimeListForUser("user");
                foreach (MyAnimeListEntry listEntry in userLookup.AnimeList)
                {
                    Console.WriteLine("Rating for {0}: {1}", listEntry.AnimeInfo.Title, listEntry.Score);
                }

                Console.WriteLine();
                Console.WriteLine();

                RecentUsersResults recentUsersResults = api.GetRecentOnlineUsers();
                foreach (string user in recentUsersResults.RecentUsers)
                {
                    Console.WriteLine("Recent user: {0}", user);
                }

                Console.WriteLine();
                Console.WriteLine();

                int eurekaSevenID = 237;
                AnimeDetailsResults eurekaSeven = api.GetAnimeDetails(eurekaSevenID);
                Console.WriteLine("Eureka Seven genres: {0}", string.Join(", ", eurekaSeven.Genres));
            }
        }
 public void GetAnimeDetailsForInvalidAnimeId()
 {
     int animeId = 99999;
     using (MyAnimeListApi api = new MyAnimeListApi())
     {
         Assert.Throws<MalAnimeNotFoundException>(() => api.GetAnimeDetails(animeId));
     }
 }
 public void GetRecentOnlineUsers()
 {
     using (MyAnimeListApi api = new MyAnimeListApi())
     {
         RecentUsersResults results = api.GetRecentOnlineUsers();
         Assert.That(results.RecentUsers.Count, Is.GreaterThan(0));
     }
 }
示例#8
0
 public void GetRecentOnlineUsers()
 {
     using (MyAnimeListApi api = new MyAnimeListApi())
     {
         RecentUsersResults results = api.GetRecentOnlineUsers();
         Assert.NotEmpty(results.RecentUsers);
     }
 }
示例#9
0
        public void GetAnimeDetailsForInvalidAnimeId()
        {
            int animeId = 99999;

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                Assert.Throws <MalAnimeNotFoundException>(() => api.GetAnimeDetails(animeId));
            }
        }
示例#10
0
        public void UpdateMangaTagsForUserTest()
        {
            string username = System.Environment.GetEnvironmentVariable("MAL_USERNAME");
            string password = System.Environment.GetEnvironmentVariable("MAL_PASSWORD");

            // Monster
            int mangaId = 1;

            MangaUpdate partialBaseInfo = new MangaUpdate()
            {
                Tags = "test base tag, test base tag 2"
            };

            MangaUpdate partialUpdateInfo = new MangaUpdate()
            {
                Tags = "test updated tag, test updated tag 2"
            };

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                using (GetUserMangaDetailsTest helper = new GetUserMangaDetailsTest())
                {
                    helper.Login(username, password);

                    string result = api.UpdateMangaForUser(mangaId, partialBaseInfo, username, password);
                    Assert.Equal("Updated", result);

                    MangaUpdate baseReults = helper.GetUserMangaDetailsAsync(username, mangaId);

                    // Assert first update against base info
                    Assert.Equal(partialBaseInfo.Tags, baseReults.Tags);

                    result = api.UpdateMangaForUser(mangaId, partialUpdateInfo, username, password);
                    Assert.Equal("Updated", result);

                    MangaUpdate updatedResults = helper.GetUserMangaDetailsAsync(username, mangaId);

                    // Assert second update with update info
                    Assert.Equal(partialUpdateInfo.Tags, updatedResults.Tags);

                    // Assert that only the tags has been changed
                    Assert.Equal(baseReults.Chapter, updatedResults.Chapter);
                    Assert.Equal(baseReults.Volume, updatedResults.Volume);
                    Assert.Equal(baseReults.Status, updatedResults.Status);
                    Assert.Equal(baseReults.Score, updatedResults.Score);
                    Assert.Equal(baseReults.TimesReread, updatedResults.TimesReread);
                    Assert.Equal(baseReults.RereadValue, updatedResults.RereadValue);
                    Assert.Equal(baseReults.DateStart, updatedResults.DateStart);
                    Assert.Equal(baseReults.DateFinish, updatedResults.DateFinish);
                    Assert.Equal(baseReults.Priority, updatedResults.Priority);
                    Assert.Equal(baseReults.EnableDiscussion, updatedResults.EnableDiscussion);
                    Assert.Equal(baseReults.EnableRereading, updatedResults.EnableRereading);
                    Assert.Equal(baseReults.Comments, updatedResults.Comments);
                    Assert.NotEqual(baseReults.Tags, updatedResults.Tags);
                }
            }
        }
示例#11
0
 public void GetRecentOnlineUsersCanceled()
 {
     using (MyAnimeListApi api = new MyAnimeListApi())
     {
         CancellationTokenSource   tokenSource = new CancellationTokenSource();
         Task <RecentUsersResults> task        = api.GetRecentOnlineUsersAsync(tokenSource.Token);
         tokenSource.Cancel();
         Assert.Throws <TaskCanceledException>(() => task.GetAwaiter().GetResult());
     }
 }
示例#12
0
        public void GetAnimeListForUser()
        {
            string username = "******";
            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                MalUserLookupResults userLookup = api.GetAnimeListForUser(username);

                // Just a smoke test that checks that getting an anime list returns something
                Assert.That(userLookup.AnimeList, Is.Not.Empty);
            }
        }
示例#13
0
        public void GetMangaListForUser()
        {
            string username = "******";

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                MalUserLookupResults userLookup = api.GetMangaListForUser(username);

                Assert.NotEmpty(userLookup.MangaList);
            }
        }
示例#14
0
        public void GetAnimeListForUserCanceled()
        {
            string username = "******";

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                CancellationTokenSource     tokenSource    = new CancellationTokenSource();
                Task <MalUserLookupResults> userLookupTask = api.GetAnimeListForUserAsync(username, tokenSource.Token);
                tokenSource.Cancel();
                Assert.Throws <TaskCanceledException>(() => userLookupTask.GetAwaiter().GetResult());
            }
        }
示例#15
0
        public void GetAnimeListForUser()
        {
            string username = "******";

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                MalUserLookupResults userLookup = api.GetAnimeListForUser(username);

                // Just a smoke test that checks that getting an anime list returns something
                Assert.NotEmpty(userLookup.AnimeList);
            }
        }
示例#16
0
        public void GetAnimeDetailsCanceled()
        {
            int animeId = 237; // Eureka Seven

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                CancellationTokenSource    tokenSource = new CancellationTokenSource();
                Task <AnimeDetailsResults> task        = api.GetAnimeDetailsAsync(animeId, tokenSource.Token);
                tokenSource.Cancel();
                Assert.Throws <TaskCanceledException>(() => task.GetAwaiter().GetResult());
            }
        }
示例#17
0
        public void TestScrapeUserAnimeDetailsFromHtml()
        {
            string html;

            using (StreamReader reader = Helpers.GetResourceStream("Cowboy_Bebop.htm"))
            {
                html = reader.ReadToEnd();
            }

            AnimeUpdate info = new AnimeUpdate()
            {
                Episode          = 26,
                Status           = AnimeCompletionStatus.Completed,
                Score            = 8,
                StorageType      = 5, // VHS
                StorageValue     = 123,
                TimesRewatched   = 2,
                RewatchValue     = 4, // high
                DateStart        = new DateTime(2017, 12, 10),
                DateFinish       = new DateTime(2017, 12, 15),
                Priority         = 1, // medium
                EnableDiscussion = 1,
                EnableRewatching = 1,
                Comments         = "test updated comment, test updated comment2",
                Tags             = "test updated tag, test updated tag 2"
            };

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                AnimeUpdate results = MalDetailScrapingUtils.ScrapeUserAnimeDetailsFromHtml(html);

                Assert.Equal(info.Episode, results.Episode);
                Assert.Equal(info.Status, results.Status);
                Assert.Equal(info.Score, results.Score);
                Assert.Equal(info.StorageType, results.StorageType);
                Assert.Equal(info.StorageValue, results.StorageValue);
                Assert.Equal(info.TimesRewatched, results.TimesRewatched);
                Assert.Equal(info.RewatchValue, results.RewatchValue);
                Assert.Equal(info.DateStart, results.DateStart);
                Assert.Equal(info.DateFinish, results.DateFinish);
                Assert.Equal(info.Priority, results.Priority);
                Assert.Equal(info.EnableDiscussion, results.EnableDiscussion);
                Assert.Equal(info.EnableRewatching, results.EnableRewatching);
                Assert.Equal(info.Comments, results.Comments);
                Assert.Equal(info.Tags, results.Tags);
            }
        }
示例#18
0
        public void TestScrapeUserMangaDetailsFromHtml()
        {
            string html;

            using (StreamReader reader = Helpers.GetResourceStream("Monster.htm"))
            {
                html = reader.ReadToEnd();
            }

            MangaUpdate info = new MangaUpdate()
            {
                Chapter          = 162,
                Volume           = 18,
                Status           = MangaCompletionStatus.Completed,
                Score            = 10,
                TimesReread      = 2,
                RereadValue      = 4, // high
                DateStart        = new DateTime(2017, 12, 10),
                DateFinish       = new DateTime(2017, 12, 15),
                Priority         = 1, // medium
                EnableDiscussion = 1,
                EnableRereading  = 1,
                Comments         = "test updated comment, test updated comment2",
                // ScanGroup = "scan_group_updated",
                Tags = "test updated tag, test updated tag 2"
            };

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                MangaUpdate results = MalDetailScrapingUtils.ScrapeUserMangaDetailsFromHtml(html);

                Assert.Equal(info.Chapter, results.Chapter);
                Assert.Equal(info.Volume, results.Volume);
                Assert.Equal(info.Status, results.Status);
                Assert.Equal(info.Score, results.Score);
                Assert.Equal(info.TimesReread, results.TimesReread);
                Assert.Equal(info.RereadValue, results.RereadValue);
                Assert.Equal(info.DateStart, results.DateStart);
                Assert.Equal(info.DateFinish, results.DateFinish);
                Assert.Equal(info.Priority, results.Priority);
                Assert.Equal(info.EnableDiscussion, results.EnableDiscussion);
                Assert.Equal(info.EnableRereading, results.EnableRereading);
                Assert.Equal(info.Comments, results.Comments);
                Assert.Equal(info.Tags, results.Tags);
            }
        }
 public void GetAnimeDetails()
 {
     int animeId = 237; // Eureka Seven
     using (MyAnimeListApi api = new MyAnimeListApi())
     {
         AnimeDetailsResults results = api.GetAnimeDetails(animeId);
         List<Genre> expectedGenres = new List<Genre>()
         {
             new Genre(2, "Adventure"),
             new Genre(8, "Drama"),
             new Genre(18, "Mecha"),
             new Genre(22, "Romance"),
             new Genre(24, "Sci-Fi"),
             new Genre(27, "Shounen")
         };
         Assert.That(results.Genres, Is.EquivalentTo(expectedGenres));
     }
 }
示例#20
0
        public void GetAnimeDetails()
        {
            int animeId = 237; // Eureka Seven

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                AnimeDetailsResults results        = api.GetAnimeDetails(animeId);
                List <Genre>        expectedGenres = new List <Genre>()
                {
                    new Genre(2, "Adventure"),
                    new Genre(8, "Drama"),
                    new Genre(18, "Mecha"),
                    new Genre(22, "Romance"),
                    new Genre(24, "Sci-Fi"),
                };
                results.Genres.Should().BeEquivalentTo(expectedGenres);
            }
        }
示例#21
0
文件: Program.cs 项目: Evanjs/mal-api
        static void Main(string[] args)
        {
            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                api.TimeoutInMs = 15000;

                MalUserLookupResults userLookup = api.GetAnimeListForUser("LordHighCaptain");
                foreach (MyAnimeListEntry listEntry in userLookup.AnimeList)
                {
                    Console.WriteLine("Rating for {0}: {1}", listEntry.AnimeInfo.Title, listEntry.Score);
                }

                Console.WriteLine();
                Console.WriteLine();

                RecentUsersResults recentUsersResults = api.GetRecentOnlineUsers();
                foreach (string user in recentUsersResults.RecentUsers)
                {
                    Console.WriteLine("Recent user: {0}", user);
                }
            }
        }
示例#22
0
        public void TestScrapeAnimeDetailsFromHtml()
        {
            string thisAssemblyPath = Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", "");
            Console.WriteLine(thisAssemblyPath);
            string htmlFilePath = Path.Combine(Path.GetDirectoryName(thisAssemblyPath), "Eureka_Seven.htm");
            string html = File.ReadAllText(htmlFilePath);

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                AnimeDetailsResults results = api.ScrapeAnimeDetailsFromHtml(html, 237);
                List<Genre> expectedGenres = new List<Genre>()
                {
                    new Genre(2, "Adventure"),
                    new Genre(8, "Drama"),
                    new Genre(18, "Mecha"),
                    new Genre(22, "Romance"),
                    new Genre(24, "Sci-Fi"),
                    new Genre(27, "Shounen")
                };
                Assert.That(results.Genres, Is.EquivalentTo(expectedGenres));
            }
        }
示例#23
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc()
            // Use property names as is on classes that get serialized, instead of camelcasing.
            .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
            services.AddOptions();
            services.Configure <Config.HtmlConfig>(Configuration.GetSection("Html"));
            services.Configure <Config.MalApiConfig>(Configuration.GetSection("MalApi"));
            services.Configure <Config.RecommendationsConfig>(Configuration.GetSection("Recommendations"));
            services.Configure <Config.ConnectionStringsConfig>(Configuration.GetSection("ConnectionStrings"));

            services.AddTransient <IAnimeRecsClientFactory, ConfigBasedRecClientFactory>();
            services.AddTransient <IAnimeRecsDbConnectionFactory, ConfigBasedAnimeRecsDbConnectionFactory>();

            IMyAnimeListApi api;

            Config.MalApiConfig apiConfig = Configuration.GetSection("MalApi").Get <Config.MalApiConfig>();
            if (apiConfig.Type == Config.MalApiType.Normal)
            {
                api = new MyAnimeListApi()
                {
                    UserAgent   = apiConfig.UserAgentString,
                    TimeoutInMs = apiConfig.TimeoutMilliseconds,
                };
            }
            else if (apiConfig.Type == Config.MalApiType.DB)
            {
                api = new PgMyAnimeListApi(Configuration.GetConnectionString("AnimeRecs"));
            }
            else
            {
                throw new Exception($"Don't know how to construct MAL API type {apiConfig.Type}.");
            }
            CachingMyAnimeListApi          cachingApi = new CachingMyAnimeListApi(api, TimeSpan.FromSeconds(apiConfig.AnimeListCacheExpirationSeconds), ownApi: true);
            SingletonMyAnimeListApiFactory factory    = new SingletonMyAnimeListApiFactory(cachingApi);

            services.AddSingleton <IMyAnimeListApiFactory>(factory);
        }
示例#24
0
        public void TestScrapeAnimeDetailsFromHtml()
        {
            string html;

            using (StreamReader reader = Helpers.GetResourceStream("Eureka_Seven.htm"))
            {
                html = reader.ReadToEnd();
            }

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                AnimeDetailsResults results        = api.ScrapeAnimeDetailsFromHtml(html, 237);
                List <Genre>        expectedGenres = new List <Genre>()
                {
                    new Genre(2, "Adventure"),
                    new Genre(8, "Drama"),
                    new Genre(18, "Mecha"),
                    new Genre(22, "Romance"),
                    new Genre(24, "Sci-Fi"),
                };
                results.Genres.Should().BeEquivalentTo(expectedGenres);
            }
        }
示例#25
0
        static void Main(string[] args)
        {
            Logging.SetUpLogging();

            try
            {
                config = new Config();

                using (IMyAnimeListApi basicApi = new MyAnimeListApi() { TimeoutInMs = config.MalTimeoutInMs, UserAgent = config.MalApiUserAgentString })
                using (IMyAnimeListApi rateLimitingApi = new RateLimitingMyAnimeListApi(basicApi, TimeSpan.FromMilliseconds(config.DelayBetweenRequestsInMs)))
                using (IMyAnimeListApi malApi = new RetryOnFailureMyAnimeListApi(rateLimitingApi, config.NumMalRequestFailuresBeforeGivingUp, config.DelayAfterMalRequestFailureInMs))
                using (NpgsqlConnection conn = new NpgsqlConnection(config.PostgresConnectionString))
                {
                    conn.Open();
                    int usersAddedSoFar = 0;
                    while (usersAddedSoFar < config.UsersPerRun)
                    {
                        RecentUsersResults recentMalUsers = malApi.GetRecentOnlineUsers();

                        foreach (string user in recentMalUsers.RecentUsers)
                        {
                            using (var transaction = conn.BeginTransaction(System.Data.IsolationLevel.RepeatableRead))
                            {
                                if (!UserIsInDatabase(user, conn, transaction))
                                {
                                    MalUserLookupResults userLookup = malApi.GetAnimeListForUser(user);
                                    if (UserMeetsCriteria(userLookup, conn, transaction))
                                    {
                                        InsertUserAndRatingsInDatabase(userLookup, conn, transaction);
                                        usersAddedSoFar++;
                                        Logging.Log.Debug("Committing transaction.");
                                        transaction.Commit();
                                        Logging.Log.Debug("Transaction committed.");

                                        if (usersAddedSoFar == config.UsersPerRun)
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        Logging.Log.InfoFormat("{0} does not meet criteria for inclusion, skipping", user);
                                    }
                                }
                                else
                                {
                                    Logging.Log.InfoFormat("{0} is already in the database, skipping.", user);
                                }
                            }
                        }
                    }

                    using (var transaction = conn.BeginTransaction(System.Data.IsolationLevel.RepeatableRead))
                    {
                        TrimDatabaseToMaxUsers(config.MaxUsersInDatabase, conn, transaction);
                        transaction.Commit();
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.Log.FatalFormat("Fatal error: {0}", ex, ex.Message);
                Environment.ExitCode = 1;
            }
        }
示例#26
0
        public void UpdateMangaForUserTest()
        {
            string username = System.Environment.GetEnvironmentVariable("MAL_USERNAME");
            string password = System.Environment.GetEnvironmentVariable("MAL_PASSWORD");

            // Monster
            int mangaId = 1;

            MangaUpdate baseInfo = new MangaUpdate()
            {
                Chapter          = 1,
                Volume           = 2,
                Status           = MangaCompletionStatus.Reading,
                Score            = 3,
                TimesReread      = 1,
                RereadValue      = 2, // low
                DateStart        = new DateTime(2017, 10, 1),
                DateFinish       = new DateTime(2017, 10, 5),
                Priority         = 0, // low
                EnableDiscussion = 0,
                EnableRereading  = 0,
                Comments         = "base comment,base comment 2",
                // ScanGroup = "scan_group",
                Tags = "test base tag, test base tag 2"
            };

            MangaUpdate updateInfo = new MangaUpdate()
            {
                Chapter          = 162,
                Volume           = 18,
                Status           = MangaCompletionStatus.Completed,
                Score            = 10,
                TimesReread      = 2,
                RereadValue      = 4, // high
                DateStart        = new DateTime(2017, 12, 10),
                DateFinish       = new DateTime(2017, 12, 15),
                Priority         = 1, // medium
                EnableDiscussion = 1,
                EnableRereading  = 1,
                Comments         = "test updated comment, test updated comment2",
                // ScanGroup = "scan_group_updated",
                Tags = "test updated tag, test updated tag 2"
            };

            using (MyAnimeListApi api = new MyAnimeListApi())
            {
                using (GetUserMangaDetailsTest helper = new GetUserMangaDetailsTest())
                {
                    helper.Login(username, password);

                    string result = api.UpdateMangaForUser(mangaId, baseInfo, username, password);
                    Assert.Equal("Updated", result);

                    MangaUpdate baseReults = helper.GetUserMangaDetailsAsync(username, mangaId);

                    // Assert first update against base info
                    Assert.Equal(baseInfo.Chapter, baseReults.Chapter);
                    Assert.Equal(baseInfo.Volume, baseReults.Volume);
                    Assert.Equal(baseInfo.Status, baseReults.Status);
                    Assert.Equal(baseInfo.Score, baseReults.Score);
                    Assert.Equal(baseInfo.TimesReread, baseReults.TimesReread);
                    Assert.Equal(baseInfo.RereadValue, baseReults.RereadValue);
                    Assert.Equal(baseInfo.DateStart, baseReults.DateStart);
                    Assert.Equal(baseInfo.DateFinish, baseReults.DateFinish);
                    Assert.Equal(baseInfo.Priority, baseReults.Priority);
                    Assert.Equal(baseInfo.EnableDiscussion, baseReults.EnableDiscussion);
                    Assert.Equal(baseInfo.EnableRereading, baseReults.EnableRereading);
                    Assert.Equal(baseInfo.Comments, baseReults.Comments);
                    Assert.Equal(baseInfo.Tags, baseReults.Tags);

                    result = api.UpdateMangaForUser(mangaId, updateInfo, username, password);
                    Assert.Equal("Updated", result);

                    MangaUpdate updatedResults = helper.GetUserMangaDetailsAsync(username, mangaId);

                    // Assert second update with update info
                    Assert.Equal(updateInfo.Chapter, updatedResults.Chapter);
                    Assert.Equal(updateInfo.Volume, updatedResults.Volume);
                    Assert.Equal(updateInfo.Status, updatedResults.Status);
                    Assert.Equal(updateInfo.Score, updatedResults.Score);
                    Assert.Equal(updateInfo.TimesReread, updatedResults.TimesReread);
                    Assert.Equal(updateInfo.RereadValue, updatedResults.RereadValue);
                    Assert.Equal(updateInfo.DateStart, updatedResults.DateStart);
                    Assert.Equal(updateInfo.DateFinish, updatedResults.DateFinish);
                    Assert.Equal(updateInfo.Priority, updatedResults.Priority);
                    Assert.Equal(updateInfo.EnableDiscussion, updatedResults.EnableDiscussion);
                    Assert.Equal(updateInfo.EnableRereading, updatedResults.EnableRereading);
                    Assert.Equal(updateInfo.Comments, updatedResults.Comments);
                    Assert.Equal(updateInfo.Tags, updatedResults.Tags);

                    // Assert all values have been changed
                    Assert.NotEqual(baseReults.Chapter, updatedResults.Chapter);
                    Assert.NotEqual(baseReults.Volume, updatedResults.Volume);
                    Assert.NotEqual(baseReults.Status, updatedResults.Status);
                    Assert.NotEqual(baseReults.Score, updatedResults.Score);
                    Assert.NotEqual(baseReults.TimesReread, updatedResults.TimesReread);
                    Assert.NotEqual(baseReults.RereadValue, updatedResults.RereadValue);
                    Assert.NotEqual(baseReults.DateStart, updatedResults.DateStart);
                    Assert.NotEqual(baseReults.DateFinish, updatedResults.DateFinish);
                    Assert.NotEqual(baseReults.Priority, updatedResults.Priority);
                    Assert.NotEqual(baseReults.EnableDiscussion, updatedResults.EnableDiscussion);
                    Assert.NotEqual(baseReults.EnableRereading, updatedResults.EnableRereading);
                    Assert.NotEqual(baseReults.Comments, updatedResults.Comments);
                    Assert.NotEqual(baseReults.Tags, updatedResults.Tags);
                }
            }
        }
示例#27
0
        // Called once
        protected override void ConfigureApplicationContainer(TinyIoCContainer container)
        {
            List<IDisposable> disposablesInitialized = new List<IDisposable>();
            try
            {
                // This seems to be called before ApplicationStartup, so read config if it hasn't been read yet
                LoadConfigIfNotLoaded();

                container.Register<IConfig>(AppGlobals.Config);

                IAnimeRecsClientFactory recServiceClientFactory = new RecClientFactory(AppGlobals.Config.RecServicePort, AppGlobals.Config.SpecialRecSourcePorts);
                container.Register<IAnimeRecsClientFactory>(recServiceClientFactory);

                IAnimeRecsDbConnectionFactory dbConnectionFactory = new AnimeRecsDbConnectionFactory(AppGlobals.Config.PostgresConnectionString);
                container.Register<IAnimeRecsDbConnectionFactory>(dbConnectionFactory);

                IMyAnimeListApi api;
                if (AppGlobals.Config.UseLocalDbMalApi)
                {
                    api = new PgMyAnimeListApi(AppGlobals.Config.PostgresConnectionString);
                }
                else
                {
                    api = new MyAnimeListApi()
                    {
                        UserAgent = AppGlobals.Config.MalApiUserAgentString,
                        TimeoutInMs = AppGlobals.Config.MalTimeoutInMs
                    };
                }
                disposablesInitialized.Add(api);

                CachingMyAnimeListApi cachingApi = new CachingMyAnimeListApi(api, AppGlobals.Config.AnimeListCacheExpiration, ownApi: true);
                disposablesInitialized.Add(cachingApi);

                SingletonMyAnimeListApiFactory factory = new SingletonMyAnimeListApiFactory(cachingApi);

                // TinyIoC will dispose of the factory when the Nancy host stops
                container.Register<IMyAnimeListApiFactory>(factory);
            }
            catch
            {
                foreach (IDisposable disposable in disposablesInitialized)
                {
                    disposable.Dispose();
                }
                throw;
            }
        }
示例#28
0
        static int Main(string[] args)
        {
            CommandLineArgs commandLine;

            try
            {
                commandLine = new CommandLineArgs(args);
                if (commandLine.ShowHelp)
                {
                    commandLine.DisplayHelp(Console.Out);
                    return((int)ExitCode.Success);
                }

                IConfigurationBuilder configBuilder = new ConfigurationBuilder()
                                                      .AddXmlFile(commandLine.ConfigFile);

                IConfigurationRoot rawConfig = configBuilder.Build();
                config = rawConfig.Get <Config>();

                if (config.LoggingConfigPath != null)
                {
                    Logging.SetUpLogging(config.LoggingConfigPath);
                }
                else
                {
                    Console.Error.WriteLine("No logging configuration file set. Logging to console.");
                    Logging.SetUpConsoleLogging();
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("Fatal error: {0}", ex, ex.Message);
                return((int)ExitCode.Failure);
            }

            try
            {
                Logging.Log.Debug($"Command line args parsed. ConfigFile={commandLine.ConfigFile}");

                using (IMyAnimeListApi basicApi = new MyAnimeListApi()
                {
                    TimeoutInMs = config.MalTimeoutInMs, UserAgent = config.MalApiUserAgentString
                })
                    using (IMyAnimeListApi rateLimitingApi = new RateLimitingMyAnimeListApi(basicApi, TimeSpan.FromMilliseconds(config.DelayBetweenRequestsInMs)))
                        using (IMyAnimeListApi malApi = new RetryOnFailureMyAnimeListApi(rateLimitingApi, config.NumMalRequestFailuresBeforeGivingUp, config.DelayAfterMalRequestFailureInMs))
                            using (NpgsqlConnection conn = new NpgsqlConnection(config.ConnectionStrings.AnimeRecs))
                            {
                                conn.Open();
                                int usersAddedSoFar = 0;
                                while (usersAddedSoFar < config.UsersPerRun)
                                {
                                    RecentUsersResults recentMalUsers = malApi.GetRecentOnlineUsers();

                                    foreach (string user in recentMalUsers.RecentUsers)
                                    {
                                        using (var transaction = conn.BeginTransaction(System.Data.IsolationLevel.RepeatableRead))
                                        {
                                            if (!UserIsInDatabase(user, conn, transaction))
                                            {
                                                MalUserLookupResults userLookup = malApi.GetAnimeListForUser(user);
                                                if (UserMeetsCriteria(userLookup, conn, transaction))
                                                {
                                                    InsertUserAndRatingsInDatabase(userLookup, conn, transaction);
                                                    usersAddedSoFar++;
                                                    Logging.Log.Debug("Committing transaction.");
                                                    transaction.Commit();
                                                    Logging.Log.Debug("Transaction committed.");

                                                    if (usersAddedSoFar == config.UsersPerRun)
                                                    {
                                                        break;
                                                    }
                                                }
                                                else
                                                {
                                                    Logging.Log.InfoFormat("{0} does not meet criteria for inclusion, skipping", user);
                                                }
                                            }
                                            else
                                            {
                                                Logging.Log.InfoFormat("{0} is already in the database, skipping.", user);
                                            }
                                        }
                                    }
                                }

                                using (var transaction = conn.BeginTransaction(System.Data.IsolationLevel.RepeatableRead))
                                {
                                    TrimDatabaseToMaxUsers(config.MaxUsersInDatabase, conn, transaction);
                                    transaction.Commit();
                                }
                            }
            }
            catch (Exception ex)
            {
                Logging.Log.FatalFormat("Fatal error: {0}", ex, ex.Message);
                return((int)ExitCode.Failure);
            }

            return((int)ExitCode.Success);
        }