mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
py3: more work toward universal _future__s
This commit is contained in:
parent
8078bf0931
commit
975b9ac168
@ -1,6 +1,8 @@
|
|||||||
from __future__ import print_function
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
''' Code to manage ebook library'''
|
''' Code to manage ebook library'''
|
||||||
|
|
||||||
|
|
||||||
@ -64,7 +66,7 @@ def generate_test_db(library_path, # {{{
|
|||||||
|
|
||||||
t = time.time() - start
|
t = time.time() - start
|
||||||
print('\nGenerated', num_of_records, 'records in:', t, 'seconds')
|
print('\nGenerated', num_of_records, 'records in:', t, 'seconds')
|
||||||
print('Time per record:', t/float(num_of_records))
|
print('Time per record:', t/num_of_records)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
from __future__ import with_statement
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
@ -466,7 +466,7 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
cast = lambda x: int(x)
|
cast = lambda x: int(x)
|
||||||
elif dt == 'rating':
|
elif dt == 'rating':
|
||||||
cast = lambda x: 0 if x is None else int(x)
|
cast = lambda x: 0 if x is None else int(x)
|
||||||
adjust = lambda x: x/2
|
adjust = lambda x: x//2
|
||||||
elif dt in ('float', 'composite'):
|
elif dt in ('float', 'composite'):
|
||||||
cast = lambda x : float(x)
|
cast = lambda x : float(x)
|
||||||
else: # count operation
|
else: # count operation
|
||||||
@ -851,7 +851,7 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
def _build_restriction_string(self, restriction):
|
def _build_restriction_string(self, restriction):
|
||||||
if self.base_restriction:
|
if self.base_restriction:
|
||||||
if restriction:
|
if restriction:
|
||||||
return u'(%s) and (%s)' % (self.base_restriction, restriction)
|
return '(%s) and (%s)' % (self.base_restriction, restriction)
|
||||||
else:
|
else:
|
||||||
return self.base_restriction
|
return self.base_restriction
|
||||||
else:
|
else:
|
||||||
@ -867,7 +867,7 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
else:
|
else:
|
||||||
q = query
|
q = query
|
||||||
if search_restriction:
|
if search_restriction:
|
||||||
q = u'(%s) and (%s)' % (search_restriction, query)
|
q = '(%s) and (%s)' % (search_restriction, query)
|
||||||
if not q:
|
if not q:
|
||||||
if set_restriction_count:
|
if set_restriction_count:
|
||||||
self.search_restriction_book_count = len(self._map)
|
self.search_restriction_book_count = len(self._map)
|
||||||
@ -924,7 +924,7 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
'''
|
'''
|
||||||
if not hasattr(id_dict, 'items'):
|
if not hasattr(id_dict, 'items'):
|
||||||
# Simple list. Make it a dict of string 'true'
|
# Simple list. Make it a dict of string 'true'
|
||||||
self.marked_ids_dict = dict.fromkeys(id_dict, u'true')
|
self.marked_ids_dict = dict.fromkeys(id_dict, 'true')
|
||||||
else:
|
else:
|
||||||
# Ensure that all the items in the dict are text
|
# Ensure that all the items in the dict are text
|
||||||
self.marked_ids_dict = dict(zip(iter(id_dict), map(unicode_type,
|
self.marked_ids_dict = dict(zip(iter(id_dict), map(unicode_type,
|
||||||
@ -1214,7 +1214,7 @@ class SortKeyGenerator(object):
|
|||||||
else:
|
else:
|
||||||
if self.library_order:
|
if self.library_order:
|
||||||
try:
|
try:
|
||||||
lang = record[self.lang_idx].partition(u',')[0]
|
lang = record[self.lang_idx].partition(',')[0]
|
||||||
except (AttributeError, ValueError, KeyError,
|
except (AttributeError, ValueError, KeyError,
|
||||||
IndexError, TypeError):
|
IndexError, TypeError):
|
||||||
lang = None
|
lang = None
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
@ -14,7 +15,7 @@ from calibre.library.catalogs import FIELDS, TEMPLATE_ALLOWED_FIELDS
|
|||||||
from calibre.customize.conversion import DummyReporter
|
from calibre.customize.conversion import DummyReporter
|
||||||
from calibre.constants import preferred_encoding
|
from calibre.constants import preferred_encoding
|
||||||
from calibre.ebooks.metadata import format_isbn
|
from calibre.ebooks.metadata import format_isbn
|
||||||
from polyglot.builtins import string_or_bytes, filter
|
from polyglot.builtins import filter, string_or_bytes, unicode_type
|
||||||
|
|
||||||
|
|
||||||
class BIBTEX(CatalogPlugin):
|
class BIBTEX(CatalogPlugin):
|
||||||
@ -126,9 +127,9 @@ class BIBTEX(CatalogPlugin):
|
|||||||
|
|
||||||
bibtex_entry = []
|
bibtex_entry = []
|
||||||
if mode != "misc" and check_entry_book_valid(entry) :
|
if mode != "misc" and check_entry_book_valid(entry) :
|
||||||
bibtex_entry.append(u'@book{')
|
bibtex_entry.append('@book{')
|
||||||
elif mode != "book" :
|
elif mode != "book" :
|
||||||
bibtex_entry.append(u'@misc{')
|
bibtex_entry.append('@misc{')
|
||||||
else :
|
else :
|
||||||
# case strict book
|
# case strict book
|
||||||
return ''
|
return ''
|
||||||
@ -137,7 +138,7 @@ class BIBTEX(CatalogPlugin):
|
|||||||
# Citation tag
|
# Citation tag
|
||||||
bibtex_entry.append(make_bibtex_citation(entry, template_citation,
|
bibtex_entry.append(make_bibtex_citation(entry, template_citation,
|
||||||
bibtexdict))
|
bibtexdict))
|
||||||
bibtex_entry = [u' '.join(bibtex_entry)]
|
bibtex_entry = [' '.join(bibtex_entry)]
|
||||||
|
|
||||||
for field in fields:
|
for field in fields:
|
||||||
if field.startswith('#'):
|
if field.startswith('#'):
|
||||||
@ -161,68 +162,68 @@ class BIBTEX(CatalogPlugin):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if field == 'authors' :
|
if field == 'authors' :
|
||||||
bibtex_entry.append(u'author = "%s"' % bibtexdict.bibtex_author_format(item))
|
bibtex_entry.append('author = "%s"' % bibtexdict.bibtex_author_format(item))
|
||||||
|
|
||||||
elif field == 'id' :
|
elif field == 'id' :
|
||||||
bibtex_entry.append(u'calibreid = "%s"' % int(item))
|
bibtex_entry.append('calibreid = "%s"' % int(item))
|
||||||
|
|
||||||
elif field == 'rating' :
|
elif field == 'rating' :
|
||||||
bibtex_entry.append(u'rating = "%s"' % int(item))
|
bibtex_entry.append('rating = "%s"' % int(item))
|
||||||
|
|
||||||
elif field == 'size' :
|
elif field == 'size' :
|
||||||
bibtex_entry.append(u'%s = "%s octets"' % (field, int(item)))
|
bibtex_entry.append('%s = "%s octets"' % (field, int(item)))
|
||||||
|
|
||||||
elif field == 'tags' :
|
elif field == 'tags' :
|
||||||
# A list to flatten
|
# A list to flatten
|
||||||
bibtex_entry.append(u'tags = "%s"' % bibtexdict.utf8ToBibtex(u', '.join(item)))
|
bibtex_entry.append('tags = "%s"' % bibtexdict.utf8ToBibtex(', '.join(item)))
|
||||||
|
|
||||||
elif field == 'comments' :
|
elif field == 'comments' :
|
||||||
# \n removal
|
# \n removal
|
||||||
item = item.replace(u'\r\n',u' ')
|
item = item.replace('\r\n', ' ')
|
||||||
item = item.replace(u'\n',u' ')
|
item = item.replace('\n', ' ')
|
||||||
# unmatched brace removal (users should use \leftbrace or \rightbrace for single braces)
|
# unmatched brace removal (users should use \leftbrace or \rightbrace for single braces)
|
||||||
item = bibtexdict.stripUnmatchedSyntax(item, u'{', u'}')
|
item = bibtexdict.stripUnmatchedSyntax(item, '{', '}')
|
||||||
# html to text
|
# html to text
|
||||||
try:
|
try:
|
||||||
item = html2text(item)
|
item = html2text(item)
|
||||||
except:
|
except:
|
||||||
log.warn("Failed to convert comments to text")
|
log.warn("Failed to convert comments to text")
|
||||||
bibtex_entry.append(u'note = "%s"' % bibtexdict.utf8ToBibtex(item))
|
bibtex_entry.append('note = "%s"' % bibtexdict.utf8ToBibtex(item))
|
||||||
|
|
||||||
elif field == 'isbn' :
|
elif field == 'isbn' :
|
||||||
# Could be 9, 10 or 13 digits
|
# Could be 9, 10 or 13 digits
|
||||||
bibtex_entry.append(u'isbn = "%s"' % format_isbn(item))
|
bibtex_entry.append('isbn = "%s"' % format_isbn(item))
|
||||||
|
|
||||||
elif field == 'formats' :
|
elif field == 'formats' :
|
||||||
# Add file path if format is selected
|
# Add file path if format is selected
|
||||||
formats = [format.rpartition('.')[2].lower() for format in item]
|
formats = [format.rpartition('.')[2].lower() for format in item]
|
||||||
bibtex_entry.append(u'formats = "%s"' % u', '.join(formats))
|
bibtex_entry.append('formats = "%s"' % ', '.join(formats))
|
||||||
if calibre_files:
|
if calibre_files:
|
||||||
files = [u':%s:%s' % (format, format.rpartition('.')[2].upper())
|
files = [':%s:%s' % (format, format.rpartition('.')[2].upper())
|
||||||
for format in item]
|
for format in item]
|
||||||
bibtex_entry.append(u'file = "%s"' % u', '.join(files))
|
bibtex_entry.append('file = "%s"' % ', '.join(files))
|
||||||
|
|
||||||
elif field == 'series_index' :
|
elif field == 'series_index' :
|
||||||
bibtex_entry.append(u'volume = "%s"' % int(item))
|
bibtex_entry.append('volume = "%s"' % int(item))
|
||||||
|
|
||||||
elif field == 'timestamp' :
|
elif field == 'timestamp' :
|
||||||
bibtex_entry.append(u'timestamp = "%s"' % isoformat(item).partition('T')[0])
|
bibtex_entry.append('timestamp = "%s"' % isoformat(item).partition('T')[0])
|
||||||
|
|
||||||
elif field == 'pubdate' :
|
elif field == 'pubdate' :
|
||||||
bibtex_entry.append(u'year = "%s"' % item.year)
|
bibtex_entry.append('year = "%s"' % item.year)
|
||||||
bibtex_entry.append(u'month = "%s"' % bibtexdict.utf8ToBibtex(strftime("%b", item)))
|
bibtex_entry.append('month = "%s"' % bibtexdict.utf8ToBibtex(strftime("%b", item)))
|
||||||
|
|
||||||
elif field.startswith('#') and isinstance(item, string_or_bytes):
|
elif field.startswith('#') and isinstance(item, string_or_bytes):
|
||||||
bibtex_entry.append(u'custom_%s = "%s"' % (field[1:],
|
bibtex_entry.append('custom_%s = "%s"' % (field[1:],
|
||||||
bibtexdict.utf8ToBibtex(item)))
|
bibtexdict.utf8ToBibtex(item)))
|
||||||
|
|
||||||
elif isinstance(item, string_or_bytes):
|
elif isinstance(item, string_or_bytes):
|
||||||
# elif field in ['title', 'publisher', 'cover', 'uuid', 'ondevice',
|
# elif field in ['title', 'publisher', 'cover', 'uuid', 'ondevice',
|
||||||
# 'author_sort', 'series', 'title_sort'] :
|
# 'author_sort', 'series', 'title_sort'] :
|
||||||
bibtex_entry.append(u'%s = "%s"' % (field, bibtexdict.utf8ToBibtex(item)))
|
bibtex_entry.append('%s = "%s"' % (field, bibtexdict.utf8ToBibtex(item)))
|
||||||
|
|
||||||
bibtex_entry = u',\n '.join(bibtex_entry)
|
bibtex_entry = ',\n '.join(bibtex_entry)
|
||||||
bibtex_entry += u' }\n\n'
|
bibtex_entry += ' }\n\n'
|
||||||
|
|
||||||
return bibtex_entry
|
return bibtex_entry
|
||||||
|
|
||||||
@ -241,7 +242,7 @@ class BIBTEX(CatalogPlugin):
|
|||||||
# define a function to replace the template entry by its value
|
# define a function to replace the template entry by its value
|
||||||
def tpl_replace(objtplname) :
|
def tpl_replace(objtplname) :
|
||||||
|
|
||||||
tpl_field = re.sub(u'[\\{\\}]', u'', objtplname.group())
|
tpl_field = re.sub('[\\{\\}]', '', objtplname.group())
|
||||||
|
|
||||||
if tpl_field in TEMPLATE_ALLOWED_FIELDS :
|
if tpl_field in TEMPLATE_ALLOWED_FIELDS :
|
||||||
if tpl_field in ['pubdate', 'timestamp'] :
|
if tpl_field in ['pubdate', 'timestamp'] :
|
||||||
@ -249,26 +250,26 @@ class BIBTEX(CatalogPlugin):
|
|||||||
elif tpl_field in ['tags', 'authors'] :
|
elif tpl_field in ['tags', 'authors'] :
|
||||||
tpl_field =entry[tpl_field][0]
|
tpl_field =entry[tpl_field][0]
|
||||||
elif tpl_field in ['id', 'series_index'] :
|
elif tpl_field in ['id', 'series_index'] :
|
||||||
tpl_field = str(entry[tpl_field])
|
tpl_field = unicode_type(entry[tpl_field])
|
||||||
else :
|
else :
|
||||||
tpl_field = entry[tpl_field]
|
tpl_field = entry[tpl_field]
|
||||||
return ascii_text(tpl_field)
|
return ascii_text(tpl_field)
|
||||||
else:
|
else:
|
||||||
return u''
|
return ''
|
||||||
|
|
||||||
if len(template_citation) >0 :
|
if len(template_citation) >0 :
|
||||||
tpl_citation = bibtexclass.utf8ToBibtex(
|
tpl_citation = bibtexclass.utf8ToBibtex(
|
||||||
bibtexclass.ValidateCitationKey(re.sub(u'\\{[^{}]*\\}',
|
bibtexclass.ValidateCitationKey(re.sub('\\{[^{}]*\\}',
|
||||||
tpl_replace, template_citation)))
|
tpl_replace, template_citation)))
|
||||||
|
|
||||||
if len(tpl_citation) >0 :
|
if len(tpl_citation) >0 :
|
||||||
return tpl_citation
|
return tpl_citation
|
||||||
|
|
||||||
if len(entry["isbn"]) > 0 :
|
if len(entry["isbn"]) > 0 :
|
||||||
template_citation = u'%s' % re.sub(u'[\\D]',u'', entry["isbn"])
|
template_citation = '%s' % re.sub('[\\D]','', entry["isbn"])
|
||||||
|
|
||||||
else :
|
else :
|
||||||
template_citation = u'%s' % str(entry["id"])
|
template_citation = '%s' % unicode_type(entry["id"])
|
||||||
|
|
||||||
return bibtexclass.ValidateCitationKey(template_citation)
|
return bibtexclass.ValidateCitationKey(template_citation)
|
||||||
|
|
||||||
@ -394,8 +395,8 @@ class BIBTEX(CatalogPlugin):
|
|||||||
for entry in data:
|
for entry in data:
|
||||||
entry['ondevice'] = db.catalog_plugin_on_device_temp_mapping[entry['id']]['ondevice']
|
entry['ondevice'] = db.catalog_plugin_on_device_temp_mapping[entry['id']]['ondevice']
|
||||||
|
|
||||||
outfile.write(u'%%%Calibre catalog\n%%%{0} entries in catalog\n\n'.format(nb_entries))
|
outfile.write('%%%Calibre catalog\n%%%{0} entries in catalog\n\n'.format(nb_entries))
|
||||||
outfile.write(u'@preamble{"This catalog of %d entries was generated by calibre on %s"}\n\n'
|
outfile.write('@preamble{"This catalog of %d entries was generated by calibre on %s"}\n\n'
|
||||||
% (nb_entries, nowf().strftime("%A, %d. %B %Y %H:%M").decode(preferred_encoding)))
|
% (nb_entries, nowf().strftime("%A, %d. %B %Y %H:%M").decode(preferred_encoding)))
|
||||||
|
|
||||||
for entry in data:
|
for entry in data:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
@ -107,10 +108,10 @@ class CSV_XML(CatalogPlugin):
|
|||||||
outfile = codecs.open(path_to_output, 'w', 'utf8')
|
outfile = codecs.open(path_to_output, 'w', 'utf8')
|
||||||
|
|
||||||
# Write a UTF-8 BOM
|
# Write a UTF-8 BOM
|
||||||
outfile.write(u'\ufeff')
|
outfile.write('\ufeff')
|
||||||
|
|
||||||
# Output the field headers
|
# Output the field headers
|
||||||
outfile.write(u'%s\n' % u','.join(fields))
|
outfile.write('%s\n' % ','.join(fields))
|
||||||
|
|
||||||
# Output the entry fields
|
# Output the entry fields
|
||||||
for entry in data:
|
for entry in data:
|
||||||
@ -144,14 +145,14 @@ class CSV_XML(CatalogPlugin):
|
|||||||
item = ', '.join(item)
|
item = ', '.join(item)
|
||||||
elif field == 'isbn':
|
elif field == 'isbn':
|
||||||
# Could be 9, 10 or 13 digits, with hyphens, possibly ending in 'X'
|
# Could be 9, 10 or 13 digits, with hyphens, possibly ending in 'X'
|
||||||
item = u'%s' % re.sub(r'[^\dX-]', '', item)
|
item = '%s' % re.sub(r'[^\dX-]', '', item)
|
||||||
elif fm.get(field, {}).get('datatype') == 'datetime':
|
elif fm.get(field, {}).get('datatype') == 'datetime':
|
||||||
item = isoformat(item, as_utc=False)
|
item = isoformat(item, as_utc=False)
|
||||||
elif field == 'comments':
|
elif field == 'comments':
|
||||||
item = item.replace(u'\r\n', u' ')
|
item = item.replace('\r\n', ' ')
|
||||||
item = item.replace(u'\n', u' ')
|
item = item.replace('\n', ' ')
|
||||||
elif fm.get(field, {}).get('datatype', None) == 'rating' and item:
|
elif fm.get(field, {}).get('datatype', None) == 'rating' and item:
|
||||||
item = u'%.2g' % (item / 2.0)
|
item = '%.2g' % (item / 2)
|
||||||
|
|
||||||
# Convert HTML to markdown text
|
# Convert HTML to markdown text
|
||||||
if isinstance(item, unicode_type):
|
if isinstance(item, unicode_type):
|
||||||
@ -161,9 +162,9 @@ class CSV_XML(CatalogPlugin):
|
|||||||
if closing_tag:
|
if closing_tag:
|
||||||
item = html2text(item)
|
item = html2text(item)
|
||||||
|
|
||||||
outstr.append(u'"%s"' % unicode_type(item).replace('"', '""'))
|
outstr.append('"%s"' % unicode_type(item).replace('"', '""'))
|
||||||
|
|
||||||
outfile.write(u','.join(outstr) + u'\n')
|
outfile.write(','.join(outstr) + '\n')
|
||||||
outfile.close()
|
outfile.close()
|
||||||
|
|
||||||
elif self.fmt == 'xml':
|
elif self.fmt == 'xml':
|
||||||
@ -191,7 +192,7 @@ class CSV_XML(CatalogPlugin):
|
|||||||
if not isinstance(val, (bytes, unicode_type)):
|
if not isinstance(val, (bytes, unicode_type)):
|
||||||
if (fm.get(field, {}).get('datatype', None) ==
|
if (fm.get(field, {}).get('datatype', None) ==
|
||||||
'rating' and val):
|
'rating' and val):
|
||||||
val = u'%.2g' % (val / 2.0)
|
val = '%.2g' % (val / 2)
|
||||||
val = unicode_type(val)
|
val = unicode_type(val)
|
||||||
item = getattr(E, field)(val)
|
item = getattr(E, field)(val)
|
||||||
record.append(item)
|
record.append(item)
|
||||||
@ -221,7 +222,7 @@ class CSV_XML(CatalogPlugin):
|
|||||||
|
|
||||||
if 'series' in fields and r['series']:
|
if 'series' in fields and r['series']:
|
||||||
record.append(E.series(r['series'],
|
record.append(E.series(r['series'],
|
||||||
index=str(r['series_index'])))
|
index=unicode_type(r['series_index'])))
|
||||||
|
|
||||||
if 'cover' in fields and r['cover']:
|
if 'cover' in fields and r['cover']:
|
||||||
record.append(E.cover(r['cover'].replace(os.sep, '/')))
|
record.append(E.cover(r['cover'].replace(os.sep, '/')))
|
||||||
|
@ -16,6 +16,7 @@ from calibre.library import current_library_name
|
|||||||
from calibre.library.catalogs import AuthorSortMismatchException, EmptyCatalogException
|
from calibre.library.catalogs import AuthorSortMismatchException, EmptyCatalogException
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.utils.localization import calibre_langcode_to_name, canonicalize_lang, get_lang
|
from calibre.utils.localization import calibre_langcode_to_name, canonicalize_lang, get_lang
|
||||||
|
from polyglot.builtins import unicode_type
|
||||||
|
|
||||||
Option = namedtuple('Option', 'option, default, dest, action, help')
|
Option = namedtuple('Option', 'option, default, dest, action, help')
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
"Default: '%default'\n"
|
"Default: '%default'\n"
|
||||||
"Applies to: AZW3, EPUB, MOBI output formats")),
|
"Applies to: AZW3, EPUB, MOBI output formats")),
|
||||||
Option('--exclude-genre',
|
Option('--exclude-genre',
|
||||||
default='\\[.+\\]|^\\+$',
|
default=r'\[.+\]|^\+$',
|
||||||
dest='exclude_genre',
|
dest='exclude_genre',
|
||||||
action=None,
|
action=None,
|
||||||
help=_("Regex describing tags to exclude as genres.\n"
|
help=_("Regex describing tags to exclude as genres.\n"
|
||||||
@ -264,7 +265,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
|
|
||||||
build_log = []
|
build_log = []
|
||||||
|
|
||||||
build_log.append(u"%s('%s'): Generating %s %sin %s environment, locale: '%s'" %
|
build_log.append("%s('%s'): Generating %s %sin %s environment, locale: '%s'" %
|
||||||
(self.name,
|
(self.name,
|
||||||
current_library_name(),
|
current_library_name(),
|
||||||
self.fmt,
|
self.fmt,
|
||||||
@ -282,23 +283,23 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
if opts.connected_device['is_device_connected'] and \
|
if opts.connected_device['is_device_connected'] and \
|
||||||
opts.connected_device['kind'] == 'device':
|
opts.connected_device['kind'] == 'device':
|
||||||
if opts.connected_device['serial']:
|
if opts.connected_device['serial']:
|
||||||
build_log.append(u" connected_device: '%s' #%s%s " %
|
build_log.append(" connected_device: '%s' #%s%s " %
|
||||||
(opts.connected_device['name'],
|
(opts.connected_device['name'],
|
||||||
opts.connected_device['serial'][0:4],
|
opts.connected_device['serial'][0:4],
|
||||||
'x' * (len(opts.connected_device['serial']) - 4)))
|
'x' * (len(opts.connected_device['serial']) - 4)))
|
||||||
for storage in opts.connected_device['storage']:
|
for storage in opts.connected_device['storage']:
|
||||||
if storage:
|
if storage:
|
||||||
build_log.append(u" mount point: %s" % storage)
|
build_log.append(" mount point: %s" % storage)
|
||||||
else:
|
else:
|
||||||
build_log.append(u" connected_device: '%s'" % opts.connected_device['name'])
|
build_log.append(" connected_device: '%s'" % opts.connected_device['name'])
|
||||||
try:
|
try:
|
||||||
for storage in opts.connected_device['storage']:
|
for storage in opts.connected_device['storage']:
|
||||||
if storage:
|
if storage:
|
||||||
build_log.append(u" mount point: %s" % storage)
|
build_log.append(" mount point: %s" % storage)
|
||||||
except:
|
except:
|
||||||
build_log.append(u" (no mount points)")
|
build_log.append(" (no mount points)")
|
||||||
else:
|
else:
|
||||||
build_log.append(u" connected_device: '%s'" % opts.connected_device['name'])
|
build_log.append(" connected_device: '%s'" % opts.connected_device['name'])
|
||||||
|
|
||||||
opts_dict = vars(opts)
|
opts_dict = vars(opts)
|
||||||
if opts_dict['ids']:
|
if opts_dict['ids']:
|
||||||
@ -337,7 +338,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
sections_list.insert(0, 'Authors')
|
sections_list.insert(0, 'Authors')
|
||||||
opts.generate_authors = True
|
opts.generate_authors = True
|
||||||
|
|
||||||
opts.log(u" Sections: %s" % ', '.join(sections_list))
|
opts.log(" Sections: %s" % ', '.join(sections_list))
|
||||||
opts.section_list = sections_list
|
opts.section_list = sections_list
|
||||||
|
|
||||||
# Limit thumb_width to 1.0" - 2.0"
|
# Limit thumb_width to 1.0" - 2.0"
|
||||||
@ -397,7 +398,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
|
|
||||||
if opts.verbose:
|
if opts.verbose:
|
||||||
log.info(" Begin catalog source generation (%s)" %
|
log.info(" Begin catalog source generation (%s)" %
|
||||||
str(datetime.timedelta(seconds=int(time.time() - opts.start_time))))
|
unicode_type(datetime.timedelta(seconds=int(time.time() - opts.start_time))))
|
||||||
|
|
||||||
# Launch the Catalog builder
|
# Launch the Catalog builder
|
||||||
catalog = CatalogBuilder(db, opts, self, report_progress=notification)
|
catalog = CatalogBuilder(db, opts, self, report_progress=notification)
|
||||||
@ -406,7 +407,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
catalog.build_sources()
|
catalog.build_sources()
|
||||||
if opts.verbose:
|
if opts.verbose:
|
||||||
log.info(" Completed catalog source generation (%s)\n" %
|
log.info(" Completed catalog source generation (%s)\n" %
|
||||||
str(datetime.timedelta(seconds=int(time.time() - opts.start_time))))
|
unicode_type(datetime.timedelta(seconds=int(time.time() - opts.start_time))))
|
||||||
except (AuthorSortMismatchException, EmptyCatalogException) as e:
|
except (AuthorSortMismatchException, EmptyCatalogException) as e:
|
||||||
log.error(" *** Terminated catalog generation: %s ***" % e)
|
log.error(" *** Terminated catalog generation: %s ***" % e)
|
||||||
except:
|
except:
|
||||||
@ -499,7 +500,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
|
|
||||||
if opts.verbose:
|
if opts.verbose:
|
||||||
log.info(" Catalog creation complete (%s)\n" %
|
log.info(" Catalog creation complete (%s)\n" %
|
||||||
str(datetime.timedelta(seconds=int(time.time() - opts.start_time))))
|
unicode_type(datetime.timedelta(seconds=int(time.time() - opts.start_time))))
|
||||||
|
|
||||||
# returns to gui2.actions.catalog:catalog_generated()
|
# returns to gui2.actions.catalog:catalog_generated()
|
||||||
return catalog.error
|
return catalog.error
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPLv3 Copyright: 2010, Greg Riker
|
# License: GPLv3 Copyright: 2010, Greg Riker
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
@ -44,7 +43,7 @@ from calibre.utils.localization import get_lang, lang_as_iso639_1
|
|||||||
from calibre.utils.zipfile import ZipFile
|
from calibre.utils.zipfile import ZipFile
|
||||||
from polyglot.builtins import unicode_type, iteritems, map, zip
|
from polyglot.builtins import unicode_type, iteritems, map, zip
|
||||||
|
|
||||||
NBSP = u'\u00a0'
|
NBSP = '\u00a0'
|
||||||
|
|
||||||
|
|
||||||
class Formatter(TemplateFormatter):
|
class Formatter(TemplateFormatter):
|
||||||
@ -241,7 +240,7 @@ class CatalogBuilder(object):
|
|||||||
index = book['series_index']
|
index = book['series_index']
|
||||||
integer = int(index)
|
integer = int(index)
|
||||||
fraction = index - integer
|
fraction = index - integer
|
||||||
series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0'))
|
series_index = '%04d%s' % (integer, unicode_type('%0.4f' % fraction).lstrip('0'))
|
||||||
key = '%s ~%s %s' % (self._kf_author_to_author_sort(book['author']),
|
key = '%s ~%s %s' % (self._kf_author_to_author_sort(book['author']),
|
||||||
self.generate_sort_title(book['series']),
|
self.generate_sort_title(book['series']),
|
||||||
series_index)
|
series_index)
|
||||||
@ -260,15 +259,15 @@ class CatalogBuilder(object):
|
|||||||
(str): sort key
|
(str): sort key
|
||||||
"""
|
"""
|
||||||
if not book['series']:
|
if not book['series']:
|
||||||
fs = u'{:<%d}!{!s}' % longest_author_sort
|
fs = '{:<%d}!{!s}' % longest_author_sort
|
||||||
key = fs.format(capitalize(book['author_sort']),
|
key = fs.format(capitalize(book['author_sort']),
|
||||||
capitalize(book['title_sort']))
|
capitalize(book['title_sort']))
|
||||||
else:
|
else:
|
||||||
index = book['series_index']
|
index = book['series_index']
|
||||||
integer = int(index)
|
integer = int(index)
|
||||||
fraction = index - integer
|
fraction = index - integer
|
||||||
series_index = u'%04d%s' % (integer, str(u'%0.4f' % fraction).lstrip(u'0'))
|
series_index = '%04d%s' % (integer, unicode_type('%0.4f' % fraction).lstrip('0'))
|
||||||
fs = u'{:<%d}~{!s}{!s}' % longest_author_sort
|
fs = '{:<%d}~{!s}{!s}' % longest_author_sort
|
||||||
key = fs.format(capitalize(book['author_sort']),
|
key = fs.format(capitalize(book['author_sort']),
|
||||||
self.generate_sort_title(book['series']),
|
self.generate_sort_title(book['series']),
|
||||||
series_index)
|
series_index)
|
||||||
@ -278,7 +277,7 @@ class CatalogBuilder(object):
|
|||||||
index = book['series_index']
|
index = book['series_index']
|
||||||
integer = int(index)
|
integer = int(index)
|
||||||
fraction = index - integer
|
fraction = index - integer
|
||||||
series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0'))
|
series_index = '%04d%s' % (integer, unicode_type('%0.4f' % fraction).lstrip('0'))
|
||||||
key = '%s %s' % (self.generate_sort_title(book['series']),
|
key = '%s %s' % (self.generate_sort_title(book['series']),
|
||||||
series_index)
|
series_index)
|
||||||
return key
|
return key
|
||||||
@ -677,9 +676,9 @@ class CatalogBuilder(object):
|
|||||||
# Hack to force the cataloged leading letter to be
|
# Hack to force the cataloged leading letter to be
|
||||||
# an unadorned character if the accented version sorts before the unaccented
|
# an unadorned character if the accented version sorts before the unaccented
|
||||||
exceptions = {
|
exceptions = {
|
||||||
u'Ä': u'A',
|
'Ä': 'A',
|
||||||
u'Ö': u'O',
|
'Ö': 'O',
|
||||||
u'Ü': u'U'
|
'Ü': 'U'
|
||||||
}
|
}
|
||||||
|
|
||||||
if key is not None:
|
if key is not None:
|
||||||
@ -699,7 +698,7 @@ class CatalogBuilder(object):
|
|||||||
# Hackhackhackhackhack
|
# Hackhackhackhackhack
|
||||||
# icu returns bogus results with curly apostrophes, maybe others under OS X 10.6.x
|
# icu returns bogus results with curly apostrophes, maybe others under OS X 10.6.x
|
||||||
# When we see the magic combo of 0/-1 for ordnum/ordlen, special case the logic
|
# When we see the magic combo of 0/-1 for ordnum/ordlen, special case the logic
|
||||||
last_c = u''
|
last_c = ''
|
||||||
if ordnum == 0 and ordlen == -1:
|
if ordnum == 0 and ordlen == -1:
|
||||||
if icu_upper(c[0]) != last_c:
|
if icu_upper(c[0]) != last_c:
|
||||||
last_c = icu_upper(c[0])
|
last_c = icu_upper(c[0])
|
||||||
@ -955,7 +954,7 @@ class CatalogBuilder(object):
|
|||||||
if is_date_undefined(record['pubdate']):
|
if is_date_undefined(record['pubdate']):
|
||||||
this_title['date'] = None
|
this_title['date'] = None
|
||||||
else:
|
else:
|
||||||
this_title['date'] = strftime(u'%B %Y', as_local_time(record['pubdate']).timetuple())
|
this_title['date'] = strftime('%B %Y', as_local_time(record['pubdate']).timetuple())
|
||||||
|
|
||||||
this_title['timestamp'] = record['timestamp']
|
this_title['timestamp'] = record['timestamp']
|
||||||
|
|
||||||
@ -1091,11 +1090,11 @@ class CatalogBuilder(object):
|
|||||||
from calibre.devices.kindle.bookmark import Bookmark
|
from calibre.devices.kindle.bookmark import Bookmark
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
|
|
||||||
MBP_FORMATS = [u'azw', u'mobi', u'prc', u'txt']
|
MBP_FORMATS = ['azw', 'mobi', 'prc', 'txt']
|
||||||
mbp_formats = set(MBP_FORMATS)
|
mbp_formats = set(MBP_FORMATS)
|
||||||
PDR_FORMATS = [u'pdf']
|
PDR_FORMATS = ['pdf']
|
||||||
pdr_formats = set(PDR_FORMATS)
|
pdr_formats = set(PDR_FORMATS)
|
||||||
TAN_FORMATS = [u'tpz', u'azw1']
|
TAN_FORMATS = ['tpz', 'azw1']
|
||||||
tan_formats = set(TAN_FORMATS)
|
tan_formats = set(TAN_FORMATS)
|
||||||
|
|
||||||
class BookmarkDevice(Device):
|
class BookmarkDevice(Device):
|
||||||
@ -1174,7 +1173,7 @@ class CatalogBuilder(object):
|
|||||||
book['percent_read'] = min(float(100 * myBookmark.last_read / myBookmark.book_length), 100)
|
book['percent_read'] = min(float(100 * myBookmark.last_read / myBookmark.book_length), 100)
|
||||||
except:
|
except:
|
||||||
book['percent_read'] = 0
|
book['percent_read'] = 0
|
||||||
dots = int((book['percent_read'] + 5) / 10)
|
dots = int((book['percent_read'] + 5) // 10)
|
||||||
dot_string = self.SYMBOL_PROGRESS_READ * dots
|
dot_string = self.SYMBOL_PROGRESS_READ * dots
|
||||||
empty_dots = self.SYMBOL_PROGRESS_UNREAD * (10 - dots)
|
empty_dots = self.SYMBOL_PROGRESS_UNREAD * (10 - dots)
|
||||||
book['reading_progress'] = '%s%s' % (dot_string, empty_dots)
|
book['reading_progress'] = '%s%s' % (dot_string, empty_dots)
|
||||||
@ -1411,7 +1410,7 @@ class CatalogBuilder(object):
|
|||||||
Return:
|
Return:
|
||||||
(dict): formatted args for templating
|
(dict): formatted args for templating
|
||||||
"""
|
"""
|
||||||
series_index = str(book['series_index'])
|
series_index = unicode_type(book['series_index'])
|
||||||
if series_index.endswith('.0'):
|
if series_index.endswith('.0'):
|
||||||
series_index = series_index[:-2]
|
series_index = series_index[:-2]
|
||||||
args = dict(
|
args = dict(
|
||||||
@ -1661,7 +1660,7 @@ class CatalogBuilder(object):
|
|||||||
key=lambda x: sort_key(self._kf_books_by_author_sorter_author_sort(x, len(las))))
|
key=lambda x: sort_key(self._kf_books_by_author_sorter_author_sort(x, len(las))))
|
||||||
|
|
||||||
# Create a new month anchor
|
# Create a new month anchor
|
||||||
date_string = strftime(u'%B %Y', current_date.timetuple())
|
date_string = strftime('%B %Y', current_date.timetuple())
|
||||||
pIndexTag = soup.new_tag("p")
|
pIndexTag = soup.new_tag("p")
|
||||||
pIndexTag['class'] = "date_index"
|
pIndexTag['class'] = "date_index"
|
||||||
aTag = soup.new_tag("a")
|
aTag = soup.new_tag("a")
|
||||||
@ -1919,7 +1918,7 @@ class CatalogBuilder(object):
|
|||||||
def _add_books_to_html_by_day(todays_list, dtc):
|
def _add_books_to_html_by_day(todays_list, dtc):
|
||||||
if len(todays_list):
|
if len(todays_list):
|
||||||
# Create a new day anchor
|
# Create a new day anchor
|
||||||
date_string = strftime(u'%A, %B %d', current_date.timetuple())
|
date_string = strftime('%A, %B %d', current_date.timetuple())
|
||||||
pIndexTag = soup.new_tag("p")
|
pIndexTag = soup.new_tag("p")
|
||||||
pIndexTag['class'] = "date_index"
|
pIndexTag['class'] = "date_index"
|
||||||
aTag = soup.new_tag("a")
|
aTag = soup.new_tag("a")
|
||||||
@ -1981,7 +1980,7 @@ class CatalogBuilder(object):
|
|||||||
ptc = 0
|
ptc = 0
|
||||||
|
|
||||||
# Percent read
|
# Percent read
|
||||||
dots = int((new_entry['percent_read'] + 5) / 10)
|
dots = int((new_entry['percent_read'] + 5) // 10)
|
||||||
dot_string = self.SYMBOL_PROGRESS_READ * dots
|
dot_string = self.SYMBOL_PROGRESS_READ * dots
|
||||||
empty_dots = self.SYMBOL_PROGRESS_UNREAD * (10 - dots)
|
empty_dots = self.SYMBOL_PROGRESS_UNREAD * (10 - dots)
|
||||||
pBookTag.insert(ptc, NavigableString('%s%s' % (dot_string, empty_dots)))
|
pBookTag.insert(ptc, NavigableString('%s%s' % (dot_string, empty_dots)))
|
||||||
@ -2690,7 +2689,7 @@ class CatalogBuilder(object):
|
|||||||
series_index = ''
|
series_index = ''
|
||||||
if book['series']:
|
if book['series']:
|
||||||
series = book['series']
|
series = book['series']
|
||||||
series_index = str(book['series_index'])
|
series_index = unicode_type(book['series_index'])
|
||||||
if series_index.endswith('.0'):
|
if series_index.endswith('.0'):
|
||||||
series_index = series_index[:-2]
|
series_index = series_index[:-2]
|
||||||
|
|
||||||
@ -2754,7 +2753,7 @@ class CatalogBuilder(object):
|
|||||||
publisher = book['publisher']
|
publisher = book['publisher']
|
||||||
|
|
||||||
# Rating
|
# Rating
|
||||||
stars = int(book['rating']) / 2
|
stars = int(book['rating']) // 2
|
||||||
rating = ''
|
rating = ''
|
||||||
if stars:
|
if stars:
|
||||||
star_string = self.SYMBOL_FULL_RATING * stars
|
star_string = self.SYMBOL_FULL_RATING * stars
|
||||||
@ -2958,8 +2957,8 @@ class CatalogBuilder(object):
|
|||||||
font = ImageFont.truetype(default_font, 48)
|
font = ImageFont.truetype(default_font, 48)
|
||||||
text = self.opts.catalog_title.encode('utf-8')
|
text = self.opts.catalog_title.encode('utf-8')
|
||||||
width, height = draw.textsize(text, font=font)
|
width, height = draw.textsize(text, font=font)
|
||||||
left = max(int((MI_WIDTH - width) / 2.), 0)
|
left = max(int((MI_WIDTH - width) / 2), 0)
|
||||||
top = max(int((MI_HEIGHT - height) / 2.), 0)
|
top = max(int((MI_HEIGHT - height) / 2), 0)
|
||||||
draw.text((left, top), text, fill=(0, 0, 0), font=font)
|
draw.text((left, top), text, fill=(0, 0, 0), font=font)
|
||||||
with open(out_path, 'wb') as f:
|
with open(out_path, 'wb') as f:
|
||||||
img.save(f, 'GIF')
|
img.save(f, 'GIF')
|
||||||
@ -3100,7 +3099,7 @@ class CatalogBuilder(object):
|
|||||||
navLabelTag = ncx_soup.new_tag("navLabel")
|
navLabelTag = ncx_soup.new_tag("navLabel")
|
||||||
textTag = ncx_soup.new_tag("text")
|
textTag = ncx_soup.new_tag("text")
|
||||||
if book['series']:
|
if book['series']:
|
||||||
series_index = str(book['series_index'])
|
series_index = unicode_type(book['series_index'])
|
||||||
if series_index.endswith('.0'):
|
if series_index.endswith('.0'):
|
||||||
series_index = series_index[:-2]
|
series_index = series_index[:-2]
|
||||||
if self.generate_for_kindle_mobi:
|
if self.generate_for_kindle_mobi:
|
||||||
@ -3694,7 +3693,7 @@ class CatalogBuilder(object):
|
|||||||
# Add *article* entries for each populated month
|
# Add *article* entries for each populated month
|
||||||
# master_months_list{}: [0]:titles list [1]:date
|
# master_months_list{}: [0]:titles list [1]:date
|
||||||
for books_by_month in master_month_list:
|
for books_by_month in master_month_list:
|
||||||
datestr = strftime(u'%B %Y', books_by_month[1].timetuple())
|
datestr = strftime('%B %Y', books_by_month[1].timetuple())
|
||||||
navPointByMonthTag = ncx_soup.new_tag('navPoint')
|
navPointByMonthTag = ncx_soup.new_tag('navPoint')
|
||||||
if self.generate_for_kindle_mobi:
|
if self.generate_for_kindle_mobi:
|
||||||
navPointByMonthTag['class'] = "article"
|
navPointByMonthTag['class'] = "article"
|
||||||
@ -3844,7 +3843,7 @@ class CatalogBuilder(object):
|
|||||||
# Add *article* entries for each populated day
|
# Add *article* entries for each populated day
|
||||||
# master_day_list{}: [0]:titles list [1]:date
|
# master_day_list{}: [0]:titles list [1]:date
|
||||||
for books_by_day in master_day_list:
|
for books_by_day in master_day_list:
|
||||||
datestr = strftime(u'%A, %B %d', books_by_day[1].timetuple())
|
datestr = strftime('%A, %B %d', books_by_day[1].timetuple())
|
||||||
navPointByDayTag = ncx_soup.new_tag('navPoint')
|
navPointByDayTag = ncx_soup.new_tag('navPoint')
|
||||||
if self.generate_for_kindle_mobi:
|
if self.generate_for_kindle_mobi:
|
||||||
navPointByDayTag['class'] = "article"
|
navPointByDayTag['class'] = "article"
|
||||||
@ -3995,7 +3994,7 @@ class CatalogBuilder(object):
|
|||||||
for title in genre['books']:
|
for title in genre['books']:
|
||||||
titles.append(title['title'])
|
titles.append(title['title'])
|
||||||
titles = sorted(titles, key=lambda x: (self.generate_sort_title(x), self.generate_sort_title(x)))
|
titles = sorted(titles, key=lambda x: (self.generate_sort_title(x), self.generate_sort_title(x)))
|
||||||
titles_list = self.generate_short_description(u" • ".join(titles), dest="description")
|
titles_list = self.generate_short_description(" • ".join(titles), dest="description")
|
||||||
cmTag.insert(0, NavigableString(self.format_ncx_text(titles_list, dest='description')))
|
cmTag.insert(0, NavigableString(self.format_ncx_text(titles_list, dest='description')))
|
||||||
|
|
||||||
navPointVolumeTag.insert(3, cmTag)
|
navPointVolumeTag.insert(3, cmTag)
|
||||||
@ -4205,7 +4204,7 @@ class CatalogBuilder(object):
|
|||||||
rating = ''
|
rating = ''
|
||||||
try:
|
try:
|
||||||
if 'rating' in book:
|
if 'rating' in book:
|
||||||
stars = int(book['rating']) / 2
|
stars = int(book['rating']) // 2
|
||||||
if stars:
|
if stars:
|
||||||
star_string = self.SYMBOL_FULL_RATING * stars
|
star_string = self.SYMBOL_FULL_RATING * stars
|
||||||
empty_stars = self.SYMBOL_EMPTY_RATING * (5 - stars)
|
empty_stars = self.SYMBOL_EMPTY_RATING * (5 - stars)
|
||||||
@ -4489,7 +4488,7 @@ class CatalogBuilder(object):
|
|||||||
Return:
|
Return:
|
||||||
(str): legal XHTML anchor string of unicode character name
|
(str): legal XHTML anchor string of unicode character name
|
||||||
"""
|
"""
|
||||||
fullname = u''.join(unicodedata.name(unicode_type(cc)) for cc in c)
|
fullname = ''.join(unicodedata.name(unicode_type(cc)) for cc in c)
|
||||||
terms = fullname.split()
|
terms = fullname.split()
|
||||||
return "_".join(terms)
|
return "_".join(terms)
|
||||||
|
|
||||||
@ -4521,7 +4520,7 @@ class CatalogBuilder(object):
|
|||||||
matched = list(set(record['tags']) & set(excluded_tags))
|
matched = list(set(record['tags']) & set(excluded_tags))
|
||||||
if matched:
|
if matched:
|
||||||
for rule in self.opts.exclusion_rules:
|
for rule in self.opts.exclusion_rules:
|
||||||
if rule[1] == _('Tags') and rule[2] == str(matched[0]):
|
if rule[1] == _('Tags') and rule[2] == unicode_type(matched[0]):
|
||||||
self.opts.log.info(" - '%s' by %s (Exclusion rule '%s')" %
|
self.opts.log.info(" - '%s' by %s (Exclusion rule '%s')" %
|
||||||
(record['title'], record['authors'][0], rule[0]))
|
(record['title'], record['authors'][0], rule[0]))
|
||||||
|
|
||||||
@ -4808,12 +4807,12 @@ class CatalogBuilder(object):
|
|||||||
self.progress_int = 0.01
|
self.progress_int = 0.01
|
||||||
self.reporter(self.progress_int, self.progress_string)
|
self.reporter(self.progress_int, self.progress_string)
|
||||||
if self.opts.cli_environment:
|
if self.opts.cli_environment:
|
||||||
log_msg = u"%3.0f%% %s" % (self.progress_int * 100, self.progress_string)
|
log_msg = "%3.0f%% %s" % (self.progress_int * 100, self.progress_string)
|
||||||
if self.opts.verbose:
|
if self.opts.verbose:
|
||||||
log_msg += " (%s)" % str(datetime.timedelta(seconds=int(time.time() - self.opts.start_time)))
|
log_msg += " (%s)" % unicode_type(datetime.timedelta(seconds=int(time.time() - self.opts.start_time)))
|
||||||
else:
|
else:
|
||||||
log_msg = ("%s (%s)" % (self.progress_string,
|
log_msg = ("%s (%s)" % (self.progress_string,
|
||||||
str(datetime.timedelta(seconds=int(time.time() - self.opts.start_time)))))
|
unicode_type(datetime.timedelta(seconds=int(time.time() - self.opts.start_time)))))
|
||||||
self.opts.log(log_msg)
|
self.opts.log(log_msg)
|
||||||
|
|
||||||
def update_progress_micro_step(self, description, micro_step_pct):
|
def update_progress_micro_step(self, description, micro_step_pct):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Greg Riker'
|
__copyright__ = '2010, Greg Riker'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
@ -44,7 +44,7 @@ class NumberToText(object): # {{{
|
|||||||
|
|
||||||
# Build the hundreds component
|
# Build the hundreds component
|
||||||
if hundredsComponent:
|
if hundredsComponent:
|
||||||
hundredsComponentString = "%s hundred" % self.hundreds[hundredsComponent/100]
|
hundredsComponentString = "%s hundred" % self.hundreds[hundredsComponent//100]
|
||||||
else:
|
else:
|
||||||
hundredsComponentString = ""
|
hundredsComponentString = ""
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ class NumberToText(object): # {{{
|
|||||||
onesPart = ""
|
onesPart = ""
|
||||||
|
|
||||||
# Get the tens part
|
# Get the tens part
|
||||||
tensPart = self.tens[tensComponent / 10]
|
tensPart = self.tens[tensComponent // 10]
|
||||||
onesPart = self.lessThanTwenty[tensComponent % 10]
|
onesPart = self.lessThanTwenty[tensComponent % 10]
|
||||||
|
|
||||||
if intToTranslate % 10:
|
if intToTranslate % 10:
|
||||||
@ -183,8 +183,8 @@ class NumberToText(object): # {{{
|
|||||||
self.text = "one billion"
|
self.text = "one billion"
|
||||||
else :
|
else :
|
||||||
# Isolate the three-digit number groups
|
# Isolate the three-digit number groups
|
||||||
millionsNumber = number/10**6
|
millionsNumber = number//10**6
|
||||||
thousandsNumber = (number - (millionsNumber * 10**6))/10**3
|
thousandsNumber = (number - (millionsNumber * 10**6))//10**3
|
||||||
hundredsNumber = number - (millionsNumber * 10**6) - (thousandsNumber * 10**3)
|
hundredsNumber = number - (millionsNumber * 10**6) - (thousandsNumber * 10**3)
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("Converting %s %s %s" % (millionsNumber, thousandsNumber, hundredsNumber))
|
print("Converting %s %s %s" % (millionsNumber, thousandsNumber, hundredsNumber))
|
||||||
@ -196,7 +196,7 @@ class NumberToText(object): # {{{
|
|||||||
# Convert thousandsNumber
|
# Convert thousandsNumber
|
||||||
if thousandsNumber:
|
if thousandsNumber:
|
||||||
if number > 1099 and number < 2000:
|
if number > 1099 and number < 2000:
|
||||||
resultString = '%s %s' % (self.lessThanTwenty[number/100],
|
resultString = '%s %s' % (self.lessThanTwenty[number//100],
|
||||||
self.stringFromInt(number % 100))
|
self.stringFromInt(number % 100))
|
||||||
self.text = resultString.strip().capitalize()
|
self.text = resultString.strip().capitalize()
|
||||||
return
|
return
|
||||||
@ -222,6 +222,6 @@ class NumberToText(object): # {{{
|
|||||||
resultString = "zero"
|
resultString = "zero"
|
||||||
|
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
self.log(u'resultString: %s' % resultString)
|
self.log('resultString: %s' % resultString)
|
||||||
self.text = resultString.strip().capitalize()
|
self.text = resultString.strip().capitalize()
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
from __future__ import print_function
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Backend that implements storage of ebooks in an sqlite database.
|
Backend that implements storage of ebooks in an sqlite database.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sqlite3 as sqlite
|
import sqlite3 as sqlite
|
||||||
import datetime, re, sre_constants
|
import datetime, re, sre_constants
|
||||||
from zlib import compress, decompress
|
from zlib import compress, decompress
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from __future__ import with_statement
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
@ -6,6 +7,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
'''
|
'''
|
||||||
The database used to store ebook metadata
|
The database used to store ebook metadata
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os, sys, shutil, glob, time, functools, traceback, re, \
|
import os, sys, shutil, glob, time, functools, traceback, re, \
|
||||||
json, uuid, hashlib, copy, numbers
|
json, uuid, hashlib, copy, numbers
|
||||||
from collections import defaultdict, namedtuple
|
from collections import defaultdict, namedtuple
|
||||||
@ -91,7 +93,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if self._library_id_ is None:
|
if self._library_id_ is None:
|
||||||
ans = self.conn.get('SELECT uuid FROM library_id', all=False)
|
ans = self.conn.get('SELECT uuid FROM library_id', all=False)
|
||||||
if ans is None:
|
if ans is None:
|
||||||
ans = str(uuid.uuid4())
|
ans = unicode_type(uuid.uuid4())
|
||||||
self.library_id = ans
|
self.library_id = ans
|
||||||
else:
|
else:
|
||||||
self._library_id_ = ans
|
self._library_id_ = ans
|
||||||
@ -256,11 +258,11 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
from calibre.library.coloring import migrate_old_rule
|
from calibre.library.coloring import migrate_old_rule
|
||||||
old_rules = []
|
old_rules = []
|
||||||
for i in range(1, 6):
|
for i in range(1, 6):
|
||||||
col = self.prefs.get('column_color_name_'+str(i), None)
|
col = self.prefs.get('column_color_name_'+unicode_type(i), None)
|
||||||
templ = self.prefs.get('column_color_template_'+str(i), None)
|
templ = self.prefs.get('column_color_template_'+unicode_type(i), None)
|
||||||
if col and templ:
|
if col and templ:
|
||||||
try:
|
try:
|
||||||
del self.prefs['column_color_name_'+str(i)]
|
del self.prefs['column_color_name_'+unicode_type(i)]
|
||||||
rules = migrate_old_rule(self.field_metadata, templ)
|
rules = migrate_old_rule(self.field_metadata, templ)
|
||||||
for templ in rules:
|
for templ in rules:
|
||||||
old_rules.append((col, templ))
|
old_rules.append((col, templ))
|
||||||
@ -359,7 +361,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
''')
|
''')
|
||||||
self.conn.execute(
|
self.conn.execute(
|
||||||
'UPDATE authors SET sort=author_to_author_sort(name) WHERE sort IS NULL')
|
'UPDATE authors SET sort=author_to_author_sort(name) WHERE sort IS NULL')
|
||||||
self.conn.executescript(u'''
|
self.conn.executescript('''
|
||||||
CREATE TEMP VIEW IF NOT EXISTS tag_browser_news AS SELECT DISTINCT
|
CREATE TEMP VIEW IF NOT EXISTS tag_browser_news AS SELECT DISTINCT
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
@ -372,7 +374,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
(SELECT id FROM tags WHERE name="{0}")));
|
(SELECT id FROM tags WHERE name="{0}")));
|
||||||
'''.format(_('News')))
|
'''.format(_('News')))
|
||||||
|
|
||||||
self.conn.executescript(u'''
|
self.conn.executescript('''
|
||||||
CREATE TEMP VIEW IF NOT EXISTS tag_browser_filtered_news AS SELECT DISTINCT
|
CREATE TEMP VIEW IF NOT EXISTS tag_browser_filtered_news AS SELECT DISTINCT
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
@ -450,7 +452,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
# account for the series index column. Field_metadata knows that
|
# account for the series index column. Field_metadata knows that
|
||||||
# the series index is one larger than the series. If you change
|
# the series index is one larger than the series. If you change
|
||||||
# it here, be sure to change it there as well.
|
# it here, be sure to change it there as well.
|
||||||
self.FIELD_MAP[str(col)+'_index'] = base = base+1
|
self.FIELD_MAP[unicode_type(col)+'_index'] = base = base+1
|
||||||
self.field_metadata.set_field_record_index(
|
self.field_metadata.set_field_record_index(
|
||||||
self.custom_column_num_map[col]['label']+'_index',
|
self.custom_column_num_map[col]['label']+'_index',
|
||||||
base,
|
base,
|
||||||
@ -487,7 +489,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
# There is a chance that these can be duplicates of an existing
|
# There is a chance that these can be duplicates of an existing
|
||||||
# user category. Print the exception and continue.
|
# user category. Print the exception and continue.
|
||||||
try:
|
try:
|
||||||
self.field_metadata.add_user_category(label=u'@' + cat, name=cat)
|
self.field_metadata.add_user_category(label='@' + cat, name=cat)
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
@ -1127,7 +1129,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
try:
|
try:
|
||||||
quathors = mi.authors[:10] # Too many authors causes parsing of
|
quathors = mi.authors[:10] # Too many authors causes parsing of
|
||||||
# the search expression to fail
|
# the search expression to fail
|
||||||
query = u' and '.join([u'author:"=%s"'%(a.replace('"', '')) for a in
|
query = ' and '.join(['author:"=%s"'%(a.replace('"', '')) for a in
|
||||||
quathors])
|
quathors])
|
||||||
qauthors = mi.authors[10:]
|
qauthors = mi.authors[10:]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -1747,7 +1749,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.id = id
|
self.id = id
|
||||||
|
|
||||||
def __unicode_representation__(self):
|
def __unicode_representation__(self):
|
||||||
return u'n=%s s=%s c=%d rt=%d rc=%d id=%s' % (
|
return 'n=%s s=%s c=%d rt=%d rc=%d id=%s' % (
|
||||||
self.n, self.s, self.c, self.rt, self.rc, self.id)
|
self.n, self.s, self.c, self.rt, self.rc, self.id)
|
||||||
|
|
||||||
if ispy3:
|
if ispy3:
|
||||||
@ -1977,7 +1979,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
# Duplicate the build of items below to avoid using a lambda func
|
# Duplicate the build of items below to avoid using a lambda func
|
||||||
# in the main Tag loop. Saves a few %
|
# in the main Tag loop. Saves a few %
|
||||||
if datatype == 'rating':
|
if datatype == 'rating':
|
||||||
formatter = (lambda x:u'\u2605'*int(x/2))
|
formatter = (lambda x:'\u2605'*int(x//2))
|
||||||
avgr = lambda x: x.n
|
avgr = lambda x: x.n
|
||||||
# eliminate the zero ratings line as well as count == 0
|
# eliminate the zero ratings line as well as count == 0
|
||||||
items = [v for v in tcategories[category].values() if v.c > 0 and v.n != 0]
|
items = [v for v in tcategories[category].values() if v.c > 0 and v.n != 0]
|
||||||
@ -2613,7 +2615,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if commit:
|
if commit:
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
self.data.set(book_id, self.FIELD_MAP['languages'],
|
self.data.set(book_id, self.FIELD_MAP['languages'],
|
||||||
u','.join(final_languages), row_is_id=True)
|
','.join(final_languages), row_is_id=True)
|
||||||
if notify:
|
if notify:
|
||||||
self.notify('metadata', [book_id])
|
self.notify('metadata', [book_id])
|
||||||
return books_to_refresh
|
return books_to_refresh
|
||||||
@ -2992,7 +2994,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
tags = [x.strip().replace(',', ';') for x in tags if x.strip()]
|
tags = [x.strip().replace(',', ';') for x in tags if x.strip()]
|
||||||
tags = [x.decode(preferred_encoding, 'replace')
|
tags = [x.decode(preferred_encoding, 'replace')
|
||||||
if isbytestring(x) else x for x in tags]
|
if isbytestring(x) else x for x in tags]
|
||||||
tags = [u' '.join(x.split()) for x in tags]
|
tags = [' '.join(x.split()) for x in tags]
|
||||||
ans, seen = [], set()
|
ans, seen = [], set()
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
if tag.lower() not in seen:
|
if tag.lower() not in seen:
|
||||||
@ -3068,7 +3070,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
|
||||||
for x in ids:
|
for x in ids:
|
||||||
tags = u','.join(self.get_tags(x))
|
tags = ','.join(self.get_tags(x))
|
||||||
self.data.set(x, self.FIELD_MAP['tags'], tags, row_is_id=True)
|
self.data.set(x, self.FIELD_MAP['tags'], tags, row_is_id=True)
|
||||||
if notify:
|
if notify:
|
||||||
self.notify('metadata', ids)
|
self.notify('metadata', ids)
|
||||||
@ -3124,7 +3126,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.dirtied({id}|books_to_refresh, commit=False)
|
self.dirtied({id}|books_to_refresh, commit=False)
|
||||||
if commit:
|
if commit:
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
tags = u','.join(self.get_tags(id))
|
tags = ','.join(self.get_tags(id))
|
||||||
self.data.set(id, self.FIELD_MAP['tags'], tags, row_is_id=True)
|
self.data.set(id, self.FIELD_MAP['tags'], tags, row_is_id=True)
|
||||||
if notify:
|
if notify:
|
||||||
self.notify('metadata', [id])
|
self.notify('metadata', [id])
|
||||||
@ -3178,7 +3180,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if not isinstance(series, unicode_type):
|
if not isinstance(series, unicode_type):
|
||||||
series = series.decode(preferred_encoding, 'replace')
|
series = series.decode(preferred_encoding, 'replace')
|
||||||
series = series.strip()
|
series = series.strip()
|
||||||
series = u' '.join(series.split())
|
series = ' '.join(series.split())
|
||||||
sx = self.conn.get('SELECT id,name from series WHERE name=?', (series,))
|
sx = self.conn.get('SELECT id,name from series WHERE name=?', (series,))
|
||||||
if sx:
|
if sx:
|
||||||
aid, cur_name = sx[0]
|
aid, cur_name = sx[0]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
from __future__ import with_statement
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
@ -217,7 +217,7 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
|||||||
if hasattr(mi, 'last_modified') and hasattr(mi.last_modified, 'timetuple'):
|
if hasattr(mi, 'last_modified') and hasattr(mi.last_modified, 'timetuple'):
|
||||||
format_args['last_modified'] = strftime(timefmt, mi.last_modified.timetuple())
|
format_args['last_modified'] = strftime(timefmt, mi.last_modified.timetuple())
|
||||||
|
|
||||||
format_args['id'] = str(id)
|
format_args['id'] = unicode_type(id)
|
||||||
# Now format the custom fields
|
# Now format the custom fields
|
||||||
custom_metadata = mi.get_all_user_metadata(make_copy=False)
|
custom_metadata = mi.get_all_user_metadata(make_copy=False)
|
||||||
for key in custom_metadata:
|
for key in custom_metadata:
|
||||||
@ -247,7 +247,7 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
|||||||
components = [x.strip() for x in components.split('/')]
|
components = [x.strip() for x in components.split('/')]
|
||||||
components = [sanitize_func(x) for x in components if x]
|
components = [sanitize_func(x) for x in components if x]
|
||||||
if not components:
|
if not components:
|
||||||
components = [str(id)]
|
components = [unicode_type(id)]
|
||||||
if to_lowercase:
|
if to_lowercase:
|
||||||
components = [x.lower() for x in components]
|
components = [x.lower() for x in components]
|
||||||
if replace_whitespace:
|
if replace_whitespace:
|
||||||
@ -360,7 +360,7 @@ def do_save_book_to_disk(db, book_id, mi, plugboards,
|
|||||||
return not formats_written, book_id, mi.title
|
return not formats_written, book_id, mi.title
|
||||||
|
|
||||||
for fmt in formats:
|
for fmt in formats:
|
||||||
fmt_path = base_path+'.'+str(fmt)
|
fmt_path = base_path+'.'+unicode_type(fmt)
|
||||||
try:
|
try:
|
||||||
db.copy_format_to(book_id, fmt, fmt_path)
|
db.copy_format_to(book_id, fmt, fmt_path)
|
||||||
formats_written = True
|
formats_written = True
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
from __future__ import print_function, with_statement
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
@ -593,7 +593,7 @@ class SchemaUpgrade(object):
|
|||||||
existing = frozenset(map(int, custom_recipes))
|
existing = frozenset(map(int, custom_recipes))
|
||||||
if id_ in existing:
|
if id_ in existing:
|
||||||
id_ = max(existing) + 1000
|
id_ = max(existing) + 1000
|
||||||
id_ = str(id_)
|
id_ = unicode_type(id_)
|
||||||
fname = custom_recipe_filename(id_, title)
|
fname = custom_recipe_filename(id_, title)
|
||||||
custom_recipes[id_] = (title, fname)
|
custom_recipes[id_] = (title, fname)
|
||||||
if isinstance(script, unicode_type):
|
if isinstance(script, unicode_type):
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from __future__ import print_function, with_statement
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
@ -7,6 +8,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
Wrapper for multi-threaded access to a single sqlite database connection. Serializes
|
Wrapper for multi-threaded access to a single sqlite database connection. Serializes
|
||||||
all calls.
|
all calls.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sqlite3 as sqlite, traceback, time, uuid, os
|
import sqlite3 as sqlite, traceback, time, uuid, os
|
||||||
from sqlite3 import IntegrityError, OperationalError
|
from sqlite3 import IntegrityError, OperationalError
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
@ -20,7 +22,7 @@ from calibre import isbytestring, force_unicode
|
|||||||
from calibre.constants import iswindows, DEBUG, plugins, plugins_loc
|
from calibre.constants import iswindows, DEBUG, plugins, plugins_loc
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
from calibre import prints
|
from calibre import prints
|
||||||
from polyglot.builtins import unicode_type, cmp
|
from polyglot.builtins import cmp, native_string_type, unicode_type
|
||||||
from polyglot import reprlib
|
from polyglot import reprlib
|
||||||
from polyglot.queue import Queue
|
from polyglot.queue import Queue
|
||||||
|
|
||||||
@ -78,7 +80,7 @@ def adapt_datetime(dt):
|
|||||||
|
|
||||||
|
|
||||||
sqlite.register_adapter(datetime, adapt_datetime)
|
sqlite.register_adapter(datetime, adapt_datetime)
|
||||||
sqlite.register_converter('timestamp', convert_timestamp)
|
sqlite.register_converter(native_string_type('timestamp'), convert_timestamp)
|
||||||
|
|
||||||
|
|
||||||
def convert_bool(val):
|
def convert_bool(val):
|
||||||
@ -86,8 +88,8 @@ def convert_bool(val):
|
|||||||
|
|
||||||
|
|
||||||
sqlite.register_adapter(bool, lambda x : 1 if x else 0)
|
sqlite.register_adapter(bool, lambda x : 1 if x else 0)
|
||||||
sqlite.register_converter('bool', convert_bool)
|
sqlite.register_converter(native_string_type('bool'), convert_bool)
|
||||||
sqlite.register_converter('BOOL', convert_bool)
|
sqlite.register_converter(native_string_type('BOOL'), convert_bool)
|
||||||
|
|
||||||
|
|
||||||
class DynamicFilter(object):
|
class DynamicFilter(object):
|
||||||
@ -162,7 +164,7 @@ class IdentifiersConcat(object):
|
|||||||
self.ans = []
|
self.ans = []
|
||||||
|
|
||||||
def step(self, key, val):
|
def step(self, key, val):
|
||||||
self.ans.append(u'%s:%s'%(key, val))
|
self.ans.append('%s:%s'%(key, val))
|
||||||
|
|
||||||
def finalize(self):
|
def finalize(self):
|
||||||
try:
|
try:
|
||||||
@ -262,15 +264,15 @@ def do_connect(path, row_factory=None):
|
|||||||
conn.row_factory = sqlite.Row if row_factory else (lambda cursor, row : list(row))
|
conn.row_factory = sqlite.Row if row_factory else (lambda cursor, row : list(row))
|
||||||
conn.create_aggregate('concat', 1, Concatenate)
|
conn.create_aggregate('concat', 1, Concatenate)
|
||||||
conn.create_aggregate('aum_sortconcat', 4, AumSortedConcatenate)
|
conn.create_aggregate('aum_sortconcat', 4, AumSortedConcatenate)
|
||||||
conn.create_collation('PYNOCASE', partial(pynocase,
|
conn.create_collation(native_string_type('PYNOCASE'), partial(pynocase,
|
||||||
encoding=encoding))
|
encoding=encoding))
|
||||||
conn.create_function('title_sort', 1, title_sort)
|
conn.create_function('title_sort', 1, title_sort)
|
||||||
conn.create_function('author_to_author_sort', 1,
|
conn.create_function('author_to_author_sort', 1,
|
||||||
_author_to_author_sort)
|
_author_to_author_sort)
|
||||||
conn.create_function('uuid4', 0, lambda : str(uuid.uuid4()))
|
conn.create_function('uuid4', 0, lambda : unicode_type(uuid.uuid4()))
|
||||||
# Dummy functions for dynamically created filters
|
# Dummy functions for dynamically created filters
|
||||||
conn.create_function('books_list_filter', 1, lambda x: 1)
|
conn.create_function('books_list_filter', 1, lambda x: 1)
|
||||||
conn.create_collation('icucollate', icu_collator)
|
conn.create_collation(native_string_type('icucollate'), icu_collator)
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
|
|
||||||
@ -320,7 +322,7 @@ class DBThread(Thread):
|
|||||||
break
|
break
|
||||||
except OperationalError as err:
|
except OperationalError as err:
|
||||||
# Retry if unable to open db file
|
# Retry if unable to open db file
|
||||||
e = str(err)
|
e = unicode_type(err)
|
||||||
if 'unable to open' not in e or i == 2:
|
if 'unable to open' not in e or i == 2:
|
||||||
if 'unable to open' in e:
|
if 'unable to open' in e:
|
||||||
prints('Unable to open database for func',
|
prints('Unable to open database for func',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user