Example #1
0
        /// <summary>
        /// Add category to the book
        /// </summary>
        private void Category_OnKeyUp(object sender, KeyEventArgs e)
        {
            var textBox = (TextBox)sender;

            if (textBox.Text.Length <= 1 || (textBox.Text.Substring(textBox.Text.Length - 1) != ";" && textBox.Text.Substring(textBox.Text.Length - 1) != ","))
            {
                return;
            }

            var category = textBox.Text.Substring(0, textBox.Text.Length - 1);

            textBox.Text = String.Empty;

            if (_categoryTagList.Any(categoryTag => categoryTag.Name == category))
            {
                return;
            }

            CategoryTagsBorder.Visibility = Visibility.Visible;
            _categoryTagList.Add(new CategoryTag {
                Name = category
            });

            Db.NonQuery("INSERT OR IGNORE INTO categories VALUES(@Path, @Name, 0)", new []
            {
                new SQLiteParameter("Path", BookKeeper.GetRelativeBookFilePath(_bookFile)),
                new SQLiteParameter("Name", category)
            });
        }
Example #2
0
        /// <summary>
        /// Go through all database records along with all book files in the library root folder and remove any database entries which point to non-existing files,
        /// then attempt to generate database entries for all book files, which don't have them.
        /// </summary>
        public static void SyncDbWithFileTree()
        {
            MainWindow.Busy(true);

            Task.Factory.StartNew(() =>
            {
                GenerateFileTree();
                Tools.RemoveEmptyDirectories(Properties.Settings.Default.BooksDir);
                var fileTree           = GetFileTree();
                const string sql       = "SELECT Path FROM books";
                const string sqlDelete = "DELETE FROM books WHERE Path = @Path";
                var query    = Db.Query(sql);
                var pathList = new List <string>();

                MainWindow.Busy(UiLang.Get("BusyCleaningDb"));

                //Delete rows pointing to non-existing files
                while (query.Read())
                {
                    if (File.Exists(BookKeeper.GetAbsoluteBookFilePath(query["Path"].ToString())))
                    {
                        pathList.Add(query["Path"].ToString());
                    }
                    else
                    {
                        Db.NonQuery(sqlDelete, new[] { new SQLiteParameter("Path", query["Path"].ToString()) });
                    }
                }

                MainWindow.BusyMax(fileTree.Count(bookFile => !pathList.Contains(BookKeeper.GetRelativeBookFilePath(bookFile))));

                var i = 0;

                //Generate rows for any books missing them
                foreach (
                    var bookFile in
                    fileTree.Where(bookFile => !pathList.Contains(BookKeeper.GetRelativeBookFilePath(bookFile))))
                {
                    MainWindow.Busy(BookKeeper.GetRelativeBookFilePath(bookFile));
                    MainWindow.Busy(i++);

                    try
                    {
                        BookKeeper.GetData(bookFile);
                    }
                    catch (Exception e)
                    {
                        DebugConsole.WriteLine(
                            "Library structure: I found a book file without any entry in the database (" + bookFile +
                            "), but an error occurred during attempted adding: " + e);
                    }
                }

                MainWindow.MW.Dispatcher.Invoke(() => MainWindow.MW.BookGridReload());

                MainWindow.Busy(false);
            });
        }
Example #3
0
        private void Discard_OnClick(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show(String.Format(UiLang.Get("BookDeleteConfirm"), BookInfoGet("Title")), UiLang.Get("BookDeleteConfirmTitle"), MessageBoxButton.YesNo) != MessageBoxResult.Yes)
            {
                return;
            }

            BookKeeper.Discard(_bookFile);
            Close();
        }
Example #4
0
        private void BookGrid_OnKeyUp(object sender, KeyEventArgs e)
        {
            var dataGrid           = (DataGrid)sender;
            var forcedSettingValue = (Keyboard.IsKeyDown(Key.LeftShift)
                ? true
                : (Keyboard.IsKeyDown(Key.LeftCtrl) ? false : (bool?)null));

            switch (e.Key)
            {
            case Key.Delete:
                if (
                    MessageBox.Show(
                        String.Format(UiLang.Get("DeleteBooksConfirm"),
                                      dataGrid.SelectedItems.Count), UiLang.Get("DiscardBook"), MessageBoxButton.YesNo) !=
                    MessageBoxResult.Yes)
                {
                    return;
                }

                foreach (var book in dataGrid.SelectedItems.Cast <Book>().ToList())
                {
                    BookKeeper.Discard(book.BookFile);
                }

                break;

            case Key.F:
                foreach (var book in dataGrid.SelectedItems.Cast <Book>().ToList())
                {
                    BookInfoSet("Favorite", (forcedSettingValue ?? (!book.Favorite)), book.BookFile);
                }

                BookGridReload();     //Reload grid in the main window
                break;

            case Key.S:
                foreach (var book in dataGrid.SelectedItems.Cast <Book>().ToList())
                {
                    BookInfoSet("Sync", (forcedSettingValue ?? (!book.Sync)), book.BookFile);
                }

                BookGridReload();     //Reload grid in the main window
                break;

            case Key.D:
                foreach (var book in dataGrid.SelectedItems.Cast <Book>().ToList())
                {
                    BookInfoSet("Sync", (forcedSettingValue ?? (!book.Sync)), book.BookFile);
                    BookInfoSet("Favorite", (forcedSettingValue ?? (!book.Favorite)), book.BookFile);
                }
                BookGridReload();     //Reload grid in the main window
                break;
            }
        }
Example #5
0
        /// <summary>
        /// Remove category from the book
        /// </summary>
        private void CategoryTag_OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var categoryTag = (CategoryTag)(((Button)sender).DataContext);

            _categoryTagList.Remove(categoryTag);

            if (_categoryTagList.Count == 0)
            {
                CategoryTagsBorder.Visibility = Visibility.Collapsed;
            }

            Db.NonQuery("DELETE FROM categories WHERE Name = @Name AND Path = @Path", new []
            {
                new SQLiteParameter("Name", categoryTag.Name),
                new SQLiteParameter("Path", BookKeeper.GetRelativeBookFilePath(_bookFile))
            });
        }
Example #6
0
        /// <summary>
        /// Mark automatically added category as user added category
        /// </summary>
        private void CategoryTag_OnPreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            var categoryTag = (CategoryTag)(((Button)sender).DataContext);

            if (_categoryTagList.Count == 0)
            {
                CategoryTagsBorder.Visibility = Visibility.Collapsed;
            }

            Db.NonQuery("UPDATE categories SET FromFile = 0 WHERE Name = @Name AND Path = @Path", new[]
            {
                new SQLiteParameter("Name", categoryTag.Name),
                new SQLiteParameter("Path", BookKeeper.GetRelativeBookFilePath(_bookFile))
            });

            categoryTag.FromFile         = false;
            ((Button)sender).BorderBrush = Brushes.DarkRed;
        }
Example #7
0
        //Change value in existing .dat file for a book
        private static void BookInfoSet(string key, object value, string bookFile)
        {
            try
            {
                var bookData = BookKeeper.GetData(bookFile);

                if ((typeof(BookData)).GetField("Sync") == null)
                {
                    return;
                }

                typeof(BookData).GetField(key).SetValue(bookData, value);
                BookKeeper.SaveData(bookData);
            }
            catch (Exception e)
            {
                DebugConsole.WriteLine("Edit book: It was not possible to save the provided book data: " + e.Message);
            }
        }
Example #8
0
        /// <summary>
        /// Save data from the EditBook fields into the database
        /// </summary>
        /// <param name="key">Name of the BookData field to which to save the data</param>
        /// <param name="value">Value to be saved into the specified field</param>
        private void BookInfoSet(string key, object value)
        {
            if (_bookData == null)
            {
                return;
            }

            typeof(BookData).GetField(key).SetValue(_bookData, value);

            try
            {
                BookKeeper.SaveData(_bookData);
            }
            catch (Exception e)
            {
                MainWindow.Info(String.Format(UiLang.Get("DatFileNotAvailable"), _bookData.Title), 1);
                DebugConsole.WriteLine("Edit book: It was not possible to save the provided value into the data file: " + e.Message);
                Close();
            }
        }
Example #9
0
        /// <summary>
        /// Fetch data to fill the form fields, from the BookInfo object based on the key
        /// </summary>
        /// <param name="key">Name of the BookData field from which to get the data</param>
        /// <returns>Value from the BookData field specified by the given key</returns>
        private object BookInfoGet(string key)
        {
            if (_bookData == null) //Singleton, so we don't have to reopen the DB with saved info, after every form field loads and its load event handler calls BookInfoGet
            {
                try
                {
                    _bookData = BookKeeper.GetData(_bookFile);
                }
                catch (Exception)
                {
                    MainWindow.Info(UiLang.Get("BookInfoNotAvailable"), 1);
                    IsEnabled = false;
                    Close();
                    _bookData = new BookData();
                    return(null);
                }
            }

            return(typeof(BookData).GetField(key) != null ? typeof(BookData).GetField(key).GetValue(_bookData) : null);
        }
Example #10
0
        private static void AddBooksFromList(IEnumerable <string> list)
        {
            Busy(true);

            Task.Factory.StartNew(() =>
            {
                foreach (var file in list)
                {
                    BookKeeper.Add(file);
                }

                MW.Dispatcher.Invoke(() =>
                {
                    LibraryStructure.GenerateFileTree();
                    MW.BookGridReload();
                });

                Busy(false);
            });
        }
Example #11
0
        /// <summary>
        /// Generate a list of BookData objects, where each of them contains information about a book
        /// </summary>
        public static List <BookData> List()
        {
            var          bookData = new List <BookData>();
            const string sql      = "SELECT * FROM books";
            var          query    = Db.Query(sql);

            while (query.Read())
            {
                if (!File.Exists(BookKeeper.GetAbsoluteBookFilePath(query["Path"].ToString())))
                {
                    continue;
                }


                bookData.Add(BookKeeper.CastSqlBookRowToBookData(query));
            }

            query.Dispose();

            return(bookData);
        }
Example #12
0
        private void Category_OnLoaded(object sender, RoutedEventArgs e)
        {
            var query = Db.Query("SELECT Name, FromFile FROM categories WHERE Path = @Path", new [] { new SQLiteParameter("Path", BookKeeper.GetRelativeBookFilePath(_bookFile)) });

            while (query.Read())
            {
                var category = new CategoryTag
                {
                    Name     = query["Name"].ToString(),
                    FromFile = SQLiteConvert.ToBoolean(query["FromFile"])
                };

                _categoryTagList.Add(category);
            }

            if (_categoryTagList.Count > 0)
            {
                CategoryTagsBorder.Visibility = Visibility.Visible;
            }

            Categories.ItemsSource = _categoryTagList;

            var defaultCategories = Properties.Settings.Default.DefaultCategories.Split(';');
            var hintList          = new List <string>(defaultCategories);

            hintList.AddRange(LibraryStructure.CategoryList());
            hintList.Sort();

            new Whisperer
            {
                TextBox  = (TextBox)sender,
                HintList = hintList
            };
        }
Example #13
0
        private void BookGrid_OnLoaded(object sender, RoutedEventArgs e)
        {
            DebugConsole.WriteLine("Loading the book grid...");

            var gridLoadStopwatch = new Stopwatch();

            gridLoadStopwatch.Start();

            var sqlCategoriesQueryStopwatch = new Stopwatch();
            var sqlbooksQueryStopwatch      = new Stopwatch();
            var grid         = (DataGrid)sender;
            var sql          = AssembleQuery();
            var categoryList = new Dictionary <string, List <string> >();
            var bookDataList = new List <BookData>();
            var bookList     = new List <Book>();
            var cultureList  = CultureInfo.GetCultures(CultureTypes.SpecificCultures);

            sqlbooksQueryStopwatch.Start();

            //Turn rows form the db into BookData objects
            using (var query = Db.Query(sql.Item1, sql.Item2))
            {
                sqlbooksQueryStopwatch.Stop();
                sqlCategoriesQueryStopwatch.Start();
                //Add list of attached categories to each BookData object
                using (var queryAllCategories = Db.Query("SELECT Path, Name FROM categories")) //Pull all categories from database, so that we don't have to do a separate query for each book
                {
                    sqlCategoriesQueryStopwatch.Stop();
                    //Turn category rows into a single dictionary, where each key is a Path, whose value is a List of category Names associated with said Path
                    while (queryAllCategories.Read())
                    {
                        var key   = queryAllCategories["Path"].ToString();
                        var value = queryAllCategories["Name"].ToString();

                        if (categoryList.ContainsKey(key))
                        {
                            categoryList[key].Add(value);
                        }
                        else
                        {
                            categoryList.Add(key, new List <string> {
                                value
                            });
                        }
                    }
                }

                //Cast book rows into BookData objects and assign them their category lists
                while (query.Read())
                {
                    var bookData = BookKeeper.CastSqlBookRowToBookData(query);

                    if (categoryList.ContainsKey(query["Path"].ToString()))
                    {
                        bookData.Categories = categoryList[query["Path"].ToString()];
                    }

                    bookDataList.Add(bookData);
                }
            }

            foreach (var bookData in bookDataList)
            {
                var countryCode = "_unknown";

                if (bookData.Language != "" &&
                    cultureList.FirstOrDefault(x => x.Name == bookData.Language) != null)
                //Make sure the book language is not neutral (ex: en instead of en-US), or invalid. This will make sure we don't display for example US flag for british english.
                {
                    countryCode = new RegionInfo((new CultureInfo(bookData.Language)).Name).TwoLetterISORegionName;
                }

                bookList.Add(new Book
                {
                    Title       = bookData.Title,
                    Author      = bookData.Author,
                    Publisher   = bookData.Publisher,
                    CountryCode = countryCode,
                    Published   = bookData.Published,
                    Description = bookData.Description,
                    Series      = bookData.Series,
                    Categories  = bookData.Categories,
                    Size        = Tools.BytesFormat(bookData.Size),
                    Favorite    = bookData.Favorite,
                    Sync        = bookData.Sync,
                    Cover       = bookData.Cover,
                    BookFile    = bookData.Path,
                });
            }

            grid.ItemsSource = bookList.OrderBy(x => x.Title); //By default, the list is sorted by book titles. Note: this is much faster than ORDER BY Title directly in the sqlite query
            gridLoadStopwatch.Stop();
            DebugConsole.WriteLine(String.Format("Book grid loaded. [Book count: {0}], [Grid load: {1}], [Categories query: {2}], [Books query: {3}]", bookList.Count, gridLoadStopwatch.Elapsed, sqlCategoriesQueryStopwatch.Elapsed, sqlbooksQueryStopwatch.Elapsed));
        }
Example #14
0
        /// <summary>
        /// Take all books files marked for sync and copy them onto the reader device, if one is found.
        /// If any book files are found on the reader device, which are not marked for sync in the local library, they will be deleted from the device.
        /// </summary>
        private static void SyncBookFiles()
        {
            var localBookList        = LibraryStructure.List();
            var localBookListForSync = (from bookData in localBookList where bookData.Sync select BookKeeper.GetAbsoluteBookFilePath(bookData.Path)).ToList();
            var bookList             = GetFileList();

            if (bookList == null) //The reader is not connected, or the specified storage folder on it doesn't exist, no point to continue
            {
                MainWindow.Busy(false);
                return;
            }

            var filesToDelete = (from file in bookList
                                 let fileName = Path.GetFileName(file)
                                                where !localBookListForSync.Select(Path.GetFileName).Contains(fileName)
                                                select file).ToArray();

            var filesToCopy = localBookListForSync.Where(
                file => File.Exists(file) && !bookList.Select(Path.GetFileName).Contains(Path.GetFileName(file))).ToArray();

            MainWindow.BusyMax(filesToDelete.Length + filesToCopy.Length);
            var busyCount = 0;

            foreach (var file in filesToDelete)
            //Delete files from the reader which don't exist in the local Sync list
            {
                MainWindow.Busy(busyCount++);
                MainWindow.Busy(file);

                try
                {
                    File.SetAttributes(file, FileAttributes.Normal);
                    File.Delete(file);
                }
                catch (Exception e)
                {
                    DebugConsole.WriteLine("Usb sync: Failed to delete " + file + ": " + e);
                }
            }

            foreach (var file in filesToCopy)
            //Copy files (which don't exist in the reader) into the reader, from the local Sync list
            {
                DebugConsole.WriteLine("Copying " + file);
                MainWindow.Busy(busyCount++);
                MainWindow.Busy(file);

                try
                {
                    if (file != null)
                    {
                        File.Copy(file, Path.Combine(_deviceDir, Path.GetFileName(file)));
                    }
                }
                catch (Exception e)
                {
                    MainWindow.Info(String.Format(UiLang.Get("SyncFileCopyFailed"), file));
                    DebugConsole.WriteLine("Usb sync: Error while copying " + file + ": " + e);
                }
            }

            MainWindow.Info(UiLang.Get("SyncFinished"));
            MainWindow.Busy(false);
        }