Program.cs

200 lines | 5.976 kB Blame History Raw Download
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System.IO;
using System.Diagnostics;
using System.IO;

using Microsoft.EntityFrameworkCore;

using Tools.PdfProvider;

using Calibre.Model.Database;
using Calibre.Model.Database.Entities;

namespace Calibre
{
    class Program
    {
        private static string[] SelectDbFiles(DirectoryInfo directory)
        {
            var dbFiles = directory
                .GetFiles("metadata.db", SearchOption.AllDirectories)
                .Select(e => e.FullName)
                .ToArray();

            return dbFiles;
        }

        private static string BuildConnectionStringFromPath(string path)
        {
            return $"Filename={path}";
        }

        private static async Task<Dictionary<string, Book[]>> SearchBooksByTitle(
            string[] dbFiles,
            string containsTitle
            )
        {
            List<CalibreContext> contexts 
                = new List<CalibreContext>(containsTitle.Length);
            Dictionary<string, Task<Book[]>> data 
                = new Dictionary<string, Task<Book[]>>(containsTitle.Length);

            try
            {
                foreach (var elem in dbFiles)
                {
                    var connectionString = BuildConnectionStringFromPath(elem);
                    var libraryDirectory = new DirectoryInfo(
                        Path.GetDirectoryName(elem)
                        );

                    var context = new CalibreContext(connectionString) 
                    {
                        AsNoTracking = false,
                        LibraryDirectory = libraryDirectory
                    };
                    contexts.Add(context);

                    IQueryable<Book> selectExpr = context
                        .Books
                        .Include(e => e.Tags)
                        .ThenInclude(e => e.TagItem);

                    selectExpr = selectExpr
                        .Include(e => e.FileData);

                    selectExpr = selectExpr
                        .Include(e => e.Autors)
                        .ThenInclude(e => e.AuthorItem);

                    if (string.IsNullOrEmpty(containsTitle))
                    {
                        selectExpr = selectExpr
                            .Where(
                                e => e.Title.Contains(containsTitle)
                            );
                    }

                    var selectResultTask = selectExpr.ToArrayAsync();
                    data.Add(elem, selectResultTask);
                }

                await Task.WhenAll(
                    data.Values.ToArray()
                    );
            }
            finally 
            {
                contexts.ForEach(
                    e => e.Dispose()
                    );
            }

            var result = data
                .ToDictionary(
                    e => e.Key, 
                    e => e.Value.Result
                    );
            return result;
        }

        static void Main(string[] args)
        {
            //var connectionString = @"";

            //using (var context = new CalibreContext(connectionString))
            //{
            //    var books = context.Books
            //        .OrderBy(e => e.Id)
            //        .ToArray();
            //}


            SearchByTitleInDirectory(
                new DirectoryInfo(@""),
                ""
                )
                .GetAwaiter()
                .GetResult();
        }


        static async Task SearchByTitleInDirectory(
            DirectoryInfo directory, 
            string containsTitle
            )
        {
            var watch = Stopwatch.StartNew();

            var dbFiles = SelectDbFiles(directory);
            var searchResult = await SearchBooksByTitle(dbFiles, "")
                .ConfigureAwait(false);
            watch.Stop();


            var allBooks = searchResult
                .SelectMany(e => e.Value)
                .ToArray();

            var allTags = allBooks
                .SelectMany(e => e.Tags)
                .Select(e => e.TagItem)
                .Distinct()
                .ToHashSet();

            var searchIgnoreCase = allBooks
                .Where(
                    e => 
                        //Заголовок
                        e.Title.Contains(containsTitle, StringComparison.OrdinalIgnoreCase)
                        //Теги
                        || e.Tags.Any(
                                e => e.TagItem.Name.Contains(containsTitle, StringComparison.OrdinalIgnoreCase)
                                )
                    )
                .ToArray();

            foreach (var elem in searchIgnoreCase)
            {
                Console.WriteLine($"{elem.Title}|{elem.AuthorSort}");
            }

            var book = searchIgnoreCase.First();

            var dbFile = searchResult
                .First(
                    e => e.Value.Any(e2 => e2.Title == book.Title)
                )
                .Key;

            BookFileProvider bookFileProvider = new BookFileProvider();
            //var path = await bookFileProvider.BuildFilePathAsync(
            //    Path.GetDirectoryName(dbFile),
            //    book,
            //    (b) => Task.FromResult(b.FileData.First())
            //    );

            var bookText = await bookFileProvider.ReadFileAsync(
                    Path.GetDirectoryName(dbFile),
                    book,
                    (b) => Task.FromResult(b.FileData.First()),
                    async (s) =>
                    {
                        SimplePdfReader simplePdfReader = new SimplePdfReader();
                        var result = await simplePdfReader.ReadPdfAsync(s);
                        return result;
                    }
                );

            var booksWithPdf = allBooks
                .Where(
                    e => e.FileData.Any(e2 => e2.Format == "PDF")
                )
                .ToArray();
        }
    }
}