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

View File

@ -7,12 +7,17 @@ Defines various abstract base classes that can be subclassed to create powerful
__docformat__ = "restructuredtext en" __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 collections import defaultdict
from functools import partial from functools import partial
from contextlib import nested, closing 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.BeautifulSoup import BeautifulSoup, NavigableString, CData, Tag
from calibre.ebooks.metadata.opf import OPFCreator from calibre.ebooks.metadata.opf import OPFCreator
from calibre.ebooks.lrf import entity_to_unicode from calibre.ebooks.lrf import entity_to_unicode
@ -23,6 +28,7 @@ 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
from calibre.gui2 import images_rc # Needed for default cover
class BasicNewsRecipe(object, LoggingInterface): class BasicNewsRecipe(object, LoggingInterface):
@ -766,6 +772,89 @@ class BasicNewsRecipe(object, LoggingInterface):
self.cover_path = cpath 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): def create_opf(self, feeds, dir=None):
if dir is None: if dir is None:
dir = self.output_dir dir = self.output_dir
@ -778,7 +867,11 @@ class BasicNewsRecipe(object, LoggingInterface):
manifest = [os.path.join(dir, 'feed_%d'%i) for i in range(len(feeds))] manifest = [os.path.join(dir, 'feed_%d'%i) for i in range(len(feeds))]
manifest.append(os.path.join(dir, 'index.html')) 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): if cpath is not None and os.access(cpath, os.R_OK):
opf.cover = cpath opf.cover = cpath
manifest.append(cpath) manifest.append(cpath)

View File

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