1) make to_html support custom fields

2) clean up the _extra code
3) add a format_custom_field method to avoid duplicating code
4) pass custom metadata to book_details
This commit is contained in:
Charles Haley 2010-09-02 13:19:01 +01:00
parent e7d7937452
commit 0606afc8ff
4 changed files with 42 additions and 13 deletions

View File

@ -12,7 +12,8 @@ from calibre import prints
from calibre.ebooks.metadata.book import COPYABLE_METADATA_FIELDS from calibre.ebooks.metadata.book import COPYABLE_METADATA_FIELDS
from calibre.ebooks.metadata.book import STANDARD_METADATA_FIELDS from calibre.ebooks.metadata.book import STANDARD_METADATA_FIELDS
from calibre.ebooks.metadata.book import TOP_LEVEL_CLASSIFIERS from calibre.ebooks.metadata.book import TOP_LEVEL_CLASSIFIERS
from calibre.utils.date import isoformat from calibre.utils.date import isoformat, format_date
NULL_VALUES = { NULL_VALUES = {
@ -94,6 +95,13 @@ class Metadata(object):
return default return default
return self.__getattribute__(field) return self.__getattribute__(field)
def get_extra(self, field):
_data = object.__getattribute__(self, '_data')
if field in _data['user_metadata'].iterkeys():
return _data['user_metadata'][field]['#extra#']
raise AttributeError(
'Metadata object has no attribute named: '+ repr(field))
def set(self, field, val, extra=None): def set(self, field, val, extra=None):
self.__setattr__(field, val, extra) self.__setattr__(field, val, extra)
@ -131,14 +139,6 @@ class Metadata(object):
return _data[field] return _data[field]
return None return None
@classmethod
def get_user_metadata_value(user_mi):
return user_mi['#value#']
@classmethod
def get_user_metadata_extra(user_mi):
return user_mi['#extra#']
def set_all_user_metadata(self, metadata): def set_all_user_metadata(self, metadata):
''' '''
store custom field metadata into the object. Field is the key name store custom field metadata into the object. Field is the key name
@ -284,6 +284,25 @@ class Metadata(object):
def format_rating(self): def format_rating(self):
return unicode(self.rating) return unicode(self.rating)
def format_custom_field(self, key):
'''
returns the tuple (field_name, formatted_value)
'''
cmeta = self.get_user_metadata(key, make_copy=False)
name = unicode(cmeta['name'])
res = self.get(key, None)
if res is not None:
datatype = cmeta['datatype']
if datatype == 'text' and cmeta['is_multiple']:
res = u', '.join(res)
elif datatype == 'series':
res = res + ' [%s]'%self.format_series_index(self.get_extra(key))
elif datatype == 'datetime':
res = format_date(res, cmeta['display'].get('date_format','dd MMM yyyy'))
elif datatype == 'bool':
res = _('Yes') if res else _('No')
return (name, unicode(res))
def __unicode__(self): def __unicode__(self):
from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata import authors_to_string
ans = [] ans = []
@ -339,9 +358,13 @@ class Metadata(object):
ans += [(_('Published'), unicode(self.pubdate.isoformat(' ')))] ans += [(_('Published'), unicode(self.pubdate.isoformat(' ')))]
if self.rights is not None: if self.rights is not None:
ans += [(_('Rights'), unicode(self.rights))] ans += [(_('Rights'), unicode(self.rights))]
for key in self.user_metadata_keys:
val = self.get(key, None)
if val is not None:
(name, val) = self.format_custom_field(key)
ans += [(name, val)]
for i, x in enumerate(ans): for i, x in enumerate(ans):
ans[i] = u'<tr><td><b>%s</b></td><td>%s</td></tr>'%x ans[i] = u'<tr><td><b>%s</b></td><td>%s</td></tr>'%x
# TODO: NEWMETA: What to do about custom fields
return u'<table>%s</table>'%u'\n'.join(ans) return u'<table>%s</table>'%u'\n'.join(ans)
def __str__(self): def __str__(self):

View File

@ -28,6 +28,8 @@ WEIGHTS[_('Tags')] = 4
def render_rows(data): def render_rows(data):
keys = data.keys() keys = data.keys()
# First sort by name. The WEIGHTS sort will preserve this sub-order
keys.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))
keys.sort(cmp=lambda x, y: cmp(WEIGHTS[x], WEIGHTS[y])) keys.sort(cmp=lambda x, y: cmp(WEIGHTS[x], WEIGHTS[y]))
rows = [] rows = []
for key in keys: for key in keys:

View File

@ -323,7 +323,11 @@ class BooksModel(QAbstractTableModel): # {{{
data[_('Series')] = \ data[_('Series')] = \
_('Book <font face="serif">%s</font> of %s.')%\ _('Book <font face="serif">%s</font> of %s.')%\
(sidx, prepare_string_for_xml(series)) (sidx, prepare_string_for_xml(series))
mi = self.db.get_metadata(idx)
for key in mi.user_metadata_keys:
name, val = mi.format_custom_field(key)
if val is not None:
data[name] = val
return data return data
def set_cache(self, idx): def set_cache(self, idx):

View File

@ -1052,8 +1052,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if key in self.field_metadata and \ if key in self.field_metadata and \
user_mi[key]['datatype'] == self.field_metadata[key]['datatype']: user_mi[key]['datatype'] == self.field_metadata[key]['datatype']:
doit(self.set_custom, id, doit(self.set_custom, id,
val=Metadata.get_user_metadata_value(user_mi[key]), val=mi.get(key),
extra=Metadata.get_user_metadata_extra(user_mi[key]), extra=mi.get_extra(key),
label=user_mi[key]['label']) label=user_mi[key]['label'])
self.notify('metadata', [id]) self.notify('metadata', [id])