Example #1
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}");
                }
            }
        }