From f65418b92f0a7484b05a096ce0144f2f82eadf0f Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 7 Feb 2009 15:49:45 -0500 Subject: [PATCH 01/24] Ignore unparsable CSS in @style attributes. --- src/calibre/ebooks/oeb/stylizer.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/calibre/ebooks/oeb/stylizer.py b/src/calibre/ebooks/oeb/stylizer.py index e4a0cfd7fe..574d57f5fb 100644 --- a/src/calibre/ebooks/oeb/stylizer.py +++ b/src/calibre/ebooks/oeb/stylizer.py @@ -17,6 +17,7 @@ import types import re import copy from itertools import izip +from xml.dom import SyntaxErr as CSSSyntaxError import cssutils from cssutils.css import CSSStyleRule, CSSPageRule, CSSStyleDeclaration, \ CSSValueList, cssproperties @@ -288,15 +289,19 @@ class Style(object): def _update_cssdict(self, cssdict): self._style.update(cssdict) - + def _apply_style_attr(self): attrib = self._element.attrib - if 'style' in attrib: - css = attrib['style'].split(';') - css = filter(None, map(lambda x: x.strip(), css)) + if 'style' not in attrib: + return + css = attrib['style'].split(';') + css = filter(None, (x.strip() for x in css)) + try: style = CSSStyleDeclaration('; '.join(css)) - self._style.update(self._stylizer.flatten_style(style)) - + except CSSSyntaxError: + return + self._style.update(self._stylizer.flatten_style(style)) + def _has_parent(self): return (self._element.getparent() is not None) From 1013b69ab4d33979f6515a257355b59f83a751a1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Feb 2009 13:05:35 -0800 Subject: [PATCH 02/24] Fix #1794 (recipes language) and add new recipes for The Honolulu Advertiser and The Star Bulletin by Darko Miletic --- src/calibre/gui2/images/news/starbulletin.png | Bin 0 -> 983 bytes src/calibre/web/feeds/recipes/__init__.py | 3 +- src/calibre/web/feeds/recipes/recipe_blic.py | 1 + src/calibre/web/feeds/recipes/recipe_danas.py | 1 + .../web/feeds/recipes/recipe_de_standaard.py | 2 +- .../web/feeds/recipes/recipe_demorgen_be.py | 1 + .../web/feeds/recipes/recipe_estadao.py | 2 +- .../recipes/recipe_honoluluadvertiser.py | 58 ++++++++++++++++++ .../web/feeds/recipes/recipe_jb_online.py | 2 +- src/calibre/web/feeds/recipes/recipe_nin.py | 1 + .../web/feeds/recipes/recipe_novosti.py | 1 + .../web/feeds/recipes/recipe_o_globo.py | 2 +- .../web/feeds/recipes/recipe_pescanik.py | 1 + .../recipes/recipe_st_petersburg_times.py | 4 +- .../web/feeds/recipes/recipe_starbulletin.py | 58 ++++++++++++++++++ .../web/feeds/recipes/recipe_vijesti.py | 1 + src/calibre/web/feeds/recipes/recipe_vreme.py | 1 + 17 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 src/calibre/gui2/images/news/starbulletin.png create mode 100644 src/calibre/web/feeds/recipes/recipe_honoluluadvertiser.py create mode 100644 src/calibre/web/feeds/recipes/recipe_starbulletin.py diff --git a/src/calibre/gui2/images/news/starbulletin.png b/src/calibre/gui2/images/news/starbulletin.png new file mode 100644 index 0000000000000000000000000000000000000000..bb3afd636a2e2d0b5a515702cfdabba4c64abdf4 GIT binary patch literal 983 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI zAngIhZYQ(tK!Rljj_E*J0gT&!&6&%ahPrwy zM0{iTH}AgbJ2}T^<4>m5o`Up@Jg&H3cE9mS7@cfEVVaYN`^U-}D1_oz8H zp5ClF@bP%Gx_|`xi!WK*{SQnO^Eko0_Vl3~8-WK$^!(Sht>kEVC;qR6VfV_ra*clL z*#!At_{?Vy7F;oB`&DsH%exAjXU#nIBZMV~v(IH`yhGW>gP$r5|GbZ%xa_r`oIRub zzGIWumPRfpy{_8L)vVhsEPcJvB$L-YD&p!6MTeu2F3;HOf8U6>_~Ofgp!~-k-FrUl zJu>01-6z!x-fAlsNXy9{{M|3c=XKlfNH#Tyz3S?`I7DS z>{G8-Mp(bw^+xvhuD*(ck~Se^mdt;*2B5?yO_hDmo)eK^4jiF zw~b3Y$x_-}P#+QyI#a#swYp7Xj(C+XqRA?bV8-yM2@Zi2H6*{+9qv~sIObZ{v=UYWros=8ZF80 zY}S&6Ms@#Z3bq}c_~G*#@ta54?!Q;vFL+G&#V(mS=O&APsorO>UVPe?WAFM-URGbl zB{%0>dw$yzgC5lY>+FVx-m?>0CTq8=7i&7IyQgu^+1cQ-*fu*j2k* Date: Sat, 7 Feb 2009 13:28:50 -0800 Subject: [PATCH 03/24] IGN:Downloaded news HTML files are now always saved with the .xhtml extension --- src/calibre/__init__.py | 2 +- src/calibre/web/fetch/simple.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 7315deca40..360947de2a 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -19,7 +19,7 @@ import mechanize mimetypes.add_type('application/epub+zip', '.epub') mimetypes.add_type('text/x-sony-bbeb+xml', '.lrs') -mimetypes.add_type('http://www.w3.org/1999/xhtml', '.xhtml') +mimetypes.add_type('application/xhtml+xml', '.xhtml') mimetypes.add_type('image/svg+xml', '.svg') mimetypes.add_type('application/x-sony-bbeb', '.lrf') mimetypes.add_type('application/x-dtbncx+xml', '.ncx') diff --git a/src/calibre/web/fetch/simple.py b/src/calibre/web/fetch/simple.py index 0d073ecce7..f846c7f2e5 100644 --- a/src/calibre/web/fetch/simple.py +++ b/src/calibre/web/fetch/simple.py @@ -410,6 +410,7 @@ class RecursiveFetcher(object, LoggingInterface): _fname.decode('latin1', 'replace') _fname = _fname.encode('ascii', 'replace').replace('%', '').replace(os.sep, '') _fname = sanitize_file_name(_fname) + _fname = os.path.splitext(_fname)[0]+'.xhtml' res = os.path.join(linkdiskpath, _fname) self.downloaded_paths.append(res) self.filemap[nurl] = res From 1145b768dc7e886e8327080eeddea61a82b6de32 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Feb 2009 13:39:53 -0800 Subject: [PATCH 04/24] Fix #1791 (Major recipe update) --- .../web/feeds/recipes/recipe_ambito.py | 40 ++++-- src/calibre/web/feeds/recipes/recipe_b92.py | 37 +++-- src/calibre/web/feeds/recipes/recipe_blic.py | 45 ++++-- .../web/feeds/recipes/recipe_clarin.py | 29 ++-- src/calibre/web/feeds/recipes/recipe_danas.py | 49 ++++--- .../feeds/recipes/recipe_el_mercurio_chile.py | 29 ++-- .../web/feeds/recipes/recipe_elargentino.py | 27 ++-- .../web/feeds/recipes/recipe_elmundo.py | 40 ++++-- .../web/feeds/recipes/recipe_estadao.py | 25 ++-- .../web/feeds/recipes/recipe_granma.py | 33 +++-- .../web/feeds/recipes/recipe_harpers_full.py | 136 ++++++++++-------- .../web/feeds/recipes/recipe_infobae.py | 41 ++++-- .../web/feeds/recipes/recipe_jb_online.py | 27 ++-- .../web/feeds/recipes/recipe_jutarnji.py | 40 ++++-- .../feeds/recipes/recipe_juventudrebelde.py | 29 ++-- .../recipes/recipe_juventudrebelde_english.py | 28 ++-- .../web/feeds/recipes/recipe_la_cuarta.py | 30 ++-- .../web/feeds/recipes/recipe_la_segunda.py | 31 ++-- .../web/feeds/recipes/recipe_la_tercera.py | 31 ++-- .../web/feeds/recipes/recipe_lanacion.py | 41 +++--- .../feeds/recipes/recipe_lanacion_chile.py | 25 ++-- .../web/feeds/recipes/recipe_laprensa.py | 27 ++-- src/calibre/web/feeds/recipes/recipe_nin.py | 29 +++- .../web/feeds/recipes/recipe_novosti.py | 47 +++--- src/calibre/web/feeds/recipes/recipe_nspm.py | 40 ++++-- .../web/feeds/recipes/recipe_o_globo.py | 27 ++-- .../web/feeds/recipes/recipe_pagina12.py | 30 ++-- .../web/feeds/recipes/recipe_pescanik.py | 40 ++++-- .../web/feeds/recipes/recipe_politika.py | 48 +++++-- .../web/feeds/recipes/recipe_vijesti.py | 47 ++++-- src/calibre/web/feeds/recipes/recipe_vreme.py | 54 +++++-- 31 files changed, 808 insertions(+), 394 deletions(-) diff --git a/src/calibre/web/feeds/recipes/recipe_ambito.py b/src/calibre/web/feeds/recipes/recipe_ambito.py index 17d33a1cde..e6e3c224e9 100644 --- a/src/calibre/web/feeds/recipes/recipe_ambito.py +++ b/src/calibre/web/feeds/recipes/recipe_ambito.py @@ -1,31 +1,38 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' +__copyright__ = '2008-2009, Darko Miletic ' ''' ambito.com ''' - -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class Ambito(BasicNewsRecipe): title = 'Ambito.com' __author__ = 'Darko Miletic' - description = 'Informacion Libre las 24 horas' + description = 'Informacion Libre las 24 horas' + publisher = 'Ambito.com' + category = 'news, politics, Argentina' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True - use_embedded_content = False - encoding = 'iso--8859-1' - language = _('Spanish') + encoding = 'iso-8859-1' cover_url = 'http://www.ambito.com/img/logo_.jpg' - + remove_javascript = True + use_embedded_content = False + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Argentina' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + + keep_only_tags = [dict(name='div', attrs={'align':'justify'})] + + remove_tags = [dict(name=['object','link'])] feeds = [ (u'Principales Noticias', u'http://www.ambito.com/rss/noticiasp.asp' ) @@ -43,3 +50,12 @@ class Ambito(BasicNewsRecipe): def print_version(self, url): return url.replace('http://www.ambito.com/noticia.asp?','http://www.ambito.com/noticias/imprimir.asp?') + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_b92.py b/src/calibre/web/feeds/recipes/recipe_b92.py index c20bfab8dc..611647620b 100644 --- a/src/calibre/web/feeds/recipes/recipe_b92.py +++ b/src/calibre/web/feeds/recipes/recipe_b92.py @@ -7,25 +7,33 @@ b92.net ''' import re -from calibre.web.feeds.news import BasicNewsRecipe +from calibre.web.feeds.news import BasicNewsRecipe + class B92(BasicNewsRecipe): - title = u'B92' + title = 'B92' __author__ = 'Darko Miletic' - language = _('Serbian') description = 'Dnevne vesti iz Srbije i sveta' - oldest_article = 7 + oldest_article = 2 + publisher = 'B92.net' + category = 'news, politics, Serbia' max_articles_per_feed = 100 + remove_javascript = True no_stylesheets = True use_embedded_content = False cover_url = 'http://static.b92.net/images/fp/logo.gif' + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + keep_only_tags = [ dict(name='div', attrs={'class':'sama_vest'}) ] + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, Serbia' - , '--publisher', 'B92' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] feeds = [ (u'Vesti', u'http://www.b92.net/info/rss/vesti.xml') @@ -44,3 +52,16 @@ class B92(BasicNewsRecipe): if biz: nurl = 'http://www.b92.net/mobilni/biz/index.php?nav_id=' + article_id return nurl + + def preprocess_html(self, soup): + soup.html['xml:lang'] = 'sr-Latn' + soup.html['lang'] = 'sr-Latn' + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + for item in soup.findAll(name='img',align=True): + del item['align'] + item.insert(0,'

') + return soup + language = _('Serbian') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_blic.py b/src/calibre/web/feeds/recipes/recipe_blic.py index 33f98f562e..ae75394fec 100644 --- a/src/calibre/web/feeds/recipes/recipe_blic.py +++ b/src/calibre/web/feeds/recipes/recipe_blic.py @@ -5,32 +5,49 @@ __copyright__ = '2008, Darko Miletic ' ''' blic.rs ''' -import string,re -from calibre.web.feeds.news import BasicNewsRecipe +import re + +from calibre.web.feeds.news import BasicNewsRecipe + class Blic(BasicNewsRecipe): title = u'Blic' - __author__ = 'Darko Miletic' - description = 'Blic.rs online verzija najtiraznije novine u Srbiji donosi najnovije vesti iz Srbije i sveta, komentare, politicke analize, poslovne i ekonomske vesti, vesti iz regiona, intervjue, informacije iz kulture, reportaze, pokriva sve sportske dogadjaje, detaljan tv program, nagradne igre, zabavu, fenomenalni Blic strip, dnevni horoskop, arhivu svih dogadjaja' - oldest_article = 7 - language = _('Serbian') + __author__ = u'Darko Miletic' + description = u'Blic.co.yu online verzija najtiraznije novine u Srbiji donosi najnovije vesti iz Srbije i sveta, komentare, politicke analize, poslovne i ekonomske vesti, vesti iz regiona, intervjue, informacije iz kulture, reportaze, pokriva sve sportske dogadjaje, detaljan tv program, nagradne igre, zabavu, fenomenalni Blic strip, dnevni horoskop, arhivu svih dogadjaja' + publisher = 'RINGIER d.o.o.' + category = 'news, politics, Serbia' + oldest_article = 2 max_articles_per_feed = 100 + remove_javascript = True no_stylesheets = True use_embedded_content = False - cover_url = 'http://www.blic.rs/resources/images/header_back_tile.png' + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, Serbia' - , '--publisher', 'Blic' + '--comment', description + , '--category', category + , '--publisher', publisher ] - + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] - keep_only_tags = [ dict(name='div', attrs={'class':'single_news'}) ] + keep_only_tags = [dict(name='div', attrs={'class':'single_news'})] - feeds = [ (u'Vesti', u'http://www.blic.rs/rssall.php')] + feeds = [(u'Vesti', u'http://www.blic.rs/rssall.php')] + remove_tags = [dict(name=['object','link'])] + def print_version(self, url): start_url, question, rest_url = url.partition('?') return u'http://www.blic.rs/_print.php?' + rest_url + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Serbian') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_clarin.py b/src/calibre/web/feeds/recipes/recipe_clarin.py index cd72163c88..146719cc8b 100644 --- a/src/calibre/web/feeds/recipes/recipe_clarin.py +++ b/src/calibre/web/feeds/recipes/recipe_clarin.py @@ -1,31 +1,35 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' +__copyright__ = '2008-2009, Darko Miletic ' ''' clarin.com ''' from calibre import strftime -from calibre.web.feeds.news import BasicNewsRecipe +from calibre.web.feeds.news import BasicNewsRecipe + class Clarin(BasicNewsRecipe): title = 'Clarin' __author__ = 'Darko Miletic' description = 'Noticias de Argentina y mundo' + publisher = 'Grupo Clarin' + category = 'news, politics, Argentina' oldest_article = 2 max_articles_per_feed = 100 - language = _('Spanish') use_embedded_content = False no_stylesheets = True cover_url = strftime('http://www.clarin.com/diario/%Y/%m/%d/portada.jpg') - + remove_javascript = True + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, Argentina' - , '--publisher', 'Grupo Clarin' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' remove_tags = [ dict(name='a' , attrs={'class':'Imp' }) @@ -49,3 +53,12 @@ class Clarin(BasicNewsRecipe): rest = artl.partition('-0')[-1] lmain = rest.partition('.')[0] return 'http://www.servicios.clarin.com/notas/jsp/clarin/v9/notas/imprimir.jsp?pagid=' + lmain + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_danas.py b/src/calibre/web/feeds/recipes/recipe_danas.py index 59e99fc746..f9c05e7b20 100644 --- a/src/calibre/web/feeds/recipes/recipe_danas.py +++ b/src/calibre/web/feeds/recipes/recipe_danas.py @@ -5,38 +5,47 @@ __copyright__ = '2008, Darko Miletic ' ''' danas.rs ''' -import string,re -from calibre.web.feeds.news import BasicNewsRecipe +import re +from calibre.web.feeds.news import BasicNewsRecipe + class Danas(BasicNewsRecipe): - title = 'Danas' + title = u'Danas' __author__ = 'Darko Miletic' - description = 'Dnevne novine sa vestima iz sveta, politike, ekonomije, kulture, sporta, Beograda, Novog Sada i cele Srbije.' + description = 'Vesti' + publisher = 'Danas d.o.o.' + category = 'news, politics, Serbia' oldest_article = 2 - language = _('Serbian') max_articles_per_feed = 100 - no_stylesheets = True + no_stylesheets = False + remove_javascript = True use_embedded_content = False - cover_url = 'http://www.danas.rs/images/basic/danas.gif' + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, Serbia' - , '--publisher', 'Danas' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] - keep_only_tags = [ dict(name='div', attrs={'id':'left'}) ] + keep_only_tags = [dict(name='div', attrs={'id':'left'})] remove_tags = [ - dict(name='div', attrs={'class':'width_1_4' }) - ,dict(name='div', attrs={'class':'metaClanka' }) - ,dict(name='div', attrs={'id':'comments' }) - ,dict(name='div', attrs={'class':'baner' }) - ,dict(name='div', attrs={'class':'slikaClanka'}) + dict(name='div', attrs={'class':['width_1_4','metaClanka','baner']}) + ,dict(name='div', attrs={'id':'comments'}) + ,dict(name=['object','link']) ] - feeds = [(u'Vesti', u'http://www.danas.rs/rss/rss.asp')] + feeds = [ (u'Vesti', u'http://www.danas.rs/rss/rss.asp')] - def print_version(self, url): - return url + '&action=print' + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + language = _('Serbian') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_el_mercurio_chile.py b/src/calibre/web/feeds/recipes/recipe_el_mercurio_chile.py index 0b7d994b34..fb11d54072 100644 --- a/src/calibre/web/feeds/recipes/recipe_el_mercurio_chile.py +++ b/src/calibre/web/feeds/recipes/recipe_el_mercurio_chile.py @@ -5,31 +5,36 @@ __copyright__ = '2009, Darko Miletic ' ''' emol.com ''' -from calibre.web.feeds.news import BasicNewsRecipe +from calibre.web.feeds.news import BasicNewsRecipe + class ElMercurio(BasicNewsRecipe): title = 'El Mercurio online' - language = _('Spanish') __author__ = 'Darko Miletic' - description = 'El sitio de noticias online de Chile' + description = 'El sitio de noticias online de Chile' + publisher = 'El Mercurio' + category = 'news, politics, Chile' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' cover_url = 'http://www.emol.com/especiales/logo_emol/logo_emol.gif' - + remove_javascript = True + use_embedded_content = False + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Chile' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [ dict(name='div', attrs={'class':'despliegue-txt_750px'}) ,dict(name='div', attrs={'id':'div_cuerpo_participa'}) ] - remove_tags = [ dict(name='div', attrs={'class':'contenedor_despliegue-col-left300'}) @@ -45,4 +50,12 @@ class ElMercurio(BasicNewsRecipe): ,(u'Tecnologia', u'http://www.emol.com/rss20/rss.asp?canal=5') ,(u'La Musica', u'http://www.emol.com/rss20/rss.asp?canal=7') ] + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_elargentino.py b/src/calibre/web/feeds/recipes/recipe_elargentino.py index ef79c96baa..1801c81b81 100644 --- a/src/calibre/web/feeds/recipes/recipe_elargentino.py +++ b/src/calibre/web/feeds/recipes/recipe_elargentino.py @@ -1,30 +1,34 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' +__copyright__ = '2008-2009, Darko Miletic ' ''' elargentino.com ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class ElArgentino(BasicNewsRecipe): title = 'ElArgentino.com' __author__ = 'Darko Miletic' - description = 'Informacion Libre las 24 horas' - language = _('Spanish') + description = 'Informacion Libre las 24 horas' + publisher = 'ElArgentino.com' + category = 'news, politics, Argentina' oldest_article = 2 max_articles_per_feed = 100 + remove_javascript = True no_stylesheets = True use_embedded_content = False encoding = 'utf8' cover_url = 'http://www.elargentino.com/TemplateWeb/MediosFooter/tapa_elargentino.png' html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Argentina' - , '--publisher' , 'ElArgentino.com' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' remove_tags = [ dict(name='div', attrs={'id':'noprint' }) @@ -50,7 +54,10 @@ class ElArgentino(BasicNewsRecipe): return u'http://www.elargentino.com/Impresion.aspx?Id=' + article_id def preprocess_html(self, soup): - mtag = '' + mtag = '\n\n' soup.head.insert(0,mtag) - soup.prettify() + for item in soup.findAll(style=True): + del item['style'] return soup + + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_elmundo.py b/src/calibre/web/feeds/recipes/recipe_elmundo.py index 9fd6eefb35..3ecedb5822 100644 --- a/src/calibre/web/feeds/recipes/recipe_elmundo.py +++ b/src/calibre/web/feeds/recipes/recipe_elmundo.py @@ -6,41 +6,55 @@ __copyright__ = '2009, Darko Miletic ' elmundo.es ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class ElMundo(BasicNewsRecipe): title = 'El Mundo' __author__ = 'Darko Miletic' description = 'News from Spain' - language = _('Spanish') + publisher = 'El Mundo' + category = 'news, politics, Spain' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'iso8859_15' cover_url = 'http://estaticos02.cache.el-mundo.net/papel/imagenes/v2.0/logoverde.gif' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Spain' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' - keep_only_tags = [dict(name='div', attrs={'class':'noticia'})] - + + keep_only_tags = [ + dict(name='div', attrs={'id':['bloqueprincipal','noticia']}) + ,dict(name='div', attrs={'class':['contenido_noticia_01']}) + ] remove_tags = [ - dict(name='div', attrs={'class':['herramientas','publicidad_google','video','herramientasarriba','contenido_noticia_02']}) + dict(name='div', attrs={'class':['herramientas','publicidad_google']}) ,dict(name='div', attrs={'id':'modulo_multimedia' }) - ,dict(name=['object','script','link', 'a']) - ,dict(name='ul', attrs={'class':'herramientas'}) + ,dict(name='ul', attrs={'class':'herramientas' }) + ,dict(name=['object','link']) ] feeds = [ (u'Portada' , u'http://rss.elmundo.es/rss/descarga.htm?data2=4' ) - ,(u'Television' , u'http://rss.elmundo.es/rss/descarga.htm?data2=76') ,(u'Espana' , u'http://rss.elmundo.es/rss/descarga.htm?data2=8' ) ,(u'Internacional' , u'http://rss.elmundo.es/rss/descarga.htm?data2=9' ) ,(u'Cultura' , u'http://rss.elmundo.es/rss/descarga.htm?data2=6' ) ,(u'Ciencia/Ecologia', u'http://rss.elmundo.es/rss/descarga.htm?data2=5' ) ,(u'Comunicacion' , u'http://rss.elmundo.es/rss/descarga.htm?data2=26') + ,(u'Television' , u'http://rss.elmundo.es/rss/descarga.htm?data2=76') ] + + def preprocess_html(self, soup): + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_estadao.py b/src/calibre/web/feeds/recipes/recipe_estadao.py index f44e62e0ca..4b23fdb235 100644 --- a/src/calibre/web/feeds/recipes/recipe_estadao.py +++ b/src/calibre/web/feeds/recipes/recipe_estadao.py @@ -6,26 +6,29 @@ __copyright__ = '2009, Darko Miletic ' estadao.com.br ''' -from calibre.web.feeds.news import BasicNewsRecipe - - +from calibre.web.feeds.news import BasicNewsRecipe + class Estadao(BasicNewsRecipe): title = 'O Estado de S. Paulo' __author__ = 'Darko Miletic' - description = 'News from Brasil' - language = _('Portugese') + description = 'News from Brasil in Portugese' + publisher = 'O Estado de S. Paulo' + category = 'news, politics, Brasil' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'utf8' cover_url = 'http://www.estadao.com.br/img/logo_estadao.png' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Brasil' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='div', attrs={'id':'c1'})] @@ -52,4 +55,8 @@ class Estadao(BasicNewsRecipe): ifr = soup.find('iframe') if ifr: ifr.extract() + for item in soup.findAll(style=True): + del item['style'] return soup + + language = _('Portugese') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_granma.py b/src/calibre/web/feeds/recipes/recipe_granma.py index 43cbd32ae1..66ebba1d64 100644 --- a/src/calibre/web/feeds/recipes/recipe_granma.py +++ b/src/calibre/web/feeds/recipes/recipe_granma.py @@ -7,27 +7,30 @@ granma.cubaweb.cu ''' import urllib - -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class Granma(BasicNewsRecipe): title = 'Diario Granma' __author__ = 'Darko Miletic' - language = _('Spanish') description = 'Organo oficial del Comite Central del Partido Comunista de Cuba' + publisher = 'Granma' + category = 'news, politics, Cuba' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' cover_url = 'http://www.granma.cubaweb.cu/imagenes/granweb229d.jpg' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Cuba' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher , '--ignore-tables' ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='table', attrs={'height':'466'})] @@ -35,9 +38,15 @@ class Granma(BasicNewsRecipe): def preprocess_html(self, soup): - del soup.body.table['style'] - rtag = soup.find('td', attrs={'height':'458'}) - if rtag: - del rtag['style'] + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll('table'): + if item.has_key('width'): + del item['width'] + if item.has_key('height'): + del item['height'] + for item in soup.findAll(style=True): + del item['style'] return soup + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_harpers_full.py b/src/calibre/web/feeds/recipes/recipe_harpers_full.py index adf0bf82a3..72e633bde0 100644 --- a/src/calibre/web/feeds/recipes/recipe_harpers_full.py +++ b/src/calibre/web/feeds/recipes/recipe_harpers_full.py @@ -1,62 +1,80 @@ -#!/usr/bin/env python - -__license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' -''' -harpers.org - paid subscription/ printed issue articles -This recipe only get's article's published in text format -images and pdf's are ignored -''' - -from calibre import strftime +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2008-2009, Darko Miletic ' +''' +harpers.org - paid subscription/ printed issue articles +This recipe only get's article's published in text format +images and pdf's are ignored +''' + +from calibre import strftime + from calibre.web.feeds.news import BasicNewsRecipe -class Harpers_full(BasicNewsRecipe): - title = u"Harper's Magazine - articles from printed edition" - __author__ = u'Darko Miletic' - description = u"Harper's Magazine: Founded June 1850." - language = _('English') - oldest_article = 30 - max_articles_per_feed = 100 - no_stylesheets = True - use_embedded_content = False - simultaneous_downloads = 1 - delay = 1 - needs_subscription = True - INDEX = strftime('http://www.harpers.org/archive/%Y/%m') - LOGIN = 'http://www.harpers.org' - cover_url = strftime('http://www.harpers.org/media/pages/%Y/%m/gif/0001.gif') - - keep_only_tags = [ dict(name='div', attrs={'id':'cached'}) ] - remove_tags = [ - dict(name='table', attrs={'class':'rcnt'}) - ,dict(name='table', attrs={'class':'rcnt topline'}) - ] - - def get_browser(self): - br = BasicNewsRecipe.get_browser() - if self.username is not None and self.password is not None: - br.open(self.LOGIN) - br.select_form(nr=1) - br['handle' ] = self.username - br['password'] = self.password - br.submit() - return br +class Harpers_full(BasicNewsRecipe): + title = u"Harper's Magazine - articles from printed edition" + __author__ = u'Darko Miletic' + description = u"Harper's Magazine: Founded June 1850." + publisher = "Harpers's" + category = 'news, politics, USA' + oldest_article = 30 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + simultaneous_downloads = 1 + delay = 1 + needs_subscription = True + INDEX = strftime('http://www.harpers.org/archive/%Y/%m') + LOGIN = 'http://www.harpers.org' + cover_url = strftime('http://www.harpers.org/media/pages/%Y/%m/gif/0001.gif') + remove_javascript = True + + html2lrf_options = [ + '--comment', description + , '--category', category + , '--publisher', publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + + keep_only_tags = [ dict(name='div', attrs={'id':'cached'}) ] + remove_tags = [ + dict(name='table', attrs={'class':'rcnt'}) + ,dict(name='table', attrs={'class':'rcnt topline'}) + ] + + def get_browser(self): + br = BasicNewsRecipe.get_browser() + if self.username is not None and self.password is not None: + br.open(self.LOGIN) + br.select_form(nr=1) + br['handle' ] = self.username + br['password'] = self.password + br.submit() + return br + + def parse_index(self): + articles = [] + print 'Processing ' + self.INDEX + soup = self.index_to_soup(self.INDEX) + for item in soup.findAll('div', attrs={'class':'title'}): + text_link = item.parent.find('img',attrs={'alt':'Text'}) + if text_link: + url = self.LOGIN + item.a['href'] + title = item.a.contents[0] + date = strftime(' %B %Y') + articles.append({ + 'title' :title + ,'date' :date + ,'url' :url + ,'description':'' + }) + return [(soup.head.title.string, articles)] + + def preprocess_html(self, soup): + for item in soup.findAll(style=True): + del item['style'] + return soup - def parse_index(self): - articles = [] - print 'Processing ' + self.INDEX - soup = self.index_to_soup(self.INDEX) - for item in soup.findAll('div', attrs={'class':'title'}): - text_link = item.parent.find('img',attrs={'alt':'Text'}) - if text_link: - url = self.LOGIN + item.a['href'] - title = item.a.contents[0] - date = strftime(' %B %Y') - articles.append({ - 'title' :title - ,'date' :date - ,'url' :url - ,'description':'' - }) - return [(soup.head.title.string, articles)] \ No newline at end of file + language = _('English') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_infobae.py b/src/calibre/web/feeds/recipes/recipe_infobae.py index 5acbcfa763..40e720f94c 100644 --- a/src/calibre/web/feeds/recipes/recipe_infobae.py +++ b/src/calibre/web/feeds/recipes/recipe_infobae.py @@ -1,34 +1,36 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' +__copyright__ = '2008-2009, Darko Miletic ' ''' infobae.com ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class Infobae(BasicNewsRecipe): title = 'Infobae.com' __author__ = 'Darko Miletic' - description = 'Informacion Libre las 24 horas' + description = 'Informacion Libre las 24 horas' + publisher = 'Infobae.com' + category = 'news, politics, Argentina' oldest_article = 2 - language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'iso-8859-1' cover_url = 'http://www.infobae.com/imgs/header/header.gif' - - html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Argentina' - , '--publisher' , 'Infobae.com' - ] - - + remove_javascript = True - feeds = [ + html2lrf_options = [ + '--comment', description + , '--category', category + , '--publisher', publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + + feeds = [ (u'Noticias' , u'http://www.infobae.com/adjuntos/html/RSS/hoy.xml' ) ,(u'Salud' , u'http://www.infobae.com/adjuntos/html/RSS/salud.xml' ) ,(u'Tecnologia', u'http://www.infobae.com/adjuntos/html/RSS/tecnologia.xml') @@ -37,5 +39,14 @@ class Infobae(BasicNewsRecipe): def print_version(self, url): main, sep, article_part = url.partition('contenidos/') - article_id, rsep, rrest = article_part.partition('-') + article_id, rsep, rrest = article_part.partition('-') return u'http://www.infobae.com/notas/nota_imprimir.php?Idx=' + article_id + + def preprocess_html(self, soup): + mtag = '\n\n' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_jb_online.py b/src/calibre/web/feeds/recipes/recipe_jb_online.py index 2b40f1960d..4ac4b70836 100644 --- a/src/calibre/web/feeds/recipes/recipe_jb_online.py +++ b/src/calibre/web/feeds/recipes/recipe_jb_online.py @@ -6,25 +6,29 @@ __copyright__ = '2009, Darko Miletic ' jbonline.terra.com.br ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class JBOnline(BasicNewsRecipe): title = 'Jornal Brasileiro Online' __author__ = 'Darko Miletic' - description = 'News from Brasil' + description = 'News from Brasil' + publisher = 'Jornal Brasileiro' + category = 'news, politics, Brasil' oldest_article = 2 - language = _('Portugese') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' cover_url = 'http://jbonline.terra.com.br/img/logo_01.gif' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Brasil' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='div', attrs={'id':'corpoNoticia'})] @@ -36,7 +40,8 @@ class JBOnline(BasicNewsRecipe): ifr = soup.find('iframe') if ifr: ifr.extract() - item = soup.find('div', attrs={'id':'corpoNoticia'}) - if item: - del item['style'] + for item in soup.findAll(style=True): + del item['style'] return soup + + language = _('Portugese') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_jutarnji.py b/src/calibre/web/feeds/recipes/recipe_jutarnji.py index f2504a78c1..194d2163f9 100644 --- a/src/calibre/web/feeds/recipes/recipe_jutarnji.py +++ b/src/calibre/web/feeds/recipes/recipe_jutarnji.py @@ -6,28 +6,35 @@ __copyright__ = '2008, Darko Miletic ' jutarnji.hr ''' -import string, re -from calibre.web.feeds.news import BasicNewsRecipe -from calibre.ebooks.BeautifulSoup import BeautifulSoup +import re +from calibre.web.feeds.news import BasicNewsRecipe + class Jutarnji(BasicNewsRecipe): - title = 'Jutarnji' - __author__ = 'Darko Miletic' - description = 'Online izdanje Jutarnjeg lista' + title = u'Jutarnji' + __author__ = u'Darko Miletic' + description = u'Hrvatski portal' + publisher = 'Jutarnji.hr' + category = 'news, politics, Croatia' oldest_article = 2 max_articles_per_feed = 100 simultaneous_downloads = 1 delay = 1 no_stylesheets = True use_embedded_content = False + remove_javascript = True encoding = 'cp1250' - cover_url = 'http://www.jutarnji.hr/EPHResources/Images/2008/06/05/jhrlogo.png' + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, Croatia' - , '--publisher', 'Europapress holding d.o.o.' - ] + '--comment', description + , '--category', category + , '--publisher', publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] remove_tags = [ @@ -49,11 +56,16 @@ class Jutarnji(BasicNewsRecipe): def print_version(self, url): main, split, rest = url.partition('.jl') rmain, rsplit, rrest = main.rpartition(',') - return u'http://www.jutarnji.hr/ispis_clanka.jl?artid=' + rrest + return 'http://www.jutarnji.hr/ispis_clanka.jl?artid=' + rrest def preprocess_html(self, soup): mtag = '' soup.head.insert(0,mtag) - soup.prettify() + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + for item in soup.findAll(width=True): + del item['width'] return soup \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_juventudrebelde.py b/src/calibre/web/feeds/recipes/recipe_juventudrebelde.py index 5fa9f45e41..eea510a7cd 100644 --- a/src/calibre/web/feeds/recipes/recipe_juventudrebelde.py +++ b/src/calibre/web/feeds/recipes/recipe_juventudrebelde.py @@ -7,26 +7,30 @@ juventudrebelde.cu ''' from calibre import strftime -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class Juventudrebelde(BasicNewsRecipe): title = 'Juventud Rebelde' __author__ = 'Darko Miletic' - description = 'Diario de la Juventud Cubana' + description = 'Diario de la Juventud Cubana' + publisher = 'Juventud rebelde' + category = 'news, politics, Cuba' oldest_article = 2 - language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' cover_url = strftime('http://www.juventudrebelde.cu/UserFiles/File/impreso/iportada-%Y-%m-%d.jpg') - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Cuba' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher , '--ignore-tables' ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='div', attrs={'id':'noticia'})] @@ -40,4 +44,11 @@ class Juventudrebelde(BasicNewsRecipe): ,(u'Lectura', u'http://www.juventudrebelde.cu/rss/generales.php?seccion=lectura' ) ] - + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_juventudrebelde_english.py b/src/calibre/web/feeds/recipes/recipe_juventudrebelde_english.py index e7c1002323..5bae2b6e9c 100644 --- a/src/calibre/web/feeds/recipes/recipe_juventudrebelde_english.py +++ b/src/calibre/web/feeds/recipes/recipe_juventudrebelde_english.py @@ -5,30 +5,40 @@ __copyright__ = '2008, Darko Miletic ' ''' juventudrebelde.co.cu ''' -from calibre import strftime - -from calibre.web.feeds.news import BasicNewsRecipe +from calibre.web.feeds.news import BasicNewsRecipe + class Juventudrebelde_english(BasicNewsRecipe): title = 'Juventud Rebelde in english' __author__ = 'Darko Miletic' - description = 'The newspaper of Cuban Youth' - language = _('English') + description = 'The newspaper of Cuban Youth' + publisher = 'Juventud Rebelde' + category = 'news, politics, Cuba' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'iso-8859-1' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Cuba' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher , '--ignore-tables' ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='div', attrs={'class':'read'})] feeds = [(u'All news', u'http://www.juventudrebelde.cip.cu/rss/all/' )] + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + language = _('English') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_la_cuarta.py b/src/calibre/web/feeds/recipes/recipe_la_cuarta.py index e5576cd442..17bc708245 100644 --- a/src/calibre/web/feeds/recipes/recipe_la_cuarta.py +++ b/src/calibre/web/feeds/recipes/recipe_la_cuarta.py @@ -6,30 +6,33 @@ __copyright__ = '2009, Darko Miletic ' lacuarta.cl ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class LaCuarta(BasicNewsRecipe): title = 'La Cuarta' __author__ = 'Darko Miletic' - description = 'El sitio de noticias online de Chile' + description = 'La Cuarta Cibernetica: El Diario popular' + publisher = 'CODISA, Consorcio Digital S.A.' + category = 'news, politics, entertainment, Chile' oldest_article = 2 - language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Chile' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='div', attrs={'class':'articulo desplegado'}) ] remove_tags = [ - dict(name='script') - ,dict(name='ul') + dict(name='ul') ,dict(name='div', attrs={'id':['toolbox','articleImageDisplayer','enviarAmigo']}) ,dict(name='div', attrs={'class':['par ad-1','par ad-2']}) ,dict(name='input') @@ -37,7 +40,14 @@ class LaCuarta(BasicNewsRecipe): ,dict(name='strong', text='PUBLICIDAD') ] + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup feeds = [(u'Noticias', u'http://lacuarta.cl/app/rss?sc=TEFDVUFSVEE=')] + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_la_segunda.py b/src/calibre/web/feeds/recipes/recipe_la_segunda.py index 7f5415806d..d049d9c92b 100644 --- a/src/calibre/web/feeds/recipes/recipe_la_segunda.py +++ b/src/calibre/web/feeds/recipes/recipe_la_segunda.py @@ -6,26 +6,29 @@ __copyright__ = '2009, Darko Miletic ' lasegunda.com ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class LaSegunda(BasicNewsRecipe): title = 'La Segunda' __author__ = 'Darko Miletic' - description = 'El sitio de noticias online de Chile' - language = _('Spanish') + description = 'El sitio de noticias online de Chile' + publisher = 'La Segunda' + category = 'news, politics, Chile' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' cover_url = 'http://www.lasegunda.com/imagenes/logotipo_lasegunda_Oli.gif' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Chile' - , '--publisher' , title - , '--ignore-tables' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='table')] @@ -45,4 +48,14 @@ class LaSegunda(BasicNewsRecipe): def print_version(self, url): rest, sep, article_id = url.partition('index.asp?idnoticia=') return u'http://www.lasegunda.com/edicionOnline/include/secciones/_detalle_impresion.asp?idnoticia=' + article_id + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(name='table', width=True): + del item['width'] + for item in soup.findAll(style=True): + del item['style'] + return soup + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_la_tercera.py b/src/calibre/web/feeds/recipes/recipe_la_tercera.py index 65b0e630df..a0a2f94ee3 100644 --- a/src/calibre/web/feeds/recipes/recipe_la_tercera.py +++ b/src/calibre/web/feeds/recipes/recipe_la_tercera.py @@ -6,26 +6,30 @@ __copyright__ = '2009, Darko Miletic ' latercera.com ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class LaTercera(BasicNewsRecipe): title = 'La Tercera' __author__ = 'Darko Miletic' - description = 'El sitio de noticias online de Chile' + description = 'El sitio de noticias online de Chile' + publisher = 'La Tercera' + category = 'news, politics, Chile' oldest_article = 2 - language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True - use_embedded_content = False encoding = 'cp1252' - + remove_javascript = True + use_embedded_content = False + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Chile' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' - keep_only_tags = [dict(name='div', attrs={'class':'span-16 articulo border'}) ] + keep_only_tags = [dict(name='div', attrs={'class':['span-16 articulo border','span-16 border','span-16']}) ] remove_tags = [ dict(name='script') @@ -50,4 +54,11 @@ class LaTercera(BasicNewsRecipe): ,(u'Educacion', u'http://www.latercera.com/app/rss?sc=TEFURVJDRVJB&category=657') ] + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_lanacion.py b/src/calibre/web/feeds/recipes/recipe_lanacion.py index 6cf2afdc89..6675fc9b21 100644 --- a/src/calibre/web/feeds/recipes/recipe_lanacion.py +++ b/src/calibre/web/feeds/recipes/recipe_lanacion.py @@ -1,29 +1,32 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' +__copyright__ = '2008-2009, Darko Miletic ' ''' lanacion.com.ar ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class Lanacion(BasicNewsRecipe): title = 'La Nacion' __author__ = 'Darko Miletic' - description = 'Informacion actualizada las 24 horas, con noticias de Argentina y del mundo - Informate ya!' + description = 'Noticias de Argentina y el resto del mundo' + publisher = 'La Nacion' + category = 'news, politics, Argentina' oldest_article = 2 - language = _('Spanish') max_articles_per_feed = 100 - no_stylesheets = True use_embedded_content = False + remove_javascript = True + no_stylesheets = True html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, Argentina' - , '--publisher', 'La Nacion SA' - ] + '--comment', description + , '--category', category + , '--publisher', publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='div', attrs={'class':'nota floatFix'})] remove_tags = [ @@ -47,11 +50,11 @@ class Lanacion(BasicNewsRecipe): ,(u'Revista' , u'http://www.lanacion.com.ar/herramientas/rss/index.asp?categoria_id=494' ) ] - def get_cover_url(self): - index = 'http://www.lanacion.com.ar' - cover_url = None - soup = self.index_to_soup(index) - cover_item = soup.find('img',attrs={'class':'logo'}) - if cover_item: - cover_url = index + cover_item['src'] - return cover_url + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_lanacion_chile.py b/src/calibre/web/feeds/recipes/recipe_lanacion_chile.py index 81f31f07d8..8bd521df4b 100644 --- a/src/calibre/web/feeds/recipes/recipe_lanacion_chile.py +++ b/src/calibre/web/feeds/recipes/recipe_lanacion_chile.py @@ -7,25 +7,29 @@ lanacion.cl ''' import urllib -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class LaNacionChile(BasicNewsRecipe): title = 'La Nacion Chile' __author__ = 'Darko Miletic' - description = 'El sitio de noticias online de Chile' + description = 'El sitio de noticias online de Chile' + publisher = 'La Nacion' + category = 'news, politics, Chile' oldest_article = 2 - language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' cover_url = 'http://www.lanacion.cl/prontus_noticias_v2/imag/site/logo.gif' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Chile' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='div', attrs={'class':'bloque'})] @@ -41,5 +45,10 @@ class LaNacionChile(BasicNewsRecipe): item = soup.find('a', attrs={'href':'javascript:window.close()'}) if item: item.extract() + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] return soup + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_laprensa.py b/src/calibre/web/feeds/recipes/recipe_laprensa.py index 7c2567f8e6..f2064c1f6b 100644 --- a/src/calibre/web/feeds/recipes/recipe_laprensa.py +++ b/src/calibre/web/feeds/recipes/recipe_laprensa.py @@ -1,31 +1,35 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' +__copyright__ = '2008-2009, Darko Miletic ' ''' laprensa.com.ar ''' import urllib -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class LaPrensa(BasicNewsRecipe): title = 'La Prensa' __author__ = 'Darko Miletic' - description = 'Informacion Libre las 24 horas' + description = 'Informacion Libre las 24 horas' + publisher = 'La Prensa' + category = 'news, politics, Argentina' oldest_article = 7 - language = _('Spanish') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' cover_url = 'http://www.laprensa.com.ar/imgs/logo.gif' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Argentina' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' feeds = [ (u'Politica' , u'http://www.laprensa.com.ar/Rss.aspx?Rss=4' ) @@ -47,5 +51,10 @@ class LaPrensa(BasicNewsRecipe): def preprocess_html(self, soup): del soup.body['onload'] + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] return soup + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_nin.py b/src/calibre/web/feeds/recipes/recipe_nin.py index bc62af1b4f..d180f2b221 100644 --- a/src/calibre/web/feeds/recipes/recipe_nin.py +++ b/src/calibre/web/feeds/recipes/recipe_nin.py @@ -7,15 +7,17 @@ nin.co.yu ''' import re, urllib -from calibre.web.feeds.news import BasicNewsRecipe -class Nin(BasicNewsRecipe): +from calibre.web.feeds.news import BasicNewsRecipe + +class Nin(BasicNewsRecipe): title = 'NIN online' __author__ = 'Darko Miletic' description = 'Nedeljne informativne novine' + publisher = 'NIN' + category = 'news, politics, Serbia' no_stylesheets = True oldest_article = 15 - language = _('Serbian') simultaneous_downloads = 1 delay = 1 encoding = 'utf8' @@ -23,11 +25,17 @@ class Nin(BasicNewsRecipe): PREFIX = 'http://www.nin.co.yu' INDEX = PREFIX + '/?change_lang=ls' LOGIN = PREFIX + '/?logout=true' + remove_javascript = True + use_embedded_content = False + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, politics, Serbia' - , '--publisher' , 'NIN' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] @@ -54,3 +62,12 @@ class Nin(BasicNewsRecipe): if link_item: cover_url = self.PREFIX + link_item['src'] return cover_url + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Serbian') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_novosti.py b/src/calibre/web/feeds/recipes/recipe_novosti.py index 2fefc8a566..136302c573 100644 --- a/src/calibre/web/feeds/recipes/recipe_novosti.py +++ b/src/calibre/web/feeds/recipes/recipe_novosti.py @@ -5,32 +5,45 @@ __copyright__ = '2008, Darko Miletic ' ''' novosti.rs ''' -import string,re -from calibre.web.feeds.news import BasicNewsRecipe +import re + +from calibre.web.feeds.news import BasicNewsRecipe + class Novosti(BasicNewsRecipe): - title = 'Vecernje Novosti' - __author__ = 'Darko Miletic' - description = 'novosti, vesti, politika, dosije, drustvo, ekonomija, hronika, reportaze, svet, kultura, sport, beograd, regioni, mozaik, feljton, intrvju, pjer, fudbal, kosarka, podvig, arhiva, komentari, kolumne, srbija, republika srpska,Vecernje novosti' + title = u'Vecernje Novosti' + __author__ = u'Darko Miletic' + description = u'Vesti' + publisher = 'Kompanija Novosti' + category = 'news, politics, Serbia' oldest_article = 2 - language = _('Serbian') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False + encoding = 'utf8' + remove_javascript = True + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, Serbia' - , '--publisher', 'Novosti AD' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] - keep_only_tags = [ dict(name='div', attrs={'class':'jednaVest'}) ] - remove_tags_after = dict(name='div', attrs={'class':'info_bottom'}) - remove_tags = [ - dict(name='div', attrs={'class':'info'}) - ,dict(name='div', attrs={'class':'info_bottom'}) - ] + keep_only_tags = [dict(name='div', attrs={'class':'jednaVest'})] + remove_tags = [dict(name='div', attrs={'class':['info','info_bottom','clip_div']})] - feeds = [ (u'Vesti', u'http://www.novosti.rs/php/vesti/rss.php')] + feeds = [(u'Vesti', u'http://www.novosti.rs/php/vesti/rss.php')] + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Serbian') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_nspm.py b/src/calibre/web/feeds/recipes/recipe_nspm.py index d828636545..4cc6d50ca0 100644 --- a/src/calibre/web/feeds/recipes/recipe_nspm.py +++ b/src/calibre/web/feeds/recipes/recipe_nspm.py @@ -6,35 +6,55 @@ __copyright__ = '2008, Darko Miletic ' nspm.rs ''' -import string,re -from calibre.web.feeds.news import BasicNewsRecipe +import re +from calibre.web.feeds.news import BasicNewsRecipe + class Nspm(BasicNewsRecipe): title = u'Nova srpska politicka misao' __author__ = 'Darko Miletic' description = 'Casopis za politicku teoriju i drustvena istrazivanja' + publisher = 'NSPM' + category = 'news, politics, Serbia' oldest_article = 7 - language = _('Serbian') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False INDEX = 'http://www.nspm.rs/?alphabet=l' - cover_url = 'http://nspm.rs/templates/jsn_epic_pro/images/logol.jpg' + encoding = 'utf8' + remove_javascript = True + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, politics, Serbia' - , '--publisher', 'IIC NSPM' + '--comment', description + , '--category', category + , '--publisher', publisher + , '--ignore-tables' ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] - + remove_tags = [dict(name='a')] + def get_browser(self): br = BasicNewsRecipe.get_browser() br.open(self.INDEX) return br - feeds = [ (u'Nova srpska politicka misao', u'http://www.nspm.rs/feed/rss.html')] + feeds = [(u'Nova srpska politicka misao', u'http://www.nspm.rs/feed/rss.html')] def print_version(self, url): return url.replace('.html','/stampa.html') + + def preprocess_html(self, soup): + soup.html['xml:lang'] = 'sr-Latn-RS' + soup.html['lang'] = 'sr-Latn-RS' + ftag = soup.find('meta',attrs={'http-equiv':'Content-Language'}) + if ftag: + ftag['content'] = 'sr-Latn-RS' + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Serbian') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_o_globo.py b/src/calibre/web/feeds/recipes/recipe_o_globo.py index 83e7f2da93..f4f78d54b8 100644 --- a/src/calibre/web/feeds/recipes/recipe_o_globo.py +++ b/src/calibre/web/feeds/recipes/recipe_o_globo.py @@ -6,25 +6,29 @@ __copyright__ = '2009, Darko Miletic ' oglobo.globo.com ''' -from calibre.web.feeds.news import BasicNewsRecipe - +from calibre.web.feeds.news import BasicNewsRecipe + class OGlobo(BasicNewsRecipe): title = 'O Globo' __author__ = 'Darko Miletic' - description = 'News from Brasil' + description = 'News from Brasil' + publisher = 'O Globo' + category = 'news, politics, Brasil' oldest_article = 2 max_articles_per_feed = 100 - language = _('Portugese') no_stylesheets = True use_embedded_content = False encoding = 'cp1252' cover_url = 'http://oglobo.globo.com/_img/o-globo.png' - + remove_javascript = True + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Brasil' - , '--publisher' , title + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' keep_only_tags = [dict(name='div', attrs={'id':'ltintb'})] @@ -56,3 +60,10 @@ class OGlobo(BasicNewsRecipe): ,(u'Economia', u'http://oglobo.globo.com/rss/plantaoeconomia.xml') ,(u'Tecnologia', u'http://oglobo.globo.com/rss/plantaotecnologia.xml') ] + + def preprocess_html(self, soup): + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Portugese') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_pagina12.py b/src/calibre/web/feeds/recipes/recipe_pagina12.py index 8428a9a35f..b821ed0b68 100644 --- a/src/calibre/web/feeds/recipes/recipe_pagina12.py +++ b/src/calibre/web/feeds/recipes/recipe_pagina12.py @@ -1,31 +1,36 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' +__copyright__ = '2008-2009, Darko Miletic ' ''' pagina12.com.ar ''' from calibre import strftime -from calibre.web.feeds.news import BasicNewsRecipe +from calibre.web.feeds.news import BasicNewsRecipe + class Pagina12(BasicNewsRecipe): title = u'Pagina/12' __author__ = 'Darko Miletic' description = 'Noticias de Argentina y el resto del mundo' - language = _('Spanish') + publisher = 'La Pagina S.A.' + category = 'news, politics, Argentina' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True - use_embedded_content = False encoding = 'cp1252' cover_url = strftime('http://www.pagina12.com.ar/fotos/%Y%m%d/diario/TAPAN.jpg') - + remove_javascript = True + use_embedded_content = False + html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Argentina' - , '--publisher' , 'La Pagina S.A.' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' remove_tags = [ @@ -38,3 +43,12 @@ class Pagina12(BasicNewsRecipe): def print_version(self, url): return url.replace('http://www.pagina12.com.ar/','http://www.pagina12.com.ar/imprimir/') + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Spanish') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_pescanik.py b/src/calibre/web/feeds/recipes/recipe_pescanik.py index 48d6a90966..e3385e02aa 100644 --- a/src/calibre/web/feeds/recipes/recipe_pescanik.py +++ b/src/calibre/web/feeds/recipes/recipe_pescanik.py @@ -6,31 +6,53 @@ __copyright__ = '2008, Darko Miletic ' pescanik.net ''' -import string,re -from calibre.web.feeds.news import BasicNewsRecipe +import re +from calibre.web.feeds.news import BasicNewsRecipe + class Pescanik(BasicNewsRecipe): title = 'Pescanik' __author__ = 'Darko Miletic' description = 'Pescanik' + publisher = 'Pescanik' + category = 'news, politics, Serbia' oldest_article = 7 - language = _('Serbian') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False - html2lrf_options = ['--base-font-size', '10'] - html2epub_options = 'base_font_size = "10pt"' + remove_javascript = True + encoding = 'utf8' + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + + html2lrf_options = [ + '--comment', description + , '--category', category + , '--publisher', publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' cover_url = "http://pescanik.net/templates/ja_teline/images/logo.png" preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] - remove_tags_after = dict(name='div', attrs={'class':'article_seperator'}) - - remove_tags = [dict(name='td' , attrs={'class':'buttonheading'})] + remove_tags = [ + dict(name='td' , attrs={'class':'buttonheading'}) + ,dict(name='span', attrs={'class':'article_seperator'}) + ,dict(name=['object','link']) + ] feeds = [(u'Pescanik Online', u'http://pescanik.net/index.php?option=com_rd_rss&id=12')] def print_version(self, url): - nurl = url.replace('http://pescanik.net/index.php','http://pescanik.net/index2.php') + nurl = url.replace('/index.php','/index2.php') return nurl + '&pop=1&page=0' + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + return soup + + language = _('Serbian') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_politika.py b/src/calibre/web/feeds/recipes/recipe_politika.py index 949a9b781d..1575d8984f 100644 --- a/src/calibre/web/feeds/recipes/recipe_politika.py +++ b/src/calibre/web/feeds/recipes/recipe_politika.py @@ -5,37 +5,61 @@ __copyright__ = '2008, Darko Miletic ' ''' politika.rs ''' -import string,re -from calibre.web.feeds.news import BasicNewsRecipe +import re +from calibre.web.feeds.news import BasicNewsRecipe + class Politika(BasicNewsRecipe): - title = 'Politika Online' + title = u'Politika Online' __author__ = 'Darko Miletic' - description = 'Najstariji dnevni list na Balkanu' + description = 'Najstariji dnevni list na Balkanu' + publisher = 'Politika novine i Magazini d.o.o' + category = 'news, politics, Serbia' oldest_article = 2 max_articles_per_feed = 100 no_stylesheets = True - extra_css = '.content_center_border {text-align: left;}' use_embedded_content = False - cover_url = 'http://www.politika.rs:8080/images/politika.gif' + remove_javascript = True + encoding = 'utf8' + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, Serbia' - , '--publisher', 'POLITIKA NOVINE I MAGAZINI d.o.o.' + '--comment', description + , '--category', category + , '--publisher', publisher ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] - keep_only_tags = [ dict(name='div', attrs={'class':'contentcenter'}) ] - remove_tags_after = dict(name='div', attrs={'class':'datum_item_details'}) + keep_only_tags = [dict(name='div', attrs={'class':'content_center_border'})] + + remove_tags = [ + dict(name='div', attrs={'class':['send_print','txt-komentar']}) + ,dict(name=['object','link','a']) + ,dict(name='h1', attrs={'class':'box_header-tags'}) + ] + feeds = [ (u'Politika' , u'http://www.politika.rs/rubrike/Politika/index.1.lt.xml' ) ,(u'Svet' , u'http://www.politika.rs/rubrike/Svet/index.1.lt.xml' ) + ,(u'Redakcijski komentari', u'http://www.politika.rs/rubrike/redakcijski-komentari/index.1.lt.xml') ,(u'Pogledi' , u'http://www.politika.rs/pogledi/index.lt.xml' ) ,(u'Pogledi sa strane' , u'http://www.politika.rs/rubrike/Pogledi-sa-strane/index.1.lt.xml' ) ,(u'Tema dana' , u'http://www.politika.rs/rubrike/tema-dana/index.1.lt.xml' ) ,(u'Kultura' , u'http://www.politika.rs/rubrike/Kultura/index.1.lt.xml' ) ,(u'Zivot i stil' , u'http://www.politika.rs/rubrike/zivot-i-stil/index.1.lt.xml' ) ] + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + for item in soup.findAll(style=True): + del item['style'] + ftag = soup.find('div',attrs={'class':'content_center_border'}) + if ftag: + ftag['align'] = 'left' + return soup diff --git a/src/calibre/web/feeds/recipes/recipe_vijesti.py b/src/calibre/web/feeds/recipes/recipe_vijesti.py index e018e91b02..98a7736a96 100644 --- a/src/calibre/web/feeds/recipes/recipe_vijesti.py +++ b/src/calibre/web/feeds/recipes/recipe_vijesti.py @@ -1,38 +1,49 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' +__copyright__ = '2009, Darko Miletic ' ''' vijesti.cg.yu ''' -import string,re - -from calibre.web.feeds.news import BasicNewsRecipe +import re +from calibre.web.feeds.news import BasicNewsRecipe + class Vijesti(BasicNewsRecipe): title = 'Vijesti' __author__ = 'Darko Miletic' - description = 'News from Montenegro' - oldest_article = 2 - language = _('Serbian') + description = 'News from Montenegro' + publisher = 'Daily Press Vijesti' + category = 'news, politics, Montenegro' + oldest_article = 1 max_articles_per_feed = 100 no_stylesheets = True - use_embedded_content = False + remove_javascript = True encoding = 'cp1250' cover_url = 'http://www.vijesti.cg.yu/img/logo.gif' - + remove_javascript = True + use_embedded_content = False + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + + html2lrf_options = [ + '--comment', description + , '--category', category + , '--publisher', publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] - html2lrf_options = [ - '--comment' , description - , '--category' , 'news, Montenegro' - , '--publisher' , 'Daily Press Vijesti' - ] - keep_only_tags = [dict(name='div', attrs={'id':'mainnews'})] + remove_tags = [ + dict(name='div', attrs={'align':'right'}) + ,dict(name=['object','link']) + ] + feeds = [(u'Sve vijesti', u'http://www.vijesti.cg.yu/rss.php' )] def preprocess_html(self, soup): @@ -40,4 +51,10 @@ class Vijesti(BasicNewsRecipe): soup.html['lang'] = 'sr-Latn-ME' mtag = '' soup.head.insert(0,mtag) + for item in soup.findAll('img'): + if item.has_key('align'): + del item['align'] + item.insert(0,'

') return soup + + language = _('Serbian') \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/recipe_vreme.py b/src/calibre/web/feeds/recipes/recipe_vreme.py index 3f0f8b735f..27697acf8e 100644 --- a/src/calibre/web/feeds/recipes/recipe_vreme.py +++ b/src/calibre/web/feeds/recipes/recipe_vreme.py @@ -6,27 +6,34 @@ __copyright__ = '2008, Darko Miletic ' vreme.com ''' -import string,re +import re from calibre import strftime -from calibre.web.feeds.recipes import BasicNewsRecipe -class Vreme(BasicNewsRecipe): - - title = 'Vreme' - __author__ = 'Darko Miletic' - description = 'Politicki Nedeljnik Srbije' +from calibre.web.feeds.news import BasicNewsRecipe + +class Vreme(BasicNewsRecipe): + title = 'Vreme' + __author__ = 'Darko Miletic' + description = 'Politicki Nedeljnik Srbije' + publisher = 'Vreme d.o.o.' + category = 'news, politics, Serbia' no_stylesheets = True - language = _('Serbian') + remove_javascript = True needs_subscription = True INDEX = 'http://www.vreme.com' LOGIN = 'http://www.vreme.com/account/index.php' + remove_javascript = True + use_embedded_content = False + extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}' + html2lrf_options = [ - '--comment', description - , '--base-font-size', '10' - , '--category', 'news, politics, Serbia' - , '--publisher', 'Vreme d.o.o.' + '--comment', description + , '--category', category + , '--publisher', publisher ] - + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] def get_browser(self): @@ -67,10 +74,29 @@ class Vreme(BasicNewsRecipe): ,'description':description }) return [(soup.head.title.string, articles)] + + remove_tags = [ + dict(name=['object','link']) + ,dict(name='table',attrs={'xclass':'image'}) + ] def print_version(self, url): return url + '&print=yes' + def preprocess_html(self, soup): + del soup.body['text' ] + del soup.body['bgcolor'] + del soup.body['onload' ] + mtag = '' + soup.head.insert(0,mtag) + tbl = soup.body.table + tbbb = soup.find('td') + if tbbb: + tbbb.extract() + tbl.extract() + soup.body.insert(0,tbbb) + return soup + def get_cover_url(self): cover_url = None soup = self.index_to_soup(self.INDEX) @@ -78,3 +104,5 @@ class Vreme(BasicNewsRecipe): if cover_item: cover_url = self.INDEX + cover_item['src'] return cover_url + + language = _('Serbian') \ No newline at end of file From 4df669b37c50e5e5688192b294f738e75154142f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Feb 2009 13:53:40 -0800 Subject: [PATCH 05/24] Fix #1792 (non-standard line-endings for "\n" in .epubs) --- src/calibre/ebooks/html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/ebooks/html.py b/src/calibre/ebooks/html.py index 9a273c42ce..e264fec7cb 100644 --- a/src/calibre/ebooks/html.py +++ b/src/calibre/ebooks/html.py @@ -467,7 +467,7 @@ class Parser(PreProcessor, LoggingInterface): if self.htmlfile.is_binary: raise ValueError('Not a valid HTML file: '+self.htmlfile.path) src = open(self.htmlfile.path, 'rb').read().decode(self.htmlfile.encoding, 'replace').strip() - src = src.replace('\x00', '') + src = src.replace('\x00', '').replace('\r', ' ') src = self.preprocess(src) # lxml chokes on unicode input when it contains encoding declarations for pat in ENCODING_PATS: From 68f801dd24c601c57a101eea316e580031d899a4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Feb 2009 14:53:50 -0800 Subject: [PATCH 06/24] Update required version of python-mechanize ot 0.11.1. Should improve speed of news download. Fixes #1396 (very slow news download speeds) --- src/calibre/trac/plugins/download.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/trac/plugins/download.py b/src/calibre/trac/plugins/download.py index 0fee4fdb0d..63bb4006e1 100644 --- a/src/calibre/trac/plugins/download.py +++ b/src/calibre/trac/plugins/download.py @@ -30,7 +30,7 @@ class Distribution(object): ('libusb', '0.1.12', None, None, None), ('Qt', '4.4.0', 'qt', 'libqt4-core libqt4-gui', 'qt4'), ('PyQt', '4.4.2', 'PyQt4', 'python-qt4', 'PyQt4'), - ('mechanize for python', '0.1.8', 'dev-python/mechanize', 'python-mechanize', 'python-mechanize'), + ('mechanize for python', '0.1.11', 'dev-python/mechanize', 'python-mechanize', 'python-mechanize'), ('ImageMagick', '6.3.5', 'imagemagick', 'imagemagick', 'ImageMagick'), ('xdg-utils', '1.0.2', 'xdg-utils', 'xdg-utils', 'xdg-utils'), ('dbus-python', '0.82.2', 'dbus-python', 'python-dbus', 'dbus-python'), From 51f3cb775c6bee1d4fa7c7555d0bb7b371f53d18 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Feb 2009 18:12:13 -0800 Subject: [PATCH 07/24] ebook-viewer now uses system default fonts on windows. This should fix the bug with truncated characters on the right edge on the screen. --- src/calibre/gui2/main.py | 2 ++ src/calibre/gui2/viewer/documentview.py | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index b88842706a..776e549b2b 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -1223,6 +1223,8 @@ class Main(MainWindow, Ui_MainWindow): format = 'LRF' if 'EPUB' in formats: format = 'EPUB' + if 'MOBI' in formats: + format = 'MOBI' if not formats: d = error_dialog(self, _('Cannot view'), _('%s has no available formats.')%(title,)) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 6c1eca0061..3745036249 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -15,6 +15,7 @@ from calibre.utils.config import Config, StringConfig from calibre.gui2.viewer.config_ui import Ui_Dialog from calibre.gui2.viewer.js import bookmarks, referencing from calibre.ptempfile import PersistentTemporaryFile +from calibre.constants import iswindows def load_builtin_fonts(): from calibre.ebooks.lrf.fonts.liberation import LiberationMono_BoldItalic @@ -56,9 +57,12 @@ def config(defaults=None): help=_('Set the user CSS stylesheet. This can be used to customize the look of all books.')) fonts = c.add_group('FONTS', _('Font options')) - fonts('serif_family', default='Liberation Serif', help=_('The serif font family')) - fonts('sans_family', default='Liberation Sans', help=_('The sans-serif font family')) - fonts('mono_family', default='Liberation Mono', help=_('The monospaced font family')) + fonts('serif_family', default='Times New Roman' if iswindows else 'Liberation Serif', + help=_('The serif font family')) + fonts('sans_family', default='Verdana' if iswindows else 'Liberation Sans', + help=_('The sans-serif font family')) + fonts('mono_family', default='Courier New' if iswindows else 'Liberation Mono', + help=_('The monospaced font family')) fonts('default_font_size', default=20, help=_('The standard font size in px')) fonts('mono_font_size', default=16, help=_('The monospaced font size in px')) fonts('standard_font', default='serif', help=_('The standard font type')) From 18214e706beb1372cc76ddf5a234cf8f845fd2dd Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Feb 2009 22:02:59 -0800 Subject: [PATCH 08/24] EPUB Output:Add option to remove first image to GUI --- src/calibre/gui2/dialogs/epub.ui | 67 ++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/calibre/gui2/dialogs/epub.ui b/src/calibre/gui2/dialogs/epub.ui index 2d5c0fa153..b6e2299e1d 100644 --- a/src/calibre/gui2/dialogs/epub.ui +++ b/src/calibre/gui2/dialogs/epub.ui @@ -105,36 +105,6 @@ Book Cover - - - - - - - - - :/images/book.svg - - - true - - - Qt::AlignCenter - - - - - - - - - Use cover from &source file - - - true - - - @@ -186,6 +156,36 @@ + + + + Use cover from &source file + + + true + + + + + + + + + + + + :/images/book.svg + + + true + + + Qt::AlignCenter + + + + + opt_prefer_metadata_cover @@ -507,6 +507,13 @@ + + + + Remove &first image from source file + + + From 65887df713c86eeb29c5dd45f65cb59cb9c23bca Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 03:15:59 -0800 Subject: [PATCH 09/24] Fix Adding books progress dialog not being hidden after all books are added on Windows --- src/calibre/gui2/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 776e549b2b..1fda4100df 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -701,7 +701,7 @@ class Main(MainWindow, Ui_MainWindow): progress.show() try: for c, book in enumerate(paths): - progress.set_value(c) + progress.set_value(c+1) if progress.canceled: return format = os.path.splitext(book)[1] @@ -722,9 +722,11 @@ class Main(MainWindow, Ui_MainWindow): 'cover':self.default_thumbnail, 'tags':[]}) title = mi.title if isinstance(mi.title, unicode) else mi.title.decode(preferred_encoding, 'replace') progress.set_msg(_('Read metadata from ')+title) + QApplication.processEvents() if not to_device: progress.set_msg(_('Adding books to database...')) + QApplication.processEvents() model = self.library_view.model() paths = list(paths) @@ -741,6 +743,7 @@ class Main(MainWindow, Ui_MainWindow): else: self.upload_books(paths, list(map(sanitize_file_name, names)), infos, on_card=on_card) finally: + QApplication.processEvents() progress.hide() def upload_books(self, files, names, metadata, on_card=False, memory=None): From c2527cebe3ff033524e4278afb3b61d8d16d82c6 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sun, 8 Feb 2009 09:04:00 -0500 Subject: [PATCH 10/24] Cache Stylizer stylesheets based on Manifest.Item, not book-internal path --- src/calibre/ebooks/oeb/stylizer.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/calibre/ebooks/oeb/stylizer.py b/src/calibre/ebooks/oeb/stylizer.py index 574d57f5fb..b04492a167 100644 --- a/src/calibre/ebooks/oeb/stylizer.py +++ b/src/calibre/ebooks/oeb/stylizer.py @@ -17,6 +17,7 @@ import types import re import copy from itertools import izip +from weakref import WeakKeyDictionary from xml.dom import SyntaxErr as CSSSyntaxError import cssutils from cssutils.css import CSSStyleRule, CSSPageRule, CSSStyleDeclaration, \ @@ -107,7 +108,7 @@ class CSSSelector(etree.XPath): class Stylizer(object): - STYLESHEETS = {} + STYLESHEETS = WeakKeyDictionary() def __init__(self, tree, path, oeb, profile=PROFILES['PRS505']): self.oeb = oeb @@ -132,18 +133,19 @@ class Stylizer(object): and elem.get('type', CSS_MIME) in OEB_STYLES: href = urlnormalize(elem.attrib['href']) path = item.abshref(href) - if path not in oeb.manifest.hrefs: + sitem = oeb.manifest.hrefs.get(path, None) + if sitem is None: self.logger.warn( 'Stylesheet %r referenced by file %r not in manifest' % (path, item.href)) continue - if path in self.STYLESHEETS: - stylesheet = self.STYLESHEETS[path] + if sitem in self.STYLESHEETS: + stylesheet = self.STYLESHEETS[sitem] else: data = self._fetch_css_file(path)[1] stylesheet = parser.parseString(data, href=path) stylesheet.namespaces['h'] = XHTML_NS - self.STYLESHEETS[path] = stylesheet + self.STYLESHEETS[sitem] = stylesheet stylesheets.append(stylesheet) rules = [] index = 0 From e133ddda5527aa6ef65f9b89bf2619fd2adc3120 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 11:36:51 -0800 Subject: [PATCH 11/24] Fix #1799 (0.4.134: ebook-viewer doesn't open ePUB files) --- src/calibre/ebooks/metadata/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/ebooks/metadata/__init__.py b/src/calibre/ebooks/metadata/__init__.py index 2ba1e2ca92..eabd082142 100644 --- a/src/calibre/ebooks/metadata/__init__.py +++ b/src/calibre/ebooks/metadata/__init__.py @@ -287,7 +287,7 @@ class MetaInformation(object): ans += [('ISBN', unicode(self.isbn))] ans += [(_('Tags'), u', '.join([unicode(t) for t in self.tags]))] if self.series: - ans += [(_('Series'), unicode(self.series))+ ' #%s'%self.format_series_index()] + ans += [(_('Series'), unicode(self.series)+ ' #%s'%self.format_series_index())] ans += [(_('Language'), unicode(self.language))] for i, x in enumerate(ans): ans[i] = u'%s%s'%x From 526bdc6049ac1cb23e9eaab80d5dc19fec386885 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 12:07:12 -0800 Subject: [PATCH 12/24] LRF Output: Resize rather than crop images when the img tag specifies a width and height smaller than the actual image size. Fixes #1793 (Semi-failed conversion HTML to LRF) --- src/calibre/ebooks/lrf/html/convert_from.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/calibre/ebooks/lrf/html/convert_from.py b/src/calibre/ebooks/lrf/html/convert_from.py index 673c92ebb9..48c2ffe993 100644 --- a/src/calibre/ebooks/lrf/html/convert_from.py +++ b/src/calibre/ebooks/lrf/html/convert_from.py @@ -917,7 +917,8 @@ class HTMLConverter(object, LoggingInterface): blockStyle=self.current_block.blockStyle) - def process_image(self, path, tag_css, width=None, height=None, dropcaps=False): + def process_image(self, path, tag_css, width=None, height=None, + dropcaps=False, rescale=False): def detect_encoding(im): fmt = im.format if fmt == 'JPG': @@ -936,10 +937,6 @@ class HTMLConverter(object, LoggingInterface): return encoding = detect_encoding(im) - if width == None or height == None: - width, height = im.size - - factor = 720./self.profile.dpi def scale_image(width, height): if width <= 0: @@ -955,8 +952,15 @@ class HTMLConverter(object, LoggingInterface): return pt.name except (IOError, SystemError), err: # PIL chokes on interlaced PNG images as well a some GIF images self.log_warning(_('Unable to process image %s. Error: %s')%(path, err)) - return None + if width == None or height == None: + width, height = im.size + elif rescale and (width < im.size[0] or height < im.size[1]): + path = scale_image(width, height) + if not path: + return + + factor = 720./self.profile.dpi pheight = int(self.current_page.pageStyle.attrs['textheight']) pwidth = int(self.current_page.pageStyle.attrs['textwidth']) @@ -1518,7 +1522,8 @@ class HTMLConverter(object, LoggingInterface): except: pass dropcaps = tag.has_key('class') and tag['class'] == 'libprs500_dropcaps' - self.process_image(path, tag_css, width, height, dropcaps=dropcaps) + self.process_image(path, tag_css, width, height, + dropcaps=dropcaps, rescale=True) elif not urlparse(tag['src'])[0]: self.log_warn('Could not find image: '+tag['src']) else: From 2a474382d020dffd8234f9fa3be9563ae8f18aa5 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 16:54:19 -0800 Subject: [PATCH 13/24] Fix #1801 (Error when fetching cover.) --- src/calibre/ebooks/metadata/library_thing.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/calibre/ebooks/metadata/library_thing.py b/src/calibre/ebooks/metadata/library_thing.py index fdecf3fa99..8cc1282067 100644 --- a/src/calibre/ebooks/metadata/library_thing.py +++ b/src/calibre/ebooks/metadata/library_thing.py @@ -37,9 +37,14 @@ def cover_from_isbn(isbn, timeout=5.): if browser is None: browser = _browser() _timeout = socket.getdefaulttimeout() - socket.setdefaulttimeout(timeout) + socket.setdefaulttimeout(timeout) + src = None try: src = browser.open('http://www.librarything.com/isbn/'+isbn).read().decode('utf-8', 'replace') + except Exception, err: + if isinstance(getattr(err, 'args', [None])[0], socket.timeout): + raise LibraryThingError(_('LibraryThing.com timed out. Try again later.')) + raise s = BeautifulSoup(src) url = s.find('td', attrs={'class':'left'}) if url is None: From f8aa3bf8de8350331721ebb4dccf7d7630ec6bdc Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 17:10:53 -0800 Subject: [PATCH 14/24] Set cover in MOBI files when saving to disk. Also update metadata in LRF, EPUB and MOBI files when sending to device. --- src/calibre/ebooks/metadata/epub.py | 2 +- src/calibre/ebooks/metadata/mobi.py | 34 ++++--- src/calibre/ebooks/mobi/langcodes.py | 16 ++-- src/calibre/gui2/library.py | 6 +- src/calibre/gui2/main.py | 3 +- src/calibre/library/database.py | 113 +--------------------- src/calibre/library/database2.py | 138 ++++++++++++++++++++++++++- 7 files changed, 173 insertions(+), 139 deletions(-) diff --git a/src/calibre/ebooks/metadata/epub.py b/src/calibre/ebooks/metadata/epub.py index 360869cc9c..18e68e4b32 100644 --- a/src/calibre/ebooks/metadata/epub.py +++ b/src/calibre/ebooks/metadata/epub.py @@ -18,7 +18,7 @@ from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup from calibre.ebooks.metadata import get_parser, MetaInformation from calibre.ebooks.metadata.opf2 import OPF from calibre.ptempfile import TemporaryDirectory -from calibre import CurrentDir, fit_image +from calibre import CurrentDir class EPubException(Exception): pass diff --git a/src/calibre/ebooks/metadata/mobi.py b/src/calibre/ebooks/metadata/mobi.py index d31e19a03e..815b293c42 100644 --- a/src/calibre/ebooks/metadata/mobi.py +++ b/src/calibre/ebooks/metadata/mobi.py @@ -23,8 +23,8 @@ class StreamSlicer(object): def __init__(self, stream, start=0, stop=None): self._stream = stream self.start = start - if stop is None: - stream.seek(0, 2) + if stop is None: + stream.seek(0, 2) stop = stream.tell() self.stop = stop self._len = stop - start @@ -74,7 +74,7 @@ class StreamSlicer(object): raise TypeError("stream indices must be integers") -class MetadataUpdater(object): +class MetadataUpdater(object): def __init__(self, stream): self.stream = stream data = self.data = StreamSlicer(stream) @@ -151,18 +151,22 @@ class MetadataUpdater(object): self.exth[:] = ''.join([exth, title, '\0' * trail]) self.record0[84:92] = pack('>II', title_off, title_len) self.record0[92:96] = iana2mobi(mi.language) - if mi.cover_data[1]: - data = mi.cover_data[1] - if self.cover_record is not None: - size = len(self.cover_record) - cover = rescale_image(data, size) - cover += '\0' * (size - len(cover)) - self.cover_record[:] = cover - if self.thumbnail_record is not None: - size = len(self.thumbnail_record) - thumbnail = rescale_image(data, size, dimen=MAX_THUMB_DIMEN) - thumbnail += '\0' * (size - len(thumbnail)) - self.thumbnail_record[:] = thumbnail + if mi.cover_data[1] or mi.cover: + try: + data = mi.cover_data[1] if mi.cover_data[1] else open(mi.cover, 'rb').read() + except: + pass + else: + if self.cover_record is not None: + size = len(self.cover_record) + cover = rescale_image(data, size) + cover += '\0' * (size - len(cover)) + self.cover_record[:] = cover + if self.thumbnail_record is not None: + size = len(self.thumbnail_record) + thumbnail = rescale_image(data, size, dimen=MAX_THUMB_DIMEN) + thumbnail += '\0' * (size - len(thumbnail)) + self.thumbnail_record[:] = thumbnail return def set_metadata(stream, mi): diff --git a/src/calibre/ebooks/mobi/langcodes.py b/src/calibre/ebooks/mobi/langcodes.py index 5df11c4e38..da0b3ef62e 100644 --- a/src/calibre/ebooks/mobi/langcodes.py +++ b/src/calibre/ebooks/mobi/langcodes.py @@ -306,13 +306,15 @@ IANA_MOBI = \ 'zu': {None: (53, 0)}} def iana2mobi(icode): - subtags = list(icode.split('-')) - langdict = IANA_MOBI[None] - while len(subtags) > 0: - lang = subtags.pop(0).lower() - if lang in IANA_MOBI: - langdict = IANA_MOBI[lang] - break + langdict, subtags = IANA_MOBI[None], [] + if icode: + subtags = list(icode.split('-')) + while len(subtags) > 0: + lang = subtags.pop(0).lower() + if lang in IANA_MOBI: + langdict = IANA_MOBI[lang] + break + mcode = langdict[None] while len(subtags) > 0: subtag = subtags.pop(0) diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py index 2b0148a194..9f0877ca09 100644 --- a/src/calibre/gui2/library.py +++ b/src/calibre/gui2/library.py @@ -18,6 +18,7 @@ from calibre.library.database2 import FIELD_MAP from calibre.gui2 import NONE, TableView, qstring_to_unicode, config, \ error_dialog from calibre.utils.search_query_parser import SearchQueryParser +from calibre.ebooks.metadata.meta import set_metadata as _set_metadata class LibraryDelegate(QItemDelegate): COLOR = QColor("blue") @@ -423,7 +424,7 @@ class BooksModel(QAbstractTableModel): - def get_preferred_formats(self, rows, formats, paths=False): + def get_preferred_formats(self, rows, formats, paths=False, set_metadata=False): ans = [] for row in (row.row() for row in rows): format = None @@ -441,6 +442,9 @@ class BooksModel(QAbstractTableModel): pt = PersistentTemporaryFile(suffix='.'+format) pt.write(self.db.format(row, format)) pt.flush() + if set_metadata: + _set_metadata(pt, self.db.get_metadata(row, get_cover=True), + format) pt.close() if paths else pt.seek(0) ans.append(pt) else: diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 1fda4100df..3649a2264b 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -932,7 +932,8 @@ class Main(MainWindow, Ui_MainWindow): mi['cover'] = self.cover_to_thumbnail(cdata) metadata = iter(metadata) _files = self.library_view.model().get_preferred_formats(rows, - self.device_manager.device_class.FORMATS, paths=True) + self.device_manager.device_class.FORMATS, + paths=True, set_metadata=True) files = [getattr(f, 'name', None) for f in _files] bad, good, gf, names, remove_ids = [], [], [], [], [] for f in files: diff --git a/src/calibre/library/database.py b/src/calibre/library/database.py index 2979c95d26..37fdeb4ce4 100644 --- a/src/calibre/library/database.py +++ b/src/calibre/library/database.py @@ -4,12 +4,11 @@ __copyright__ = '2008, Kovid Goyal ' Backend that implements storage of ebooks in an sqlite database. ''' import sqlite3 as sqlite -import datetime, re, os, cPickle, traceback, sre_constants +import datetime, re, os, cPickle, sre_constants from zlib import compress, decompress from calibre import sanitize_file_name from calibre.ebooks.metadata.meta import set_metadata, metadata_from_formats -from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.metadata import MetaInformation from calibre.ebooks import BOOK_EXTENSIONS from calibre.web.feeds.recipes import migrate_automatic_profile_to_automatic_recipe @@ -1389,77 +1388,7 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; def all_ids(self): return [i[0] for i in self.conn.get('SELECT id FROM books')] - def export_to_dir(self, dir, indices, byauthor=False, single_dir=False, - index_is_id=False, callback=None): - if not os.path.exists(dir): - raise IOError('Target directory does not exist: '+dir) - by_author = {} - count = 0 - for index in indices: - id = index if index_is_id else self.id(index) - au = self.conn.get('SELECT author_sort FROM books WHERE id=?', - (id,), all=False) - if not au: - au = self.authors(index, index_is_id=index_is_id) - if not au: - au = _('Unknown') - au = au.split(',')[0] - if not by_author.has_key(au): - by_author[au] = [] - by_author[au].append(index) - for au in by_author.keys(): - apath = os.path.join(dir, sanitize_file_name(au)) - if not single_dir and not os.path.exists(apath): - os.mkdir(apath) - for idx in by_author[au]: - title = re.sub(r'\s', ' ', self.title(idx, index_is_id=index_is_id)) - tpath = os.path.join(apath, sanitize_file_name(title)) - id = idx if index_is_id else self.id(idx) - id = str(id) - if not single_dir and not os.path.exists(tpath): - os.mkdir(tpath) - - name = au + ' - ' + title if byauthor else title + ' - ' + au - name += '_'+id - base = dir if single_dir else tpath - mi = self.get_metadata(idx, index_is_id=index_is_id) - cover = self.cover(idx, index_is_id=index_is_id) - if cover is not None: - cname = sanitize_file_name(name) + '.jpg' - cpath = os.path.join(base, cname) - open(cpath, 'wb').write(cover) - mi.cover = cname - f = open(os.path.join(base, sanitize_file_name(name)+'.opf'), 'wb') - if not mi.authors: - mi.authors = [_('Unknown')] - opf = OPFCreator(base, mi) - opf.render(f) - f.close() - - fmts = self.formats(idx, index_is_id=index_is_id) - if not fmts: - fmts = '' - for fmt in fmts.split(','): - data = self.format(idx, fmt, index_is_id=index_is_id) - if not data: - continue - fname = name +'.'+fmt.lower() - fname = sanitize_file_name(fname) - f = open(os.path.join(base, fname), 'w+b') - f.write(data) - f.flush() - f.seek(0) - try: - set_metadata(f, mi, fmt.lower()) - except: - print 'Error setting metadata for book:', mi.title - traceback.print_exc() - f.close() - count += 1 - if callable(callback): - if not callback(count, mi.title): - return - + def import_book(self, mi, formats): @@ -1573,43 +1502,7 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; return duplicates - def export_single_format_to_dir(self, dir, indices, format, - index_is_id=False, callback=None): - dir = os.path.abspath(dir) - if not index_is_id: - indices = map(self.id, indices) - failures = [] - for count, id in enumerate(indices): - try: - data = self.format(id, format, index_is_id=True) - if not data: - failures.append((id, self.title(id, index_is_id=True))) - continue - except: - failures.append((id, self.title(id, index_is_id=True))) - continue - title = self.title(id, index_is_id=True) - au = self.authors(id, index_is_id=True) - if not au: - au = _('Unknown') - fname = '%s - %s.%s'%(title, au, format.lower()) - fname = sanitize_file_name(fname) - if not os.path.exists(dir): - os.makedirs(dir) - f = open(os.path.join(dir, fname), 'w+b') - f.write(data) - f.seek(0) - try: - set_metadata(f, self.get_metadata(id, index_is_id=True), stream_type=format.lower()) - except: - pass - f.close() - if callable(callback): - if not callback(count, title): - break - return failures - - + class SearchToken(object): diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 4a2c669a25..8c762f8680 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -19,8 +19,9 @@ from calibre.library import title_sort from calibre.library.database import LibraryDatabase from calibre.library.sqlite import connect, IntegrityError from calibre.utils.search_query_parser import SearchQueryParser -from calibre.ebooks.metadata import string_to_authors, authors_to_string -from calibre.ebooks.metadata.meta import get_metadata +from calibre.ebooks.metadata import string_to_authors, authors_to_string, MetaInformation +from calibre.ebooks.metadata.meta import get_metadata, set_metadata +from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.constants import preferred_encoding, iswindows, isosx, filesystem_encoding from calibre.ptempfile import PersistentTemporaryFile from calibre.customize.ui import run_plugins_on_import @@ -556,7 +557,8 @@ class LibraryDatabase2(LibraryDatabase): traceback.print_exc() continue - def cover(self, index, index_is_id=False, as_file=False, as_image=False): + def cover(self, index, index_is_id=False, as_file=False, as_image=False, + as_path=False): ''' Return the cover image as a bytestring (in JPEG format) or None. @@ -566,6 +568,8 @@ class LibraryDatabase2(LibraryDatabase): id = index if index_is_id else self.id(index) path = os.path.join(self.library_path, self.path(id, index_is_id=True), 'cover.jpg') if os.access(path, os.R_OK): + if as_path: + return path f = open(path, 'rb') if as_image: img = QImage() @@ -573,6 +577,30 @@ class LibraryDatabase2(LibraryDatabase): return img return f if as_file else f.read() + def get_metadata(self, idx, index_is_id=False, get_cover=False): + ''' + Convenience method to return metadata as a L{MetaInformation} object. + ''' + aum = self.authors(idx, index_is_id=index_is_id) + if aum: aum = [a.strip().replace('|', ',') for a in aum.split(',')] + mi = MetaInformation(self.title(idx, index_is_id=index_is_id), aum) + mi.author_sort = self.author_sort(idx, index_is_id=index_is_id) + mi.comments = self.comments(idx, index_is_id=index_is_id) + mi.publisher = self.publisher(idx, index_is_id=index_is_id) + tags = self.tags(idx, index_is_id=index_is_id) + if tags: + mi.tags = [i.strip() for i in tags.split(',')] + mi.series = self.series(idx, index_is_id=index_is_id) + if mi.series: + mi.series_index = self.series_index(idx, index_is_id=index_is_id) + mi.rating = self.rating(idx, index_is_id=index_is_id) + mi.isbn = self.isbn(idx, index_is_id=index_is_id) + id = idx if index_is_id else self.id(idx) + mi.application_id = id + if get_cover: + mi.cover = self.cover(id, index_is_id=True, as_path=True) + return mi + def has_book(self, mi): title = mi.title if title: @@ -1322,5 +1350,107 @@ books_series_link feeds self.vacuum() progress.reset() return len(books) - + + def export_to_dir(self, dir, indices, byauthor=False, single_dir=False, + index_is_id=False, callback=None): + if not os.path.exists(dir): + raise IOError('Target directory does not exist: '+dir) + by_author = {} + count = 0 + for index in indices: + id = index if index_is_id else self.id(index) + au = self.conn.get('SELECT author_sort FROM books WHERE id=?', + (id,), all=False) + if not au: + au = self.authors(index, index_is_id=index_is_id) + if not au: + au = _('Unknown') + au = au.split(',')[0] + if not by_author.has_key(au): + by_author[au] = [] + by_author[au].append(index) + for au in by_author.keys(): + apath = os.path.join(dir, sanitize_file_name(au)) + if not single_dir and not os.path.exists(apath): + os.mkdir(apath) + for idx in by_author[au]: + title = re.sub(r'\s', ' ', self.title(idx, index_is_id=index_is_id)) + tpath = os.path.join(apath, sanitize_file_name(title)) + id = idx if index_is_id else self.id(idx) + id = str(id) + if not single_dir and not os.path.exists(tpath): + os.mkdir(tpath) + + name = au + ' - ' + title if byauthor else title + ' - ' + au + name += '_'+id + base = dir if single_dir else tpath + mi = self.get_metadata(idx, index_is_id=index_is_id, get_cover=True) + f = open(os.path.join(base, sanitize_file_name(name)+'.opf'), 'wb') + if not mi.authors: + mi.authors = [_('Unknown')] + opf = OPFCreator(base, mi) + opf.render(f) + f.close() + + fmts = self.formats(idx, index_is_id=index_is_id) + if not fmts: + fmts = '' + for fmt in fmts.split(','): + data = self.format(idx, fmt, index_is_id=index_is_id) + if not data: + continue + fname = name +'.'+fmt.lower() + fname = sanitize_file_name(fname) + f = open(os.path.join(base, fname), 'w+b') + f.write(data) + f.flush() + f.seek(0) + try: + set_metadata(f, mi, fmt.lower()) + except: + pass + f.close() + count += 1 + if callable(callback): + if not callback(count, mi.title): + return + + def export_single_format_to_dir(self, dir, indices, format, + index_is_id=False, callback=None): + dir = os.path.abspath(dir) + if not index_is_id: + indices = map(self.id, indices) + failures = [] + for count, id in enumerate(indices): + try: + data = self.format(id, format, index_is_id=True) + if not data: + failures.append((id, self.title(id, index_is_id=True))) + continue + except: + failures.append((id, self.title(id, index_is_id=True))) + continue + title = self.title(id, index_is_id=True) + au = self.authors(id, index_is_id=True) + if not au: + au = _('Unknown') + fname = '%s - %s.%s'%(title, au, format.lower()) + fname = sanitize_file_name(fname) + if not os.path.exists(dir): + os.makedirs(dir) + f = open(os.path.join(dir, fname), 'w+b') + f.write(data) + f.seek(0) + try: + set_metadata(f, self.get_metadata(id, index_is_id=True, get_cover=True), + stream_type=format.lower()) + except: + pass + f.close() + if callable(callback): + if not callback(count, title): + break + return failures + + From d439798750ff3da8e56f027c38a4f9cc9553c656 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 17:35:39 -0800 Subject: [PATCH 15/24] IGN:Fix minor bugs in setting metadata for MOBI and EPUB --- src/calibre/customize/ui.py | 1 + src/calibre/ebooks/metadata/mobi.py | 4 +++- src/calibre/ebooks/metadata/opf2.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index c79b4ed98e..7374eaba11 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -141,6 +141,7 @@ def set_file_type_metadata(stream, mi, ftype): plugin.set_metadata(stream, mi, ftype.lower().strip()) break except: + print 'Failed to set metadata for', repr(getattr(mi, 'title', '')) traceback.print_exc() diff --git a/src/calibre/ebooks/metadata/mobi.py b/src/calibre/ebooks/metadata/mobi.py index 815b293c42..b464b6553f 100644 --- a/src/calibre/ebooks/metadata/mobi.py +++ b/src/calibre/ebooks/metadata/mobi.py @@ -86,9 +86,9 @@ class MetadataUpdater(object): image_base, = unpack('>I', record0[108:112]) flags, = unpack('>I', record0[128:132]) have_exth = self.have_exth = (flags & 0x40) != 0 + self.cover_record = self.thumbnail_record = None if not have_exth: return - self.cover_record = self.thumbnail_record = None exth_off = unpack('>I', record0[20:24])[0] + 16 + record0.start exth = self.exth = StreamSlicer(stream, exth_off, record0.stop) nitems, = unpack('>I', exth[8:12]) @@ -143,6 +143,8 @@ class MetadataUpdater(object): exth = ['EXTH', pack('>II', len(exth) + 12, len(recs)), exth, pad] exth = ''.join(exth) title = (mi.title or _('Unknown')).encode(self.codec, 'replace') + if getattr(self, 'exth', None) is None: + raise MobiError('No existing EXTH record. Cannot update metadata.') title_off = (self.exth.start - self.record0.start) + len(exth) title_len = len(title) trail = len(self.exth) - len(exth) - len(title) diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 2e6fe598ec..32ba2cb45a 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -618,7 +618,7 @@ class OPF(object): def fset(self, val): remove = list(self.authors_path(self.metadata)) for elem in remove: - self.metadata.remove(elem) + elem.getparent().remove(elem) for author in val: attrib = {'{%s}role'%self.NAMESPACES['opf']: 'aut'} elem = self.create_metadata_element('creator', attrib=attrib) From 99a477a18663a36d01012fabf504473eb8314551 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 18:14:35 -0800 Subject: [PATCH 16/24] IGN:... --- src/calibre/web/feeds/recipes/recipe_honoluluadvertiser.py | 1 + src/calibre/web/feeds/recipes/recipe_jutarnji.py | 3 ++- src/calibre/web/feeds/recipes/recipe_starbulletin.py | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/calibre/web/feeds/recipes/recipe_honoluluadvertiser.py b/src/calibre/web/feeds/recipes/recipe_honoluluadvertiser.py index ef36a700ed..d4f3e0a3ab 100644 --- a/src/calibre/web/feeds/recipes/recipe_honoluluadvertiser.py +++ b/src/calibre/web/feeds/recipes/recipe_honoluluadvertiser.py @@ -15,6 +15,7 @@ class Honoluluadvertiser(BasicNewsRecipe): publisher = 'Honolulu Advertiser' category = 'news, Honolulu, Hawaii' oldest_article = 2 + language = _('English') max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False diff --git a/src/calibre/web/feeds/recipes/recipe_jutarnji.py b/src/calibre/web/feeds/recipes/recipe_jutarnji.py index 194d2163f9..03c22c9b99 100644 --- a/src/calibre/web/feeds/recipes/recipe_jutarnji.py +++ b/src/calibre/web/feeds/recipes/recipe_jutarnji.py @@ -20,6 +20,7 @@ class Jutarnji(BasicNewsRecipe): max_articles_per_feed = 100 simultaneous_downloads = 1 delay = 1 + language = _('Croatian') no_stylesheets = True use_embedded_content = False remove_javascript = True @@ -68,4 +69,4 @@ class Jutarnji(BasicNewsRecipe): for item in soup.findAll(width=True): del item['width'] return soup - \ No newline at end of file + diff --git a/src/calibre/web/feeds/recipes/recipe_starbulletin.py b/src/calibre/web/feeds/recipes/recipe_starbulletin.py index db99ebcec7..4fc9e51a8c 100644 --- a/src/calibre/web/feeds/recipes/recipe_starbulletin.py +++ b/src/calibre/web/feeds/recipes/recipe_starbulletin.py @@ -16,6 +16,7 @@ class Starbulletin(BasicNewsRecipe): category = 'news, Honolulu, Hawaii' oldest_article = 2 max_articles_per_feed = 100 + language = _('English') no_stylesheets = True use_embedded_content = False encoding = 'utf8' From 5b32638db4c982336978914f8f03453259ca4db8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 18:27:28 -0800 Subject: [PATCH 17/24] IGN:... --- src/calibre/trac/donations/server.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/calibre/trac/donations/server.py b/src/calibre/trac/donations/server.py index 0141c6a317..d7ffde63e2 100644 --- a/src/calibre/trac/donations/server.py +++ b/src/calibre/trac/donations/server.py @@ -236,7 +236,9 @@ Donors per day: %(dpd).2f ml = mdates.MonthLocator() # every month fig = plt.figure(1, (8, 4), 96)#, facecolor, edgecolor, frameon, FigureClass) ax = fig.add_subplot(111) + average = sum(y)/len(y) ax.bar(x, y, align='center', width=20, color='g') + ax.hlines([average], x[0], x[-1]) ax.xaxis.set_major_locator(ml) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %y')) ax.set_xlim(_months[0].min-timedelta(days=15), _months[-1].min+timedelta(days=15)) From 9220c79d736247534cf08ed89aee4c8b3fa9e29b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 19:29:58 -0800 Subject: [PATCH 18/24] IGN:SUpport for multiple ids in device scanner --- src/calibre/devices/scanner.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/calibre/devices/scanner.py b/src/calibre/devices/scanner.py index f0cd9a66eb..a93ef54c32 100644 --- a/src/calibre/devices/scanner.py +++ b/src/calibre/devices/scanner.py @@ -58,17 +58,20 @@ class DeviceScanner(object): return False def is_device_connected(self, device): + vendor_ids = device.VENDOR_ID if hasattr(device.VENDOR_ID, '__len__') else [device.VENDOR_ID] + product_ids = device.PRODUCT_ID if hasattr(device.PRODUCT_ID, '__len__') else [device.PRODUCT_ID] if iswindows: - vid, pid = 'vid_%4.4x'%device.VENDOR_ID, 'pid_%4.4x'%device.PRODUCT_ID - vidd, pidd = 'vid_%i'%device.VENDOR_ID, 'pid_%i'%device.PRODUCT_ID - for device_id in self.devices: - if (vid in device_id or vidd in device_id) and (pid in device_id or pidd in device_id): - if self.test_bcd_windows(device_id, getattr(device, 'BCD', None)): - if device.can_handle(device_id): - return True + for vendor_id, product_id in zip(vendor_ids, product_ids): + vid, pid = 'vid_%4.4x'%vendor_id, 'pid_%4.4x'%product_id + vidd, pidd = 'vid_%i'%vendor_id, 'pid_%i'%product_id + for device_id in self.devices: + if (vid in device_id or vidd in device_id) and (pid in device_id or pidd in device_id): + if self.test_bcd_windows(device_id, getattr(device, 'BCD', None)): + if device.can_handle(device_id): + return True else: for vendor, product, bcdDevice in self.devices: - if device.VENDOR_ID == vendor and device.PRODUCT_ID == product: + if vendor in vendor_ids and product in product_ids: if self.test_bcd(bcdDevice, getattr(device, 'BCD', None)): if device.can_handle((vendor, product, bcdDevice)): return True From 167fb7a7bc2ea4861a21cdf7a31a1b7a2fd24d4c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 20:39:42 -0800 Subject: [PATCH 19/24] New recipe for The Indianapolis Star by Owen Kelly --- src/calibre/web/feeds/recipes/__init__.py | 2 +- src/calibre/web/feeds/recipes/recipe_indy_star.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/calibre/web/feeds/recipes/recipe_indy_star.py diff --git a/src/calibre/web/feeds/recipes/__init__.py b/src/calibre/web/feeds/recipes/__init__.py index 161666d45d..623d9df6b7 100644 --- a/src/calibre/web/feeds/recipes/__init__.py +++ b/src/calibre/web/feeds/recipes/__init__.py @@ -27,7 +27,7 @@ recipe_modules = ['recipe_' + r for r in ( 'shacknews', 'teleread', 'granma', 'juventudrebelde', 'juventudrebelde_english', 'la_tercera', 'el_mercurio_chile', 'la_cuarta', 'lanacion_chile', 'la_segunda', 'jb_online', 'estadao', 'o_globo', 'vijesti', 'elmundo', 'the_oz', - 'honoluluadvertiser', 'starbulletin', 'exiled', + 'honoluluadvertiser', 'starbulletin', 'exiled', 'indy_star', )] import re, imp, inspect, time, os diff --git a/src/calibre/web/feeds/recipes/recipe_indy_star.py b/src/calibre/web/feeds/recipes/recipe_indy_star.py new file mode 100644 index 0000000000..81efa77dbe --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_indy_star.py @@ -0,0 +1,15 @@ +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1234144423(BasicNewsRecipe): + title = u'Indianapolis Star' + oldest_article = 5 + language = _('English') + __author__ = 'Owen Kelly' + max_articles_per_feed = 100 + + cover_url = u'http://www2.indystar.com/frontpage/images/today.jpg' + + feeds = [(u'Community Headlines', u'http://www.indystar.com/apps/pbcs.dll/section?Category=LOCAL&template=rss&mime=XML'), (u'News Headlines', u'http://www.indystar.com/apps/pbcs.dll/section?Category=NEWS&template=rss&mime=XML'), (u'Business Headlines', u'http://www..indystar.com/apps/pbcs.dll/section?Category=BUSINESS&template=rss&mime=XML'), (u'Sports Headlines', u'http://www.indystar.com/apps/pbcs.dll/section?Category=SPORTS&template=rss&mime=XML'), (u'Lifestyle Headlines', u'http://www.indystar.com/apps/pbcs.dll/section?Category=LIVING&template=rss&mime=XML'), (u'Opinion Headlines', u'http://www.indystar.com/apps/pbcs.dll/section?Category=OPINION&template=rss&mime=XML')] + + def print_version(self, url): + return url + '&template=printart' \ No newline at end of file From 6d5648fbdcf12bddda8346c445256c944ddb9a61 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Feb 2009 21:46:51 -0800 Subject: [PATCH 20/24] IGN:Updated translations --- src/calibre/translations/ar.po | 1595 ++++++++++++++++------------- src/calibre/translations/bg.po | 1593 ++++++++++++++++------------- src/calibre/translations/ca.po | 1579 ++++++++++++++++------------- src/calibre/translations/cs.po | 1593 ++++++++++++++++------------- src/calibre/translations/de.po | 1645 +++++++++++++++++------------- src/calibre/translations/el.po | 1593 ++++++++++++++++------------- src/calibre/translations/es.po | 1683 ++++++++++++++++++------------- src/calibre/translations/fr.po | 1579 ++++++++++++++++------------- src/calibre/translations/gl.po | 1593 ++++++++++++++++------------- src/calibre/translations/hu.po | 1607 ++++++++++++++++------------- src/calibre/translations/it.po | 1643 +++++++++++++++++------------- src/calibre/translations/nb.po | 1593 ++++++++++++++++------------- src/calibre/translations/nds.po | 1645 +++++++++++++++++------------- src/calibre/translations/nl.po | 1584 ++++++++++++++++------------- src/calibre/translations/pl.po | 1598 ++++++++++++++++------------- src/calibre/translations/pt.po | 1607 ++++++++++++++++------------- src/calibre/translations/ro.po | 1595 ++++++++++++++++------------- src/calibre/translations/ru.po | 1643 +++++++++++++++++------------- src/calibre/translations/sk.po | 1638 +++++++++++++++++------------- src/calibre/translations/sl.po | 1584 ++++++++++++++++------------- src/calibre/translations/sv.po | 1593 ++++++++++++++++------------- src/calibre/translations/te.po | 1579 ++++++++++++++++------------- 22 files changed, 20339 insertions(+), 15023 deletions(-) diff --git a/src/calibre/translations/ar.po b/src/calibre/translations/ar.po index f615c21206..2c62c5cd3c 100644 --- a/src/calibre/translations/ar.po +++ b/src/calibre/translations/ar.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: calibre\n" "Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2009-01-27 01:54+0000\n" +"POT-Creation-Date: 2009-02-08 21:09+0000\n" "PO-Revision-Date: 2009-02-04 10:04+0000\n" -"Last-Translator: Abdellah Chelli \n" +"Last-Translator: عبد الله شلي (Abdellah Chelli) \n" "Language-Team: Arabic \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2009-02-04 21:04+0000\n" +"X-Launchpad-Export-Date: 2009-02-09 05:36+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41 @@ -23,9 +23,10 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/__init__.py:44 #: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:71 -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:497 -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:989 -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1002 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:498 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1014 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1030 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1032 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:77 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:79 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:81 @@ -42,8 +43,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:199 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:229 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:232 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:255 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:277 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:261 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:283 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:45 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:47 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/meta.py:87 @@ -51,30 +52,33 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:145 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:334 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:449 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:820 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:849 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:12 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:36 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:66 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:477 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:60 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:118 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:479 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/to_oeb.py:46 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:361 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:366 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:858 -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:861 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:569 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:574 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1150 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1153 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:53 #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftrim.py:54 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:48 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:168 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:170 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:365 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:37 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:33 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:38 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:362 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:376 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:899 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:700 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:942 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:945 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:900 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:717 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:962 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:965 #: /home/kovid/work/calibre/src/calibre/gui2/tools.py:61 #: /home/kovid/work/calibre/src/calibre/gui2/tools.py:123 #: /home/kovid/work/calibre/src/calibre/library/cli.py:257 @@ -83,10 +87,12 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/library/database.py:1434 #: /home/kovid/work/calibre/src/calibre/library/database.py:1468 #: /home/kovid/work/calibre/src/calibre/library/database.py:1594 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:473 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:485 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:828 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:861 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:466 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:478 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:831 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:864 +#: /home/kovid/work/calibre/src/calibre/library/server.py:315 +#: /home/kovid/work/calibre/src/calibre/web/feeds/news.py:51 msgid "Unknown" msgstr "مجهول" @@ -207,7 +213,7 @@ msgid "Disable the named plugin" msgstr "عطل الملحق المسمى" #: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:41 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:384 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:385 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:70 msgid "The reader has no storage card connected." msgstr "" @@ -223,11 +229,11 @@ msgid "There is insufficient free space in main memory" msgstr "لا توجد مساحة كافية في الذاكرة الرئيسية" #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:140 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:167 -#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:195 -#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:191 -#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:227 -#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:254 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:168 +#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:196 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:192 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:228 +#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:255 msgid "Unable to detect the %s disk drive. Try rebooting." msgstr "" @@ -241,24 +247,24 @@ msgid "" "name." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:107 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:108 msgid "" "Profile of the target device this EPUB is meant for. Set to None to create a " "device independent EPUB. The profile is used for device specific " "restrictions on the EPUB. Choices are: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:109 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:113 msgid "" "Either the path to a CSS stylesheet or raw CSS. This CSS will override any " "existing CSS declarations in the source files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:110 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:117 msgid "Control auto-detection of document structure." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:112 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:122 msgid "" "An XPath expression to detect chapter titles. The default is to consider " "

or\n" @@ -272,7 +278,7 @@ msgid "" "help on using this feature.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:121 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:132 msgid "" "Specify how to mark detected chapters. A value of \"pagebreak\" will insert " "page breaks before chapters. A value of \"rule\" will insert a line before " @@ -280,17 +286,23 @@ msgid "" "\"both\" will use both page breaks and lines to mark chapters." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:123 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:139 msgid "Path to the cover to be used for this book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:142 msgid "" "Use the cover detected from the source file in preference to the specified " "cover." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:128 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:145 +msgid "" +"Remove the first image from the input ebook. Useful if the first image in " +"the source file is a cover and you are specifying an external cover." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:149 msgid "" "Turn off splitting at page breaks. Normally, input files are automatically " "split at every page break into two files. This gives an output ebook that " @@ -299,7 +311,20 @@ msgid "" "turn off splitting on page breaks." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:130 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:157 +msgid "" +"XPath expression to detect page boundaries for building a custom pagination " +"map, as used by AdobeDE. Default is not to build an explicit pagination map." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:161 +msgid "" +"XPath expression to find the name of each page in the pagination map " +"relative to its boundary element. Default is to number all pages staring " +"with 1." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:165 msgid "" "Control the automatic generation of a Table of Contents. If an OPF file is " "detected\n" @@ -308,38 +333,45 @@ msgid "" "to auto-generate a Table of Contents.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:171 msgid "" "Maximum number of links to insert into the TOC. Set to 0 to disable. Default " "is: %default. Links are only added to the TOC if less than the --toc-" "threshold number of chapters were detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:175 msgid "Don't add auto-detected chapters to the Table of Contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:177 msgid "" "If fewer than this number of chapters is detected, then links are added to " "the Table of Contents. Default: %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:142 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:180 msgid "" "XPath expression that specifies all tags that should be added to the Table " "of Contents at level one. If this is specified, it takes precedence over " "other forms of auto-detection." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:144 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:184 msgid "" "XPath expression that specifies all tags that should be added to the Table " "of Contents at level two. Each entry is added under the previous level one " "entry." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:146 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:188 +msgid "" +"XPath expression that specifies all tags that should be added to the Table " +"of Contents at level three. Each entry is added under the previous level two " +"entry." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:192 msgid "" "Path to a .ncx file that contains the table of contents to use for this " "ebook. The NCX file should contain links relative to the directory it is " @@ -347,65 +379,77 @@ msgid "" "an overview of the NCX format." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:148 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:198 msgid "" "Normally, if the source file already has a Table of Contents, it is used in " "preference to the autodetected one. With this option, the autodetected one " "is always used." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:150 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:202 msgid "Control page layout" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:152 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:204 msgid "Set the top margin in pts. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:154 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:206 msgid "Set the bottom margin in pts. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:156 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:208 msgid "Set the left margin in pts. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:158 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:210 msgid "Set the right margin in pts. Default is %default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:160 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:212 msgid "" "The base font size in pts. Default is %defaultpt. Set to 0 to disable " "rescaling of fonts." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:162 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:215 msgid "" -"Remove spacing between paragraphs. Will not work if the source file forces " -"inter-paragraph spacing." +"Remove spacing between paragraphs. Also sets a indent on paragraphs of " +"1.5em. You can override this by adding p {text-indent: 0cm} to --override-" +"css. Spacing removal will not work if the source file forces inter-paragraph " +"spacing." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:164 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:221 +msgid "Do not force text to be justified in output." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:223 +msgid "" +"Remove table markup, converting it into paragraphs. This is useful if your " +"source file uses a table to manage layout." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:226 msgid "" "Preserve the HTML tag structure while splitting large HTML files. This is " "only neccessary if the HTML files contain CSS that uses sibling selectors. " "Enabling this greatly slows down processing of large HTML files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:167 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:232 msgid "Print generated OPF file to stdout" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:169 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:234 msgid "Print generated NCX file to stdout" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:171 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:237 msgid "Keep intermediate files during processing by html2epub" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:173 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:239 msgid "" "Extract the contents of the produced EPUB file to the specified directory." msgstr "" @@ -418,11 +462,11 @@ msgid "" "formats are: %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:102 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:103 msgid "Could not find an ebook inside the archive" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:214 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:225 msgid "" "%prog [options] file.html|opf\n" "\n" @@ -433,14 +477,14 @@ msgid "" "the element of the OPF file. \n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:465 -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:746 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:589 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:476 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:758 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:613 msgid "Output written to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:487 -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1087 +#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_html.py:498 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:1117 msgid "You must specify an input HTML file" msgstr "" @@ -459,88 +503,88 @@ msgid "" "cause incorrect rendering." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:509 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:510 msgid "Written processed HTML to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:872 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:898 msgid "Options to control the traversal of HTML" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:879 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:905 msgid "The output directory. Default is the current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:881 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:537 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:907 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:560 msgid "Character encoding for HTML files. Default is to auto detect." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:883 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:909 msgid "" "Create the output in a zip file. If this option is specified, the --output " "should be the name of a file not a directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:885 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:911 msgid "Control the following of links in HTML files." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:887 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:913 msgid "" "Traverse links in HTML files breadth first. Normally, they are traversed " "depth first" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:889 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:915 msgid "" "Maximum levels of recursion when following links in HTML files. Must be non-" "negative. 0 implies that no links in the root HTML file are followed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:891 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:917 msgid "Set metadata of the generated ebook" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:893 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:919 msgid "Set the title. Default is to autodetect." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:895 -msgid "The author(s) of the ebook, as a comma separated list." +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:921 +msgid "The author(s) of the ebook, as a & separated list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:897 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:923 msgid "The subject(s) of this book, as a comma separated list." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:899 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:925 msgid "Set the publisher of this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:901 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:927 msgid "A summary of this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:903 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:929 msgid "Load metadata from the specified OPF file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:905 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:931 msgid "Options useful for debugging" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:907 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:933 msgid "" "Be more verbose while processing. Can be specified multiple times to " "increase verbosity." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:909 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:935 msgid "Output HTML is \"pretty printed\" for easier parsing by humans" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:915 +#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:941 msgid "" "%prog [options] file.html|opf\n" "\n" @@ -561,7 +605,7 @@ msgid "%prog [options] LITFILE" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:855 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:501 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:503 msgid "Output directory. Defaults to current directory." msgstr "" @@ -570,23 +614,23 @@ msgid "Legibly format extracted markup. May modify meaningful whitespace." msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:861 -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:719 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:549 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:731 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:572 msgid "Useful for debugging." msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lit/reader.py:872 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:525 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:527 msgid "OEB ebook created in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:713 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:725 msgid "%prog [options] OPFFILE" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:716 +#: /home/kovid/work/calibre/src/calibre/ebooks/lit/writer.py:728 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/from_feeds.py:26 -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:546 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:569 msgid "Output file. Default is derived from input filename." msgstr "" @@ -617,7 +661,7 @@ msgid "Sort key for the author" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:87 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:278 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:284 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:39 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:108 msgid "Publisher" @@ -638,6 +682,7 @@ msgid "Output file name. Default is derived from input filename" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:96 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:544 msgid "" "Render HTML tables as blocks of text instead of actual tables. This is " "neccessary if the HTML contains very large or complex tables." @@ -1079,54 +1124,54 @@ msgstr "" msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:957 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:954 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:995 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:999 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1010 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1014 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1763 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1768 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1765 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1770 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1787 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1792 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1817 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1822 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1860 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1865 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1863 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1868 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1988 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1993 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1994 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1999 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -1338,55 +1383,50 @@ msgstr "" msgid "Set the comment" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:276 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:282 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:69 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:70 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:36 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:103 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:359 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:969 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:970 msgid "Title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:277 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:283 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:37 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:104 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:364 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:970 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:971 msgid "Author(s)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:279 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:285 msgid "Producer" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:493 -msgid "Category" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:281 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:286 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:71 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:64 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:432 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:489 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:357 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:320 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:58 msgid "Comments" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:283 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:288 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:109 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:309 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:909 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:973 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:910 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:974 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 msgid "Tags" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:284 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:290 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:110 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:325 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:59 @@ -1394,27 +1434,27 @@ msgstr "" msgid "Series" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:285 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:291 msgid "Language" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:199 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:202 msgid "A comma separated list of tags to set" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:201 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:204 msgid "The series to which this book belongs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:203 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:206 msgid "The series index" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:205 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:208 msgid "The book language" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:207 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:210 msgid "Extract the cover" msgstr "" @@ -1506,7 +1546,7 @@ msgstr "" msgid "Set the ISBN" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:965 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1012 msgid "Set the dc:language field" msgstr "" @@ -1522,59 +1562,65 @@ msgstr "" msgid "Creating Mobipocket file from EPUB..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:499 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:501 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:523 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:525 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:512 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:528 msgid "Options to control the conversion to MOBI" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:519 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:535 msgid "Mobipocket-specific options." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:521 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:537 msgid "" "Compress file text using PalmDOC compression. Results in smaller files, but " "takes a long time to run." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:524 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:540 msgid "Modify images to meet Palm device size limitations." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:526 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:542 msgid "Title for any generated in-line table of contents." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:527 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:548 +msgid "" +"When present, use the author sorting information for generating the " +"Mobipocket author metadata." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:550 msgid "" "Device renderer profiles. Affects conversion of font sizes, image rescaling " "and rasterization of tables. Valid profiles are: %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:532 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:555 msgid "Source renderer profile. Default is %default." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:535 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:558 msgid "Destination renderer profile. Default is %default." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:543 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:566 msgid "[options]" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:561 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:584 msgid "Unknown source profile %r" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:565 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer.py:588 msgid "Unknown destination profile %r" msgstr "" @@ -1582,74 +1628,74 @@ msgstr "" msgid "The output directory. Defaults to the current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:586 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:822 msgid "Cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:587 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:823 msgid "Title Page" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:588 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:824 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/htmltoc.py:18 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:47 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:160 msgid "Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:589 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:825 msgid "Index" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:590 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:826 msgid "Glossary" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:591 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:827 msgid "Acknowledgements" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:592 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:828 msgid "Bibliography" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:593 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:829 msgid "Colophon" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:594 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:830 msgid "Copyright" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:595 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:831 msgid "Dedication" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:596 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:832 msgid "Epigraph" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:597 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:833 msgid "Foreword" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:598 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:834 msgid "List of Illustrations" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:599 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:835 msgid "List of Tables" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:600 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:836 msgid "Notes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:601 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:837 msgid "Preface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:602 +#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:838 msgid "Main Text" msgstr "" @@ -1814,7 +1860,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:85 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:316 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:904 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:905 #: /home/kovid/work/calibre/src/calibre/gui2/status.py:56 msgid "Path" msgstr "" @@ -1880,8 +1926,8 @@ msgid "&Number of Colors:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:92 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:440 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:502 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 msgid "&Profile:" msgstr "" @@ -1996,7 +2042,7 @@ msgid "Access log:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:345 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:385 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:402 msgid "Failed to start content server" msgstr "" @@ -2034,7 +2080,7 @@ msgid "Compacting..." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:417 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:340 msgid "Configuration" msgstr "" @@ -2054,16 +2100,16 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:452 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:453 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:478 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:414 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:497 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:308 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:313 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:327 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:336 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:471 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:499 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:333 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:338 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:340 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:344 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:352 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:361 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:363 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:365 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:369 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:371 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:126 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:131 @@ -2071,10 +2117,10 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:267 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:269 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:270 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:332 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:336 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:342 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:333 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:341 msgid "..." msgstr "" @@ -2223,13 +2269,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:460 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:174 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:178 msgid "&Username:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:461 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:58 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:179 msgid "&Password:" msgstr "" @@ -2241,7 +2287,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:463 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/password_ui.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:180 msgid "&Show password" msgstr "" @@ -2334,377 +2380,413 @@ msgstr "" msgid "Convert %s to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:68 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:70 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:55 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:297 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:143 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:161 msgid "Metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:70 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:72 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:98 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:57 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:297 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:298 msgid "Look & Feel" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:72 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:74 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:99 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:59 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:298 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:299 msgid "Page Setup" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:74 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:98 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:76 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:100 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:61 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:299 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:300 msgid "Chapter Detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:95 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 msgid "" "Specify metadata such as title and author for the book.\n" "\n" "Metadata will be updated in the database as well as the generated %s file." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:96 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:98 msgid "" "Adjust the look of the generated ebook by specifying things like font sizes." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:97 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:99 msgid "Specify the page layout settings like margins." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:98 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:299 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:100 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:300 msgid "Fine tune the detection of chapter and section headings." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:106 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:167 msgid "Choose cover for " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:113 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:59 msgid "Cannot read" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:112 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:114 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:175 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:60 msgid "You do not have permission to read the file: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:122 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:68 msgid "Error reading file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:121 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:123 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:184 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:69 msgid "

There was an error reading from file:
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:127 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:129 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:190 msgid " is not a valid picture" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:238 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1053 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:241 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1073 msgid "Cannot convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:239 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:242 msgid "This book has no available formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:247 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:93 msgid "No available formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:248 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:94 msgid "Cannot convert %s as this book has no supported formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:249 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:252 msgid "Choose the format to convert to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:264 msgid "Invalid XPath expression" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:265 msgid "The expression %s is invalid. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:410 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:467 msgid "Convert to EPUB" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:411 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:494 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:341 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:468 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:496 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:366 msgid "Book Cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:412 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:495 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:342 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:469 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:497 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:367 msgid "Change &cover image:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:413 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:496 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:343 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:470 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:498 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:368 msgid "Browse for an image to use as the cover of this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:415 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:498 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:472 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:500 msgid "Use cover from &source file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:416 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:499 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:305 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:473 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:501 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:330 msgid "&Title: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:417 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:500 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:306 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:474 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:502 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:331 msgid "Change the title of this book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:418 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:501 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:309 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:334 msgid "&Author(s): " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:419 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:502 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:476 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 msgid "" "Change the author(s) of this book. Multiple authors should be separated by " "an &. If the author name contains an &, use && to represent it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:420 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:503 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:477 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 msgid "Author So&rt:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:421 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:504 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:478 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 msgid "" "Change the author(s) of this book. Multiple authors should be separated by a " "comma" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:422 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:505 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:479 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:136 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:318 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:343 msgid "&Publisher: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:423 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:480 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:137 msgid "Change the publisher of this book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:424 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:319 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:481 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:344 msgid "Ta&gs: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:425 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:482 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:139 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:320 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:345 msgid "" "Tags categorize the book. This is particularly useful while searching. " "

They can be any words or phrases, separated by commas." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:426 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:483 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:144 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:323 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:348 msgid "&Series:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:427 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:428 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:484 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:485 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:145 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:146 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:324 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:325 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:350 msgid "List of known series. You can add new series." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:429 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:430 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:328 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:329 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:486 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:487 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:353 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:354 msgid "Series index." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:431 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:330 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:488 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:355 msgid "Book " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:433 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:490 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 msgid "Source en&coding:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:434 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:491 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 msgid "Base &font size:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:435 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:442 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:444 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:446 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:448 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:492 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:508 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:510 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:512 msgid " pt" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:436 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:493 msgid "Remove &spacing between paragraphs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:437 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:494 msgid "Preserve &tag structure when splitting" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:438 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:495 msgid "&Rescale images" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:439 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:496 +msgid "&Ignore tables" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:497 +msgid "&Use author sort to set author field in output" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:498 +msgid "No text &justification" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:499 +msgid "&Linearize tables" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:500 +msgid "Remove &first image from source file" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:501 msgid "Override &CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:441 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 -msgid "&Left Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:443 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 -msgid "&Right Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:445 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 -msgid "&Top Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:447 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 -msgid "&Bottom Margin:" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:449 -msgid "Do not &split on page breaks" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:450 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:503 msgid "&Source profile:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:451 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:504 msgid "&Destination profile:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:452 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:505 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:541 +msgid "&Left Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:543 +msgid "&Right Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:509 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:545 +msgid "&Top Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:511 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 +msgid "&Bottom Margin:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:513 +msgid "Do not &split on page breaks" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:514 +msgid "&Page map" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:515 +msgid "" +"

You can control how calibre detects page boundaries using a XPath " +"expression. To learn how to use XPath expressions see the XPath " +"tutorial. The page boundaries are useful only if you want a mapping from " +"pages in a paper book, to locations in the e-book. This controls where Adobe " +"Digital Editions displays the page numbers in the right margin.

" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:516 +msgid "&Boundary XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:517 +msgid "&Name XPath:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:518 msgid "Automatic &chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:453 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:519 +msgid "" +"

You can control how calibre detects chapters using a XPath expression. To " +"learn how to use XPath expressions see the XPath " +"tutorial

" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:520 msgid "&XPath:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:454 -msgid "" -"\n" -"\n" -"

You can control how " -"calibre detects chapters using a XPath expression. To learn how to use XPath " -"expressions see the XPath " -"tutorial

" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:459 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:521 msgid "Chapter &mark:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:460 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:522 msgid "Automatic &Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:461 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:523 msgid "Number of &links to add to Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:462 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:524 msgid "Do not add &detected chapters to the Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:463 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:525 msgid "Chapter &threshold" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:464 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:526 msgid "&Force use of auto-generated Table of Contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:465 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:527 msgid "Level &1 TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:466 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:528 msgid "Level &2 TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:467 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:529 msgid "&Title for generated TOC" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:530 +msgid "Level &3 TOC" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:38 msgid "Author Sort" msgstr "" @@ -2765,7 +2847,7 @@ msgid "" "Select the book that most closely matches your copy from the list below" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:32 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:37 msgid "Details of job" msgstr "" @@ -2798,185 +2880,189 @@ msgstr "" msgid "Set conversion defaults" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:261 msgid "" "Preprocess the file before converting to LRF. This is useful if you know " "that the file is from a specific source. Known sources:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:262 msgid "
  1. baen - Books from BAEN Publishers
  2. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:263 msgid "" "
  3. pdftohtml - HTML files that are the output of the program " "pdftohtml
  4. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:264 msgid "
  5. book-designer - HTML0 files from Book Designer
  6. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:297 msgid "" "Specify metadata such as title and author for the book.

    Metadata will be " "updated in the database as well as the generated LRF file." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:297 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:298 msgid "" "Adjust the look of the generated LRF file by specifying things like font " "sizes and the spacing between words." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:298 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:299 msgid "" "Specify the page settings like margins and the screen size of the target " "device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:308 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:309 msgid "No help available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:412 msgid "Bulk convert ebooks to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:492 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:494 msgid "Convert to LRF" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 -msgid " pts" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 -msgid "Embedded Fonts" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:495 +msgid "Category" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519 -msgid "&Serif:" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:526 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 +msgid " pts" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 -msgid "S&ans-serif:" +msgid "Embedded Fonts" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 -msgid "&Monospace:" +msgid "&Serif:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 +msgid "S&ans-serif:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -msgid "Minimum &indent:" +msgid "&Monospace:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 -msgid "&Word spacing:" +msgid "Minimum &indent:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 -msgid "Enable auto &rotation of images" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 -msgid "Insert &blank lines between paragraphs" +msgid "&Word spacing:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -msgid "Ignore &tables" +msgid "Enable auto &rotation of images" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -msgid "Ignore &colors" +msgid "Insert &blank lines between paragraphs" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -msgid "&Preprocess:" +msgid "Ignore &tables" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:532 -msgid "Header" +msgid "Ignore &colors" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:533 -msgid "&Show header" +msgid "&Preprocess:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:534 -msgid "&Header format:" +msgid "Header" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:535 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:540 +msgid "&Show header" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +msgid "&Header format:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:542 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:544 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:546 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:107 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/config_ui.py:109 msgid " px" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:538 msgid "Header &separation:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:537 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:539 msgid "Override
    CSS" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:547 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 msgid "&Convert tables to images (good for large/complex tables)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:548 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:550 msgid "&Multiplier for text size in rendered tables:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:549 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 msgid "Title based detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:550 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 msgid "&Disable chapter detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:551 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 msgid "&Regular expression:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:552 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:554 msgid "Add &chapters to table of contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:553 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 msgid "Don't add &links to the table of contents" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:554 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:556 msgid "Tag based detection" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:555 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 msgid "&Page break before tag:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:556 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 msgid "&Force page break before tag:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 msgid "Force page break before &attribute:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:560 msgid "Detect chapter &at tag:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:559 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:561 msgid "" "\n" @@ -2995,36 +3081,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:127 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:304 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:329 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:130 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:310 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:335 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:131 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:336 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:132 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:314 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:339 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:133 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:134 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:340 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:341 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:135 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:342 msgid " stars" msgstr "" @@ -3034,8 +3120,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:140 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:141 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:321 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:322 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:346 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:347 msgid "Open Tag Editor" msgstr "" @@ -3099,61 +3185,61 @@ msgstr "" msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:328 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:332 msgid "Swap the author and title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:337 msgid "" "Automatically create the author sort entry based on the current author entry" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:326 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:351 msgid "Remove unused series (Series that have no books)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:331 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:356 msgid "IS&BN:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:333 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:358 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:334 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:359 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:335 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:360 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:337 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:362 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:339 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:364 msgid "Set the cover for the book from the selected format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:370 msgid "Reset cover to default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:372 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:348 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:373 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:349 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:374 msgid "Change password" msgstr "" @@ -3165,153 +3251,167 @@ msgstr "" msgid "Aborting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:39 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:40 msgid "You" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:123 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:138 +msgid "Custom" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:125 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:136 +msgid "Scheduled" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:232 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:218 msgid "Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:308 msgid "%d recipes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:309 msgid "Monday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:309 msgid "Tuesday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:309 msgid "Wednesday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:309 msgid "day" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:310 msgid "Friday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:310 msgid "Saturday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:310 msgid "Sunday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:310 msgid "Thursday" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:343 msgid "Must set account information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:344 msgid "This recipe requires a username and password" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:317 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:370 msgid "Created by: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:355 -msgid "Last downloaded: %s days ago" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:408 +msgid "%d days, %d hours and %d minutes ago" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:357 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:410 +msgid "Last downloaded" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:412 msgid "Last downloaded: never" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:384 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:438 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:165 msgid "Schedule news download" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:387 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:441 msgid "Add a custom news source" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:394 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:448 #: /home/kovid/work/calibre/src/calibre/gui2/tags.py:50 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:772 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:776 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1083 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:775 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:779 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1086 msgid "News" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:166 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221 msgid "Recipes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:167 msgid "Schedule for download" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:168 msgid "title" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:165 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:169 msgid "description" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:170 msgid "author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:167 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:171 msgid "&Schedule for download:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:168 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:174 msgid "Every " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:173 msgid "at" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:175 msgid "" "Interval at which to download this recipe. A value of zero means that the " "recipe will be downloaded every hour." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:172 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:180 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:176 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:184 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:263 msgid " days" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:177 msgid "&Account" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:181 msgid "For the scheduling to work, you must leave calibre running." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:178 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:182 msgid "&Download now" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:183 msgid "" "Delete downloaded news older than the specified number of days. Set to zero " "to disable." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:181 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:185 msgid "Delete downloaded news older than " msgstr "" @@ -3338,35 +3438,35 @@ msgstr "" msgid "Negate" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:87 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:88 msgid "Advanced Search" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:88 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:89 msgid "Find entries that have..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:89 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:90 msgid "&All these words:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:91 msgid "This exact &phrase:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:92 msgid "&One or more of these words:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:93 msgid "But dont show entries that have..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:93 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:94 msgid "Any of these &unwanted words:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:94 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:95 msgid "" "See the User Manual for more help" @@ -3735,12 +3835,12 @@ msgid "Job has already run" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library.py:105 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:971 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:972 msgid "Size (MB)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library.py:106 -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:972 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:973 msgid "Date" msgstr "" @@ -3758,25 +3858,25 @@ msgstr "" msgid "Book %s of %s." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:739 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:740 msgid "Not allowed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:740 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:741 msgid "" "Dropping onto a device is not supported. First add the book to the calibre " "library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:903 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:904 msgid "Format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:908 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:909 msgid "Timestamp" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/library.py:1006 +#: /home/kovid/work/calibre/src/calibre/gui2/library.py:1007 msgid "Search (For Advanced Search click the button to the left)" msgstr "" @@ -3868,132 +3968,132 @@ msgstr "" msgid "&Restart" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 msgid "" "

    For help visit %s.kovidgoyal.net
    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:143 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:138 msgid "%s: %s by Kovid Goyal %%(version)s
    %%(device)s

    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:162 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:159 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:163 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:159 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:166 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:161 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:179 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:170 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:181 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:172 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:184 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:185 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:176 msgid "" "Add books from directories, including sub-directories (One book per " "directory, assumes every ebook file is the same book in a different format)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:186 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 msgid "" "Add books from directories, including sub directories (Multiple books per " "directory, assumes every ebook file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:201 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:356 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:192 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:353 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:202 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:193 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:203 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1258 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1280 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:206 -#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:362 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:197 +#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:359 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:207 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:198 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:215 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:216 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:218 msgid "Set defaults for conversion" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:219 msgid "Set defaults for conversion of comics" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:250 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:241 msgid "Similar books..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:298 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:289 msgid "Bad database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:300 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1391 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1413 msgid "Choose a location for your ebook library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:424 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:441 msgid "Browse by covers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:513 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:530 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:514 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:531 msgid " detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:536 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:553 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:547 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:564 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:548 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:565 msgid "" "\n" "

    The database of books on the reader is corrupted. Try the " @@ -4009,312 +4109,312 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:597 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:614 msgid "Adding books recursively..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:602 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:619 msgid "Added " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:602 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:619 msgid "Searching..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:612 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:716 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:629 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:735 msgid "" "

    Books with the same title as the following already exist in the database. " "Add them anyway?