View Single Post
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