示例#1
0
        static int Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();

            var configuration = ConsoleConfigurationBuilder.BuildConfiguration(args, assembly);

            var connectionString = configuration.GetConnectionString("DefaultConnection");

            var upgrader = DeployChanges.To.SqlDatabase(connectionString)
                           .WithScriptsEmbeddedInAssembly(assembly)
                           .WithTransactionPerScript()
                           .LogToConsole()
                           .Build();

            var result = upgrader.PerformUpgrade();

            if (!result.Successful)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(result.Error);
                Console.ResetColor();
#if DEBUG
                Console.ReadLine();
#endif
                return(-1);
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Success!");
            Console.ResetColor();
            return(0);
        }
示例#2
0
        static async Task Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();

            var configuration = ConsoleConfigurationBuilder.BuildConfiguration(args, assembly);

            var serviceRegistry = new ServiceRegistry();

            serviceRegistry.Scan(s =>
            {
                // Look for any registry in a DLL we built.
                s.AssembliesAndExecutablesFromApplicationBaseDirectory(f => f?.FullName?.StartsWith("Fulgoribus.", StringComparison.OrdinalIgnoreCase) ?? false);

                s.LookForRegistries();
            });
            serviceRegistry.AddHttpClient();
            // Need to use a lamba to resolve the SqlConnection because trying to bind by type was going off into setter injection land.
            serviceRegistry.For <IDbConnection>().Use(_ => new SqlConnection(configuration.GetConnectionString("DefaultConnection"))).Scoped();
            using var container = new Container(serviceRegistry);

            var bookRepo    = container.GetInstance <IBookRepository>();
            var regexVolume = new Regex("[0-9]+[0-9.]*", RegexOptions.Compiled);
            var regexCover  = new Regex(@"""https:\/\/c\.bookwalker\.jp\/([0-9]+)\/.*\.jpg""", RegexOptions.Compiled);

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            var httpClientFactory = container.GetInstance <IHttpClientFactory>();

            using (var sqlConnection = new SqlConnection(configuration.GetConnectionString("DefaultConnection")))
                using (var reader = new StreamReader(configuration["BookwalkerImport:ImportPath"], Encoding.GetEncoding(932)))
                    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                    {
                        csv.Configuration.RegisterClassMap <BookwalkerBookMap>();
                        await foreach (var record in csv.EnumerateRecordsAsync(new BookwalkerBook()))
                        {
                            if (record.Url?.StartsWith("https://global.bookwalker.jp") ?? false)
                            {
                                if (record.Category == Categories.ArtBook ||
                                    record.Category == Categories.BookshelfSkin ||
                                    record.Category == Categories.LiteratureAndNovels ||
                                    record.Category == Categories.Manga ||
                                    record.Category == Categories.NonFiction)
                                {
                                    // Do nothing.
                                }
                                else if (record.Category == Categories.LightNovel)
                                {
                                    var bookId = record.Url.Replace("https://global.bookwalker.jp/", string.Empty).Replace("/", string.Empty);

                                    var book = await bookRepo.GetBookByRetailerAsync("BW", bookId);

                                    if (book == null)
                                    {
                                        book = new Book
                                        {
                                            Title       = record.Title,
                                            ReleaseDate = record.ReleaseDate,
                                            Label       = record.Label
                                        };
                                        await bookRepo.SaveBookAsync(book);

                                        var seriesTitle = record.Series.GetValueOrNull();
                                        if (seriesTitle != null)
                                        {
                                            var series = await bookRepo.GetSeriesAsync(seriesTitle);

                                            if (series == null)
                                            {
                                                series = new Series
                                                {
                                                    Title = seriesTitle
                                                };
                                                await bookRepo.SaveSeriesAsync(series);
                                            }

                                            // Try to get the sort order as the first number in the title (to handle Kokoro Connect Volumes 9/10) that is not
                                            // part of the series (to handle 86).
                                            decimal?sortOrder        = null;
                                            var     titleForParsing  = book.Title.Replace(seriesTitle, string.Empty);
                                            var     volumeCandidates = regexVolume.Matches(titleForParsing);
                                            var     books            = await bookRepo.GetSeriesBooksAsync(series.SeriesId !.Value);

                                            if (volumeCandidates.Any())
                                            {
                                                // Take the first one.
                                                sortOrder = Convert.ToDecimal(volumeCandidates.First().Value);

                                                // Make sure this doesn't collide with an existing volume. (e.g. Ascendance of a Bookworm)
                                                if (books.Any(b => b.SortOrder == sortOrder))
                                                {
                                                    sortOrder = null;
                                                }
                                            }

                                            if (!sortOrder.HasValue)
                                            {
                                                Console.WriteLine($"Unknown series order for series {seriesTitle}, book {book.Title}. Picking next available integer.");
                                                if (books.Any())
                                                {
                                                    var lastSortOrder = books.Last().SortOrder !.Value;
                                                    sortOrder = Math.Ceiling(lastSortOrder);
                                                    if (sortOrder == lastSortOrder)
                                                    {
                                                        sortOrder += 1;
                                                    }
                                                }
                                                else
                                                {
                                                    sortOrder = 1;
                                                }
                                            }
                                            var seriesBook = new SeriesBook
                                            {
                                                Series    = series,
                                                Book      = book,
                                                SortOrder = sortOrder,
                                                Volume    = sortOrder.ToString()
                                            };
                                            await bookRepo.SaveSeriesBookAsync(seriesBook);
                                        }

                                        var bookRetailer = new BookRetailer
                                        {
                                            BookId      = book.BookId,
                                            RetailerId  = "BW",
                                            RetailerKey = bookId
                                        };
                                        await bookRepo.SaveBookRetailerAsync(bookRetailer);
                                    }

                                    if (book.BookId.HasValue)
                                    {
                                        var cover = await bookRepo.GetBookCoverAsync(book.BookId.Value);

                                        if (cover == null)
                                        {
                                            cover = new BookCover
                                            {
                                                BookId = book.BookId.Value
                                            };

                                            try
                                            {
                                                var client = httpClientFactory.CreateClient();
                                                var body   = await client.GetStringAsync(record.Url);

                                                var matches = regexCover.Matches(body);
                                                if (matches.Any() && int.TryParse(new string(matches.First().Groups[1].Value.Reverse().ToArray()), out var id))
                                                {
                                                    var imageUrl = "http://c.bookwalker.jp/coverImage_" + (id - 1) + ".jpg";
                                                    var result   = await client.GetAsync(imageUrl);

                                                    if (result.StatusCode == HttpStatusCode.Forbidden)
                                                    {
                                                        // Try using the URL as-is. Not as good as the full-fat cover but it will do.
                                                        var quotedUrl = matches.First().Value;
                                                        var url       = quotedUrl[1..^ 1];