Create a generic cover for news recipes that dont specify one

This commit is contained in:
Kovid Goyal 2008-12-09 18:10:41 -08:00
parent b6df865ffd
commit ec1b12b494
3 changed files with 99 additions and 5 deletions

View file

@ -20,6 +20,7 @@ def __init__(self, id, title, url, summary, published, content):
self.id = id
self.title = title.strip() if title else title
self.url = url
self.summary = summary
if summary and not isinstance(summary, unicode):
summary = summary.decode('utf-8', 'replace')
if summary and '<' in summary:
@ -31,7 +32,7 @@ def __init__(self, id, title, url, summary, published, content):
print summary.encode('utf-8')
traceback.print_exc()
summary = u''
self.summary = summary
self.text_summary = summary
self.content = content
self.date = published
self.utctime = datetime(*self.date[:6])

View file

@ -7,12 +7,17 @@
__docformat__ = "restructuredtext en"
import logging, os, cStringIO, time, traceback, re, urlparse, sys
import logging, os, cStringIO, time, traceback, re, urlparse, sys, tempfile, functools
from collections import defaultdict
from functools import partial
from contextlib import nested, closing
from calibre import browser, __appname__, iswindows, LoggingInterface, strftime
from PyQt4.Qt import QApplication, QFile, Qt, QPalette, QSize, QImage, QPainter, \
QBuffer, QByteArray, SIGNAL, QUrl, QEventLoop, QIODevice
from PyQt4.QtWebKit import QWebPage
from calibre import browser, __appname__, iswindows, LoggingInterface, strftime, __version__
from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString, CData, Tag
from calibre.ebooks.metadata.opf import OPFCreator
from calibre.ebooks.lrf import entity_to_unicode
@ -23,6 +28,7 @@
from calibre.web.fetch.simple import RecursiveFetcher
from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending
from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2 import images_rc # Needed for default cover
class BasicNewsRecipe(object, LoggingInterface):
@ -766,6 +772,89 @@ def download_cover(self):
self.cover_path = cpath
def default_cover(self, cover_file):
'''
Create a generic cover for recipes that dont have a cover
'''
if QApplication.instance() is None: QApplication([])
f = QFile(':/library')
f.open(QIODevice.ReadOnly)
img = str(f.readAll())
f.close()
f = tempfile.NamedTemporaryFile(suffix='library.png')
f.write(img)
f.flush()
img = f.name
html= u'''\
<html>
<head>
<style type="text/css">
body {
background: white no-repeat fixed center center;
text-align: center;
vertical-align: center;
overflow: hidden;
font-size: 18px;
}
h1 { font-family: serif; }
h2, h4 { font-family: monospace; }
</style>
</head>
<body>
<h1>%(title)s</h1>
<br/><br/>
<div style="position:relative">
<div style="position: absolute; left: 0; top: 0; width:100%%; height:100%%; vertical-align:center">
<img src="%(img)s" alt="calibre" style="opacity:0.3"/>
</div>
<div style="position: absolute; left: 0; top: 0; width:100%%; height:100%%; vertical-align:center">
<h2>%(date)s</h2>
<br/><br/><br/><br/><br/>
<h3>%(author)s</h3>
<br/><br/></br/><br/><br/><br/><br/><br/><br/>
<h4>Produced by %(app)s</h4>
</div>
</div>
</body>
</html>
'''%dict(title=self.title, author=self.__author__,
date=time.strftime(self.timefmt),
app=__appname__ +' '+__version__,
img=img)
f2 = tempfile.NamedTemporaryFile(suffix='cover.html')
f2.write(html)
f2.flush()
page = QWebPage()
pal = page.palette()
pal.setBrush(QPalette.Background, Qt.white)
page.setPalette(pal)
page.setViewportSize(QSize(590, 750))
page.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)
page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
loop = QEventLoop()
def render_html(page, loop, ok):
try:
image = QImage(page.viewportSize(), QImage.Format_ARGB32)
image.setDotsPerMeterX(96*(100/2.54))
image.setDotsPerMeterY(96*(100/2.54))
painter = QPainter(image)
page.mainFrame().render(painter)
painter.end()
ba = QByteArray()
buf = QBuffer(ba)
buf.open(QBuffer.WriteOnly)
image.save(buf, 'JPEG')
image_data = str(ba.data())
cover_file.write(image_data)
cover_file.flush()
finally:
loop.exit(0)
page.connect(page, SIGNAL('loadFinished(bool)'), functools.partial(render_html, page, loop))
page.mainFrame().load(QUrl.fromLocalFile(f2.name))
loop.exec_()
def create_opf(self, feeds, dir=None):
if dir is None:
dir = self.output_dir
@ -778,7 +867,11 @@ def create_opf(self, feeds, dir=None):
manifest = [os.path.join(dir, 'feed_%d'%i) for i in range(len(feeds))]
manifest.append(os.path.join(dir, 'index.html'))
cpath = getattr(self, 'cover_path', None)
cpath = getattr(self, 'cover_path', None)
if cpath is None:
pf = PersistentTemporaryFile('_recipe_cover.jpg')
self.default_cover(pf)
cpath = pf.name
if cpath is not None and os.access(cpath, os.R_OK):
opf.cover = cpath
manifest.append(cpath)

View file

@ -145,7 +145,7 @@ def __init__(self):
<a class="article" href="${article.url}">${article.title}</a>
<span class="article_date">${article.localtime.strftime(" [%a, %d %b %H:%M]")}</span>
<div class="article_decription" py:if="article.summary">
${Markup(cutoff(article.summary))}
${Markup(cutoff(article.text_summary))}
</div>
</li>
</py:for>