Fix cover fetching for The Atlantic and fix regressions in epub-meta and ebook-viewer

This commit is contained in:
Kovid Goyal 2008-10-17 14:49:48 -07:00
parent 894c1570db
commit 70a90c3b50
7 changed files with 3587 additions and 30 deletions

View File

@ -144,6 +144,7 @@ if __name__ == '__main__':
ncx_template = 'ebooks/metadata/ncx.xml', ncx_template = 'ebooks/metadata/ncx.xml',
fb2_xsl = 'ebooks/lrf/fb2/fb2.xsl', fb2_xsl = 'ebooks/lrf/fb2/fb2.xsl',
metadata_sqlite = 'library/metadata_sqlite.sql', metadata_sqlite = 'library/metadata_sqlite.sql',
jquery = 'gui2/viewer/jquery.js',
) )
DEST = os.path.join('src', APPNAME, 'resources.py') DEST = os.path.join('src', APPNAME, 'resources.py')

View File

@ -8,7 +8,6 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import sys, os, time import sys, os, time
from cStringIO import StringIO from cStringIO import StringIO
from contextlib import closing from contextlib import closing
from ctypes import c_long, byref
from PyQt4.Qt import QUrl, QEventLoop, QSize, QByteArray, QBuffer, \ from PyQt4.Qt import QUrl, QEventLoop, QSize, QByteArray, QBuffer, \
SIGNAL, QPainter, QImage, QObject, QApplication, Qt, QPalette SIGNAL, QPainter, QImage, QObject, QApplication, Qt, QPalette
@ -19,7 +18,7 @@ from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup
from calibre.ebooks.metadata import get_parser, MetaInformation from calibre.ebooks.metadata import get_parser, MetaInformation
from calibre.ebooks.metadata.opf2 import OPF from calibre.ebooks.metadata.opf2 import OPF
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre import CurrentDir from calibre import CurrentDir, fit_image
class EPubException(Exception): class EPubException(Exception):
pass pass
@ -120,11 +119,11 @@ class CoverRenderer(QObject):
def render_html(self, ok): def render_html(self, ok):
self.rendered = True self.rendered = True
try: try:
from calibre.utils.PythonMagickWand import ImageMagick, NewMagickWand, MagickGetImageBlob, \
MagickReadImageBlob, MagickTrimImage, MagickSetFormat
if not ok: if not ok:
return return
self.page.setViewportSize(QSize(1280, 1024)) size = self.page.mainFrame().contentsSize()
width, height = fit_image(size.width(), size.height(), 1280, 1024)[1:]
self.page.setViewportSize(QSize(width, height))
image = QImage(self.page.viewportSize(), QImage.Format_ARGB32) image = QImage(self.page.viewportSize(), QImage.Format_ARGB32)
image.setDotsPerMeterX(96*(100/2.54)) image.setDotsPerMeterX(96*(100/2.54))
image.setDotsPerMeterY(96*(100/2.54)) image.setDotsPerMeterY(96*(100/2.54))
@ -136,21 +135,7 @@ class CoverRenderer(QObject):
buf = QBuffer(ba) buf = QBuffer(ba)
buf.open(QBuffer.WriteOnly) buf.open(QBuffer.WriteOnly)
image.save(buf, 'JPEG') image.save(buf, 'JPEG')
raw = str(ba.data()) self.image_data = str(ba.data())
with ImageMagick():
wand = NewMagickWand()
if not MagickReadImageBlob(wand, raw, len(raw)):
raise ValueError('Failed to load cover image')
if not MagickTrimImage(wand, 10.):
raise ValueError('Failed to process cover image')
x = c_long(0)
if not MagickSetFormat(wand, 'JPEG'):
raise Exception()
dat = MagickGetImageBlob(wand, byref(x))
obuf = StringIO()
for i in xrange(x.value):
obuf.write(chr(dat[i]))
self.image_data = obuf.getvalue()
finally: finally:
self.loop.exit(0) self.loop.exit(0)

View File

@ -14,6 +14,7 @@ from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings
from calibre.utils.config import Config, StringConfig from calibre.utils.config import Config, StringConfig
from calibre.gui2.viewer.config_ui import Ui_Dialog from calibre.gui2.viewer.config_ui import Ui_Dialog
def load_builtin_fonts(): def load_builtin_fonts():
from calibre.ebooks.lrf.fonts.liberation import LiberationMono_BoldItalic from calibre.ebooks.lrf.fonts.liberation import LiberationMono_BoldItalic
QFontDatabase.addApplicationFontFromData(QByteArray(LiberationMono_BoldItalic.font_data)) QFontDatabase.addApplicationFontFromData(QByteArray(LiberationMono_BoldItalic.font_data))
@ -128,6 +129,14 @@ class Document(QWebPage):
# Miscellaneous # Miscellaneous
settings.setAttribute(QWebSettings.LinksIncludedInFocusChain, True) settings.setAttribute(QWebSettings.LinksIncludedInFocusChain, True)
# Load jQuery
self.connect(self.mainFrame(), SIGNAL('javaScriptWindowObjectCleared()'),
self.load_javascript_libraries)
def load_javascript_libraries(self):
from calibre.resources import jquery
self.javascript(jquery)
def javascript(self, string, typ=None): def javascript(self, string, typ=None):
ans = self.mainFrame().evaluateJavaScript(string) ans = self.mainFrame().evaluateJavaScript(string)
if typ == 'int': if typ == 'int':
@ -259,7 +268,7 @@ class DocumentView(QWebView):
self.connect(self.scrollbar, SIGNAL('valueChanged(int)'), self.scroll_horizontally) self.connect(self.scrollbar, SIGNAL('valueChanged(int)'), self.scroll_horizontally)
def scroll_horizontally(self, amount): def scroll_horizontally(self, amount):
self.document.scroll_to(x=amount) self.document.scroll_to(y=self.document.ypos, x=amount)
def link_hovered(self, link, text, context): def link_hovered(self, link, text, context):
link, text = unicode(link), unicode(text) link, text = unicode(link), unicode(text)
@ -340,6 +349,7 @@ class DocumentView(QWebView):
if scrolled: if scrolled:
self.manager.scrolled(self.document.scroll_fraction) self.manager.scrolled(self.document.scroll_fraction)
@classmethod @classmethod
def test_line(cls, img, y): def test_line(cls, img, y):
start = img.pixel(0, y) start = img.pixel(0, y)

3549
src/calibre/gui2/viewer/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -363,9 +363,15 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.view.load_path(path, pos=pos) self.view.load_path(path, pos=pos)
def viewport_resized(self, frac): def viewport_resized(self, frac):
pos = self.pos.value() new_page = self.pos.value()
self.view.scroll_to(pos, notify=False) if self.current_page is not None:
#self.set_page_number(frac) try:
frac = float(new_page-self.current_page.start_page)/(self.current_page.pages-1)
except ZeroDivisionError:
frac = 0
self.view.scroll_to(frac, notify=False)
else:
self.set_page_number(frac)
def close_progress_indicator(self): def close_progress_indicator(self):
self.pi.stop() self.pi.stop()

View File

@ -79,6 +79,9 @@ class BasicNewsRecipe(object, LoggingInterface):
#: If True stylesheets are not downloaded and processed #: If True stylesheets are not downloaded and processed
no_stylesheets = False no_stylesheets = False
#: Convenient flag to strip all javascripts tags from the downloaded HTML
remove_javascript = True
#: If True the GUI will ask the user for a username and password #: If True the GUI will ask the user for a username and password
#: to use while downloading #: to use while downloading
#: @type: boolean #: @type: boolean
@ -485,6 +488,9 @@ class BasicNewsRecipe(object, LoggingInterface):
if self.no_stylesheets: if self.no_stylesheets:
for link in list(soup.findAll('link', type=re.compile('css'))): for link in list(soup.findAll('link', type=re.compile('css'))):
link.extract() link.extract()
if self.remove_javascript:
for script in list(soup.findAll('script')):
script.extract()
return self.postprocess_html(soup, first_fetch) return self.postprocess_html(soup, first_fetch)

View File

@ -5,7 +5,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
''' '''
theatlantic.com theatlantic.com
''' '''
import re
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
class TheAtlantic(BasicNewsRecipe): class TheAtlantic(BasicNewsRecipe):
@ -28,7 +28,7 @@ class TheAtlantic(BasicNewsRecipe):
if issue: if issue:
self.timefmt = ' [%s]'%self.tag_to_string(issue).rpartition('|')[-1].strip().replace('/', '-') self.timefmt = ' [%s]'%self.tag_to_string(issue).rpartition('|')[-1].strip().replace('/', '-')
cover = soup.find('img', alt='feature image', src=True) cover = soup.find('img', alt=re.compile('Cover'), src=True)
if cover is not None: if cover is not None:
self.cover_url = 'http://theatlantic.com'+cover['src'] self.cover_url = 'http://theatlantic.com'+cover['src']