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
49d1385ea9
34
recipes/rebelion.recipe
Normal file
34
recipes/rebelion.recipe
Normal file
@ -0,0 +1,34 @@
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
import re
|
||||
|
||||
class RebelionRecipe (BasicNewsRecipe):
|
||||
__author__ = u'Marc Busqué <marc@lamarciana.com>' #Thanks to atlantique http://www.mobileread.com/forums/member.php?u=67876
|
||||
__url__ = 'http://www.lamarciana.com'
|
||||
__version__ = '1.0'
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2012, Marc Busqué <marc@lamarciana.com>'
|
||||
title = u'Rebelion.org'
|
||||
description = u'Rebelión pretende ser un medio de información alternativa que publique las noticias que no son consideradas importantes por los medios de comunicación tradicionales. También, dar a las noticias un tratamiento diferente en la línea de mostrar los intereses que los poderes económicos y políticos del mundo capitalista ocultan para mantener sus privilegios y el status actual. Queremos servir y ayudarnos de todos los grupos, colectivos y personas que trabajan por cambiar este mundo en una perspectiva radicalmente diferente, más justa, igualitaria y equilibrada social y ecológicamente. Es nuestro objetivo contar con la participación y colaboración de todos vosotros para que Rebelión sea un espacio serio, riguroso y actualizado en la difusión de noticias.'
|
||||
url = 'http://www.rebelion.org'
|
||||
language = 'es'
|
||||
tags = 'contrainformación, información alternativa'
|
||||
oldest_article = 1
|
||||
remove_empty_feeds = True
|
||||
encoding = 'latin1' #
|
||||
keep_only_tags = [
|
||||
{'name': 'div', 'attrs': {'id': 'CuerpoNoticia'}}
|
||||
]
|
||||
no_stylesheets = True
|
||||
extra_css = '.autor {font-style: italic;} .titulo {font-size: 150%;} .titulo, .pretitulo {text-align: center;} #TextoNoticia {text-align:justify;} .autor, .fuente, .entradilla {font-size: 90%; text-align: left;}'
|
||||
|
||||
feeds = [
|
||||
(u'Titulares del día', u'http://www.rebelion.org/rss_portada.php'),
|
||||
]
|
||||
|
||||
#See http://www.mobileread.com/forums/showthread.php?t=174501
|
||||
def print_version(self, url):
|
||||
id = re.compile('\d*$').search(url).group()
|
||||
return u'http://www.rebelion.org/noticia.php?id=%s' % id
|
@ -177,7 +177,7 @@ class ANDROID(USBMS):
|
||||
'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA',
|
||||
'GENERIC-', 'ZTE', 'MID', 'QUALCOMM', 'PANDIGIT', 'HYSTON',
|
||||
'VIZIO', 'GOOGLE', 'FREESCAL', 'KOBO_INC', 'LENOVO', 'ROCKCHIP',
|
||||
'POCKET', 'ONDA_MID', 'ZENITHIN', 'INGENIC', 'PMID701C']
|
||||
'POCKET', 'ONDA_MID', 'ZENITHIN', 'INGENIC', 'PMID701C', 'PD']
|
||||
WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE',
|
||||
'__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897',
|
||||
'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID',
|
||||
@ -193,7 +193,7 @@ class ANDROID(USBMS):
|
||||
'GT-I9003_CARD', 'XT912', 'FILE-CD_GADGET', 'RK29_SDK', 'MB855',
|
||||
'XT910', 'BOOK_A10', 'USB_2.0_DRIVER', 'I9100T', 'P999DW',
|
||||
'KTABLET_PC', 'INGENIC', 'GT-I9001_CARD', 'USB_2.0_DRIVER',
|
||||
'GT-S5830L_CARD']
|
||||
'GT-S5830L_CARD', 'UNIVERSE']
|
||||
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
||||
'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
||||
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
|
||||
|
@ -312,13 +312,9 @@ class EPUBOutput(OutputFormatPlugin):
|
||||
Perform various markup transforms to get the output to render correctly
|
||||
in the quirky ADE.
|
||||
'''
|
||||
from calibre.ebooks.oeb.base import XPath, XHTML, OEB_STYLES, barename, urlunquote
|
||||
from calibre.ebooks.oeb.base import XPath, XHTML, barename, urlunquote
|
||||
|
||||
stylesheet = None
|
||||
for item in self.oeb.manifest:
|
||||
if item.media_type.lower() in OEB_STYLES:
|
||||
stylesheet = item
|
||||
break
|
||||
stylesheet = self.oeb.manifest.main_stylesheet
|
||||
|
||||
# ADE cries big wet tears when it encounters an invalid fragment
|
||||
# identifier in the NCX toc.
|
||||
|
@ -99,12 +99,8 @@ class PDFOutput(OutputFormatPlugin):
|
||||
|
||||
# Remove page-break-before on <body> element as it causes
|
||||
# blank pages in PDF Output
|
||||
from calibre.ebooks.oeb.base import OEB_STYLES, XPath
|
||||
stylesheet = None
|
||||
for item in self.oeb.manifest:
|
||||
if item.media_type.lower() in OEB_STYLES:
|
||||
stylesheet = item
|
||||
break
|
||||
from calibre.ebooks.oeb.base import XPath
|
||||
stylesheet = self.oeb.manifest.main_stylesheet
|
||||
if stylesheet is not None:
|
||||
from cssutils.css import CSSRule
|
||||
classes = set(['.calibre'])
|
||||
|
@ -5,7 +5,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import re
|
||||
import re, error as re_error
|
||||
from math import ceil
|
||||
from calibre.ebooks.conversion.preprocess import DocAnalysis, Dehyphenator
|
||||
from calibre.utils.logging import default_log
|
||||
@ -148,7 +148,7 @@ class HeuristicProcessor(object):
|
||||
return wordcount.words
|
||||
|
||||
def markup_italicis(self, html):
|
||||
self.log.debug("\n\n\nitalicize debugging \n\n\n")
|
||||
#self.log.debug("\n\n\nitalicize debugging \n\n\n")
|
||||
ITALICIZE_WORDS = [
|
||||
'Etc.', 'etc.', 'viz.', 'ie.', 'i.e.', 'Ie.', 'I.e.', 'eg.',
|
||||
'e.g.', 'Eg.', 'E.g.', 'et al.', 'et cetera', 'n.b.', 'N.b.',
|
||||
@ -184,6 +184,9 @@ class HeuristicProcessor(object):
|
||||
except OverflowError:
|
||||
# match.group(0) was too large to be compiled into a regex
|
||||
continue
|
||||
except re_error:
|
||||
# the match was not a valid regular expression
|
||||
continue
|
||||
|
||||
return html
|
||||
|
||||
|
@ -81,6 +81,23 @@ _css_url_re = re.compile(r'url\s*\([\'"]{0,1}(.*?)[\'"]{0,1}\)', re.I)
|
||||
_css_import_re = re.compile(r'@import "(.*?)"')
|
||||
_archive_re = re.compile(r'[^ ]+')
|
||||
|
||||
# Tags that should not be self closed in epub output
|
||||
self_closing_bad_tags = {'a', 'abbr', 'address', 'article', 'aside', 'audio', 'b',
|
||||
'bdo', 'blockquote', 'body', 'button', 'cite', 'code', 'dd', 'del', 'details',
|
||||
'dfn', 'div', 'dl', 'dt', 'em', 'fieldset', 'figcaption', 'figure', 'footer',
|
||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'i', 'ins', 'kbd',
|
||||
'label', 'legend', 'li', 'map', 'mark', 'meter', 'nav', 'ol', 'output', 'p',
|
||||
'pre', 'progress', 'q', 'rp', 'rt', 'samp', 'section', 'select', 'small',
|
||||
'span', 'strong', 'sub', 'summary', 'sup', 'textarea', 'time', 'ul', 'var',
|
||||
'video'}
|
||||
|
||||
_self_closing_pat = re.compile(
|
||||
r'<(?P<tag>%s)(?=[\s/])(?P<arg>[^>]*)/>'%('|'.join(self_closing_bad_tags)),
|
||||
re.IGNORECASE)
|
||||
|
||||
def close_self_closing_tags(raw):
|
||||
return _self_closing_pat.sub(r'<\g<tag>\g<arg>></\g<tag>>', raw)
|
||||
|
||||
def iterlinks(root, find_links_in_css=True):
|
||||
'''
|
||||
Iterate over all links in a OEB Document.
|
||||
@ -938,13 +955,10 @@ class Manifest(object):
|
||||
if isinstance(data, etree._Element):
|
||||
ans = xml2str(data, pretty_print=self.oeb.pretty_print)
|
||||
if self.media_type in OEB_DOCS:
|
||||
# Convert self closing div|span|a|video|audio|iframe tags
|
||||
# Convert self closing div|span|a|video|audio|iframe|etc tags
|
||||
# to normally closed ones, as they are interpreted
|
||||
# incorrectly by some browser based renderers
|
||||
ans = re.sub(
|
||||
# tag name followed by either a space or a /
|
||||
r'<(?P<tag>div|a|span|video|audio|iframe)(?=[\s/])(?P<arg>[^>]*)/>',
|
||||
r'<\g<tag>\g<arg>></\g<tag>>', ans)
|
||||
ans = close_self_closing_tags(ans)
|
||||
return ans
|
||||
if isinstance(data, unicode):
|
||||
return data.encode('utf-8')
|
||||
@ -1142,6 +1156,19 @@ class Manifest(object):
|
||||
element(elem, OPF('item'), attrib=attrib)
|
||||
return elem
|
||||
|
||||
@dynamic_property
|
||||
def main_stylesheet(self):
|
||||
def fget(self):
|
||||
ans = getattr(self, '_main_stylesheet', None)
|
||||
if ans is None:
|
||||
for item in self:
|
||||
if item.media_type.lower() in OEB_STYLES:
|
||||
ans = item
|
||||
break
|
||||
return ans
|
||||
def fset(self, item):
|
||||
self._main_stylesheet = item
|
||||
return property(fget=fget, fset=fset)
|
||||
|
||||
class Spine(object):
|
||||
"""Collection of manifest items composing an OEB data model book's main
|
||||
|
@ -378,7 +378,7 @@ class CSSFlattener(object):
|
||||
for child in node:
|
||||
self.flatten_node(child, stylizer, names, styles, psize, item_id, left)
|
||||
|
||||
def flatten_head(self, item, stylizer, href):
|
||||
def flatten_head(self, item, href, global_href):
|
||||
html = item.data
|
||||
head = html.find(XHTML('head'))
|
||||
for node in head:
|
||||
@ -390,33 +390,55 @@ class CSSFlattener(object):
|
||||
and node.get('type', CSS_MIME) in OEB_STYLES:
|
||||
head.remove(node)
|
||||
href = item.relhref(href)
|
||||
etree.SubElement(head, XHTML('link'),
|
||||
l = etree.SubElement(head, XHTML('link'),
|
||||
rel='stylesheet', type=CSS_MIME, href=href)
|
||||
l.tail='\n'
|
||||
href = item.relhref(global_href)
|
||||
l = etree.SubElement(head, XHTML('link'),
|
||||
rel='stylesheet', type=CSS_MIME, href=href)
|
||||
l.tail = '\n'
|
||||
|
||||
def replace_css(self, css):
|
||||
manifest = self.oeb.manifest
|
||||
for item in manifest.values():
|
||||
if item.media_type in OEB_STYLES:
|
||||
manifest.remove(item)
|
||||
id, href = manifest.generate('css', 'stylesheet.css')
|
||||
item = manifest.add(id, href, CSS_MIME, data=cssutils.parseString(css,
|
||||
validate=False))
|
||||
self.oeb.manifest.main_stylesheet = item
|
||||
return href
|
||||
|
||||
def collect_global_css(self):
|
||||
global_css = defaultdict(list)
|
||||
for item in self.oeb.spine:
|
||||
stylizer = self.stylizers[item]
|
||||
stylizer.page_rule['margin-top'] = '%gpt'%\
|
||||
float(self.context.margin_top)
|
||||
stylizer.page_rule['margin-bottom'] = '%gpt'%\
|
||||
float(self.context.margin_bottom)
|
||||
|
||||
items = stylizer.page_rule.items()
|
||||
items.sort()
|
||||
css = '; '.join("%s: %s" % (key, val) for key, val in items)
|
||||
style = etree.SubElement(head, XHTML('style'), type=CSS_MIME)
|
||||
style.text = "\n\t\t@page { %s; }" % css
|
||||
css = ';\n'.join("%s: %s" % (key, val) for key, val in items)
|
||||
css = '@page {\n%s\n}\n'%css
|
||||
rules = [r.cssText for r in stylizer.font_face_rules]
|
||||
raw = '\n\n'.join(rules)
|
||||
# Make URLs referring to fonts relative to this item
|
||||
sheet = cssutils.parseString(raw, validate=False)
|
||||
cssutils.replaceUrls(sheet, item.relhref, ignoreImportRules=True)
|
||||
style.text += '\n' + sheet.cssText
|
||||
css += '\n\n' + raw
|
||||
global_css[css].append(item)
|
||||
|
||||
def replace_css(self, css):
|
||||
gc_map = {}
|
||||
manifest = self.oeb.manifest
|
||||
id, href = manifest.generate('css', 'stylesheet.css')
|
||||
for item in manifest.values():
|
||||
if item.media_type in OEB_STYLES:
|
||||
manifest.remove(item)
|
||||
item = manifest.add(id, href, CSS_MIME, data=css)
|
||||
return href
|
||||
for css in global_css:
|
||||
id_, href = manifest.generate('page_css', 'page_styles.css')
|
||||
manifest.add(id_, href, CSS_MIME, data=cssutils.parseString(css,
|
||||
validate=False))
|
||||
gc_map[css] = href
|
||||
|
||||
ans = {}
|
||||
for css, items in global_css.iteritems():
|
||||
for item in items:
|
||||
ans[item] = gc_map[css]
|
||||
return ans
|
||||
|
||||
def flatten_spine(self):
|
||||
names = defaultdict(int)
|
||||
@ -433,7 +455,8 @@ class CSSFlattener(object):
|
||||
items.sort()
|
||||
css = ''.join(".%s {\n%s;\n}\n\n" % (key, val) for key, val in items)
|
||||
href = self.replace_css(css)
|
||||
global_css = self.collect_global_css()
|
||||
for item in self.oeb.spine:
|
||||
stylizer = self.stylizers[item]
|
||||
self.flatten_head(item, stylizer, href)
|
||||
self.flatten_head(item, href, global_css[item])
|
||||
|
||||
|
@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
from collections import Counter
|
||||
|
||||
from calibre.ebooks.oeb.base import OEB_STYLES, barename, XPath
|
||||
from calibre.ebooks.oeb.base import barename, XPath
|
||||
|
||||
class RemoveAdobeMargins(object):
|
||||
'''
|
||||
@ -51,10 +51,7 @@ class RemoveFakeMargins(object):
|
||||
self.stats = {}
|
||||
self.selector_map = {}
|
||||
|
||||
for item in self.oeb.manifest:
|
||||
if item.media_type.lower() in OEB_STYLES:
|
||||
stylesheet = item
|
||||
break
|
||||
stylesheet = self.oeb.manifest.main_stylesheet
|
||||
if stylesheet is None:
|
||||
return
|
||||
|
||||
|
@ -259,33 +259,36 @@ class RuleEditor(QDialog): # {{{
|
||||
l.addWidget(l3, 2, 2)
|
||||
|
||||
self.color_box = QComboBox(self)
|
||||
self.color_label = QLabel('Sample text Sample text')
|
||||
self.color_label.setTextFormat(Qt.RichText)
|
||||
l.addWidget(self.color_box, 2, 3)
|
||||
l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 4)
|
||||
l.addWidget(self.color_label, 2, 4)
|
||||
l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 5)
|
||||
|
||||
self.l4 = l4 = QLabel(
|
||||
_('Only if the following conditions are all satisfied:'))
|
||||
l.addWidget(l4, 3, 0, 1, 5)
|
||||
l.addWidget(l4, 3, 0, 1, 6)
|
||||
|
||||
self.scroll_area = sa = QScrollArea(self)
|
||||
sa.setMinimumHeight(300)
|
||||
sa.setMinimumWidth(950)
|
||||
sa.setWidgetResizable(True)
|
||||
l.addWidget(sa, 4, 0, 1, 5)
|
||||
l.addWidget(sa, 4, 0, 1, 6)
|
||||
|
||||
self.add_button = b = QPushButton(QIcon(I('plus.png')),
|
||||
_('Add another condition'))
|
||||
l.addWidget(b, 5, 0, 1, 5)
|
||||
l.addWidget(b, 5, 0, 1, 6)
|
||||
b.clicked.connect(self.add_blank_condition)
|
||||
|
||||
self.l5 = l5 = QLabel(_('You can disable a condition by'
|
||||
' blanking all of its boxes'))
|
||||
l.addWidget(l5, 6, 0, 1, 5)
|
||||
l.addWidget(l5, 6, 0, 1, 6)
|
||||
|
||||
self.bb = bb = QDialogButtonBox(
|
||||
QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
|
||||
bb.accepted.connect(self.accept)
|
||||
bb.rejected.connect(self.reject)
|
||||
l.addWidget(bb, 7, 0, 1, 5)
|
||||
l.addWidget(bb, 7, 0, 1, 6)
|
||||
|
||||
self.conditions_widget = QWidget(self)
|
||||
sa.setWidget(self.conditions_widget)
|
||||
@ -308,8 +311,21 @@ class RuleEditor(QDialog): # {{{
|
||||
self.color_box.addItems(QColor.colorNames())
|
||||
self.color_box.setCurrentIndex(0)
|
||||
|
||||
self.update_color_label()
|
||||
self.color_box.currentIndexChanged.connect(self.update_color_label)
|
||||
self.resize(self.sizeHint())
|
||||
|
||||
def update_color_label(self):
|
||||
pal = QApplication.palette()
|
||||
bg1 = unicode(pal.color(pal.Base).name())
|
||||
bg2 = unicode(pal.color(pal.AlternateBase).name())
|
||||
c = unicode(self.color_box.currentText())
|
||||
self.color_label.setText('''
|
||||
<span style="color: {c}; background-color: {bg1}"> {st} </span>
|
||||
<span style="color: {c}; background-color: {bg2}"> {st} </span>
|
||||
'''.format(c=c, bg1=bg1, bg2=bg2, st=_('Sample Text')))
|
||||
|
||||
|
||||
def add_blank_condition(self):
|
||||
c = ConditionEditor(self.fm, parent=self.conditions_widget)
|
||||
self.conditions.append(c)
|
||||
@ -617,7 +633,7 @@ if __name__ == '__main__':
|
||||
|
||||
db = db()
|
||||
|
||||
if False:
|
||||
if True:
|
||||
d = RuleEditor(db.field_metadata)
|
||||
d.add_blank_condition()
|
||||
d.exec_()
|
||||
|
@ -9,7 +9,7 @@ import mechanize
|
||||
|
||||
from calibre.constants import (__appname__, __version__, iswindows, isosx,
|
||||
isportable)
|
||||
from calibre import browser
|
||||
from calibre import browser, prints, as_unicode
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.gui2 import config, dynamic, open_url
|
||||
from calibre.gui2.dialogs.plugin_updater import get_plugin_updates_available
|
||||
@ -45,14 +45,14 @@ class CheckForUpdates(QThread):
|
||||
version = get_newest_version()
|
||||
if version and version != __version__ and len(version) < 10:
|
||||
calibre_update_version = version
|
||||
except:
|
||||
traceback.print_exc()
|
||||
except Exception as e:
|
||||
prints('Failed to check for calibre update:', as_unicode(e))
|
||||
try:
|
||||
update_plugins = get_plugin_updates_available()
|
||||
if update_plugins is not None:
|
||||
plugins_update_found = len(update_plugins)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
except Exception as e:
|
||||
prints('Failed to check for plugin update:', as_unicode(e))
|
||||
if (calibre_update_version != NO_CALIBRE_UPDATE or
|
||||
plugins_update_found > 0):
|
||||
self.update_found.emit('%s%s%d'%(calibre_update_version,
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user