diff --git a/resources/recipes/180.recipe b/resources/recipes/180.recipe index 5158bb99e0..4f00314795 100644 --- a/resources/recipes/180.recipe +++ b/resources/recipes/180.recipe @@ -12,7 +12,7 @@ class Noticias(BasicNewsRecipe): title = '180.com.uy' __author__ = 'Gustavo Azambuja' description = 'Noticias de Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 5 diff --git a/resources/recipes/7dias.recipe b/resources/recipes/7dias.recipe index e111617b8d..3dc93295a8 100644 --- a/resources/recipes/7dias.recipe +++ b/resources/recipes/7dias.recipe @@ -20,7 +20,7 @@ class SieteDias(BasicNewsRecipe): no_stylesheets = True use_embedded_content = False encoding = 'utf-8' - language = 'es' + language = 'es_AR' lang = 'es-AR' direction = 'ltr' diff --git a/resources/recipes/ambito.recipe b/resources/recipes/ambito.recipe index 7074463e34..dd92ee19b3 100644 --- a/resources/recipes/ambito.recipe +++ b/resources/recipes/ambito.recipe @@ -58,4 +58,4 @@ class Ambito(BasicNewsRecipe): del item['style'] return soup - language = 'es' + language = 'es_AR' diff --git a/resources/recipes/animal_politico.recipe b/resources/recipes/animal_politico.recipe index f48587ea94..5e57e266bc 100644 --- a/resources/recipes/animal_politico.recipe +++ b/resources/recipes/animal_politico.recipe @@ -12,7 +12,7 @@ class AdvancedUserRecipe1290663986(BasicNewsRecipe): masthead_url = 'http://www.animalpolitico.com/wp-content/themes/animal_mu/images/logo.png' oldest_article = 1 max_articles_per_feed = 100 - language = 'es' + language = 'es_MX' #feeds = [(u'Animal Politico', u'http://www.animalpolitico.com/feed/')] diff --git a/resources/recipes/axxon_magazine.recipe b/resources/recipes/axxon_magazine.recipe index 331e6fe2b5..93cb5cd03b 100644 --- a/resources/recipes/axxon_magazine.recipe +++ b/resources/recipes/axxon_magazine.recipe @@ -17,7 +17,7 @@ class Axxon_news(BasicNewsRecipe): max_articles_per_feed = 100 no_stylesheets = False use_embedded_content = False - language = 'es' + language = 'es_AR' encoding = 'utf-8' publication_type = 'magazine' INDEX = 'http://axxon.com.ar/rev/' diff --git a/resources/recipes/axxon_news.recipe b/resources/recipes/axxon_news.recipe index a9a99e1de1..3d0f8effd0 100644 --- a/resources/recipes/axxon_news.recipe +++ b/resources/recipes/axxon_news.recipe @@ -18,7 +18,7 @@ class Axxon_news(BasicNewsRecipe): max_articles_per_feed = 100 no_stylesheets = False use_embedded_content = False - language = 'es' + language = 'es_AR' lang = 'es-AR' diff --git a/resources/recipes/bbc_es.recipe b/resources/recipes/bbc_es.recipe new file mode 100644 index 0000000000..b2b6192620 --- /dev/null +++ b/resources/recipes/bbc_es.recipe @@ -0,0 +1,53 @@ +__license__ = 'GPL v3' +__author__ = 'Luis Hernandez' +__copyright__ = 'Luis Hernandez' +__version__ = 'v1.0' +__date__ = '29 January 2011' + +''' +http://www.bbc.co.uk/mundo/ +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1294946868(BasicNewsRecipe): + + title = u'BBC Mundo' + publisher = u'BBC' + + __author__ = 'Luis Hernandez' + description = 'BBC World for spanish readers' + + cover_url = 'http://1.bp.blogspot.com/_NHiOjk_uZwU/TEYy7IJAdAI/AAAAAAAABP8/coAE-pJ7_5E/s1600/bbcmundo_h.png' + oldest_article = 2 + max_articles_per_feed = 100 + + remove_javascript = True + no_stylesheets = True + use_embedded_content = False + + language = 'es' + remove_empty_feeds = True + encoding = 'UTF-8' + timefmt = '[%a, %d %b, %Y]' + + remove_tags_before = dict(name='div' , attrs={'class':['g-group']}) + remove_tags_after = dict(name='div' , attrs={'class':[' g-w8']}) + + remove_tags = [ + dict(name='ul', attrs={'class':['document-tools blq-clearfix','blq-clearfix']}) + ,dict(name='div', attrs={'class':['box bx-quote-bubble','socialmedia-links','list li-carousel','list li-plain rolling-news','list li-plain','box bx-livestats','li-tab content','list li-relatedlinks','list li-relatedinternetlinks']}) + ] + + feeds = [ + (u'Portada' , u'http://www.bbc.co.uk/mundo/index.xml') + ,(u'Ultimas Noticias' , u'http://www.bbc.co.uk/mundo/ultimas_noticias/index.xml') + ,(u'Internacional' , u'http://www.bbc.co.uk/mundo/temas/internacional/index.xml') + ,(u'Economia' , u'http://www.bbc.co.uk/mundo/temas/economia/index.xml') + ,(u'America Latina' , u'http://www.bbc.co.uk/mundo/temas/america_latina/index.xml') + ,(u'Ciencia' , u'http://www.bbc.co.uk/mundo/temas/ciencia/index.xml') + ,(u'Salud' , u'http://www.bbc.co.uk/mundo/temas/salud/index.xml') + ,(u'Tecnologia' , u'http://www.bbc.co.uk/mundo/temas/tecnologia/index.xml') + ,(u'Cultura' , u'http://www.bbc.co.uk/mundo/temas/cultura/index.xml') + ] + diff --git a/resources/recipes/bitacora.recipe b/resources/recipes/bitacora.recipe index a36eb52988..7f41f8f32b 100644 --- a/resources/recipes/bitacora.recipe +++ b/resources/recipes/bitacora.recipe @@ -12,7 +12,7 @@ class General(BasicNewsRecipe): title = 'bitacora.com.uy' __author__ = 'Gustavo Azambuja' description = 'Noticias de Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 5 diff --git a/resources/recipes/buenosaireseconomico.recipe b/resources/recipes/buenosaireseconomico.recipe index c9f89269b4..782358e6d3 100644 --- a/resources/recipes/buenosaireseconomico.recipe +++ b/resources/recipes/buenosaireseconomico.recipe @@ -20,7 +20,7 @@ class BsAsEconomico(BasicNewsRecipe): no_stylesheets = True use_embedded_content = False encoding = 'utf-8' - language = 'es' + language = 'es_AR' lang = 'es-AR' direction = 'ltr' diff --git a/resources/recipes/clarin.recipe b/resources/recipes/clarin.recipe index cf9440ad55..7bbb663d1d 100644 --- a/resources/recipes/clarin.recipe +++ b/resources/recipes/clarin.recipe @@ -18,7 +18,7 @@ class Clarin(BasicNewsRecipe): use_embedded_content = False no_stylesheets = True encoding = 'utf8' - language = 'es' + language = 'es_AR' publication_type = 'newspaper' INDEX = 'http://www.clarin.com' masthead_url = 'http://www.clarin.com/static/CLAClarin/images/logo-clarin-print.jpg' diff --git a/resources/recipes/criticadigital.recipe b/resources/recipes/criticadigital.recipe index d1ef97aef9..3cb72e6be4 100644 --- a/resources/recipes/criticadigital.recipe +++ b/resources/recipes/criticadigital.recipe @@ -14,7 +14,7 @@ class CriticaDigital(BasicNewsRecipe): description = 'Noticias de Argentina' oldest_article = 2 max_articles_per_feed = 100 - language = 'es' + language = 'es_AR' no_stylesheets = True use_embedded_content = False diff --git a/resources/recipes/cubadebate.recipe b/resources/recipes/cubadebate.recipe index f8887b2672..d563f0f86e 100644 --- a/resources/recipes/cubadebate.recipe +++ b/resources/recipes/cubadebate.recipe @@ -11,7 +11,7 @@ class CubaDebate(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Contra el Terorismo Mediatico' oldest_article = 15 - language = 'es' + language = 'es_CU' max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False @@ -20,8 +20,8 @@ class CubaDebate(BasicNewsRecipe): encoding = 'utf-8' masthead_url = 'http://www.cubadebate.cu/wp-content/themes/cubadebate/images/logo.gif' publication_type = 'newsportal' - extra_css = """ - #BlogTitle{font-size: xx-large; font-weight: bold} + extra_css = """ + #BlogTitle{font-size: xx-large; font-weight: bold} body{font-family: Verdana, Arial, Tahoma, sans-serif} """ @@ -41,7 +41,7 @@ class CubaDebate(BasicNewsRecipe): feeds = [(u'Articulos', u'http://www.cubadebate.cu/feed/')] remove_attributes=['width','height','lang'] - + def print_version(self, url): return url + 'print/' @@ -50,5 +50,5 @@ class CubaDebate(BasicNewsRecipe): del item['style'] for item in soup.findAll('img'): if not item.has_key('alt'): - item['alt'] = 'image' + item['alt'] = 'image' return soup diff --git a/resources/recipes/deutsche_welle_es.recipe b/resources/recipes/deutsche_welle_es.recipe index ab80b2f11f..c68a03b981 100644 --- a/resources/recipes/deutsche_welle_es.recipe +++ b/resources/recipes/deutsche_welle_es.recipe @@ -16,7 +16,7 @@ class DeutscheWelle_es(BasicNewsRecipe): max_articles_per_feed = 100 use_embedded_content = False no_stylesheets = True - language = 'es' + language = 'de_ES' publication_type = 'newsportal' remove_empty_feeds = True masthead_url = 'http://www.dw-world.de/skins/std/channel1/pics/dw_logo1024.gif' diff --git a/resources/recipes/diagonales.recipe b/resources/recipes/diagonales.recipe index 1604967e63..eff06efc1d 100644 --- a/resources/recipes/diagonales.recipe +++ b/resources/recipes/diagonales.recipe @@ -20,7 +20,7 @@ class Diagonales(BasicNewsRecipe): no_stylesheets = True use_embedded_content = False encoding = 'utf-8' - language = 'es' + language = 'es_AR' lang = 'es-AR' direction = 'ltr' diff --git a/resources/recipes/el_mercurio_chile.recipe b/resources/recipes/el_mercurio_chile.recipe index a8371f5af9..df4d027af3 100644 --- a/resources/recipes/el_mercurio_chile.recipe +++ b/resources/recipes/el_mercurio_chile.recipe @@ -20,8 +20,8 @@ class ElMercurio(BasicNewsRecipe): masthead_url = 'http://www.emol.com/especiales/logo_emol/logo_emol.gif' remove_javascript = True use_embedded_content = False - language = 'es' - + language = 'es_CL' + conversion_options = { 'comment' : description @@ -33,7 +33,7 @@ class ElMercurio(BasicNewsRecipe): keep_only_tags = [dict(name='div', attrs={'id':['cont_iz_titulobajada','cont_iz_creditos_1_a','cont_iz_cuerpo']})] remove_tags = [dict(name='div', attrs={'id':'cont_iz_cuerpo_relacionados'})] remove_attributes = ['height','width'] - + feeds = [ (u'Noticias de ultima hora', u'http://rss.emol.com/rss.asp?canal=0') ,(u'Nacional', u'http://rss.emol.com/rss.asp?canal=1') diff --git a/resources/recipes/el_observador.recipe b/resources/recipes/el_observador.recipe index 6338426d59..994963671e 100644 --- a/resources/recipes/el_observador.recipe +++ b/resources/recipes/el_observador.recipe @@ -13,7 +13,7 @@ class ObservaDigital(BasicNewsRecipe): title = 'Observa Digital' __author__ = 'yrvn' description = 'Noticias de Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 5 diff --git a/resources/recipes/el_pais_uy.recipe b/resources/recipes/el_pais_uy.recipe index 1e9c400162..aceedf0b8c 100644 --- a/resources/recipes/el_pais_uy.recipe +++ b/resources/recipes/el_pais_uy.recipe @@ -14,7 +14,7 @@ class General(BasicNewsRecipe): description = 'Noticias de Uruguay y el resto del mundo' publisher = 'EL PAIS S.A.' category = 'news, politics, Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 2 diff --git a/resources/recipes/el_universal.recipe b/resources/recipes/el_universal.recipe index f053812c05..441f77cbe1 100644 --- a/resources/recipes/el_universal.recipe +++ b/resources/recipes/el_universal.recipe @@ -20,7 +20,7 @@ class ElUniversal(BasicNewsRecipe): remove_javascript = True remove_empty_feeds = True publication_type = 'newspaper' - language = 'es' + language = 'es_MX' extra_css = ''' body{font-family:Arial,Helvetica,sans-serif} diff --git a/resources/recipes/elargentino.recipe b/resources/recipes/elargentino.recipe index c33b845e0a..6086ff6b59 100644 --- a/resources/recipes/elargentino.recipe +++ b/resources/recipes/elargentino.recipe @@ -12,7 +12,7 @@ class ElArgentino(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Informacion Libre las 24 horas' publisher = 'ElArgentino.com' - category = 'news, politics, Argentina' + category = 'news, politics, Argentina' oldest_article = 2 max_articles_per_feed = 100 remove_javascript = True @@ -20,7 +20,7 @@ class ElArgentino(BasicNewsRecipe): use_embedded_content = False encoding = 'utf8' cover_url = 'http://www.elargentino.com/TemplateWeb/MediosFooter/tapa_elargentino.png' - language = 'es' + language = 'es_AR' html2lrf_options = [ @@ -28,16 +28,16 @@ class ElArgentino(BasicNewsRecipe): , '--category', category , '--publisher', publisher ] - - html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' remove_tags = [ dict(name='div', attrs={'id':'noprint' }) ,dict(name='div', attrs={'class':'encabezadoImprimir'}) ,dict(name='a' , attrs={'target':'_blank' }) ] - - feeds = [ + + feeds = [ (u'Portada' , u'http://www.elargentino.com/Highlights.aspx?Content-Type=text/xml&ChannelDesc=Home' ) ,(u'Pais' , u'http://www.elargentino.com/Highlights.aspx?ParentType=Section&ParentId=112&Content-Type=text/xml&ChannelDesc=Pa%C3%ADs' ) ,(u'Economia' , u'http://www.elargentino.com/Highlights.aspx?ParentType=Section&ParentId=107&Content-Type=text/xml&ChannelDesc=Econom%C3%ADa' ) @@ -51,12 +51,12 @@ class ElArgentino(BasicNewsRecipe): def print_version(self, url): main, sep, article_part = url.partition('/nota-') - article_id, rsep, rrest = article_part.partition('-') + article_id, rsep, rrest = article_part.partition('-') return u'http://www.elargentino.com/Impresion.aspx?Id=' + 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'] + del item['style'] return soup diff --git a/resources/recipes/elcomercio.recipe b/resources/recipes/elcomercio.recipe index 37733bda8b..69c513a835 100644 --- a/resources/recipes/elcomercio.recipe +++ b/resources/recipes/elcomercio.recipe @@ -18,7 +18,7 @@ class ElComercio(BasicNewsRecipe): no_stylesheets = True encoding = 'utf-8' use_embedded_content = True - language = 'es' + language = 'es_EC' masthead_url = 'http://ww1.elcomercio.com/nv_images/headers/EC/logo_new_08.gif' extra_css = ' body{font-family: Arial,Verdana,sans-serif} img{margin-bottom: 1em} ' diff --git a/resources/recipes/elcronista.recipe b/resources/recipes/elcronista.recipe index d96a9746d6..93615f8f42 100644 --- a/resources/recipes/elcronista.recipe +++ b/resources/recipes/elcronista.recipe @@ -13,7 +13,7 @@ class ElCronista(BasicNewsRecipe): __author__ = 'Darko Miletic' description = 'Noticias de Argentina' oldest_article = 2 - language = 'es' + language = 'es_AR' max_articles_per_feed = 100 no_stylesheets = True @@ -25,14 +25,14 @@ class ElCronista(BasicNewsRecipe): , '--category' , 'news, Argentina' , '--publisher' , title ] - + keep_only_tags = [ dict(name='table', attrs={'width':'100%' }) ,dict(name='h1' , attrs={'class':'Arialgris16normal'}) ] remove_tags = [dict(name='a', attrs={'class':'Arialazul12'})] - + feeds = [ (u'Economia' , u'http://www.cronista.com/adjuntos/8/rss/Economia_EI.xml' ) ,(u'Negocios' , u'http://www.cronista.com/adjuntos/8/rss/negocios_EI.xml' ) @@ -69,4 +69,4 @@ class ElCronista(BasicNewsRecipe): if link_item: cover_url = index + link_item.img['src'] return cover_url - + diff --git a/resources/recipes/eltiempo_hn.recipe b/resources/recipes/eltiempo_hn.recipe index e4d11466ee..81d1ecbb9d 100644 --- a/resources/recipes/eltiempo_hn.recipe +++ b/resources/recipes/eltiempo_hn.recipe @@ -21,7 +21,7 @@ class ElTiempoHn(BasicNewsRecipe): no_stylesheets = True remove_javascript = True encoding = 'utf-8' - language = 'es' + language = 'es_HN' lang = 'es-HN' direction = 'ltr' diff --git a/resources/recipes/eluniversal_ve.recipe b/resources/recipes/eluniversal_ve.recipe index af5d75e3e7..28667cd39b 100644 --- a/resources/recipes/eluniversal_ve.recipe +++ b/resources/recipes/eluniversal_ve.recipe @@ -18,7 +18,7 @@ class ElUniversal(BasicNewsRecipe): encoding = 'cp1252' publisher = 'El Universal' category = 'news, Caracas, Venezuela, world' - language = 'es' + language = 'es_VE' cover_url = strftime('http://static.eluniversal.com/%Y/%m/%d/portada.jpg') conversion_options = { diff --git a/resources/recipes/eluniversalimpresa.recipe b/resources/recipes/eluniversalimpresa.recipe index 7263a76e2a..a48556eedb 100644 --- a/resources/recipes/eluniversalimpresa.recipe +++ b/resources/recipes/eluniversalimpresa.recipe @@ -3,7 +3,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class ElUniversalImpresaRecipe(BasicNewsRecipe): __license__ = 'GPL v3' __author__ = 'kwetal' - language = 'es' + language = 'es_MX' version = 1 title = u'El Universal (Edici\u00F3n Impresa)' diff --git a/resources/recipes/eluniverso_ec.recipe b/resources/recipes/eluniverso_ec.recipe index a0e8b46474..8696e9d2f6 100644 --- a/resources/recipes/eluniverso_ec.recipe +++ b/resources/recipes/eluniverso_ec.recipe @@ -17,7 +17,7 @@ class ElUniverso_Ecuador(BasicNewsRecipe): no_stylesheets = True encoding = 'utf8' use_embedded_content = False - language = 'es' + language = 'es_EC' remove_empty_feeds = True publication_type = 'newspaper' masthead_url = 'http://servicios2.eluniverso.com/versiones/v1/img/Hd/lg_ElUniverso.gif' diff --git a/resources/recipes/endgadget_ja.recipe b/resources/recipes/endgadget_ja.recipe index 891e6720a5..3c20380e9b 100644 --- a/resources/recipes/endgadget_ja.recipe +++ b/resources/recipes/endgadget_ja.recipe @@ -18,3 +18,6 @@ class EndgadgetJapan(BasicNewsRecipe): language = 'ja' encoding = 'utf-8' feeds = [(u'engadget', u'http://japanese.engadget.com/rss.xml')] + + remove_tags_before = dict(name="div", attrs={'id':"content_wrap"}) + remove_tags_after = dict(name='h3', attrs={'id':'addcomments'}) diff --git a/resources/recipes/explosm.recipe b/resources/recipes/explosm.recipe new file mode 100644 index 0000000000..8cdff609cb --- /dev/null +++ b/resources/recipes/explosm.recipe @@ -0,0 +1,54 @@ +from calibre.web.feeds.news import BasicNewsRecipe +import re + +class Explosm(BasicNewsRecipe): + title = u'Explosm Rotated' + __author__ = 'Andromeda Rabbit' + description = 'Explosm' + language = 'en' + use_embedded_content = False + no_stylesheets = True + oldest_article = 24 + remove_javascript = True + remove_empty_feeds = True + max_articles_per_feed = 10 + + feeds = [ + (u'Explosm Feed', u'http://feeds.feedburner.com/Explosm') + ] + + #match_regexps = [r'http://www.explosm.net/comics/.*'] + + keep_only_tags = [dict(name='img', attrs={'alt':'Cyanide and Happiness, a daily webcomic'})] + remove_tags = [dict(name='div'), dict(name='span'), dict(name='table'), dict(name='br'), dict(name='nobr'), dict(name='a'), dict(name='b')] + + extra_css = ''' + h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;} + h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;} + p{font-family:Arial,Helvetica,sans-serif;font-size:small;} + body{font-family:Helvetica,Arial,sans-serif;font-size:small;}''' + + def get_cover_url(self): + return 'http://cdn.shopify.com/s/files/1/0059/1872/products/cyanidetitle_large.jpg?1295846286' + + def parse_feeds(self): + feeds = BasicNewsRecipe.parse_feeds(self) + + for curfeed in feeds: + delList = [] + for a,curarticle in enumerate(curfeed.articles): + if re.search(r'http://www.explosm.net/comics', curarticle.url) == None: + delList.append(curarticle) + if len(delList)>0: + for d in delList: + index = curfeed.articles.index(d) + curfeed.articles[index:index+1] = [] + + return feeds + + def skip_ad_pages(self, soup): + # Skip ad pages served before actual article + skip_tag = soup.find(name='img', attrs={'alt':'Cyanide and Happiness, a daily webcomic'}) + if skip_tag is None: + return soup + return None diff --git a/resources/recipes/freeway.recipe b/resources/recipes/freeway.recipe index cb6d41ebb2..c50c35d8ca 100644 --- a/resources/recipes/freeway.recipe +++ b/resources/recipes/freeway.recipe @@ -12,7 +12,7 @@ class General(BasicNewsRecipe): title = 'freeway.com.uy' __author__ = 'Gustavo Azambuja' description = 'Revista Freeway, Montevideo, Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 1 diff --git a/resources/recipes/granma.recipe b/resources/recipes/granma.recipe index 75e89a3d03..01f383cb68 100644 --- a/resources/recipes/granma.recipe +++ b/resources/recipes/granma.recipe @@ -20,7 +20,7 @@ class Granma(BasicNewsRecipe): use_embedded_content = False encoding = 'cp1252' cover_url = 'http://www.granma.cubaweb.cu/imagenes/granweb229d.jpg' - language = 'es' + language = 'es_CU' remove_javascript = True diff --git a/resources/recipes/ieco.recipe b/resources/recipes/ieco.recipe index 8c59d033a1..eb11c103d2 100644 --- a/resources/recipes/ieco.recipe +++ b/resources/recipes/ieco.recipe @@ -18,7 +18,7 @@ class iEco(BasicNewsRecipe): encoding = 'utf-8' publisher = 'Grupo Clarin' category = 'news, economia, mercados, bolsa de valores, finanzas, empresas, negocios, empleos, emprendedores, marketinguniversidades, tecnologia, agronegocios, noticias, informacion' - language = 'es' + language = 'es_AR' cover_url = 'http://www.ieco.clarin.com/static2/images/Tapa-PDF.gif' extra_css = ' #bd{font-family: sans-serif} ' diff --git a/resources/recipes/infobae.recipe b/resources/recipes/infobae.recipe index b7f9cd3c6c..9553746449 100644 --- a/resources/recipes/infobae.recipe +++ b/resources/recipes/infobae.recipe @@ -16,7 +16,7 @@ class Infobae(BasicNewsRecipe): max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False - language = 'es' + language = 'es_AR' encoding = 'cp1252' masthead_url = 'http://www.infobae.com/imgs/header/header.gif' remove_javascript = True @@ -25,7 +25,7 @@ class Infobae(BasicNewsRecipe): body{font-family:Arial,Helvetica,sans-serif;} .popUpTitulo{color:#0D4261; font-size: xx-large} ''' - + conversion_options = { 'comment' : description , 'tags' : category @@ -33,7 +33,7 @@ class Infobae(BasicNewsRecipe): , 'language' : language , 'linearize_tables' : True } - + feeds = [ (u'Noticias' , u'http://www.infobae.com/adjuntos/html/RSS/hoy.xml' ) diff --git a/resources/recipes/juventudrebelde.recipe b/resources/recipes/juventudrebelde.recipe index dd908d57b2..93d550027a 100644 --- a/resources/recipes/juventudrebelde.recipe +++ b/resources/recipes/juventudrebelde.recipe @@ -20,7 +20,7 @@ class Juventudrebelde(BasicNewsRecipe): no_stylesheets = True use_embedded_content = False encoding = 'cp1252' - language = 'es' + language = 'es_CU' cover_url = strftime('http://www.juventudrebelde.cu/UserFiles/File/impreso/iportada-%Y-%m-%d.jpg') remove_javascript = True diff --git a/resources/recipes/la_cuarta.recipe b/resources/recipes/la_cuarta.recipe index ad1a6a975e..10d6b6ce3a 100644 --- a/resources/recipes/la_cuarta.recipe +++ b/resources/recipes/la_cuarta.recipe @@ -50,4 +50,4 @@ class LaCuarta(BasicNewsRecipe): feeds = [(u'Noticias', u'http://lacuarta.cl/app/rss?sc=TEFDVUFSVEE=')] - language = 'es' + language = 'es_CL' diff --git a/resources/recipes/la_diaria.recipe b/resources/recipes/la_diaria.recipe index d89eb465dd..8aa98483c0 100644 --- a/resources/recipes/la_diaria.recipe +++ b/resources/recipes/la_diaria.recipe @@ -12,7 +12,7 @@ class General(BasicNewsRecipe): title = 'La Diaria' __author__ = 'Gustavo Azambuja' description = 'Noticias de Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 5 diff --git a/resources/recipes/la_jornada.recipe b/resources/recipes/la_jornada.recipe index 3ee6dc4b3f..71c526a0a0 100644 --- a/resources/recipes/la_jornada.recipe +++ b/resources/recipes/la_jornada.recipe @@ -19,7 +19,7 @@ class LaJornada_mx(BasicNewsRecipe): no_stylesheets = True encoding = 'utf8' use_embedded_content = False - language = 'es' + language = 'es_MX' remove_empty_feeds = True cover_url = strftime("http://www.jornada.unam.mx/%Y/%m/%d/portada.pdf") masthead_url = 'http://www.jornada.unam.mx/v7.0/imagenes/la-jornada-trans.png' @@ -34,8 +34,8 @@ class LaJornada_mx(BasicNewsRecipe): .credito{font-weight: bold; margin-left: 1em} .credito-autor{font-variant: small-caps; font-weight: bold } .credito-titulo{text-align: right} - .hemero{text-align: right; font-size: 0.9em; margin-bottom: 0.5em } - .loc{font-weight: bold} + .hemero{text-align: right; font-size: 0.9em; margin-bottom: 0.5em } + .loc{font-weight: bold} .carton{text-align: center} .credit{font-weight: bold} .sumario{font-weight: bold; text-align: center} @@ -56,7 +56,7 @@ class LaJornada_mx(BasicNewsRecipe): ,re.DOTALL|re.IGNORECASE) ,lambda match: '

' + match.group(1) + '

') ] - + keep_only_tags = [ dict(name='div', attrs={'class':['documentContent','cabeza','sumarios','credito-articulo','text','carton']}) ,dict(name='div', attrs={'id':'renderComments'}) @@ -88,4 +88,4 @@ class LaJornada_mx(BasicNewsRecipe): def get_article_url(self, article): rurl = article.get('link', None) return rurl.rpartition('&partner=')[0] - + diff --git a/resources/recipes/la_razon_bo.recipe b/resources/recipes/la_razon_bo.recipe index 18a00d6763..6af899b760 100644 --- a/resources/recipes/la_razon_bo.recipe +++ b/resources/recipes/la_razon_bo.recipe @@ -18,7 +18,7 @@ class LaRazon_Bol(BasicNewsRecipe): no_stylesheets = True encoding = 'cp1252' use_embedded_content = False - language = 'es' + language = 'es_BO' publication_type = 'newspaper' delay = 1 remove_empty_feeds = True diff --git a/resources/recipes/la_segunda.recipe b/resources/recipes/la_segunda.recipe index 537bff4104..8ce25e35b3 100644 --- a/resources/recipes/la_segunda.recipe +++ b/resources/recipes/la_segunda.recipe @@ -9,7 +9,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class LaSegunda(BasicNewsRecipe): title = 'La Segunda' __author__ = 'Darko Miletic' - description = 'El sitio de noticias online de Chile' + description = 'El sitio de noticias online de Chile' publisher = 'La Segunda' category = 'news, politics, Chile' oldest_article = 2 @@ -19,9 +19,9 @@ class LaSegunda(BasicNewsRecipe): encoding = 'cp1252' masthead_url = 'http://www.lasegunda.com/imagenes/logotipo_lasegunda_Oli.gif' remove_empty_feeds = True - language = 'es' - extra_css = ' .titulonegritastop{font-size: xx-large; font-weight: bold} ' - + language = 'es_CL' + extra_css = ' .titulonegritastop{font-size: xx-large; font-weight: bold} ' + conversion_options = { 'comment' : description , 'tags' : category @@ -29,13 +29,13 @@ class LaSegunda(BasicNewsRecipe): , 'language' : language , 'linearize_tables' : True } - + remove_tags_before = dict(attrs={'class':'titulonegritastop'}) remove_tags = [dict(name='img')] remove_attributes = ['width','height'] - - - feeds = [ + + + feeds = [ (u'Noticias de ultima hora', u'http://www.lasegunda.com/rss20/index.asp?canal=0') ,(u'Politica' , u'http://www.lasegunda.com/rss20/index.asp?canal=21') ,(u'Cronica' , u'http://www.lasegunda.com/rss20/index.asp?canal=20') @@ -49,6 +49,6 @@ class LaSegunda(BasicNewsRecipe): ] def print_version(self, url): - rest, sep, article_id = url.partition('index.asp?idnoticia=') + rest, sep, article_id = url.partition('index.asp?idnoticia=') return u'http://www.lasegunda.com/edicionOnline/include/secciones/_detalle_impresion.asp?idnoticia=' + article_id - + diff --git a/resources/recipes/lamujerdemivida.recipe b/resources/recipes/lamujerdemivida.recipe index 207646902b..be7a3fad0d 100644 --- a/resources/recipes/lamujerdemivida.recipe +++ b/resources/recipes/lamujerdemivida.recipe @@ -11,15 +11,15 @@ from calibre.web.feeds.news import BasicNewsRecipe class LaMujerDeMiVida(BasicNewsRecipe): title = 'La Mujer de mi Vida' __author__ = 'Darko Miletic' - description = 'Cultura de otra manera' + description = 'Cultura de otra manera' oldest_article = 90 max_articles_per_feed = 100 no_stylesheets = True use_embedded_content = False encoding = 'cp1252' publisher = 'La Mujer de mi Vida' - category = 'literatura, critica, arte, ensayos' - language = 'es' + category = 'literatura, critica, arte, ensayos' + language = 'es_AR' INDEX = 'http://www.lamujerdemivida.com.ar/' html2lrf_options = [ @@ -28,8 +28,8 @@ class LaMujerDeMiVida(BasicNewsRecipe): , '--publisher', publisher , '--ignore-tables' ] - - html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True' + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True' keep_only_tags = [dict(name='table', attrs={'width':'570'})] @@ -51,7 +51,7 @@ class LaMujerDeMiVida(BasicNewsRecipe): if cover_item: cover_url = self.INDEX + cover_item['src'] return cover_url - + def parse_index(self): totalfeeds = [] lfeeds = self.get_feeds() @@ -74,4 +74,4 @@ class LaMujerDeMiVida(BasicNewsRecipe): }) totalfeeds.append((feedtitle, articles)) return totalfeeds - + diff --git a/resources/recipes/lanacion.recipe b/resources/recipes/lanacion.recipe index 050cb2e79c..05e777ec67 100644 --- a/resources/recipes/lanacion.recipe +++ b/resources/recipes/lanacion.recipe @@ -16,17 +16,17 @@ class Lanacion(BasicNewsRecipe): max_articles_per_feed = 100 use_embedded_content = False no_stylesheets = True - language = 'es' + language = 'es_AR' publication_type = 'newspaper' - remove_empty_feeds = True + remove_empty_feeds = True masthead_url = 'http://www.lanacion.com.ar/imgs/layout/logos/ln341x47.gif' extra_css = """ h1{font-family: Georgia,serif} - h2{color: #626262} - body{font-family: Arial,sans-serif} + h2{color: #626262} + body{font-family: Arial,sans-serif} img{margin-top: 0.5em; margin-bottom: 0.2em; display: block} - .notaFecha{color: #808080} - .notaEpigrafe{font-size: x-small} - .topNota h1{font-family: Arial,sans-serif} + .notaFecha{color: #808080} + .notaEpigrafe{font-size: x-small} + .topNota h1{font-family: Arial,sans-serif} """ @@ -45,7 +45,7 @@ class Lanacion(BasicNewsRecipe): ,dict(attrs={'class':['titulosMultimedia','derecha','techo color','encuesta','izquierda compartir','floatFix','videoCentro']}) ,dict(name=['iframe','embed','object','form','base','hr','meta','link','input']) ] - remove_tags_after = dict(attrs={'class':['tags','nota-destacado']}) + remove_tags_after = dict(attrs={'class':['tags','nota-destacado']}) remove_attributes = ['height','width','visible','onclick','data-count','name'] feeds = [ diff --git a/resources/recipes/lanacion_chile.recipe b/resources/recipes/lanacion_chile.recipe index f913b61855..0c0d4550fa 100644 --- a/resources/recipes/lanacion_chile.recipe +++ b/resources/recipes/lanacion_chile.recipe @@ -51,4 +51,4 @@ class LaNacionChile(BasicNewsRecipe): del item['style'] return soup - language = 'es' + language = 'es_CL' diff --git a/resources/recipes/laprensa.recipe b/resources/recipes/laprensa.recipe index 1f8c708b32..eb54ec989a 100644 --- a/resources/recipes/laprensa.recipe +++ b/resources/recipes/laprensa.recipe @@ -21,9 +21,9 @@ class LaPrensa(BasicNewsRecipe): encoding = 'cp1252' # cover_url = 'http://www.laprensa.com.ar/imgs/logo.gif' remove_javascript = True - language = 'es' + language = 'es_AR' lang = 'es' - + html2lrf_options = [ '--comment', description , '--category', category @@ -32,7 +32,7 @@ class LaPrensa(BasicNewsRecipe): html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' filter_regexps = [r'.*archive.aspx.*'] - + remove_tags = [ dict(name='td', attrs={'class':["link-registro","link-buscador"]}), dict(name='td', attrs={'id':["TDTabItem1","TDTabItem2","TDTabItem3","TDTabItem4"]}), @@ -58,9 +58,9 @@ class LaPrensa(BasicNewsRecipe): dict(name='img', src = "/versions/1/imgs/separador-linea-azul.gif"), dict(name='img', src = " /versions/1/imgs/separador-linea.gif"), dict(name='a',text ="Powered by Civinext Groupware - V. 2.0.3567.23706"), - dict(name='img', height ="0") + dict(name='img', height ="0") ] - + extra_css = ''' .seccion{font-size:xx-small;} body{font-family:Arial,Helvetica,sans-serif;font-size:x-small;} @@ -69,7 +69,7 @@ class LaPrensa(BasicNewsRecipe): .fecha{font-size:xx-small;} .volanta{font-size:xx-small;} ''' - + feeds = [ (u'Politica' , u'http://www.laprensa.com.ar/ResourcesManager.aspx?Resource=Rss.aspx&Rss=4' ) ,(u'Economia' , u'http://www.laprensa.com.ar/ResourcesManager.aspx?Resource=Rss.aspx&Rss=5' ) @@ -80,14 +80,14 @@ class LaPrensa(BasicNewsRecipe): ,(u'Espectaculos', u'http://www.laprensa.com.ar/ResourcesManager.aspx?Resource=Rss.aspx?Rss=10') ] - + def preprocess_html(self, soup): - + for t in soup.findAll(['table','td','tr','span','tbody']): t.name = 'div' for t in soup.findAll(['hr']): t.extract() - + mtag = '' soup.head.insert(0,mtag) for item in soup.findAll(style=True): @@ -95,8 +95,8 @@ class LaPrensa(BasicNewsRecipe): for item in soup.findAll(align = "center"): del item['align'] for item in soup.findAll(bgcolor="ffffff"): - del item['bgcolor'] + del item['bgcolor'] return soup - - - + + + diff --git a/resources/recipes/laprensa_hn.recipe b/resources/recipes/laprensa_hn.recipe index 356882d177..d7895bf09d 100644 --- a/resources/recipes/laprensa_hn.recipe +++ b/resources/recipes/laprensa_hn.recipe @@ -21,7 +21,7 @@ class LaPrensaHn(BasicNewsRecipe): no_stylesheets = True remove_javascript = True encoding = 'utf-8' - language = 'es' + language = 'es_HN' lang = 'es-HN' direction = 'ltr' diff --git a/resources/recipes/laprensa_ni.recipe b/resources/recipes/laprensa_ni.recipe index c7f35a6d6a..9aba2839ef 100644 --- a/resources/recipes/laprensa_ni.recipe +++ b/resources/recipes/laprensa_ni.recipe @@ -22,7 +22,7 @@ class LaPrensa_ni(BasicNewsRecipe): use_embedded_content = False encoding = 'cp1252' remove_javascript = True - language = 'es' + language = 'es_NI' months_es = ['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre'] current_month = months_es[datetime.date.today().month - 1] diff --git a/resources/recipes/latribuna.recipe b/resources/recipes/latribuna.recipe index e7e461cd01..13c59dc4aa 100644 --- a/resources/recipes/latribuna.recipe +++ b/resources/recipes/latribuna.recipe @@ -21,7 +21,7 @@ class LaTribuna(BasicNewsRecipe): no_stylesheets = True remove_javascript = True encoding = 'utf-8' - language = 'es' + language = 'es_HN' lang = 'es-HN' direction = 'ltr' diff --git a/resources/recipes/ledevoir.recipe b/resources/recipes/ledevoir.recipe index c54f21c7ec..bc473be181 100644 --- a/resources/recipes/ledevoir.recipe +++ b/resources/recipes/ledevoir.recipe @@ -9,6 +9,8 @@ __description__ = 'Canadian Paper ' http://www.ledevoir.com/ ''' +import re + from calibre.web.feeds.news import BasicNewsRecipe class ledevoir(BasicNewsRecipe): @@ -32,6 +34,8 @@ class ledevoir(BasicNewsRecipe): remove_javascript = True no_stylesheets = True + preprocess_regexps = [(re.compile(r'(title|alt)=".*?>.*?"', re.DOTALL), lambda m: '')] + keep_only_tags = [ dict(name='div', attrs={'id':'article'}), dict(name='ul', attrs={'id':'ariane'}) diff --git a/resources/recipes/los_tiempos_bo.recipe b/resources/recipes/los_tiempos_bo.recipe index ae2774ff59..00ddd9d7c1 100644 --- a/resources/recipes/los_tiempos_bo.recipe +++ b/resources/recipes/los_tiempos_bo.recipe @@ -18,7 +18,7 @@ class LosTiempos_Bol(BasicNewsRecipe): no_stylesheets = True encoding = 'cp1252' use_embedded_content = False - language = 'es' + language = 'es_BO' publication_type = 'newspaper' delay = 1 remove_empty_feeds = True diff --git a/resources/recipes/milenio.recipe b/resources/recipes/milenio.recipe index a279eb37dc..e6ca103952 100644 --- a/resources/recipes/milenio.recipe +++ b/resources/recipes/milenio.recipe @@ -12,7 +12,7 @@ import datetime class Milenio(BasicNewsRecipe): title = u'Milenio-diario' __author__ = 'Bmsleight' - language = 'es' + language = 'es_MX' description = 'Milenio-diario' oldest_article = 10 max_articles_per_feed = 100 diff --git a/resources/recipes/miradasalsur.recipe b/resources/recipes/miradasalsur.recipe index f966a94ee9..fd306adc86 100644 --- a/resources/recipes/miradasalsur.recipe +++ b/resources/recipes/miradasalsur.recipe @@ -20,7 +20,7 @@ class MiradasAlSur(BasicNewsRecipe): no_stylesheets = True use_embedded_content = False encoding = 'utf-8' - language = 'es' + language = 'es_AR' lang = 'es-AR' direction = 'ltr' diff --git a/resources/recipes/montevideo_com.recipe b/resources/recipes/montevideo_com.recipe index cabd4181d6..6f1474f0c0 100644 --- a/resources/recipes/montevideo_com.recipe +++ b/resources/recipes/montevideo_com.recipe @@ -12,7 +12,7 @@ class Noticias(BasicNewsRecipe): title = 'Montevideo COMM' __author__ = 'Gustavo Azambuja' description = 'Noticias de Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 5 diff --git a/resources/recipes/newsweek_argentina.recipe b/resources/recipes/newsweek_argentina.recipe index 96c50bf6c3..a474f75f60 100644 --- a/resources/recipes/newsweek_argentina.recipe +++ b/resources/recipes/newsweek_argentina.recipe @@ -20,7 +20,7 @@ class Newsweek_Argentina(BasicNewsRecipe): no_stylesheets = True use_embedded_content = False encoding = 'utf-8' - language = 'es' + language = 'es_AR' lang = 'es-AR' direction = 'ltr' diff --git a/resources/recipes/observa_digital.recipe b/resources/recipes/observa_digital.recipe index 375d67236c..cb493bcb26 100644 --- a/resources/recipes/observa_digital.recipe +++ b/resources/recipes/observa_digital.recipe @@ -12,7 +12,7 @@ class Noticias(BasicNewsRecipe): title = 'Observa Digital' __author__ = '2010, Gustavo Azambuja ' description = 'Noticias desde Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 5 diff --git a/resources/recipes/pagina12.recipe b/resources/recipes/pagina12.recipe index 2809e87e2a..b706acb7d7 100644 --- a/resources/recipes/pagina12.recipe +++ b/resources/recipes/pagina12.recipe @@ -19,15 +19,15 @@ class Pagina12(BasicNewsRecipe): no_stylesheets = True encoding = 'cp1252' use_embedded_content = False - language = 'es' + language = 'es_AR' remove_empty_feeds = True publication_type = 'newspaper' masthead_url = 'http://www.pagina12.com.ar/commons/imgs/logo-home.gif' - extra_css = """ - body{font-family: Arial,Helvetica,sans-serif } + extra_css = """ + body{font-family: Arial,Helvetica,sans-serif } img{margin-bottom: 0.4em; display:block} - #autor{font-weight: bold} - #fecha,#epigrafe{font-size: 0.9em; margin: 5px} + #autor{font-weight: bold} + #fecha,#epigrafe{font-size: 0.9em; margin: 5px} #imagen{border: 1px solid black; margin: 0 0 1.25em 1.25em; width: 232px } .fgprincipal{font-size: large; font-weight: bold} """ @@ -83,7 +83,7 @@ class Pagina12(BasicNewsRecipe): del it['href'] del it['title'] for item in soup.findAll('p'): - it = item.find('h3') + it = item.find('h3') if it: it.name='span' - return soup \ No newline at end of file + return soup diff --git a/resources/recipes/perfil.recipe b/resources/recipes/perfil.recipe index 7f51485bd0..7db86f9d4a 100644 --- a/resources/recipes/perfil.recipe +++ b/resources/recipes/perfil.recipe @@ -17,7 +17,7 @@ class Perfil(BasicNewsRecipe): no_stylesheets = True encoding = 'cp1252' use_embedded_content = False - language = 'es' + language = 'es_AR' remove_empty_feeds = True masthead_url = 'http://www.perfil.com/export/sites/diarioperfil/arte/10/logo_perfilcom_mm.gif' extra_css = """ diff --git a/resources/recipes/reptantes.recipe b/resources/recipes/reptantes.recipe index 51b65c6639..8e5ccbd192 100644 --- a/resources/recipes/reptantes.recipe +++ b/resources/recipes/reptantes.recipe @@ -13,7 +13,7 @@ class Reptantes(BasicNewsRecipe): description = u"cada vez que te haces acupuntura, tu muñeco vudú sufre en algún lado" oldest_article = 130 max_articles_per_feed = 100 - language = 'es' + language = 'es_AR' encoding = 'utf-8' no_stylesheets = True use_embedded_content = False diff --git a/resources/recipes/revista_bla.recipe b/resources/recipes/revista_bla.recipe index 15c7e7fb3f..a575d01d0b 100644 --- a/resources/recipes/revista_bla.recipe +++ b/resources/recipes/revista_bla.recipe @@ -12,7 +12,7 @@ class Noticias(BasicNewsRecipe): title = 'Revista Bla' __author__ = 'Gustavo Azambuja' description = 'Moda | Uruguay' - language = 'es' + language = 'es_UY' timefmt = '[%a, %d %b, %Y]' use_embedded_content = False recursion = 5 diff --git a/resources/recipes/veintitres.recipe b/resources/recipes/veintitres.recipe index 6c8d3d1260..d36ac8568b 100644 --- a/resources/recipes/veintitres.recipe +++ b/resources/recipes/veintitres.recipe @@ -20,7 +20,7 @@ class Veintitres(BasicNewsRecipe): no_stylesheets = True use_embedded_content = False encoding = 'utf-8' - language = 'es' + language = 'es_AR' lang = 'es-AR' direction = 'ltr' diff --git a/resources/recipes/vijesti.recipe b/resources/recipes/vijesti.recipe index c901755b78..d650bdec06 100644 --- a/resources/recipes/vijesti.recipe +++ b/resources/recipes/vijesti.recipe @@ -1,6 +1,6 @@ __license__ = 'GPL v3' -__copyright__ = '2009-2010, Darko Miletic ' +__copyright__ = '2009-2011, Darko Miletic ' ''' vijesti.me @@ -18,12 +18,16 @@ class Vijesti(BasicNewsRecipe): oldest_article = 2 max_articles_per_feed = 150 no_stylesheets = True - encoding = 'cp1250' + encoding = 'utf8' use_embedded_content = False language = 'sr' publication_type = 'newspaper' - masthead_url = 'http://www.vijesti.me/img/logo.gif' - extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}' + extra_css = """ + @font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} + @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} + body{font-family: Georgia,"Times New Roman",Times,serif1,serif} + .articledescription,.article,.chapter{font-family: sans1, sans-serif} + """ conversion_options = { 'comment' : description @@ -34,11 +38,11 @@ class Vijesti(BasicNewsRecipe): preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] - keep_only_tags = [dict(name='div', attrs={'id':'mainnews'})] + keep_only_tags = [dict(name='div', attrs={'id':['article_intro_text','article_text']})] remove_tags = [dict(name=['object','link','embed','form'])] - feeds = [(u'Sve vijesti', u'http://www.vijesti.me/rss.php' )] + feeds = [(u'Sve vijesti', u'http://www.vijesti.me/rss/' )] def preprocess_html(self, soup): return self.adeify_images(soup) diff --git a/setup/installer/linux/freeze2.py b/setup/installer/linux/freeze2.py index bd8463b1a7..4d5d1a63e7 100644 --- a/setup/installer/linux/freeze2.py +++ b/setup/installer/linux/freeze2.py @@ -360,6 +360,9 @@ class LinuxFreeze(Command): def main(): try: sys.argv[0] = sys.calibre_basename + dfv = os.environ.get('CALIBRE_DEVELOP_FROM', None) + if dfv and os.path.exists(dfv): + sys.path.insert(0, os.path.abspath(dfv)) set_default_encoding() set_helper() set_qt_plugin_path() diff --git a/src/calibre/devices/eb600/driver.py b/src/calibre/devices/eb600/driver.py index 95f6dc6ab0..1f723ce46a 100644 --- a/src/calibre/devices/eb600/driver.py +++ b/src/calibre/devices/eb600/driver.py @@ -21,6 +21,7 @@ from calibre.devices.usbms.driver import USBMS class EB600(USBMS): name = 'Netronix EB600 Device Interface' + gui_name = 'Netronix EB600' description = _('Communicate with the EB600 eBook reader.') author = 'Kovid Goyal' supported_platforms = ['windows', 'osx', 'linux'] diff --git a/src/calibre/ebooks/comic/input.py b/src/calibre/ebooks/comic/input.py index 04d097ac67..c9b11e31f2 100755 --- a/src/calibre/ebooks/comic/input.py +++ b/src/calibre/ebooks/comic/input.py @@ -53,7 +53,7 @@ def find_pages(dir, sort_on_mtime=False, verbose=False): prints('\t'+'\n\t'.join([os.path.basename(p) for p in pages])) return pages -class PageProcessor(list): +class PageProcessor(list): # {{{ ''' Contains the actual image rendering logic. See :method:`render` and :method:`process_pages`. @@ -111,6 +111,13 @@ class PageProcessor(list): SCRWIDTH, SCRHEIGHT = self.opts.output_profile.comic_screen_size + try: + if self.opts.comic_image_size: + SCRWIDTH, SCRHEIGHT = map(int, [x.strip() for x in + self.opts.comic_image_size.split('x')]) + except: + pass # Ignore + if self.opts.keep_aspect_ratio: # Preserve the aspect ratio by adding border aspect = float(sizex) / float(sizey) @@ -170,6 +177,7 @@ class PageProcessor(list): dest = dest[:-1] os.rename(dest+'8', dest) self.append(dest) +# }}} def render_pages(tasks, dest, opts, notification=lambda x, y: x): ''' @@ -291,7 +299,11 @@ class ComicInput(InputFormatPlugin): OptionRecommendation(name='no_process', recommended_value=False, help=_("Apply no processing to the image")), OptionRecommendation(name='dont_grayscale', recommended_value=False, - help=_('Do not convert the image to grayscale (black and white)')) + help=_('Do not convert the image to grayscale (black and white)')), + OptionRecommendation(name='comic_image_size', recommended_value=None, + help=_('Specify the image size as widthxheight pixels. Normally,' + ' an image size is automatically calculated from the output ' + 'profile, this option overrides it.')), ]) recommendations = set([ diff --git a/src/calibre/ebooks/lit/input.py b/src/calibre/ebooks/lit/input.py index ff901c3715..9ccbba543f 100644 --- a/src/calibre/ebooks/lit/input.py +++ b/src/calibre/ebooks/lit/input.py @@ -38,13 +38,16 @@ class LITInput(InputFormatPlugin): if len(body) == 1 and body[0].tag == XHTML('pre'): pre = body[0] from calibre.ebooks.txt.processor import convert_basic, preserve_spaces, \ - separate_paragraphs_single_line + separate_paragraphs_single_line + from calibre.ebooks.chardet import xml_to_unicode from lxml import etree import copy html = separate_paragraphs_single_line(pre.text) html = preserve_spaces(html) html = convert_basic(html).replace('', ''%XHTML_NS) + html = xml_to_unicode(html, strip_encoding_pats=True, + resolve_entities=True)[0] root = etree.fromstring(html) body = XPath('//h:body')(root) pre.tag = XHTML('div') diff --git a/src/calibre/ebooks/mobi/reader.py b/src/calibre/ebooks/mobi/reader.py index 2f397006a1..0ae3c9ac9d 100644 --- a/src/calibre/ebooks/mobi/reader.py +++ b/src/calibre/ebooks/mobi/reader.py @@ -488,7 +488,7 @@ class MobiReader(object): def remove_random_bytes(self, html): - return re.sub('\x14|\x15|\x19|\x1c|\x1d|\xef|\x12|\x13|\xec|\x08', + return re.sub('\x14|\x15|\x19|\x1c|\x1d|\xef|\x12|\x13|\xec|\x08|\x01|\x02|\x03|\x04|\x05|\x06|\x07', '', html) def ensure_unit(self, raw, unit='px'): diff --git a/src/calibre/ebooks/rtf/input.py b/src/calibre/ebooks/rtf/input.py index ca6f2c7b95..52f6feb071 100644 --- a/src/calibre/ebooks/rtf/input.py +++ b/src/calibre/ebooks/rtf/input.py @@ -83,6 +83,7 @@ class RTFInput(InputFormatPlugin): os.mkdir(debug_dir) debug_dir = 'rtfdebug' run_lev = 4 + self.log('Running RTFParser in debug mode') except: pass parser = ParseRtf( @@ -230,22 +231,6 @@ class RTFInput(InputFormatPlugin): with open('styles.css', 'ab') as f: f.write(css) - # def preprocess(self, fname): - # self.log('\tPreprocessing to convert unicode characters') - # try: - # data = open(fname, 'rb').read() - # from calibre.ebooks.rtf.preprocess import RtfTokenizer, RtfTokenParser - # tokenizer = RtfTokenizer(data) - # tokens = RtfTokenParser(tokenizer.tokens) - # data = tokens.toRTF() - # fname = 'preprocessed.rtf' - # with open(fname, 'wb') as f: - # f.write(data) - # except: - # self.log.exception( - # 'Failed to preprocess RTF to convert unicode sequences, ignoring...') - # return fname - def convert_borders(self, doc): border_styles = [] style_map = {} @@ -280,8 +265,6 @@ class RTFInput(InputFormatPlugin): self.opts = options self.log = log self.log('Converting RTF to XML...') - #Name of the preprocesssed RTF file - # fname = self.preprocess(stream.name) try: xml = self.generate_xml(stream.name) except RtfInvalidCodeException, e: @@ -335,3 +318,4 @@ class RTFInput(InputFormatPlugin): opf.render(open('metadata.opf', 'wb')) return os.path.abspath('metadata.opf') + diff --git a/src/calibre/ebooks/rtf/rtfml.py b/src/calibre/ebooks/rtf/rtfml.py index 1fb14eb06f..f739207018 100644 --- a/src/calibre/ebooks/rtf/rtfml.py +++ b/src/calibre/ebooks/rtf/rtfml.py @@ -24,14 +24,15 @@ from calibre.utils.magick.draw import save_cover_data_to, identify_data TAGS = { 'b': '\\b', 'del': '\\deleted', - 'h1': '\\b \\par \\pard \\hyphpar', - 'h2': '\\b \\par \\pard \\hyphpar', - 'h3': '\\b \\par \\pard \\hyphpar', - 'h4': '\\b \\par \\pard \\hyphpar', - 'h5': '\\b \\par \\pard \\hyphpar', - 'h6': '\\b \\par \\pard \\hyphpar', - 'li': '\\par \\pard \\hyphpar \t', - 'p': '\\par \\pard \\hyphpar \t', + 'h1': '\\s1 \\afs32', + 'h2': '\\s2 \\afs28', + 'h3': '\\s3 \\afs28', + 'h4': '\\s4 \\afs23', + 'h5': '\\s5 \\afs23', + 'h6': '\\s6 \\afs21', + 'i': '\\i', + 'li': '\t', + 'p': '\t', 'sub': '\\sub', 'sup': '\\super', 'u': '\\ul', @@ -39,15 +40,9 @@ TAGS = { SINGLE_TAGS = { 'br': '\n{\\line }\n', - 'div': '\n{\\line }\n', -} - -SINGLE_TAGS_END = { - 'div': '\n{\\line }\n', } STYLES = [ - ('display', {'block': '\\par \\pard \\hyphpar'}), ('font-weight', {'bold': '\\b', 'bolder': '\\b'}), ('font-style', {'italic': '\\i'}), ('text-align', {'center': '\\qc', 'left': '\\ql', 'right': '\\qr'}), @@ -55,6 +50,7 @@ STYLES = [ ] BLOCK_TAGS = [ + 'div', 'p', 'h1', 'h2', @@ -112,14 +108,16 @@ class RTFMLizer(object): stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts, self.opts.output_profile) output += self.dump_text(item.data.find(XHTML('body')), stylizer) - output += '{\\page } ' + output += '{\\page }' for item in self.oeb_book.spine: self.log.debug('Converting %s to RTF markup...' % item.href) content = unicode(etree.tostring(item.data, encoding=unicode)) content = self.remove_newlines(content) + content = self.remove_tabs(content) content = etree.fromstring(content) stylizer = Stylizer(content, item.href, self.oeb_book, self.opts, self.opts.output_profile) output += self.dump_text(content.find(XHTML('body')), stylizer) + output += '{\\page }' output += self.footer() output = self.insert_images(output) output = self.clean_text(output) @@ -134,8 +132,23 @@ class RTFMLizer(object): return text + def remove_tabs(self, text): + self.log.debug('\Replace tabs with space for processing...') + text = text.replace('\t', ' ') + + return text + def header(self): - return u'{\\rtf1{\\info{\\title %s}{\\author %s}}\\ansi\\ansicpg1252\\deff0\\deflang1033' % (self.oeb_book.metadata.title[0].value, authors_to_string([x.value for x in self.oeb_book.metadata.creator])) + header = u'{\\rtf1{\\info{\\title %s}{\\author %s}}\\ansi\\ansicpg1252\\deff0\\deflang1033\n' % (self.oeb_book.metadata.title[0].value, authors_to_string([x.value for x in self.oeb_book.metadata.creator])) + return header + \ + '{\\fonttbl{\\f0\\froman\\fprq2\\fcharset128 Times New Roman;}{\\f1\\froman\\fprq2\\fcharset128 Times New Roman;}{\\f2\\fswiss\\fprq2\\fcharset128 Arial;}{\\f3\\fnil\\fprq2\\fcharset128 Arial;}{\\f4\\fnil\\fprq2\\fcharset128 MS Mincho;}{\\f5\\fnil\\fprq2\\fcharset128 Tahoma;}{\\f6\\fnil\\fprq0\\fcharset128 Tahoma;}}\n' \ + '{\\stylesheet{\\ql \\li0\\ri0\\nowidctlpar\\wrapdefault\\faauto\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\af25\\afs24\\alang1033 \\ltrch\\fcs0 \\fs24\\lang1033\\langfe255\\cgrid\\langnp1033\\langfenp255 \\snext0 Normal;}\n' \ + '{\\s1\\ql \\li0\\ri0\\sb240\\sa120\\keepn\\nowidctlpar\\wrapdefault\\faauto\\outlinelevel0\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\ab\\af0\\afs32\\alang1033 \\ltrch\\fcs0 \\b\\fs32\\lang1033\\langfe255\\loch\\f1\\hich\\af1\\dbch\\af26\\cgrid\\langnp1033\\langfenp255 \\sbasedon15 \\snext16 \\slink21 heading 1;}\n' \ + '{\\s2\\ql \\li0\\ri0\\sb240\\sa120\\keepn\\nowidctlpar\\wrapdefault\\faauto\\outlinelevel1\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\ab\\ai\\af0\\afs28\\alang1033 \\ltrch\\fcs0 \\b\\i\\fs28\\lang1033\\langfe255\\loch\\f1\\hich\\af1\\dbch\\af26\\cgrid\\langnp1033\\langfenp255 \\sbasedon15 \\snext16 \\slink22 heading 2;}\n' \ + '{\\s3\\ql \\li0\\ri0\\sb240\\sa120\\keepn\\nowidctlpar\\wrapdefault\\faauto\\outlinelevel2\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\ab\\af0\\afs28\\alang1033 \\ltrch\\fcs0 \\b\\fs28\\lang1033\\langfe255\\loch\\f1\\hich\\af1\\dbch\\af26\\cgrid\\langnp1033\\langfenp255 \\sbasedon15 \\snext16 \\slink23 heading 3;}\n' \ + '{\\s4\\ql \\li0\\ri0\\sb240\\sa120\\keepn\\nowidctlpar\\wrapdefault\\faauto\\outlinelevel3\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\ab\\ai\\af0\\afs23\\alang1033 \\ltrch\\fcs0\\b\\i\\fs23\\lang1033\\langfe255\\loch\\f1\\hich\\af1\\dbch\\af26\\cgrid\\langnp1033\\langfenp255 \\sbasedon15 \\snext16 \\slink24 heading 4;}\n' \ + '{\\s5\\ql \\li0\\ri0\\sb240\\sa120\\keepn\\nowidctlpar\\wrapdefault\\faauto\\outlinelevel4\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\ab\\af0\\afs23\\alang1033 \\ltrch\\fcs0 \\b\\fs23\\lang1033\\langfe255\\loch\\f1\\hich\\af1\\dbch\\af26\\cgrid\\langnp1033\\langfenp255 \\sbasedon15 \\snext16 \\slink25 heading 5;}\n' \ + '{\\s6\\ql \\li0\\ri0\\sb240\\sa120\\keepn\\nowidctlpar\\wrapdefault\\faauto\\outlinelevel5\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\ab\\af0\\afs21\\alang1033 \\ltrch\\fcs0 \\b\\fs21\\lang1033\\langfe255\\loch\\f1\\hich\\af1\\dbch\\af26\\cgrid\\langnp1033\\langfenp255 \\sbasedon15 \\snext16 \\slink26 heading 6;}}\n' def footer(self): return ' }' @@ -170,19 +183,16 @@ class RTFMLizer(object): return (hex_string, width, height) def clean_text(self, text): - # Remove excess spaces at beginning and end of lines - text = re.sub('(?m)^[ ]+', '', text) - text = re.sub('(?m)[ ]+$', '', text) - # Remove excessive newlines - #text = re.sub('%s{1,1}' % os.linesep, '%s%s' % (os.linesep, os.linesep), text) text = re.sub('%s{3,}' % os.linesep, '%s%s' % (os.linesep, os.linesep), text) # Remove excessive spaces text = re.sub('[ ]{2,}', ' ', text) + text = re.sub('\t{2,}', '\t', text) + text = re.sub('\t ', '\t', text) + # Remove excessive line breaks text = re.sub(r'(\{\\line \}\s*){3,}', r'{\\line }{\\line }', text) - #text = re.compile(r'(\{\\line \}\s*)+(?P}*)\s*\{\\par').sub(lambda mo: r'%s{\\par' % mo.group('brackets'), text) # Remove non-breaking spaces text = text.replace(u'\xa0', ' ') @@ -222,7 +232,7 @@ class RTFMLizer(object): block_start = '' block_end = '' if 'block' not in tag_stack: - block_start = '{\\par \\pard \\hyphpar ' + block_start = '{\\par\\pard\\hyphpar ' block_end = '}' text += '%s SPECIAL_IMAGE-%s-REPLACE_ME %s' % (block_start, src, block_end) @@ -245,7 +255,7 @@ class RTFMLizer(object): tag_stack.append(style_tag) # Proccess tags that contain text. - if hasattr(elem, 'text') and elem.text != None and elem.text.strip() != '': + if hasattr(elem, 'text') and elem.text: text += txt2rtf(elem.text) for item in elem: @@ -254,16 +264,15 @@ class RTFMLizer(object): for i in range(0, tag_count): end_tag = tag_stack.pop() if end_tag != 'block': - text += u'}' + if tag in BLOCK_TAGS: + text += u'\\par\\pard\\plain\\hyphpar}' + else: + text += u'}' - single_tag_end = SINGLE_TAGS_END.get(tag, None) - if single_tag_end: - text += single_tag_end - - if hasattr(elem, 'tail') and elem.tail != None and elem.tail.strip() != '': + if hasattr(elem, 'tail') and elem.tail: if 'block' in tag_stack: text += '%s' % txt2rtf(elem.tail) else: - text += '{\\par \\pard \\hyphpar %s}' % txt2rtf(elem.tail) + text += '{\\par\\pard\\hyphpar %s}' % txt2rtf(elem.tail) return text diff --git a/src/calibre/ebooks/rtf2xml/ParseRtf.py b/src/calibre/ebooks/rtf2xml/ParseRtf.py index d673836210..831183f0dd 100755 --- a/src/calibre/ebooks/rtf2xml/ParseRtf.py +++ b/src/calibre/ebooks/rtf2xml/ParseRtf.py @@ -238,6 +238,8 @@ class ParseRtf: bug_handler = RtfInvalidCodeException, ) enc = 'cp' + encode_obj.get_codepage() + if enc == 'cp10000': + enc = 'mac_roman' msg = 'Exception in token processing' if check_encoding_obj.check_encoding(self.__file, enc): file_name = self.__file if isinstance(self.__file, str) \ diff --git a/src/calibre/ebooks/rtf2xml/colors.py b/src/calibre/ebooks/rtf2xml/colors.py index d81b293bbf..eba03547c8 100755 --- a/src/calibre/ebooks/rtf2xml/colors.py +++ b/src/calibre/ebooks/rtf2xml/colors.py @@ -15,8 +15,10 @@ # # # # ######################################################################### -import sys, os, tempfile, re +import sys, os, tempfile, re + from calibre.ebooks.rtf2xml import copy + class Colors: """ Change lines with color info from color numbers to the actual color names. @@ -40,8 +42,10 @@ class Colors: self.__file = in_file self.__copy = copy self.__bug_handler = bug_handler + self.__line = 0 self.__write_to = tempfile.mktemp() self.__run_level = run_level + def __initiate_values(self): """ Initiate all values. @@ -61,6 +65,7 @@ class Colors: self.__color_num = 1 self.__line_color_exp = re.compile(r'bdr-color_:(\d+)') # cw 3: - msg = 'no value in self.__color_dict for key %s\n' % num - raise self.__bug_hanlder, msg - if hex_num == None: + if hex_num is None: hex_num = '0' + if self.__run_level > 5: + msg = 'no value in self.__color_dict' \ + 'for key %s at line %d\n' % (num, self.__line) + raise self.__bug_handler, msg return hex_num + def __do_nothing_func(self, line): """ Bad RTF will have text in the color table """ pass + def convert_colors(self): """ Requires: @@ -226,20 +238,16 @@ class Colors: info, and substitute the number with the hex number. """ self.__initiate_values() - read_obj = open(self.__file, 'r') - self.__write_obj = open(self.__write_to, 'w') - line_to_read = 1 - while line_to_read: - line_to_read = read_obj.readline() - line = line_to_read - self.__token_info = line[:16] - action = self.__state_dict.get(self.__state) - if action == None: - sys.stderr.write('no no matching state in module fonts.py\n') - sys.stderr.write(self.__state + '\n') - action(line) - read_obj.close() - self.__write_obj.close() + with open(self.__file, 'r') as read_obj: + with open(self.__write_to, 'w') as self.__write_obj: + for line in read_obj: + self.__line+=1 + self.__token_info = line[:16] + action = self.__state_dict.get(self.__state) + if action is None: + sys.stderr.write('no matching state in module fonts.py\n') + sys.stderr.write(self.__state + '\n') + action(line) copy_obj = copy.Copy(bug_handler = self.__bug_handler) if self.__copy: copy_obj.copy_file(self.__write_to, "color.data") diff --git a/src/calibre/ebooks/rtf2xml/convert_to_tags.py b/src/calibre/ebooks/rtf2xml/convert_to_tags.py index 6927537474..1abc672f85 100755 --- a/src/calibre/ebooks/rtf2xml/convert_to_tags.py +++ b/src/calibre/ebooks/rtf2xml/convert_to_tags.py @@ -33,13 +33,13 @@ class ConvertToTags: self.__copy = copy self.__dtd_path = dtd_path self.__no_dtd = no_dtd - if encoding != 'mac_roman': - self.__encoding = 'cp' + encoding - else: + self.__encoding = 'cp' + encoding + if encoding == 'mac_roman': self.__encoding = 'mac_roman' self.__indent = indent self.__run_level = run_level self.__write_to = tempfile.mktemp() + self.__convert_utf = False def __initiate_values(self): """ @@ -213,7 +213,8 @@ class ConvertToTags: if not check_encoding_obj.check_encoding(self.__file, verbose=False): self.__write_obj.write('') elif not check_encoding_obj.check_encoding(self.__file, self.__encoding): - self.__write_obj.write('' % self.__encoding) + self.__write_obj.write('') + self.__convert_utf = True else: self.__write_obj.write('') sys.stderr.write('Bad RTF encoding, revert to US-ASCII chars and' @@ -253,15 +254,28 @@ class ConvertToTags: an empty tag function. """ self.__initiate_values() - self.__write_obj = open(self.__write_to, 'w') - self.__write_dec() - with open(self.__file, 'r') as read_obj: - for line in read_obj: - self.__token_info = line[:16] - action = self.__state_dict.get(self.__token_info) - if action is not None: - action(line) + with open(self.__write_to, 'w') as self.__write_obj: + self.__write_dec() + with open(self.__file, 'r') as read_obj: + for line in read_obj: + self.__token_info = line[:16] + action = self.__state_dict.get(self.__token_info) + if action is not None: + action(line) self.__write_obj.close() + #convert all encodings to UTF8 to avoid unsupported encodings in lxml + if self.__convert_utf: + copy_obj = copy.Copy(bug_handler = self.__bug_handler) + copy_obj.rename(self.__write_to, self.__file) + with open(self.__file, 'r') as read_obj: + with open(self.__write_to, 'w') as write_obj: + file = read_obj.read() + try: + file = file.decode(self.__encoding) + write_obj.write(file.encode('utf-8')) + except: + sys.stderr.write('Conversion to UTF-8 is not possible,' + ' encoding should be very carefully checked') copy_obj = copy.Copy(bug_handler = self.__bug_handler) if self.__copy: copy_obj.copy_file(self.__write_to, "convert_to_tags.data") diff --git a/src/calibre/ebooks/rtf2xml/default_encoding.py b/src/calibre/ebooks/rtf2xml/default_encoding.py index 3ddfbcd321..c0a43db800 100755 --- a/src/calibre/ebooks/rtf2xml/default_encoding.py +++ b/src/calibre/ebooks/rtf2xml/default_encoding.py @@ -75,12 +75,16 @@ class DefaultEncoding: self._encoding() self.__datafetched = True code_page = 'ansicpg' + self.__code_page + if self.__code_page == '10000': + self.__code_page = 'mac_roman' return self.__platform, code_page, self.__default_num def get_codepage(self): if not self.__datafetched: self._encoding() self.__datafetched = True + if self.__code_page == '10000': + self.__code_page = 'mac_roman' return self.__code_page def get_platform(self): diff --git a/src/calibre/ebooks/rtf2xml/fonts.py b/src/calibre/ebooks/rtf2xml/fonts.py index b85717ce48..45ed3c1957 100755 --- a/src/calibre/ebooks/rtf2xml/fonts.py +++ b/src/calibre/ebooks/rtf2xml/fonts.py @@ -16,7 +16,9 @@ # # ######################################################################### import sys, os, tempfile + from calibre.ebooks.rtf2xml import copy + class Fonts: """ Change lines with font info from font numbers to the actual font names. @@ -45,6 +47,7 @@ class Fonts: self.__default_font_num = default_font_num self.__write_to = tempfile.mktemp() self.__run_level = run_level + def __initiate_values(self): """ Initiate all values. @@ -67,6 +70,7 @@ class Fonts: self.__font_table = {} # individual font written self.__wrote_ind_font = 0 + def __default_func(self, line): """ Requires: @@ -79,6 +83,7 @@ class Fonts: if self.__token_info == 'miTimes0\n' ) + 'Times0\n') + def __after_font_table_func(self, line): """ Required: @@ -169,7 +177,7 @@ class Fonts: if self.__token_info == 'cw 3: msg = 'no value for %s in self.__font_table\n' % font_num raise self.__bug_handler, msg @@ -182,6 +190,7 @@ class Fonts: ) else: self.__write_obj.write(line) + def convert_fonts(self): """ Required: @@ -197,20 +206,15 @@ class Fonts: info. Substitute a font name for a font number. """ self.__initiate_values() - read_obj = open(self.__file, 'r') - self.__write_obj = open(self.__write_to, 'w') - line_to_read = 1 - while line_to_read: - line_to_read = read_obj.readline() - line = line_to_read - self.__token_info = line[:16] - action = self.__state_dict.get(self.__state) - if action == None: - sys.stderr.write('no no matching state in module fonts.py\n') - sys.stderr.write(self.__state + '\n') - action(line) - read_obj.close() - self.__write_obj.close() + with open(self.__file, 'r') as read_obj: + with open(self.__write_to, 'w') as self.__write_obj: + for line in read_obj: + self.__token_info = line[:16] + action = self.__state_dict.get(self.__state) + if action is None: + sys.stderr.write('no matching state in module fonts.py\n' \ + + self.__state + '\n') + action(line) default_font_name = self.__font_table.get(self.__default_font_num) if not default_font_name: default_font_name = 'Not Defined' diff --git a/src/calibre/ebooks/rtf2xml/get_char_map.py b/src/calibre/ebooks/rtf2xml/get_char_map.py index fb3ef28b4f..5944d1920d 100755 --- a/src/calibre/ebooks/rtf2xml/get_char_map.py +++ b/src/calibre/ebooks/rtf2xml/get_char_map.py @@ -43,7 +43,7 @@ class GetCharMap: def get_char_map(self, map): if map == 'ansicpg0': map = 'ansicpg1250' - if map in ('ansicpg10000', '10000'): + if map == 'ansicpg10000': map = 'mac_roman' found_map = False map_dict = {} diff --git a/src/calibre/ebooks/rtf2xml/tokenize.py b/src/calibre/ebooks/rtf2xml/tokenize.py index 20438a2e66..59c2cab082 100755 --- a/src/calibre/ebooks/rtf2xml/tokenize.py +++ b/src/calibre/ebooks/rtf2xml/tokenize.py @@ -126,12 +126,6 @@ class Tokenize: tokens = re.split(self.__splitexp, input_file) #remove empty tokens and \n return filter(lambda x: len(x) > 0 and x != '\n', tokens) - #input_file = re.sub(self.__utf_exp, self.__from_ms_to_utf8, input_file) - # line = re.sub( self.__neg_utf_exp, self.__neg_unicode_func, line) - # this is for older RTF - #line = re.sub(self.__par_exp, '\\par ', line) - #return filter(lambda x: len(x) > 0, \ - #(self.__remove_line.sub('', x) for x in tokens)) def __compile_expressions(self): SIMPLE_RPL = { @@ -160,7 +154,7 @@ class Tokenize: } self.__replace_spchar = MReplace(SIMPLE_RPL) #add ;? in case of char following \u - self.__ms_hex_exp = re.compile(r"\\\'([0-9a-fA-F]{2})") #r"\\\'(..)" + self.__ms_hex_exp = re.compile(r"\\\'([0-9a-fA-F]{2})") self.__utf_exp = re.compile(r"\\u(-?\d{3,6}) ?") self.__bin_exp = re.compile(r"(?:\\bin(-?\d{0,10})[\n ]+)[01\n]+") #manage upr/ud situations @@ -172,14 +166,21 @@ class Tokenize: self.__splitexp = re.compile(r"(\\[{}]|\n|\\[^\s\\{}&]+(?:[ \t\r\f\v])?)") #this is for old RTF self.__par_exp = re.compile(r'\\\n+') - # self.__par_exp = re.compile(r'\\$') + #handle cw using a digit as argument and without space as delimiter + self.__cwdigit_exp = re.compile(r"(\\[a-zA-Z]+[\-0-9]+)([^0-9 \\]+)") #self.__bin_exp = re.compile(r"\\bin(-?\d{1,8}) {0,1}") #self.__utf_exp = re.compile(r"^\\u(-?\d{3,6})") #self.__splitexp = re.compile(r"(\\[\\{}]|{|}|\n|\\[^\s\\{}&]+(?:\s)?)") #self.__remove_line = re.compile(r'\n+') - #self.__mixed_exp = re.compile(r"(\\[a-zA-Z]+\d+)(\D+)") ##self.num_exp = re.compile(r"(\*|:|[a-zA-Z]+)(.*)") + def __correct_spliting(self, token): + match_obj = re.search(self.__cwdigit_exp, token) + if match_obj is None: + return token + else: + return '%s\n%s' % (match_obj.group(1), match_obj.group(2)) + def tokenize(self): """Main class for handling other methods. Reads the file \ , uses method self.sub_reg to make basic substitutions,\ @@ -187,7 +188,7 @@ class Tokenize: #read with open(self.__file, 'r') as read_obj: input_file = read_obj.read() - + #process simple replacements and split giving us a correct list #remove '' and \n in the process tokens = self.__sub_reg_split(input_file) @@ -195,7 +196,9 @@ class Tokenize: tokens = map(self.__unicode_process, tokens) #remove empty items created by removing \uc tokens = filter(lambda x: len(x) > 0, tokens) - + #handles bothersome cases + tokens = map(self.__correct_spliting, tokens) + #write with open(self.__write_to, 'wb') as write_obj: write_obj.write('\n'.join(tokens)) @@ -203,11 +206,9 @@ class Tokenize: copy_obj = copy.Copy(bug_handler = self.__bug_handler) if self.__copy: copy_obj.copy_file(self.__write_to, "tokenize.data") - # if self.__out_file: - # self.__file = self.__out_file copy_obj.rename(self.__write_to, self.__file) os.remove(self.__write_to) - + #self.__special_tokens = [ '_', '~', "'", '{', '}' ] # import sys @@ -223,4 +224,4 @@ class Tokenize: # if __name__ == '__main__': - # sys.exit(main()) \ No newline at end of file + # sys.exit(main()) diff --git a/src/calibre/gui2/convert/comic_input.py b/src/calibre/gui2/convert/comic_input.py index fe86f133d1..f7f8023c0e 100644 --- a/src/calibre/gui2/convert/comic_input.py +++ b/src/calibre/gui2/convert/comic_input.py @@ -22,7 +22,7 @@ class PluginWidget(Widget, Ui_Form): ['colors', 'dont_normalize', 'keep_aspect_ratio', 'right2left', 'despeckle', 'no_sort', 'no_process', 'landscape', 'dont_sharpen', 'disable_trim', 'wide', 'output_format', - 'dont_grayscale'] + 'dont_grayscale', 'comic_image_size'] ) self.db, self.book_id = db, book_id for x in get_option('output_format').option.choices: diff --git a/src/calibre/gui2/convert/comic_input.ui b/src/calibre/gui2/convert/comic_input.ui index c3b363d7e9..52c0ad2bb5 100644 --- a/src/calibre/gui2/convert/comic_input.ui +++ b/src/calibre/gui2/convert/comic_input.ui @@ -7,7 +7,7 @@ 0 0 599 - 345 + 398 @@ -37,70 +37,70 @@ - + Disable &normalize - + Keep &aspect ratio - + Disable &Sharpening - + Disable &Trimming - + &Wide - + &Landscape - + &Right to left - + Don't so&rt - + De&speckle - + Qt::Vertical @@ -120,7 +120,7 @@ - + &Output format: @@ -130,7 +130,7 @@ - + @@ -140,6 +140,19 @@ + + + + Override image &size: + + + opt_comic_image_size + + + + + + diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 1cf0fa5d67..a5066a99ef 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -687,7 +687,7 @@ class DeviceMixin(object): # {{{ except: pass if not self.device_error_dialog.isVisible(): - self.device_error_dialog.setDetailedText(job.details) + self.device_error_dialog.set_details(job.details) self.device_error_dialog.show() # Device connected {{{ @@ -838,9 +838,9 @@ class DeviceMixin(object): # {{{ format_count[f] = 1 for f in self.device_manager.device.settings().format_map: if f in format_count.keys(): - formats.append((f, _('%i of %i Books' % (format_count[f], len(rows))), True if f in aval_out_formats else False)) + formats.append((f, _('%i of %i Books') % (format_count[f], len(rows))), True if f in aval_out_formats else False) elif f in aval_out_formats: - formats.append((f, _('0 of %i Books' % len(rows)), True)) + formats.append((f, _('0 of %i Books') % len(rows)), True) d = ChooseFormatDeviceDialog(self, _('Choose format to send to device'), formats) if d.exec_() != QDialog.Accepted: return diff --git a/src/calibre/gui2/dialogs/check_library.py b/src/calibre/gui2/dialogs/check_library.py index bd665a7e2e..f6688b0a9e 100644 --- a/src/calibre/gui2/dialogs/check_library.py +++ b/src/calibre/gui2/dialogs/check_library.py @@ -7,7 +7,7 @@ import os, shutil from PyQt4.Qt import QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget, QLabel, \ QPushButton, QDialogButtonBox, QApplication, QTreeWidgetItem, \ - QLineEdit, Qt, QProgressBar, QSize, QTimer + QLineEdit, Qt, QProgressBar, QSize, QTimer, QIcon, QTextEdit from calibre.gui2.dialogs.confirm_delete import confirm from calibre.library.check_library import CheckLibrary, CHECKS @@ -16,7 +16,7 @@ from calibre import prints, as_unicode from calibre.ptempfile import PersistentTemporaryFile from calibre.library.sqlite import DBThread, OperationalError -class DBCheck(QDialog): +class DBCheck(QDialog): # {{{ def __init__(self, parent, db): QDialog.__init__(self, parent) @@ -74,21 +74,27 @@ class DBCheck(QDialog): self.reject() def start_load(self): - self.conn.close() - self.pb.setMaximum(self.count) - self.pb.setValue(0) - self.msg.setText(_('Loading database from SQL')) - self.db.conn.close() - self.ndbpath = PersistentTemporaryFile('.db') - self.ndbpath.close() - self.ndbpath = self.ndbpath.name - t = DBThread(self.ndbpath, False) - t.connect() - self.conn = t.conn - self.conn.execute('create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)') - self.conn.commit() + try: + self.conn.close() + self.pb.setMaximum(self.count) + self.pb.setValue(0) + self.msg.setText(_('Loading database from SQL')) + self.db.conn.close() + self.ndbpath = PersistentTemporaryFile('.db') + self.ndbpath.close() + self.ndbpath = self.ndbpath.name + t = DBThread(self.ndbpath, False) + t.connect() + self.conn = t.conn + self.conn.execute('create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)') + self.conn.commit() + + QTimer.singleShot(0, self.do_one_load) + except Exception, e: + import traceback + self.error = (as_unicode(e), traceback.format_exc()) + self.reject() - QTimer.singleShot(0, self.do_one_load) def do_one_load(self): if self.rejected: @@ -128,7 +134,7 @@ class DBCheck(QDialog): def reject(self): self.rejected = True QDialog.reject(self) - +# }}} class Item(QTreeWidgetItem): pass @@ -140,9 +146,70 @@ class CheckLibraryDialog(QDialog): self.db = db self.setWindowTitle(_('Check Library -- Problems Found')) + self.setWindowIcon(QIcon(I('debug.png'))) - self._layout = QVBoxLayout(self) - self.setLayout(self._layout) + self._tl = QHBoxLayout() + self._layout = QVBoxLayout() + self.setLayout(self._tl) + self._tl.addLayout(self._layout) + self.helpw = QTextEdit(self) + self._tl.addWidget(self.helpw) + self.helpw.setReadOnly(True) + self.helpw.setText(_('''\ +

Help

+ +

calibre stores the list of your books and their metadata in a + database. The actual book files and covers are stored as normal + files in the calibre library folder. The database contains a list of the files + and covers belonging to each book entry. This tool checks that the + actual files in the library folder on your computer match the + information in the database.

+ +

The result of each type of check is shown to the left. The various + checks are: +

+ + +

There are two kinds of automatic fixes possible: Delete + marked and Fix marked.

+

Delete marked is used to remove extra files/folders/covers that + have no entries in the database. Check the box next to the item you want + to delete. Use with caution.

+

Fix marked is applicable only to covers (the two lines marked + 'fixable'). In the case of missing cover files, checking the fixable + box and pushing this button will remove the cover mark from the + database for all the files in that category. In the case of extra + cover files, checking the fixable box and pushing this button will + add the cover mark to the database for all the files in that + category.

+ ''')) self.log = QTreeWidget(self) self.log.itemChanged.connect(self.item_changed) @@ -193,7 +260,7 @@ class CheckLibraryDialog(QDialog): self._layout.addLayout(h) self._layout.addWidget(self.bbox) - self.resize(750, 500) + self.resize(950, 500) self.bbox.setEnabled(True) def do_exec(self): @@ -341,5 +408,6 @@ class CheckLibraryDialog(QDialog): if __name__ == '__main__': app = QApplication([]) - d = CheckLibraryDialog() + from calibre.library import db + d = CheckLibraryDialog(None, db()) d.exec_() diff --git a/src/calibre/gui2/dialogs/message_box.py b/src/calibre/gui2/dialogs/message_box.py index 565fb147fc..9d586ce28d 100644 --- a/src/calibre/gui2/dialogs/message_box.py +++ b/src/calibre/gui2/dialogs/message_box.py @@ -45,14 +45,12 @@ class MessageBox(QDialog, Ui_Dialog): self.ctc_button.clicked.connect(self.copy_to_clipboard) - if det_msg: - self.show_det_msg = _('Show &details') - self.hide_det_msg = _('Hide &details') - self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole) - self.det_msg_toggle.clicked.connect(self.toggle_det_msg) - self.det_msg_toggle.setToolTip( - _('Show detailed information about this error')) - + self.show_det_msg = _('Show &details') + self.hide_det_msg = _('Hide &details') + self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole) + self.det_msg_toggle.clicked.connect(self.toggle_det_msg) + self.det_msg_toggle.setToolTip( + _('Show detailed information about this error')) self.copy_action = QAction(self) self.addAction(self.copy_action) @@ -66,10 +64,14 @@ class MessageBox(QDialog, Ui_Dialog): else: self.bb.button(self.bb.Ok).setDefault(True) + if not det_msg: + self.det_msg_toggle.setVisible(False) + self.do_resize() + def toggle_det_msg(self, *args): - vis = self.det_msg.isVisible() + vis = unicode(self.det_msg_toggle.text()) == self.hide_det_msg self.det_msg_toggle.setText(self.show_det_msg if vis else self.hide_det_msg) self.det_msg.setVisible(not vis) @@ -100,6 +102,15 @@ class MessageBox(QDialog, Ui_Dialog): self.bb.button(self.bb.Ok).setFocus(Qt.OtherFocusReason) return ret + def set_details(self, msg): + if not msg: + msg = '' + self.det_msg.setPlainText(msg) + self.det_msg_toggle.setText(self.show_det_msg) + self.det_msg_toggle.setVisible(bool(msg)) + self.det_msg.setVisible(False) + self.do_resize() + if __name__ == '__main__': app = QApplication([]) from calibre.gui2 import question_dialog diff --git a/src/calibre/gui2/dialogs/restore_library.py b/src/calibre/gui2/dialogs/restore_library.py index dd1befc11b..a57d6c86c1 100644 --- a/src/calibre/gui2/dialogs/restore_library.py +++ b/src/calibre/gui2/dialogs/restore_library.py @@ -21,7 +21,7 @@ class DBRestore(QDialog): self.l = QVBoxLayout() self.setLayout(self.l) self.l1 = QLabel(''+_('Restoring database from backups, do not' - ' interrupt, this will happen in two stages')+'...') + ' interrupt, this will happen in three stages')+'...') self.setWindowTitle(_('Restoring database')) self.l.addWidget(self.l1) self.pb = QProgressBar(self) @@ -104,7 +104,7 @@ def restore_database(db, parent=None): else: if r.errors_occurred: warning_dialog(parent, _('Success'), - _('Restoring the database succeeded with some warnings', + _('Restoring the database succeeded with some warnings' ' click Show details to see the details.'), det_msg=r.report, show=True) else: diff --git a/src/calibre/gui2/preferences/plugins.py b/src/calibre/gui2/preferences/plugins.py index 1edd4fe5f9..8f77a03c24 100644 --- a/src/calibre/gui2/preferences/plugins.py +++ b/src/calibre/gui2/preferences/plugins.py @@ -266,7 +266,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def add_plugin(self): path = choose_files(self, 'add a plugin dialog', _('Add plugin'), - filters=[(_('Plugins'), ['zip'])], all_files=False, + filters=[(_('Plugins') + ' (*.zip)', ['zip'])], all_files=False, select_only_single_file=True) if not path: return diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index 50c384b24c..655c7ea7c6 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -275,7 +275,7 @@ def generate_catalog(parent, dbspec, ids, device_manager, db): if device_manager.is_device_connected: device = device_manager.device - connected_device['name'] = device.gui_name + connected_device['name'] = device.get_gui_name() try: storage = [] if device._main_prefix: diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py index 8ad64c8cdd..460bf79c87 100644 --- a/src/calibre/library/catalog.py +++ b/src/calibre/library/catalog.py @@ -232,6 +232,7 @@ class BIBTEX(CatalogPlugin): # {{{ help = _('The fields to output when cataloging books in the ' 'database. Should be a comma-separated list of fields.\n' 'Available fields: %s.\n' + 'plus user-created custom fields.\n' 'Example: %s=title,authors,tags\n' "Default: '%%default'\n" "Applies to: BIBTEX output format")%(', '.join(FIELDS), @@ -269,7 +270,7 @@ class BIBTEX(CatalogPlugin): # {{{ dest = 'bib_cit', action = None, help = _('The template for citation creation from database fields.\n' - ' Should be a template with {} enclosed fields.\n' + 'Should be a template with {} enclosed fields.\n' 'Available fields: %s.\n' "Default: '%%default'\n" "Applies to: BIBTEX output format")%', '.join(TEMPLATE_ALLOWED_FIELDS)), @@ -344,7 +345,7 @@ class BIBTEX(CatalogPlugin): # {{{ if field == 'authors' : bibtex_entry.append(u'author = "%s"' % bibtexdict.bibtex_author_format(item)) - elif field in ['title', 'publisher', 'cover', 'uuid', + elif field in ['title', 'publisher', 'cover', 'uuid', 'ondevice', 'author_sort', 'series'] : bibtex_entry.append(u'%s = "%s"' % (field, bibtexdict.utf8ToBibtex(item))) @@ -378,7 +379,7 @@ class BIBTEX(CatalogPlugin): # {{{ if calibre_files: files = [u':%s:%s' % (format, format.rpartition('.')[2].upper())\ for format in item] - bibtex_entry.append(u'files = "%s"' % u', '.join(files)) + bibtex_entry.append(u'file = "%s"' % u', '.join(files)) elif field == 'series_index' : bibtex_entry.append(u'volume = "%s"' % int(item)) @@ -474,6 +475,8 @@ class BIBTEX(CatalogPlugin): # {{{ if opts.verbose: opts_dict = vars(opts) log("%s(): Generating %s" % (self.name,self.fmt)) + if opts.connected_device['is_device_connected']: + log(" connected_device: %s" % opts.connected_device['name']) if opts_dict['search_text']: log(" --search='%s'" % opts_dict['search_text']) @@ -548,6 +551,7 @@ class BIBTEX(CatalogPlugin): # {{{ as outfile: #File header nb_entries = len(data) + #check in book strict if all is ok else throw a warning into log if bib_entry == 'book' : nb_books = len(filter(check_entry_book_valid, data)) @@ -555,6 +559,11 @@ class BIBTEX(CatalogPlugin): # {{{ log(" WARNING: only %d entries in %d are book compatible" % (nb_books, nb_entries)) nb_entries = nb_books + # If connected device, add 'On Device' values to data + if opts.connected_device['is_device_connected'] and 'ondevice' in fields: + for entry in data: + entry['ondevice'] = db.catalog_plugin_on_device_temp_mapping[entry['id']]['ondevice'] + outfile.write(u'%%%Calibre catalog\n%%%{0} entries in catalog\n\n'.format(nb_entries)) outfile.write(u'@preamble{"This catalog of %d entries was generated by calibre on %s"}\n\n' % (nb_entries, nowf().strftime("%A, %d. %B %Y %H:%M").decode(preferred_encoding))) diff --git a/src/calibre/library/check_library.py b/src/calibre/library/check_library.py index b49330db3e..19ecb97308 100644 --- a/src/calibre/library/check_library.py +++ b/src/calibre/library/check_library.py @@ -30,8 +30,8 @@ CHECKS = [('invalid_titles', _('Invalid titles'), True, False), ('missing_formats', _('Missing book formats'), False, False), ('extra_formats', _('Extra book formats'), True, False), ('extra_files', _('Unknown files in books'), True, False), - ('missing_covers', _('Missing covers in books'), False, True), - ('extra_covers', _('Extra covers in books'), True, True), + ('missing_covers', _('Missing covers files'), False, True), + ('extra_covers', _('Cover files not in database'), True, True), ('failed_folders', _('Folders raising exception'), False, False) ] diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 3c6d4016f2..3fc16e99b4 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -1549,7 +1549,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): elif mi.cover is not None: if os.access(mi.cover, os.R_OK): with lopen(mi.cover, 'rb') as f: - doit(self.set_cover, id, f, commit=False) + raw = f.read() + if raw: + doit(self.set_cover, id, raw, commit=False) if mi.tags: doit(self.set_tags, id, mi.tags, notify=False, commit=False) if mi.comments: diff --git a/src/calibre/library/restore.py b/src/calibre/library/restore.py index bc2c740279..76f3c0333d 100644 --- a/src/calibre/library/restore.py +++ b/src/calibre/library/restore.py @@ -141,7 +141,7 @@ class Restore(Thread): sizes = [os.path.getsize(os.path.join(dirpath, x)) for x in formats] names = [os.path.splitext(x)[0] for x in formats] opf = os.path.join(dirpath, 'metadata.opf') - mi = OPF(opf).to_book_metadata() + mi = OPF(opf, basedir=dirpath).to_book_metadata() timestamp = os.path.getmtime(opf) path = os.path.relpath(dirpath, self.src_library_path).replace(os.sep, '/') diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index 15e836940e..849ded82c9 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -295,7 +295,9 @@ e-ink screen :) Note that in the case of the Kindle, there is a way to manipulate collections via USB, but it requires that the Kindle be rebooted *every time* it is disconnected from the computer, for the changes to the collections to be recognized. As such, it is unlikely that -any |app| developers will ever feel motivated enough to support it. +any |app| developers will ever feel motivated enough to support it. There is however, a |app| plugin +that allows you to create collections on your Kindle from the |app| metadata. It is available +`here `_. Library Management ------------------ diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index 03016f965e..44482e118c 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.7.43\n" -"POT-Creation-Date: 2011-01-28 12:03+MST\n" -"PO-Revision-Date: 2011-01-28 12:03+MST\n" +"POT-Creation-Date: 2011-01-30 12:40+MST\n" +"PO-Revision-Date: 2011-01-30 12:40+MST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -113,8 +113,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdf/writer.py:101 #: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:329 #: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:331 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:300 -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:299 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:306 #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:100 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:331 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:334 @@ -124,8 +124,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:120 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:145 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:147 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1066 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1069 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1064 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1067 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_empty_book.py:55 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/add_empty_book.py:67 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:47 @@ -149,15 +149,15 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/library/database2.py:432 #: /home/kovid/work/calibre/src/calibre/library/database2.py:444 #: /home/kovid/work/calibre/src/calibre/library/database2.py:1529 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:1630 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2470 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:1632 #: /home/kovid/work/calibre/src/calibre/library/database2.py:2472 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2603 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2474 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2605 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:229 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:158 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:161 #: /home/kovid/work/calibre/src/calibre/library/server/xml.py:79 -#: /home/kovid/work/calibre/src/calibre/utils/localization.py:119 +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:129 #: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:46 #: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:64 #: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:78 @@ -409,7 +409,7 @@ msgid "Setup the calibre Content Server which will give you access to your calib msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:889 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:163 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:269 msgid "Plugins" msgstr "" @@ -497,32 +497,32 @@ msgid "This profile is intended for the Cybook G3." msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:149 -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:595 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:596 msgid "This profile is intended for the Cybook Opus." msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:161 -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:608 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:609 msgid "This profile is intended for the Amazon Kindle." msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:173 -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:658 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:659 msgid "This profile is intended for the Irex Illiad." msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:185 -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:671 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:672 msgid "This profile is intended for the IRex Digital Reader 1000." msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:198 -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:685 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:686 msgid "This profile is intended for the IRex Digital Reader 800." msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/profiles.py:210 -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:699 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:700 msgid "This profile is intended for the B&N Nook." msgstr "" @@ -570,15 +570,15 @@ msgstr "" msgid "This profile is intended for the SONY PRS line. The 500/505/700 etc, in landscape mode. Mainly useful for comics." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:634 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:635 msgid "This profile is intended for the Amazon Kindle DX." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:711 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:712 msgid "This profile is intended for the B&N Nook Color." msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:722 +#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:723 msgid "This profile is intended for the Sanda Bambook." msgstr "" @@ -724,7 +724,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:262 #: /home/kovid/work/calibre/src/calibre/library/database2.py:244 #: /home/kovid/work/calibre/src/calibre/library/database2.py:257 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2334 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2336 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:150 msgid "News" msgstr "" @@ -732,8 +732,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2554 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:65 #: /home/kovid/work/calibre/src/calibre/library/catalog.py:625 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2297 -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2315 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2299 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2317 msgid "Catalog" msgstr "" @@ -841,7 +841,7 @@ msgid "Communicate with the Blackberry smart phone." msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/blackberry/driver.py:14 -#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:253 +#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:254 #: /home/kovid/work/calibre/src/calibre/devices/nuut2/driver.py:18 #: /home/kovid/work/calibre/src/calibre/devices/prs500/driver.py:90 msgid "Kovid Goyal" @@ -855,23 +855,23 @@ msgstr "" msgid "Communicate with the Cybook Orizon eBook reader." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:24 +#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:25 msgid "Communicate with the EB600 eBook reader." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:193 +#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:194 msgid "Communicate with the Astak Mentor EB600" msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:216 +#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:217 msgid "Communicate with the PocketBook 301 reader." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:233 +#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:234 msgid "Communicate with the PocketBook 602/603/902/903 reader." msgstr "" -#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:252 +#: /home/kovid/work/calibre/src/calibre/devices/eb600/driver.py:253 msgid "Communicate with the PocketBook 701" msgstr "" @@ -2665,7 +2665,7 @@ msgid "%s format books are not supported" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/cover.py:98 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:173 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:220 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:691 msgid "Book %s of %s" @@ -2720,7 +2720,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/pdb/output.py:32 #: /home/kovid/work/calibre/src/calibre/ebooks/pml/output.py:37 #: /home/kovid/work/calibre/src/calibre/ebooks/rb/output.py:21 -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:35 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:34 msgid "Add Table of Contents to beginning of the book." msgstr "" @@ -2957,12 +2957,12 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/snb/output.py:25 #: /home/kovid/work/calibre/src/calibre/ebooks/tcr/output.py:23 -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:31 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:30 msgid "Specify the character encoding of the output document. The default is utf-8." msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/snb/output.py:29 -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:38 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:37 msgid "The maximum number of characters per line. This splits on the first space before the specified value. If no space is found the line will be broken at the space after and will exceed the specified value. Also, there is a minimum of 25 characters. Use 0 to disable line splitting." msgstr "" @@ -3023,24 +3023,28 @@ msgstr "" msgid "Do not insert a Table of Contents into the output text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:25 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:24 msgid "Type of newline to use. Options are %s. Default is 'system'. Use 'old_mac' for compatibility with Mac OS 9 and earlier. For Mac OS X use 'unix'. 'system' will default to the newline type used by this OS." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:45 +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:44 msgid "Force splitting on the max-line-length value when no space is present. Also allows max-line-length to be below the minimum" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:49 -msgid "Produce Markdown formatted text." +msgid "" +"Formatting used within the document.\n" +"* plain: Produce plain text.\n" +"* markdown: Produce Markdown formatted text.\n" +"* textile: Produce Textile formatted text." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:52 -msgid "Do not remove links within the document. This is only useful when paired with the markdown-format option because links are always removed with plain text output." +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:55 +msgid "Do not remove links within the document. This is only useful when paired with a txt-output-formatting option that is not none because links are always removed with plain text output." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:57 -msgid "Do not remove image references within the document. This is only useful when paired with the markdown-format option because image references are always removed with plain text output." +#: /home/kovid/work/calibre/src/calibre/ebooks/txt/output.py:60 +msgid "Do not remove image references within the document. This is only useful when paired with a txt-output-formatting option that is not none because links are always removed with plain text output." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:70 @@ -3119,44 +3123,44 @@ msgstr "" msgid "Default action to perform when send to device button is clicked" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:126 msgid "Maximum number of waiting worker processes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:126 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:128 msgid "Download social metadata (tags/rating/etc.)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:128 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:130 msgid "Overwrite author and title with new metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:132 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:101 msgid "Automatically download the cover, if available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:132 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:134 msgid "Limit max simultaneous jobs to number of CPUs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:136 msgid "tag browser categories not to display" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:136 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:138 msgid "The layout of the user interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:140 msgid "Show the average rating per item indication in the tag browser" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:140 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:142 msgid "Disable UI animations" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:410 msgid "Choose Files" msgstr "" @@ -3381,170 +3385,178 @@ msgstr "" msgid "Select destination for %s.%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:81 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar.py:54 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:167 #: /home/kovid/work/calibre/src/calibre/library/server/opds.py:126 msgid "%d books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:83 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:82 msgid "Choose calibre library to work with" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:92 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:91 msgid "Switch/create library..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:102 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:77 msgid "Quick switch" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:104 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:78 msgid "Rename library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:106 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:79 msgid "Delete library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:109 msgid "Pick a random book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:128 msgid "Library Maintenance" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:129 msgid "Library metadata backup status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:133 msgid "Start backing up metadata of all books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:138 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:137 msgid "Check library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:141 +msgid "Restore database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:216 msgid "Rename" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:212 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:217 msgid "Choose a new name for the library %s. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:218 msgid "Note that the actual library folder will be renamed." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:220 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:225 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:191 msgid "Already exists" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:226 msgid "The folder %s already exists. Delete it first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:232 msgid "Rename failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:233 msgid "Failed to rename the library at %s. The most common cause for this is if one of the files in the library is open in another program." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:238 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:243 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/confirm_delete_ui.py:53 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:78 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:360 #: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:424 #: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:430 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/columns.py:102 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:169 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:275 msgid "Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:239 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:244 msgid "All files from %s will be permanently deleted. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:258 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:263 msgid "none" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:264 msgid "Backup status" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:265 msgid "Book metadata files remaining to be written: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:271 msgid "Backup metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:272 msgid "Metadata will be backed up while calibre is running, at the rate of approximately 1 book every three seconds." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:289 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:180 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:240 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:304 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:106 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:340 msgid "Success" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:290 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:305 msgid "Found no errors in your calibre library database. Do you want calibre to check if the files in your library match the information in the database?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:310 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:150 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:674 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:876 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:672 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:877 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:101 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/bulk_download.py:190 msgid "Failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:311 msgid "Database integrity check failed, click Show details for details." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:301 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:316 msgid "No problems found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:302 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:317 msgid "The files in your library match the information in the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:311 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:326 msgid "No library found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:312 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:327 msgid "No existing calibre library was found at %s. It will be removed from the list of known libraries." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:365 -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:370 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:380 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:385 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:167 #: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:101 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:780 msgid "Not allowed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:366 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:381 msgid "You cannot change libraries while using the environment variable CALIBRE_OVERRIDE_DATABASE_PATH." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:371 +#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:386 msgid "You cannot change libraries while jobs are running." msgstr "" @@ -3565,7 +3577,7 @@ msgid "Bulk convert" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/actions/convert.py:86 -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:507 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:506 msgid "Cannot convert" msgstr "" @@ -4191,7 +4203,7 @@ msgid "The specified directory could not be processed." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add.py:250 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:823 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:821 msgid "No books" msgstr "" @@ -4442,7 +4454,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/rb_output.py:15 #: /home/kovid/work/calibre/src/calibre/gui2/convert/snb_output.py:15 #: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_input.py:13 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output.py:17 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output.py:16 msgid "Options specific to" msgstr "" @@ -4458,7 +4470,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/pml_output.py:15 #: /home/kovid/work/calibre/src/calibre/gui2/convert/rb_output.py:15 #: /home/kovid/work/calibre/src/calibre/gui2/convert/snb_output.py:15 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output.py:17 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output.py:16 msgid "output" msgstr "" @@ -4503,7 +4515,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:139 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc_ui.py:60 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard_ui.py:113 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template_ui.py:46 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/saving_ui.py:67 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:68 @@ -5698,11 +5710,13 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/regex_builder_ui.py:96 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:81 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:89 msgid "&Previous" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/regex_builder_ui.py:97 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:82 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:88 msgid "&Next" msgstr "" @@ -5917,7 +5931,7 @@ msgstr "" msgid "Do not insert Table of Contents into output text when using markdown" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output.py:16 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output.py:15 msgid "TXT Output" msgstr "" @@ -6046,8 +6060,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:576 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:599 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:650 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:302 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:303 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:308 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:501 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:502 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:114 @@ -6055,7 +6069,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:235 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:268 #: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:975 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:973 msgid "Undefined" msgstr "" @@ -6199,7 +6213,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/device.py:594 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/misc.py:41 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:204 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:304 #: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:54 msgid "Error" msgstr "" @@ -6209,84 +6223,92 @@ msgid "Error communicating with device" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/device.py:611 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1116 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1114 #: /home/kovid/work/calibre/src/calibre/gui2/email.py:297 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:629 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:627 msgid "Select folder to open as device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:680 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:678 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:681 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:679 msgid "There was a temporary error talking to the device. Please unplug and reconnect the device and or reboot." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:724 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:722 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:726 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:724 msgid " detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:824 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:822 msgid "selected to send" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:846 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:841 +msgid "%i of %i Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:843 +msgid "0 of %i Books" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:844 msgid "Choose format to send to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:854 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:852 msgid "No device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:855 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:853 msgid "Cannot send: No device is connected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:858 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:862 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:856 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:860 msgid "No card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:859 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:863 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:857 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:861 msgid "Cannot send: Device has no storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:909 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:992 -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1110 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:907 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:990 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1108 msgid "Auto convert the following books before uploading to the device?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:938 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:936 msgid "Sending catalogs to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1023 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1021 msgid "Sending news to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1077 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1075 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1117 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1115 msgid "Could not upload the following books to the device, as no suitable formats were found. Convert the book(s) to a format supported by your device first." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1181 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1179 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1182 +#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1180 msgid "

Cannot upload books to device there is no more free space available " msgstr "" @@ -6409,61 +6431,119 @@ msgstr "" msgid "Dumping database to SQL" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:81 msgid "Loading database from SQL" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:148 msgid "Check Library -- Problems Found" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:158 +msgid "" +"

Help

\n" +"\n" +"

calibre stores the list of your books and their metadata in a\n" +" database. The actual book files and covers are stored as normal\n" +" files in the calibre library folder. The database contains a list of the files\n" +" and covers belonging to each book entry. This tool checks that the\n" +" actual files in the library folder on your computer match the\n" +" information in the database.

\n" +"\n" +"

The result of each type of check is shown to the left. The various\n" +" checks are:\n" +"

\n" +"
    \n" +"
  • Invalid titles: These are files and folders appearing\n" +" in the library where books titles should, but that do not have the\n" +" correct form to be a book title.
  • \n" +"
  • Extra titles: These are extra files in your calibre\n" +" library that appear to be correctly-formed titles, but have no corresponding\n" +" entries in the database
  • \n" +"
  • Invalid authors: These are files appearing\n" +" in the library where only author folders should be.
  • \n" +"
  • Extra authors: These are folders in the\n" +" calibre library that appear to be authors but that do not have entries\n" +" in the database
  • \n" +"
  • Missing book formats: These are book formats that are in\n" +" the database but have no corresponding format file in the book's folder.\n" +"
  • Extra book formats: These are book format files found in\n" +" the book's folder but not in the database.\n" +"
  • Unknown files in books: These are extra files in the\n" +" folder of each book that do not correspond to a known format or cover\n" +" file.
  • \n" +"
  • Missing cover files: These represent books that are marked\n" +" in the database as having covers but the actual cover files are\n" +" missing.
  • \n" +"
  • Cover files not in database: These are books that have\n" +" cover files but are marked as not having covers in the database.
  • \n" +"
  • Folder raising exception: These represent folders in the\n" +" calibre library that could not be processed/understood by this\n" +" tool.
  • \n" +"
\n" +"\n" +"

There are two kinds of automatic fixes possible: Delete\n" +" marked and Fix marked.

\n" +"

Delete marked is used to remove extra files/folders/covers that\n" +" have no entries in the database. Check the box next to the item you want\n" +" to delete. Use with caution.

\n" +"

Fix marked is applicable only to covers (the two lines marked\n" +" 'fixable'). In the case of missing cover files, checking the fixable\n" +" box and pushing this button will remove the cover mark from the\n" +" database for all the files in that category. In the case of extra\n" +" cover files, checking the fixable box and pushing this button will\n" +" add the cover mark to the database for all the files in that\n" +" category.

\n" +" " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:218 msgid "&Run the check again" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:154 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:221 msgid "Copy &to clipboard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:161 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:228 msgid "Delete marked files (checked subitems)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:167 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:234 msgid "Fix marked sections (checked fixable items)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:177 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:244 msgid "Names to ignore:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:182 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:249 msgid "Enter comma-separated standard file name wildcards, such as synctoy*.dat" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:185 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:252 msgid "Extensions to ignore" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:190 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:257 msgid "Enter comma-separated extensions without a leading dot. Used only in book folders" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:239 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:306 msgid "(fixable)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:329 msgid "Path from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:329 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:89 #: /home/kovid/work/calibre/src/calibre/library/server/browse.py:253 msgid "Name" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:287 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/check_library.py:354 msgid "The marked files and folders will be permanently deleted. Are you sure?" msgstr "" @@ -6816,159 +6896,159 @@ msgstr "" msgid "&Copy to clipboard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:49 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:48 msgid "Show &details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:50 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:49 msgid "Hide &details" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:54 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:53 msgid "Show detailed information about this error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:92 #: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:525 msgid "Copied" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:57 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:58 msgid "Title/Author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:58 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:59 msgid "Standard metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:60 msgid "Custom metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:61 msgid "Search/Replace" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:64 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:65 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/progress.py:76 msgid "Working" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:257 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:384 msgid "Lower Case" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:258 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:383 msgid "Upper Case" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:258 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:259 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:386 msgid "Title Case" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:260 #: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:387 msgid "Capitalize" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:263 msgid "Character match" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:264 msgid "Regular Expression" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:267 msgid "Replace field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:268 msgid "Prepend to field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:269 msgid "Append to field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:278 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:279 msgid "Editing meta information for %d books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:319 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:320 msgid "Immediately make all changes without closing the dialog. This operation cannot be canceled or undone" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:377 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:378 msgid "Book %d:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:392 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:393 msgid "You can destroy your library using this feature. Changes are permanent. There is no undo function. You are strongly encouraged to back up your library before proceeding.

Search and replace in text fields using character matching or regular expressions. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:400 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:401 msgid "In character mode, the field is searched for the entered search text. The text is replaced by the specified replacement text everywhere it is found in the specified field. After replacement is finished, the text can be changed to upper-case, lower-case, or title-case. If the case-sensitive check box is checked, the search text must match exactly. If it is unchecked, the search text will match both upper- and lower-case letters" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:411 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:412 msgid "In regular expression mode, the search text is an arbitrary python-compatible regular expression. The replacement text can contain backreferences to parenthesized expressions in the pattern. The search is not anchored, and can match and replace multiple times on the same string. The modification functions (lower-case etc) are applied to the matched text, not to the field as a whole. The destination box specifies the field where the result after matching and replacement is to be assigned. You can replace the text in the field, or prepend or append the matched text. See this reference for more information on python's regular expressions, and in particular the 'sub' function." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:475 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:476 msgid "S/R TEMPLATE ERROR" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:595 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:596 msgid "You must specify a destination when source is a composite field" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:698 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:706 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:810 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:699 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:707 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:811 msgid "Search/replace invalid" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:699 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:700 msgid "Authors cannot be set to the empty string. Book title %s not processed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:707 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:708 msgid "Title cannot be set to the empty string. Book title %s not processed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:811 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:812 msgid "Search pattern is invalid: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:862 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:863 msgid "" "Applying changes to %d books.\n" "Phase {0} {1}%%." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:891 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:892 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:555 msgid "Delete saved search/replace" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:892 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:893 msgid "The selected saved search/replace will be deleted. Are you sure?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:912 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:920 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:910 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:918 msgid "Save search/replace" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:913 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:911 msgid "Search/replace name:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:921 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk.py:919 msgid "That saved search/replace already exists and will be overwritten. Are you sure?" msgstr "" @@ -7076,7 +7156,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:528 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:440 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:959 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:957 msgid "&Date:" msgstr "" @@ -7448,12 +7528,12 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:682 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:687 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:899 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:897 msgid "This ISBN number is valid" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:690 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:906 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:904 msgid "This ISBN number is invalid" msgstr "" @@ -7464,39 +7544,39 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:771 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:849 -msgid "You have changed the tags. In order to use the tags editor, you must either discard or apply these changes" +msgid "You have changed the tags. In order to use the tags editor, you must either discard or apply these changes. Apply changes?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:807 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:805 msgid "Timed out" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:808 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:806 msgid "The download of social metadata timed out, the servers are probably busy. Try again later." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:815 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:813 msgid "There were errors" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:816 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:814 msgid "There were errors downloading social metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:850 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:848 msgid "Cannot fetch metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:851 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:849 msgid "You must specify at least one of ISBN, Title, Authors or Publisher" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:946 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:944 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:302 msgid "Permission denied" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:947 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:945 #: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:303 msgid "Could not open %s. Is it being used by another program?" msgstr "" @@ -7554,7 +7634,7 @@ msgid "Remove unused series (Series that have no books)" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:439 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:872 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:870 msgid "IS&BN:" msgstr "" @@ -7563,7 +7643,7 @@ msgid "dd MMM yyyy" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:442 -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1010 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:1008 msgid "Publishe&d:" msgstr "" @@ -7664,6 +7744,30 @@ msgstr "" msgid "Aborting..." msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:23 +msgid "Restoring database from backups, do not interrupt, this will happen in three stages" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:25 +msgid "Restoring database" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:79 +msgid "Your list of books, with all their metadata is stored in a single file, called a database. In addition, metadata for each individual book is stored in that books' folder, as a backup.

This operation will rebuild the database from the individual book metadata. This is useful if the database has been corrupted and you get a blank list of books. Note that restoring only restores books, not any settings stored in the database, or any custom recipes.

Do you want to restore the database?" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:102 +msgid "Restoring database failed, click Show details to see details" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:107 +msgid "Restoring the database succeeded with some warnings click Show details to see the details." +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/restore_library.py:112 +msgid "Restoring database was successful" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/saved_search_editor.py:55 msgid "The current saved search will be permanently deleted. Are you sure?" msgstr "" @@ -8402,7 +8506,7 @@ msgid "Attached, you will find the e-book" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/email.py:247 -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:186 msgid "by" msgstr "" @@ -8964,35 +9068,35 @@ msgstr "" msgid "If you are sure it is not running" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:322 -msgid "Cannot Start " -msgstr "" - #: /home/kovid/work/calibre/src/calibre/gui2/main.py:323 -msgid "%s is already running." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:326 msgid "may be running in the system tray, in the" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:328 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:325 msgid "upper right region of the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:330 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:327 msgid "lower right region of the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:333 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:330 msgid "try rebooting your computer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:335 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:347 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:346 msgid "try deleting the file" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:335 +msgid "Cannot Start " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:336 +msgid "%s is already running." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/main_window.py:20 msgid "Redirect console output to a dialog window (both stdout and stderr). Useful on windows where GUI apps do not have a output streams." msgstr "" @@ -9041,11 +9145,11 @@ msgstr "" msgid "Tags categorize the book. This is particularly useful while searching.

They can be any wordsor phrases, separated by commas." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:913 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:911 msgid "&Publisher:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:978 +#: /home/kovid/work/calibre/src/calibre/gui2/metadata/basic_widgets.py:976 msgid "Clear date" msgstr "" @@ -9823,97 +9927,109 @@ msgstr "" msgid "Delete plugboard" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:110 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:179 msgid "%(plugin_type)s %(plugins)s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:111 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:180 msgid "plugins" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:120 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:189 msgid "" "\n" "Customization: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:162 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:218 +msgid "Search for plugin" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:226 +msgid "No matches" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:227 +msgid "Could not find any matching plugins" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:268 msgid "Add plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:276 msgid "Installing plugins is a security risk. Plugins can contain a virus/malware. Only install it if you got it from a trusted source. Are you sure you want to proceed?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:181 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:287 msgid "Plugin {0} successfully installed under {1} plugins. You may have to restart calibre for the plugin to take effect." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:195 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:295 msgid "No valid plugin path" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:196 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:296 msgid "%s is not a valid plugin path" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:205 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:305 msgid "Select an actual plugin under %s to customize" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:311 msgid "Plugin cannot be disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:212 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:312 msgid "The plugin: %s cannot be disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:322 msgid "Plugin not customizable" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:323 msgid "Plugin: %s does not need customization" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:329 msgid "Must restart" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:330 msgid "You must restart calibre before you can configure the %s plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:335 msgid "Plugin {0} successfully removed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:243 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:343 msgid "Cannot remove builtin plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:244 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins.py:344 msgid " cannot be removed. It is a builtin plugin. Try disabling it instead." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:59 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:87 msgid "Here you can customize the behavior of Calibre by controlling what plugins it uses." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:60 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:90 msgid "Enable/&Disable plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:61 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:91 msgid "&Customize plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:62 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:92 msgid "&Remove plugin" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:63 +#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:93 msgid "&Add a new plugin" msgstr "" @@ -10016,7 +10132,7 @@ msgid "Here you can control how calibre will save your books when you click the msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:75 -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:382 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:381 msgid "Failed to start content server" msgstr "" @@ -10598,62 +10714,62 @@ msgstr "" msgid "The following books have already been converted to %s format. Do you wish to reconvert them?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:194 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:192 msgid "&Restore" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:196 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:194 msgid "&Donate to support calibre" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:200 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:198 msgid "&Eject connected device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:245 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:243 msgid "Calibre Quick Start Guide" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:305 msgid "Debug mode" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:308 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:306 msgid "You have started calibre in debug mode. After you quit calibre, the debug log will be available in the file: %s

The log will be displayed automatically." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:495 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:494 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:518 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:517 msgid "Recipe Disabled" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:534 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:533 msgid "Failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:571 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:570 msgid "is the result of the efforts of many volunteers from all over the world. If you find it useful, please consider donating to support its development. Your donation helps keep calibre development going." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:597 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:596 msgid "There are active jobs. Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:600 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:599 msgid "" " is communicating with the device!
\n" " Quitting may cause corruption on the device.
\n" " Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:604 -msgid "WARNING: Active jobs" +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:603 +msgid "Active jobs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:674 +#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:669 msgid "will keep running in the system tray. To close it, choose Quit in the context menu of the system tray." msgstr "" @@ -11766,11 +11882,11 @@ msgid "Unknown files in books" msgstr "" #: /home/kovid/work/calibre/src/calibre/library/check_library.py:33 -msgid "Missing covers in books" +msgid "Missing covers files" msgstr "" #: /home/kovid/work/calibre/src/calibre/library/check_library.py:34 -msgid "Extra covers in books" +msgid "Cover files not in database" msgstr "" #: /home/kovid/work/calibre/src/calibre/library/check_library.py:35 @@ -12246,15 +12362,15 @@ msgstr "" msgid "Main" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2629 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2631 msgid "

Migrating old database to ebook library in %s

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2658 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2660 msgid "Copying %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/database2.py:2675 +#: /home/kovid/work/calibre/src/calibre/library/database2.py:2677 msgid "Compacting database" msgstr "" @@ -12933,18 +13049,58 @@ msgid "Spanish (Paraguay)" msgstr "" #: /home/kovid/work/calibre/src/calibre/utils/localization.py:115 -msgid "German (AT)" +msgid "Spanish (Uruguay)" msgstr "" #: /home/kovid/work/calibre/src/calibre/utils/localization.py:116 -msgid "French (BE)" +msgid "Spanish (Argentina)" msgstr "" #: /home/kovid/work/calibre/src/calibre/utils/localization.py:117 -msgid "Dutch (NL)" +msgid "Spanish (Mexico)" msgstr "" #: /home/kovid/work/calibre/src/calibre/utils/localization.py:118 +msgid "Spanish (Cuba)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:119 +msgid "Spanish (Chile)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:120 +msgid "Spanish (Ecuador)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:121 +msgid "Spanish (Honduras)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:122 +msgid "Spanish (Venezuela)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:123 +msgid "Spanish (Bolivia)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:124 +msgid "Spanish (Nicaragua)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:125 +msgid "German (AT)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:126 +msgid "French (BE)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:127 +msgid "Dutch (NL)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/utils/localization.py:128 msgid "Dutch (BE)" msgstr "" diff --git a/src/calibre/utils/localization.py b/src/calibre/utils/localization.py index b9995db2bf..037a147e28 100644 --- a/src/calibre/utils/localization.py +++ b/src/calibre/utils/localization.py @@ -112,6 +112,16 @@ _extra_lang_codes = { 'en_IE' : _('English (Ireland)'), 'en_CN' : _('English (China)'), 'es_PY' : _('Spanish (Paraguay)'), + 'es_UY' : _('Spanish (Uruguay)'), + 'es_AR' : _('Spanish (Argentina)'), + 'es_MX' : _('Spanish (Mexico)'), + 'es_CU' : _('Spanish (Cuba)'), + 'es_CL' : _('Spanish (Chile)'), + 'es_EC' : _('Spanish (Ecuador)'), + 'es_HN' : _('Spanish (Honduras)'), + 'es_VE' : _('Spanish (Venezuela)'), + 'es_BO' : _('Spanish (Bolivia)'), + 'es_NI' : _('Spanish (Nicaragua)'), 'de_AT' : _('German (AT)'), 'fr_BE' : _('French (BE)'), 'nl' : _('Dutch (NL)'),