From 8d7494e5ecc1d8d2b1d780993bf478323d97ece0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 30 Aug 2012 16:55:06 +0530 Subject: [PATCH 01/10] Conversion: Add an option under Structure Detection to set the 'Start reading at' metadata with an XPath expression. Fixes #1043233 (Add ability to create start point in ebooks) --- src/calibre/ebooks/conversion/cli.py | 2 +- src/calibre/ebooks/conversion/plumber.py | 10 ++ .../ebooks/oeb/transforms/structure.py | 31 ++++++- .../gui2/convert/structure_detection.py | 7 +- .../gui2/convert/structure_detection.ui | 93 ++++++++++--------- 5 files changed, 94 insertions(+), 49 deletions(-) diff --git a/src/calibre/ebooks/conversion/cli.py b/src/calibre/ebooks/conversion/cli.py index a860b75839..fb1974f93b 100644 --- a/src/calibre/ebooks/conversion/cli.py +++ b/src/calibre/ebooks/conversion/cli.py @@ -170,7 +170,7 @@ def add_pipeline_options(parser, plumber): 'chapter', 'chapter_mark', 'prefer_metadata_cover', 'remove_first_image', 'insert_metadata', 'page_breaks_before', - 'remove_fake_margins', + 'remove_fake_margins', 'start_reading_at', ] ), diff --git a/src/calibre/ebooks/conversion/plumber.py b/src/calibre/ebooks/conversion/plumber.py index 6a7b5e586b..dcb5add27e 100644 --- a/src/calibre/ebooks/conversion/plumber.py +++ b/src/calibre/ebooks/conversion/plumber.py @@ -304,6 +304,16 @@ OptionRecommendation(name='chapter_mark', 'to mark chapters.') ), +OptionRecommendation(name='start_reading_at', + recommended_value=None, level=OptionRecommendation.LOW, + help=_('An XPath expression to detect the location in the document' + ' at which to start reading. Some ebook reading programs' + ' (most prominently the Kindle) use this location as the' + ' position at which to open the book. See the XPath tutorial' + ' in the calibre User Manual for further help using this' + ' feature.') + ), + OptionRecommendation(name='extra_css', recommended_value=None, level=OptionRecommendation.LOW, help=_('Either the path to a CSS stylesheet or raw CSS. ' diff --git a/src/calibre/ebooks/oeb/transforms/structure.py b/src/calibre/ebooks/oeb/transforms/structure.py index b90774bcc7..3af4d87a13 100644 --- a/src/calibre/ebooks/oeb/transforms/structure.py +++ b/src/calibre/ebooks/oeb/transforms/structure.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import re +import re, uuid from lxml import etree from urlparse import urlparse @@ -80,6 +80,35 @@ class DetectStructure(object): if not node.title or not node.title.strip(): node.title = _('Unnamed') + if self.opts.start_reading_at: + self.detect_start_reading() + + def detect_start_reading(self): + expr = self.opts.start_reading_at + try: + expr = XPath(expr) + except: + self.log.warn( + 'Invalid start reading at XPath expression, ignoring: %s'%expr) + return + for item in self.oeb.spine: + if not hasattr(item.data, 'xpath'): continue + matches = expr(item.data) + if matches: + elem = matches[0] + eid = elem.get('id', None) + if not eid: + eid = u'start_reading_at_'+unicode(uuid.uuid4()).replace(u'-', u'') + elem.set('id', eid) + if u'text' in self.oeb.guide: + self.oeb.guide.remove(u'text') + self.oeb.guide.add(u'text', u'Start', item.href+u'#'+eid) + self.log('Setting start reading at position to %s in %s'%( + self.opts.start_reading_at, item.href)) + return + self.log.warn("Failed to find start reading at position: %s"% + self.opts.start_reading_at) + def detect_chapters(self): self.detected_chapters = [] diff --git a/src/calibre/gui2/convert/structure_detection.py b/src/calibre/gui2/convert/structure_detection.py index b58c473bd4..0946d13e46 100644 --- a/src/calibre/gui2/convert/structure_detection.py +++ b/src/calibre/gui2/convert/structure_detection.py @@ -20,7 +20,7 @@ class StructureDetectionWidget(Widget, Ui_Form): def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, - ['chapter', 'chapter_mark', + ['chapter', 'chapter_mark', 'start_reading_at', 'remove_first_image', 'remove_fake_margins', 'insert_metadata', 'page_breaks_before'] ) @@ -31,15 +31,18 @@ class StructureDetectionWidget(Widget, Ui_Form): self.opt_chapter.set_msg(_('Detect chapters at (XPath expression):')) self.opt_page_breaks_before.set_msg(_('Insert page breaks before ' '(XPath expression):')) + self.opt_start_reading_at.set_msg( + _('Start reading at (XPath expression):')) def break_cycles(self): Widget.break_cycles(self) def pre_commit_check(self): - for x in ('chapter', 'page_breaks_before'): + for x in ('chapter', 'page_breaks_before', 'start_reading_at'): x = getattr(self, 'opt_'+x) if not x.check(): error_dialog(self, _('Invalid XPath'), _('The XPath expression %s is invalid.')%x.text).exec_() return False return True + diff --git a/src/calibre/gui2/convert/structure_detection.ui b/src/calibre/gui2/convert/structure_detection.ui index 4ba90c1c2c..21d285fb33 100644 --- a/src/calibre/gui2/convert/structure_detection.ui +++ b/src/calibre/gui2/convert/structure_detection.ui @@ -14,10 +14,40 @@ Form - + + + + Remove &fake margins + + + + + + + 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. + + + true + + + + + + + + + + Insert &metadata as page at start of book + + + + + + + - + Chapter &mark: @@ -27,44 +57,14 @@ - + 20 - - - - Remove first &image - - - - - - - Insert &metadata as page at start of book - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + Qt::Horizontal @@ -77,22 +77,25 @@ - - + + - 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. - - - true + Remove first &image - - - - Remove &fake margins + + + + Qt::Vertical - + + + 20 + 40 + + + From 653ea57586a0a1d059c8e6e5b410761db8723d80 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 30 Aug 2012 17:12:44 +0530 Subject: [PATCH 02/10] Handle string with NULL bytes in them in the ICU upper/lower functions --- src/calibre/utils/icu.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/calibre/utils/icu.py b/src/calibre/utils/icu.py index f1f94dc175..66ee8fd59f 100644 --- a/src/calibre/utils/icu.py +++ b/src/calibre/utils/icu.py @@ -82,6 +82,17 @@ def icu_sort_key(collator, obj): obj = obj.replace(b'\0', b'') return _secondary_collator.sort_key(obj) +def icu_change_case(upper, locale, obj): + func = _icu.upper if upper else _icu.lower + try: + return func(locale, obj) + except TypeError: + if isinstance(obj, unicode): + obj = obj.replace(u'\0', u'') + else: + obj = obj.replace(b'\0', b'') + return func(locale, obj) + def py_find(pattern, source): pos = source.find(pattern) if pos > -1: @@ -163,10 +174,10 @@ case_sensitive_sort_key = py_case_sensitive_sort_key if _icu_not_ok else \ case_sensitive_strcmp = cmp if _icu_not_ok else icu_case_sensitive_strcmp upper = (lambda s: s.upper()) if _icu_not_ok else \ - partial(_icu.upper, get_locale()) + partial(icu_change_case, True, get_locale()) lower = (lambda s: s.lower()) if _icu_not_ok else \ - partial(_icu.lower, get_locale()) + partial(icu_change_case, False, get_locale()) title_case = (lambda s: s.title()) if _icu_not_ok else \ partial(_icu.title, get_locale()) From 847e90600158d6161175b861a4498bd5a0ee10ac Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 30 Aug 2012 19:19:30 +0530 Subject: [PATCH 03/10] Catalogs: Fix regression that broke sorting of non series titles before series titles --- src/calibre/library/catalogs/epub_mobi_builder.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index a8cee7e1c9..d823d80cb3 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -1294,7 +1294,7 @@ Author '{0}': def add_books_to_HTML_by_month(this_months_list, dtc): if len(this_months_list): - this_months_list = sorted(this_months_list, key=self.booksByAuthorSorter_author_sort) + this_months_list = sorted(this_months_list, key=lambda x: sort_key(self.booksByAuthorSorter_author_sort(x))) # Create a new month anchor date_string = strftime(u'%B %Y', current_date.timetuple()) @@ -3091,14 +3091,14 @@ Author '{0}': Sort non-series books before series books ''' if not book['series']: - key = '%s %s' % (capitalize(book['author_sort']), + key = '%s ~%s' % (capitalize(book['author_sort']), capitalize(book['title_sort'])) else: index = book['series_index'] integer = int(index) fraction = index-integer series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0')) - key = '%s ~%s %s' % (capitalize(book['author_sort']), + key = '%s %s %s' % (capitalize(book['author_sort']), self.generateSortTitle(book['series']), series_index) return key @@ -3228,9 +3228,9 @@ Author '{0}': # Hack to force the cataloged leading letter to be # an unadorned character if the accented version sorts before the unaccented exceptions = { - u'Ä':u'A', - u'Ö':u'O', - u'Ü':u'U' + u'??':u'A', + u'??':u'O', + u'??':u'U' } if key is not None: From 80300df3f45c7e1947dc072cd65a7f27019a4059 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 30 Aug 2012 19:27:53 +0530 Subject: [PATCH 04/10] samefile_windows(); Return true if the strings are the same upto case differences. --- src/calibre/utils/filenames.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index c843100157..d9fd12d466 100644 --- a/src/calibre/utils/filenames.py +++ b/src/calibre/utils/filenames.py @@ -203,6 +203,11 @@ def samefile_windows(src, dst): import win32file from pywintypes import error + samestring = (os.path.normcase(os.path.abspath(src)) == + os.path.normcase(os.path.abspath(dst))) + if samestring: + return True + def get_fileid(x): if isbytestring(x): x = x.decode(filesystem_encoding) try: From 7e3e206779387ee104711017e1cfa1f9ff0fffb1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 31 Aug 2012 00:03:17 +0530 Subject: [PATCH 05/10] ... --- src/calibre/library/catalogs/epub_mobi_builder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index d823d80cb3..1860dcfe47 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -3228,9 +3228,9 @@ Author '{0}': # Hack to force the cataloged leading letter to be # an unadorned character if the accented version sorts before the unaccented exceptions = { - u'??':u'A', - u'??':u'O', - u'??':u'U' + u'Ä':u'A', + u'Ö':u'O', + u'Ü':u'U' } if key is not None: From e50338f9c7a497221397ee36f91db578d9fc1509 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 31 Aug 2012 08:41:50 +0530 Subject: [PATCH 06/10] version 0.8.67 --- Changelog.yaml | 50 ++++++++++++++++++++++++++++++++++++++++ src/calibre/constants.py | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Changelog.yaml b/Changelog.yaml index 975d77247a..b0bd4dea38 100644 --- a/Changelog.yaml +++ b/Changelog.yaml @@ -19,6 +19,56 @@ # new recipes: # - title: +- version: 0.8.67 + date: 2012-08-31 + + new features: + - title: "PDF Output: Generate a PDF Outline based on the Table of Contents of the input document" + + - title: "Conversion: Add an option under Structure Detection to set the 'Start reading at' metadata with an XPath expression." + tickets: [1043233] + + - title: "Speed up changing the title and author of files with books larger than 3MB by avoiding an unnecessary extra copy." + + - title: "Wireless device driver: Make detecting and connecting to devices easier on networks where mdns is disabled" + + - title: "PDF Output: Allow choosing the default font family and size when generating PDF files (under PDF Options) in the conversion dialog" + + - title: "Metadata dialog: Comments editor: Allow specifying the name of a link when using the insert link button." + tickets: [1042683] + + - title: "Remove the unmaintained pdfmanipulate command line utility. There are many other tools that provide similar functionality, for example, pdftk and podofo" + + bug fixes: + - title: "Catalogs: Fix regression that broke sorting of non series titles before series titles" + + - title: "PDF Output: Do not create duplicate embedded fonts in the PDF for every individual HTML file in the input document" + + - title: "Fix regression that broke DnD of files having a # character in their names to the book details panel" + + - title: "PDF Output: Allow generating PDF files with more than 512 pages on windows." + tickets: [1041614] + + - title: "Fix minor bug in handling of the completion popups when using the next/previous buttons in the edit metadata dialog" + ticket: [1041389] + + improved recipes: + - Coding Horror + - TIME Magazine + + new recipes: + - title: Cumhuriyet Yzarlar + author: Sethi Eksi + + - title: Arcadia + author: Masahiro Hasegawa + + - title: Business Week Magazine and Chronicle of Higher Education + author: Rick Shang + + - title: CIPER Chile + author: Darko Miletic + - version: 0.8.66 date: 2012-08-24 diff --git a/src/calibre/constants.py b/src/calibre/constants.py index c1e0faba36..24c4791554 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -4,7 +4,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __appname__ = u'calibre' -numeric_version = (0, 8, 66) +numeric_version = (0, 8, 67) __version__ = u'.'.join(map(unicode, numeric_version)) __author__ = u"Kovid Goyal " From 40ce3d50371a899ec2f22b4fe05a864584dd7502 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 31 Aug 2012 09:12:31 +0530 Subject: [PATCH 07/10] IGN:Tag release --- src/calibre/translations/calibre.pot | 731 +++++++++++---------------- 1 file changed, 308 insertions(+), 423 deletions(-) diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index 7c00385294..ecdb4a1e5d 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -4,9 +4,9 @@ # msgid "" msgstr "" -"Project-Id-Version: calibre 0.8.66\n" -"POT-Creation-Date: 2012-08-24 10:47+IST\n" -"PO-Revision-Date: 2012-08-24 10:47+IST\n" +"Project-Id-Version: calibre 0.8.67\n" +"POT-Creation-Date: 2012-08-31 08:42+IST\n" +"PO-Revision-Date: 2012-08-31 08:42+IST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -30,13 +30,12 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/hanvon/driver.py:101 #: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:74 #: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:77 -#: /home/kovid/work/calibre/src/calibre/devices/kobo/books.py:24 +#: /home/kovid/work/calibre/src/calibre/devices/kobo/books.py:25 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:656 -#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:165 -#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:151 +#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:191 +#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:152 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:70 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:71 -#: /home/kovid/work/calibre/src/calibre/devices/prs500/books.py:267 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:661 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:468 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:469 @@ -129,23 +128,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdb/ereader/writer.py:174 #: /home/kovid/work/calibre/src/calibre/ebooks/pdb/palmdoc/writer.py:29 #: /home/kovid/work/calibre/src/calibre/ebooks/pdb/ztxt/writer.py:27 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:82 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:83 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/decrypt.py:73 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/decrypt.py:74 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/encrypt.py:63 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/encrypt.py:64 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:52 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/merge.py:65 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/merge.py:66 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/reverse.py:63 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/reverse.py:64 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:62 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:63 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:81 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:82 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:111 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:108 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:109 #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:425 #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:433 #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:166 @@ -154,7 +138,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add.py:159 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:166 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:667 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:41 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:124 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:143 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:145 @@ -188,12 +172,12 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/library/database2.py:585 #: /home/kovid/work/calibre/src/calibre/library/database2.py:593 #: /home/kovid/work/calibre/src/calibre/library/database2.py:604 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2180 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2334 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2758 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3405 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3407 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3544 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2189 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2343 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2767 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3414 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3416 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3553 #: /home/kovid/work/calibre/src/calibre/library/server/content.py:250 #: /home/kovid/work/calibre/src/calibre/library/server/content.py:251 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:247 @@ -201,9 +185,6 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:163 #: /home/kovid/work/calibre/src/calibre/library/server/xml.py:79 #: /home/kovid/work/calibre/src/calibre/utils/localization.py:188 -#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:46 -#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:66 -#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:88 #: /home/kovid/work/calibre/src/calibre/web/feeds/recipes/collection.py:45 #: /home/kovid/work/calibre/src/calibre/web/feeds/recipes/collection.py:53 msgid "Unknown" @@ -885,26 +866,26 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:666 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:67 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:668 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1053 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1052 #: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:852 #: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:875 msgid "Yes" msgstr "" #: /home/kovid/work/calibre/src/calibre/db/fields.py:163 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1208 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1207 msgid "Main" msgstr "" #: /home/kovid/work/calibre/src/calibre/db/fields.py:165 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:77 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1210 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1209 msgid "Card A" msgstr "" #: /home/kovid/work/calibre/src/calibre/db/fields.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:79 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1212 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1211 msgid "Card B" msgstr "" @@ -1047,14 +1028,14 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1199 #: /home/kovid/work/calibre/src/calibre/library/database2.py:370 #: /home/kovid/work/calibre/src/calibre/library/database2.py:383 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3262 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3271 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:187 msgid "News" msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2769 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3218 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3236 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3227 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3245 msgid "Catalog" msgstr "" @@ -1111,8 +1092,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:264 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:268 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:324 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:857 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:859 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:885 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:887 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:277 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:279 msgid "Transferring books to device..." @@ -1122,8 +1103,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:344 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:480 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:515 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:870 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:881 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:898 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:909 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:301 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:332 msgid "Adding books to device metadata listing..." @@ -1145,8 +1126,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:374 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:468 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:475 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:901 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:907 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:929 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:935 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:366 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:371 msgid "Removing books from device metadata listing..." @@ -1173,7 +1154,6 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/blackberry/driver.py:37 #: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:281 #: /home/kovid/work/calibre/src/calibre/devices/nuut2/driver.py:18 -#: /home/kovid/work/calibre/src/calibre/devices/prs500/driver.py:90 msgid "Kovid Goyal" msgstr "" @@ -1611,10 +1591,6 @@ msgstr "" msgid "Communicate with the Nuut2 eBook reader." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/prs500/driver.py:89 -msgid "Communicate with the Sony PRS-500 eBook reader." -msgstr "" - #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:22 msgid "Communicate with Sony eBook readers older than the PRST1." msgstr "" @@ -1624,23 +1600,23 @@ msgid "Comments have been removed as the SONY reader chokes on them" msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:66 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:114 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:133 msgid "All by title" msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:67 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:115 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:134 msgid "All by author" msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:70 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:68 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:132 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:151 msgid "Comma separated list of metadata fields to turn into collections on the device. Possibilities include: " msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:73 -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:135 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:154 #, python-format msgid ". Two special collections are available: %(abt)s:%(abtv)s and %(aba)s:%(abav)s. Add these values to the list to enable them. The collections will be given the name provided after the \":\" character." msgstr "" @@ -1709,84 +1685,84 @@ msgstr "" msgid "Set this option if you want the author on the Sony to appear the same way the T1 sets it. This means it will only show the first author for books with multiple authors. Leave this disabled if you use Metadata Plugboards." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:54 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:62 msgid "SmartDevice" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:56 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:64 msgid "Communicate with Smart Device apps" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:118 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:137 msgid "Enable connections at startup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:119 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:138 msgid "Check this box to allow connections when calibre starts" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:121 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:140 msgid "Security password" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:122 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:141 msgid "Enter a password that the device app must use to connect to calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:124 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:143 msgid "Use fixed network port" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:125 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:144 msgid "If checked, use the port number in the \"Port\" box, otherwise the driver will pick a random port" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:127 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:146 msgid "Port number: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:128 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:147 msgid "Enter the port number the driver is to use if the \"fixed port\" box is checked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:129 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:148 msgid "Print extra debug information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:130 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:149 msgid "Check this box if requested when reporting problems" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:140 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:159 msgid "Enable the no-activity timeout" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:141 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:160 #, python-format msgid "If this box is checked, calibre will automatically disconnect if a connected device does nothing for %d minutes. Unchecking this box disables this timeout, so calibre will never automatically disconnect." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:591 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:616 #, python-format msgid "Too many connection attempts from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:705 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:733 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:95 msgid "Get device information..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:976 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1013 #, python-format msgid "Invalid port in options: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:986 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1021 #, python-format msgid "Failed to connect to port %d. Try a different value." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:999 +#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1033 msgid "Failed to allocate a random port" msgstr "" @@ -2435,6 +2411,27 @@ msgstr "" msgid "Preserve the aspect ratio of the cover, instead of stretching it to fill the full first page of the generated pdf." msgstr "" +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:93 +msgid "The font family used to render serif fonts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:96 +msgid "The font family used to render sans-serif fonts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:99 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:103 +msgid "The font family used to render monospaced fonts" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:106 +msgid "The default font size" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:109 +msgid "The default font size for monospaced text" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pml_output.py:22 msgid "Specify the character encoding of the output document. The default is cp1252." msgstr "" @@ -2660,261 +2657,265 @@ msgid "Specify how to mark detected chapters. A value of \"pagebreak\" will inse msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:309 +msgid "An XPath expression to detect the location in the document at which to start reading. Some ebook reading programs (most prominently the Kindle) use this location as the position at which to open the book. See the XPath tutorial in the calibre User Manual for further help using this feature." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:319 msgid "Either the path to a CSS stylesheet or raw CSS. This CSS will be appended to the style rules from the source file, so it can be used to override those rules." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:317 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:327 msgid "A comma separated list of CSS properties that will be removed from all CSS style rules. This is useful if the presence of some style information prevents it from being overridden on your device. For example: font-family,color,margin-left,margin-right" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:328 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:338 msgid "An XPath expression. Page breaks are inserted before the specified elements. To disable use the expression: /" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:334 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:344 msgid "Some documents specify page margins by specifying a left and right margin on each individual paragraph. calibre will try to detect and remove these margins. Sometimes, this can cause the removal of margins that should not have been removed. In this case you can disable the removal." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:345 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:355 #, python-format msgid "Set the top margin in pts. Default is %default. Setting this to less than zero will cause no margin to be set. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:351 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:361 #, python-format msgid "Set the bottom margin in pts. Default is %default. Setting this to less than zero will cause no margin to be set. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:357 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:367 #, python-format msgid "Set the left margin in pts. Default is %default. Setting this to less than zero will cause no margin to be set. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:363 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:373 #, python-format msgid "Set the right margin in pts. Default is %default. Setting this to less than zero will cause no margin to be set. Note: 72 pts equals 1 inch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:370 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:380 msgid "Change text justification. A value of \"left\" converts all justified text in the source to left aligned (i.e. unjustified) text. A value of \"justify\" converts all unjustified text to justified. A value of \"original\" (the default) does not change justification in the source file. Note that only some output formats support justification." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:380 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:390 msgid "Remove spacing between paragraphs. Also sets an indent on paragraphs of 1.5em. Spacing removal will not work if the source file does not use paragraphs (

or

tags)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:387 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:397 msgid "When calibre removes blank lines between paragraphs, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent (in em). If you set this value negative, then the indent specified in the input document is used, that is, calibre does not change the indentation." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:396 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:406 msgid "Use the cover detected from the source file in preference to the specified cover." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:402 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:412 msgid "Insert a blank line between paragraphs. Will not work if the source file does not use paragraphs (

or

tags)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:409 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:419 msgid "Set the height of the inserted blank lines (in em). The height of the lines between paragraphs will be twice the value set here." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:416 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:426 msgid "Remove the first image from the input ebook. Useful if the input document has a cover image that is not identified as a cover. In this case, if you set a cover in calibre, the output document will end up with two cover images if you do not specify this option." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:425 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:435 msgid "Insert the book metadata at the start of the book. This is useful if your ebook reader does not support displaying/searching metadata directly." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:433 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:443 msgid "Convert plain quotes, dashes and ellipsis to their typographically correct equivalents. For details, see http://daringfireball.net/projects/smartypants" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:441 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:451 msgid "Convert fancy quotes, dashes and ellipsis to their plain equivalents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:449 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:459 msgid "Read metadata from the specified OPF file. Metadata read from this file will override any metadata in the source file." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:456 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:466 #, python-format msgid "Transliterate unicode characters to an ASCII representation. Use with care because this will replace unicode characters with ASCII. For instance it will replace \"%s\" with \"Mikhail Gorbachiov\". Also, note that in cases where there are multiple representations of a character (characters shared by Chinese and Japanese for instance) the representation based on the current calibre interface language will be used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:471 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:481 msgid "Preserve ligatures present in the input document. A ligature is a special rendering of a pair of characters like ff, fi, fl et cetera. Most readers do not have support for ligatures in their default fonts, so they are unlikely to render correctly. By default, calibre will turn a ligature into the corresponding pair of normal characters. This option will preserve them instead." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:483 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:493 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:38 msgid "Set the title." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:487 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:497 msgid "Set the authors. Multiple authors should be separated by ampersands." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:492 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:502 msgid "The version of the title to be used for sorting. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:496 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:506 msgid "String to be used when sorting by author. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:500 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:510 msgid "Set the cover to the specified file or URL" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:504 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:514 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:54 msgid "Set the ebook description." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:508 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:518 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:56 msgid "Set the ebook publisher." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:512 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:522 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:60 msgid "Set the series this ebook belongs to." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:516 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:526 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:62 msgid "Set the index of the book in this series." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:520 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:530 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:64 msgid "Set the rating. Should be a number between 1 and 5." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:524 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:534 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:66 msgid "Set the ISBN of the book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:528 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:538 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:68 msgid "Set the tags for the book. Should be a comma separated list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:532 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:542 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:70 msgid "Set the book producer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:536 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:546 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/cli.py:72 msgid "Set the language." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:540 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:550 msgid "Set the publication date." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:544 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:554 msgid "Set the book timestamp (no longer used anywhere)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:548 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:558 msgid "Enable heuristic processing. This option must be set for any heuristic processing to take place." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:553 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:563 msgid "Detect unformatted chapter headings and sub headings. Change them to h2 and h3 tags. This setting will not create a TOC, but can be used in conjunction with structure detection to create one." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:560 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:570 msgid "Look for common words and patterns that denote italics and italicize them." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:565 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:575 msgid "Turn indentation created from multiple non-breaking space entities into CSS indents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:570 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:580 msgid "Scale used to determine the length at which a line should be unwrapped. Valid values are a decimal between 0 and 1. The default is 0.4, just below the median line length. If only a few lines in the document require unwrapping this value should be reduced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:578 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:588 msgid "Unwrap lines using punctuation and other formatting clues." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:582 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:592 msgid "Remove empty paragraphs from the document when they exist between every other paragraph" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:587 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:597 msgid "Left aligned scene break markers are center aligned. Replace soft scene breaks that use multiple blank lines with horizontal rules." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:593 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:603 msgid "Replace scene breaks with the specified text. By default, the text from the input document is used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:598 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:608 msgid "Analyze hyphenated words throughout the document. The document itself is used as a dictionary to determine whether hyphens should be retained or removed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:604 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:614 msgid "Looks for occurrences of sequential

or

tags. The tags are renumbered to prevent splitting in the middle of chapter headings." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:610 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:620 msgid "Search pattern (regular expression) to be replaced with sr1-replace." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:615 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:625 msgid "Replacement to replace the text found with sr1-search." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:619 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:629 msgid "Search pattern (regular expression) to be replaced with sr2-replace." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:624 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:634 msgid "Replacement to replace the text found with sr2-search." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:628 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:638 msgid "Search pattern (regular expression) to be replaced with sr3-replace." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:633 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:643 msgid "Replacement to replace the text found with sr3-search." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:637 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:647 msgid "Path to a file containing search and replace regular expressions. The file must contain alternating lines of regular expression followed by replacement pattern (which can be an empty line). The regular expression must be in the python regex syntax and the file must be UTF-8 encoded." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:746 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:756 msgid "Could not find an ebook inside the archive" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:804 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:814 msgid "Values of series index and rating must be numbers. Ignoring" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:811 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:821 msgid "Failed to parse date/time" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:973 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:983 msgid "Converting input to HTML..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1000 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1010 msgid "Running transforms on ebook..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1113 +#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plumber.py:1123 msgid "Creating" msgstr "" @@ -3114,11 +3115,11 @@ msgstr "" msgid "Convert LRS to LRS, useful for debugging." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:457 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:485 msgid "Invalid LRF file. Could not set metadata." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:582 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:610 msgid "" "%prog [options] mybook.lrf\n" "\n" @@ -3127,59 +3128,59 @@ msgid "" "\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:589 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:617 msgid "Set the book title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:591 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:619 msgid "Set sort key for the title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:593 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:621 msgid "Set the author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:595 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:623 msgid "Set sort key for the author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:597 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:625 msgid "The category this book belongs to. E.g.: History" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:628 msgid "Path to a graphic that will be set as this files' thumbnail" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:603 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:631 msgid "Path to a txt file containing the comment to be stored in the lrf file." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:607 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:635 msgid "Extract thumbnail from LRF file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:608 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:636 msgid "Set the publisher" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:609 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:637 msgid "Set the book classification" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:610 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:638 msgid "Set the book creator" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:611 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:639 msgid "Set the book producer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:613 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:641 msgid "Extract cover from LRF file. Note that the LRF format has no defined cover, so we use some heuristics to guess the cover." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:615 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:643 msgid "Set book ID" msgstr "" @@ -3202,7 +3203,6 @@ msgid "No" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:769 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:45 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/quickview.py:85 #: /home/kovid/work/calibre/src/calibre/gui2/library/models.py:58 @@ -3231,7 +3231,6 @@ msgid "Publisher" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:772 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:49 msgid "Producer" msgstr "" @@ -3636,182 +3635,10 @@ msgstr "" msgid "Sidebar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/cli.py:31 -msgid "" -"command ...\n" -"\n" -"command can be one of the following:\n" -"[%%commands]\n" -"\n" -"Use %prog command --help to get more information about a specific command\n" -"\n" -"Manipulate a PDF.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:29 -msgid "" -"[options] file.pdf\n" -"\n" -"Crop a PDF file.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:38 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/decrypt.py:32 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/encrypt.py:34 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/merge.py:36 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/reverse.py:34 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:33 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:41 -msgid "Path to output file. By default a file is created in the current directory." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:41 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/outline_writer.py:49 +#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/outline_writer.py:57 #, python-format -msgid "Number of pixels to crop from the left most x (default is %s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:44 -#, python-format -msgid "Number of pixels to crop from the left most y (default is %s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:47 -#, python-format -msgid "Number of pixels to crop from the right most x (default is %s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:50 -#, python-format -msgid "Number of pixels to crop from the right most y (default is %s)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:53 -msgid "A file generated by ghostscript which allows each page to be individually cropped `gs -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox file.pdf 2> bounding`" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:73 -msgid "Crop Options:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/crop.py:73 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/decrypt.py:60 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/encrypt.py:54 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/merge.py:56 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/reverse.py:54 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:53 -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:61 -msgid "Options to control the transformation of pdf" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/decrypt.py:23 -msgid "" -"[options] file.pdf password\n" -"\n" -"Decrypt a PDF.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/decrypt.py:60 -msgid "Decrypt Options:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/encrypt.py:25 -msgid "" -"[options] file.pdf password\n" -"\n" -"Encrypt a PDF.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/encrypt.py:54 -msgid "Encrypt Options:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:21 -msgid "" -"file.pdf ...\n" -"\n" -"Get info about a PDF.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:46 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:49 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:305 -msgid "Author" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:47 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:27 -msgid "Subject" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:48 -msgid "Creator" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:50 -msgid "Pages" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:51 -msgid "File Size" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/info.py:52 -msgid "PDF Version" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/merge.py:25 -msgid "" -"[options] file1.pdf file2.pdf ...\n" -"\n" -"Metadata will be used from the first PDF specified.\n" -"\n" -"Merges individual PDFs.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/merge.py:56 -msgid "Merge Options:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/reverse.py:25 -msgid "" -"[options] file.pdf\n" -"\n" -"Reverse a PDF.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/reverse.py:54 -msgid "Reverse Options:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:24 -msgid "" -"file.pdf degrees\n" -"\n" -"Rotate pages of a PDF clockwise.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/rotate.py:53 -msgid "Rotate Options:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:25 -msgid "" -"\n" -"%prog %%name [options] file.pdf page_to_split_on ...\n" -"%prog %%name [options] file.pdf page_range_to_split_on ...\n" -"\t\n" -"Ex.\n" -"\t\n" -"%prog %%name file.pdf 6\n" -"%prog %%name file.pdf 6-12\n" -"%prog %%name file.pdf 6-12 8 10 9-20\n" -"\n" -"Split a PDF.\n" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/manipulate/split.py:61 -msgid "Split Options:" +msgid "Page %d" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftohtml.py:71 @@ -4766,6 +4593,10 @@ msgstr "" msgid "Do you want wireless device connections to be started automatically when calibre starts?" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:245 +msgid "Many IP addresses. See Start/Stop dialog." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_collections.py:13 msgid "Manage collections" msgstr "" @@ -5761,12 +5592,12 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdb_input_ui.py:36 #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdb_output_ui.py:47 #: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_input_ui.py:43 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:96 #: /home/kovid/work/calibre/src/calibre/gui2/convert/pmlz_output_ui.py:46 #: /home/kovid/work/calibre/src/calibre/gui2/convert/rb_output_ui.py:33 #: /home/kovid/work/calibre/src/calibre/gui2/convert/search_and_replace_ui.py:145 #: /home/kovid/work/calibre/src/calibre/gui2/convert/snb_output_ui.py:42 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:62 #: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:70 #: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_input_ui.py:91 #: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output_ui.py:87 @@ -6187,19 +6018,23 @@ msgstr "" msgid "Choose background color" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:209 msgid "Create link" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:195 -msgid "Enter URL" +#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:215 +msgid "Enter &URL:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:216 +msgid "Enter name (optional):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:577 msgid "Normal view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:555 +#: /home/kovid/work/calibre/src/calibre/gui2/comments_editor.py:578 msgid "HTML Source" msgstr "" @@ -7011,20 +6846,60 @@ msgstr "" msgid "PDF Output" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:55 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:97 msgid "&Paper Size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:56 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:98 msgid "&Orientation:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:99 +msgid "&Custom size:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:100 msgid "Preserve &aspect ratio of cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:58 -msgid "&Custom size:" +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:101 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:362 +msgid "Se&rif family:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:102 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:363 +msgid "&Sans family:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:364 +msgid "&Monospace family:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:369 +msgid "S&tandard font:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:105 +msgid "Default font si&ze:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:368 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:383 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:385 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:387 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:391 +msgid " px" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:367 +msgid "Monospace &font size:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pml_output.py:14 @@ -7307,35 +7182,39 @@ msgstr "" msgid "Insert page breaks before (XPath expression):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection.py:35 +msgid "Start reading at (XPath expression):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection.py:44 #: /home/kovid/work/calibre/src/calibre/gui2/convert/toc.py:39 msgid "Invalid XPath" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection.py:43 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection.py:45 #: /home/kovid/work/calibre/src/calibre/gui2/convert/toc.py:40 #, python-format msgid "The XPath expression %s is invalid." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:60 -msgid "Chapter &mark:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:61 -msgid "Remove first &image" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:62 -msgid "Insert &metadata as page at start of book" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:63 -msgid "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." +msgid "Remove &fake margins" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:64 -msgid "Remove &fake margins" +msgid "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." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:65 +msgid "Insert &metadata as page at start of book" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:66 +msgid "Chapter &mark:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:67 +msgid "Remove first &image" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/toc.py:16 @@ -8329,6 +8208,12 @@ msgstr "" msgid "All checked books will be permanently deleted from your device. Please verify the list." msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/edit_authors_dialog.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:305 +msgid "Author" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 msgid "Location" msgstr "" @@ -9112,7 +8997,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:65 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:213 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:92 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server_ui.py:148 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/send_email.py:81 msgid "&Show password" @@ -9959,79 +9844,104 @@ msgstr "" msgid "Choose formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:21 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:46 msgid "Use a password if calibre is running on a network that is not secure. For example, if you run calibre on a laptop, use that laptop in an airport, and want to connect your smart device to calibre, you should use a password." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:27 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:52 msgid "Check this box if you want calibre to automatically start the smart device interface when calibre starts. You should not do this if you are using a network that is not secure and you are not setting a password." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:33 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:58 msgid "Check this box if you want calibre to use a fixed network port. Normally you will not need to do this. However, if your device consistently fails to connect to calibre, try checking this box and entering a number." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:64 msgid "Try 9090. If calibre says that it fails to connect to the port, try another number. You can use any number between 8,000 and 32,000." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:79 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:85 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:70 +msgid "These are the IP addresses for this computer. If you decide to have your device connect to calibre using a fixed IP address, one of these addresses should be the one you use. It is unlikely but possible that the correct IP address is not listed here, in which case you will need to go to your computer's control panel to get a complete list of your computer's network interfaces and IP addresses." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:101 +msgid "Enable automatic metadata management" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:104 +msgid "Enabling automatic metadata management tells calibre to send any changes you made to books' metadata when your device is connected, which is the most useful setting when using the wireless device interface. If automatic metadata management is not enabled, changes are sent only when you re-send the book. You can get more information or change this preference to some other choice at Preferences -> Sending books to devices -> Metadata management" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:123 +msgid "Automatic metadata management is enabled" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:137 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:148 msgid "Invalid port number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:138 msgid "You must provide a port number." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:86 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:144 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:149 msgid "The port must be a number between 8000 and 32000." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:164 #: /home/kovid/work/calibre/src/calibre/gui2/ui.py:394 msgid "Problem starting the wireless device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice.py:165 #: /home/kovid/work/calibre/src/calibre/gui2/ui.py:395 #, python-format msgid "The wireless device driver did not start. It said \"%s\"" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:78 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:85 msgid "Smart device control" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:79 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:86 msgid "" "

Start wireless device connections.\n" "

You may see some messages from your computer's firewall or anti-virus manager asking you if it is OK for calibre to connect to the network. Please answer yes. If you do not, wireless connections will not work." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:81 -msgid "Optional password for security" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:88 +msgid "Calibre IP addresses:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:89 +msgid "Possibe IP addresses:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:90 msgid "Optional &password:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:84 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:91 +msgid "Optional password for security" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:93 msgid "Optional &fixed port:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:85 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:94 msgid "Optional port number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:86 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:95 msgid "&Use a fixed port" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/smartdevice_ui.py:96 msgid "&Automatically allow connections at calibre startup" msgstr "" @@ -11104,12 +11014,12 @@ msgid "LRF Viewer toolbar" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:131 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:521 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:514 msgid "Next Page" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/main_ui.py:132 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:515 msgid "Previous Page" msgstr "" @@ -12668,6 +12578,10 @@ msgstr "" msgid "Email" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:27 +msgid "Subject" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:32 msgid "Formats to email. The first matching format will be sent." msgstr "" @@ -12680,7 +12594,7 @@ msgstr "" msgid "If checked, downloaded news will be automatically mailed
to this email address (provided it is in one of the listed formats)." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/emailp.py:117 msgid "new email address" msgstr "" @@ -15082,39 +14996,10 @@ msgstr "" msgid "Configure Ebook viewer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:362 -msgid "Se&rif family:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:363 -msgid "&Sans family:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:364 -msgid "&Monospace family:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:365 msgid "&Default font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:366 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:368 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:383 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:385 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:387 -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:391 -msgid " px" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:367 -msgid "Monospace &font size:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:369 -msgid "S&tandard font:" -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:370 msgid "Serif" msgstr "" @@ -15303,44 +15188,44 @@ msgstr "" msgid "No results found for:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:487 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:480 msgid "&Lookup in dictionary" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:492 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:485 msgid "View &image..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:495 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:488 msgid "&Search for next occurrence" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:500 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:493 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:138 msgid "Go to..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:505 msgid "Next Section" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:506 msgid "Previous Section" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:515 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:508 msgid "Document Start" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:509 msgid "Document End" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:511 msgid "Section Start" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:519 +#: /home/kovid/work/calibre/src/calibre/gui2/viewer/documentview.py:512 msgid "Section End" msgstr "" @@ -16938,17 +16823,17 @@ msgstr "" msgid "creating custom column " msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3570 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3579 #, python-format msgid "

Migrating old database to ebook library in %s

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3599 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3608 #, python-format msgid "Copying %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:3616 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:3625 msgid "Compacting database" msgstr "" From 47dd9752f335908b147b8d93d4975e560056553c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 31 Aug 2012 11:28:02 +0530 Subject: [PATCH 08/10] ... --- setup/translations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/translations.py b/setup/translations.py index 28be777345..3f821b7556 100644 --- a/setup/translations.py +++ b/setup/translations.py @@ -152,7 +152,7 @@ class Translations(POT): # {{{ subprocess.check_call(['msgfmt', '-o', dest, iso639]) elif locale not in ('en_GB', 'en_CA', 'en_AU', 'si', 'ur', 'sc', 'ltg', 'nds', 'te', 'yi', 'fo', 'sq', 'ast', 'ml', 'ku', - 'fr_CA', 'him'): + 'fr_CA', 'him', 'jv', 'ka'): self.warn('No ISO 639 translations for locale:', locale) self.write_stats() From 6627f20c2cd4b628954adbb05ce52ee161c8e4f0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 31 Aug 2012 11:56:47 +0530 Subject: [PATCH 09/10] MTP: Implement get_device_information() --- src/calibre/devices/mtp/base.py | 3 +- src/calibre/devices/mtp/driver.py | 76 ++++++++++++++++++++- src/calibre/devices/mtp/filesystem_cache.py | 28 ++++++++ src/calibre/devices/mtp/unix/driver.py | 20 +----- src/calibre/devices/mtp/windows/driver.py | 16 +---- src/calibre/devices/usbms/driver.py | 2 +- 6 files changed, 109 insertions(+), 36 deletions(-) diff --git a/src/calibre/devices/mtp/base.py b/src/calibre/devices/mtp/base.py index 3e7dc63f87..4f8bbc991f 100644 --- a/src/calibre/devices/mtp/base.py +++ b/src/calibre/devices/mtp/base.py @@ -35,13 +35,14 @@ class MTPDeviceBase(DevicePlugin): DevicePlugin.__init__(self, *args, **kwargs) self.progress_reporter = None self.current_friendly_name = None + self.report_progress = lambda x, y: None def reset(self, key='-1', log_packets=False, report_progress=None, detected_device=None): pass def set_progress_reporter(self, report_progress): - self.progress_reporter = report_progress + self.report_progress = report_progress def get_gui_name(self): return self.current_friendly_name or self.name diff --git a/src/calibre/devices/mtp/driver.py b/src/calibre/devices/mtp/driver.py index 54827d234a..53a1fe36db 100644 --- a/src/calibre/devices/mtp/driver.py +++ b/src/calibre/devices/mtp/driver.py @@ -7,14 +7,86 @@ __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' -from calibre.constants import iswindows +import json, pprint +from io import BytesIO + +from calibre.constants import iswindows, numeric_version +from calibre.utils.config import from_json, to_json +from calibre.utils.date import now, isoformat if iswindows: from calibre.devices.mtp.windows.driver import MTP_DEVICE as BASE BASE else: from calibre.devices.mtp.unix.driver import MTP_DEVICE as BASE +pprint class MTP_DEVICE(BASE): - pass + + METADATA_CACHE = 'metadata.calibre' + DRIVEINFO = 'driveinfo.calibre' + + def _update_drive_info(self, storage, location_code, name=None): + import uuid + f = storage.find_path((self.DRIVEINFO,)) + dinfo = {} + if f is not None: + stream = self.get_file(f) + try: + dinfo = json.load(stream, object_hook=from_json) + except: + dinfo = None + if dinfo.get('device_store_uuid', None) is None: + dinfo['device_store_uuid'] = unicode(uuid.uuid4()) + if dinfo.get('device_name', None) is None: + dinfo['device_name'] = self.current_friendly_name + if name is not None: + dinfo['device_name'] = name + dinfo['location_code'] = location_code + dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None) + dinfo['calibre_version'] = '.'.join([unicode(i) for i in numeric_version]) + dinfo['date_last_connected'] = isoformat(now()) + dinfo['mtp_prefix'] = storage.storage_prefix + raw = json.dumps(dinfo, default=to_json) + self.put_file(storage, self.DRIVEINFO, BytesIO(raw), len(raw)) + self.driveinfo = dinfo + + def open(self, devices, library_uuid): + self.current_library_uuid = library_uuid + BASE.open(self, devices, library_uuid) + + def get_device_information(self, end_session=True): + self.report_progress(1.0, _('Get device information...')) + self.driveinfo = {} + for sid, location_code in ( (self._main_id, 'main'), (self._carda_id, + 'A'), (self._cardb_id, 'B')): + if sid is None: continue + self._update_drive_info(self.filesystem_cache.storage(sid), location_code) + dinfo = self.get_basic_device_information() + return tuple( list(dinfo) + [self.driveinfo] ) + + def card_prefix(self, end_session=True): + ans = [None, None] + if self._carda_id is not None: + ans[0] = self.filesystem_cache.storage(self._carda_id).storage_prefix + if self._cardb_id is not None: + ans[1] = self.filesystem_cache.storage(self._cardb_id).storage_prefix + return tuple(ans) + +if __name__ == '__main__': + dev = MTP_DEVICE(None) + dev.startup() + try: + from calibre.devices.scanner import DeviceScanner + scanner = DeviceScanner() + scanner.scan() + devs = scanner.devices + cd = dev.detect_managed_devices(devs) + if cd is None: + raise ValueError('Failed to detect MTP device') + dev.open(cd, None) + pprint.pprint(dev.get_device_information()) + finally: + dev.shutdown() + diff --git a/src/calibre/devices/mtp/filesystem_cache.py b/src/calibre/devices/mtp/filesystem_cache.py index 3370967054..cd97c5c2ed 100644 --- a/src/calibre/devices/mtp/filesystem_cache.py +++ b/src/calibre/devices/mtp/filesystem_cache.py @@ -47,6 +47,9 @@ class FileOrFolder(object): self.fs_cache = weakref.ref(fs_cache) self.deleted = False + if self.storage_id == self.object_id: + self.storage_prefix = 'mtp:::%s:::'%self.persistent_id + def __repr__(self): name = 'Folder' if self.is_folder else 'File' try: @@ -125,6 +128,26 @@ class FileOrFolder(object): return e return None + def find_path(self, path): + ''' + Find a path in this folder, where path is a + tuple of folder and file names like ('eBooks', 'newest', + 'calibre.epub'). Finding is case-insensitive. + ''' + parent = self + components = list(path) + while components: + child = components[0] + components = components[1:] + c = parent.folder_named(child) + if c is None: + c = parent.file_named(child) + if c is None: + return None + parent = c + return parent + + class FilesystemCache(object): def __init__(self, all_storage, entries): @@ -164,4 +187,9 @@ class FilesystemCache(object): for e in self.entries: e.dump(out=out) + def storage(self, storage_id): + for e in self.entries: + if e.storage_id == storage_id: + return e + diff --git a/src/calibre/devices/mtp/unix/driver.py b/src/calibre/devices/mtp/unix/driver.py index e179647629..5d7d767a9b 100644 --- a/src/calibre/devices/mtp/unix/driver.py +++ b/src/calibre/devices/mtp/unix/driver.py @@ -46,14 +46,6 @@ class MTP_DEVICE(MTPDeviceBase): def set_debug_level(self, lvl): self.libmtp.set_debug_level(lvl) - def report_progress(self, sent, total): - try: - p = int(sent/total * 100) - except ZeroDivisionError: - p = 100 - if self.progress_reporter is not None: - self.progress_reporter(p) - @synchronous def detect_managed_devices(self, devices_on_system, force_refresh=False): if self.libmtp is None: return None @@ -212,19 +204,10 @@ class MTP_DEVICE(MTPDeviceBase): return self._filesystem_cache @synchronous - def get_device_information(self, end_session=True): + def get_basic_device_information(self): d = self.dev return (self.current_friendly_name, d.device_version, d.device_version, '') - @synchronous - def card_prefix(self, end_session=True): - ans = [None, None] - if self._carda_id is not None: - ans[0] = 'mtp:::%d:::'%self._carda_id - if self._cardb_id is not None: - ans[1] = 'mtp:::%d:::'%self._cardb_id - return tuple(ans) - @synchronous def total_space(self, end_session=True): ans = [0, 0, 0] @@ -298,6 +281,7 @@ class MTP_DEVICE(MTPDeviceBase): if not ok: raise DeviceError('Failed to get file: %s with errors: %s'%( f.full_path, self.format_errorstack(errs))) + stream.seek(0) return stream @synchronous diff --git a/src/calibre/devices/mtp/windows/driver.py b/src/calibre/devices/mtp/windows/driver.py index 63eef1df66..0506f63054 100644 --- a/src/calibre/devices/mtp/windows/driver.py +++ b/src/calibre/devices/mtp/windows/driver.py @@ -203,24 +203,11 @@ class MTP_DEVICE(MTPDeviceBase): self.current_friendly_name = devdata.get('friendly_name', None) @same_thread - def get_device_information(self, end_session=True): + def get_basic_device_information(self): d = self.dev.data dv = d.get('device_version', '') - for sid, location_code in ( (self._main_id, 'main'), (self._carda_id, - 'A'), (self._cardb_id, 'B')): - if sid is None: continue - # TODO: Implement the drive info dict return (self.current_friendly_name, dv, dv, '') - @same_thread - def card_prefix(self, end_session=True): - ans = [None, None] - if self._carda_id is not None: - ans[0] = 'mtp:::%s:::'%self._carda_id - if self._cardb_id is not None: - ans[1] = 'mtp:::%s:::'%self._cardb_id - return tuple(ans) - @same_thread def total_space(self, end_session=True): ans = [0, 0, 0] @@ -260,6 +247,7 @@ class MTP_DEVICE(MTPDeviceBase): except Exception as e: raise DeviceError('Failed to fetch the file %s with error: %s'% f.full_path, as_unicode(e)) + stream.seek(0) return stream @same_thread diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index b86d61182d..12e30073ac 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -63,7 +63,7 @@ class USBMS(CLI, Device): dinfo = {} if dinfo.get('device_store_uuid', None) is None: dinfo['device_store_uuid'] = unicode(uuid.uuid4()) - if dinfo.get('device_name') is None: + if dinfo.get('device_name', None) is None: dinfo['device_name'] = self.get_gui_name() if name is not None: dinfo['device_name'] = name From 8d881f9f7f647849cd013d775a4f81728a52739e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 31 Aug 2012 12:00:50 +0530 Subject: [PATCH 10/10] ... --- src/calibre/devices/mtp/driver.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/calibre/devices/mtp/driver.py b/src/calibre/devices/mtp/driver.py index 53a1fe36db..c3e34a2be5 100644 --- a/src/calibre/devices/mtp/driver.py +++ b/src/calibre/devices/mtp/driver.py @@ -73,6 +73,14 @@ class MTP_DEVICE(BASE): ans[1] = self.filesystem_cache.storage(self._cardb_id).storage_prefix return tuple(ans) + def set_driveinfo_name(self, location_code, name): + sid = {'main':self._main_id, 'A':self._carda_id, + 'B':self._cardb_id}.get(location_code, None) + if sid is None: + return + self._update_drive_info(self.filesystem_cache.storage(sid), + location_code, name=name) + if __name__ == '__main__': dev = MTP_DEVICE(None) dev.startup()