Initial attempt at getting PDF.js to work with separate downloads
This commit is contained in:
parent
8f1690eff7
commit
df67c254f8
@ -32,10 +32,11 @@ import enum
|
||||
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QObject, QModelIndex,
|
||||
QTimer, QAbstractListModel, QUrl)
|
||||
|
||||
from qutebrowser.browser import pdfjs
|
||||
from qutebrowser.commands import cmdexc, cmdutils
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import (usertypes, standarddir, utils, message, log,
|
||||
qtutils)
|
||||
qtutils, objreg)
|
||||
from qutebrowser.qt import sip
|
||||
|
||||
|
||||
@ -224,9 +225,6 @@ class _DownloadTarget:
|
||||
|
||||
"""Abstract base class for different download targets."""
|
||||
|
||||
def __init__(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def suggested_filename(self):
|
||||
"""Get the suggested filename for this download target."""
|
||||
raise NotImplementedError
|
||||
@ -300,6 +298,17 @@ class OpenFileDownloadTarget(_DownloadTarget):
|
||||
return 'temporary file'
|
||||
|
||||
|
||||
class PDFJSDownloadTarget(_DownloadTarget):
|
||||
|
||||
"""Open the download via PDF.js."""
|
||||
|
||||
def suggested_filename(self):
|
||||
raise NoFilenameError
|
||||
|
||||
def __str__(self):
|
||||
return 'temporary PDF.js file'
|
||||
|
||||
|
||||
class DownloadItemStats(QObject):
|
||||
|
||||
"""Statistics (bytes done, total bytes, time, etc.) about a download.
|
||||
@ -405,6 +414,8 @@ class AbstractDownloadItem(QObject):
|
||||
arg: The error message as string.
|
||||
remove_requested: Emitted when the removal of this download was
|
||||
requested.
|
||||
pdfjs_requested: Emitted when PDF.js should be opened with the given
|
||||
filename.
|
||||
"""
|
||||
|
||||
data_changed = pyqtSignal()
|
||||
@ -412,6 +423,7 @@ class AbstractDownloadItem(QObject):
|
||||
error = pyqtSignal(str)
|
||||
cancelled = pyqtSignal()
|
||||
remove_requested = pyqtSignal()
|
||||
pdfjs_requested = pyqtSignal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
@ -730,6 +742,19 @@ class AbstractDownloadItem(QObject):
|
||||
return
|
||||
self.open_file(cmdline)
|
||||
|
||||
def _pdfjs_if_successful(self):
|
||||
"""Open the file via PDF.js if downloading was successful."""
|
||||
if not self.successful:
|
||||
log.downloads.debug("{} finished but not successful, not opening!"
|
||||
.format(self))
|
||||
return
|
||||
|
||||
filename = self._get_open_filename()
|
||||
if filename is None: # pragma: no cover
|
||||
log.downloads.error("No filename to open the download!")
|
||||
return
|
||||
self.pdfjs_requested.emit(filename)
|
||||
|
||||
def set_target(self, target):
|
||||
"""Set the target for a given download.
|
||||
|
||||
@ -741,7 +766,7 @@ class AbstractDownloadItem(QObject):
|
||||
elif isinstance(target, FileDownloadTarget):
|
||||
self._set_filename(
|
||||
target.filename, force_overwrite=target.force_overwrite)
|
||||
elif isinstance(target, OpenFileDownloadTarget):
|
||||
elif isinstance(target, (OpenFileDownloadTarget, PDFJSDownloadTarget)):
|
||||
try:
|
||||
fobj = temp_download_manager.get_tmpfile(self.basename)
|
||||
except OSError as exc:
|
||||
@ -749,8 +774,15 @@ class AbstractDownloadItem(QObject):
|
||||
message.error(msg)
|
||||
self.cancel()
|
||||
return
|
||||
self.finished.connect(
|
||||
functools.partial(self._open_if_successful, target.cmdline))
|
||||
|
||||
if isinstance(target, OpenFileDownloadTarget):
|
||||
self.finished.connect(
|
||||
functools.partial(self._open_if_successful, target.cmdline))
|
||||
elif isinstance(target, PDFJSDownloadTarget):
|
||||
self.finished.connect(self._pdfjs_if_successful)
|
||||
else:
|
||||
assert False, target
|
||||
|
||||
self._set_tempfile(fobj)
|
||||
else: # pragma: no cover
|
||||
raise ValueError("Unsupported download target: {}".format(target))
|
||||
@ -797,6 +829,13 @@ class AbstractDownloadManager(QObject):
|
||||
dl.stats.update_speed()
|
||||
self.data_changed.emit(-1)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _on_pdfjs_requested(self, filename):
|
||||
"""Open PDF.js when a download requests it."""
|
||||
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
||||
window='last-focused')
|
||||
tabbed_browser.tabopen(pdfjs.get_main_url(filename))
|
||||
|
||||
def _init_item(self, download, auto_remove, suggested_filename):
|
||||
"""Initialize a newly created DownloadItem."""
|
||||
download.cancelled.connect(download.remove)
|
||||
@ -813,6 +852,8 @@ class AbstractDownloadManager(QObject):
|
||||
download.data_changed.connect(
|
||||
functools.partial(self._on_data_changed, download))
|
||||
download.error.connect(self._on_error)
|
||||
download.pdfjs_requested.connect(self._on_pdfjs_requested)
|
||||
|
||||
download.basename = suggested_filename
|
||||
idx = len(self.downloads)
|
||||
download.index = idx + 1 # "Human readable" index
|
||||
|
@ -22,9 +22,10 @@
|
||||
|
||||
import os
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtCore import QUrl, QUrlQuery
|
||||
|
||||
from qutebrowser.utils import utils, javascript, jinja
|
||||
from qutebrowser.config import config
|
||||
|
||||
|
||||
class PDFJSNotFound(Exception):
|
||||
@ -210,3 +211,17 @@ def is_available():
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def should_use_pdfjs(mimetype):
|
||||
return (mimetype in ['application/pdf', 'application/x-pdf'] and
|
||||
config.val.content.pdfjs)
|
||||
|
||||
|
||||
def get_main_url(filename):
|
||||
"""Get the URL to be opened to view a local PDF."""
|
||||
url = QUrl('qute://pdfjs')
|
||||
query = QUrlQuery()
|
||||
query.addQueryItem('file', QUrl.fromLocalFile(filename).toString())
|
||||
url.setQuery(query)
|
||||
return url
|
||||
|
@ -523,6 +523,11 @@ def qute_pastebin_version(_url):
|
||||
@add_handler('pdfjs')
|
||||
def qute_pdfjs(url):
|
||||
"""Handler for qute://pdfjs. Return the pdf.js viewer."""
|
||||
if url.path() == '/':
|
||||
filepath = QUrlQuery(url).queryItemValue("file")
|
||||
data = pdfjs.generate_pdfjs_page(QUrl.fromLocalFile(filepath))
|
||||
return 'text/html', data
|
||||
|
||||
try:
|
||||
data = pdfjs.get_pdfjs_res(url.path())
|
||||
except pdfjs.PDFJSNotFound as e:
|
||||
@ -534,5 +539,6 @@ def qute_pdfjs(url):
|
||||
raise NotFoundError("Can't find pdfjs resource '{}'".format(e.path))
|
||||
else:
|
||||
mimetype, _encoding = mimetypes.guess_type(url.fileName())
|
||||
assert mimetype is not None, url
|
||||
if mimetype is None:
|
||||
mimetype = 'application/octet-stream'
|
||||
return mimetype, data
|
||||
|
@ -30,7 +30,7 @@ from PyQt5.QtPrintSupport import QPrintDialog
|
||||
from PyQt5.QtWebKitWidgets import QWebPage, QWebFrame
|
||||
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.browser import pdfjs, shared
|
||||
from qutebrowser.browser import pdfjs, shared, downloads
|
||||
from qutebrowser.browser.webkit import http
|
||||
from qutebrowser.browser.webkit.network import networkmanager
|
||||
from qutebrowser.utils import message, usertypes, log, jinja, objreg
|
||||
@ -275,10 +275,9 @@ class BrowserPage(QWebPage):
|
||||
else:
|
||||
reply.finished.connect(functools.partial(
|
||||
self.display_content, reply, 'image/jpeg'))
|
||||
elif (mimetype in ['application/pdf', 'application/x-pdf'] and
|
||||
config.val.content.pdfjs):
|
||||
# Use pdf.js to display the page
|
||||
self._show_pdfjs(reply)
|
||||
elif pdfjs.should_use_pdfjs(mimetype):
|
||||
download_manager.fetch(reply,
|
||||
target=downloads.PDFJSDownloadTarget())
|
||||
else:
|
||||
# Unknown mimetype, so download anyways.
|
||||
download_manager.fetch(reply,
|
||||
|
Loading…
Reference in New Issue
Block a user