Merge branch 'pdfjs' of https://github.com/Kingdread/qutebrowser into Kingdread-pdfjs

This commit is contained in:
Florian Bruhin 2016-02-01 20:07:56 +01:00
commit 7be296333a
4 changed files with 89 additions and 27 deletions

View File

@ -63,7 +63,7 @@ def _generate_pdfjs_script(url):
def fix_urls(asset):
"""Take a html page and replace each relative URL wth an absolute.
"""Take a html page and replace each relative URL with an absolute.
This is specialized for pdf.js files and not a general purpose function.
@ -90,27 +90,36 @@ def fix_urls(asset):
SYSTEM_PDFJS_PATHS = [
'/usr/share/pdf.js/', # Debian pdf.js-common
'/usr/share/javascript/pdf/', # Debian libjs-pdf
os.path.expanduser('~/.local/share/qutebrowser/pdfjs/'), # fallback
# Debian pdf.js-common
# Arch Linux pdfjs (AUR)
'/usr/share/pdf.js/',
# Debian libjs-pdf
'/usr/share/javascript/pdf/',
# fallback
os.path.expanduser('~/.local/share/qutebrowser/pdfjs/'),
]
def get_pdfjs_res(path):
def get_pdfjs_res_and_path(path):
"""Get a pdf.js resource in binary format.
Returns a (content, path) tuple, where content is the file content and path
is the path where the file was found. If path is None, the bundled version
was used.
Args:
path: The path inside the pdfjs directory.
"""
path = path.lstrip('/')
content = None
file_path = None
# First try a system wide installation
# System installations might strip off the 'build/' or 'web/' prefixes.
# qute expects them, so we need to adjust for it.
names_to_try = [path, _remove_prefix(path)]
for system_path in SYSTEM_PDFJS_PATHS:
content = _read_from_system(system_path, names_to_try)
content, file_path = _read_from_system(system_path, names_to_try)
if content is not None:
break
@ -126,9 +135,19 @@ def get_pdfjs_res(path):
# Might be script/html or might be binary
text_content = content.decode('utf-8')
except UnicodeDecodeError:
return content
return (content, file_path)
text_content = fix_urls(text_content)
return text_content.encode('utf-8')
return (text_content.encode('utf-8'), file_path)
def get_pdfjs_res(path):
"""Get a pdf.js resource in binary format.
Args:
path: The path inside the pdfjs directory.
"""
content, _path = get_pdfjs_res_and_path(path)
return content
def _remove_prefix(path):
@ -147,10 +166,13 @@ def _remove_prefix(path):
def _read_from_system(system_path, names):
"""Try to read a file with one of the given names in system_path.
Returns a (content, path) tuple, where the path is the filepath that was
used.
Each file in names is considered equal, the first file that is found
is read and its binary content returned.
Returns None if no file could be found
Returns (None, None) if no file could be found
Args:
system_path: The folder where the file should be searched.
@ -158,11 +180,12 @@ def _read_from_system(system_path, names):
"""
for name in names:
try:
with open(os.path.join(system_path, name), 'rb') as f:
return f.read()
full_path = os.path.join(system_path, name)
with open(full_path, 'rb') as f:
return (f.read(), full_path)
except OSError:
continue
return None
return (None, None)
def is_available():

View File

@ -192,16 +192,20 @@ def _pdfjs_version():
A string with the version number.
"""
try:
pdfjs_file = pdfjs.get_pdfjs_res('build/pdf.js').decode('utf-8')
pdfjs_file, file_path = pdfjs.get_pdfjs_res_and_path('build/pdf.js')
except pdfjs.PDFJSNotFound:
return 'no'
else:
pdfjs_file = pdfjs_file.decode('utf-8')
version_re = re.compile(r"^PDFJS\.version = '([^']+)';$", re.MULTILINE)
match = version_re.search(pdfjs_file)
if not match:
return 'unknown'
pdfjs_version = 'unknown'
else:
return match.group(1)
pdfjs_version = match.group(1)
if file_path is None:
file_path = 'bundled'
return '{} ({})'.format(pdfjs_version, file_path)
def version(short=False):

View File

@ -20,7 +20,9 @@
"""Update all third-party-modules."""
import argparse
import urllib.request
import urllib.error
import shutil
import json
import os
@ -41,12 +43,34 @@ def get_latest_pdfjs_url():
return (version_name, download_url)
def update_pdfjs():
"""Download and extract the latest pdf.js version."""
version, url = get_latest_pdfjs_url()
def update_pdfjs(target_version=None):
"""Download and extract the latest pdf.js version.
If target_version is not None, download the given version instead.
Args:
target_version: None or version string ('x.y.z')
"""
if target_version is None:
version, url = get_latest_pdfjs_url()
else:
# We need target_version as x.y.z, without the 'v' prefix, though the
# user might give it on the command line
if target_version.startswith('v'):
target_version = target_version[1:]
# version should have the prefix to be consistent with the return value
# of get_latest_pdfjs_url()
version = 'v' + target_version
url = ('https://github.com/mozilla/pdf.js/releases/download/'
'v{0}/pdfjs-{0}-dist.zip').format(target_version)
target_path = os.path.join('qutebrowser', '3rdparty', 'pdfjs')
print("=> Downloading pdf.js {}".format(version))
(archive_path, _headers) = urllib.request.urlretrieve(url)
try:
(archive_path, _headers) = urllib.request.urlretrieve(url)
except urllib.error.HTTPError as error:
print("Could not retrieve pdfjs {}: {}".format(version, error))
return
if os.path.isdir(target_path):
print("Removing old version in {}".format(target_path))
shutil.rmtree(target_path)
@ -58,7 +82,16 @@ def update_pdfjs():
def main():
update_pdfjs()
"""Update 3rd party modules."""
parser = argparse.ArgumentParser()
parser.add_argument(
'--pdfjs', '-p',
help='Specify pdfjs version. If not given, '
'the latest version is used.',
required=False, metavar='VERSION')
args = parser.parse_args()
update_pdfjs(args.pdfjs)
if __name__ == '__main__':
main()

View File

@ -535,14 +535,15 @@ class TestPDFJSVersion:
"""Tests for _pdfjs_version."""
def test_not_found(self, mocker):
mocker.patch('qutebrowser.utils.version.pdfjs.get_pdfjs_res',
mocker.patch('qutebrowser.utils.version.pdfjs.get_pdfjs_res_and_path',
side_effect=pdfjs.PDFJSNotFound)
assert version._pdfjs_version() == 'no'
def test_unknown(self, monkeypatch):
monkeypatch.setattr('qutebrowser.utils.version.pdfjs.get_pdfjs_res',
lambda path: b'foobar')
assert version._pdfjs_version() == 'unknown'
monkeypatch.setattr(
'qutebrowser.utils.version.pdfjs.get_pdfjs_res_and_path',
lambda path: (b'foobar', None))
assert version._pdfjs_version() == 'unknown (bundled)'
def test_known(self, monkeypatch):
pdfjs_code = textwrap.dedent("""
@ -558,9 +559,10 @@ class TestPDFJSVersion:
// Use strict in our context only - users might not want it
'use strict';
""").strip().encode('utf-8')
monkeypatch.setattr('qutebrowser.utils.version.pdfjs.get_pdfjs_res',
lambda path: pdfjs_code)
assert version._pdfjs_version() == '1.2.109'
monkeypatch.setattr(
'qutebrowser.utils.version.pdfjs.get_pdfjs_res_and_path',
lambda path: (pdfjs_code, '/foo/bar/pdf.js'))
assert version._pdfjs_version() == '1.2.109 (/foo/bar/pdf.js)'
class FakeQSslSocket: