mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
No longer need Qt to generate the default cover for news downloads
This commit is contained in:
parent
13e3d2c610
commit
b42671831e
Binary file not shown.
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 124 KiB |
@ -19,15 +19,13 @@ from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString, CData,
|
|||||||
from calibre.ebooks.metadata.opf2 import OPFCreator
|
from calibre.ebooks.metadata.opf2 import OPFCreator
|
||||||
from calibre import entity_to_unicode
|
from calibre import entity_to_unicode
|
||||||
from calibre.web import Recipe
|
from calibre.web import Recipe
|
||||||
from calibre.ebooks import render_html
|
|
||||||
from calibre.ebooks.metadata.toc import TOC
|
from calibre.ebooks.metadata.toc import TOC
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.web.feeds import feed_from_xml, templates, feeds_from_index, Feed
|
from calibre.web.feeds import feed_from_xml, templates, feeds_from_index, Feed
|
||||||
from calibre.web.fetch.simple import option_parser as web2disk_option_parser
|
from calibre.web.fetch.simple import option_parser as web2disk_option_parser
|
||||||
from calibre.web.fetch.simple import RecursiveFetcher
|
from calibre.web.fetch.simple import RecursiveFetcher
|
||||||
from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending
|
from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending
|
||||||
from calibre.ptempfile import PersistentTemporaryFile, \
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
PersistentTemporaryDirectory
|
|
||||||
from calibre.utils.date import now as nowf
|
from calibre.utils.date import now as nowf
|
||||||
|
|
||||||
class BasicNewsRecipe(Recipe):
|
class BasicNewsRecipe(Recipe):
|
||||||
@ -928,63 +926,52 @@ class BasicNewsRecipe(Recipe):
|
|||||||
'''
|
'''
|
||||||
Create a generic cover for recipes that dont have a cover
|
Create a generic cover for recipes that dont have a cover
|
||||||
'''
|
'''
|
||||||
from calibre.gui2 import is_ok_to_use_qt
|
try:
|
||||||
if not is_ok_to_use_qt():
|
try:
|
||||||
return False
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
img_data = open(I('library.png'), 'rb').read()
|
Image, ImageDraw, ImageFont
|
||||||
tdir = PersistentTemporaryDirectory('_default_cover')
|
except ImportError:
|
||||||
img = os.path.join(tdir, 'logo.png')
|
import Image, ImageDraw, ImageFont
|
||||||
with open(img, 'wb') as g:
|
font_path = P('fonts/liberation/LiberationSerif-Bold.ttf')
|
||||||
g.write(img_data)
|
font = ImageFont.truetype(font_path, 48)
|
||||||
img = os.path.basename(img)
|
title = self.title if isinstance(self.title, unicode) else \
|
||||||
html= u'''\
|
self.title.decode(preferred_encoding, 'replace')
|
||||||
<html>
|
date = strftime(self.timefmt)
|
||||||
<head>
|
app = '['+__appname__ +' '+__version__+']'
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<style type="text/css">
|
COVER_WIDTH, COVER_HEIGHT = 590, 750
|
||||||
body {
|
img = Image.new('RGB', (COVER_WIDTH, COVER_HEIGHT), 'white')
|
||||||
background: white no-repeat fixed center center;
|
draw = ImageDraw.Draw(img)
|
||||||
text-align: center;
|
# Title
|
||||||
vertical-align: center;
|
width, height = draw.textsize(title, font=font)
|
||||||
overflow: hidden;
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
font-size: 18px;
|
top = 15
|
||||||
}
|
draw.text((left, top), title, fill=(0,0,0), font=font)
|
||||||
h1 { font-family: serif; }
|
bottom = top + height
|
||||||
h2, h4 { font-family: monospace; }
|
# Date
|
||||||
</style>
|
font = ImageFont.truetype(font_path, 32)
|
||||||
</head>
|
width, height = draw.textsize(date, font=font)
|
||||||
<body>
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
<h1>%(title)s</h1>
|
draw.text((left, bottom+15), date, fill=(0,0,0), font=font)
|
||||||
<br/><br/>
|
# Vanity
|
||||||
<div style="position:relative">
|
font = ImageFont.truetype(font_path, 28)
|
||||||
<div style="position: absolute; left: 0; top: 0; width:100%%; height:100%%; vertical-align:center">
|
width, height = draw.textsize(app, font=font)
|
||||||
<img src="%(img)s" alt="calibre" style="opacity:0.3"/>
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
</div>
|
top = COVER_HEIGHT - height - 15
|
||||||
<div style="position: absolute; left: 0; top: 0; width:100%%; height:100%%; vertical-align:center">
|
draw.text((left, top), app, fill=(0,0,0), font=font)
|
||||||
<h2>%(date)s</h2>
|
# Logo
|
||||||
<br/><br/><br/><br/><br/>
|
logo = Image.open(I('library.png'), 'r')
|
||||||
<h3>%(author)s</h3>
|
width, height = logo.size
|
||||||
<br/><br/></br/><br/><br/><br/><br/><br/><br/>
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
<h4>Produced by %(app)s</h4>
|
top = max(int((COVER_HEIGHT - height)/2.), 0)
|
||||||
</div>
|
img.paste(logo, (left, top))
|
||||||
</div>
|
img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE)
|
||||||
</body>
|
|
||||||
</html>
|
img.convert('RGB').save(cover_file, 'JPEG')
|
||||||
'''%dict(title=self.title if isinstance(self.title, unicode) else self.title.decode(preferred_encoding, 'replace'),
|
|
||||||
author=self.__author__ if isinstance(self.__author__, unicode) else self.__author__.decode(preferred_encoding, 'replace'),
|
|
||||||
date=strftime(self.timefmt),
|
|
||||||
app=__appname__ +' '+__version__,
|
|
||||||
img=img)
|
|
||||||
hf = os.path.join(tdir, 'cover.htm')
|
|
||||||
with open(hf, 'wb') as f:
|
|
||||||
f.write(html.encode('utf-8'))
|
|
||||||
renderer = render_html(hf)
|
|
||||||
if renderer.tb is not None:
|
|
||||||
self.log.warning('Failed to render default cover')
|
|
||||||
self.log.debug(renderer.tb)
|
|
||||||
else:
|
|
||||||
cover_file.write(renderer.data)
|
|
||||||
cover_file.flush()
|
cover_file.flush()
|
||||||
|
except:
|
||||||
|
self.log.exception('Failed to generate default cover')
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_masthead_title(self):
|
def get_masthead_title(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user