From 6342febb4410f84b4f8df8afc260be8d5356309b Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Mon, 1 Feb 2016 16:43:20 +0100 Subject: [PATCH 1/4] pdfjs: Update documentation The-Compiler made an AUR package for pdfjs so we should mention it in the SYSTEM_PDFJS_PATHS, even though it uses the same path as the Debian package. --- qutebrowser/browser/pdfjs.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/qutebrowser/browser/pdfjs.py b/qutebrowser/browser/pdfjs.py index 83b89330c..337464bce 100644 --- a/qutebrowser/browser/pdfjs.py +++ b/qutebrowser/browser/pdfjs.py @@ -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,9 +90,13 @@ 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/'), ] From 449a54c7d0ca9475f38080b3134f01d360dadc67 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Mon, 1 Feb 2016 17:28:18 +0100 Subject: [PATCH 2/4] pdfjs: add file path to version information Shows "bundled" if the bundled version is used. --- qutebrowser/browser/pdfjs.py | 35 ++++++++++++++++++++++++-------- qutebrowser/utils/version.py | 10 ++++++--- tests/unit/utils/test_version.py | 16 ++++++++------- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/qutebrowser/browser/pdfjs.py b/qutebrowser/browser/pdfjs.py index 337464bce..b38d6edd1 100644 --- a/qutebrowser/browser/pdfjs.py +++ b/qutebrowser/browser/pdfjs.py @@ -100,21 +100,26 @@ SYSTEM_PDFJS_PATHS = [ ] -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 @@ -130,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): @@ -151,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. @@ -162,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(): diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index e96be6131..e2ca84fe2 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -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): diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index f8c1a88e3..14d819464 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -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: From 63f0171d30fe391942acba084fe0acdc2437ced2 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Mon, 1 Feb 2016 17:46:16 +0100 Subject: [PATCH 3/4] update_3rdparty: add option for pdfjs version This way we can instruct update_3rdparty to download a specific version of pdfjs, e.g. to make debugging easier or to match the version of a system package. Syntax: update_3rdparty.py -p 1.2.109 or update_3rdparty.py --pdfjs=1.2.109 If the command line argument is not given, the script will automatically download the latest release. --- scripts/dev/update_3rdparty.py | 42 ++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/scripts/dev/update_3rdparty.py b/scripts/dev/update_3rdparty.py index 6db01bc11..f53135a99 100755 --- a/scripts/dev/update_3rdparty.py +++ b/scripts/dev/update_3rdparty.py @@ -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,15 @@ def update_pdfjs(): def main(): - update_pdfjs() + 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() From 90e88ce0d0de0a4177d4159d7c49887f99f620f2 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Mon, 1 Feb 2016 18:14:24 +0100 Subject: [PATCH 4/4] update_3rdparty: add docstring to main() --- scripts/dev/update_3rdparty.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/dev/update_3rdparty.py b/scripts/dev/update_3rdparty.py index f53135a99..1455a7603 100755 --- a/scripts/dev/update_3rdparty.py +++ b/scripts/dev/update_3rdparty.py @@ -82,6 +82,7 @@ def update_pdfjs(target_version=None): def main(): + """Update 3rd party modules.""" parser = argparse.ArgumentParser() parser.add_argument( '--pdfjs', '-p',