mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
4325a82e82
@ -422,6 +422,33 @@ class MetadataField(object):
|
||||
elem = obj.create_metadata_element(self.name, is_dc=self.is_dc)
|
||||
obj.set_text(elem, self.renderer(val))
|
||||
|
||||
class TitleSortField(MetadataField):
|
||||
|
||||
def __get__(self, obj, type=None):
|
||||
c = self.__real_get__(obj, type)
|
||||
if c is None:
|
||||
matches = obj.title_path(obj.metadata)
|
||||
if matches:
|
||||
for match in matches:
|
||||
ans = match.get('{%s}file-as'%obj.NAMESPACES['opf'], None)
|
||||
if not ans:
|
||||
ans = match.get('file-as', None)
|
||||
if ans:
|
||||
c = ans
|
||||
if not c:
|
||||
c = self.none_is
|
||||
else:
|
||||
c = c.strip()
|
||||
return c
|
||||
|
||||
def __set__(self, obj, val):
|
||||
MetadataField.__set__(self, obj, val)
|
||||
matches = obj.title_path(obj.metadata)
|
||||
if matches:
|
||||
for match in matches:
|
||||
for attr in list(match.attrib):
|
||||
if attr.endswith('file-as'):
|
||||
del match.attrib[attr]
|
||||
|
||||
def serialize_user_metadata(metadata_elem, all_user_metadata, tail='\n'+(' '*8)):
|
||||
from calibre.utils.config import to_json
|
||||
@ -490,6 +517,7 @@ class OPF(object): # {{{
|
||||
rights = MetadataField('rights')
|
||||
series = MetadataField('series', is_dc=False)
|
||||
series_index = MetadataField('series_index', is_dc=False, formatter=float, none_is=1)
|
||||
title_sort = TitleSortField('title_sort', is_dc=False)
|
||||
rating = MetadataField('rating', is_dc=False, formatter=int)
|
||||
pubdate = MetadataField('date', formatter=parse_date,
|
||||
renderer=isoformat)
|
||||
@ -776,47 +804,6 @@ class OPF(object): # {{{
|
||||
|
||||
return property(fget=fget, fset=fset)
|
||||
|
||||
@dynamic_property
|
||||
def title_sort(self):
|
||||
|
||||
def fget(self):
|
||||
#first try the title_sort meta tag
|
||||
matches = self.root.xpath('//*[name() = "meta" and starts-with(@name,'
|
||||
'"calibre:title_sort") and @content]')
|
||||
if matches:
|
||||
for elem in matches:
|
||||
return self.get_text(elem)
|
||||
# fallback to file-as
|
||||
matches = self.title_path(self.metadata)
|
||||
if matches:
|
||||
for match in matches:
|
||||
ans = match.get('{%s}file-as'%self.NAMESPACES['opf'], None)
|
||||
if not ans:
|
||||
ans = match.get('file-as', None)
|
||||
if ans:
|
||||
return ans
|
||||
return None
|
||||
|
||||
def fset(self, val):
|
||||
matches = self.root.xpath('//*[name() = "meta" and starts-with(@name,'
|
||||
'"calibre:title_sort") and @content]')
|
||||
if matches:
|
||||
for elem in matches:
|
||||
elem.getparent().remove(elem)
|
||||
matches = self.title_path(self.metadata)
|
||||
if matches:
|
||||
for elem in matches:
|
||||
parent = elem.getparent()
|
||||
attrib = {}
|
||||
attrib['name'] = 'calibre:title_sort'
|
||||
attrib['content'] = val
|
||||
e = elem.makeelement('meta', attrib=attrib)
|
||||
e.tail = '\n'+(' '*8)
|
||||
parent.append(elem)
|
||||
|
||||
return property(fget=fget, fset=fset)
|
||||
|
||||
|
||||
@dynamic_property
|
||||
def tags(self):
|
||||
|
||||
@ -1146,8 +1133,6 @@ class OPFCreator(Metadata):
|
||||
metadata = M.metadata()
|
||||
a = metadata.append
|
||||
role = {}
|
||||
if self.title_sort:
|
||||
role = {'file-as':self.title_sort}
|
||||
a(DC_ELEM('title', self.title if self.title else _('Unknown'),
|
||||
opf_attrs=role))
|
||||
for i, author in enumerate(self.authors):
|
||||
@ -1182,6 +1167,8 @@ class OPFCreator(Metadata):
|
||||
a(CAL_ELEM('calibre:series', self.series))
|
||||
if self.series_index is not None:
|
||||
a(CAL_ELEM('calibre:series_index', self.format_series_index()))
|
||||
if self.title_sort:
|
||||
a(CAL_ELEM('calibre:title_sort', self.title_sort))
|
||||
if self.rating is not None:
|
||||
a(CAL_ELEM('calibre:rating', str(self.rating)))
|
||||
if self.timestamp is not None:
|
||||
@ -1337,7 +1324,6 @@ def test_m2o():
|
||||
mi.author_sort = 'author sort'
|
||||
mi.pubdate = nowf()
|
||||
mi.language = 'en'
|
||||
mi.category = 'test'
|
||||
mi.comments = 'what a fun book\n\n'
|
||||
mi.publisher = 'publisher'
|
||||
mi.isbn = 'boooo'
|
||||
@ -1352,11 +1338,11 @@ def test_m2o():
|
||||
opf = metadata_to_opf(mi)
|
||||
print opf
|
||||
newmi = MetaInformation(OPF(StringIO(opf)))
|
||||
for attr in ('author_sort', 'title_sort', 'comments', 'category',
|
||||
for attr in ('author_sort', 'title_sort', 'comments',
|
||||
'publisher', 'series', 'series_index', 'rating',
|
||||
'isbn', 'tags', 'cover_data', 'application_id',
|
||||
'language', 'cover',
|
||||
'book_producer', 'timestamp', 'lccn', 'lcc', 'ddc',
|
||||
'book_producer', 'timestamp',
|
||||
'pubdate', 'rights', 'publication_type'):
|
||||
o, n = getattr(mi, attr), getattr(newmi, attr)
|
||||
if o != n and o.strip() != n.strip():
|
||||
@ -1458,4 +1444,6 @@ def test_user_metadata():
|
||||
print opf.render()
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_user_metadata()
|
||||
#test_user_metadata()
|
||||
#test_m2o()
|
||||
test()
|
||||
|
@ -48,10 +48,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="XPathEdit" name="opt_page_breaks_before" native="true"/>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="3">
|
||||
<item row="7" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -77,6 +77,16 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>The header and footer removal options have been replaced by the Search & Replace options. Click the Search & Replace category in the bar to the left to use these options. Leave the replace field blank and enter your header/footer removal regexps into the search field.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
Loading…
x
Reference in New Issue
Block a user