Merge from trunk

This commit is contained in:
Charles Haley 2013-01-08 10:02:00 +01:00
commit 6331180d96
9 changed files with 188 additions and 71 deletions

View File

@ -1,33 +1,36 @@
from calibre.web.feeds.recipes import BasicNewsRecipe
class AdvancedUserRecipe1303841067(BasicNewsRecipe):
title = u'Börse-online'
__author__ = 'schuster'
oldest_article = 1
title = u'Börse-online'
__author__ = 'schuster, Armin Geller'
oldest_article = 1
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
language = 'de'
remove_javascript = True
cover_url = 'http://www.dpv.de/images/1995/source.gif'
masthead_url = 'http://www.zeitschriften-cover.de/cover/boerse-online-cover-januar-2010-x1387.jpg'
extra_css = '''
h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;}
h4{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;}
img {min-width:300px; max-width:600px; min-height:300px; max-height:800px}
p{font-family:Arial,Helvetica,sans-serif;font-size:small;}
body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
'''
remove_tags_bevor = [dict(name='h3')]
remove_tags_after = [dict(name='div', attrs={'class':'artikelfuss'})]
remove_tags = [dict(attrs={'class':['moduleTopNav', 'moduleHeaderNav', 'text', 'blau', 'poll1150']}),
dict(id=['newsletterlayer', 'newsletterlayerClose', 'newsletterlayer_body', 'newsletterarray_error', 'newsletterlayer_emailadress', 'newsletterlayer_submit', 'kommentar']),
dict(name=['h2', 'Gesamtranking', 'h3',''])]
no_stylesheets = True
use_embedded_content = False
language = 'de'
remove_javascript = True
encoding = 'iso-8859-1'
timefmt = ' [%a, %d %b %Y]'
cover_url = 'http://www.wirtschaftsmedien-shop.de/s/media/coverimages/7576_2013107.jpg'
masthead_url = 'http://upload.wikimedia.org/wikipedia/de/5/56/B%C3%B6rse_Online_Logo.svg'
remove_tags_after = [dict(name='div', attrs={'class':['artikelfuss', 'rahmen600']})]
remove_tags = [
dict(name='div', attrs={'id':['breadcrumb', 'rightCol', 'clearall']}),
dict(name='div', attrs={'class':['footer', 'artikelfuss']}),
]
keep_only_tags = [
dict(name='div', attrs={'id':['contentWrapper']})
]
feeds = [(u'Börsennachrichten', u'http://www.boerse-online.de/rss/')]
def print_version(self, url):
return url.replace('.html#nv=rss', '.html?mode=print')
feeds = [(u'Börsennachrichten', u'http://www.boerse-online.de/rss/')]

BIN
recipes/icons/libartes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

69
recipes/libartes.recipe Normal file
View File

@ -0,0 +1,69 @@
__license__ = 'GPL v3'
__copyright__ = '2013, Darko Miletic <darko.miletic at gmail.com>'
'''
libartes.com
'''
import re
from calibre import strftime
from calibre.web.feeds.news import BasicNewsRecipe
class Libartes(BasicNewsRecipe):
title = 'Libartes'
__author__ = 'Darko Miletic'
description = 'Elektronski časopis Libartes delo je kulturnih entuzijasta, umetnika i teoretičara umetnosti i književnosti. Časopis Libartes izlazi tromesečno i bavi se različitim granama umetnosti - književnošću, muzikom, filmom, likovnim umetnostima, dizajnom i arhitekturom.'
publisher = 'Libartes'
category = 'literatura, knjizevnost, film, dizajn, arhitektura, muzika'
no_stylesheets = True
INDEX = 'http://libartes.com/'
use_embedded_content = False
encoding = 'utf-8'
language = 'sr'
publication_type = 'magazine'
masthead_url = 'http://libartes.com/index_files/logo.gif'
extra_css = """
@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)}
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
body{font-family: "Times New Roman",Times,serif1, serif}
img{display:block}
.naslov{font-size: xx-large; font-weight: bold}
.nag{font-size: large; font-weight: bold}
"""
conversion_options = {
'comment' : description
, 'tags' : category
, 'publisher' : publisher
, 'language' : language
}
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
remove_tags_before = dict(attrs={'id':'nav'})
remove_tags_after = dict(attrs={'id':'fb' })
keep_only_tags = [dict(name='div', attrs={'id':'center_content'})]
remove_tags = [
dict(name=['object','link','iframe','embed','meta'])
,dict(attrs={'id':'nav'})
]
def parse_index(self):
articles = []
soup = self.index_to_soup(self.INDEX)
for item in soup.findAll(name='a', attrs={'class':'belad'}, href=True):
feed_link = item
if feed_link['href'].startswith(self.INDEX):
url = feed_link['href']
else:
url = self.INDEX + feed_link['href']
title = self.tag_to_string(feed_link)
date = strftime(self.timefmt)
articles.append({
'title' :title
,'date' :date
,'url' :url
,'description':''
})
return [('Casopis Libartes', articles)]

View File

@ -10,7 +10,7 @@ Convert OEB ebook format to PDF.
import glob, os
from calibre.constants import iswindows
from calibre.constants import iswindows, islinux
from calibre.customize.conversion import (OutputFormatPlugin,
OptionRecommendation)
from calibre.ptempfile import TemporaryDirectory
@ -73,13 +73,13 @@ class PDFOutput(OutputFormatPlugin):
' of stretching it to fill the full first page of the'
' generated pdf.')),
OptionRecommendation(name='pdf_serif_family',
recommended_value='Times New Roman', help=_(
recommended_value='Liberation Serif' if islinux else 'Times New Roman', help=_(
'The font family used to render serif fonts')),
OptionRecommendation(name='pdf_sans_family',
recommended_value='Helvetica', help=_(
recommended_value='Liberation Sans' if islinux else 'Helvetica', help=_(
'The font family used to render sans-serif fonts')),
OptionRecommendation(name='pdf_mono_family',
recommended_value='Courier New', help=_(
recommended_value='Liberation Mono' if islinux else 'Courier New', help=_(
'The font family used to render monospaced fonts')),
OptionRecommendation(name='pdf_standard_font', choices=['serif',
'sans', 'mono'],
@ -102,6 +102,10 @@ class PDFOutput(OutputFormatPlugin):
])
def convert(self, oeb_book, output_path, input_plugin, opts, log):
from calibre.gui2 import must_use_qt, load_builtin_fonts
must_use_qt()
load_builtin_fonts()
self.oeb = oeb_book
self.input_plugin, self.opts, self.log = input_plugin, opts, log
self.output_path = output_path
@ -135,7 +139,6 @@ class PDFOutput(OutputFormatPlugin):
If you ever move to Qt WebKit 2.3+ then this will be unnecessary.
'''
from calibre.ebooks.oeb.base import urlnormalize
from calibre.gui2 import must_use_qt
from calibre.utils.fonts.utils import remove_embed_restriction
from PyQt4.Qt import QFontDatabase, QByteArray, QRawFont, QFont
@ -165,7 +168,6 @@ class PDFOutput(OutputFormatPlugin):
raw = remove_embed_restriction(raw)
except:
continue
must_use_qt()
fid = QFontDatabase.addApplicationFontFromData(QByteArray(raw))
family_name = None
if fid > -1:

View File

@ -239,7 +239,7 @@ class PdfEngine(QPaintEngine):
@store_error
def drawTextItem(self, point, text_item):
# super(PdfEngine, self).drawTextItem(point, text_item)
# return super(PdfEngine, self).drawTextItem(point, text_item)
self.apply_graphics_state()
gi = self.qt_hack.get_glyphs(point, text_item)
if not gi.indices:
@ -247,7 +247,10 @@ class PdfEngine(QPaintEngine):
return
name = hash(bytes(gi.name))
if name not in self.fonts:
self.fonts[name] = self.create_sfnt(text_item)
try:
self.fonts[name] = self.create_sfnt(text_item)
except UnsupportedFont:
return super(PdfEngine, self).drawTextItem(point, text_item)
metrics = self.fonts[name]
for glyph_id in gi.indices:
try:

View File

@ -147,9 +147,10 @@ class PDFWriter(QObject):
opts = self.opts
page_size = get_page_size(self.opts)
xdpi, ydpi = self.view.logicalDpiX(), self.view.logicalDpiY()
# We cannot set the side margins in the webview as there is no right
# margin for the last page (the margins are implemented with
# -webkit-column-gap)
ml, mr = opts.margin_left, opts.margin_right
margin_side = min(ml, mr)
ml, mr = ml - margin_side, mr - margin_side
self.doc = PdfDevice(out_stream, page_size=page_size, left_margin=ml,
top_margin=0, right_margin=mr, bottom_margin=0,
xdpi=xdpi, ydpi=ydpi, errors=self.log.error,
@ -162,9 +163,7 @@ class PDFWriter(QObject):
self.total_items = len(items)
mt, mb = map(self.doc.to_px, (opts.margin_top, opts.margin_bottom))
ms = self.doc.to_px(margin_side, vertical=False)
self.margin_top, self.margin_size, self.margin_bottom = map(
lambda x:int(floor(x)), (mt, ms, mb))
self.margin_top, self.margin_bottom = map(lambda x:int(floor(x)), (mt, mb))
self.painter = QPainter(self.doc)
self.doc.set_metadata(title=pdf_metadata.title,
@ -185,7 +184,8 @@ class PDFWriter(QObject):
self.painter.restore()
QTimer.singleShot(0, self.render_book)
self.loop.exec_()
if self.loop.exec_() == 1:
raise Exception('PDF Output failed, see log for details')
if self.toc is not None and len(self.toc) > 0:
self.doc.add_outline(self.toc)
@ -258,7 +258,7 @@ class PDFWriter(QObject):
paged_display.layout();
paged_display.fit_images();
py_bridge.value = book_indexing.all_links_and_anchors();
'''%(self.margin_top, self.margin_size, self.margin_bottom))
'''%(self.margin_top, 0, self.margin_bottom))
amap = self.bridge_value
if not isinstance(amap, dict):

View File

@ -11,7 +11,7 @@ from math import sqrt
from collections import namedtuple
from PyQt4.Qt import (
QBrush, QPen, Qt, QPointF, QTransform, QPainterPath, QPaintEngine, QImage)
QBrush, QPen, Qt, QPointF, QTransform, QPaintEngine, QImage)
from calibre.ebooks.pdf.render.common import (
Name, Array, fmtnum, Stream, Dictionary)
@ -248,7 +248,7 @@ class TexturePattern(TilingPattern):
class GraphicsState(object):
FIELDS = ('fill', 'stroke', 'opacity', 'transform', 'brush_origin',
'clip', 'do_fill', 'do_stroke')
'clip_updated', 'do_fill', 'do_stroke')
def __init__(self):
self.fill = QBrush()
@ -256,7 +256,7 @@ class GraphicsState(object):
self.opacity = 1.0
self.transform = QTransform()
self.brush_origin = QPointF()
self.clip = QPainterPath()
self.clip_updated = False
self.do_fill = False
self.do_stroke = True
self.qt_pattern_cache = {}
@ -274,7 +274,7 @@ class GraphicsState(object):
ans.opacity = self.opacity
ans.transform = self.transform * QTransform()
ans.brush_origin = QPointF(self.brush_origin)
ans.clip = self.clip
ans.clip_updated = self.clip_updated
ans.do_fill, ans.do_stroke = self.do_fill, self.do_stroke
return ans
@ -311,7 +311,7 @@ class Graphics(object):
s.opacity = state.opacity()
if flags & QPaintEngine.DirtyClipPath or flags & QPaintEngine.DirtyClipRegion:
s.clip = painter.clipPath()
s.clip_updated = True
def reset(self):
self.current_state = GraphicsState()
@ -326,7 +326,7 @@ class Graphics(object):
ps = self.pending_state
pdf = self.pdf
if (ps.transform != pdf_state.transform or ps.clip != pdf_state.clip):
if ps.transform != pdf_state.transform or ps.clip_updated:
pdf.restore_stack()
pdf.save_stack()
pdf_state = self.base_state
@ -341,11 +341,14 @@ class Graphics(object):
pdf_state.brush_origin != ps.brush_origin):
self.apply_fill(ps, pdf_system, painter)
if (pdf_state.clip != ps.clip):
p = convert_path(ps.clip)
fill_rule = {Qt.OddEvenFill:'evenodd',
Qt.WindingFill:'winding'}[ps.clip.fillRule()]
pdf.add_clip(p, fill_rule=fill_rule)
if ps.clip_updated:
ps.clip_updated = False
path = painter.clipPath()
if not path.isEmpty():
p = convert_path(path)
fill_rule = {Qt.OddEvenFill:'evenodd',
Qt.WindingFill:'winding'}[path.fillRule()]
pdf.add_clip(p, fill_rule=fill_rule)
self.current_state = self.pending_state
self.pending_state = None

View File

@ -766,6 +766,26 @@ class Translator(QTranslator):
gui_thread = None
qt_app = None
def load_builtin_fonts():
global _rating_font
# Load the builtin fonts and any fonts added to calibre by the user to
# Qt
for ff in glob.glob(P('fonts/liberation/*.?tf')) + \
[P('fonts/calibreSymbols.otf')] + \
glob.glob(os.path.join(config_dir, 'fonts', '*.?tf')):
if ff.rpartition('.')[-1].lower() in {'ttf', 'otf'}:
with open(ff, 'rb') as s:
# Windows requires font files to be executable for them to be
# loaded successfully, so we use the in memory loader
fid = QFontDatabase.addApplicationFontFromData(s.read())
if fid > -1:
fam = QFontDatabase.applicationFontFamilies(fid)
fam = set(map(unicode, fam))
if u'calibre Symbols' in fam:
_rating_font = u'calibre Symbols'
class Application(QApplication):
def __init__(self, args, force_calibre_style=False,
@ -798,27 +818,12 @@ class Application(QApplication):
return ret
def load_builtin_fonts(self, scan_for_fonts=False):
global _rating_font
if scan_for_fonts:
from calibre.utils.fonts.scanner import font_scanner
# Start scanning the users computer for fonts
font_scanner
# Load the builtin fonts and any fonts added to calibre by the user to
# Qt
for ff in glob.glob(P('fonts/liberation/*.?tf')) + \
[P('fonts/calibreSymbols.otf')] + \
glob.glob(os.path.join(config_dir, 'fonts', '*.?tf')):
if ff.rpartition('.')[-1].lower() in {'ttf', 'otf'}:
with open(ff, 'rb') as s:
# Windows requires font files to be executable for them to be
# loaded successfully, so we use the in memory loader
fid = QFontDatabase.addApplicationFontFromData(s.read())
if fid > -1:
fam = QFontDatabase.applicationFontFamilies(fid)
fam = set(map(unicode, fam))
if u'calibre Symbols' in fam:
_rating_font = u'calibre Symbols'
load_builtin_fonts()
def load_calibre_style(self):
# On OS X QtCurve resets the palette, so we preserve it explicitly

View File

@ -1109,8 +1109,8 @@ not multiple and the destination field is multiple</string>
<rect>
<x>0</x>
<y>0</y>
<width>205</width>
<height>66</height>
<width>934</width>
<height>213</height>
</rect>
</property>
<layout class="QGridLayout" name="testgrid">
@ -1269,8 +1269,8 @@ not multiple and the destination field is multiple</string>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>252</x>
<y>382</y>
<x>258</x>
<y>638</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
@ -1285,8 +1285,8 @@ not multiple and the destination field is multiple</string>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>320</x>
<y>382</y>
<x>326</x>
<y>638</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
@ -1294,5 +1294,37 @@ not multiple and the destination field is multiple</string>
</hint>
</hints>
</connection>
<connection>
<sender>remove_all_tags</sender>
<signal>toggled(bool)</signal>
<receiver>remove_tags</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>888</x>
<y>266</y>
</hint>
<hint type="destinationlabel">
<x>814</x>
<y>268</y>
</hint>
</hints>
</connection>
<connection>
<sender>clear_languages</sender>
<signal>toggled(bool)</signal>
<receiver>languages</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>874</x>
<y>418</y>
</hint>
<hint type="destinationlabel">
<x>817</x>
<y>420</y>
</hint>
</hints>
</connection>
</connections>
</ui>