From c1bb1ab5c6446622367afbfa04e2aaea5a7cc9e3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 20 Mar 2012 09:57:59 +0530 Subject: [PATCH 1/6] E-book viewer: When in full screen mode, using the close window keyboard shortcut drops out of full screen instead of closing the window --- src/calibre/gui2/viewer/main.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 64521ecdd7..a83c5d12c0 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -5,11 +5,11 @@ import traceback, os, sys, functools, collections, re from functools import partial from threading import Thread -from PyQt4.Qt import QApplication, Qt, QIcon, QTimer, SIGNAL, QByteArray, \ - QDoubleSpinBox, QLabel, QTextBrowser, \ - QPainter, QBrush, QColor, QStandardItemModel, QPalette, \ - QStandardItem, QUrl, QRegExpValidator, QRegExp, QLineEdit, \ - QToolButton, QMenu, QInputDialog, QAction, QKeySequence +from PyQt4.Qt import (QApplication, Qt, QIcon, QTimer, SIGNAL, QByteArray, + QDoubleSpinBox, QLabel, QTextBrowser, + QPainter, QBrush, QColor, QStandardItemModel, QPalette, + QStandardItem, QUrl, QRegExpValidator, QRegExp, QLineEdit, + QToolButton, QMenu, QInputDialog, QAction, QKeySequence) from calibre.gui2.viewer.main_ui import Ui_EbookViewer from calibre.gui2.viewer.printing import Printing @@ -338,6 +338,10 @@ class EbookViewer(MainWindow, Ui_EbookViewer): count += 1 def closeEvent(self, e): + if self.isFullScreen(): + self.showNormal() + e.ignore() + return self.save_state() return MainWindow.closeEvent(self, e) From 7658a536ccff140c22e66e7b432b26e8bc166271 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 20 Mar 2012 18:34:24 +0530 Subject: [PATCH 2/6] E-book viewer: A whole new full screen mode, with no toolbars to distract from the text and the ability to set the width of the column of tet via Preferences in the ebook viewer. Fixes #959830 (Feature request for ebook viewer app) --- src/calibre/gui2/viewer/config.ui | 11 ++- src/calibre/gui2/viewer/documentview.py | 48 +++++++++-- src/calibre/gui2/viewer/main.py | 101 +++++++++++++++++++++--- src/calibre/gui2/viewer/main.ui | 3 + 4 files changed, 139 insertions(+), 24 deletions(-) diff --git a/src/calibre/gui2/viewer/config.ui b/src/calibre/gui2/viewer/config.ui index 3158241f28..f876b87fc3 100644 --- a/src/calibre/gui2/viewer/config.ui +++ b/src/calibre/gui2/viewer/config.ui @@ -255,7 +255,10 @@ - + + + Set the maximum width that the book's text and pictures will take when in fullscreen mode. This allows you to read the book text without it becoming too wide. + px @@ -270,10 +273,10 @@ - Maximum &view width: + Maximum text width in &fullscreen: - max_view_width + max_fs_width @@ -350,7 +353,7 @@ serif_family sans_family mono_family - max_view_width + max_fs_width opt_remember_window_size buttonBox diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 2f520c1912..7999458004 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -12,7 +12,7 @@ from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, QPainter, QPalette, QBrush, QFontDatabase, QDialog, QColor, QPoint, QImage, QRegion, QVariant, QIcon, QFont, pyqtSignature, QAction, QByteArray, QMenu, - pyqtSignal, QSwipeGesture) + pyqtSignal, QSwipeGesture, QApplication) from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings from calibre.utils.config import Config, StringConfig @@ -46,8 +46,10 @@ def config(defaults=None): help=_('Remember last used window size')) c.add_opt('user_css', default='', help=_('Set the user CSS stylesheet. This can be used to customize the look of all books.')) - c.add_opt('max_view_width', default=6000, - help=_('Maximum width of the viewer window, in pixels.')) + c.add_opt('max_fs_width', default=800, + help=_("Set the maximum width that the book's text and pictures will take" + " when in fullscreen mode. This allows you to read the book text" + " without it becoming too wide.")) c.add_opt('fit_images', default=True, help=_('Resize images larger than the viewer window to fit inside it')) c.add_opt('hyphenate', default=False, help=_('Hyphenate text')) @@ -101,7 +103,7 @@ class ConfigDialog(QDialog, Ui_Dialog): self.standard_font.setCurrentIndex({'serif':0, 'sans':1, 'mono':2}[opts.standard_font]) self.css.setPlainText(opts.user_css) self.css.setToolTip(_('Set the user CSS stylesheet. This can be used to customize the look of all books.')) - self.max_view_width.setValue(opts.max_view_width) + self.max_fs_width.setValue(opts.max_fs_width) with zipfile.ZipFile(P('viewer/hyphenate/patterns.zip', allow_user_override=False), 'r') as zf: pats = [x.split('.')[0].replace('-', '_') for x in zf.namelist()] @@ -144,7 +146,7 @@ class ConfigDialog(QDialog, Ui_Dialog): c.set('user_css', unicode(self.css.toPlainText())) c.set('remember_window_size', self.opt_remember_window_size.isChecked()) c.set('fit_images', self.opt_fit_images.isChecked()) - c.set('max_view_width', int(self.max_view_width.value())) + c.set('max_fs_width', int(self.max_fs_width.value())) c.set('hyphenate', self.hyphenate.isChecked()) c.set('remember_current_page', self.opt_remember_current_page.isChecked()) c.set('wheel_flips_pages', self.opt_wheel_flips_pages.isChecked()) @@ -192,6 +194,8 @@ class Document(QWebPage): # {{{ self.loaded_javascript = False self.js_loader = JavaScriptLoader( dynamic_coffeescript=self.debug_javascript) + self.initial_left_margin = self.initial_right_margin = u'' + self.in_fullscreen_mode = False self.setLinkDelegationPolicy(self.DelegateAllLinks) self.scroll_marks = [] @@ -239,6 +243,9 @@ class Document(QWebPage): # {{{ self.enable_page_flip = self.page_flip_duration > 0.1 self.font_magnification_step = opts.font_magnification_step self.wheel_flips_pages = opts.wheel_flips_pages + screen_width = QApplication.desktop().screenGeometry().width() + # Leave some space for the scrollbar and some border + self.max_fs_width = min(opts.max_fs_width, screen_width-50) def fit_images(self): if self.do_fit_images: @@ -274,6 +281,30 @@ class Document(QWebPage): # {{{ self.set_bottom_padding(0) self.fit_images() self.init_hyphenate() + self.initial_left_margin = unicode(self.javascript( + 'document.body.style.marginLeft').toString()) + self.initial_right_margin = unicode(self.javascript( + 'document.body.style.marginRight').toString()) + if self.in_fullscreen_mode: + self.switch_to_fullscreen_mode() + + def switch_to_fullscreen_mode(self): + self.in_fullscreen_mode = True + self.javascript(''' + var s = document.body.style; + s.maxWidth = "%dpx"; + s.marginLeft = "auto"; + s.marginRight = "auto"; + '''%self.max_fs_width) + + def switch_to_window_mode(self): + self.in_fullscreen_mode = False + self.javascript(''' + var s = document.body.style; + s.maxWidth = "none"; + s.marginLeft = "%s"; + s.marginRight = "%s"; + '''%(self.initial_left_margin, self.initial_right_margin)) @pyqtSignature("QString") def debug(self, msg): @@ -581,8 +612,8 @@ class DocumentView(QWebView): # {{{ def config(self, parent=None): self.document.do_config(parent) - if self.manager is not None: - self.manager.set_max_width() + if self.document.in_fullscreen_mode: + self.document.switch_to_fullscreen_mode() self.setFocus(Qt.OtherFocusReason) def bookmark(self): @@ -602,6 +633,9 @@ class DocumentView(QWebView): # {{{ menu.insertAction(list(menu.actions())[0], self.search_action) menu.addSeparator() menu.addAction(self.goto_location_action) + if self.document.in_fullscreen_mode and self.manager is not None: + menu.addSeparator() + menu.addAction(self.manager.toggle_toolbar_action) menu.exec_(ev.globalPos()) def lookup(self, *args): diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index a83c5d12c0..c1cb89aeb6 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -6,10 +6,10 @@ from functools import partial from threading import Thread from PyQt4.Qt import (QApplication, Qt, QIcon, QTimer, SIGNAL, QByteArray, - QDoubleSpinBox, QLabel, QTextBrowser, - QPainter, QBrush, QColor, QStandardItemModel, QPalette, - QStandardItem, QUrl, QRegExpValidator, QRegExp, QLineEdit, - QToolButton, QMenu, QInputDialog, QAction, QKeySequence) + QSize, QDoubleSpinBox, QLabel, QTextBrowser, QPropertyAnimation, + QPainter, QBrush, QColor, QStandardItemModel, QPalette, QStandardItem, + QUrl, QRegExpValidator, QRegExp, QLineEdit, QToolButton, QMenu, + QInputDialog, QAction, QKeySequence) from calibre.gui2.viewer.main_ui import Ui_EbookViewer from calibre.gui2.viewer.printing import Printing @@ -55,8 +55,6 @@ class TOC(QStandardItemModel): self.appendRow(TOCItem(t)) self.setHorizontalHeaderItem(0, QStandardItem(_('Table of Contents'))) - - class Worker(Thread): def run(self): @@ -292,6 +290,37 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.tool_bar2.setContextMenuPolicy(Qt.PreventContextMenu) self.tool_bar.widgetForAction(self.action_bookmark).setPopupMode(QToolButton.MenuButtonPopup) self.action_full_screen.setCheckable(True) + self.full_screen_label = QLabel(''' +
+

%s

+

%s

+

%s

+
+ '''%(_('Full screen mode'), + _('Right click to show controls'), + _('Press Esc to quit')), + self) + self.full_screen_label.setVisible(False) + self.full_screen_label.setStyleSheet(''' + QLabel { + text-align: center; + background-color: white; + color: black; + border-width: 1px; + border-style: solid; + border-radius: 20px; + } + ''') + self.toggle_toolbar_action = QAction(_('Show/hide controls'), self) + self.toggle_toolbar_action.triggered.connect(self.toggle_toolbars) + self.addAction(self.toggle_toolbar_action) + self.full_screen_label_anim = QPropertyAnimation( + self.full_screen_label, 'size') + self.esc_full_screen_action = a = QAction(self) + self.addAction(a) + a.setShortcut(Qt.Key_Escape) + a.setEnabled(False) + a.triggered.connect(self.action_full_screen.trigger) self.print_menu = QMenu() self.print_menu.addAction(QIcon(I('print-preview.png')), _('Print Preview')) @@ -299,7 +328,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.tool_bar.widgetForAction(self.action_print).setPopupMode(QToolButton.MenuButtonPopup) self.connect(self.action_print, SIGNAL("triggered(bool)"), partial(self.print_book, preview=False)) self.connect(self.print_menu.actions()[0], SIGNAL("triggered(bool)"), partial(self.print_book, preview=True)) - self.set_max_width() ca = self.view.copy_action ca.setShortcut(QKeySequence.Copy) self.addAction(ca) @@ -313,6 +341,13 @@ class EbookViewer(MainWindow, Ui_EbookViewer): w = self.tool_bar.widgetForAction(self.action_open_ebook) w.setPopupMode(QToolButton.MenuButtonPopup) + for x in ('tool_bar', 'tool_bar2'): + x = getattr(self, x) + for action in x.actions(): + # So that the keyboard shortcuts for these actions will + # continue to function even when the toolbars are hidden + self.addAction(action) + self.restore_state() def set_toc_visible(self, yes): @@ -339,12 +374,17 @@ class EbookViewer(MainWindow, Ui_EbookViewer): def closeEvent(self, e): if self.isFullScreen(): - self.showNormal() + self.action_full_screen.trigger() e.ignore() return self.save_state() return MainWindow.closeEvent(self, e) + def toggle_toolbars(self): + for x in ('tool_bar', 'tool_bar2'): + x = getattr(self, x) + x.setVisible(not x.isVisible()) + def save_state(self): state = bytearray(self.saveState(self.STATE_VERSION)) vprefs['viewer_toolbar_state'] = state @@ -386,11 +426,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self._lookup = None self.dictionary_view.setHtml(html) - def set_max_width(self): - from calibre.gui2.viewer.documentview import config - c = config().parse() - self.frame.setMaximumWidth(c.max_view_width) - def get_remember_current_page_opt(self): from calibre.gui2.viewer.documentview import config c = config().parse() @@ -405,6 +440,46 @@ class EbookViewer(MainWindow, Ui_EbookViewer): else: self.showFullScreen() + def showFullScreen(self): + self.tool_bar.setVisible(False) + self.tool_bar2.setVisible(False) + self._original_frame_margins = ( + self.centralwidget.layout().contentsMargins(), + self.frame.layout().contentsMargins()) + self.frame.layout().setContentsMargins(0, 0, 0, 0) + self.centralwidget.layout().setContentsMargins(0, 0, 0, 0) + + super(EbookViewer, self).showFullScreen() + QTimer.singleShot(10, self.show_full_screen_label) + + def show_full_screen_label(self): + f = self.full_screen_label + self.esc_full_screen_action.setEnabled(True) + f.setVisible(True) + height = 200 + width = int(0.7*self.view.width()) + f.resize(width, height) + f.move((self.view.width() - width)//2, (self.view.height()-height)//2) + a = self.full_screen_label_anim + a.setDuration(500) + a.setStartValue(QSize(width, 0)) + a.setEndValue(QSize(width, height)) + a.start() + QTimer.singleShot(2750, self.full_screen_label.hide) + self.view.document.switch_to_fullscreen_mode() + + def showNormal(self): + self.esc_full_screen_action.setEnabled(False) + self.tool_bar.setVisible(True) + self.tool_bar2.setVisible(True) + self.full_screen_label.setVisible(False) + if hasattr(self, '_original_frame_margins'): + om = self._original_frame_margins + self.centralwidget.layout().setContentsMargins(om[0]) + self.frame.layout().setContentsMargins(om[1]) + super(EbookViewer, self).showNormal() + self.view.document.switch_to_window_mode() + def goto(self, ref): if ref: tokens = ref.split('.') diff --git a/src/calibre/gui2/viewer/main.ui b/src/calibre/gui2/viewer/main.ui index 3137ad2e07..659a534fa8 100644 --- a/src/calibre/gui2/viewer/main.ui +++ b/src/calibre/gui2/viewer/main.ui @@ -284,6 +284,9 @@ Toggle full screen + + Toggle full screen (F11) + From 9915d4b9636ec094f9b501d94ec55b4986df9c7c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 20 Mar 2012 18:49:00 +0530 Subject: [PATCH 3/6] Fix Le Monde --- recipes/le_monde.recipe | 79 +++++------------------------------------ 1 file changed, 8 insertions(+), 71 deletions(-) diff --git a/recipes/le_monde.recipe b/recipes/le_monde.recipe index 8fcdf9c870..6c7f15cca7 100644 --- a/recipes/le_monde.recipe +++ b/recipes/le_monde.recipe @@ -3,7 +3,6 @@ __copyright__ = '2011' ''' lemonde.fr ''' -import re from calibre.web.feeds.recipes import BasicNewsRecipe class LeMonde(BasicNewsRecipe): @@ -41,77 +40,8 @@ class LeMonde(BasicNewsRecipe): remove_empty_feeds = True - filterDuplicates = True + auto_cleanup = True - def preprocess_html(self, soup): - for alink in soup.findAll('a'): - if alink.string is not None: - tstr = alink.string - alink.replaceWith(tstr) - return self.adeify_images(soup) - - preprocess_regexps = [ - (re.compile(r'([0-9])%'), lambda m: m.group(1) + ' %'), - (re.compile(r'([0-9])([0-9])([0-9]) ([0-9])([0-9])([0-9])'), lambda m: m.group(1) + m.group(2) + m.group(3) + ' ' + m.group(4) + m.group(5) + m.group(6)), - (re.compile(r'([0-9]) ([0-9])([0-9])([0-9])'), lambda m: m.group(1) + ' ' + m.group(2) + m.group(3) + m.group(4)), - (re.compile(r''), lambda match: ' '), - (re.compile(r'\("'), lambda match: '(« '), - (re.compile(r'"\)'), lambda match: ' »)'), - (re.compile(r'“'), lambda match: '(« '), - (re.compile(r'”'), lambda match: ' »)'), - (re.compile(r'>\''), lambda match: '>‘'), - (re.compile(r' \''), lambda match: ' ‘'), - (re.compile(r'\''), lambda match: '’'), - (re.compile(r'"'), lambda match: '« '), - (re.compile(r'""'), lambda match: '« '), - (re.compile(r'""'), lambda match: ' »'), - (re.compile(r'"'), lambda match: ' »'), - (re.compile(r'""'), lambda match: '>« '), - (re.compile(r'"<'), lambda match: ' »<'), - (re.compile(r'’"'), lambda match: '’« '), - (re.compile(r' "'), lambda match: ' « '), - (re.compile(r'" '), lambda match: ' » '), - (re.compile(r'"\.'), lambda match: ' ».'), - (re.compile(r'",'), lambda match: ' »,'), - (re.compile(r'"\?'), lambda match: ' »?'), - (re.compile(r'":'), lambda match: ' »:'), - (re.compile(r'";'), lambda match: ' »;'), - (re.compile(r'"\!'), lambda match: ' »!'), - (re.compile(r' :'), lambda match: ' :'), - (re.compile(r' ;'), lambda match: ' ;'), - (re.compile(r' \?'), lambda match: ' ?'), - (re.compile(r' \!'), lambda match: ' !'), - (re.compile(r'\s»'), lambda match: ' »'), - (re.compile(r'«\s'), lambda match: '« '), - (re.compile(r' %'), lambda match: ' %'), - (re.compile(r'\.jpg » border='), lambda match: '.jpg'), - (re.compile(r'\.png » border='), lambda match: '.png'), - (re.compile(r' – '), lambda match: ' – '), - (re.compile(r' – '), lambda match: ' – '), - (re.compile(r' - '), lambda match: ' – '), - (re.compile(r' -,'), lambda match: ' –,'), - (re.compile(r'»:'), lambda match: '» :'), - ] - - - keep_only_tags = [ - dict(name='div', attrs={'class':['contenu']}) - ] - remove_tags = [dict(name='div', attrs={'class':['LM_atome']})] - remove_tags_after = [dict(id='appel_temoignage')] - - def get_article_url(self, article): - url = article.get('guid', None) - if '/chat/' in url or '.blog' in url or '/video/' in url or '/sport/' in url or '/portfolio/' in url or '/visuel/' in url : - url = None - return url - -# def get_article_url(self, article): -# link = article.get('link') -# if 'blog' not in link and ('chat' not in link): -# return link feeds = [ ('A la une', 'http://www.lemonde.fr/rss/une.xml'), @@ -137,3 +67,10 @@ class LeMonde(BasicNewsRecipe): return cover_url + def get_article_url(self, article): + url = article.get('guid', None) + if '/chat/' in url or '.blog' in url or '/video/' in url or '/sport/' in url or '/portfolio/' in url or '/visuel/' in url : + url = None + return url + + From 6b12bc2e560458daa07c4ef2ab30b60f6e9fa280 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 20 Mar 2012 18:51:53 +0530 Subject: [PATCH 4/6] Fix calibre not supporting different http and https proxies. Fixes #960173 (Proxy error with multiple "*_proxy" environment variables under GNU/Linux) --- src/calibre/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index ea5e4858ca..2a2242a68f 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -381,12 +381,15 @@ def browser(honor_time=True, max_time=2, mobile_browser=False, user_agent=None): user_agent = USER_AGENT_MOBILE if mobile_browser else USER_AGENT opener.addheaders = [('User-agent', user_agent)] proxies = get_proxies() + to_add = {} http_proxy = proxies.get('http', None) if http_proxy: - opener.set_proxies({'http':http_proxy}) + to_add['http'] = http_proxy https_proxy = proxies.get('https', None) if https_proxy: - opener.set_proxies({'https':https_proxy}) + to_add['https'] = https_proxy + if to_add: + opener.set_proxies(to_add) return opener From 3656de9ea2309977894b8fa04c31e00105145ca6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 20 Mar 2012 19:47:45 +0530 Subject: [PATCH 5/6] Klub knjige by Darko Miletic. Fixes #960197 (New recipe for blog klub knjige) --- recipes/klubknjige.recipe | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 recipes/klubknjige.recipe diff --git a/recipes/klubknjige.recipe b/recipes/klubknjige.recipe new file mode 100644 index 0000000000..dd16c0b3b9 --- /dev/null +++ b/recipes/klubknjige.recipe @@ -0,0 +1,42 @@ + +__license__ = 'GPL v3' +__copyright__ = '2012, Darko Miletic ' +''' +klub-knjige.blogspot.com +''' + +import re +from calibre.web.feeds.news import BasicNewsRecipe + +class KlubKnjige(BasicNewsRecipe): + title = 'Klub knjige' + __author__ = 'Darko Miletic' + description = 'literarni blog' + oldest_article = 30 + max_articles_per_feed = 100 + language = 'sr' + encoding = 'utf-8' + no_stylesheets = True + use_embedded_content = True + publication_type = 'blog' + extra_css = """ + @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} + body{font-family: Arial,Tahoma,Helvetica,FreeSans,sans1,sans-serif} + img{margin-bottom: 0.8em; border: 1px solid #333333; padding: 4px } + """ + + conversion_options = { + 'comment' : description + , 'tags' : 'knjige, blog, srbija, sf' + , 'publisher': 'Klub Knjige' + , 'language' : language + } + + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] + + feeds = [(u'Posts', u'http://klub-knjige.blogspot.com/feeds/posts/default')] + + def preprocess_html(self, soup): + for item in soup.findAll(style=True): + del item['style'] + return self.adeify_images(soup) From 931d46cd84761f55372adbe4ca04a1ffe2d6b73a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 20 Mar 2012 20:47:51 +0530 Subject: [PATCH 6/6] Ivana Milakovic by Darko Miletic. Fixes #960279 (New recipe for blog Ivana Milakovic) --- recipes/ivanamilakovic.recipe | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 recipes/ivanamilakovic.recipe diff --git a/recipes/ivanamilakovic.recipe b/recipes/ivanamilakovic.recipe new file mode 100644 index 0000000000..34e00a7ed8 --- /dev/null +++ b/recipes/ivanamilakovic.recipe @@ -0,0 +1,43 @@ +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai + +__license__ = 'GPL v3' +__copyright__ = '2012, Darko Miletic ' +''' +ivanamilakovic.blogspot.com +''' + +import re +from calibre.web.feeds.news import BasicNewsRecipe + +class IvanaMilakovic(BasicNewsRecipe): + title = u'Ivana Milaković' + __author__ = 'Darko Miletic' + description = u'Hronika mačijeg škrabala - priče, inspiracija, knjige, pisanje, prevodi...' + oldest_article = 80 + max_articles_per_feed = 100 + language = 'sr' + encoding = 'utf-8' + no_stylesheets = True + use_embedded_content = True + publication_type = 'blog' + extra_css = """ + @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} + body{font-family: Arial,Tahoma,Helvetica,FreeSans,sans1,sans-serif} + img{margin-bottom: 0.8em; border: 1px solid #333333; padding: 4px } + """ + + conversion_options = { + 'comment' : description + , 'tags' : 'knjige, blog, srbija, sf' + , 'publisher': 'Ivana Milakovic' + , 'language' : language + } + + preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')] + + feeds = [(u'Posts', u'http://ivanamilakovic.blogspot.com/feeds/posts/default')] + + def preprocess_html(self, soup): + for item in soup.findAll(style=True): + del item['style'] + return self.adeify_images(soup)