mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
f5be845169
@ -1,15 +1,16 @@
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>, Rogelio Domínguez <rogelio.dominguez@gmail.com>'
|
||||||
'''
|
'''
|
||||||
www.jornada.unam.mx
|
www.jornada.unam.mx
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
import re
|
||||||
from calibre import strftime
|
from calibre import strftime
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class LaJornada_mx(BasicNewsRecipe):
|
class LaJornada_mx(BasicNewsRecipe):
|
||||||
title = 'La Jornada (Mexico)'
|
title = 'La Jornada (Mexico)'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic/Rogelio Domínguez'
|
||||||
description = 'Noticias del diario mexicano La Jornada'
|
description = 'Noticias del diario mexicano La Jornada'
|
||||||
publisher = 'DEMOS, Desarrollo de Medios, S.A. de C.V.'
|
publisher = 'DEMOS, Desarrollo de Medios, S.A. de C.V.'
|
||||||
category = 'news, Mexico'
|
category = 'news, Mexico'
|
||||||
@ -20,12 +21,26 @@ class LaJornada_mx(BasicNewsRecipe):
|
|||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
language = 'es'
|
language = 'es'
|
||||||
remove_empty_feeds = True
|
remove_empty_feeds = True
|
||||||
cover_url = strftime("http://www.jornada.unam.mx/%Y/%m/%d/planitas/portadita.jpg")
|
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'
|
masthead_url = 'http://www.jornada.unam.mx/v7.0/imagenes/la-jornada-trans.png'
|
||||||
|
publication_type = 'newspaper'
|
||||||
extra_css = """
|
extra_css = """
|
||||||
body{font-family: "Times New Roman",serif }
|
body{font-family: "Times New Roman",serif }
|
||||||
.cabeza{font-size: xx-large; font-weight: bold }
|
.cabeza{font-size: xx-large; font-weight: bold }
|
||||||
.credito-articulo{font-size: 1.3em}
|
.documentFirstHeading{font-size: xx-large; font-weight: bold }
|
||||||
|
.credito-articulo{font-variant: small-caps; font-weight: bold }
|
||||||
|
.foto{text-align: center}
|
||||||
|
.pie-foto{font-size: 0.9em}
|
||||||
|
.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}
|
||||||
|
.carton{text-align: center}
|
||||||
|
.credit{font-weight: bold}
|
||||||
|
.text{margin-top: 1.4em}
|
||||||
|
p.inicial{display: inline; font-size: xx-large; font-weight: bold}
|
||||||
|
p.s-s{display: inline; text-indent: 0}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
@ -35,15 +50,21 @@ class LaJornada_mx(BasicNewsRecipe):
|
|||||||
, 'language' : language
|
, 'language' : language
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preprocess_regexps = [
|
||||||
|
(re.compile( r'<div class="inicial">(.*)</div><p class="s-s">'
|
||||||
|
,re.DOTALL|re.IGNORECASE)
|
||||||
|
,lambda match: '<p class="inicial">' + match.group(1) + '</p><p class="s-s">')
|
||||||
|
]
|
||||||
|
|
||||||
keep_only_tags = [
|
keep_only_tags = [
|
||||||
dict(name='div', attrs={'class':['documentContent','cabeza','sumarios','text']})
|
dict(name='div', attrs={'class':['documentContent','cabeza','sumarios','credito-articulo','text','carton']})
|
||||||
,dict(name='div', attrs={'id':'renderComments'})
|
,dict(name='div', attrs={'id':'renderComments'})
|
||||||
]
|
]
|
||||||
remove_tags = [dict(name='div', attrs={'class':'buttonbar'})]
|
remove_tags = [dict(name='div', attrs={'class':['buttonbar','comment-cont']})]
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'Ultimas noticias' , u'http://www.jornada.unam.mx/ultimas/news/RSS' )
|
(u'Opinion' , u'http://www.jornada.unam.mx/rss/opinion.xml' )
|
||||||
,(u'Opinion' , u'http://www.jornada.unam.mx/rss/opinion.xml' )
|
,(u'Cartones' , u'http://www.jornada.unam.mx/rss/cartones.xml' )
|
||||||
,(u'Politica' , u'http://www.jornada.unam.mx/rss/politica.xml' )
|
,(u'Politica' , u'http://www.jornada.unam.mx/rss/politica.xml' )
|
||||||
,(u'Economia' , u'http://www.jornada.unam.mx/rss/economia.xml' )
|
,(u'Economia' , u'http://www.jornada.unam.mx/rss/economia.xml' )
|
||||||
,(u'Mundo' , u'http://www.jornada.unam.mx/rss/mundo.xml' )
|
,(u'Mundo' , u'http://www.jornada.unam.mx/rss/mundo.xml' )
|
||||||
@ -55,6 +76,7 @@ class LaJornada_mx(BasicNewsRecipe):
|
|||||||
,(u'Gastronomia' , u'http://www.jornada.unam.mx/rss/gastronomia.xml' )
|
,(u'Gastronomia' , u'http://www.jornada.unam.mx/rss/gastronomia.xml' )
|
||||||
,(u'Espectaculos' , u'http://www.jornada.unam.mx/rss/espectaculos.xml' )
|
,(u'Espectaculos' , u'http://www.jornada.unam.mx/rss/espectaculos.xml' )
|
||||||
,(u'Deportes' , u'http://www.jornada.unam.mx/rss/deportes.xml' )
|
,(u'Deportes' , u'http://www.jornada.unam.mx/rss/deportes.xml' )
|
||||||
|
,(u'Ultimas noticias' , u'http://www.jornada.unam.mx/ultimas/news/RSS' )
|
||||||
]
|
]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
@ -62,3 +84,7 @@ class LaJornada_mx(BasicNewsRecipe):
|
|||||||
del item['style']
|
del item['style']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
|
def get_article_url(self, article):
|
||||||
|
rurl = article.get('link', None)
|
||||||
|
return rurl.rpartition('&partner=')[0]
|
||||||
|
|
||||||
|
@ -22,10 +22,19 @@ class NrcNextRecipe(BasicNewsRecipe):
|
|||||||
|
|
||||||
remove_tags = []
|
remove_tags = []
|
||||||
remove_tags.append(dict(name = 'div', attrs = {'class' : 'meta'}))
|
remove_tags.append(dict(name = 'div', attrs = {'class' : 'meta'}))
|
||||||
|
remove_tags.append(dict(name = 'p', attrs = {'class' : 'meta'}))
|
||||||
remove_tags.append(dict(name = 'div', attrs = {'class' : 'datumlabel'}))
|
remove_tags.append(dict(name = 'div', attrs = {'class' : 'datumlabel'}))
|
||||||
|
remove_tags.append(dict(name = 'div', attrs = {'class' : 'sharing-is-caring'}))
|
||||||
|
remove_tags.append(dict(name = 'div', attrs = {'class' : 'navigation'}))
|
||||||
|
remove_tags.append(dict(name = 'div', attrs = {'class' : 'reageer'}))
|
||||||
|
remove_tags.append(dict(name = 'div', attrs = {'class' : 'comment odd alt thread-odd thread-alt depth-1 reactie '}))
|
||||||
|
remove_tags.append(dict(name = 'div', attrs = {'class' : 'comment even thread-even depth-1 reactie '}))
|
||||||
remove_tags.append(dict(name = 'ul', attrs = {'class' : 'cats single'}))
|
remove_tags.append(dict(name = 'ul', attrs = {'class' : 'cats single'}))
|
||||||
remove_tags.append(dict(name = 'ul', attrs = {'class' : 'cats onderwerpen'}))
|
remove_tags.append(dict(name = 'ul', attrs = {'class' : 'cats onderwerpen'}))
|
||||||
remove_tags.append(dict(name = 'ul', attrs = {'class' : 'cats rubrieken'}))
|
remove_tags.append(dict(name = 'ul', attrs = {'class' : 'cats rubrieken'}))
|
||||||
|
remove_tags.append(dict(name = 'h3', attrs = {'class' : 'reacties'}))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extra_css = '''
|
extra_css = '''
|
||||||
body {font-family: verdana, arial, helvetica, geneva, sans-serif; text-align: left;}
|
body {font-family: verdana, arial, helvetica, geneva, sans-serif; text-align: left;}
|
||||||
@ -41,20 +50,18 @@ class NrcNextRecipe(BasicNewsRecipe):
|
|||||||
feeds[u'koken'] = u'http://www.nrcnext.nl/koken/'
|
feeds[u'koken'] = u'http://www.nrcnext.nl/koken/'
|
||||||
feeds[u'geld & werk'] = u'http://www.nrcnext.nl/geld-en-werk/'
|
feeds[u'geld & werk'] = u'http://www.nrcnext.nl/geld-en-werk/'
|
||||||
feeds[u'vandaag'] = u'http://www.nrcnext.nl'
|
feeds[u'vandaag'] = u'http://www.nrcnext.nl'
|
||||||
feeds[u'city life in afrika'] = u'http://www.nrcnext.nl/city-life-in-afrika/'
|
# feeds[u'city life in afrika'] = u'http://www.nrcnext.nl/city-life-in-afrika/'
|
||||||
answer = []
|
answer = []
|
||||||
articles = {}
|
articles = {}
|
||||||
indices = []
|
indices = []
|
||||||
|
|
||||||
for index, feed in feeds.items() :
|
for index, feed in feeds.items() :
|
||||||
soup = self.index_to_soup(feed)
|
soup = self.index_to_soup(feed)
|
||||||
|
for post in soup.findAll(True, attrs={'class' : 'post '}) :
|
||||||
for post in soup.findAll(True, attrs={'class' : 'post'}) :
|
|
||||||
# Find the links to the actual articles and rember the location they're pointing to and the title
|
# Find the links to the actual articles and rember the location they're pointing to and the title
|
||||||
a = post.find('a', attrs={'rel' : 'bookmark'})
|
a = post.find('a', attrs={'rel' : 'bookmark'})
|
||||||
href = a['href']
|
href = a['href']
|
||||||
title = self.tag_to_string(a)
|
title = self.tag_to_string(a)
|
||||||
|
|
||||||
if index == 'columnisten' :
|
if index == 'columnisten' :
|
||||||
# In this feed/page articles can be written by more than one author.
|
# In this feed/page articles can be written by more than one author.
|
||||||
# It is nice to see their names in the titles.
|
# It is nice to see their names in the titles.
|
||||||
@ -74,7 +81,8 @@ class NrcNextRecipe(BasicNewsRecipe):
|
|||||||
indices.append(index)
|
indices.append(index)
|
||||||
|
|
||||||
# Now, sort the temporary list of feeds in the order they appear on the website
|
# Now, sort the temporary list of feeds in the order they appear on the website
|
||||||
indices = self.sort_index_by(indices, {u'columnisten' : 1, u'koken' : 3, u'geld & werk' : 2, u'vandaag' : 0, u'city life in afrika' : 4})
|
# indices = self.sort_index_by(indices, {u'columnisten' : 1, u'koken' : 3, u'geld & werk' : 2, u'vandaag' : 0, u'city life in afrika' : 4})
|
||||||
|
indices = self.sort_index_by(indices, {u'columnisten' : 1, u'koken' : 3, u'geld & werk' : 2, u'vandaag' : 0})
|
||||||
# Apply this sort order to the actual list of feeds and articles
|
# Apply this sort order to the actual list of feeds and articles
|
||||||
answer = [(key, articles[key]) for key in indices if articles.has_key(key)]
|
answer = [(key, articles[key]) for key in indices if articles.has_key(key)]
|
||||||
|
|
||||||
|
@ -1370,8 +1370,8 @@ class DeviceMixin(object): # {{{
|
|||||||
# the if just above should have found them. Mark the book
|
# the if just above should have found them. Mark the book
|
||||||
# anyway, and print a message about the situation
|
# anyway, and print a message about the situation
|
||||||
loc[i] = True
|
loc[i] = True
|
||||||
print 'book_on_device: matched title/author but not db_id!', \
|
prints('book_on_device: matched title/author but not db_id!',
|
||||||
mi.title, authors_to_string(mi.authors)
|
mi.title, authors_to_string(mi.authors))
|
||||||
continue
|
continue
|
||||||
# Also check author sort, because it can be used as author in
|
# Also check author sort, because it can be used as author in
|
||||||
# some formats
|
# some formats
|
||||||
|
@ -145,20 +145,23 @@ class StatusBar(QStatusBar): # {{{
|
|||||||
self._font = QFont()
|
self._font = QFont()
|
||||||
self._font.setBold(True)
|
self._font.setBold(True)
|
||||||
self.setFont(self._font)
|
self.setFont(self._font)
|
||||||
|
self.defmsg = QLabel(self.default_message)
|
||||||
|
self.defmsg.setFont(self._font)
|
||||||
|
self.addWidget(self.defmsg)
|
||||||
|
|
||||||
def initialize(self, systray=None):
|
def initialize(self, systray=None):
|
||||||
self.systray = systray
|
self.systray = systray
|
||||||
self.notifier = get_notifier(systray)
|
self.notifier = get_notifier(systray)
|
||||||
self.messageChanged.connect(self.message_changed,
|
|
||||||
type=Qt.QueuedConnection)
|
|
||||||
self.message_changed('')
|
|
||||||
|
|
||||||
def device_connected(self, devname):
|
def device_connected(self, devname):
|
||||||
self.device_string = _('Connected ') + devname
|
self.device_string = _('Connected ') + devname
|
||||||
|
self.defmsg.setText(self.default_message + ' ..::.. ' +
|
||||||
|
self.device_string)
|
||||||
self.clearMessage()
|
self.clearMessage()
|
||||||
|
|
||||||
def device_disconnected(self):
|
def device_disconnected(self):
|
||||||
self.device_string = ''
|
self.device_string = ''
|
||||||
|
self.defmsg.setText(self.default_message)
|
||||||
self.clearMessage()
|
self.clearMessage()
|
||||||
|
|
||||||
def new_version_available(self, ver, url):
|
def new_version_available(self, ver, url):
|
||||||
@ -188,15 +191,6 @@ class StatusBar(QStatusBar): # {{{
|
|||||||
def clear_message(self):
|
def clear_message(self):
|
||||||
self.clearMessage()
|
self.clearMessage()
|
||||||
|
|
||||||
def message_changed(self, msg):
|
|
||||||
if not msg or msg.isEmpty() or msg.isNull() or \
|
|
||||||
not unicode(msg).strip():
|
|
||||||
extra = ''
|
|
||||||
if self.device_string:
|
|
||||||
extra = ' ..::.. ' + self.device_string
|
|
||||||
self.showMessage(self.default_message + extra)
|
|
||||||
|
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class LayoutMixin(object): # {{{
|
class LayoutMixin(object): # {{{
|
||||||
|
@ -18,6 +18,11 @@ class AbortCommit(Exception):
|
|||||||
|
|
||||||
class ConfigWidgetInterface(object):
|
class ConfigWidgetInterface(object):
|
||||||
|
|
||||||
|
'''
|
||||||
|
This class defines the interface that all widgets displayed in the
|
||||||
|
Preferences dialog must implement. To create a plugin for a new
|
||||||
|
'''
|
||||||
|
|
||||||
changed_signal = None
|
changed_signal = None
|
||||||
supports_restoring_to_defaults = True
|
supports_restoring_to_defaults = True
|
||||||
restore_defaults_desc = _('Restore settings to default values. '
|
restore_defaults_desc = _('Restore settings to default values. '
|
||||||
|
@ -13,7 +13,7 @@ from PyQt4.Qt import QMainWindow, Qt, QIcon, QStatusBar, QFont, QWidget, \
|
|||||||
QToolBar, QSize, pyqtSignal, QPixmap, QToolButton, QAction, \
|
QToolBar, QSize, pyqtSignal, QPixmap, QToolButton, QAction, \
|
||||||
QDialogButtonBox, QHBoxLayout
|
QDialogButtonBox, QHBoxLayout
|
||||||
|
|
||||||
from calibre.constants import __appname__, __version__, islinux, isosx
|
from calibre.constants import __appname__, __version__, islinux
|
||||||
from calibre.gui2 import gprefs, min_available_height, available_width, \
|
from calibre.gui2 import gprefs, min_available_height, available_width, \
|
||||||
warning_dialog
|
warning_dialog
|
||||||
from calibre.gui2.preferences import init_gui, AbortCommit, get_plugin
|
from calibre.gui2.preferences import init_gui, AbortCommit, get_plugin
|
||||||
@ -33,18 +33,13 @@ class StatusBar(QStatusBar): # {{{
|
|||||||
self._font.setBold(True)
|
self._font.setBold(True)
|
||||||
self.setFont(self._font)
|
self.setFont(self._font)
|
||||||
|
|
||||||
self.messageChanged.connect(self.message_changed,
|
self.w = QLabel(self.default_message)
|
||||||
type=Qt.QueuedConnection)
|
self.w.setFont(self._font)
|
||||||
self.message_changed('')
|
self.addWidget(self.w)
|
||||||
|
|
||||||
def message_changed(self, msg):
|
|
||||||
if not msg or msg.isEmpty() or msg.isNull() or \
|
|
||||||
not unicode(msg).strip():
|
|
||||||
self.showMessage(self.default_message)
|
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class BarTitle(QWidget):
|
class BarTitle(QWidget): # {{{
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
@ -70,6 +65,8 @@ class BarTitle(QWidget):
|
|||||||
self.setToolTip(tt)
|
self.setToolTip(tt)
|
||||||
self.setWhatsThis(tt)
|
self.setWhatsThis(tt)
|
||||||
|
|
||||||
|
# }}}
|
||||||
|
|
||||||
class Category(QWidget): # {{{
|
class Category(QWidget): # {{{
|
||||||
|
|
||||||
plugin_activated = pyqtSignal(object)
|
plugin_activated = pyqtSignal(object)
|
||||||
@ -164,7 +161,7 @@ class Preferences(QMainWindow):
|
|||||||
self.must_restart = False
|
self.must_restart = False
|
||||||
self.committed = False
|
self.committed = False
|
||||||
|
|
||||||
self.resize(900, 760 if isosx else 710)
|
self.resize(900, 720)
|
||||||
nh, nw = min_available_height()-25, available_width()-10
|
nh, nw = min_available_height()-25, available_width()-10
|
||||||
if nh < 0:
|
if nh < 0:
|
||||||
nh = 800
|
nh = 800
|
||||||
@ -201,7 +198,6 @@ class Preferences(QMainWindow):
|
|||||||
self.cw.layout().addWidget(self.bb)
|
self.cw.layout().addWidget(self.bb)
|
||||||
self.bb.rejected.connect(self.close, type=Qt.QueuedConnection)
|
self.bb.rejected.connect(self.close, type=Qt.QueuedConnection)
|
||||||
self.setCentralWidget(self.cw)
|
self.setCentralWidget(self.cw)
|
||||||
self.bb.setVisible(isosx)
|
|
||||||
self.browser = Browser(self)
|
self.browser = Browser(self)
|
||||||
self.browser.show_plugin.connect(self.show_plugin)
|
self.browser.show_plugin.connect(self.show_plugin)
|
||||||
self.stack.addWidget(self.browser)
|
self.stack.addWidget(self.browser)
|
||||||
|
@ -165,3 +165,11 @@ User Interface Actions
|
|||||||
:members:
|
:members:
|
||||||
:member-order: bysource
|
:member-order: bysource
|
||||||
|
|
||||||
|
Preferences Plugins
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
.. autoclass:: calibre.customize.PreferencesPlugin
|
||||||
|
:show-inheritance:
|
||||||
|
:members:
|
||||||
|
:member-order: bysource
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user