Register Guidelines E-Books Search Today's Posts Mark Forums Read

Go Back   MobileRead Forums > E-Book Software > Calibre > Development

Notices

Reply
 
Thread Tools Search this Thread
Old 07-04-2014, 10:56 AM   #1
DiapDealer
Grand Sorcerer
DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.
 
DiapDealer's Avatar
 
Posts: 9,006
Karma: 40853212
Join Date: Jan 2010
Device: Nexus 7, Kindle Fire HD
Add books programatically from plugin

GUI plugin.

Having trouble getting the parameters right for the add_books() method (database2.py). I'm using advice from an older post to the effect of:

Code:
gui = get_gui()
db = gui.library_view.model().db
db.add_books(...)
I have a file object (PersistentTemporaryFile) representing a valid ePub called "result"

I have a metadata object ('mi'); retrieved using
Code:
mi = get_metadata(result, 'epub')
I'm able to successfully use 'import_book' to add the book:
Code:
db.import_book(mi, [result.name])
with all the correct metadata, so I'm assuming my get_metadata call is working(?), but I can't seem to get the add_books() call to work without the following error:
Spoiler:
Code:
calibre, version 1.40.0
ERROR: Unhandled exception: <b>AttributeError</b>:'str' object has no attribute 'tags'

calibre 1.40  isfrozen: True is64bit: False
Windows-Vista-6.0.6002-SP2 Windows ('32bit', 'WindowsPE')
('Windows', 'Vista', '6.0.6002')
Python 2.7.5
Windows: ('Vista', '6.0.6002', 'SP2', 'Multiprocessor Free')
Traceback (most recent call last):
  File "calibre_plugins.obok_dedrm.dialogs", line 76, in _ok_clicked
  File "site-packages\calibre\gui2\library\models.py", line 306, in add_books
  File "site-packages\calibre\db\legacy.py", line 218, in add_books
  File "site-packages\calibre\db\cache.py", line 1409, in add_books
  File "site-packages\calibre\db\cache.py", line 57, in call_func_with_lock
  File "site-packages\calibre\db\cache.py", line 1363, in create_book_entry
AttributeError: 'str' object has no attribute 'tags'

I can't seem to nail down what is needed in the 'paths' and 'formats' parameters of the add_book() method.

Can someone clue me in to how to pass the correct parameters to the add_books method (based on my file object and my metadata object)?

I'm wanting to use the "add_books" method instead of "import_book" simply because it has the "add_duplicates" flag that I'm assuming that I can set to false in order to prevent adding a duplicate book (or at least honor the library settings for dealing with duplicates). If there's a better way to achieve that, I'm all ears, too.

Thanks in advance
DiapDealer is online now   Reply With Quote
Old 07-04-2014, 11:57 AM   #2
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,908
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
database2.py is the obsolete API, instead use

db.new_api.add_books

https://github.com/kovidgoyal/calibr...cache.py#L1406
kovidgoyal is offline   Reply With Quote
Old 07-04-2014, 12:39 PM   #3
chaley
"chaley", not "charley"
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 5,409
Karma: 821648
Join Date: Jan 2010
Location: France
Device: Many android devices
Not sure if this will help, but you should probably be using the new db api. For that one add_books is:
Code:
    def add_books(self, books, add_duplicates=True, apply_import_tags=True, preserve_uuid=False, run_hooks=True, dbapi=None):
        duplicates, ids = [], []
        for mi, format_map in books:
            book_id = self.create_book_entry(mi, add_duplicates=add_duplicates, apply_import_tags=apply_import_tags, preserve_uuid=preserve_uuid)
            if book_id is None:
                duplicates.append((mi, format_map))
            else:
                ids.append(book_id)
                for fmt, stream_or_path in format_map.iteritems():
                    self.add_format(book_id, fmt, stream_or_path, dbapi=dbapi, run_hooks=run_hooks)
        return ids, duplicates
The books parameter is a dictionary of mi records and a formats dict telling calibre where to get the format.

You get a reference to "cache" via db.new_api.

EDIT: walked away from my screen and Kovid answered.
chaley is offline   Reply With Quote
Old 07-04-2014, 01:30 PM   #4
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,908
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
Here's some long overdue API documentation for the db interface:

http://manual.calibre-ebook.com/db_api.html
kovidgoyal is offline   Reply With Quote
Old 07-04-2014, 01:46 PM   #5
DiapDealer
Grand Sorcerer
DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.
 
DiapDealer's Avatar
 
Posts: 9,006
Karma: 40853212
Join Date: Jan 2010
Device: Nexus 7, Kindle Fire HD
Sweet! Thanks for the pointers guys. I had a sneaking suspicion (especially when seeing the word "legacy" in error messages) that there were newer options to go with here.
DiapDealer is online now   Reply With Quote
Old 07-05-2014, 11:23 AM   #6
DiapDealer
Grand Sorcerer
DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.
 
DiapDealer's Avatar
 
Posts: 9,006
Karma: 40853212
Join Date: Jan 2010
Device: Nexus 7, Kindle Fire HD
Out of curiosity/completeness ... should a minimum_calibre_version should be specified for plugins that utilize the new api? Or is it all backward-compatible with the old api?
DiapDealer is online now   Reply With Quote
Old 07-05-2014, 11:42 AM   #7
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,908
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
You can use the old api in all versions of calibre, the new api needs calibre 1.0 or newer. So if you use the new api you need a minimum_version
kovidgoyal is offline   Reply With Quote
Old 07-05-2014, 12:06 PM   #8
DiapDealer
Grand Sorcerer
DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.
 
DiapDealer's Avatar
 
Posts: 9,006
Karma: 40853212
Join Date: Jan 2010
Device: Nexus 7, Kindle Fire HD
Thanks again.
DiapDealer is online now   Reply With Quote
Old 07-08-2014, 11:13 PM   #9
jhowell
Zealot
jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'
 
jhowell's Avatar
 
Posts: 138
Karma: 39769
Join Date: Nov 2011
Location: Florida
Device: iPad 2, Kinde PW II
I am trying to update my plugin to use the new API, but I ran into a problem when using "db.new_api.add_books" instead of "db.import_book".

After changing my code to use add_books the new books no longer appear in the main table of books in the GUI. All that appears is a blank row at the end created by my call to gui.library_view.model().books_added(number_added_ books).

I looked at the code for add_books in calibre.db.legacy and saw that after calling self.new_api.add_books it later calls self.data.books_added.

Code:
    def add_books(self, paths, formats, metadata, add_duplicates=True, return_ids=False):
        books = [(mi, {fmt:path}) for mi, path, fmt in zip(metadata, paths, formats)]
        book_ids, duplicates = self.new_api.add_books(books, add_duplicates=add_duplicates, dbapi=self)
        if duplicates:
            paths, formats, metadata = [], [], []
            for mi, format_map in duplicates:
                metadata.append(mi)
                for fmt, path in format_map.iteritems():
                    formats.append(fmt)
                    paths.append(path)
            duplicates = (paths, formats, metadata)
        ids = book_ids if return_ids else len(book_ids)
        if book_ids:
            self.data.books_added(book_ids)
        return duplicates or None, ids
I added a similar call in my plugin and this solved the problem.

So I am wondering if it is best to leave it this way or is there something else I should be doing to properly update the GUI after adding books in the new API?
jhowell is offline   Reply With Quote
Old 07-08-2014, 11:22 PM   #10
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,908
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
To fully update the GUI after adding new books you would need to do

db.data.books_added(book_ids)
self.gui.library_view.model().books_added(num)
self.gui.db_images.reset()
self.gui.tags_view.recount()

This updates all the various components of the GUI.

Last edited by kovidgoyal; 07-15-2014 at 10:34 PM.
kovidgoyal is offline   Reply With Quote
Old 07-08-2014, 11:30 PM   #11
jhowell
Zealot
jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'jhowell can spell AND pronounce 'liseuse.'
 
jhowell's Avatar
 
Posts: 138
Karma: 39769
Join Date: Nov 2011
Location: Florida
Device: iPad 2, Kinde PW II
Quote:
Originally Posted by kovidgoyal View Post
To fully update the GUI after adding new books you would need to do

db.data.books_added(book_ids)
self.gui.library_view.model().books_added(num)
self.gui.db_images.beginResetModel(), self.gui.db_images.endResetModel()
self.gui.tags_view.recount()

This updates all the various components of the GUI.
Thanks.
jhowell is offline   Reply With Quote
Old 07-15-2014, 10:24 PM   #12
DiapDealer
Grand Sorcerer
DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.
 
DiapDealer's Avatar
 
Posts: 9,006
Karma: 40853212
Join Date: Jan 2010
Device: Nexus 7, Kindle Fire HD
Quote:
Originally Posted by kovidgoyal View Post
To fully update the GUI after adding new books you would need to do

db.data.books_added(book_ids)
self.gui.library_view.model().books_added(num)
self.gui.db_images.beginResetModel(), self.gui.db_images.endResetModel()
self.gui.tags_view.recount()

This updates all the various components of the GUI.
self.gui.db_images.beginResetModel(), self.gui.db_images.endResetModel() seems to be working for me in the PyQt5 beta versions of calibre, but not in the current (PyQt4) versions.

Getting the following error:
Code:
AttributeError: 'DatabaseImages' object has no attribute 'beginResetModel'
DiapDealer is online now   Reply With Quote
Old 07-15-2014, 10:34 PM   #13
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 25,908
Karma: 5035037
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
Sorry, my mistake, just use reset() it will work in both.
kovidgoyal is offline   Reply With Quote
Old 07-15-2014, 11:06 PM   #14
DiapDealer
Grand Sorcerer
DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.
 
DiapDealer's Avatar
 
Posts: 9,006
Karma: 40853212
Join Date: Jan 2010
Device: Nexus 7, Kindle Fire HD
No prob. Thanks for the correction.

Last edited by DiapDealer; 07-20-2014 at 12:40 PM.
DiapDealer is online now   Reply With Quote
Old 07-20-2014, 12:40 PM   #15
DiapDealer
Grand Sorcerer
DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.DiapDealer ought to be getting tired of karma fortunes by now.
 
DiapDealer's Avatar
 
Posts: 9,006
Karma: 40853212
Join Date: Jan 2010
Device: Nexus 7, Kindle Fire HD
Quote:
Originally Posted by kovidgoyal View Post
To fully update the GUI after adding new books you would need to do

db.data.books_added(book_ids)
self.gui.library_view.model().books_added(num)
self.gui.db_images.reset()
self.gui.tags_view.recount()

This updates all the various components of the GUI.
This works fine for me when adding new books, but if my plugin adds a format to the book that happens to be the current selection, none of the above makes that new format show up (without selecting something else and coming back). It's very possible it's supposed to work that way, which is why I'm checking.

Would there be any downside to adding the following code to your suggested snippet in a general "GUI refresh" utility-method within a plugin?:
Code:
current_idx = self.gui.library_view.currentIndex()
if current_idx.isValid():
    self.gui.library_view.model().current_changed(current_idx, current_idx)
Or is there another/better way to refresh that currently selected book's details in the gui?
(Using the new api's "add_format" method if that's relevant)

Last edited by DiapDealer; 07-20-2014 at 12:52 PM.
DiapDealer is online now   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Plugin ideas... add yours here kiwidude Plugins 638 09-10-2014 05:15 AM
calibre add new plugin ? book64 Plugins 5 06-18-2013 11:36 PM
Trying to add large library of books - add books seems to have hung nicknefarious Library Management 1 06-18-2012 09:32 AM
How do I add a Table view in my plugin? katsu Development 3 10-24-2011 12:05 PM
Getting book's id number programatically GreyNomad Development 3 03-18-2011 04:16 AM


All times are GMT -4. The time now is 07:52 PM.


MobileRead.com is a privately owned, operated and funded community.