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
6331180d96
@ -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
BIN
recipes/icons/libartes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 282 B |
69
recipes/libartes.recipe
Normal file
69
recipes/libartes.recipe
Normal 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)]
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user