From 6ebb37aa17c9e0c95a7596aa4d4bca5808e033bc Mon Sep 17 00:00:00 2001 From: Lamar Pavel Date: Tue, 20 Oct 2015 02:52:11 +0200 Subject: [PATCH 001/103] Update UA list and add script to fetch UAs The script is based on a gist posted by @averrin and has been modified to print the output according to the format expected by qutebrowser, ready to be pasted into configtypes.py. --- qutebrowser/config/configtypes.py | 75 ++++++++++++++++--------------- scripts/ua_fetch.py | 20 +++++++++ 2 files changed, 59 insertions(+), 36 deletions(-) create mode 100644 scripts/ua_fetch.py diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 86e500f1e..698a289b7 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1558,49 +1558,52 @@ class UserAgent(BaseType): def validate(self, value): self._basic_validation(value) + # To update the following list of user agents, run the script 'ua_fetch.py'. + # Vim-protip: Place your cursor below this comment and run + # :r!python scripts/ua_fetch.py def complete(self): """Complete a list of common user agents.""" out = [ - ('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 ' - 'Firefox/35.0', - "Firefox 35.0 Win7 64-bit"), - ('Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 ' - 'Firefox/35.0', - "Firefox 35.0 Ubuntu"), - ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:35.0) ' - 'Gecko/20100101 Firefox/35.0', - "Firefox 35.0 MacOSX"), - - ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) ' - 'AppleWebKit/600.3.18 (KHTML, like Gecko) Version/8.0.3 ' - 'Safari/600.3.18', - "Safari 8.0 MacOSX"), - ('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, ' - 'like Gecko) Chrome/40.0.2214.111 Safari/537.36', - "Chrome 40.0 Win7 64-bit"), - ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) ' - 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 ' + 'like Gecko) Chrome/45.0.2454.101 Safari/537.36', + "Chrome 45.0 Win7 64-bit"), + ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) ' + 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 ' 'Safari/537.36', - "Chrome 40.0 MacOSX"), - ('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 ' - '(KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36', - "Chrome 40.0 Linux"), - + "Chrome 45.0 MacOSX"), + ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) ' + 'AppleWebKit/600.8.9 (KHTML, like Gecko) Version/8.0.8 ' + 'Safari/600.8.9', + "Safari 8.0 MacOSX"), + ('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, ' + 'like Gecko) Chrome/45.0.2454.101 Safari/537.36', + "Chrome 45.0 Win10 64-bit"), + ('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 ' + 'Firefox/41.0', + "Firefox 41.0 Win7 64-bit"), + ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11) ' + 'AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 ' + 'Safari/601.1.56', + "Safari Generic MacOSX"), + ('Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, ' + 'like Gecko) Chrome/45.0.2454.101 Safari/537.36', + "Chrome 45.0 Win8.1 64-bit"), + ('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 ' + 'Firefox/40.0', + "Firefox 40.0 Win7 64-bit"), ('Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like ' 'Gecko', - "IE 11.0 Win7 64-bit"), - - ('Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) ' - 'AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 ' - 'Mobile/12B440 Safari/600.1.4', - "Mobile Safari 8.0 iOS"), - ('Mozilla/5.0 (Android; Mobile; rv:35.0) Gecko/35.0 Firefox/35.0', - "Firefox 35, Android"), - ('Mozilla/5.0 (Linux; Android 5.0.2; One Build/KTU84L.H4) ' - 'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 ' - 'Chrome/37.0.0.0 Mobile Safari/537.36', - "Android Browser"), + "IE 11.0 for Desktop Win7 64-bit"), + ('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, ' + 'like Gecko) Chrome/45.0.2454.93 Safari/537.36', + "Chrome 45.0 Win7 64-bit"), + ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) ' + 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 ' + 'Safari/537.36', + "Chrome 45.0 MacOSX"), + ('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, ' + 'like Gecko) Chrome/45.0.2454.99 Safari/537.36', + "Chrome 45.0 Win7 64-bit"), ('Mozilla/5.0 (compatible; Googlebot/2.1; ' '+http://www.google.com/bot.html', diff --git a/scripts/ua_fetch.py b/scripts/ua_fetch.py new file mode 100644 index 000000000..a9e39b40a --- /dev/null +++ b/scripts/ua_fetch.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +import requests +from lxml import html + +url = 'https://techblog.willshouse.com/2012/01/03/most-common-user-agents/' +page = requests.get(url) +page = html.fromstring(page.text) +path = '//*[@id="post-2229"]/div[2]/table/tbody' +table = page.xpath(path)[0] + +indent = " " +print("%sdef complete(self):" % indent) +print("%s\"\"\"Complete a list of common user agents.\"\"\"" % (2 * indent)) +print("%sout = [" % (2 * indent)) +for row in table[:12]: + ua = row[1].text_content() + browser = row[2].text_content() + print("%s(\'%s\',\n%s \"%s\")," % (3 * indent, ua, 3 * indent, browser)) +print("%s]\n%sreturn out\n" % (2 * indent, 2 * indent)) From 332df99a7725cb97018bb4baadcda5645f4f3f5c Mon Sep 17 00:00:00 2001 From: Lamar Pavel Date: Tue, 20 Oct 2015 03:28:27 +0200 Subject: [PATCH 002/103] Add docstring to new script --- scripts/ua_fetch.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/ua_fetch.py b/scripts/ua_fetch.py index a9e39b40a..9f3ab785e 100644 --- a/scripts/ua_fetch.py +++ b/scripts/ua_fetch.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +"""Fetch list of popular user-agents. + +The script is based on a gist posted by github.com/averrin, the ouput of this +script is formatted to be pasted into configtypes.py. +""" import requests from lxml import html From 71a150af225a6b970b011e2dfb9092340e3dcfda Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 20 Oct 2015 06:54:43 +0200 Subject: [PATCH 003/103] Refactor asciidoc2html.py. --- scripts/asciidoc2html.py | 176 ++++++++++++++++++++++----------------- 1 file changed, 100 insertions(+), 76 deletions(-) diff --git a/scripts/asciidoc2html.py b/scripts/asciidoc2html.py index 707a780c9..a94a3b910 100755 --- a/scripts/asciidoc2html.py +++ b/scripts/asciidoc2html.py @@ -32,86 +32,47 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir)) from scripts import utils -def _get_asciidoc_cmd(args): - """Try to find out what commandline to use to invoke asciidoc.""" - if args.asciidoc is not None: - return args.asciidoc +class AsciiDoc: - try: - subprocess.call(['asciidoc'], stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL) - except OSError: - pass - else: - return ['asciidoc'] + """Abstraction of an asciidoc subprocess.""" - try: - subprocess.call(['asciidoc.py'], stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL) - except OSError: - pass - else: - return ['asciidoc.py'] - - raise FileNotFoundError - - -def call_asciidoc(args, src, dst): - """Call asciidoc for the given files. - - Args: - args: The asciidoc binary to use, as a list. - src: The source .asciidoc file. - dst: The destination .html file, or None to auto-guess. - """ - print("Calling asciidoc for {}...".format(os.path.basename(src))) - args = args[:] - if dst is not None: - args += ['--out-file', dst] - args.append(src) - try: - subprocess.check_call(args) - except (subprocess.CalledProcessError, OSError) as e: - utils.print_col(str(e), 'red') - sys.exit(1) - - -def main(colors=False): - """Generate html files for the online documentation.""" - utils.change_cwd() - utils.use_color = colors - parser = argparse.ArgumentParser() - parser.add_argument('--all', help="Build all documentation into a given " - "directory.", nargs=1) - parser.add_argument('--asciidoc', help="Full path to python and " - "asciidoc.py. If not given, it's searched in PATH.", - nargs=2, required=False, - metavar=('PYTHON', 'ASCIIDOC')) - args = parser.parse_args() - asciidoc_files = [ + FILES = [ ('FAQ.asciidoc', 'qutebrowser/html/doc/FAQ.html'), ('CHANGELOG.asciidoc', 'qutebrowser/html/doc/CHANGELOG.html'), ('doc/quickstart.asciidoc', 'qutebrowser/html/doc/quickstart.html'), ('doc/userscripts.asciidoc', 'qutebrowser/html/doc/userscripts.html'), ] - try: - os.mkdir('qutebrowser/html/doc') - except FileExistsError: - pass - try: - asciidoc = _get_asciidoc_cmd(args) - except FileNotFoundError: - utils.print_col("Could not find asciidoc! Please install it, or use " - "the --asciidoc argument to point this script to the " - "correct python/asciidoc.py location!", 'red') - sys.exit(1) - if args.all: + + def __init__(self, args): + self._cmd = None + self._args = args + + def prepare(self): + """Get the asciidoc command and create the homedir to use.""" + self._cmd = self._get_asciidoc_cmd() + + def build(self): + if self._args.website: + self._build_website() + else: + self._build_docs() + + def _build_docs(self): + files = self.FILES[:] + for src in glob.glob('doc/help/*.asciidoc'): + name, _ext = os.path.splitext(os.path.basename(src)) + dst = 'qutebrowser/html/doc/{}.html'.format(name) + files.append((src, dst)) + for src, dst in files: + self.call(src, dst) + + def _build_website(self): for root, _dirs, files in os.walk(os.getcwd()): for filename in files: if os.path.splitext(filename)[1] != '.asciidoc': continue src = os.path.join(root, filename) - parts = [args.all[0]] + parts = [self._args.all[0]] dirname = os.path.dirname(src) if dirname: parts.append(os.path.relpath(os.path.dirname(src))) @@ -120,14 +81,77 @@ def main(colors=False): 'html'))) dst = os.path.join(*parts) os.makedirs(os.path.dirname(dst), exist_ok=True) - call_asciidoc(asciidoc, src, dst) - else: - for src in glob.glob('doc/help/*.asciidoc'): - name, _ext = os.path.splitext(os.path.basename(src)) - dst = 'qutebrowser/html/doc/{}.html'.format(name) - asciidoc_files.append((src, dst)) - for src, dst in asciidoc_files: - call_asciidoc(asciidoc, src, dst) + self.call(src, dst) + + def _get_asciidoc_cmd(self): + """Try to find out what commandline to use to invoke asciidoc.""" + if self._args.asciidoc is not None: + return self._args.asciidoc + + try: + subprocess.call(['asciidoc'], stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + except OSError: + pass + else: + return ['asciidoc'] + + try: + subprocess.call(['asciidoc.py'], stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + except OSError: + pass + else: + return ['asciidoc.py'] + + raise FileNotFoundError + + def call(self, src, dst, theme=None): + """Call asciidoc for the given files. + + Args: + src: The source .asciidoc file. + dst: The destination .html file, or None to auto-guess. + theme: The CSS to use as a theme. + """ + print("Calling asciidoc for {}...".format(os.path.basename(src))) + args = self._cmd[:] + if dst is not None: + args += ['--out-file', dst] + args.append(src) + try: + subprocess.check_call(args) + except (subprocess.CalledProcessError, OSError) as e: + utils.print_col(str(e), 'red') + sys.exit(1) + + +def main(colors=False): + """Generate html files for the online documentation.""" + utils.change_cwd() + utils.use_color = colors + parser = argparse.ArgumentParser() + parser.add_argument('--website', help="Build website into a given " + "directory.", nargs=1) + parser.add_argument('--asciidoc', help="Full path to python and " + "asciidoc.py. If not given, it's searched in PATH.", + nargs=2, required=False, + metavar=('PYTHON', 'ASCIIDOC')) + args = parser.parse_args() + try: + os.mkdir('qutebrowser/html/doc') + except FileExistsError: + pass + + asciidoc = AsciiDoc(args) + try: + asciidoc.prepare() + except FileNotFoundError: + utils.print_col("Could not find asciidoc! Please install it, or use " + "the --asciidoc argument to point this script to the " + "correct python/asciidoc.py location!", 'red') + sys.exit(1) + asciidoc.build() if __name__ == '__main__': From 7703fa217b051df93a15690c8d8f8ed95ddaec18 Mon Sep 17 00:00:00 2001 From: Lamar Pavel Date: Tue, 20 Oct 2015 17:28:22 +0200 Subject: [PATCH 004/103] Add some UAs manually for diversity The automatically fetched list includes popular user-agents but does not guarantee any kind of diversity, so there are now a few statically printed UAs from mobile browsers. --- qutebrowser/config/configtypes.py | 2 +- scripts/dev/ua_fetch.py | 61 +++++++++++++++++++++++++++++++ scripts/ua_fetch.py | 27 -------------- 3 files changed, 62 insertions(+), 28 deletions(-) create mode 100644 scripts/dev/ua_fetch.py delete mode 100644 scripts/ua_fetch.py diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 698a289b7..0c3d9dde2 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1560,7 +1560,7 @@ class UserAgent(BaseType): # To update the following list of user agents, run the script 'ua_fetch.py'. # Vim-protip: Place your cursor below this comment and run - # :r!python scripts/ua_fetch.py + # :r!python scripts/dev/ua_fetch.py def complete(self): """Complete a list of common user agents.""" out = [ diff --git a/scripts/dev/ua_fetch.py b/scripts/dev/ua_fetch.py new file mode 100644 index 000000000..26aba6d10 --- /dev/null +++ b/scripts/dev/ua_fetch.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2015 lamarpavel +# Copyright 2015 Alexey Nabrodov (Averrin) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + + +"""Fetch list of popular user-agents. + +The script is based on a gist posted by github.com/averrin, the ouput of this +script is formatted to be pasted into configtypes.py. +""" + +import requests +from lxml import html # pylint: disable=import-error + +# Fetch list of popular user-agents and store the relevant strings +url = 'https://techblog.willshouse.com/2012/01/03/most-common-user-agents/' +page = requests.get(url) +page = html.fromstring(page.text) +path = '//*[@id="post-2229"]/div[2]/table/tbody' +table = page.xpath(path)[0] +indent = " " + +# Print function defition followed by an automatically fetched list of popular +# user agents and a few additional entries for diversity. +print("%sdef complete(self):" % indent) +print("%s\"\"\"Complete a list of common user agents.\"\"\"" % (2 * indent)) +print("%sout = [" % (2 * indent)) +for row in table[:12]: + ua = row[1].text_content() + browser = row[2].text_content() + print("%s(\'%s\',\n%s \"%s\")," % (3 * indent, ua, 3 * indent, browser)) +print(""" + ('Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) ' + 'AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 ' + 'Mobile/12B440 Safari/600.1.4', + "Mobile Safari 8.0 iOS"), + ('Mozilla/5.0 (Android; Mobile; rv:35.0) Gecko/35.0 Firefox/35.0', + "Firefox 35, Android"), + ('Mozilla/5.0 (Linux; Android 5.0.2; One Build/KTU84L.H4) ' + 'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 ' + 'Chrome/37.0.0.0 Mobile Safari/537.36', + "Android Browser") +""") +print("%s]\n%sreturn out\n" % (2 * indent, 2 * indent)) diff --git a/scripts/ua_fetch.py b/scripts/ua_fetch.py deleted file mode 100644 index 9f3ab785e..000000000 --- a/scripts/ua_fetch.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python3 -# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: - -"""Fetch list of popular user-agents. - -The script is based on a gist posted by github.com/averrin, the ouput of this -script is formatted to be pasted into configtypes.py. -""" - -import requests -from lxml import html - -url = 'https://techblog.willshouse.com/2012/01/03/most-common-user-agents/' -page = requests.get(url) -page = html.fromstring(page.text) -path = '//*[@id="post-2229"]/div[2]/table/tbody' -table = page.xpath(path)[0] - -indent = " " -print("%sdef complete(self):" % indent) -print("%s\"\"\"Complete a list of common user agents.\"\"\"" % (2 * indent)) -print("%sout = [" % (2 * indent)) -for row in table[:12]: - ua = row[1].text_content() - browser = row[2].text_content() - print("%s(\'%s\',\n%s \"%s\")," % (3 * indent, ua, 3 * indent, browser)) -print("%s]\n%sreturn out\n" % (2 * indent, 2 * indent)) From 08bbb6b7c7bf2b5eba8563791b8449e2d00d66e9 Mon Sep 17 00:00:00 2001 From: Lamar Pavel Date: Tue, 20 Oct 2015 17:30:39 +0200 Subject: [PATCH 005/103] Consider new UA script in tox tests To avoid failing tests tox now includes one of the modules required by the script and the latter informs pylint to ignore one of the imports. --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index cbe077b75..6c4d349d1 100644 --- a/tox.ini +++ b/tox.ini @@ -96,6 +96,7 @@ deps = logilab-common==1.1.0 six==1.10.0 vulture==0.8.1 + requests==2.8.1 commands = {envpython} scripts/link_pyqt.py --tox {envdir} {envpython} -m pylint scripts qutebrowser --rcfile=.pylintrc --output-format=colorized --reports=no --expected-line-ending-format=LF From e03068ed845faf3008db53d5992f2357c0d116d7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 20 Oct 2015 18:13:31 +0200 Subject: [PATCH 006/103] Start adding website features to asciidoc2html. --- scripts/asciidoc2html.py | 59 +++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/scripts/asciidoc2html.py b/scripts/asciidoc2html.py index a94a3b910..455dfd165 100755 --- a/scripts/asciidoc2html.py +++ b/scripts/asciidoc2html.py @@ -25,6 +25,8 @@ import os.path import sys import subprocess import glob +import shutil +import tempfile import argparse sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir)) @@ -46,10 +48,24 @@ class AsciiDoc: def __init__(self, args): self._cmd = None self._args = args + self._homedir = None + self._themedir = None + self._tempdir = None def prepare(self): """Get the asciidoc command and create the homedir to use.""" self._cmd = self._get_asciidoc_cmd() + self._homedir = tempfile.mkdtemp() + self._themedir = os.path.join( + self._homedir, '.asciidoc', 'themes', 'qute') + self._tempdir = os.path.join(self._homedir, 'tmp') + os.makedirs(self._tempdir) + os.makedirs(self._themedir) + + def cleanup(self): + """Clean up the temporary home directory for asciidoc.""" + if self._homedir is not None: + shutil.rmtree(self._homedir) def build(self): if self._args.website: @@ -67,21 +83,39 @@ class AsciiDoc: self.call(src, dst) def _build_website(self): + theme_file = os.path.abspath(os.path.join('www', 'qute.css')) + shutil.copy(theme_file, self._themedir) + + outdir = self._args.website[0] + for root, _dirs, files in os.walk(os.getcwd()): for filename in files: if os.path.splitext(filename)[1] != '.asciidoc': continue + src = os.path.join(root, filename) - parts = [self._args.all[0]] + src_basename = os.path.basename(src) + parts = [outdir] dirname = os.path.dirname(src) if dirname: parts.append(os.path.relpath(os.path.dirname(src))) parts.append( - os.extsep.join((os.path.splitext(os.path.basename(src))[0], + os.extsep.join((os.path.splitext(src_basename)[0], 'html'))) dst = os.path.join(*parts) os.makedirs(os.path.dirname(dst), exist_ok=True) - self.call(src, dst) + + modified_src = os.path.join(self._tempdir, src_basename) + shutil.copy('www/header.asciidoc', modified_src) + + with open(modified_src, 'a', encoding='utf-8') as outfp: + with open(src, 'r', encoding='utf-8') as infp: + outfp.write(infp.read()) + + self.call(modified_src, dst, '--theme=qute') + + for path in ['icons', 'doc/img']: + shutil.copytree(path, os.path.join(outdir, path)) def _get_asciidoc_cmd(self): """Try to find out what commandline to use to invoke asciidoc.""" @@ -106,21 +140,22 @@ class AsciiDoc: raise FileNotFoundError - def call(self, src, dst, theme=None): + def call(self, src, dst, *args): """Call asciidoc for the given files. Args: src: The source .asciidoc file. dst: The destination .html file, or None to auto-guess. - theme: The CSS to use as a theme. + *args: Additional arguments passed to asciidoc. """ print("Calling asciidoc for {}...".format(os.path.basename(src))) - args = self._cmd[:] + cmdline = self._cmd[:] if dst is not None: - args += ['--out-file', dst] - args.append(src) + cmdline += ['--out-file', dst] + cmdline += args + cmdline.append(src) try: - subprocess.check_call(args) + subprocess.check_call(cmdline, env={'HOME': self._homedir}) except (subprocess.CalledProcessError, OSError) as e: utils.print_col(str(e), 'red') sys.exit(1) @@ -151,7 +186,11 @@ def main(colors=False): "the --asciidoc argument to point this script to the " "correct python/asciidoc.py location!", 'red') sys.exit(1) - asciidoc.build() + + try: + asciidoc.build() + finally: + asciidoc.cleanup() if __name__ == '__main__': From 45f9e61815bb6691e5c326cc3cb22f831abc3f3f Mon Sep 17 00:00:00 2001 From: Lamar Pavel Date: Tue, 20 Oct 2015 18:17:12 +0200 Subject: [PATCH 007/103] Fix pylint error (line too long) --- qutebrowser/config/configtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 0c3d9dde2..6d3b4813e 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1558,7 +1558,7 @@ class UserAgent(BaseType): def validate(self, value): self._basic_validation(value) - # To update the following list of user agents, run the script 'ua_fetch.py'. + # To update the following list of user agents, run the script 'ua_fetch.py' # Vim-protip: Place your cursor below this comment and run # :r!python scripts/dev/ua_fetch.py def complete(self): From 406b7a7034e9dbda7ad262827262e79200f94481 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 21 Oct 2015 07:18:42 +0200 Subject: [PATCH 008/103] Fix wrong image width in README.asciidoc. --- README.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.asciidoc b/README.asciidoc index 7f1941703..58e9ae385 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -24,7 +24,7 @@ Screenshots ----------- image:doc/img/main.png["screenshot 1",width=300,link="doc/img/main.png"] -image:doc/img/downloads.png["screenshot 2",width=300j,link="doc/img/downloads.png"] +image:doc/img/downloads.png["screenshot 2",width=300,link="doc/img/downloads.png"] image:doc/img/completion.png["screenshot 3",width=300,link="doc/img/completion.png"] image:doc/img/hints.png["screenshot 4",width=300,link="doc/img/hints.png"] From f6fffee9d324b71a26bb3fb7d8e7073e162ea0ec Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 21 Oct 2015 07:19:04 +0200 Subject: [PATCH 009/103] www: Keep modified sources if building failed. --- scripts/asciidoc2html.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/asciidoc2html.py b/scripts/asciidoc2html.py index 455dfd165..fc1df3faf 100755 --- a/scripts/asciidoc2html.py +++ b/scripts/asciidoc2html.py @@ -51,6 +51,7 @@ class AsciiDoc: self._homedir = None self._themedir = None self._tempdir = None + self._failed = False def prepare(self): """Get the asciidoc command and create the homedir to use.""" @@ -64,7 +65,7 @@ class AsciiDoc: def cleanup(self): """Clean up the temporary home directory for asciidoc.""" - if self._homedir is not None: + if self._homedir is not None and not self._failed: shutil.rmtree(self._homedir) def build(self): @@ -157,7 +158,9 @@ class AsciiDoc: try: subprocess.check_call(cmdline, env={'HOME': self._homedir}) except (subprocess.CalledProcessError, OSError) as e: + self._failed = True utils.print_col(str(e), 'red') + print("Keeping modified sources in {}.".format(self._homedir)) sys.exit(1) From daf81f5fcd4dbc8428b3160cafd755afc533b8c7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 21 Oct 2015 07:31:47 +0200 Subject: [PATCH 010/103] www: Working website generation. --- README.asciidoc | 2 ++ scripts/asciidoc2html.py | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/README.asciidoc b/README.asciidoc index 58e9ae385..673d57271 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -6,6 +6,7 @@ qutebrowser =========== +// QUTE_WEB_HIDE image:icons/qutebrowser-64x64.png[qutebrowser logo] *A keyboard-driven, vim-like browser based on PyQt5 and QtWebKit.* image:https://img.shields.io/pypi/l/qutebrowser.svg?style=flat["license badge",link="https://github.com/The-Compiler/qutebrowser/blob/master/COPYING"] @@ -14,6 +15,7 @@ image:https://img.shields.io/github/issues/The-Compiler/qutebrowser.svg?style=fl image:https://requires.io/github/The-Compiler/qutebrowser/requirements.svg?branch=master["requirements badge",link="https://requires.io/github/The-Compiler/qutebrowser/requirements/?branch=master"] image:https://travis-ci.org/The-Compiler/qutebrowser.svg?branch=master["Build Status", link="https://travis-ci.org/The-Compiler/qutebrowser"] image:https://ci.appveyor.com/api/projects/status/9gmnuip6i1oq7046?svg=true["AppVeyor build status", link="https://ci.appveyor.com/project/The-Compiler/qutebrowser"] +// QUTE_WEB_HIDE_END qutebrowser is a keyboard-focused browser with a minimal GUI. It's based on Python, PyQt5 and QtWebKit and free software, licensed under the GPL. diff --git a/scripts/asciidoc2html.py b/scripts/asciidoc2html.py index fc1df3faf..b442d46b5 100755 --- a/scripts/asciidoc2html.py +++ b/scripts/asciidoc2html.py @@ -20,6 +20,7 @@ """Generate the html documentation based on the asciidoc files.""" +import re import os import os.path import sys @@ -111,13 +112,32 @@ class AsciiDoc: with open(modified_src, 'a', encoding='utf-8') as outfp: with open(src, 'r', encoding='utf-8') as infp: - outfp.write(infp.read()) + outfp.write('\n') + hidden = False + for line in infp: + if line.strip() == '// QUTE_WEB_HIDE': + assert not hidden + hidden = True + elif line.strip() == '// QUTE_WEB_HIDE_END': + assert hidden + hidden = False + + # Let's see if this looks good everywhere... + if re.match(r'^=+$', line): + line = line.replace('=', '-') + elif re.match(r'^= .+', line): + line = '==' + line[1:] + + if not hidden: + outfp.write(line) self.call(modified_src, dst, '--theme=qute') for path in ['icons', 'doc/img']: shutil.copytree(path, os.path.join(outdir, path)) + os.symlink('README.html', os.path.join(outdir, 'index.html')) + def _get_asciidoc_cmd(self): """Try to find out what commandline to use to invoke asciidoc.""" if self._args.asciidoc is not None: From fabe53564f48e23b58bdc0dc8c37ad5832a07772 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 21 Oct 2015 19:48:00 +0200 Subject: [PATCH 011/103] Add www folder. --- www/header.asciidoc | 14 +++ www/media/favicon.png | Bin 0 -> 2117 bytes www/media/font.css | 13 +++ www/media/opensans-bold.woff2 | Bin 0 -> 16276 bytes www/media/opensans.woff2 | Bin 0 -> 15572 bytes www/media/qutebrowser.svg | 211 ++++++++++++++++++++++++++++++++++ www/qute.css | 166 ++++++++++++++++++++++++++ 7 files changed, 404 insertions(+) create mode 100644 www/header.asciidoc create mode 100644 www/media/favicon.png create mode 100644 www/media/font.css create mode 100644 www/media/opensans-bold.woff2 create mode 100644 www/media/opensans.woff2 create mode 100644 www/media/qutebrowser.svg create mode 100644 www/qute.css diff --git a/www/header.asciidoc b/www/header.asciidoc new file mode 100644 index 000000000..e42cdd817 --- /dev/null +++ b/www/header.asciidoc @@ -0,0 +1,14 @@ ++++ +
+ +
+

qutebrowser

+ A keyboard-driven browser. +
+
+ ++++ diff --git a/www/media/favicon.png b/www/media/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7efee9a05a94a6d3c7bb0f1d13b17d9ccdb0664c GIT binary patch literal 2117 zcmV-L2)g%)P)s{~ef0;Qv ztXX?)S53nMVx)QaXU>1-o9~?S%?$8AZtRm7$B29~gDpZw8wgDx_$)v^HEbtOMEI1e z-0@h(GmS@?eXBmTTQLe-v>lH866NrDp{ZS@P@Qz3I|?i(35yO>22@_>Jksp9-c={9 zQ_8j82p{st|0@Qb7@+!Zx5*TuTF|Vgv#J0udvd zh|Wq$FUZg%9362Vjp5!M!;FC`P?*s zCs$AK)gP8Czne&94*lun(|GmFg_XrM1EQ`GdP^rnumup>%7SZwDFBkzb(1lEpjI5c z6mbr2$iORO)~BO+`sQnIyvI(S?JFASty^Jk-wl0J8@S;CxeoHz`jPE@6D2VzGEfKs ztx2+j^$cGLiDp;P;mbtlcCdn06ahSTL4KjpiFJ&=`9bk#ZBskS_I(jrT~pB!Gjw>i zcEP%Gv9QWo47LM18irhm14=@a`|-IuH{t%e09*wSu`lOlox1_NQv^`+XYxrmcX0gL z7|+Eb%fS&aw{}CTX)4)Kfo4|N+nU8yW)Yd5zr(#b2D0)6bV9@QNDHpW`%rt&E)b|r z5gsT3AhgUDNbHo6$s(=1q7r&zTOo#Po1$gKSu>nYLZy?XgVM$2Yvai0Ed;8oa7RZg zQ$%}TouRTrA(rI;&=ugF`>NbPb#6sDnOO#Acnc-9QD*{-i;Y#x@PL(9mJE$f%%G=t z0Jcw(kTpJOF@(yY@ro!Wg@H6#x*OPa+aqfZy*oY{|Su z23%XJfdt2r5m+H0yNIUvWjwOC5rT6}E;=~hH;Adhi^xxp6w{ykYGAZ?!))({@Gt+r z%vxNT;QnR+1pv0~AelH?K3rMN4=@gpf>MNR-bEr$xl~$aiU1s2P79&s^#uR+zffd`s4PDoc4*-~KWonz=9vSYoI+4-Ur zyOtbNj*4)PAD*rIAOfK^RabDJYo%vbdnH4;Tmlq zn!K4PGO*~zrcJx?Jm^dK-V-?W{=gu^qPh#oQ?+#MgxoX0W*p-*~VM ziwj9Ojtj5HgUU)D-a6M?0)PnM4A>uHs0wPBTOtfZ6$YaU($2#gJ`b6gSpi(v4&vTn zdnwnm?l7_z-PeWAd$`FTN@NwL(i+-p>q}0WwW6p9$YygG_;3jK`uu3AC`Xkh5t*38 z_+THL$^MnySJXle-a*oFPo$sRbbTFw%<)iM|LN2VjM(0JWmfjhNCYc5%vEBi)OrAl z2&Ye<#o*u&Dl7ePU5SaADBN6nl`@vWY~Ks!54~fj7GM0x3rSLIemP*x?E?7YSECwh z@k?|!iIQYA3wAM-6E%#`m9iL91o%A+f&;o?qI26e+;{(e?Ck17Lof)(agdl#KuQTA z1Qgf7OdqsB3yju1@O114{GqIyw|=$oRP%GUbSd@xc)Yd3@cu;T+7Zn#cy~zPzBUbl zEnk6GX9f}C(J0dCG$s=+`Xd5Tl!Kc-Kxl9sJLX#Xr;|_rq_ z>qkQYqxq{{UU;;P%?X55j?jNo;?k@H2vE`?*KvBKZT(^4_~w^x`)OAB*yOL}7%SZV6#@NIF0MvgEMyf)=_;k+j|>6LB>OM zvwKXPJ>W6KXAQwSb-}6_hanYHy`y$Mo>4I(H7H5FO|I vs+tqLijnFYQ5lQL`K5d^@gIfzziIylte*3xKVF!600000NkvXXu0mjfu$bZm literal 0 HcmV?d00001 diff --git a/www/media/font.css b/www/media/font.css new file mode 100644 index 000000000..98b144f52 --- /dev/null +++ b/www/media/font.css @@ -0,0 +1,13 @@ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(opensans.woff2) format('woff2'); +} + +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(opensans-bold.woff2) format('woff2'); +} \ No newline at end of file diff --git a/www/media/opensans-bold.woff2 b/www/media/opensans-bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..be4c25b4299232febd93f9b7528642869d60f16a GIT binary patch literal 16276 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 EKejGBx&QzG literal 0 HcmV?d00001 diff --git a/www/media/opensans.woff2 b/www/media/opensans.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..5287058cf90dd427ca8ad6e330cd339bd257dd9c GIT binary patch literal 15572 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 ab)kb)z25LcH12#3l+gg_#ocOw0{nk#e8;T- literal 0 HcmV?d00001 diff --git a/www/media/qutebrowser.svg b/www/media/qutebrowser.svg new file mode 100644 index 000000000..bf75e2462 --- /dev/null +++ b/www/media/qutebrowser.svg @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/www/qute.css b/www/qute.css new file mode 100644 index 000000000..95b34e11d --- /dev/null +++ b/www/qute.css @@ -0,0 +1,166 @@ +* { + margin: 0px 0px; + padding: 0px 0px; +} + +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + -webkit-text-size-adjust: none; + color: #333333; +} + +#header { + display: none; +} + +#headline { + background-color: #333333; + padding: 20px 20px; + overflow: auto; + color: #888; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +#headline .qutebrowser-logo { + display: block; + height: 70px; + float: left; +} + +#headline .text { + float: right; + text-align: right; +} + +#headline .text h1 { + color: #1e89c6; + border: none; +} + +#headline .text { + color: #666666; +} + +#menu { + padding: 0px 20px; + background-color: #555555; + color: #CCC; + overflow: auto; + margin-bottom: 10px; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +#menu a { + color: #CCC; + text-decoration: none; + background-color: #555555; + padding: 10px 20px; + float: left; +} + +#menu a:hover { + background-color: #1e89c6; +} + +.sect1 { + padding: 10px 40px; +} + +.sect2 { + padding: 10px 0px; +} + +div.footnote { + padding: 10px 40px; +} + +hr { + margin: 0px 40px; + color: #CCCCCC; +} + +h1, h2, h3, h4, h5, h6 { + color: #0A396E; + margin-bottom: 10px; + border-bottom: 1px solid #CCCCCC; +} + +.ulist { + padding-left: 20px; + margin-top: 10px; +} + +#footer { + padding: 20px 40px; + border-top: 1px solid #CCCCCC; + color: #888888; +} + +a { + color: #1e89c6; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +ol { + margin-left: 20px; + margin-top: 20px; + margin-bottom: 20px; +} + +li { + margin-bottom: 10px; +} + +.hdlist1 { + color: #0A396E; + margin-bottom: 10px; + margin-top: 10px; + border-bottom: 1px solid #CCCCCC; +} + +@media screen and (max-width: 480px) { + #headline .qutebrowser-logo { + margin-left: auto; + margin-right: auto; + display: block; + width: 30%; + height: auto; + float: none; + } + + #headline .text { + display: none; + } + + #menu { + padding: 0px 0px; + background-color: #555555; + color: #CCC; + overflow: hidden; + width: 100%; + } + + #menu a { + color: #CCC; + text-decoration: none; + background-color: #555555; + width: 100%; + padding: 10px 40px; + } +} + + + + + +