From a4271b42cd1b92d5edf4e8c8e619513f204409a2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 2 Sep 2010 13:30:01 -0600 Subject: [PATCH 1/3] Milenio by bmsleight --- resources/recipes/milenio.recipe | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 resources/recipes/milenio.recipe diff --git a/resources/recipes/milenio.recipe b/resources/recipes/milenio.recipe new file mode 100644 index 0000000000..a279eb37dc --- /dev/null +++ b/resources/recipes/milenio.recipe @@ -0,0 +1,47 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2010, Brendan Sleight ' +''' +impreso.milenio.com +''' +from calibre import strftime +from calibre.web.feeds.news import BasicNewsRecipe + +import datetime + +class Milenio(BasicNewsRecipe): + title = u'Milenio-diario' + __author__ = 'Bmsleight' + language = 'es' + description = 'Milenio-diario' + oldest_article = 10 + max_articles_per_feed = 100 + no_stylesheets = False + index = 'http://impreso.milenio.com' + + keep_only_tags = [ + dict(name='div', attrs={'class':'content'}) + ] + + def parse_index(self): + # "%m/%d/%Y" + # http://impreso.milenio.com/Nacional/2010/09/01/ + totalfeeds = [] + soup = self.index_to_soup(self.index + "/Nacional/" + datetime.date.today().strftime("%Y/%m/%d")) + maincontent = soup.find('div',attrs={'class':'content'}) + mfeed = [] + if maincontent: + for itt in maincontent.findAll('a',href=True): + if "/node/" in str(itt['href']): + url = self.index + itt['href'] + title = self.tag_to_string(itt) + description = '' + date = strftime(self.timefmt) + mfeed.append({ + 'title' :title + ,'date' :date + ,'url' :url + ,'description':description + }) + totalfeeds.append(('Articles', mfeed)) + return totalfeeds From 60306d1c90447a0fc30ace9de8c1f8ac9ad74ab5 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 2 Sep 2010 17:19:42 -0600 Subject: [PATCH 2/3] First new preference widget tested and working --- src/calibre/customize/__init__.py | 2 ++ src/calibre/customize/builtins.py | 3 ++- src/calibre/gui2/preferences/__init__.py | 17 +++++++++++------ src/calibre/gui2/preferences/look_feel.py | 4 ++-- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index 2b7c476579..27e319de14 100644 --- a/src/calibre/customize/__init__.py +++ b/src/calibre/customize/__init__.py @@ -391,6 +391,8 @@ class PreferencesPlugin(Plugin): # {{{ #: The category this plugin should be in category = None + #: The category name displayed to the user for this plugin + gui_category = None #: The name displayed to the user for this plugin gui_name = None diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index f7bc29784e..d7c05a7807 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -679,7 +679,8 @@ plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog, class LookAndFeel(PreferencesPlugin): name = 'Look & Feel' gui_name = _('Look and Feel') - category = _('Interface') + category = 'Interface' + gui_category = _('Interface') category_order = 1 name_order = 1 config_widget = 'calibre.gui2.preferences.look_feel' diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index 3baba75609..c9322f6659 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -58,7 +58,7 @@ class Setting(object): def initialize(self): self.gui_obj.blockSignals(True) - if self.datatype == 'choices': + if self.datatype == 'choice': self.gui_obj.clear() for x in self.choices: if isinstance(x, basestring): @@ -90,7 +90,7 @@ class Setting(object): self.gui_obj.setValue(val) elif self.datatype == 'string': self.gui_obj.setText(val if val else '') - elif self.datatype == 'choices': + elif self.datatype == 'choice': idx = self.gui_obj.findData(QVariant(val)) if idx == -1: idx = 0 @@ -100,12 +100,12 @@ class Setting(object): if self.datatype == 'bool': val = bool(self.gui_obj.isChecked()) elif self.datatype == 'number': - val = self.gui_obj.value(val) + val = self.gui_obj.value() elif self.datatype == 'string': val = unicode(self.gui_name.text()).strip() if self.empty_string_is_None and not val: val = None - elif self.datatype == 'choices': + elif self.datatype == 'choice': idx = self.gui_obj.currentIndex() if idx < 0: idx = 0 val = unicode(self.gui_obj.itemData(idx).toString()) @@ -135,7 +135,7 @@ class ConfigWidgetBase(QWidget, ConfigWidgetInterface): for setting in self.settings.values(): setting.initialize() - def commit(self): + def commit(self, *args): for setting in self.settings.values(): setting.commit() @@ -165,11 +165,13 @@ def test_widget(category, name, gui=None): # {{{ w = pl.create_widget(d) bb.button(bb.RestoreDefaults).clicked.connect(w.restore_defaults) bb.button(bb.Apply).setEnabled(False) - w.changed_signal.connect(lambda : bb.button(bb.Apply).setEnable(True)) + bb.button(bb.Apply).clicked.connect(d.accept) + w.changed_signal.connect(lambda : bb.button(bb.Apply).setEnabled(True)) l = QVBoxLayout() d.setLayout(l) l.addWidget(w) l.addWidget(bb) + mygui = gui is None if gui is None: from calibre.gui2.ui import Main from calibre.gui2.main import option_parser @@ -181,7 +183,10 @@ def test_widget(category, name, gui=None): # {{{ gui = Main(opts) gui.initialize(db.library_path, db, None, actions, show_gui=False) w.genesis(gui) + w.initialize() if d.exec_() == QDialog.Accepted: w.commit() + if mygui: + gui.shutdown() # }}} diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index eb13dd5429..a4fb13bfa1 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -32,10 +32,10 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): if l != lang] if lang != 'en': items.append(('en', get_language('en'))) - items.sort(cmp=lambda x, y: cmp(x[1], y[1])) + items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one - choices = [get_language(lang), lang] + choices + choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices) r('show_avg_rating', config) From 02153492b97dd9f539efeba5a4a432b3eae551ed Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 2 Sep 2010 18:07:54 -0600 Subject: [PATCH 3/3] Allow preference widgets to signal than they need a restart --- src/calibre/gui2/preferences/__init__.py | 49 +++++++++++++++-------- src/calibre/gui2/preferences/look_feel.py | 8 ++-- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index c9322f6659..fa4c2da328 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -26,36 +26,36 @@ class ConfigWidgetInterface(object): class Setting(object): def __init__(self, name, config_obj, widget, gui_name=None, - empty_string_is_None=True, choices=None): + empty_string_is_None=True, choices=None, restart_required=False): self.name, self.gui_name = name, gui_name self.empty_string_is_None = empty_string_is_None + self.restart_required = restart_required self.choices = choices if gui_name is None: self.gui_name = 'opt_'+name self.config_obj = config_obj self.gui_obj = getattr(widget, self.gui_name) + self.widget = widget if isinstance(self.gui_obj, QCheckBox): self.datatype = 'bool' - self.gui_obj.stateChanged.connect(lambda x: - widget.changed_signal.emit()) + self.gui_obj.stateChanged.connect(self.changed) elif isinstance(self.gui_obj, QAbstractSpinBox): self.datatype = 'number' - self.gui_obj.valueChanged.connect(lambda x: - widget.changed_signal.emit()) + self.gui_obj.valueChanged.connect(self.changed) elif isinstance(self.gui_obj, QLineEdit): self.datatype = 'string' - self.gui_obj.textChanged.connect(lambda x: - widget.changed_signal.emit()) + self.gui_obj.textChanged.connect(self.changed) elif isinstance(self.gui_obj, QComboBox): self.datatype = 'choice' - self.gui_obj.editTextChanged.connect(lambda x: - widget.changed_signal.emit()) - self.gui_obj.currentIndexChanged.connect(lambda x: - widget.changed_signal.emit()) + self.gui_obj.editTextChanged.connect(self.changed) + self.gui_obj.currentIndexChanged.connect(self.changed) else: raise ValueError('Unknown data type') + def changed(self, *args): + self.widget.changed_signal.emit() + def initialize(self): self.gui_obj.blockSignals(True) if self.datatype == 'choice': @@ -66,9 +66,15 @@ class Setting(object): self.gui_obj.addItem(x[0], QVariant(x[1])) self.set_gui_val(self.get_config_val(default=False)) self.gui_obj.blockSignals(False) + self.initial_value = self.get_gui_val() def commit(self): - self.set_config_val(self.get_gui_val()) + val = self.get_gui_val() + oldval = self.get_config_val() + changed = val != oldval + if changed: + self.set_config_val(self.get_gui_val()) + return changed and self.restart_required def restore_defaults(self): self.set_gui_val(self.get_config_val(default=True)) @@ -122,10 +128,11 @@ class ConfigWidgetBase(QWidget, ConfigWidgetInterface): self.setupUi(self) self.settings = {} - def register(self, name, config_obj, gui_name=None, choices=None, setting=Setting): + def register(self, name, config_obj, gui_name=None, choices=None, + restart_required=False, setting=Setting): setting = setting(name, config_obj, self, gui_name=gui_name, - choices=choices) - self.register_setting(setting) + choices=choices, restart_required=restart_required) + return self.register_setting(setting) def register_setting(self, setting): self.settings[setting.name] = setting @@ -136,8 +143,12 @@ class ConfigWidgetBase(QWidget, ConfigWidgetInterface): setting.initialize() def commit(self, *args): + restart_required = False for setting in self.settings.values(): - setting.commit() + rr = setting.commit() + if rr: + restart_required = True + return restart_required def restore_defaults(self, *args): for setting in self.settings.values(): @@ -184,8 +195,12 @@ def test_widget(category, name, gui=None): # {{{ gui.initialize(db.library_path, db, None, actions, show_gui=False) w.genesis(gui) w.initialize() + restart_required = False if d.exec_() == QDialog.Accepted: - w.commit() + restart_required = w.commit() + if restart_required: + from calibre.gui2 import warning_dialog + warning_dialog(gui, 'Restart required', 'Restart required', show=True) if mygui: gui.shutdown() # }}} diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index a4fb13bfa1..a0805e8915 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -20,7 +20,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r = self.register - r('gui_layout', config, choices= + r('gui_layout', config, restart_required=True, choices= [(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('cover_flow_queue_length', config) @@ -36,15 +36,15 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices - r('language', prefs, choices=choices) + r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) - r('systray_icon', config) + r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) - r('separate_cover_flow', config) + r('separate_cover_flow', config, restart_required=True) r('search_as_you_type', config) choices = [(_('Small'), 'small'), (_('Medium'), 'medium'),