Example #1
0
        public override void DeleteBook(int id)
        {
            Database.BookEntry bookEntry = Database.BOOKS.FirstOrDefault(x => x.Id == id);
            if (bookEntry == null)
            {
                throw new Database.IDNotFoundException();
            }

            Database.RemoveBook(bookEntry);

            string filePath = AbsoluteFilePath(bookEntry);

            try
            {
                File.Delete(filePath);
            }
            catch (FileNotFoundException) { }
            catch (DirectoryNotFoundException) { }
            catch (Exception e)
            {
                throw new Exception($"{bookEntry.Title} was removed from database but the file could not be deleted. {e.Message}");
            }

            Utils.Files.CleanBackward(Path.GetDirectoryName(filePath), LibraryRoot);
        }
Example #2
0
        public virtual void UpdateBookMetadata(BookBase donor)
        {
            Database.BookEntry entry = Database.BOOKS.FirstOrDefault(x => x.Id == donor.Id);
            if (entry == null)
            {
                return;
            }
            BookBase recip = BookBase.Auto(AbsoluteFilePath(entry));

            recip.UpdateMetadata(donor);

            Database.UpdateBook(donor);

            string origPath   = recip.FilePath;
            string targetPath = FormatFilePath(FilePathTemplate(), recip);

            if (origPath != targetPath)
            {
                try
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                    File.Move(origPath, targetPath);
                    donor.FilePath = targetPath;
                    Database.UpdateBook(donor);
                }
                catch (Exception e)
                {
                    throw new Exception($"Could not rename file in library directory. {e.Message}");
                }
            }
        }
        public MetadataEditor(Database.BookEntry book, HashSet <string> authors, HashSet <string> series, HashSet <string> publishers)
        {
            this.DataContext = this;
            this.AuthorsList = App.LocalLibrary.Database.ListAuthors();
            this.SeriesList  = App.LocalLibrary.Database.ListSeries();
            this.ModBook     = new Database.BookEntry(book);

            AuthorsList   = authors.ToArray();
            SeriesList    = series.ToArray();
            PublisherList = publishers.ToArray();

            InitializeComponent();
        }
Example #4
0
        // todo test this whole region
        #region book import methods

        /// <summary>
        /// Used to import from another device's library.
        /// </summary>
        private void ImportBook(Database.BookEntry remoteEntry)
        {
            Logger.Info("Importing {}.", remoteEntry.Title);
            BookBase localBook = CombinedLibrary.FirstOrDefault(x => x.IsLocal && x.Id == remoteEntry.Id);

            if (localBook != null)
            {
                Logger.Info("{}[{}] already exists in library, copying metadata from Kindle.", localBook.Title, localBook.Id);
                try
                {
                    localBook.UpdateMetadata(remoteEntry);
                }
                catch (LiteDB.LiteException e)
                {
                    Logger.Error(e, "Unable to update metadata in database.");
                    throw new Exception($"Unable to update metadata in database; {e.Message}");
                }
                catch (Exception e)
                {
                    Logger.Error(e, "Unable to write metadata to disk.");
                    throw new Exception($"Unable to write metadata to disk; {e.Message}");
                }
            }

            Dictionary <string, string> remoteMetadata = remoteEntry.Props();

            string localFile = Path.Combine(App.Config.LibraryRoot, App.Config.LibraryRoot, "{Title}").DictFormat(remoteMetadata);

            localFile = Utils.Files.MakeFilesystemSafe(localFile + Path.GetExtension(remoteEntry.FilePath));

            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(localFile));
            }
            catch (Exception e)
            {
                Logger.Error(e, "Unable to create directories.");
                throw new Exception($"Unable to create directories; {e.Message}");
            }

            Database.BookEntry localEntry;
            if (File.Exists(localFile))
            {
                localEntry = CombinedLibrary.FirstOrDefault(x => x.IsLocal && x.FilePath == localFile);
                if (localEntry == null) // target file exists but is *not* in local db
                {
                    Logger.Info("{} exists but is not in local database. File will be overwritten with remote copy.", localFile);
                    try
                    {
                        File.Delete(localFile);
                        File.Copy(remoteEntry.FilePath, localFile);
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "Unable to overwrite file.");
                        throw new Exception($"Unable to overwrite file; {e.Message}");
                    }
                    try
                    {
                        App.LocalLibrary.ImportBook(remoteEntry);
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "Unable to update library database.");
                        throw new Exception($"Unable to update library; {e.Message}");
                    }
                }
                else // target file exists and *is* in local db
                {
                    string msg = $"{localEntry.Title} exists in local library. Metadata will be copied from Kindle";
                    if (SelectedDevice != null && localEntry.Id != remoteEntry.Id)
                    {
                        Logger.Info(msg + " ID [{}] on {} will be changed from to [{}] to match local database.", remoteEntry.Id, SelectedDevice.Name, localEntry.Id);
                        try
                        {
                            SelectedDevice.Database.ChangeBookId(remoteEntry, localEntry.Id);
                        }
                        catch (Exception e)
                        {
                            Logger.Error(e, "Unable to write to database.");
                            throw new Exception($"Unable to write to database; {e.Message}");
                        }
                    }
                    Logger.Info(msg, remoteEntry.Title);
                    try
                    {
                        localEntry.UpdateMetadata(remoteEntry);
                        App.LocalLibrary.Database.UpdateBook(localEntry);
                    }
                    catch (LiteDB.LiteException e)
                    {
                        Logger.Error(e, "Unable to write metadata to database.");
                        throw new Exception($"Unable to write metadata database; {e.Message}");
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "Unable to write metadata to disk.");
                        throw new Exception($"Unable to write metadata disk; {e.Message}");
                    }
                }
            }
            else
            {
                localEntry = CombinedLibrary.FirstOrDefault(x => x.IsLocal && x.Id == remoteEntry.Id);
                if (localEntry != null)
                {
                    Logger.Info("{} found in database but not on disk, removing database entry before importing.", localEntry.Title);
                    try
                    {
                        App.LocalLibrary.Database.RemoveBook(localEntry);
                    }
                    catch (LiteDB.LiteException e)
                    {
                        Logger.Error(e, "Unable to write to database.");
                        throw new Exception($"Unable to write to database; {e.Message}");
                    }
                }

                try
                {
                    App.LocalLibrary.ImportBook(remoteEntry);
                }
                catch (LiteDB.LiteException e)
                {
                    Logger.Error(e, "Unable to write to database.");
                    throw new Exception($"Unable to write to database; {e.Message}");
                }
                catch (Exception e)
                {
                    Logger.Error(e, "Unable to import book.");
                    throw new Exception($"Unable to import book; {e.Message}");
                }
            }
        }
Example #5
0
        public async void _RemoveBook()
        {
            if (SelectedTableRow == null)
            {
                return;
            }
            Database.BookEntry book = SelectedTableRow;

            bool onDevice = SelectedDevice == null ? false : CombinedLibrary.Any(x => x.IsRemote && x.Id == book.Id);
            bool onPC     = CombinedLibrary.Any(x => x.IsLocal && x.Id == book.Id);

            var dlg = new Dialogs.DeleteConfirm(book.Title, onDevice, onPC);
            await MaterialDesignThemes.Wpf.DialogHost.Show(dlg);

            if (dlg.DialogResult == false)
            {
                return;
            }
            if (dlg.DeleteFrom == 0 || dlg.DeleteFrom == 1) // device
            {
                Database.BookEntry remoteBook = SelectedDevice.Database.BOOKS.FirstOrDefault(x => x.Id == book.Id);
                try
                {
                    SelectedDevice.DeleteBook(book.Id);
                }
                catch (Exception e)
                {
                    var errDlg = new Dialogs.Error($"Unable to delete book from {SelectedDevice.Name}", e.Message);
                    await MaterialDesignThemes.Wpf.DialogHost.Show(errDlg);

                    return;
                }
            }
            if (dlg.DeleteFrom == 0 || dlg.DeleteFrom == 2) // pc
            {
                Database.BookEntry localBook = CombinedLibrary.FirstOrDefault(x => x.IsLocal && x.Id == book.Id);
                try
                {
                    if (localBook != null)
                    {
                        try
                        {
                            App.LocalLibrary.DeleteBook(localBook);
                        }
                        catch (FileNotFoundException) { }
                        catch (DirectoryNotFoundException) { }

                        Utils.Files.CleanBackward(Path.GetDirectoryName(localBook.FilePath), App.LibraryDirectory);
                    }
                    App.LocalLibrary.Database.RemoveBook(book);
                }
                catch (Exception e)
                {
                    var errDlg = new Dialogs.Error("Unable to delete book from library", e.Message);
                    await MaterialDesignThemes.Wpf.DialogHost.Show(errDlg);

                    return;
                }
            }

            string msg = dlg.DeleteFrom == 0 ? "PC & Kindle" : (dlg.DeleteFrom == 2 ? "PC" : "Kindle");

            SnackBarQueue.Enqueue($"{book.Title} deleted from {msg}.");
        }
Example #6
0
        public async void _SyncDeviceLibrary()
        {
            if (SelectedDevice == null)
            {
                var errDlg = new Dialogs.Error("No Kindle Selected", "Connect to Kindle Before Transferring Books");
                await MaterialDesignThemes.Wpf.DialogHost.Show(errDlg);

                return;
            }

            List <Database.BookEntry> toTransfer = new List <Database.BookEntry>();

            foreach (Database.BookEntry book in App.LocalLibrary.Database.BOOKS)
            {
                if (!SelectedDevice.Database.BOOKS.Any(x => x.Id == book.Id))
                {
                    toTransfer.Add(book);
                }
            }

            var dlg = new Dialogs.SyncConfirm(toTransfer, SelectedDevice.Name);
            await MaterialDesignThemes.Wpf.DialogHost.Show(dlg);

            if (dlg.DialogResult == false)
            {
                return;
            }

            var a = dlg.UserSelectedBooks;

            foreach (var b in dlg.UserSelectedBooks)
            {
                if (!b.Checked)
                {
                    Database.BookEntry t = toTransfer.FirstOrDefault(x => x.Id == b.Id);
                    if (t != null)
                    {
                        toTransfer.Remove(t);
                    }
                }
            }

            var prgDlg = new Dialogs.Progress("Syncing Kindle Library", false);

            OpenBottomDrawer(prgDlg.Content);

            _ = Task.Run(() =>
            {
                List <Exception> errs = new List <Exception>();
                int step = 100 / toTransfer.Count;
                for (int i = 0; i < toTransfer.Count; i++)
                {
                    Database.BookEntry book = toTransfer[i];
                    try
                    {
                        prgDlg.Current  = $"Copying {book.Title}";
                        prgDlg.Percent += step;
                        book.FilePath   = App.LocalLibrary.AbsoluteFilePath(book);
                        SelectedDevice.ImportBook(book);
                    }
                    catch (Exception e)
                    {
                        e.Data.Add("item", book.Title);
                        errs.Add(e);
                    }
                }

                if (errs.Count > 0)
                {
                    prgDlg.Finish("Library sync finished with errors:");
                    prgDlg.ShowError(new AggregateException(errs.ToArray()));
                }
                else
                {
                    prgDlg.Close();
                    SnackBarQueue.Enqueue($"{SelectedDevice.Name} library synced");
                }
            });
        }
Example #7
0
        public Unit _ReceiveBook(IList bookList)
        {
            if (bookList.Count == 0)
            {
                return(Unit.Default);
            }

            Database.BookEntry[] dbRows = new Database.BookEntry[bookList.Count];
            bookList.CopyTo(dbRows, 0);

            Task.Run(() =>
            {
                if (bookList.Count == 1)
                {
                    Database.BookEntry book = (Database.BookEntry)bookList[0];
                    try
                    {
                        book.FilePath = SelectedDevice.AbsoluteFilePath(book);
                        ImportBook(book);
                    }
                    catch (Exception e)
                    {
                        App.Current.Dispatcher.Invoke(() =>
                        {
                            var dlg = new Dialogs.Error("Error transferring book", e.Message);
                            MaterialDesignThemes.Wpf.DialogHost.Show(dlg);
                        });
                        return;
                    }
                    SnackBarQueue.Enqueue($"{book.Title} copied to library.");
                }
                else
                {
                    List <Exception> errs = new List <Exception>();

                    var prgDlg = new Dialogs.Progress("Syncing Library", false);
                    OpenBottomDrawer(prgDlg.Content);

                    int step = 100 / bookList.Count;

                    foreach (Database.BookEntry b in bookList)
                    {
                        Database.BookEntry book = new Database.BookEntry(b);
                        try
                        {
                            book.FilePath = SelectedDevice.AbsoluteFilePath(book);
                            ImportBook(book);
                        }
                        catch (Exception e)
                        {
                            e.Data["item"] = book.Title;
                            errs.Add(e);
                        }
                    }

                    if (errs.Count > 0)
                    {
                        prgDlg.Finish("Book transfer finished with errors:");
                        prgDlg.ShowError(new AggregateException(errs.ToArray()));
                    }
                    else
                    {
                        prgDlg.Close();
                        SnackBarQueue.Enqueue("Book transfer finished");
                    }
                }
            });

            return(Unit.Default);
        }