Register Guidelines E-Books Today's Posts Search

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

Notices

Reply
 
Thread Tools Search this Thread
Old 12-13-2011, 09:43 AM   #1
richlyon
Junior Member
richlyon began at the beginning.
 
Posts: 2
Karma: 10
Join Date: Dec 2011
Device: iPad
Accessing the database from Python

Hello everyone - I've enjoyed getting my head around plugin architecture, zipping my files, stopping and starting the code on each comma change, etc. etc. and suspect I will die of a frustration-induced stroke before I get much further.

Is there a simple way of accessing the database from within an external Python program? An interface, if you like ? How else can I retrieve and set book metadata from python outside the plugin metaphor?

Thanks all

Rich
richlyon is offline   Reply With Quote
Old 12-13-2011, 10:11 AM   #2
chaley
Grand Sorcerer
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: 11,733
Karma: 6690881
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Use "calibre-debug -e foo.py". This lets you run standalone python that uses calibre's interface to the database (the stuff in library.database2).

Here is an example of a program that reads & writes metadata in the database for an arbitrary book with ID=1283. Note that I wrote this program quite some time ago and don't know if it still works properly.
Spoiler:
Code:
from calibre.ebooks.metadata.book import ALL_METADATA_FIELDS
from calibre.ebooks.metadata.book.base import Metadata
from calibre.library.database2 import LibraryDatabase2
from calibre.utils.config import prefs
from calibre.utils.date import now

src = prefs['library_path']
db = LibraryDatabase2(src)

def check_equal(mi, nmi):
    for k in ALL_METADATA_FIELDS:
        if k == 'user_categories':
            continue
        v1 = mi.get(k)
        v2 = nmi.get(k)
        if k == 'tags':
            v1 = set(v1)
            v2 = set(v2)
        if v1 != v2:
            print 'not a match', k, v1, v2

id=1283
orig_mi = db.get_metadata(id, index_is_id=True)
print 'Set metadata to itself w/o force'
db.set_metadata(id, orig_mi)
nmi = db.get_metadata(id, index_is_id=True)
check_equal(orig_mi, nmi)

print 'Set metadata to itself w/force'
db.set_metadata(id, orig_mi, force_changes=True)
nmi = db.get_metadata(id, index_is_id=True)
check_equal(orig_mi, nmi)

print 'Null set. Should change nothing'
mi = db.get_metadata(id, index_is_id=True)
db.set_metadata(id, Metadata(None), set_title=False, set_authors=False)
nmi = db.get_metadata(id, index_is_id=True)
check_equal(mi, nmi)
           
print 'None tags. Should not change tags.'
old_tags = mi.tags
mi.tags = None
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if set(nmi.tags) != set(orig_mi.tags):
    print 'failed'

print 'Empty tags w/o force. Should not change tags'
mi.tags = []
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if set(nmi.tags) != set(orig_mi.tags):
    print 'failed', nmi.tags

print 'Empty tags w/force. Should change tags'
mi.tags = []
db.set_metadata(id, mi, force_changes=True)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.tags:
    print 'failed', nmi.tags

print 'Reset tags'
mi.tags = old_tags
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if set(nmi.tags) != set(mi.tags):
    print 'failed'

for attr in ('publisher', 'series', 'comments', 'author_sort'):
    print 'set %s w/o force'%attr
    setattr(mi, attr, '')
    db.set_metadata(id, mi)
    nmi = db.get_metadata(id, index_is_id=True)
    if getattr(nmi, attr, None) == '':
        print 'failed'

    print 'set %s w/force'%attr
    setattr(mi, attr, '')
    db.set_metadata(id, mi, force_changes=True)
    nmi = db.get_metadata(id, index_is_id=True)
    if getattr(nmi, attr, None) != '':
        print 'failed'

print 'restore metadata to original'
db.set_metadata(id, orig_mi, force_changes=True)
nmi = db.get_metadata(id, index_is_id=True)
check_equal(orig_mi, nmi)
mi = db.get_metadata(id, index_is_id=True)
        
print 'set pubdate to None w/o force. Should not change'
orig_pubdate = mi.pubdate
mi.pubdate = None
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.pubdate != orig_pubdate:
    print 'failed'
    
print 'set pubdate to None w/force. Should not change'
mi.pubdate = None
db.set_metadata(id, mi, force_changes=True)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.pubdate != orig_pubdate:
    print 'failed'
    
print 'set pubdate to now w/o force. Should change'
pd = mi.pubdate = now()
db.set_metadata(id, mi, force_changes=True)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.pubdate != pd:
    print 'failed'
    
print 'set rating to 5 w/o force. Should change'
mi.rating = 5
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.rating != 5:
    print 'failed'
    
print 'set rating to zero w/o force. Should change to zero'
mi.rating = 0
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.rating != 0:
    print 'failed'

print 'set series_index to 5 w/o force'
mi.series_index = 5.0
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.series_index != 5.0:
    print 'failed', nmi
    
print 'set series_index to 0 w/o force'
mi.series_index = 0.0
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.series_index != 0.0:
    print 'failed'

print 'set identifiers to None w/o force. Should not change'
orig_idents = mi.identifiers
mi.identifiers = None
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if set(orig_idents) != set(nmi.identifiers):
    print 'failed', orig_idents, nmi.identifiers

print 'set identifiers to None w/force. Should change'
mi.identifiers = None
db.set_metadata(id, mi, force_changes=True)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.identifiers != {}:
    print 'failed', nmi.identifiers

print 'set custom column to None w/o force. Should not change'
orig_cc = mi.get('#text')
mi.set('#text', None)
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.get('#text') != orig_cc:
    print 'failed'

print 'set custom column to None w/force. Should change'
mi.set('#text', None)
db.set_metadata(id, mi, force_changes=True)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.get('#text')is not None:
    print 'failed', nmi.get('#text')

print 'set custom column to "A" w/o force. Should change'
mi.set('#text', 'A')
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.get('#text') != 'A':
    print 'failed'

print 'set custom column to "" w/o force. Should change to None'
mi.set('#text', '')
db.set_metadata(id, mi)
nmi = db.get_metadata(id, index_is_id=True)
if nmi.get('#text') is not None:
    print 'failed', nmi.get('#text')

print 'Restore metadata to original'
db.set_metadata(id, orig_mi, force_changes=True)
nmi = db.get_metadata(id, index_is_id=True)
check_equal(orig_mi, nmi)

Last edited by chaley; 12-13-2011 at 10:14 AM. Reason: Added correctness disclaimer
chaley is offline   Reply With Quote
Advert
Old 12-13-2011, 11:43 AM   #3
richlyon
Junior Member
richlyon began at the beginning.
 
Posts: 2
Karma: 10
Join Date: Dec 2011
Device: iPad
Thanks for the help, Charles, I appreciate it.

Last edited by richlyon; 12-13-2011 at 01:04 PM.
richlyon is offline   Reply With Quote
Reply

Tags
python


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Calibre Database cp Kindle Database mitch13 Library Management 1 05-22-2011 07:33 PM
Bad database and python tobarefeet Calibre 1 03-31-2010 01:55 PM
Accessing internal and SD Storage ramjet1953 OpenInkpot 2 02-16-2010 10:51 AM
Accessing Gmail kellstr Amazon Kindle 3 09-24-2008 06:22 AM
Mobile accessing your PC while on vacation Colin Dunstan Lounge 1 08-02-2005 02:15 PM


All times are GMT -4. The time now is 02:25 AM.


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