diff --git a/resources/images/swap.png b/resources/images/swap.png index 60b8803d95..e5aeb60e22 100644 Binary files a/resources/images/swap.png and b/resources/images/swap.png differ diff --git a/resources/recipes/el_pais.recipe b/resources/recipes/el_pais.recipe index c953a4dd95..1e2164b2af 100644 --- a/resources/recipes/el_pais.recipe +++ b/resources/recipes/el_pais.recipe @@ -1,8 +1,8 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__author__ = 'Lorenzo Vigentini, based on earlier version by Kovid Goyal' +__author__ = 'Jordi Balcells, based on an earlier version by Lorenzo Vigentini & Kovid Goyal' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' -description = 'Main daily newspaper from Spain - v1.02 (10, January 2010)' +description = 'Main daily newspaper from Spain - v1.03 (03, September 2010)' __docformat__ = 'restructuredtext en' ''' @@ -12,12 +12,12 @@ elpais.es from calibre.web.feeds.news import BasicNewsRecipe class ElPais(BasicNewsRecipe): - __author__ = 'Kovid Goyal & Lorenzo Vigentini' + __author__ = 'Kovid Goyal & Lorenzo Vigentini & Jordi Balcells' description = 'Main daily newspaper from Spain' cover_url = 'http://www.elpais.com/im/tit_logo_global.gif' title = u'El Pais' - publisher = 'Ediciones El Pais SL' + publisher = u'Ediciones El Pa\xeds SL' category = 'News, politics, culture, economy, general interest' language = 'es' @@ -32,7 +32,8 @@ class ElPais(BasicNewsRecipe): remove_javascript = True no_stylesheets = True - keep_only_tags = [ dict(name='div', attrs={'class':['cabecera_noticia','cabecera_noticia_reportaje','contenido_noticia','caja_despiece','presentacion']})] + keep_only_tags = [ dict(name='div', attrs={'class':['cabecera_noticia','cabecera_noticia_reportaje','cabecera_noticia_opinion','contenido_noticia','caja_despiece','presentacion']})] + extra_css = ''' p{style:normal size:12 serif} @@ -40,25 +41,29 @@ class ElPais(BasicNewsRecipe): remove_tags = [ dict(name='div', attrs={'class':['zona_superior','pie_enlaces_inferiores','contorno_f','ampliar']}), - dict(name='div', attrs={'class':['limpiar','mod_apoyo','borde_sup','votos','info_complementa','info_relacionada']}), - dict(name='div', attrs={'id':['suscribirse suscrito','google_noticia','utilidades','coment','foros_not','pie','lomas']}) + dict(name='div', attrs={'class':['limpiar','mod_apoyo','borde_sup','votos','info_complementa','info_relacionada','buscador_m','nav_ant_sig']}), + dict(name='div', attrs={'id':['suscribirse suscrito','google_noticia','utilidades','coment','foros_not','pie','lomas','calendar']}), + dict(name='p', attrs={'class':'nav_meses'}), + dict(attrs={'class':['enlaces_m','miniaturas_m']}) ] feeds = [ (u'Titulares de portada', u'http://www.elpais.com/rss/feed.html?feedId=1022'), (u'Internacional', u'http://www.elpais.com/rss/feed.html?feedId=1001'), - (u'Espana', u'http://www.elpais.com/rss/feed.html?feedId=1002'), + (u'Espa\xf1a', u'http://www.elpais.com/rss/feed.html?feedId=1002'), (u'Deportes', u'http://www.elpais.com/rss/feed.html?feedId=1007'), - (u'Economia', u'http://www.elpais.com/rss/feed.html?feedId=1006'), - (u'Politica', u'http://www.elpais.com/rss/feed.html?feedId=17073'), - (u'Tecnologia', u'http://www.elpais.com/rss/feed.html?feedId=1005'), + (u'Econom\xeda', u'http://www.elpais.com/rss/feed.html?feedId=1006'), + (u'Pol\xedtica', u'http://www.elpais.com/rss/feed.html?feedId=17073'), + (u'Tecnolog\xeda', u'http://www.elpais.com/rss/feed.html?feedId=1005'), (u'Cultura', u'http://www.elpais.com/rss/feed.html?feedId=1008'), (u'Gente', u'http://www.elpais.com/rss/feed.html?feedId=1009'), (u'Sociedad', u'http://www.elpais.com/rss/feed.html?feedId=1004'), - (u'Opinion', u'http://www.elpais.com/rss/feed.html?feedId=1003'), + (u'Opini\xf3n', u'http://www.elpais.com/rss/feed.html?feedId=1003'), (u'Ciencia', u'http://www.elpais.com/rss/feed.html?feedId=17068'), (u'Justicia y leyes', u'http://www.elpais.com/rss/feed.html?feedId=17069'), - ] + (u'Medio ambiente', u'http://www.elpais.com/rss/feed.html?feedId=17071'), + (u'Vi\xf1etas', u'http://www.elpais.com/rss/feed.html?feedId=17058') + ] def print_version(self, url): url = url+'?print=1' diff --git a/src/calibre/devices/apple/driver.py b/src/calibre/devices/apple/driver.py index c6abe595b6..e318d368ff 100644 --- a/src/calibre/devices/apple/driver.py +++ b/src/calibre/devices/apple/driver.py @@ -2488,7 +2488,8 @@ class ITUNES(DriverBase): zf_opf.close() # If 'News' in tags, tweak the title/author for friendlier display in iBooks - if _('News') or _('Catalog') in metadata.tags: + if _('News') in metadata.tags or \ + _('Catalog') in metadata.tags: if metadata.title.find('[') > 0: metadata.title = metadata.title[:metadata.title.find('[')-1] date_as_author = '%s, %s %s, %s' % (strftime('%A'), strftime('%B'), strftime('%d').lstrip('0'), strftime('%Y')) diff --git a/src/calibre/ebooks/__init__.py b/src/calibre/ebooks/__init__.py index 6596e9b1a2..624b277e61 100644 --- a/src/calibre/ebooks/__init__.py +++ b/src/calibre/ebooks/__init__.py @@ -138,3 +138,11 @@ def check_ebook_format(stream, current_guess): stream.seek(0) return ans +def calibre_cover(title, author_string, series_string=None, + output_format='jpg', title_size=46, author_size=36): + from calibre.utils.magick.draw import create_cover_page, TextLine + lines = [TextLine(title, title_size), TextLine(author_string, author_size)] + if series_string: + lines.append(TextLine(series_string, author_size)) + return create_cover_page(lines, I('library.png'), output_format='jpg') + diff --git a/src/calibre/ebooks/metadata/archive.py b/src/calibre/ebooks/metadata/archive.py index 624c2ad5e5..f5982406ea 100644 --- a/src/calibre/ebooks/metadata/archive.py +++ b/src/calibre/ebooks/metadata/archive.py @@ -70,7 +70,7 @@ class ArchiveExtract(FileTypePlugin): fname = fnames[0] ext = os.path.splitext(fname)[1][1:] if ext.lower() not in ('lit', 'epub', 'mobi', 'prc', 'rtf', 'pdf', - 'mp3', 'pdb', 'azw', 'azw1'): + 'mp3', 'pdb', 'azw', 'azw1', 'fb2'): return archive of = self.temporary_file('_archive_extract.'+ext) diff --git a/src/calibre/ebooks/oeb/transforms/cover.py b/src/calibre/ebooks/oeb/transforms/cover.py index 83b7b5d3c1..59b42df68a 100644 --- a/src/calibre/ebooks/oeb/transforms/cover.py +++ b/src/calibre/ebooks/oeb/transforms/cover.py @@ -89,19 +89,22 @@ class CoverManager(object): ''' Create a generic cover for books that dont have a cover ''' - from calibre.ebooks.metadata import authors_to_string + from calibre.ebooks.metadata import authors_to_string, fmt_sidx if self.no_default_cover: return None self.log('Generating default cover') m = self.oeb.metadata title = unicode(m.title[0]) authors = [unicode(x) for x in m.creator if x.role == 'aut'] + series_string = None + if m.series and m.series_index: + series_string = _('Book %s of %s')%( + fmt_sidx(m.series_index[0], use_roman=True), m.series[0]) try: - from calibre.utils.magick.draw import create_cover_page, TextLine - lines = [TextLine(title, 44), TextLine(authors_to_string(authors), - 32)] - img_data = create_cover_page(lines, I('library.png')) + from calibre.ebooks import calibre_cover + img_data = calibre_cover(title, authors_to_string(authors), + series_string=series_string) id, href = self.oeb.manifest.generate('cover_image', 'cover_image.jpg') item = self.oeb.manifest.add(id, href, guess_type('t.jpg')[0], diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 1393a50738..3d79b01c14 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -144,15 +144,23 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.cover_data = cover def generate_cover(self, *args): - from calibre.utils.magick.draw import create_cover_page, TextLine + from calibre.ebooks import calibre_cover + from calibre.ebooks.metadata import fmt_sidx + from calibre.gui2 import config title = unicode(self.title.text()).strip() author = unicode(self.authors.text()).strip() if not title or not author: return error_dialog(self, _('Specify title and author'), _('You must specify a title and author before generating ' 'a cover'), show=True) - lines = [TextLine(title, 44), TextLine(author, 32)] - self.cover_data = create_cover_page(lines, I('library.png')) + series = unicode(self.series.text()).strip() + series_string = None + if series: + series_string = _('Book %s of %s')%( + fmt_sidx(self.series_index.value(), + use_roman=config['use_roman_numerals_for_series_number']), series) + self.cover_data = calibre_cover(title, author, + series_string=series_string) pix = QPixmap() pix.loadFromData(self.cover_data) self.cover.setPixmap(pix) diff --git a/src/calibre/gui2/layout.py b/src/calibre/gui2/layout.py index 68f093da95..58d5267c8e 100644 --- a/src/calibre/gui2/layout.py +++ b/src/calibre/gui2/layout.py @@ -215,6 +215,7 @@ class ToolBar(QToolBar): # {{{ self.location_manager.locations_changed.connect(self.build_bar) donate.setAutoRaise(True) donate.setCursor(Qt.PointingHandCursor) + self.added_actions = [] self.build_bar() self.preferred_width = self.sizeHint().width() @@ -237,7 +238,13 @@ class ToolBar(QToolBar): # {{{ actions = '-device' if showing_device else '' actions = gprefs['action-layout-toolbar'+actions] + for ac in self.added_actions: + m = ac.menu() + if m is not None: + m.setVisible(False) + self.clear() + self.added_actions = [] for what in actions: if what is None: @@ -245,6 +252,7 @@ class ToolBar(QToolBar): # {{{ elif what == 'Location Manager': for ac in self.location_manager.available_actions: self.addAction(ac) + self.added_actions.append(ac) self.setup_tool_button(ac, QToolButton.MenuButtonPopup) elif what == 'Donate': self.d_widget = QWidget() @@ -255,6 +263,7 @@ class ToolBar(QToolBar): # {{{ elif what in self.gui.iactions: action = self.gui.iactions[what] self.addAction(action.qaction) + self.added_actions.append(action.qaction) self.setup_tool_button(action.qaction, action.popup_type) def setup_tool_button(self, ac, menu_mode=None): diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index c8f1f62856..79f4c29998 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -173,6 +173,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.pending_anchor = None self.pending_reference = None self.pending_bookmark = None + self.existing_bookmarks= [] self.selected_text = None self.read_settings() self.dictionary_box.hide() @@ -415,15 +416,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.action_font_size_smaller.setEnabled(self.view.multiplier() > 0.2) self.set_page_number(frac) - def bookmark(self, *args): - title, ok = QInputDialog.getText(self, _('Add bookmark'), _('Enter title for bookmark:')) - title = unicode(title).strip() - if ok and title: - pos = self.view.bookmark() - bookmark = '%d#%s'%(self.current_index, pos) - self.iterator.add_bookmark((title, bookmark)) - self.set_bookmarks(self.iterator.bookmarks) - def find(self, text, repeat=False, backwards=False): if not text: @@ -539,15 +531,34 @@ class EbookViewer(MainWindow, Ui_EbookViewer): getattr(self, o).setEnabled(False) self.setCursor(Qt.BusyCursor) + def bookmark(self, *args): + num = 1 + bm = None + while True: + bm = _('Bookmark #%d')%num + if bm not in self.existing_bookmarks: + break + num += 1 + title, ok = QInputDialog.getText(self, _('Add bookmark'), + _('Enter title for bookmark:'), text=bm) + title = unicode(title).strip() + if ok and title: + pos = self.view.bookmark() + bookmark = '%d#%s'%(self.current_index, pos) + self.iterator.add_bookmark((title, bookmark)) + self.set_bookmarks(self.iterator.bookmarks) + def set_bookmarks(self, bookmarks): self.bookmarks_menu.clear() self.bookmarks_menu.addAction(_("Manage Bookmarks"), self.manage_bookmarks) self.bookmarks_menu.addSeparator() current_page = None + self.existing_bookmarks = [] for bm in bookmarks: if bm[0] == 'calibre_current_page_bookmark': current_page = bm else: + self.existing_bookmarks.append(bm[0]) self.bookmarks_menu.addAction(bm[0], partial(self.goto_bookmark, bm)) return current_page diff --git a/src/calibre/utils/magick/draw.py b/src/calibre/utils/magick/draw.py index 17bf1c273a..82a0237b8d 100644 --- a/src/calibre/utils/magick/draw.py +++ b/src/calibre/utils/magick/draw.py @@ -165,12 +165,17 @@ def create_cover_page(top_lines, logo_path, width=590, height=750, top = height - lheight - 10 canvas.compose(vanity, left, top) - logo = Image() - logo.open(logo_path) - lwidth, lheight = logo.size - left = int(max(0, (width - lwidth)/2.)) - top = max(int((height - lheight)/2.), bottom+20) - canvas.compose(logo, left, top) + available = (width, int(top - bottom)-20) + if available[1] > 40: + logo = Image() + logo.open(logo_path) + lwidth, lheight = logo.size + scaled, lwidth, lheight = fit_image(lwidth, lheight, *available) + if scaled: + logo.size = (lwidth, lheight) + left = int(max(0, (width - lwidth)/2.)) + top = bottom+10 + canvas.compose(logo, left, top) return canvas.export(output_format) diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 6df73487ed..9ba9583c73 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -1018,12 +1018,11 @@ class BasicNewsRecipe(Recipe): Create a generic cover for recipes that dont have a cover ''' try: - from calibre.utils.magick.draw import create_cover_page, TextLine + from calibre.ebooks import calibre_cover title = self.title if isinstance(self.title, unicode) else \ self.title.decode(preferred_encoding, 'replace') date = strftime(self.timefmt) - lines = [TextLine(title, 44), TextLine(date, 32)] - img_data = create_cover_page(lines, I('library.png'), output_format='jpg') + img_data = calibre_cover(title, date) cover_file.write(img_data) cover_file.flush() except: