From c575435782bc345d7f374c81090fe01e93badfb5 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 1 Oct 2015 13:15:50 +0100 Subject: [PATCH 001/327] misc/editor: Fix tempfile deleted on error / editor crash This patch attempts to fix an issue where an error occuring in misc/guiprocess or the editor process crashing would delete the temporary file thus making it impossible to recover changes not commited to the form field from the editor. --- qutebrowser/misc/editor.py | 3 ++- qutebrowser/misc/guiprocess.py | 3 +++ tests/unit/misc/test_editor.py | 13 +++++++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/qutebrowser/misc/editor.py b/qutebrowser/misc/editor.py index 4211fe184..4bb83574e 100644 --- a/qutebrowser/misc/editor.py +++ b/qutebrowser/misc/editor.py @@ -58,7 +58,8 @@ class ExternalEditor(QObject): return try: os.close(self._oshandle) - os.remove(self._filename) + if self._proc.exit_status() != QProcess.CrashExit: + os.remove(self._filename) except OSError as e: # NOTE: Do not replace this with "raise CommandError" as it's # executed async. diff --git a/qutebrowser/misc/guiprocess.py b/qutebrowser/misc/guiprocess.py index 2c4c4f0a2..0df4d446f 100644 --- a/qutebrowser/misc/guiprocess.py +++ b/qutebrowser/misc/guiprocess.py @@ -151,3 +151,6 @@ class GUIProcess(QObject): else: message.error(self._win_id, "Error while spawning {}: {}.".format( self._what, self._proc.error()), immediately=True) + + def exit_status(self): + return self._proc.exitStatus() diff --git a/tests/unit/misc/test_editor.py b/tests/unit/misc/test_editor.py index ae1db876c..edeeb8922 100644 --- a/tests/unit/misc/test_editor.py +++ b/tests/unit/misc/test_editor.py @@ -91,19 +91,28 @@ class TestFileHandling: filename = editor._filename assert os.path.exists(filename) + editor._proc._proc.exitStatus = mock.Mock( + return_value=QProcess.CrashExit) editor._proc.finished.emit(1, QProcess.NormalExit) - assert not os.path.exists(filename) + assert os.path.exists(filename) + + os.remove(filename) def test_crash(self, editor): """Test file handling when closing with a crash.""" editor.edit("") filename = editor._filename assert os.path.exists(filename) + + editor._proc._proc.exitStatus = mock.Mock( + return_value=QProcess.CrashExit) editor._proc.error.emit(QProcess.Crashed) editor._proc.finished.emit(0, QProcess.CrashExit) - assert not os.path.exists(filename) + assert os.path.exists(filename) + + os.remove(filename) @pytest.mark.posix def test_unreadable(self, message_mock, editor): From d73491b0c80254bea2f327e7acd3ff616f21f037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Wi=C3=9Fmann?= Date: Fri, 14 Aug 2015 23:53:52 +0200 Subject: [PATCH 002/327] Add password_fill userscript Add a configurable userscript that fills login forms (i.e. the fiels "Username" and "Password) of websites using a configurable backend where the actual passwords are stored. The only backend yet is using the password store "pass". --- misc/userscripts/password_fill | 276 +++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100755 misc/userscripts/password_fill diff --git a/misc/userscripts/password_fill b/misc/userscripts/password_fill new file mode 100755 index 000000000..15114044d --- /dev/null +++ b/misc/userscripts/password_fill @@ -0,0 +1,276 @@ +#!/bin/bash -e +help() { + blink=$'\e[1;31m' reset=$'\e[0m' +cat < +In case of questions or suggestions, do not hesitate to send me an E-Mail or to +directly ask me via IRC (nickname thorsten\`) in #qutebrowser on freenode. + + $blink!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$reset + WARNING: the passwords are stored in qutebrowser's + debug log reachable via the url qute:log + $blink!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$reset + +Usage: run as a userscript form qutebrowser, e.g.: + spawn --userscript ~/.config/qutebrowser/password_fill + +Behaviour: + It will try to find a username/password entry in the configured backend + (currently only pass) for the current website and will load that pair of + username and password to any form on the current page that has some password + entry field. + +EOF +} + +set -o pipefail +shopt -s nocasematch + +if [ -z "$QUTE_FIFO" ] ; then + help + exit +fi + +error() { + local msg="$*" + echo "message-error '${msg//\'/\\\'}'" >> "$QUTE_FIFO" +} +msg() { + local msg="$*" + echo "message-info '${msg//\'/\\\'}'" >> "$QUTE_FIFO" +} +die() { + error "$*" + exit 0 +} + +# ======================================================= # +# CONFIGURATION +# ======================================================= # +# The configuration file is per default located in +# ~/.config/qutebrowser/password_fill_rc and is a bash script that is loaded +# later in the present script. So basically you can replace all of the +# following definitions and make them fit your needs. + +# The following simplifies a URL to the domain (e.g. "wiki.qutebrowser.org") +# which is later used to search the correct entries in the password backend. If +# you e.g. don't want the "www." to be removed or if you want to distinguish +# between different paths on the same domain. + +simplify_url() { + simple_url="${1##*://}" # remove protocoll specification + simple_url="${simple_url%%\?*}" # remove GET parameters + simple_url="${simple_url%%/*}" # remove directory path + simple_url="${simple_url##www.}" # remove www. subdomain +} + + +# Backend implementations tell, how the actual password store is accessed. +# Right now, there is only one fully functional password backend, namely for +# the program "pass". +# A password backend consists of three actions: +# - init() initializes backend-specific things and does sanity checks. +# - query_entries() is called with a simplified url and is expected to fill +# the bash array $files with the names of matching password entries. There +# are no requirements how these names should look like. +# - open_entry() is called with some specific entry of the $files array and is +# expected to write the username of that entry to the $username variable and +# the corresponding password to $password + +reset_backend() { + init() { true ; } + query_entries() { true ; } + open_entry() { true ; } +} + +# choose_entry() is expected to choose one entry from the array $files and +# write it to the variable $file. +choose_entry() { + choose_entry_random +} + +# The default implementation chooses a random entry from the array. So if there +# are multiple matching entries, multiple calls to this userscript will +# eventually pick the "correct" entry. I.e. if this userscript is bound to +# "zl", the user has to press "zl" until the correct username shows up in the +# login form. +choose_entry_random() { + local nr=${#files[@]} + file="${files[$((RANDOM % nr))]}" + # Warn user, that there might be other matching password entries + if [ "$nr" -gt 1 ] ; then + msg "Picked $file out of $nr entries: ${files[*]}" + fi +} + +# another implementation would be to ask the user via some menu (like rofi or +# dmenu or zenity or even qutebrowser completion in future?) which entry to +# pick +MENU_COMMAND=( head -n 1 ) +choose_entry_menu() { + local nr=${#files[@]} + if [ "$nr" -eq 1 ] ; then + file="${files[0]}" + else + file=$( printf "%s\n" "${files[@]}" | "${MENU_COMMAND[@]}" ) + fi +} + +choose_entry_rofi() { + MENU_COMMAND=( rofi -p "qutebrowser> " -dmenu + -mesg $'Pick a password entry for '"${QUTE_URL//&/&}"'' ) + choose_entry_menu || true +} + +choose_entry_zenity() { + MENU_COMMAND=( zenity --list --title "Qutebrowser password fill" + --text "Pick the password entry:" + --column "Name" ) + choose_entry_menu || true +} + +choose_entry_zenity_radio() { + zenity_helper() { + awk '{ print $0 ; print $0 }' \ + | zenity --list --radiolist \ + --title "Qutebrowser password fill" \ + --text "Pick the password entry:" \ + --column " " --column "Name" + } + MENU_COMMAND=( zenity_helper ) + choose_entry_menu || true +} + +# ======================================================= +# backend: PASS + +# configuration options: +match_filename=1 # whether allowing entry match by filepath +match_line=1 # whether allowing entry match by URL-Pattern in file +match_line_pattern='^url: .*' # applied using grep -iE +user_pattern='^(user|username): ' + +GPG_OPTS=( "--quiet" "--yes" "--compress-algo=none" "--no-encrypt-to" ) +GPG="gpg" +export GPG_TTY="${GPG_TTY:-$(tty 2>/dev/null)}" +which gpg2 &>/dev/null && GPG="gpg2" +[[ -n $GPG_AGENT_INFO || $GPG == "gpg2" ]] && GPG_OPTS+=( "--batch" "--use-agent" ) + +pass_backend() { + init() { + PREFIX="${PASSWORD_STORE_DIR:-$HOME/.password-store}" + if ! [ -d "$PREFIX" ] ; then + die "Can not open password store dir »$PREFIX«" + fi + } + query_entries() { + local url="$1" + + if ((match_line)) ; then + # add entries with matching URL-tag + while read -r -d "" passfile ; do + if $GPG "${GPG_OPTS}" -d "$passfile" \ + | grep --max-count=1 -iE "${match_line_pattern}${url}" > /dev/null + then + passfile="${passfile#$PREFIX}" + passfile="${passfile#/}" + files+=( "${passfile%.gpg}" ) + fi + done < <(find -L "$PREFIX" -iname '*.gpg' -print0) + fi + if ((match_filename)) ; then + # add entries wth matching filepath + while read -r passfile ; do + passfile="${passfile#$PREFIX}" + passfile="${passfile#/}" + files+=( "${passfile%.gpg}" ) + done < <(find -L "$PREFIX" -iname '*.gpg' | grep "$url") + fi + } + open_entry() { + local path="$PREFIX/${1}.gpg" + password="" + local firstline=1 + while read -r line ; do + if ((firstline)) ; then + password="$line" + firstline=0 + else + if [[ $line =~ $user_pattern ]] ; then + # remove the matching prefix "user: " from the beginning of the line + username=${line#${BASH_REMATCH[0]}} + break + fi + fi + done < <($GPG "${GPG_OPTS}" -d "$path" ) + } +} +# ======================================================= + +# load some sane default backend +reset_backend +pass_backend +# load configuration +QUTE_CONFIG_DIR=${QUTE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/qutebrowser/} +PWFILL_CONFIG=${PFILL_CONFIG:-${QUTE_CONFIG_DIR}/password_fill_rc} +if [ -f "$CONFIG_FILE" ] ; then + source "$CONFIG_FILE" +fi +init + +simplify_url "$QUTE_URL" +query_entries "${simple_url}" +if [ 0 -eq "${#files[@]}" ] ; then + die "No entry found for »$simple_url«" +fi +choose_entry +if [ -z "$file" ] ; then + # choose_entry didn't want any of these entries + exit 0 +fi +open_entry "$file" +#username="$(date)" +#password="XYZ" + +[ -n "$username" ] || die "Username not set in entry $file" +[ -n "$password" ] || die "Password not set in entry $file" + +js() { +cat <> "$QUTE_FIFO" From fb5e6e6c35eaf5d3112bc20d73bc53a4c9acf91c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Wi=C3=9Fmann?= Date: Sat, 5 Dec 2015 12:11:10 +0100 Subject: [PATCH 003/327] More sane defaults - Remove Port from URL - Use zenity per default - Allow customization of handling of no entries are found --- misc/userscripts/password_fill | 50 ++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/misc/userscripts/password_fill b/misc/userscripts/password_fill index 15114044d..7ce989902 100755 --- a/misc/userscripts/password_fill +++ b/misc/userscripts/password_fill @@ -62,9 +62,41 @@ simplify_url() { simple_url="${1##*://}" # remove protocoll specification simple_url="${simple_url%%\?*}" # remove GET parameters simple_url="${simple_url%%/*}" # remove directory path + simple_url="${simple_url%:*}" # remove port simple_url="${simple_url##www.}" # remove www. subdomain } +# no_entries_found() is called if the first query_entries() call did not find +# any matching entries. Multiple implementations are possible: +# The easiest behaviour is to quit: +#no_entries_found() { +# if [ 0 -eq "${#files[@]}" ] ; then +# die "No entry found for »$simple_url«" +# fi +#} +# But you could also fill the files array with all entries from your pass db +# if the first db query did not find anything +# no_entries_found() { +# if [ 0 -eq "${#files[@]}" ] ; then +# query_entries "" +# if [ 0 -eq "${#files[@]}" ] ; then +# die "No entry found for »$simple_url«" +# fi +# fi +# } + +# Another beahviour is to drop another level of subdomains until search hits +# are found: +no_entries_found() { + while [ 0 -eq "${#files[@]}" ] && [ -n "$simple_url" ]; do + simple_url=$(sed 's,^[^.]*\.,,' <<< "$simple_url") + query_entries "$simple_url" + #die "No entry found for »$simple_url«" + done + if [ 0 -eq "${#files[@]}" ] ; then + die "No entry found for »$simple_url«" + fi +} # Backend implementations tell, how the actual password store is accessed. # Right now, there is only one fully functional password backend, namely for @@ -87,7 +119,7 @@ reset_backend() { # choose_entry() is expected to choose one entry from the array $files and # write it to the variable $file. choose_entry() { - choose_entry_random + choose_entry_zenity } # The default implementation chooses a random entry from the array. So if there @@ -147,7 +179,8 @@ choose_entry_zenity_radio() { # configuration options: match_filename=1 # whether allowing entry match by filepath -match_line=1 # whether allowing entry match by URL-Pattern in file +match_line=0 # whether allowing entry match by URL-Pattern in file + # Note: match_line=1 gets very slow, even for small password stores! match_line_pattern='^url: .*' # applied using grep -iE user_pattern='^(user|username): ' @@ -213,17 +246,17 @@ reset_backend pass_backend # load configuration QUTE_CONFIG_DIR=${QUTE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/qutebrowser/} -PWFILL_CONFIG=${PFILL_CONFIG:-${QUTE_CONFIG_DIR}/password_fill_rc} -if [ -f "$CONFIG_FILE" ] ; then - source "$CONFIG_FILE" +PWFILL_CONFIG=${PWFILL_CONFIG:-${QUTE_CONFIG_DIR}/password_fill_rc} +if [ -f "$PWFILL_CONFIG" ] ; then + source "$PWFILL_CONFIG" fi init simplify_url "$QUTE_URL" query_entries "${simple_url}" -if [ 0 -eq "${#files[@]}" ] ; then - die "No entry found for »$simple_url«" -fi +no_entries_found +# remove duplicates +mapfile -t files < <(printf "%s\n" "${files[@]}" | sort | uniq ) choose_entry if [ -z "$file" ] ; then # choose_entry didn't want any of these entries @@ -232,6 +265,7 @@ fi open_entry "$file" #username="$(date)" #password="XYZ" +#msg "$username, ${#password}" [ -n "$username" ] || die "Username not set in entry $file" [ -n "$password" ] || die "Password not set in entry $file" From ffdc0f664f77c25bd82b935d8c439bd0ceed6d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Wi=C3=9Fmann?= Date: Sat, 5 Dec 2015 12:26:14 +0100 Subject: [PATCH 004/327] Ask for confirmation on fuzzy entry matching --- misc/userscripts/password_fill | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/misc/userscripts/password_fill b/misc/userscripts/password_fill index 7ce989902..2a5c21792 100755 --- a/misc/userscripts/password_fill +++ b/misc/userscripts/password_fill @@ -19,7 +19,10 @@ Behaviour: It will try to find a username/password entry in the configured backend (currently only pass) for the current website and will load that pair of username and password to any form on the current page that has some password - entry field. + entry field. If multiple entries are found, a zenity menu is offered. + + If no entry is found, then it crops subdomains from the url if at least one + entry is found in the backend. (In that case, it always shows a menu) EOF } @@ -92,6 +95,8 @@ no_entries_found() { simple_url=$(sed 's,^[^.]*\.,,' <<< "$simple_url") query_entries "$simple_url" #die "No entry found for »$simple_url«" + # enforce menu if we do "fuzzy" matching + menu_if_one_entry=1 done if [ 0 -eq "${#files[@]}" ] ; then die "No entry found for »$simple_url«" @@ -140,9 +145,11 @@ choose_entry_random() { # dmenu or zenity or even qutebrowser completion in future?) which entry to # pick MENU_COMMAND=( head -n 1 ) +# whether to show the menu if there is only one entrie in it +menu_if_one_entry=0 choose_entry_menu() { local nr=${#files[@]} - if [ "$nr" -eq 1 ] ; then + if [ "$nr" -eq 1 ] && ! ((menu_if_one_entry)) ; then file="${files[0]}" else file=$( printf "%s\n" "${files[@]}" | "${MENU_COMMAND[@]}" ) From 497a6e072043698d040681b4fcf5166a07535fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Wi=C3=9Fmann?= Date: Wed, 9 Dec 2015 23:25:55 +0100 Subject: [PATCH 005/327] Fixup url simplifier loop Now, the loop which successively simplifies the url, always terminates. --- misc/userscripts/password_fill | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/misc/userscripts/password_fill b/misc/userscripts/password_fill index 2a5c21792..4da4ebe90 100755 --- a/misc/userscripts/password_fill +++ b/misc/userscripts/password_fill @@ -92,7 +92,14 @@ simplify_url() { # are found: no_entries_found() { while [ 0 -eq "${#files[@]}" ] && [ -n "$simple_url" ]; do - simple_url=$(sed 's,^[^.]*\.,,' <<< "$simple_url") + shorter_simple_url=$(sed 's,^[^.]*\.,,' <<< "$simple_url") + if [ "$shorter_simple_url" = "$simple_url" ] ; then + # if no dot, then even remove the top level domain + simple_url="" + query_entries "$simple_url" + break + fi + simple_url="$shorter_simple_url" query_entries "$simple_url" #die "No entry found for »$simple_url«" # enforce menu if we do "fuzzy" matching From e4b809927fa6a0f11f28fc2d0262e8c1ddb13388 Mon Sep 17 00:00:00 2001 From: Tobias Werth Date: Fri, 11 Dec 2015 16:23:47 +0100 Subject: [PATCH 006/327] Escape password properly in generated JS. --- misc/userscripts/password_fill | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/userscripts/password_fill b/misc/userscripts/password_fill index 4da4ebe90..2304502db 100755 --- a/misc/userscripts/password_fill +++ b/misc/userscripts/password_fill @@ -304,7 +304,7 @@ cat < Date: Fri, 11 Dec 2015 16:54:16 +0100 Subject: [PATCH 007/327] Add documentation in password_fill Describe usage and configuration. Also allow "login:" as a prefix for login name in pass entries. --- misc/userscripts/password_fill | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/misc/userscripts/password_fill b/misc/userscripts/password_fill index 2304502db..7d0ad3b9b 100755 --- a/misc/userscripts/password_fill +++ b/misc/userscripts/password_fill @@ -15,6 +15,13 @@ directly ask me via IRC (nickname thorsten\`) in #qutebrowser on freenode. Usage: run as a userscript form qutebrowser, e.g.: spawn --userscript ~/.config/qutebrowser/password_fill +Pass backend: (see also passwordstore.org) + This script expects pass to store the credentials of each page in an extra + file, where the filename (or filepath) contains the domain of the respective + page. The first line of the file must contain the password, the login name + must be contained in a later line beginning with "user:", "login:", or + "username:" (configurable by the user_pattern variable). + Behaviour: It will try to find a username/password entry in the configured backend (currently only pass) for the current website and will load that pair of @@ -24,11 +31,16 @@ Behaviour: If no entry is found, then it crops subdomains from the url if at least one entry is found in the backend. (In that case, it always shows a menu) +Configuration: + This script loads the bash script ~/.config/qutebrowser/password_fill_rc (if + it exists), so you can change any configuration variable and overwrite any + function you like. + EOF } set -o pipefail -shopt -s nocasematch +shopt -s nocasematch # make regexp matching in bash case insensitive if [ -z "$QUTE_FIFO" ] ; then help @@ -196,7 +208,7 @@ match_filename=1 # whether allowing entry match by filepath match_line=0 # whether allowing entry match by URL-Pattern in file # Note: match_line=1 gets very slow, even for small password stores! match_line_pattern='^url: .*' # applied using grep -iE -user_pattern='^(user|username): ' +user_pattern='^(user|username|login): ' GPG_OPTS=( "--quiet" "--yes" "--compress-algo=none" "--no-encrypt-to" ) GPG="gpg" From 26f2ae5ad014b1e41031bdb50d62d9dd9c6a718f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Wi=C3=9Fmann?= Date: Fri, 11 Dec 2015 17:04:50 +0100 Subject: [PATCH 008/327] Do proper javascript escaping in password_fill --- misc/userscripts/password_fill | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/misc/userscripts/password_fill b/misc/userscripts/password_fill index 7d0ad3b9b..bc12e228b 100755 --- a/misc/userscripts/password_fill +++ b/misc/userscripts/password_fill @@ -60,6 +60,12 @@ die() { exit 0 } +javascript_escape() { + # print the first argument in a escaped way, such that it can savely + # be used within javascripts double quotes + sed "s,[\\\'\"],\\\&,g" <<< "$1" +} + # ======================================================= # # CONFIGURATION # ======================================================= # @@ -313,10 +319,10 @@ cat < Date: Mon, 15 Feb 2016 14:38:11 +0100 Subject: [PATCH 009/327] let help text match reality --- doc/help/settings.asciidoc | 2 +- qutebrowser/config/configdata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 4142adbe7..bf3074946 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -180,7 +180,7 @@ |<>|Whether to scatter hint key chains (like Vimium) or not (like dwb). |<>|Make chars in hint strings uppercase. |<>|The dictionary file to be used by the word hints. -|<>|Whether to auto-follow a hint if there's only one left. +|<>|Follow a hint immediately when the hint text is completely matched. |<>|A comma-separated list of regexes to use for 'next' links. |<>|A comma-separated list of regexes to use for 'prev' links. |============== diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 656452a83..19a7e10e9 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -896,7 +896,7 @@ def data(readonly=False): ('auto-follow', SettingValue(typ.Bool(), 'true'), - "Whether to auto-follow a hint if there's only one left."), + "Follow a hint immediately when the hint text is completely matched."), ('next-regexes', SettingValue(typ.RegexList(flags=re.IGNORECASE), From 007425cf163b61dcd41845f377fc74e1c89b6dd3 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Thu, 18 Feb 2016 16:17:35 +0100 Subject: [PATCH 010/327] downloads: fix filename for data: links Issue #1214 Now uses a sensible filename for data: links instead of the whole base64 content. For PDF.js, it even uses the correct pdf filename. TODO: Produces "QPainter::end: Painter ended with 2 saved states" while running the tests here (Arch Linux): CPython: 3.5.1 Qt: 5.5.1, runtime: 5.5.1 PyQt: 5.5.1 --- qutebrowser/browser/downloads.py | 20 ++++++++++++++++++- .../integration/data/downloads/issue1214.html | 10 ++++++++++ tests/integration/features/downloads.feature | 10 ++++++++++ tests/integration/features/misc.feature | 12 +++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/integration/data/downloads/issue1214.html diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 8c977fb34..667e8e7a2 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -775,7 +775,25 @@ class DownloadManager(QAbstractListModel): request.setAttribute(QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) - suggested_fn = urlutils.filename_from_url(request.url()) + if request.url().scheme().lower() != 'data': + suggested_fn = urlutils.filename_from_url(request.url()) + else: + # We might be downloading a binary blob embedded on a page or even + # generated dynamically via javascript. We try to figure out a more + # sensible name than the base64 content of the data. + origin = request.originatingObject() + try: + origin_url = origin.url() + except AttributeError: + # Raised either if origin is None or some object that doesn't + # have its own url. We're probably fine with a default fallback + # then. + suggested_fn = 'binary blob' + else: + # Use the originating URL as a base for the filename (works + # e.g. for pdf.js). + suggested_fn = urlutils.filename_from_url(origin_url) + if suggested_fn is None: suggested_fn = 'qutebrowser-download' diff --git a/tests/integration/data/downloads/issue1214.html b/tests/integration/data/downloads/issue1214.html new file mode 100644 index 000000000..db56cdc61 --- /dev/null +++ b/tests/integration/data/downloads/issue1214.html @@ -0,0 +1,10 @@ + + + + + Wrong filename when using data: links + + + download + + diff --git a/tests/integration/features/downloads.feature b/tests/integration/features/downloads.feature index 5881767f6..d2ce1ce3c 100644 --- a/tests/integration/features/downloads.feature +++ b/tests/integration/features/downloads.feature @@ -34,6 +34,16 @@ Feature: Downloading things from a website. And I run :leave-mode Then no crash should happen + Scenario: Downloading a data: link (issue 1214) + When I set completion -> download-path-suggestion to filename + And I set storage -> prompt-download-directory to true + And I open data/downloads/issue1214.html + And I run :hint links download + And I run :follow-hint a + And I wait for "Asking question text='Save file to:'>, *" in the log + And I run :leave-mode + Then no crash should happen + Scenario: Retrying a failed download When I run :download http://localhost:(port)/does-not-exist And I wait for the error "Download error: * - server replied: NOT FOUND" diff --git a/tests/integration/features/misc.feature b/tests/integration/features/misc.feature index 7a0f9ae2f..bec5a65b9 100644 --- a/tests/integration/features/misc.feature +++ b/tests/integration/features/misc.feature @@ -290,6 +290,18 @@ Feature: Various utility commands. And I open data/misc/test.pdf Then "Download finished" should be logged + Scenario: Downloading a pdf via pdf.js button (issue 1214) + Given pdfjs is available + When I set content -> enable-pdfjs to true + And I set completion -> download-path-suggestion to filename + And I set storage -> prompt-download-directory to true + And I open data/misc/test.pdf + And I wait for "[qute://pdfjs/*] PDF * (PDF.js: *)" in the log + And I run :jseval document.getElementById("download").click() + And I wait for "Asking question text='Save file to:'>, *" in the log + And I run :leave-mode + Then no crash should happen + # :print # Disabled because it causes weird segfaults and QPainter warnings in Qt... From 6826a979101fa8e292c37875a2225ff26165b6ad Mon Sep 17 00:00:00 2001 From: avk Date: Mon, 22 Feb 2016 15:10:39 +0100 Subject: [PATCH 011/327] Tests for browser.network.pastebin --- tests/unit/browser/network/test_pastebin.py | 60 +++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tests/unit/browser/network/test_pastebin.py diff --git a/tests/unit/browser/network/test_pastebin.py b/tests/unit/browser/network/test_pastebin.py new file mode 100644 index 000000000..e0999bc60 --- /dev/null +++ b/tests/unit/browser/network/test_pastebin.py @@ -0,0 +1,60 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2016 Anna Kobak (avk) : +# +# 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 . + +"""Tests for qutebrowser.browser.network""" + +import pytest +from PyQt5.QtCore import QUrl + +from qutebrowser.browser.network import pastebin +from qutebrowser.misc import httpclient + +DATA = [{"name" : "XYZ", "title" : "hello world", "text" : "xyz. 123 \n 172ANB", "reply" : "abc" }] + +class HTTPPostStub(httpclient.HTTPClient): + + """A stub class for HTTPClient. + + Attributes: + url: the last url send by post() + data: the last data send by post() + """ + + def __init__(self): + super().__init__() + + def post(self, url, data): + self.url = url + self.data = data + + + +def test_constructor(qapp): + client = pastebin.PastebinClient() + assert isinstance(client._client, httpclient.HTTPClient) + +@pytest.mark.parametrize('data', DATA) +def test_paste(data): + client = pastebin.PastebinClient() + http_stub = HTTPPostStub() + client._client = http_stub + client.paste(data["name"], data["title"], data["text"], data["reply"]) + assert http_stub.data == data + assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create') + From 90c80782258c89a4c2612f73985fba15078803ad Mon Sep 17 00:00:00 2001 From: avk Date: Mon, 22 Feb 2016 16:09:57 +0100 Subject: [PATCH 012/327] More tests for browser.network.pastebin --- tests/unit/browser/network/test_pastebin.py | 41 +++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/tests/unit/browser/network/test_pastebin.py b/tests/unit/browser/network/test_pastebin.py index e0999bc60..1e237d58c 100644 --- a/tests/unit/browser/network/test_pastebin.py +++ b/tests/unit/browser/network/test_pastebin.py @@ -1,6 +1,6 @@ # vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: -# Copyright 2016 Anna Kobak (avk) : +# Copyright 2016 Anna Kobak (avk) : # # This file is part of qutebrowser. # @@ -25,7 +25,15 @@ from PyQt5.QtCore import QUrl from qutebrowser.browser.network import pastebin from qutebrowser.misc import httpclient -DATA = [{"name" : "XYZ", "title" : "hello world", "text" : "xyz. 123 \n 172ANB", "reply" : "abc" }] +DATA = [{"name" : "XYZ", "title" : "hello world", "text" : "xyz. 123 \n 172ANB", "reply" : "abc" }, + {"name" : "the name", "title" : "the title", "text" : "some Text", "reply" : "some parent"}] + +DATA_NOPARENT = [{"name" : "XYZ", "title" : "hello world", "text" : "xyz. 123 \n 172ANB"}, + {"name" : "the name", "title" : "the title", "text" : "some Text"}] + +HTTP_VALID = ["http://paste.the-compiler.org/view/ges83nt3", "http://paste.the-compiler.org/view/3gjnwg4"] + +HTTP_INVALID = ["http invalid", "http:/invalid.org"] class HTTPPostStub(httpclient.HTTPClient): @@ -50,7 +58,7 @@ def test_constructor(qapp): assert isinstance(client._client, httpclient.HTTPClient) @pytest.mark.parametrize('data', DATA) -def test_paste(data): +def test_paste_with_parent(data): client = pastebin.PastebinClient() http_stub = HTTPPostStub() client._client = http_stub @@ -58,3 +66,30 @@ def test_paste(data): assert http_stub.data == data assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create') +@pytest.mark.parametrize('data', DATA_NOPARENT) +def test_paste_without_parent(data): + client = pastebin.PastebinClient() + http_stub = HTTPPostStub() + client._client = http_stub + client.paste(data["name"], data["title"], data["text"]) + assert http_stub.data == data + assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create') + +@pytest.mark.parametrize('http', HTTP_VALID) +def test_on_client_success(http, qtbot): + client = pastebin.PastebinClient() + http_stub = HTTPPostStub() + client._client = http_stub + with qtbot.assertNotEmitted(client.error): + with qtbot.waitSignal(client.success): + client.on_client_success(http) + +@pytest.mark.parametrize('http', HTTP_INVALID) +def test_on_client_success_invalid_http(http, qtbot): + client = pastebin.PastebinClient() + http_stub = HTTPPostStub() + client._client = http_stub + with qtbot.assertNotEmitted(client.success): + with qtbot.waitSignal(client.error): + client.on_client_success(http) + From a84c8ac247513318dce19a4b3c6f033e520a50d7 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Mon, 22 Feb 2016 17:39:34 +0100 Subject: [PATCH 013/327] tests: add workaround for QPainter bug As suggested in the github discussion. --- tests/integration/features/misc.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/integration/features/misc.feature b/tests/integration/features/misc.feature index bec5a65b9..416836b3b 100644 --- a/tests/integration/features/misc.feature +++ b/tests/integration/features/misc.feature @@ -292,7 +292,11 @@ Feature: Various utility commands. Scenario: Downloading a pdf via pdf.js button (issue 1214) Given pdfjs is available - When I set content -> enable-pdfjs to true + # WORKAROUND to prevent the "Painter ended with 2 saved states" warning + # Might be related to https://bugreports.qt.io/browse/QTBUG-13524 and + # a weird interaction with the previous test. + When I wait 0.5s + And I set content -> enable-pdfjs to true And I set completion -> download-path-suggestion to filename And I set storage -> prompt-download-directory to true And I open data/misc/test.pdf From c9bb6d01119c53f250459a96505759e5ed5f56e3 Mon Sep 17 00:00:00 2001 From: avk Date: Mon, 22 Feb 2016 20:46:22 +0100 Subject: [PATCH 014/327] tests for browser.network.pastebin - code refactor --- scripts/dev/check_coverage.py | 2 + tests/unit/browser/network/test_pastebin.py | 114 ++++++++++++-------- 2 files changed, 71 insertions(+), 45 deletions(-) diff --git a/scripts/dev/check_coverage.py b/scripts/dev/check_coverage.py index ff5bc01f5..939fd5e71 100644 --- a/scripts/dev/check_coverage.py +++ b/scripts/dev/check_coverage.py @@ -65,6 +65,8 @@ PERFECT_FILES = [ 'qutebrowser/browser/network/filescheme.py'), ('tests/unit/browser/network/test_networkreply.py', 'qutebrowser/browser/network/networkreply.py'), + ('tests/unit/browser/network/test_pastebin.py', + 'qutebrowser/browser/network/pastebin.py'), ('tests/unit/browser/test_signalfilter.py', 'qutebrowser/browser/signalfilter.py'), diff --git a/tests/unit/browser/network/test_pastebin.py b/tests/unit/browser/network/test_pastebin.py index 1e237d58c..d72c9f6b8 100644 --- a/tests/unit/browser/network/test_pastebin.py +++ b/tests/unit/browser/network/test_pastebin.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . -"""Tests for qutebrowser.browser.network""" +"""Tests for qutebrowser.browser.network.""" import pytest from PyQt5.QtCore import QUrl @@ -25,15 +25,6 @@ from PyQt5.QtCore import QUrl from qutebrowser.browser.network import pastebin from qutebrowser.misc import httpclient -DATA = [{"name" : "XYZ", "title" : "hello world", "text" : "xyz. 123 \n 172ANB", "reply" : "abc" }, - {"name" : "the name", "title" : "the title", "text" : "some Text", "reply" : "some parent"}] - -DATA_NOPARENT = [{"name" : "XYZ", "title" : "hello world", "text" : "xyz. 123 \n 172ANB"}, - {"name" : "the name", "title" : "the title", "text" : "some Text"}] - -HTTP_VALID = ["http://paste.the-compiler.org/view/ges83nt3", "http://paste.the-compiler.org/view/3gjnwg4"] - -HTTP_INVALID = ["http invalid", "http:/invalid.org"] class HTTPPostStub(httpclient.HTTPClient): @@ -46,50 +37,83 @@ class HTTPPostStub(httpclient.HTTPClient): def __init__(self): super().__init__() - - def post(self, url, data): + self.url = None + self.data = None + + def post(self, url, data=None): self.url = url self.data = data +@pytest.fixture +def pbclient(): + client = pastebin.PastebinClient() + http_stub = HTTPPostStub() + client._client = http_stub + return client + def test_constructor(qapp): - client = pastebin.PastebinClient() - assert isinstance(client._client, httpclient.HTTPClient) + pbclient = pastebin.PastebinClient() + assert isinstance(pbclient._client, httpclient.HTTPClient) -@pytest.mark.parametrize('data', DATA) -def test_paste_with_parent(data): - client = pastebin.PastebinClient() - http_stub = HTTPPostStub() - client._client = http_stub - client.paste(data["name"], data["title"], data["text"], data["reply"]) - assert http_stub.data == data - assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create') - -@pytest.mark.parametrize('data', DATA_NOPARENT) -def test_paste_without_parent(data): - client = pastebin.PastebinClient() - http_stub = HTTPPostStub() - client._client = http_stub - client.paste(data["name"], data["title"], data["text"]) + +@pytest.mark.parametrize('data', [ + { + "name": "XYZ", + "title": "hello world", + "text": "xyz. 123 \n 172ANB", + "reply": "abc" + }, + { + "name": "the name", + "title": "the title", + "text": "some Text", + "reply": "some parent" + } +]) +def test_paste_with_parent(data, pbclient): + http_stub = pbclient._client + pbclient.paste(data["name"], data["title"], data["text"], data["reply"]) assert http_stub.data == data assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create') -@pytest.mark.parametrize('http', HTTP_VALID) -def test_on_client_success(http, qtbot): - client = pastebin.PastebinClient() - http_stub = HTTPPostStub() - client._client = http_stub - with qtbot.assertNotEmitted(client.error): - with qtbot.waitSignal(client.success): - client.on_client_success(http) -@pytest.mark.parametrize('http', HTTP_INVALID) -def test_on_client_success_invalid_http(http, qtbot): - client = pastebin.PastebinClient() - http_stub = HTTPPostStub() - client._client = http_stub - with qtbot.assertNotEmitted(client.success): - with qtbot.waitSignal(client.error): - client.on_client_success(http) +@pytest.mark.parametrize('data', [ + { + "name": "XYZ", + "title": "hello world", + "text": "xyz. 123 \n 172ANB" + }, + { + "name": "the name", + "title": "the title", + "text": "some Text" + } +]) +def test_paste_without_parent(data, pbclient): + http_stub = pbclient._client + pbclient.paste(data["name"], data["title"], data["text"]) + assert pbclient._client.data == data + assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create') + +@pytest.mark.parametrize('http', [ + "http://paste.the-compiler.org/view/ges83nt3", + "http://paste.the-compiler.org/view/3gjnwg4" +]) +def test_on_client_success(http, pbclient, qtbot): + with qtbot.assertNotEmitted(pbclient.error): + with qtbot.waitSignal(pbclient.success): + pbclient.on_client_success(http) + + +@pytest.mark.parametrize('http', [ + "http invalid", + "http:/invalid.org" + "http//invalid.com" +]) +def test_on_client_success_invalid_http(http, pbclient, qtbot): + with qtbot.assertNotEmitted(pbclient.success): + with qtbot.waitSignal(pbclient.error): + pbclient.on_client_success(http) From a382b366bcd0e2ddff71f07ae701626f0ba48e00 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Mon, 22 Feb 2016 21:46:54 +0100 Subject: [PATCH 015/327] tests: increase wait time Otherwise the test might still fail on some systems --- tests/integration/features/misc.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/features/misc.feature b/tests/integration/features/misc.feature index 416836b3b..8fa35c558 100644 --- a/tests/integration/features/misc.feature +++ b/tests/integration/features/misc.feature @@ -295,7 +295,7 @@ Feature: Various utility commands. # WORKAROUND to prevent the "Painter ended with 2 saved states" warning # Might be related to https://bugreports.qt.io/browse/QTBUG-13524 and # a weird interaction with the previous test. - When I wait 0.5s + When I wait 1s And I set content -> enable-pdfjs to true And I set completion -> download-path-suggestion to filename And I set storage -> prompt-download-directory to true From e5dc10a29eddd3dbf2cad5e523b331ff67ff0e70 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Mon, 22 Feb 2016 23:38:18 +0100 Subject: [PATCH 016/327] downloads: handle relative XDG_DOWNLOAD_DIR Issues #1269, #866 qutebrowser would crash when XDG_DOWNLOAD_DIR was set to some non-absolute value (which should not happen, but it can) and "storage -> download-dir" was empty, since when the user didn't give an absolute filename, even the joined path of download_dir() (i.e. XDG_DOWNLOAD_DIR in this case) and the filename was not absolute either. Since the path was not absolute, create_full_filename returned None, which meant that os.path.basename(self._filename) raised an exception. Now we display an error message and fall back to $HOME. --- CHANGELOG.asciidoc | 1 + qutebrowser/browser/downloads.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 4a79c8543..6b52eba9b 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -51,6 +51,7 @@ Fixed - Fixed crashes when opening an empty URL (e.g. via pasting). - Fixed validation of duplicate values in `hints -> chars`. - Fixed crash when PDF.js was partially installed. +- Fixed crash when XDG_DOWNLOAD_DIR was not an absolute path. v0.5.1 ------ diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 8c977fb34..d9d412f1e 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -534,6 +534,22 @@ class DownloadItem(QObject): self._filename = create_full_filename( self.basename, os.path.join(download_dir(), filename)) + # At this point, we have a misconfigured XDG_DOWNLOAd_DIR, as + # download_dir() + filename is still no absolute path. + # The config value is checked for "absoluteness", but + # ~/.config/user-dirs.dirs may be misconfigured and a non-absolute path + # may be set for XDG_DOWNLOAD_DIR + if self._filename is None: + message.error( + self._win_id, + "XDG_DOWNLOAD_DIR points to a relative path - please check" + " your ~/.config/user-dirs.dirs. The download is saved in your " + "home directory.", + ) + # fall back to $HOME as download_dir + self._filename = create_full_filename( + self.basename, os.path.expanduser(os.path.join('~', filename))) + self.basename = os.path.basename(self._filename) last_used_directory = os.path.dirname(self._filename) From 0df4da5b9119b57a2687cbd3679076af79b781b3 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 23 Feb 2016 08:47:53 +0100 Subject: [PATCH 017/327] Also display XDG_* in crash reports --- qutebrowser/misc/crashdialog.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/misc/crashdialog.py b/qutebrowser/misc/crashdialog.py index 213c38187..161ce9308 100644 --- a/qutebrowser/misc/crashdialog.py +++ b/qutebrowser/misc/crashdialog.py @@ -96,7 +96,8 @@ def get_fatal_crash_dialog(debug, data): def _get_environment_vars(): """Gather environment variables for the crash info.""" - masks = ('DESKTOP_SESSION', 'DE', 'QT_*', 'PYTHON*', 'LC_*', 'LANG') + masks = ('DESKTOP_SESSION', 'DE', 'QT_*', 'PYTHON*', 'LC_*', 'LANG', + 'XDG_*') info = [] for key, value in os.environ.items(): for m in masks: From 20daf1f86ec24a1a84335c938325253c1f8e7648 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Tue, 23 Feb 2016 14:33:10 +0100 Subject: [PATCH 018/327] fix lint --- qutebrowser/browser/downloads.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index d9d412f1e..a3453513b 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -543,8 +543,8 @@ class DownloadItem(QObject): message.error( self._win_id, "XDG_DOWNLOAD_DIR points to a relative path - please check" - " your ~/.config/user-dirs.dirs. The download is saved in your " - "home directory.", + " your ~/.config/user-dirs.dirs. The download is saved in" + " your home directory.", ) # fall back to $HOME as download_dir self._filename = create_full_filename( From 2dfce2060293928a4bee3fc1f35ff523214f0156 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 24 Feb 2016 20:11:40 +0100 Subject: [PATCH 019/327] tox: Update hypothesis to 3.0.4. - Fix version parsing of py.test to work with py.test release candidates - More general handling of the health check problem where things could fail because of a cache miss - now one "free" example is generated before the start of the health check run. - Fix a bug where Hypothesis would error when running on Python 2.7.3 or earlier because it was trying to pass a bytearray object to struct.unpack (which is only supported since 2.7.4). --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 9166a4bc1..5d488c3e6 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ deps = Flask==0.10.1 glob2==0.4.1 httpbin==0.4.1 - hypothesis==3.0.2 + hypothesis==3.0.4 itsdangerous==0.24 Mako==1.0.3 parse==1.6.6 From 8c6c976afc42c16f0523b55acf880cbc89591f97 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 24 Feb 2016 20:14:14 +0100 Subject: [PATCH 020/327] tox: Update pytest-html to 1.8.0. - Remove duplication from the environment section - Dropped support for Python 3.2 - Indicated setup and teardown in report - Fixed colour of errors in report --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 5d488c3e6..f24d4094d 100644 --- a/tox.ini +++ b/tox.ini @@ -31,7 +31,7 @@ deps = pytest-catchlog==1.2.2 pytest-cov==2.2.1 pytest-faulthandler==1.3.0 - pytest-html==1.7 + pytest-html==1.8.0 pytest-mock==0.10.1 pytest-qt==1.11.0 pytest-instafail==0.3.0 From 7c90f8900cabac9951ba7ae105e8dc95e5b1b8a9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 24 Feb 2016 20:15:10 +0100 Subject: [PATCH 021/327] tox: Update pytest-mock to 0.11.0. - PropertyMock is now accessible from mocker. - Fix regression using one of the assert_* methods in patched functions which receive a parameter named method. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index f24d4094d..cf582be74 100644 --- a/tox.ini +++ b/tox.ini @@ -32,7 +32,7 @@ deps = pytest-cov==2.2.1 pytest-faulthandler==1.3.0 pytest-html==1.8.0 - pytest-mock==0.10.1 + pytest-mock==0.11.0 pytest-qt==1.11.0 pytest-instafail==0.3.0 pytest-travis-fold==1.2.0 From 10f9ac6c2794121caed384fa722ef503a9f1664e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 25 Feb 2016 21:12:47 +0100 Subject: [PATCH 022/327] tox: Update hypothesis to 3.0.5 - Fix a bug where Hypothesis would now error on py.test development versions. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index cf582be74..239b342e6 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ deps = Flask==0.10.1 glob2==0.4.1 httpbin==0.4.1 - hypothesis==3.0.4 + hypothesis==3.0.5 itsdangerous==0.24 Mako==1.0.3 parse==1.6.6 From 2e12fb3c657e1d74dc5e288bbdd7642494420440 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 27 Feb 2016 00:26:24 +0100 Subject: [PATCH 023/327] Use pytest-platform-markers --- pytest.ini | 8 -------- tests/conftest.py | 22 +++------------------- tox.ini | 1 + 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/pytest.ini b/pytest.ini index e52ef27d8..b0e51fdf8 100644 --- a/pytest.ini +++ b/pytest.ini @@ -3,20 +3,12 @@ norecursedirs = .tox .venv addopts = --strict -rfEsw --faulthandler-timeout=70 --instafail markers = gui: Tests using the GUI (e.g. spawning widgets) - posix: Tests which only can run on a POSIX OS. - windows: Tests which only can run on Windows. - linux: Tests which only can run on Linux. - osx: Tests which only can run on OS X. - not_osx: Tests which can not run on OS X. - not_frozen: Tests which can't be run if sys.frozen is True. no_xvfb: Tests which can't be run with Xvfb. - frozen: Tests which can only be run if sys.frozen is True. integration: Tests which test a bigger portion of code, run without coverage. skip: Always skipped test. pyqt531_or_newer: Needs PyQt 5.3.1 or newer. xfail_norun: xfail the test with out running it flaky: Tests which are flaky and should be rerun - ci: Tests which should only run on CI. qt_log_level_fail = WARNING qt_log_ignore = ^SpellCheck: .* diff --git a/tests/conftest.py b/tests/conftest.py index bdfd96510..f0552b47b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -45,33 +45,17 @@ hypothesis.settings.load_profile('default') def _apply_platform_markers(item): """Apply a skip marker to a given item.""" markers = [ - ('posix', os.name != 'posix', "Requires a POSIX os"), - ('windows', os.name != 'nt', "Requires Windows"), - ('linux', not sys.platform.startswith('linux'), "Requires Linux"), - ('osx', sys.platform != 'darwin', "Requires OS X"), - ('not_osx', sys.platform == 'darwin', "Skipped on OS X"), - ('not_frozen', getattr(sys, 'frozen', False), - "Can't be run when frozen"), - ('frozen', not getattr(sys, 'frozen', False), - "Can only run when frozen"), ('skip', True, "Always skipped."), ('pyqt531_or_newer', PYQT_VERSION < 0x050301, - "Needs PyQt 5.3.1 or newer"), - ('ci', 'CI' not in os.environ, "Only runs on CI."), + "Needs PyQt 5.3.1 or newer."), ] - for searched_marker, condition, default_reason in markers: + for searched_marker, condition, reason in markers: marker = item.get_marker(searched_marker) if not marker or not condition: continue - if 'reason' in marker.kwargs: - reason = '{}: {}'.format(default_reason, marker.kwargs['reason']) - del marker.kwargs['reason'] - else: - reason = default_reason + '.' - skipif_marker = pytest.mark.skipif(condition, *marker.args, - reason=reason, **marker.kwargs) + skipif_marker = pytest.mark.skipif(condition, reason=reason) item.add_marker(skipif_marker) diff --git a/tox.ini b/tox.ini index 239b342e6..6a08f392f 100644 --- a/tox.ini +++ b/tox.ini @@ -39,6 +39,7 @@ deps = pytest-repeat==0.2 pytest-rerunfailures==1.0.1 pytest-xvfb==0.1.0 + pytest-platform-markers==0.1.0 six==1.10.0 termcolor==1.1.0 vulture==0.8.1 From 83e86706ffcbf42f5bd8431e628f6a8c6ec4fc8d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 27 Feb 2016 02:14:34 +0100 Subject: [PATCH 024/327] tests: Make check for ddg being loaded less strict Before this change, adding a new logging message involving logging e.g. the default duckduckgo setting value failed. Now we basically use a black- instead of a whitelist and only fail if we get a load status message for duckduckgo. --- tests/integration/quteprocess.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/integration/quteprocess.py b/tests/integration/quteprocess.py index 5b9fb3281..191730e98 100644 --- a/tests/integration/quteprocess.py +++ b/tests/integration/quteprocess.py @@ -264,12 +264,12 @@ class QuteProc(testprocess.Process): testutils.pattern_match(pattern='[*] [FAIL] *', value=msg.message)) # Try to complain about the most common mistake when accidentally - # loading external resources. A fuzzy_url line gets logged when - # initializing settings though, so ignore those. - is_ddg_page = ( - 'duckduckgo' in msg.message and not (msg.module == 'urlutils' and - msg.function == 'fuzzy_url')) - return msg.loglevel > logging.INFO or is_js_error or is_ddg_page + # loading external resources. + is_ddg_load = testutils.pattern_match( + pattern="load status for : *", + value=msg.message) + return msg.loglevel > logging.INFO or is_js_error or is_ddg_load def _maybe_skip(self): """Skip the test if [SKIP] lines were logged.""" From fab86cce5efbdef3fe0e41267fb80d0a43d70711 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 27 Feb 2016 02:25:08 +0100 Subject: [PATCH 025/327] tox: Update pytest-xvfb to 0.2.0 - The ``no_xvfb``-marker is now registered automatically so pytest doesn't fail when run with ``--strict``. - The ``xvfb`` fixture is now session-scoped. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 6a08f392f..05418a32c 100644 --- a/tox.ini +++ b/tox.ini @@ -38,7 +38,7 @@ deps = pytest-travis-fold==1.2.0 pytest-repeat==0.2 pytest-rerunfailures==1.0.1 - pytest-xvfb==0.1.0 + pytest-xvfb==0.2.0 pytest-platform-markers==0.1.0 six==1.10.0 termcolor==1.1.0 From 0f5b4d58e22857230cbd487c3a1bde7fd8a18399 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 27 Feb 2016 02:40:30 +0100 Subject: [PATCH 026/327] pytest.ini: Remove registration of flaky marker It's already registered by the plugin. --- pytest.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index b0e51fdf8..e8717adef 100644 --- a/pytest.ini +++ b/pytest.ini @@ -8,7 +8,6 @@ markers = skip: Always skipped test. pyqt531_or_newer: Needs PyQt 5.3.1 or newer. xfail_norun: xfail the test with out running it - flaky: Tests which are flaky and should be rerun qt_log_level_fail = WARNING qt_log_ignore = ^SpellCheck: .* From a4687c6745aede8ee65b5f6e9d7480e4ef31e9e9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 27 Feb 2016 02:41:01 +0100 Subject: [PATCH 027/327] Fix lint --- tests/integration/quteprocess.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/quteprocess.py b/tests/integration/quteprocess.py index 191730e98..cad527ac4 100644 --- a/tests/integration/quteprocess.py +++ b/tests/integration/quteprocess.py @@ -266,9 +266,9 @@ class QuteProc(testprocess.Process): # Try to complain about the most common mistake when accidentally # loading external resources. is_ddg_load = testutils.pattern_match( - pattern="load status for : *", - value=msg.message) + pattern="load status for : *", + value=msg.message) return msg.loglevel > logging.INFO or is_js_error or is_ddg_load def _maybe_skip(self): From 48f87d1656b7faaa60c1136c5203a8297046ed53 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 27 Feb 2016 02:45:34 +0100 Subject: [PATCH 028/327] Revert "Use pytest-platform-markers" This reverts commit 2e12fb3c657e1d74dc5e288bbdd7642494420440. It seems like it's currently broken... --- pytest.ini | 8 ++++++++ tests/conftest.py | 22 +++++++++++++++++++--- tox.ini | 1 - 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/pytest.ini b/pytest.ini index e8717adef..017506411 100644 --- a/pytest.ini +++ b/pytest.ini @@ -3,11 +3,19 @@ norecursedirs = .tox .venv addopts = --strict -rfEsw --faulthandler-timeout=70 --instafail markers = gui: Tests using the GUI (e.g. spawning widgets) + posix: Tests which only can run on a POSIX OS. + windows: Tests which only can run on Windows. + linux: Tests which only can run on Linux. + osx: Tests which only can run on OS X. + not_osx: Tests which can not run on OS X. + not_frozen: Tests which can't be run if sys.frozen is True. no_xvfb: Tests which can't be run with Xvfb. + frozen: Tests which can only be run if sys.frozen is True. integration: Tests which test a bigger portion of code, run without coverage. skip: Always skipped test. pyqt531_or_newer: Needs PyQt 5.3.1 or newer. xfail_norun: xfail the test with out running it + ci: Tests which should only run on CI. qt_log_level_fail = WARNING qt_log_ignore = ^SpellCheck: .* diff --git a/tests/conftest.py b/tests/conftest.py index f0552b47b..bdfd96510 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -45,17 +45,33 @@ hypothesis.settings.load_profile('default') def _apply_platform_markers(item): """Apply a skip marker to a given item.""" markers = [ + ('posix', os.name != 'posix', "Requires a POSIX os"), + ('windows', os.name != 'nt', "Requires Windows"), + ('linux', not sys.platform.startswith('linux'), "Requires Linux"), + ('osx', sys.platform != 'darwin', "Requires OS X"), + ('not_osx', sys.platform == 'darwin', "Skipped on OS X"), + ('not_frozen', getattr(sys, 'frozen', False), + "Can't be run when frozen"), + ('frozen', not getattr(sys, 'frozen', False), + "Can only run when frozen"), ('skip', True, "Always skipped."), ('pyqt531_or_newer', PYQT_VERSION < 0x050301, - "Needs PyQt 5.3.1 or newer."), + "Needs PyQt 5.3.1 or newer"), + ('ci', 'CI' not in os.environ, "Only runs on CI."), ] - for searched_marker, condition, reason in markers: + for searched_marker, condition, default_reason in markers: marker = item.get_marker(searched_marker) if not marker or not condition: continue - skipif_marker = pytest.mark.skipif(condition, reason=reason) + if 'reason' in marker.kwargs: + reason = '{}: {}'.format(default_reason, marker.kwargs['reason']) + del marker.kwargs['reason'] + else: + reason = default_reason + '.' + skipif_marker = pytest.mark.skipif(condition, *marker.args, + reason=reason, **marker.kwargs) item.add_marker(skipif_marker) diff --git a/tox.ini b/tox.ini index 05418a32c..6c5e7846d 100644 --- a/tox.ini +++ b/tox.ini @@ -39,7 +39,6 @@ deps = pytest-repeat==0.2 pytest-rerunfailures==1.0.1 pytest-xvfb==0.2.0 - pytest-platform-markers==0.1.0 six==1.10.0 termcolor==1.1.0 vulture==0.8.1 From 4aa7649c0a9b780dd1897f8017f6a7da40db5331 Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Tue, 23 Feb 2016 07:52:45 +0100 Subject: [PATCH 029/327] Implemented heurisitc on multiline paste --- qutebrowser/browser/commands.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 586573948..faa5be6ee 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -820,8 +820,10 @@ class CommandDispatcher: raise cmdexc.CommandError("{} is empty.".format(target)) log.misc.debug("{} contained: '{}'".format(target, text.replace('\n', '\\n'))) - text_urls = enumerate(u for u in text.split('\n') if u.strip()) - for i, text_url in text_urls: + text_urls = [u for u in text.split('\n') if u.strip()] + if len(text_urls) > 1 and not urlutils.is_url(text_urls[0]): + text_urls = [text] + for i, text_url in enumerate(text_urls): if not window and i > 0: tab = False bg = True From 594b0d29106f49862b6fb69587c8cea76051bf8f Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Fri, 26 Feb 2016 07:59:51 +0100 Subject: [PATCH 030/327] Refactors path validity check to its own function --- qutebrowser/utils/urlutils.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index e70a09f2d..54a55dd9b 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -348,6 +348,40 @@ def raise_cmdexc_if_invalid(url): if not url.isValid(): raise cmdexc.CommandError(get_errstring(url)) +def get_path_if_valid(pathstr, cwd = None, relative=False, check_exists = False): + """Check if path is a valid path + + Args: + pathstr: The path as string + + Return: + True if it is a valid path, False otherwise. + """ + log.url.debug("Checking if '{}' is a path".format(pathstr)) + + pathstr = pathstr.strip() + expanded = os.path.expanduser(pathstr) + + if os.path.isabs(expanded): + path = expanded + elif relative and cwd: + path = os.path.join(cwd, expanded) + elif relative: + try: + path = os.path.abspath(expanded) + except OSError: + path = None + else: + path = None + + if check_exists: + if path is not None and os.path.exists(path): + log.url.debug("URL is a local file") + else: + path = None + + return path + def filename_from_url(url): """Get a suitable filename from an URL. From 4500bc24d4073f1d7fc615f96024167400743ae3 Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Fri, 26 Feb 2016 08:01:06 +0100 Subject: [PATCH 031/327] fuzzy_url uses path check function --- qutebrowser/utils/urlutils.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index 54a55dd9b..723f2c62f 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -171,22 +171,10 @@ def fuzzy_url(urlstr, cwd=None, relative=False, do_search=True): A target QUrl to a search page or the original URL. """ urlstr = urlstr.strip() - expanded = os.path.expanduser(urlstr) + path = get_path_if_valid(urlstr, cwd = cwd, relative = relative, + check_exists = True) - if os.path.isabs(expanded): - path = expanded - elif relative and cwd: - path = os.path.join(cwd, expanded) - elif relative: - try: - path = os.path.abspath(expanded) - except OSError: - path = None - else: - path = None - - if path is not None and os.path.exists(path): - log.url.debug("URL is a local file") + if path is not None: url = QUrl.fromLocalFile(path) elif (not do_search) or is_url(urlstr): # probably an address From 006d8760c4fe620f854fbf7d5ca75cdb4838a6c8 Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Fri, 26 Feb 2016 08:01:44 +0100 Subject: [PATCH 032/327] Adds path checking to the multiline url heuristic --- qutebrowser/browser/commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index faa5be6ee..44418864f 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -821,7 +821,8 @@ class CommandDispatcher: log.misc.debug("{} contained: '{}'".format(target, text.replace('\n', '\\n'))) text_urls = [u for u in text.split('\n') if u.strip()] - if len(text_urls) > 1 and not urlutils.is_url(text_urls[0]): + if len(text_urls) > 1 and not urlutils.is_url(text_urls[0]) \ + and urlutils.get_path_if_valid(text_urls[0], check_exists = True) is None: text_urls = [text] for i, text_url in enumerate(text_urls): if not window and i > 0: From 702b235981cb431149308260b12b7db50e7a2966 Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Fri, 26 Feb 2016 10:00:49 +0100 Subject: [PATCH 033/327] Fixes formatting to make pylint happy. --- qutebrowser/browser/commands.py | 3 ++- qutebrowser/utils/urlutils.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 44418864f..fd1e12990 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -822,7 +822,8 @@ class CommandDispatcher: text.replace('\n', '\\n'))) text_urls = [u for u in text.split('\n') if u.strip()] if len(text_urls) > 1 and not urlutils.is_url(text_urls[0]) \ - and urlutils.get_path_if_valid(text_urls[0], check_exists = True) is None: + and urlutils.get_path_if_valid(text_urls[0], + check_exists=True) is not None: text_urls = [text] for i, text_url in enumerate(text_urls): if not window and i > 0: diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index 723f2c62f..3f79cb87c 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -171,8 +171,8 @@ def fuzzy_url(urlstr, cwd=None, relative=False, do_search=True): A target QUrl to a search page or the original URL. """ urlstr = urlstr.strip() - path = get_path_if_valid(urlstr, cwd = cwd, relative = relative, - check_exists = True) + path = get_path_if_valid(urlstr, cwd=cwd, relative=relative, + check_exists=True) if path is not None: url = QUrl.fromLocalFile(path) @@ -336,7 +336,7 @@ def raise_cmdexc_if_invalid(url): if not url.isValid(): raise cmdexc.CommandError(get_errstring(url)) -def get_path_if_valid(pathstr, cwd = None, relative=False, check_exists = False): +def get_path_if_valid(pathstr, cwd=None, relative=False, check_exists=False): """Check if path is a valid path Args: From 67ebdc6eb6994d937c7fbbabcc15e9bc964ad2ea Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Fri, 26 Feb 2016 10:02:41 +0100 Subject: [PATCH 034/327] Fixes the position of the logging line --- qutebrowser/utils/urlutils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index 3f79cb87c..42f222a42 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -345,9 +345,8 @@ def get_path_if_valid(pathstr, cwd=None, relative=False, check_exists=False): Return: True if it is a valid path, False otherwise. """ - log.url.debug("Checking if '{}' is a path".format(pathstr)) - pathstr = pathstr.strip() + log.url.debug("Checking if '{}' is a path".format(pathstr)) expanded = os.path.expanduser(pathstr) if os.path.isabs(expanded): From 79ad65ee649e8357881c5a17a49af4e7077c238d Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Sat, 27 Feb 2016 12:36:13 +0100 Subject: [PATCH 035/327] Fixes flake8 errors --- qutebrowser/utils/urlutils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index 42f222a42..e7e2ebe97 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -336,11 +336,12 @@ def raise_cmdexc_if_invalid(url): if not url.isValid(): raise cmdexc.CommandError(get_errstring(url)) + def get_path_if_valid(pathstr, cwd=None, relative=False, check_exists=False): - """Check if path is a valid path + """Check if path is a valid path. Args: - pathstr: The path as string + pathstr: The path as string. Return: True if it is a valid path, False otherwise. From 108d0c87632f7182304aa83550d9d2a3ea7ea2d7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 28 Feb 2016 14:47:24 +0100 Subject: [PATCH 036/327] tox: Update flake8-deprecated to 1.0. - Warn if using xmlconfig.file, self.loadZCML is the preferred option. - Avoid false reports by suffixing an opening parenthesis on all methods. - Add decorators from zope.interface and zope.component. Due to the bugfix we can also remove the D001 suppression. --- setup.cfg | 2 -- tox.ini | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index 307403556..7f28c527d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -22,7 +22,6 @@ exclude = .venv,.hypothesis,.git,__pycache__,resources.py # P101: format string does contain unindexed parameters # P102: docstring does contain unindexed parameters # P103: other string does contain unindexed parameters -# D001: found assert_ replace it with assertTrue # D102: Missing docstring in public method (will be handled by others) # D103: Missing docstring in public function (will be handled by others) # D104: Missing docstring in public package (will be handled by others) @@ -37,7 +36,6 @@ ignore = N802, L101,L102,L103,L201,L202,L203,L204,L207,L302, P101,P102,P103, - D001, D102,D103,D104,D105,D209,D211,D402 max-complexity = 12 putty-ignore = diff --git a/tox.ini b/tox.ini index 6c5e7846d..ecfd09496 100644 --- a/tox.ini +++ b/tox.ini @@ -164,7 +164,7 @@ deps = pep8==1.7.0 pyflakes==1.0.0 flake8-string-format==0.2.1 - flake8-deprecated==0.2 + flake8-deprecated==1.0 flake8-mock==0.2 flake8-pep3101==0.2 flake8-docstrings==0.2.5 From 5395e0f6e288d3ec8e462479481975df04224ba4 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 28 Feb 2016 15:26:18 +0100 Subject: [PATCH 037/327] tests: Use a fresh instance as a workaround Waiting seems like a perfect recipe for another flaky test, so let's better be safe. --- tests/integration/features/misc.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/features/misc.feature b/tests/integration/features/misc.feature index 8fa35c558..c838323a1 100644 --- a/tests/integration/features/misc.feature +++ b/tests/integration/features/misc.feature @@ -295,8 +295,8 @@ Feature: Various utility commands. # WORKAROUND to prevent the "Painter ended with 2 saved states" warning # Might be related to https://bugreports.qt.io/browse/QTBUG-13524 and # a weird interaction with the previous test. - When I wait 1s - And I set content -> enable-pdfjs to true + And I have a fresh instance + When I set content -> enable-pdfjs to true And I set completion -> download-path-suggestion to filename And I set storage -> prompt-download-directory to true And I open data/misc/test.pdf From 0ab44c4f4a0b85662d8be482dc1fe0a7353ee1d0 Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Sun, 28 Feb 2016 23:41:20 +0100 Subject: [PATCH 038/327] Reformats code as requested --- qutebrowser/browser/commands.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index fd1e12990..312e7c534 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -821,9 +821,9 @@ class CommandDispatcher: log.misc.debug("{} contained: '{}'".format(target, text.replace('\n', '\\n'))) text_urls = [u for u in text.split('\n') if u.strip()] - if len(text_urls) > 1 and not urlutils.is_url(text_urls[0]) \ - and urlutils.get_path_if_valid(text_urls[0], - check_exists=True) is not None: + if (len(text_urls) > 1 and not urlutils.is_url(text_urls[0]) and + urlutils.get_path_if_valid( + text_urls[0], check_exists=True) is None): text_urls = [text] for i, text_url in enumerate(text_urls): if not window and i > 0: From d8ad0a14af122e237bd63f9de53913930ede7385 Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Sun, 28 Feb 2016 23:42:14 +0100 Subject: [PATCH 039/327] Fixes wrong documentation --- qutebrowser/utils/urlutils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index e7e2ebe97..73f8d6569 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -342,9 +342,13 @@ def get_path_if_valid(pathstr, cwd=None, relative=False, check_exists=False): Args: pathstr: The path as string. + cwd: The current working directory, or None. + relative: Whether to resolve relative files. + check_exists: Whether to check if the file + actually exists of filesystem. Return: - True if it is a valid path, False otherwise. + The path if it is a valid path, None otherwise. """ pathstr = pathstr.strip() log.url.debug("Checking if '{}' is a path".format(pathstr)) From 89ac5cba6226b7989b50ce3b3f29fadc1673737c Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Sun, 28 Feb 2016 23:43:38 +0100 Subject: [PATCH 040/327] Adds test to reach 100% coverage on urlutils --- tests/unit/utils/test_urlutils.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/unit/utils/test_urlutils.py b/tests/unit/utils/test_urlutils.py index bb2778765..99e1eac56 100644 --- a/tests/unit/utils/test_urlutils.py +++ b/tests/unit/utils/test_urlutils.py @@ -238,6 +238,18 @@ class TestFuzzyUrl: with pytest.raises(urlutils.InvalidUrlError): urlutils.fuzzy_url(url, do_search=True) + @pytest.mark.parametrize('path, check_exists', [ + ('/foo', False), + ('/bar', True), + ]) + def test_get_path_existing(self, path, check_exists, os_mock): + """Test with an absolute path.""" + os_mock.path.exists.return_value = False + expected = None if check_exists else path + + url = urlutils.get_path_if_valid(path, check_exists=check_exists) + assert url == expected + @pytest.mark.parametrize('url, special', [ ('file:///tmp/foo', True), From a9fdf09a047b29158d7d97d389e42979793fa92f Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Sun, 28 Feb 2016 23:44:26 +0100 Subject: [PATCH 041/327] Adds test of the heuristic --- tests/integration/features/yankpaste.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/integration/features/yankpaste.feature b/tests/integration/features/yankpaste.feature index b1e329ce9..ce6ec2b1a 100644 --- a/tests/integration/features/yankpaste.feature +++ b/tests/integration/features/yankpaste.feature @@ -126,6 +126,18 @@ Feature: Yanking and pasting. - data/hello2.txt - data/hello3.txt + Scenario: Pasting multiline text + Given I have a fresh instance + When I set searchengines -> DEFAULT to http://localhost:(port)/data/hello.txt?q={} + And I put the following lines into the clipboard: + this url: + http://qutebrowser.org + should not open + And I run :paste -t + Then the following tabs should be open: + - about:blank + - data/hello.txt?q=this%20url%3A%0Ahttp%3A//qutebrowser.org%0Ashould%20not%20open (active) + Scenario: Pasting multiple urls in a background tab Given I open about:blank When I run :tab-only From 25bc2dc1db772d614d38824664a77566d8786e2d Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Sun, 28 Feb 2016 23:45:02 +0100 Subject: [PATCH 042/327] Changes formatters to print multiline text on one line --- qutebrowser/browser/commands.py | 3 +-- qutebrowser/utils/urlutils.py | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 312e7c534..8b820c078 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -818,8 +818,7 @@ class CommandDispatcher: text = utils.get_clipboard(selection=sel) if not text.strip(): raise cmdexc.CommandError("{} is empty.".format(target)) - log.misc.debug("{} contained: '{}'".format(target, - text.replace('\n', '\\n'))) + log.misc.debug("{} contained: {!r}".format(target, text)) text_urls = [u for u in text.split('\n') if u.strip()] if (len(text_urls) > 1 and not urlutils.is_url(text_urls[0]) and urlutils.get_path_if_valid( diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index 73f8d6569..ac9a49c7e 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -80,7 +80,7 @@ def _parse_search_term(s): engine = None term = s - log.url.debug("engine {}, term '{}'".format(engine, term)) + log.url.debug("engine {}, term {!r}".format(engine, term)) return (engine, term) @@ -93,7 +93,7 @@ def _get_search_url(txt): Return: The search URL as a QUrl. """ - log.url.debug("Finding search engine for '{}'".format(txt)) + log.url.debug("Finding search engine for {!r}".format(txt)) engine, term = _parse_search_term(txt) assert term if engine is None: @@ -186,7 +186,7 @@ def fuzzy_url(urlstr, cwd=None, relative=False, do_search=True): url = _get_search_url(urlstr) except ValueError: # invalid search engine url = qurl_from_user_input(urlstr) - log.url.debug("Converting fuzzy term {} to URL -> {}".format( + log.url.debug("Converting fuzzy term {!r} to URL -> {}".format( urlstr, url.toDisplayString())) if do_search and config.get('general', 'auto-search') and urlstr: qtutils.ensure_valid(url) @@ -234,7 +234,7 @@ def is_url(urlstr): """ autosearch = config.get('general', 'auto-search') - log.url.debug("Checking if '{}' is a URL (autosearch={}).".format( + log.url.debug("Checking if {!r} is a URL (autosearch={}).".format( urlstr, autosearch)) urlstr = urlstr.strip() @@ -351,7 +351,7 @@ def get_path_if_valid(pathstr, cwd=None, relative=False, check_exists=False): The path if it is a valid path, None otherwise. """ pathstr = pathstr.strip() - log.url.debug("Checking if '{}' is a path".format(pathstr)) + log.url.debug("Checking if {!r} is a path".format(pathstr)) expanded = os.path.expanduser(pathstr) if os.path.isabs(expanded): From 8f593d948cff3b4d2522af294dc10f562406effe Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Sun, 28 Feb 2016 23:56:23 +0100 Subject: [PATCH 043/327] Fixing flake8 error --- qutebrowser/browser/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 8b820c078..c34c766a2 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -821,8 +821,8 @@ class CommandDispatcher: log.misc.debug("{} contained: {!r}".format(target, text)) text_urls = [u for u in text.split('\n') if u.strip()] if (len(text_urls) > 1 and not urlutils.is_url(text_urls[0]) and - urlutils.get_path_if_valid( - text_urls[0], check_exists=True) is None): + urlutils.get_path_if_valid( + text_urls[0], check_exists=True) is None): text_urls = [text] for i, text_url in enumerate(text_urls): if not window and i > 0: From 9286fadeee4bd59269817420fe43f09fda270336 Mon Sep 17 00:00:00 2001 From: Tarcisio Fedrizzi Date: Mon, 29 Feb 2016 00:39:37 +0100 Subject: [PATCH 044/327] Adds wait to paste multiline text test --- tests/integration/features/yankpaste.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/features/yankpaste.feature b/tests/integration/features/yankpaste.feature index ce6ec2b1a..8f6c6552f 100644 --- a/tests/integration/features/yankpaste.feature +++ b/tests/integration/features/yankpaste.feature @@ -134,6 +134,7 @@ Feature: Yanking and pasting. http://qutebrowser.org should not open And I run :paste -t + And I wait until data/hello.txt?q=this%20url%3A%0Ahttp%3A//qutebrowser.org%0Ashould%20not%20open is loaded Then the following tabs should be open: - about:blank - data/hello.txt?q=this%20url%3A%0Ahttp%3A//qutebrowser.org%0Ashould%20not%20open (active) From 2542f114ad3cb2629a7d8f70a3e686e4efa189ac Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 29 Feb 2016 06:47:33 +0100 Subject: [PATCH 045/327] tox: Update pyroma to 2.0.0 - Big rewrite of how data is extracted from Distutils/Setuptools. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index ecfd09496..a1f468cc5 100644 --- a/tox.ini +++ b/tox.ini @@ -178,7 +178,7 @@ basepython = python3 skip_install = true passenv = deps = - pyroma==1.8.3 + pyroma==2.0.0 docutils==0.12 commands = {envdir}/bin/pyroma . From ffe289b410caca8cf8b2b9190fb1fc5588261635 Mon Sep 17 00:00:00 2001 From: Tomas Orsava Date: Mon, 29 Feb 2016 17:55:09 +0100 Subject: [PATCH 046/327] Updated installation instructions for Fedora. --- INSTALL.asciidoc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/INSTALL.asciidoc b/INSTALL.asciidoc index 34c729152..d686b0c05 100644 --- a/INSTALL.asciidoc +++ b/INSTALL.asciidoc @@ -66,11 +66,13 @@ Then <>. On Fedora --------- -qutebrowser should run on Fedora 22. +qutebrowser is available in the official repositories for Fedora 22 and newer. -Unfortunately there is no Fedora package yet, but installing qutebrowser is -still relatively easy! If you want to help packaging it for Fedora, please -mailto:mail@qutebrowser.org[get in touch]! +---- +# dnf install qutebrowser +---- + +Or you can install it manually on Fedora 22 and newer: Install the dependencies via dnf: From 531f4a85ffe9205fbc78d56488ad25e68c5547b8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 07:08:04 +0100 Subject: [PATCH 047/327] tox: Update pytest to 2.9.0. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New Features - New pytest.mark.skip mark, which unconditionally skips marked tests. - --doctest-glob may now be passed multiple times in the command-line. - New -rp and -rP reporting options give the summary and full output of passing tests, respectively. - pytest.mark.xfail now has a strict option which makes XPASS tests to fail the test suite, defaulting to False. There’s also a xfail_strict ini option that can be used to configure it project-wise. - Parser.addini now supports options of type bool. - New ALLOW_BYTES doctest option strips b prefixes from byte strings in doctest output (similar to ALLOW_UNICODE). - give a hint on KeyboardInterrupt to use the –fulltrace option to show the errors - catch IndexError exceptions when getting exception source location. This fixes pytest internal error for dynamically generated code (fixtures and tests) where source lines are fake by intention Changes - Important: py.code has been merged into the pytest repository as pytest._code. This decision was made because py.code had very few uses outside pytest and the fact that it was in a different repository made it difficult to fix bugs on its code in a timely manner. The team hopes with this to be able to better refactor out and improve that code. This change shouldn’t affect users, but it is useful to let users aware if they encounter any strange behavior. Keep in mind that the code for pytest._code is private and experimental, so you definitely should not import it explicitly! Please note that the original py.code is still available in pylib. - pytest_enter_pdb now optionally receives the pytest config object. - Removed code and documentation for Python 2.5 or lower versions, including removal of the obsolete _pytest.assertion.oldinterpret module. - Comparisons now always show up in full when CI or BUILD_NUMBER is found in the environment, even when -vv isn’t used. - --lf and --ff now support long names: --last-failed and --failed-first respectively. - Added expected exceptions to pytest.raises fail message - Collection only displays progress (“collecting X items”) when in a terminal. This avoids cluttering the output when using --color=yes to obtain colors in CI integrations systems Bug Fixes - The -s and -c options should now work under xdist; Config.fromdictargs now represents its input much more faithfully. - support Python 3.5’s @ operator in assertion rewriting. - Fix formatting utf-8 explanation messages. - Fix traceback style docs to describe all of the available options (auto/long/short/line/native/no), with auto being the default since v2.6. - junit record_xml_property doesn’t allow multiple records with same name. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index a1f468cc5..722d8d569 100644 --- a/tox.ini +++ b/tox.ini @@ -26,7 +26,7 @@ deps = parse==1.6.6 parse-type==0.3.4 py==1.4.31 - pytest==2.8.7 + pytest==2.9.0 pytest-bdd==2.16.0 pytest-catchlog==1.2.2 pytest-cov==2.2.1 From 1169d5ac520847b69efaf1c3392d65f71184a34e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 07:12:47 +0100 Subject: [PATCH 048/327] Reduce pytest output on CI. We don't need -v anymore as pytest 2.9 will display full diffs either way. --- .appveyor.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index f1fd299ae..ed6c735a5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -14,4 +14,4 @@ install: - C:\Python27\python -u scripts\dev\ci_install.py test_script: - - C:\Python34\Scripts\tox -e %TESTENV% -- -v --junitxml=junit.xml + - C:\Python34\Scripts\tox -e %TESTENV% -- --junitxml=junit.xml diff --git a/.travis.yml b/.travis.yml index c72a05059..32e205ef9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ install: - python scripts/dev/ci_install.py script: - - tox -e $TESTENV -- -v --cov-report term tests + - tox -e $TESTENV -- tests after_success: - '[[ $TESTENV == *-cov ]] && codecov -e TESTENV -X gcov' From d1ec64cab1b1981acfbbb8703f762ae7d27d0321 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 07:14:06 +0100 Subject: [PATCH 049/327] Remove skip marker as it's builtin in pytest now --- tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index bdfd96510..24ab37940 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -54,7 +54,6 @@ def _apply_platform_markers(item): "Can't be run when frozen"), ('frozen', not getattr(sys, 'frozen', False), "Can only run when frozen"), - ('skip', True, "Always skipped."), ('pyqt531_or_newer', PYQT_VERSION < 0x050301, "Needs PyQt 5.3.1 or newer"), ('ci', 'CI' not in os.environ, "Only runs on CI."), From 9efae021fadb4abcd01893015630cb69fc05ca95 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 07:14:50 +0100 Subject: [PATCH 050/327] Set xfail_strict=true for pytest --- pytest.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest.ini b/pytest.ini index 017506411..e80be8ed1 100644 --- a/pytest.ini +++ b/pytest.ini @@ -37,3 +37,4 @@ qt_log_ignore = ^QObject::connect: Cannot connect \(null\)::stateChanged\(QNetworkSession::State\) to QNetworkReplyHttpImpl::_q_networkSessionStateChanged\(QNetworkSession::State\) ^QXcbClipboard: Cannot transfer data, no data available qt_wait_signal_raising = true +xfail_strict = true From 4314d6420b4cc116a375b31d82ecb968758e74a9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 07:27:25 +0100 Subject: [PATCH 051/327] pytest: Don't show skipped test summaries by default --- pytest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index e80be8ed1..e44ad1d77 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,6 @@ [pytest] norecursedirs = .tox .venv -addopts = --strict -rfEsw --faulthandler-timeout=70 --instafail +addopts = --strict -rfEw --faulthandler-timeout=70 --instafail markers = gui: Tests using the GUI (e.g. spawning widgets) posix: Tests which only can run on a POSIX OS. From d799970f659f3c97f0ccf7a74c9b603c2dab4ef9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 07:29:41 +0100 Subject: [PATCH 052/327] requirements: Update pygments to 2.1.1 - Fixed Jython compatibility - Fixed HTML formatter output with leading empty lines - Added a mapping table for LaTeX encodings and added utf8 - Fixed image formatter font searching on Macs - Fixed deepcopy-ing of Token instances - Fixed Julia string interpolation - Fixed statefulness of HttpLexer between get_tokens calls - Many smaller fixes to various lexers --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5d38700eb..26ff8883f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ Jinja2==2.8.0 MarkupSafe==0.23 -Pygments==2.1.1 +Pygments==2.1.2 pyPEG2==2.15.2 PyYAML==3.11 colorama==0.3.6 From 43a4a6a3e77e4dafd4825d562e60783b00b2cf4b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 08:01:47 +0100 Subject: [PATCH 053/327] Add pkg_resources._vendor.pyparsing when freezing. This is similar to 85299d293f8951154427c8469b2a7407a1a3a706. --- scripts/dev/freeze.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/dev/freeze.py b/scripts/dev/freeze.py index 29d7a74a1..f6ff6de31 100755 --- a/scripts/dev/freeze.py +++ b/scripts/dev/freeze.py @@ -86,7 +86,8 @@ def get_build_exe_options(skip_html=False): 'include_msvcr': True, 'includes': [], 'excludes': ['tkinter'], - 'packages': ['pygments', 'pkg_resources._vendor.packaging'], + 'packages': ['pygments', 'pkg_resources._vendor.packaging', + 'pkg_resources._vendor.pyparsing'], } From 38ac95d907546dc8ddfb0c7f0d9e9b3fbde12b47 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 08:05:15 +0100 Subject: [PATCH 054/327] Revert "pytest.ini: Remove registration of flaky marker" This reverts commit 0f5b4d58e22857230cbd487c3a1bde7fd8a18399. Seems this is needed when freezing, otherwise we get a "'flaky' not a registered marker" error despite the plugin being installed. Conflicts: pytest.ini --- pytest.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest.ini b/pytest.ini index e44ad1d77..3d99b7c78 100644 --- a/pytest.ini +++ b/pytest.ini @@ -16,6 +16,7 @@ markers = pyqt531_or_newer: Needs PyQt 5.3.1 or newer. xfail_norun: xfail the test with out running it ci: Tests which should only run on CI. + flaky: Tests which are flaky and should be rerun qt_log_level_fail = WARNING qt_log_ignore = ^SpellCheck: .* From 5d87770513a1bacd5fbd6f34fb4ff07527aafd57 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 08:09:04 +0100 Subject: [PATCH 055/327] tests: Allow XPASS for test_installed_package We need to use strict=False here as test_installed_package can XPASS when running frozen tests. --- tests/test_conftest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_conftest.py b/tests/test_conftest.py index abb377806..4dff7ddce 100644 --- a/tests/test_conftest.py +++ b/tests/test_conftest.py @@ -44,7 +44,8 @@ def test_fail_on_warnings(): warnings.warn('test', PendingDeprecationWarning) -@pytest.mark.xfail(reason="https://github.com/The-Compiler/qutebrowser/issues/1070") +@pytest.mark.xfail(reason="https://github.com/The-Compiler/qutebrowser/issues/1070", + strict=False) def test_installed_package(): """Make sure the tests are running against the installed package.""" print(sys.path) From 7e3337a9015326faf9251b08081aec5d87233aea Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Mar 2016 08:18:37 +0100 Subject: [PATCH 056/327] tox: Update pyflakes to 1.1.0 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 722d8d569..a15a53121 100644 --- a/tox.ini +++ b/tox.ini @@ -162,7 +162,7 @@ deps = flake8-copyright==0.1 mccabe==0.4.0 pep8==1.7.0 - pyflakes==1.0.0 + pyflakes==1.1.0 flake8-string-format==0.2.1 flake8-deprecated==1.0 flake8-mock==0.2 From 69b160d9d470af97dcf1364f0cd4978d21c8011e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 6 Mar 2016 16:41:39 +0100 Subject: [PATCH 057/327] requirements: Update Pygments to 2.1.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 26ff8883f..b9ad383ce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ Jinja2==2.8.0 MarkupSafe==0.23 -Pygments==2.1.2 +Pygments==2.1.3 pyPEG2==2.15.2 PyYAML==3.11 colorama==0.3.6 From 38c17af191ea9b546c03954bd95238ac64e84eca Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 6 Mar 2016 16:42:52 +0100 Subject: [PATCH 058/327] tox: Update flake8-pep3101 to 0.3 - Allow stdin processing, this way text editor can pass input to flake8. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index a15a53121..6412b3ea4 100644 --- a/tox.ini +++ b/tox.ini @@ -166,7 +166,7 @@ deps = flake8-string-format==0.2.1 flake8-deprecated==1.0 flake8-mock==0.2 - flake8-pep3101==0.2 + flake8-pep3101==0.3 flake8-docstrings==0.2.5 pep257==0.7.0 # still needed by flake8-docstrings but ignored pydocstyle==1.0.0 From 3a76df3fd09bd600b51f72b260ad0bf9b04fd6af Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 6 Mar 2016 16:43:42 +0100 Subject: [PATCH 059/327] tox: Update hypothesis to 3.1.0 - Add a 'nothing' strategy that never successfully generates values. - sampled_from() and one_of() can both now be called with an empty argument list, in which case they also never generate any values. - one_of may now be called with a single argument that is a collection of strategies as well as as varargs. - Add a 'runner' strategy which returns the instance of the current test object if there is one. - 'Bundle' for RuleBasedStateMachine is now a normal(ish) strategy and can be used as such. - Tests using RuleBasedStateMachine should now shrink significantly better. - Hypothesis now uses a pretty-printing library internally, compatible with IPython's pretty printing protocol (actually using the same code). This may improve the quality of output in some cases. - As a 'phases' setting that allows more fine grained control over which parts of the process Hypothesis runs - Add a suppress_health_check setting which allows you to turn off specific health checks in a fine grained manner. - Fix a bug where lists of non fixed size would always draw one more element than they included. This mostly didn't matter, but if would cause problems with empty strategies or ones with side effects. - Add a mechanism to the Django model generator to allow you to explicitly request the default value (thanks to Jeremy Thurgood for this one). --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 6412b3ea4..68e9cbb92 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ deps = Flask==0.10.1 glob2==0.4.1 httpbin==0.4.1 - hypothesis==3.0.5 + hypothesis==3.1.0 itsdangerous==0.24 Mako==1.0.3 parse==1.6.6 From c28dbe84f7676803b7071685f0f9e7a7e52531d9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 6 Mar 2016 16:45:41 +0100 Subject: [PATCH 060/327] tox: Update pyroma to 2.0.2 - Faked the __name__ variable to allow you to have a "if __name__" construct in the setup.py. - Fixed a bug under Python 3 with certain imports. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 68e9cbb92..1df721c30 100644 --- a/tox.ini +++ b/tox.ini @@ -178,7 +178,7 @@ basepython = python3 skip_install = true passenv = deps = - pyroma==2.0.0 + pyroma==2.0.2 docutils==0.12 commands = {envdir}/bin/pyroma . From 0bef594902d1fbcf554264a9f35c73a0e9eba2db Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 7 Mar 2016 20:24:58 +0100 Subject: [PATCH 061/327] Remove manual install for Fedora --- INSTALL.asciidoc | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/INSTALL.asciidoc b/INSTALL.asciidoc index d686b0c05..69d37ceeb 100644 --- a/INSTALL.asciidoc +++ b/INSTALL.asciidoc @@ -72,25 +72,6 @@ qutebrowser is available in the official repositories for Fedora 22 and newer. # dnf install qutebrowser ---- -Or you can install it manually on Fedora 22 and newer: - -Install the dependencies via dnf: - ----- -# dnf update -# dnf install python3-qt5 python-tox python3-sip ----- - -To generate the documentation for the `:help` command, when using the git -repository (rather than a release): - ----- -# dnf install asciidoc source-highlight -$ python3 scripts/asciidoc2html.py ----- - -Then <>. - On Archlinux ------------ From 4189d6e3271afe5fa284c0f38bdfec707c68ff3a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 7 Mar 2016 20:25:06 +0100 Subject: [PATCH 062/327] Regenerate authors. --- README.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/README.asciidoc b/README.asciidoc index 8fdc2fb49..fea89e001 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -195,6 +195,7 @@ Contributors, sorted by the number of commits in descending order: * xd1le * evan * dylan araps +* Tomas Orsava * Tim Harder * Thiago Barroso Perrotta * Stefan Tatschner From 0c3eb7a31c9de83a6b455a327511a8111c4c5fdb Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Mar 2016 17:38:26 +0100 Subject: [PATCH 063/327] Specify valid loglevels for --loglevel/-l --- doc/qutebrowser.1.asciidoc | 2 +- qutebrowser/qutebrowser.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/qutebrowser.1.asciidoc b/doc/qutebrowser.1.asciidoc index 69b14c945..17d184e0b 100644 --- a/doc/qutebrowser.1.asciidoc +++ b/doc/qutebrowser.1.asciidoc @@ -66,7 +66,7 @@ show it. How URLs should be opened if there is already a qutebrowser instance running. === debug arguments -*-l* 'LOGLEVEL', *--loglevel* 'LOGLEVEL':: +*-l* '{critical,error,warning,info,debug,vdebug}', *--loglevel* '{critical,error,warning,info,debug,vdebug}':: Set loglevel *--logfilter* 'LOGFILTER':: diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py index 8e8400258..6c0b7699f 100644 --- a/qutebrowser/qutebrowser.py +++ b/qutebrowser/qutebrowser.py @@ -74,7 +74,9 @@ def get_argparser(): debug = parser.add_argument_group('debug arguments') debug.add_argument('-l', '--loglevel', dest='loglevel', - help="Set loglevel", default='info') + help="Set loglevel", default='info', + choices=['critical', 'error', 'warning', 'info', + 'debug', 'vdebug']) debug.add_argument('--logfilter', help="Comma-separated list of things to be logged " "to the debug log on stdout.") From bb5c483b7a28ce71c29e62dbd2b135ed02b53d4a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Mar 2016 17:41:40 +0100 Subject: [PATCH 064/327] requirements: Update colorama to 0.3.7 * check if stream has 'closed' attribute before testing it * objects might become None at exit --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b9ad383ce..8f3bb052b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ MarkupSafe==0.23 Pygments==2.1.3 pyPEG2==2.15.2 PyYAML==3.11 -colorama==0.3.6 +colorama==0.3.7 colorlog==2.6.1 cssutils==1.0.1 From 88e4102ae193c2309b19133fa4d91eac58ab6b12 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 9 Mar 2016 10:10:36 +0100 Subject: [PATCH 065/327] Move Liberation Mono after Courier as default font Before, in fonts -> _monospace we preferred Liberation Mono to Courier and Courier New. Unfortunately, that font looks horrible on Windows if it's installed, so let's avoid using it if possible. On Linux, hopefully Courier New/Courier isn't available, and Liberation Mono will get picked up instead (or one of the other alternatives). --- qutebrowser/config/configdata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 03ca2d78f..ccf79bba0 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1199,7 +1199,7 @@ def data(readonly=False): SettingValue(typ.Font(), 'Terminus, Monospace, ' '"DejaVu Sans Mono", Monaco, ' '"Bitstream Vera Sans Mono", "Andale Mono", ' - '"Liberation Mono", "Courier New", Courier, ' + '"Courier New", Courier, "Liberation Mono", ' 'monospace, Fixed, Consolas, Terminal'), "Default monospace fonts."), From 146c44b351f67ccd136b4e10a6cfbd5c5dad0073 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 9 Mar 2016 21:19:40 +0100 Subject: [PATCH 066/327] tox: Update pylint-tip repo to github --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 1df721c30..fdc8020b9 100644 --- a/tox.ini +++ b/tox.ini @@ -141,8 +141,8 @@ passenv = {[testenv:pylint]passenv} deps = {[testenv]deps} {[testenv:misc]deps} - hg+https://bitbucket.org/logilab/astroid - hg+https://bitbucket.org/logilab/pylint + git+https://github.com/PyCQA/astroid.git + git+https://github.com/PyCQA/pylint.git ./scripts/dev/pylint_checkers commands = {envpython} scripts/link_pyqt.py --tox {envdir} From c681d6203fa8c8f33fbb82e7ff3a9aaba9c0284c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 9 Mar 2016 21:20:03 +0100 Subject: [PATCH 067/327] tox: Add missing requests dependency for pylint-tip --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index fdc8020b9..5f562b6cd 100644 --- a/tox.ini +++ b/tox.ini @@ -143,6 +143,7 @@ deps = {[testenv:misc]deps} git+https://github.com/PyCQA/astroid.git git+https://github.com/PyCQA/pylint.git + requests==2.9.1 ./scripts/dev/pylint_checkers commands = {envpython} scripts/link_pyqt.py --tox {envdir} From 82b52d8799a0e6f7e73cc465a018bcbad654bc3d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 9 Mar 2016 21:20:30 +0100 Subject: [PATCH 068/327] tox: Rename pylint-tip to pylint-master --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 5f562b6cd..e505f13a0 100644 --- a/tox.ini +++ b/tox.ini @@ -135,7 +135,7 @@ commands = {envpython} -m pylint scripts qutebrowser --output-format=colorized --reports=no {envpython} scripts/dev/run_pylint_on_tests.py {toxinidir} --output-format=colorized --reports=no -[testenv:pylint-tip] +[testenv:pylint-master] basepython = python3 passenv = {[testenv:pylint]passenv} deps = From 119f01bd5f39eb2c7a57318135452ec8c10e520a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 9 Mar 2016 21:20:52 +0100 Subject: [PATCH 069/327] tox: Add {posargs} to pylint envs --- tox.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tox.ini b/tox.ini index e505f13a0..2950a5d01 100644 --- a/tox.ini +++ b/tox.ini @@ -132,8 +132,8 @@ deps = ./scripts/dev/pylint_checkers commands = {envpython} scripts/link_pyqt.py --tox {envdir} - {envpython} -m pylint scripts qutebrowser --output-format=colorized --reports=no - {envpython} scripts/dev/run_pylint_on_tests.py {toxinidir} --output-format=colorized --reports=no + {envpython} -m pylint scripts qutebrowser --output-format=colorized --reports=no {posargs} + {envpython} scripts/dev/run_pylint_on_tests.py {toxinidir} --output-format=colorized --reports=no {posargs} [testenv:pylint-master] basepython = python3 @@ -147,8 +147,8 @@ deps = ./scripts/dev/pylint_checkers commands = {envpython} scripts/link_pyqt.py --tox {envdir} - {envpython} -m pylint scripts qutebrowser --output-format=colorized --reports=no - {envpython} scripts/dev/run_pylint_on_tests.py --output-format=colorized --reports=no + {envpython} -m pylint scripts qutebrowser --output-format=colorized --reports=no {posargs} + {envpython} scripts/dev/run_pylint_on_tests.py --output-format=colorized --reports=no {posargs} [testenv:flake8] basepython = python3 From 2fb186efcd5270f29239af62eaa98cbafd0d6768 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Mar 2016 20:27:03 +0100 Subject: [PATCH 070/327] Fix UnboundLocalError in :unbind --- qutebrowser/config/parsers/keyconf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/config/parsers/keyconf.py b/qutebrowser/config/parsers/keyconf.py index 8db0e5054..487659984 100644 --- a/qutebrowser/config/parsers/keyconf.py +++ b/qutebrowser/config/parsers/keyconf.py @@ -201,7 +201,7 @@ class KeyConfigParser(QObject): sect = self.keybindings[mode] except KeyError: raise cmdexc.CommandError("Can't find mode section '{}'!".format( - sect)) + mode)) try: del sect[key] except KeyError: From b509bc330f2be0fd70f8df6877b6ad803c1e6978 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Mar 2016 20:41:55 +0100 Subject: [PATCH 071/327] Remove unnecessary cmdline args on CI --- .appveyor.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index ed6c735a5..e380db569 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -14,4 +14,4 @@ install: - C:\Python27\python -u scripts\dev\ci_install.py test_script: - - C:\Python34\Scripts\tox -e %TESTENV% -- --junitxml=junit.xml + - C:\Python34\Scripts\tox -e %TESTENV% diff --git a/.travis.yml b/.travis.yml index 32e205ef9..3fe2ed9a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ install: - python scripts/dev/ci_install.py script: - - tox -e $TESTENV -- tests + - tox -e $TESTENV after_success: - '[[ $TESTENV == *-cov ]] && codecov -e TESTENV -X gcov' From a94abb085814c1792128b7e3d70343a6a59e60a7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Mar 2016 06:53:52 +0100 Subject: [PATCH 072/327] tox: Update CherryPy to 5.1.0 * Bugfix for ``test_HTTP11_pipelining`` test in Python 3.5 * Bugfix regarding the keyword arguments support for Python 3 on the config file. * Bugfix for ``test_2_KeyboardInterrupt`` test in Python 3.5. by monkey patching the HTTPRequest given a bug on CPython that is affecting the testsuite (https://bugs.python.org/issue23377). * Add additional parameter ``raise_subcls`` to the tests helpers `openURL` and ``CPWebCase.getPage`` to have finer control on which exceptions can be raised. * Add support for direct keywords on the calls (e.g. ``foo=bar``) on the config file under Python 3. * Add additional validation to determine if the process is running as a daemon on ``cherrypy.process.plugins.SignalHandler`` to allow the execution of the testsuite under CI tools. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 2950a5d01..c549641cc 100644 --- a/tox.ini +++ b/tox.ini @@ -44,7 +44,7 @@ deps = vulture==0.8.1 Werkzeug==0.11.4 wheel==0.29.0 - cherrypy==5.0.1 + cherrypy==5.1.0 commands = {envpython} scripts/link_pyqt.py --tox {envdir} {envpython} -m py.test {posargs:tests} From 8a0d89d9404c784f2e002a81f7798fcfdb80c327 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Mar 2016 06:55:05 +0100 Subject: [PATCH 073/327] tox: Update Mako to 1.0.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [test] [feature] The default test runner is now py.test. Running “python setup.py test” will make use of py.test instead of nose. nose still works as a test runner as well, however. [lexer] [bug] Major improvements to lexing of intricate Python sections which may contain complex backslash sequences, as well as support for the bitwise operator (e.g. pipe symbol) inside of expression sections distinct from the Mako “filter” operator, provided the operator is enclosed within parentheses or brackets. Pull request courtesy Daniel Martin. [feature] Added new method Template.list_defs(). Pull request courtesy Jonathan Vanasco. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index c549641cc..7f38f14a4 100644 --- a/tox.ini +++ b/tox.ini @@ -22,7 +22,7 @@ deps = httpbin==0.4.1 hypothesis==3.1.0 itsdangerous==0.24 - Mako==1.0.3 + Mako==1.0.4 parse==1.6.6 parse-type==0.3.4 py==1.4.31 From 0c6d6367de92a2233248f2ff294aec70d53ff607 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Mar 2016 07:17:11 +0100 Subject: [PATCH 074/327] Force qapp fixture for test_configtypes_hypothesis. The test needs a QApplication --- tests/unit/config/test_configtypes_hypothesis.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/config/test_configtypes_hypothesis.py b/tests/unit/config/test_configtypes_hypothesis.py index c83bdb092..a7ab043ef 100644 --- a/tests/unit/config/test_configtypes_hypothesis.py +++ b/tests/unit/config/test_configtypes_hypothesis.py @@ -42,6 +42,7 @@ def gen_classes(): yield member +@pytest.mark.usefixtures('qapp') @pytest.mark.parametrize('klass', gen_classes()) @hypothesis.given(strategies.text()) @hypothesis.example('\x00') From 42a4c1ce4ca236fa2fa3680a7d79a5627df3c8f2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Mar 2016 07:26:16 +0100 Subject: [PATCH 075/327] Also test transform in test_configtypes_hypothesis If validating works, we might as well also check if transforming does too. --- tests/unit/config/test_configtypes_hypothesis.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/config/test_configtypes_hypothesis.py b/tests/unit/config/test_configtypes_hypothesis.py index a7ab043ef..fe7807c4a 100644 --- a/tests/unit/config/test_configtypes_hypothesis.py +++ b/tests/unit/config/test_configtypes_hypothesis.py @@ -56,3 +56,5 @@ def test_configtypes_hypothesis(klass, s): klass().validate(s) except configexc.ValidationError: pass + else: + klass().transform(s) From 25ee48d28baba052e4e0ecae3d506b7f132fd1ef Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 14 Mar 2016 19:05:15 +0100 Subject: [PATCH 076/327] Add an --all flag to :download-cancel --- CHANGELOG.asciidoc | 1 + doc/help/commands.asciidoc | 5 +++++ qutebrowser/browser/downloads.py | 30 +++++++++++++++++++----------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 6b52eba9b..9d59e5368 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -28,6 +28,7 @@ Added clipboard. - New mode `word` for `hints -> mode` which uses a dictionary and link-texts for hints instead of single characters. +- New `--all` argument for `:download-cancel` to cancel all running downloads. Changed ~~~~~~~ diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 81daecb79..395e3d6e4 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -161,8 +161,13 @@ The form `:download [url] [dest]` is deprecated, use `:download --dest [dest] [u [[download-cancel]] === download-cancel +Syntax: +:download-cancel [*--all*]+ + Cancel the last/[count]th download. +==== optional arguments +* +*-a*+, +*--all*+: Cancel all running downloads + ==== count The index of the download to cancel. diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index c3c6203d9..73a7f0dc0 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -948,22 +948,30 @@ class DownloadManager(QAbstractListModel): @cmdutils.register(instance='download-manager', scope='window', count='count') - def download_cancel(self, count=0): + def download_cancel(self, all_=False, count=0): """Cancel the last/[count]th download. Args: + all_: Cancel all running downloads count: The index of the download to cancel. """ - try: - download = self.downloads[count - 1] - except IndexError: - self.raise_no_download(count) - if download.done: - if not count: - count = len(self.downloads) - raise cmdexc.CommandError("Download {} is already done!" - .format(count)) - download.cancel() + if all_: + # We need to make a copy as we're indirectly mutating + # self.downloads here + for download in self.downloads[:]: + if not download.done: + download.cancel() + else: + try: + download = self.downloads[count - 1] + except IndexError: + self.raise_no_download(count) + if download.done: + if not count: + count = len(self.downloads) + raise cmdexc.CommandError("Download {} is already done!" + .format(count)) + download.cancel() @cmdutils.register(instance='download-manager', scope='window', count='count') From 35731feeb5288c724d9cd143ad9042ce411de295 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 14 Mar 2016 19:05:36 +0100 Subject: [PATCH 077/327] Fix docs for :download-* commands --- doc/help/commands.asciidoc | 8 ++++---- qutebrowser/browser/downloads.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 395e3d6e4..4fc62d37e 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -180,14 +180,14 @@ Remove all finished downloads from the list. Delete the last/[count]th download from disk. ==== count -The index of the download to cancel. +The index of the download to delete. [[download-open]] === download-open Open the last/[count]th download. ==== count -The index of the download to cancel. +The index of the download to open. [[download-remove]] === download-remove @@ -199,14 +199,14 @@ Remove the last/[count]th download from the list. * +*-a*+, +*--all*+: Deprecated argument for removing all finished downloads. ==== count -The index of the download to cancel. +The index of the download to remove. [[download-retry]] === download-retry Retry the first failed/[count]th download. ==== count -The index of the download to cancel. +The index of the download to retry. [[fake-key]] === fake-key diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 73a7f0dc0..7f7e62903 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -979,7 +979,7 @@ class DownloadManager(QAbstractListModel): """Delete the last/[count]th download from disk. Args: - count: The index of the download to cancel. + count: The index of the download to delete. """ try: download = self.downloads[count - 1] @@ -998,7 +998,7 @@ class DownloadManager(QAbstractListModel): """Open the last/[count]th download. Args: - count: The index of the download to cancel. + count: The index of the download to open. """ try: download = self.downloads[count - 1] @@ -1016,7 +1016,7 @@ class DownloadManager(QAbstractListModel): """Retry the first failed/[count]th download. Args: - count: The index of the download to cancel. + count: The index of the download to retry. """ if count: try: @@ -1103,7 +1103,7 @@ class DownloadManager(QAbstractListModel): Args: all_: Deprecated argument for removing all finished downloads. - count: The index of the download to cancel. + count: The index of the download to remove. """ if all_: message.warning(self._win_id, ":download-remove --all is " From ca7361a8a2491b120d726e7f1ce38f57e617fee9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 14 Mar 2016 19:05:45 +0100 Subject: [PATCH 078/327] Update default font list in settings docs --- doc/help/settings.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 4142adbe7..757371e94 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -2041,7 +2041,7 @@ Fonts used for the UI, with optional style/weight/size. === _monospace Default monospace fonts. -Default: +pass:[Terminus, Monospace, "DejaVu Sans Mono", Monaco, "Bitstream Vera Sans Mono", "Andale Mono", "Liberation Mono", "Courier New", Courier, monospace, Fixed, Consolas, Terminal]+ +Default: +pass:[Terminus, Monospace, "DejaVu Sans Mono", Monaco, "Bitstream Vera Sans Mono", "Andale Mono", "Courier New", Courier, "Liberation Mono", monospace, Fixed, Consolas, Terminal]+ [[fonts-completion]] === completion From 06190a048825eea7c961b645c9ef8f281df25d91 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 14 Mar 2016 19:06:16 +0100 Subject: [PATCH 079/327] bdd: Do better cleanup/separation for downloads --- tests/integration/features/downloads.feature | 4 ++-- tests/integration/features/test_downloads.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/integration/features/downloads.feature b/tests/integration/features/downloads.feature index d2ce1ce3c..da26e8d43 100644 --- a/tests/integration/features/downloads.feature +++ b/tests/integration/features/downloads.feature @@ -1,8 +1,8 @@ Feature: Downloading things from a website. Background: - Given I set storage -> prompt-download-directory to false - And I run :download-clear + Given I set up a temporary download dir + And I clean old downloads Scenario: Downloading which redirects with closed tab (issue 889) When I set tabs -> last-close to blank diff --git a/tests/integration/features/test_downloads.py b/tests/integration/features/test_downloads.py index 86301a6e3..d2bc7eb7b 100644 --- a/tests/integration/features/test_downloads.py +++ b/tests/integration/features/test_downloads.py @@ -21,6 +21,19 @@ import pytest_bdd as bdd bdd.scenarios('downloads.feature') +@bdd.given("I set up a temporary download dir") +def temporary_download_dir(quteproc, tmpdir): + quteproc.set_setting('storage', 'prompt-download-directory', 'false') + quteproc.set_setting('storage', 'remember-download-directory', 'false') + quteproc.set_setting('storage', 'download-directory', str(tmpdir)) + + +@bdd.given("I clean old downloads") +def clean_old_downloads(quteproc): + quteproc.send_cmd(':download-cancel --all') + quteproc.send_cmd(':download-clear') + + @bdd.when("I wait until the download is finished") def wait_for_download_finished(quteproc): quteproc.wait_for(category='downloads', message='Download finished') From 41b6f68fd71e92f0bbf3b92a14ca41ea7dc5352d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 14 Mar 2016 19:06:42 +0100 Subject: [PATCH 080/327] bdd: Add some more tests for downloads --- tests/integration/features/downloads.feature | 74 ++++++++++++++++++++ tests/integration/features/test_downloads.py | 12 ++++ 2 files changed, 86 insertions(+) diff --git a/tests/integration/features/downloads.feature b/tests/integration/features/downloads.feature index da26e8d43..b812514bc 100644 --- a/tests/integration/features/downloads.feature +++ b/tests/integration/features/downloads.feature @@ -87,3 +87,77 @@ Feature: Downloading things from a website. And I run :download --mhtml --dest mhtml-response-headers.mht And I wait for "File successfully written." in the log Then no crash should happen + + ## :download-cancel + + Scenario: Cancelling a download + When I run :download http://localhost:(port)/drip?numbytes=128&duration=5 + And I run :download-cancel + Then "cancelled" should be logged + + Scenario: Cancelling a download which does not exist + When I run :download-cancel with count 42 + Then the error "There's no download 42!" should be shown + + Scenario: Cancelling a download which is already done + When I open data/downloads/download.bin + And I wait until the download is finished + And I run :download-cancel + Then the error "Download 1 is already done!" should be shown + + Scenario: Cancelling a download which is already done (with count) + When I open data/downloads/download.bin + And I wait until the download is finished + And I run :download-cancel with count 1 + Then the error "Download 1 is already done!" should be shown + + Scenario: Cancelling all downloads + When I run :download http://localhost:(port)/drip?numbytes=128&duration=5 + And I run :download http://localhost:(port)/drip?numbytes=128&duration=5 + And I run :download-cancel --all + Then "cancelled" should be logged + And "cancelled" should be logged + + ## :download-delete + + Scenario: Deleting a download + When I open data/downloads/download.bin + And I wait until the download is finished + And I run :download-delete + Then the downloaded file download.bin should not exist + + Scenario: Deleting a download which does not exist + When I run :download-delete with count 42 + Then the error "There's no download 42!" should be shown + + Scenario: Deleting a download which is not done yet + When I run :download http://localhost:(port)/drip?numbytes=128&duration=5 + And I run :download-delete + Then the error "Download 1 is not done!" should be shown + + Scenario: Deleting a download which is not done yet (with count) + When I run :download http://localhost:(port)/drip?numbytes=128&duration=5 + And I run :download-delete with count 1 + Then the error "Download 1 is not done!" should be shown + + ## :download-open + + # Scenario: Opening a download + # When I open data/downloads/download.bin + # And I wait until the download is finished + # And I run :download-open + # Then ... + + Scenario: Opening a download which does not exist + When I run :download-open with count 42 + Then the error "There's no download 42!" should be shown + + Scenario: Opening a download which is not done yet + When I run :download http://localhost:(port)/drip?numbytes=128&duration=5 + And I run :download-open + Then the error "Download 1 is not done!" should be shown + + Scenario: Opening a download which is not done yet (with count) + When I run :download http://localhost:(port)/drip?numbytes=128&duration=5 + And I run :download-open with count 1 + Then the error "Download 1 is not done!" should be shown diff --git a/tests/integration/features/test_downloads.py b/tests/integration/features/test_downloads.py index d2bc7eb7b..51613dc61 100644 --- a/tests/integration/features/test_downloads.py +++ b/tests/integration/features/test_downloads.py @@ -37,3 +37,15 @@ def clean_old_downloads(quteproc): @bdd.when("I wait until the download is finished") def wait_for_download_finished(quteproc): quteproc.wait_for(category='downloads', message='Download finished') + + +@bdd.then(bdd.parsers.parse("The downloaded file {filename} should not exist")) +def download_should_not_exist(filename, tmpdir): + path = tmpdir / filename + assert not path.check() + + +@bdd.then(bdd.parsers.parse("The downloaded file {filename} should exist")) +def download_should_exist(filename, tmpdir): + path = tmpdir / filename + assert path.check() From 60c293846f9e864195df14742119840c8922f275 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 14 Mar 2016 19:11:41 +0100 Subject: [PATCH 081/327] Un-deprecate :download-remove --all --- CHANGELOG.asciidoc | 2 ++ doc/help/commands.asciidoc | 2 +- qutebrowser/browser/downloads.py | 4 +--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 9d59e5368..ca46d31cc 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -38,6 +38,8 @@ Changed - `general -> editor` can now also handle `{}` inside another argument (e.g. to open `vim` via `termite`) - Improved performance when scrolling with many tabs open. - Shift-Insert now also pastes primary selection for prompts. +- `:download-remove --all` got un-deprecated to provide symmetry with + `:download-cancel --all`. It does the same as `:download-clear`. Fixed ~~~~~ diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 4fc62d37e..0d6fa8169 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -196,7 +196,7 @@ Syntax: +:download-remove [*--all*]+ Remove the last/[count]th download from the list. ==== optional arguments -* +*-a*+, +*--all*+: Deprecated argument for removing all finished downloads. +* +*-a*+, +*--all*+: Remove all finished downloads. ==== count The index of the download to remove. diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 7f7e62903..331054cfa 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -1102,12 +1102,10 @@ class DownloadManager(QAbstractListModel): """Remove the last/[count]th download from the list. Args: - all_: Deprecated argument for removing all finished downloads. + all_: Remove all finished downloads. count: The index of the download to remove. """ if all_: - message.warning(self._win_id, ":download-remove --all is " - "deprecated - use :download-clear instead!") self.download_clear() else: try: From 97ddd674dde8a9b00cf6e7447383b97e6287e76d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 07:14:39 +0100 Subject: [PATCH 082/327] Use fake_statusbar for test_elided_text See #1313 --- tests/unit/mainwindow/statusbar/test_textbase.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/mainwindow/statusbar/test_textbase.py b/tests/unit/mainwindow/statusbar/test_textbase.py index 2b9bd4cc1..24aa0773d 100644 --- a/tests/unit/mainwindow/statusbar/test_textbase.py +++ b/tests/unit/mainwindow/statusbar/test_textbase.py @@ -31,7 +31,7 @@ from qutebrowser.mainwindow.statusbar.textbase import TextBase (Qt.ElideMiddle, lambda s: '…' in s), (Qt.ElideNone, lambda s: '…' not in s), ]) -def test_elided_text(qtbot, elidemode, check): +def test_elided_text(fake_statusbar, qtbot, elidemode, check): """Ensure that a widget too small to hold the entire label text will elide. It is difficult to check what is actually being drawn in a portable way, so @@ -46,11 +46,11 @@ def test_elided_text(qtbot, elidemode, check): """ label = TextBase(elidemode=elidemode) qtbot.add_widget(label) + fake_statusbar.hbox.addWidget(label) + long_string = 'Hello world! ' * 100 label.setText(long_string) - label.resize(100, 50) - label.show() - qtbot.waitForWindowShown(label) + assert check(label._elided_text) From 569e7b11fb88c45ede7c55e3eb2afbcca46a7ff1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 07:19:43 +0100 Subject: [PATCH 083/327] Make test_elided_text work with non-unicode output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When Qt detects it can't output unicode (via the locale?), it elides using "..." instead of the unicode char "…". Now the test works in both scenarios. --- tests/unit/mainwindow/statusbar/test_textbase.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/mainwindow/statusbar/test_textbase.py b/tests/unit/mainwindow/statusbar/test_textbase.py index 24aa0773d..32058e259 100644 --- a/tests/unit/mainwindow/statusbar/test_textbase.py +++ b/tests/unit/mainwindow/statusbar/test_textbase.py @@ -26,10 +26,10 @@ from qutebrowser.mainwindow.statusbar.textbase import TextBase @pytest.mark.parametrize('elidemode, check', [ - (Qt.ElideRight, lambda s: s.endswith('…')), - (Qt.ElideLeft, lambda s: s.startswith('…')), - (Qt.ElideMiddle, lambda s: '…' in s), - (Qt.ElideNone, lambda s: '…' not in s), + (Qt.ElideRight, lambda s: s.endswith('…') or s.endswith('...')), + (Qt.ElideLeft, lambda s: s.startswith('…') or s.startswith('...')), + (Qt.ElideMiddle, lambda s: '…' in s or '...' in s), + (Qt.ElideNone, lambda s: '…' not in s and '...' not in s), ]) def test_elided_text(fake_statusbar, qtbot, elidemode, check): """Ensure that a widget too small to hold the entire label text will elide. From ed3fd71e6fe4ab0c43a0020cdb9d5e58f6ece8db Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 08:29:33 +0100 Subject: [PATCH 084/327] Force showing of label in test_elided_text It seems the paintEvent of TextBase never got called since we switched to using fake_statusbar, breaking the 100% coverage check. --- tests/unit/mainwindow/statusbar/test_textbase.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/mainwindow/statusbar/test_textbase.py b/tests/unit/mainwindow/statusbar/test_textbase.py index 32058e259..8a1b2db39 100644 --- a/tests/unit/mainwindow/statusbar/test_textbase.py +++ b/tests/unit/mainwindow/statusbar/test_textbase.py @@ -50,6 +50,8 @@ def test_elided_text(fake_statusbar, qtbot, elidemode, check): long_string = 'Hello world! ' * 100 label.setText(long_string) + label.show() + qtbot.waitForWindowShown(label) assert check(label._elided_text) From 3ec7a01590ef39ee48f6cb2563aeab741b1401a7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Mar 2016 06:52:07 +0100 Subject: [PATCH 085/327] Add Dockerfile for Debian jessie --- misc/docker/debian-jessie/Dockerfile | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 misc/docker/debian-jessie/Dockerfile diff --git a/misc/docker/debian-jessie/Dockerfile b/misc/docker/debian-jessie/Dockerfile new file mode 100644 index 000000000..8ee43f42f --- /dev/null +++ b/misc/docker/debian-jessie/Dockerfile @@ -0,0 +1,27 @@ +FROM debian:jessie +MAINTAINER Florian Bruhin + +RUN apt-get -y update && \ + apt-get -y install python3-pyqt5 python3-pyqt5.qtwebkit python-tox \ + python3-sip python3-dev xvfb git dbus \ + python3-setuptools wget xinit build-essential \ + xserver-xorg-core xserver-xorg-video-dummy herbstluftwm +RUN dbus-uuidgen --ensure +RUN wget http://www.karlrunge.com/x11vnc/Xdummy -O /usr/local/bin/Xdummy && \ + chmod +x /usr/local/bin/Xdummy +RUN Xdummy -install +# Keep image small after Xdummy is installed +RUN apt-get -y purge build-essential && apt-get -y autoremove + +RUN useradd user && mkdir /home/user && chown -R user:users /home/user +USER user +WORKDIR /home/user + +RUN echo 'exec herbstluftwm' > /home/user/.xinitrc + +ENV DISPLAY=:0 + +CMD startx -- /usr/local/bin/Xdummy :0 & \ + git clone /outside qutebrowser.git && \ + cd qutebrowser.git && \ + tox -e py34 From 241536dcdc79d133674215b0e7ee6161b6354d63 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 19:03:50 +0100 Subject: [PATCH 086/327] travis: Use explicit matrix --- .travis.yml | 65 +++++++++++++++++++---------------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3fe2ed9a3..dcf3b826e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,30 +1,34 @@ -# So we get Ubuntu Trusty - using "dist: trusty" breaks OS X. sudo: required dist: trusty - -os: - - linux - - osx - - env: global: - PATH=/home/travis/bin:/home/travis/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - matrix: - - TESTENV=py35 - - TESTENV=py34-cov - - TESTENV=unittests-nodisp - - TESTENV=misc - - TESTENV=vulture - - TESTENV=flake8 - - TESTENV=pyroma - - TESTENV=check-manifest - - TESTENV=pylint - - TESTENV=eslint - # Not really, but this is here so we can do stuff by hand. language: c +matrix: + include: + - os: linux + env: TESTENV=py34-cov + - os: linux + env: TESTENV=unittests-nodisp + - os: osx + env: TESTENV=py35 + - os: linux + env: TESTENV=pylint + - os: linux + env: TESTENV=flake8 + - os: linux + env: TESTENV=vulture + - os: linux + env: TESTENV=misc + - os: linux + env: TESTENV=pyroma + - os: linux + env: TESTENV=check-manifest + - os: linux + env: TESTENV=eslint + cache: directories: - $HOME/.cache/pip @@ -39,29 +43,6 @@ script: after_success: - '[[ $TESTENV == *-cov ]] && codecov -e TESTENV -X gcov' -matrix: - exclude: - - os: linux - env: TESTENV=py35 - - os: osx - env: TESTENV=py34-cov - - os: osx - env: TESTENV=unittests-nodisp - - os: osx - env: TESTENV=misc - - os: osx - env: TESTENV=vulture - - os: osx - env: TESTENV=flake8 - - os: osx - env: TESTENV=pyroma - - os: osx - env: TESTENV=check-manifest - - os: osx - env: TESTENV=pylint - - os: osx - env: TESTENV=eslint - notifications: webhooks: - https://buildtimetrend.herokuapp.com/travis From bc080f047eb00249a4a5aa0ba30c40007f421510 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 19:16:11 +0100 Subject: [PATCH 087/327] Add Dockerfile for Archlinux --- misc/docker/archlinux/Dockerfile | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 misc/docker/archlinux/Dockerfile diff --git a/misc/docker/archlinux/Dockerfile b/misc/docker/archlinux/Dockerfile new file mode 100644 index 000000000..965e8d133 --- /dev/null +++ b/misc/docker/archlinux/Dockerfile @@ -0,0 +1,40 @@ +FROM base/archlinux +MAINTAINER Florian Bruhin + +RUN echo 'Server = http://mirror.de.leaseweb.net/archlinux/$repo/os/$arch' > /etc/pacman.d/mirrorlist +RUN pacman-key --init && pacman-key --populate archlinux && pacman -Sy --noconfirm archlinux-keyring + +RUN pacman-key -r 0xD6A1C70FE80A0C82 && \ + pacman-key --lsign-key 0xD6A1C70FE80A0C82 && \ + echo -e '[qt-debug]\nServer = http://qutebrowser.org/qt-debug/$arch' >> /etc/pacman.conf + +RUN pacman -Suyy --noconfirm +RUN pacman-db-upgrade + +RUN pacman -S --noconfirm \ + git \ + python-tox \ + qt5-base-debug \ + qt5-webkit-debug \ + python-pyqt5-debug \ + base-devel \ + xorg-xinit \ + herbstluftwm \ + xorg-server-xvfb + +RUN echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen && locale-gen + +RUN useradd user && mkdir /home/user && chown -R user:users /home/user +USER user +WORKDIR /home/user + +ENV DISPLAY=:0 +ENV LC_ALL=en_US.UTF-8 +ENV LANG=en_US.UTF-8 + +CMD Xvfb -screen 0 800x600x24 :0 & \ + sleep 2 && \ + herbstluftwm & \ + git clone /outside qutebrowser.git && \ + cd qutebrowser.git && \ + tox -e py35 From cc94e7bfeee20724adfda3209cf6e022cdaf6784 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 19:18:16 +0100 Subject: [PATCH 088/327] Move ci_install.py to subdir --- .appveyor.yml | 2 +- .travis.yml | 2 +- scripts/dev/{ci_install.py => ci/install.py} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename scripts/dev/{ci_install.py => ci/install.py} (100%) diff --git a/.appveyor.yml b/.appveyor.yml index e380db569..b85b64285 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -11,7 +11,7 @@ environment: - TESTENV: pylint install: - - C:\Python27\python -u scripts\dev\ci_install.py + - C:\Python27\python -u scripts\dev\ci\install.py test_script: - C:\Python34\Scripts\tox -e %TESTENV% diff --git a/.travis.yml b/.travis.yml index dcf3b826e..085b1b4ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,7 @@ cache: - $HOME/build/The-Compiler/qutebrowser/.cache install: - - python scripts/dev/ci_install.py + - python scripts/dev/ci/install.py script: - tox -e $TESTENV diff --git a/scripts/dev/ci_install.py b/scripts/dev/ci/install.py similarity index 100% rename from scripts/dev/ci_install.py rename to scripts/dev/ci/install.py From 62db2c724f79d41982a1416909bf254e05ab9200 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 19:23:49 +0100 Subject: [PATCH 089/327] Try to run Docker on Travis --- .travis.yml | 8 +++++++- scripts/dev/ci/install.py | 6 +++--- scripts/dev/ci/travis_run.sh | 8 ++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 scripts/dev/ci/travis_run.sh diff --git a/.travis.yml b/.travis.yml index 085b1b4ac..5c3eaf4f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,12 @@ matrix: env: TESTENV=py34-cov - os: linux env: TESTENV=unittests-nodisp + - os: linux + env: DOCKER=debian-jessie + services: docker + - os: linux + env: DOCKER=archlinux + services: docker - os: osx env: TESTENV=py35 - os: linux @@ -38,7 +44,7 @@ install: - python scripts/dev/ci/install.py script: - - tox -e $TESTENV + - bash scripts/dev/ci/travis_run.sh after_success: - '[[ $TESTENV == *-cov ]] && codecov -e TESTENV -X gcov' diff --git a/scripts/dev/ci/install.py b/scripts/dev/ci/install.py index e56752cfa..09a740e3a 100644 --- a/scripts/dev/ci/install.py +++ b/scripts/dev/ci/install.py @@ -40,13 +40,13 @@ try: except ImportError: winreg = None -TESTENV = os.environ['TESTENV'] +TESTENV = os.environ.get('TESTENV', None) TRAVIS_OS = os.environ.get('TRAVIS_OS_NAME', None) INSTALL_PYQT = TESTENV in ('py34', 'py35', 'py34-cov', 'py35-cov', 'unittests-nodisp', 'vulture', 'pylint') XVFB = TRAVIS_OS == 'linux' and TESTENV == 'py34' pip_packages = ['tox'] -if TESTENV.endswith('-cov'): +if TESTENV is not None and TESTENV.endswith('-cov'): pip_packages.append('codecov') @@ -115,7 +115,7 @@ if 'APPVEYOR' in os.environ: f.write(r'@C:\Python34\python %*') check_setup(r'C:\Python34\python') -elif TRAVIS_OS == 'linux': +elif TRAVIS_OS == 'linux' and 'DOCKER' not in os.environ: folded_cmd(['sudo', 'pip', 'install'] + pip_packages) pkgs = [] diff --git a/scripts/dev/ci/travis_run.sh b/scripts/dev/ci/travis_run.sh new file mode 100644 index 000000000..ddedb0099 --- /dev/null +++ b/scripts/dev/ci/travis_run.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [[ $DOCKER ]]; then + docker build -t img misc/docker/$DOCKER + docker run --privileged -v $PWD:/outside img +else + tox -e $TESTENV +fi From 123de8783f981fa8894b7f26460b8540a6c3617c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 19:32:20 +0100 Subject: [PATCH 090/327] ci/install.py fixup --- scripts/dev/ci/install.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/dev/ci/install.py b/scripts/dev/ci/install.py index 09a740e3a..7130305c5 100644 --- a/scripts/dev/ci/install.py +++ b/scripts/dev/ci/install.py @@ -115,7 +115,9 @@ if 'APPVEYOR' in os.environ: f.write(r'@C:\Python34\python %*') check_setup(r'C:\Python34\python') -elif TRAVIS_OS == 'linux' and 'DOCKER' not in os.environ: +elif TRAVIS_OS == 'linux' and 'DOCKER' in os.environ: + pass +elif TRAVIS_OS == 'linux': folded_cmd(['sudo', 'pip', 'install'] + pip_packages) pkgs = [] From 6d225a7858960e4482ad5316f03078be1ca25a4a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 19:48:43 +0100 Subject: [PATCH 091/327] Set DEBIAN_FRONTEND=noninteractive for Debian Dockerfile --- misc/docker/debian-jessie/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/docker/debian-jessie/Dockerfile b/misc/docker/debian-jessie/Dockerfile index 8ee43f42f..88ea3e009 100644 --- a/misc/docker/debian-jessie/Dockerfile +++ b/misc/docker/debian-jessie/Dockerfile @@ -1,6 +1,8 @@ FROM debian:jessie MAINTAINER Florian Bruhin +ENV DEBIAN_FRONTEND=noninteractive + RUN apt-get -y update && \ apt-get -y install python3-pyqt5 python3-pyqt5.qtwebkit python-tox \ python3-sip python3-dev xvfb git dbus \ From bc6bf82301015591c894e5e0ad629ceb5d85a01d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 21:08:19 +0100 Subject: [PATCH 092/327] docker: Minimize Debian Jessie image --- misc/docker/debian-jessie/Dockerfile | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/misc/docker/debian-jessie/Dockerfile b/misc/docker/debian-jessie/Dockerfile index 88ea3e009..1cfa395e7 100644 --- a/misc/docker/debian-jessie/Dockerfile +++ b/misc/docker/debian-jessie/Dockerfile @@ -4,26 +4,23 @@ MAINTAINER Florian Bruhin ENV DEBIAN_FRONTEND=noninteractive RUN apt-get -y update && \ + apt-get -y dist-upgrade && \ apt-get -y install python3-pyqt5 python3-pyqt5.qtwebkit python-tox \ - python3-sip python3-dev xvfb git dbus \ - python3-setuptools wget xinit build-essential \ - xserver-xorg-core xserver-xorg-video-dummy herbstluftwm -RUN dbus-uuidgen --ensure -RUN wget http://www.karlrunge.com/x11vnc/Xdummy -O /usr/local/bin/Xdummy && \ - chmod +x /usr/local/bin/Xdummy -RUN Xdummy -install -# Keep image small after Xdummy is installed -RUN apt-get -y purge build-essential && apt-get -y autoremove + python3-sip xvfb git python3-setuptools wget \ + herbstluftwm locales +RUN echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen && locale-gen RUN useradd user && mkdir /home/user && chown -R user:users /home/user USER user WORKDIR /home/user -RUN echo 'exec herbstluftwm' > /home/user/.xinitrc - ENV DISPLAY=:0 +ENV LC_ALL=en_US.UTF-8 +ENV LANG=en_US.UTF-8 -CMD startx -- /usr/local/bin/Xdummy :0 & \ +CMD Xvfb -screen 0 800x600x24 :0 & \ + sleep 2 && \ + herbstluftwm & \ git clone /outside qutebrowser.git && \ cd qutebrowser.git && \ tox -e py34 From b19da05097f863c3bec96373af53c3cb309b0d08 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 21:38:17 +0100 Subject: [PATCH 093/327] flake8: Ignore "If is too complex" in ci/install.py --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index 7f28c527d..b5cf191ed 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,6 +50,7 @@ putty-ignore = tests/*/*/test_*.py : +D100,D101,D401 tests/*/test_*.py : +D100,D101,D401 tests/unit/browser/http/test_content_disposition.py : +D400 + scripts/dev/ci/install.py : +C901 copyright-check = True copyright-regexp = # Copyright [\d-]+ .* copyright-min-file-size = 110 From 0bc31e5373a089812fe109fee30758ee9df037f8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 21:39:30 +0100 Subject: [PATCH 094/327] docker: Also run on Ubuntu Wily on Travis --- .travis.yml | 3 +++ misc/docker/ubuntu-wily/Dockerfile | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 misc/docker/ubuntu-wily/Dockerfile diff --git a/.travis.yml b/.travis.yml index 5c3eaf4f0..446db8b0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,9 @@ matrix: - os: linux env: DOCKER=archlinux services: docker + - os: linux + env: DOCKER=ubuntu-wily + services: docker - os: osx env: TESTENV=py35 - os: linux diff --git a/misc/docker/ubuntu-wily/Dockerfile b/misc/docker/ubuntu-wily/Dockerfile new file mode 100644 index 000000000..71404a360 --- /dev/null +++ b/misc/docker/ubuntu-wily/Dockerfile @@ -0,0 +1,25 @@ +FROM ubuntu:wily +MAINTAINER Florian Bruhin + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get -y update && \ + apt-get -y dist-upgrade && \ + apt-get -y install python3-pyqt5 python3-pyqt5.qtwebkit python-tox \ + python3-sip xvfb git python3-setuptools wget \ + herbstluftwm language-pack-en + +RUN useradd user && mkdir /home/user && chown -R user:users /home/user +USER user +WORKDIR /home/user + +ENV DISPLAY=:0 +ENV LC_ALL=en_US.UTF-8 +ENV LANG=en_US.UTF-8 + +CMD Xvfb -screen 0 800x600x24 :0 & \ + sleep 2 && \ + herbstluftwm & \ + git clone /outside qutebrowser.git && \ + cd qutebrowser.git && \ + tox -e py34 From 543aa48e26628c5072ce61172231d9c2dd39c6fa Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 21:42:48 +0100 Subject: [PATCH 095/327] travis: Add IRC notifications --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 446db8b0a..6588ad7bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,3 +55,8 @@ after_success: notifications: webhooks: - https://buildtimetrend.herokuapp.com/travis + irc: + channels: + - "chat.freenode.net#qutebrowser" + on_success: change + on_failure: always From 5ae9f0405dd592829aadd9c5573db930e3215bd3 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 22:32:53 +0100 Subject: [PATCH 096/327] travis: Fine-tune IRC notifications --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6588ad7bd..37f06769b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,3 +60,7 @@ notifications: - "chat.freenode.net#qutebrowser" on_success: change on_failure: always + skip_join: true + template: + - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}" + - "%{compare_url} - %{build_url}" From 07d31634c69686abb5c5055ca9b6ec2ddc92e68c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 22:43:47 +0100 Subject: [PATCH 097/327] Add script to check for doc changes --- scripts/dev/check_doc_changes.py | 35 ++++++++++++++++++++++++++++++++ tox.ini | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100755 scripts/dev/check_doc_changes.py diff --git a/scripts/dev/check_doc_changes.py b/scripts/dev/check_doc_changes.py new file mode 100755 index 000000000..6e99f94a7 --- /dev/null +++ b/scripts/dev/check_doc_changes.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2016 Florian Bruhin (The Compiler) + +# 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 . + +"""Check if docs changed and output an error if so.""" + +import sys +import subprocess + +code = subprocess.call(['git', '--no-pager', 'diff', '--exit-code', '--stat']) +if code != 0: + print() + print('The autogenerated docs changed, please run this to update them:') + print(' tox -e docs') + print(' git commit -am "Update docs"') + print() + print('(Or you have uncommited changes, in which case you can ignore ' + 'this.)') +sys.exit(code) diff --git a/tox.ini b/tox.ini index 7f38f14a4..8aff26f7f 100644 --- a/tox.ini +++ b/tox.ini @@ -203,7 +203,7 @@ deps = commands = {envpython} scripts/link_pyqt.py --tox {envdir} {envpython} scripts/dev/src2asciidoc.py - git --no-pager diff --exit-code --stat + {envpython} scripts/dev/check_doc_changes.py {envpython} scripts/asciidoc2html.py {posargs} [testenv:cxfreeze-windows] From f1ec6e1e004c5affdb4ba1a00607f01322338e2e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 22:46:49 +0100 Subject: [PATCH 098/327] Check docs on Travis --- .travis.yml | 2 ++ scripts/dev/ci/install.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 37f06769b..ccb2d8e3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,8 @@ matrix: env: TESTENV=pylint - os: linux env: TESTENV=flake8 + - os: linux + env: TESTENV=docs - os: linux env: TESTENV=vulture - os: linux diff --git a/scripts/dev/ci/install.py b/scripts/dev/ci/install.py index 7130305c5..4f08ea502 100644 --- a/scripts/dev/ci/install.py +++ b/scripts/dev/ci/install.py @@ -43,7 +43,7 @@ except ImportError: TESTENV = os.environ.get('TESTENV', None) TRAVIS_OS = os.environ.get('TRAVIS_OS_NAME', None) INSTALL_PYQT = TESTENV in ('py34', 'py35', 'py34-cov', 'py35-cov', - 'unittests-nodisp', 'vulture', 'pylint') + 'unittests-nodisp', 'vulture', 'pylint', 'docs') XVFB = TRAVIS_OS == 'linux' and TESTENV == 'py34' pip_packages = ['tox'] if TESTENV is not None and TESTENV.endswith('-cov'): @@ -128,6 +128,8 @@ elif TRAVIS_OS == 'linux': pkgs += ['python3-pyqt5', 'python3-pyqt5.qtwebkit'] if TESTENV == 'eslint': pkgs += ['npm', 'nodejs', 'nodejs-legacy'] + if TESTENV == 'docs': + pkgs += ['asciidoc'] if pkgs: fix_sources_list() From cc6d2ddc1dbfefb1314abb06d5384fb63c1931e9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 15 Mar 2016 23:22:19 +0100 Subject: [PATCH 099/327] Revert "Check docs on Travis" This reverts commit f1ec6e1e004c5affdb4ba1a00607f01322338e2e. --depth=50 on Travis messes up author generation --- .travis.yml | 2 -- scripts/dev/ci/install.py | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index ccb2d8e3f..37f06769b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,8 +27,6 @@ matrix: env: TESTENV=pylint - os: linux env: TESTENV=flake8 - - os: linux - env: TESTENV=docs - os: linux env: TESTENV=vulture - os: linux diff --git a/scripts/dev/ci/install.py b/scripts/dev/ci/install.py index 4f08ea502..7130305c5 100644 --- a/scripts/dev/ci/install.py +++ b/scripts/dev/ci/install.py @@ -43,7 +43,7 @@ except ImportError: TESTENV = os.environ.get('TESTENV', None) TRAVIS_OS = os.environ.get('TRAVIS_OS_NAME', None) INSTALL_PYQT = TESTENV in ('py34', 'py35', 'py34-cov', 'py35-cov', - 'unittests-nodisp', 'vulture', 'pylint', 'docs') + 'unittests-nodisp', 'vulture', 'pylint') XVFB = TRAVIS_OS == 'linux' and TESTENV == 'py34' pip_packages = ['tox'] if TESTENV is not None and TESTENV.endswith('-cov'): @@ -128,8 +128,6 @@ elif TRAVIS_OS == 'linux': pkgs += ['python3-pyqt5', 'python3-pyqt5.qtwebkit'] if TESTENV == 'eslint': pkgs += ['npm', 'nodejs', 'nodejs-legacy'] - if TESTENV == 'docs': - pkgs += ['asciidoc'] if pkgs: fix_sources_list() From 172611a1b98d06b5ea1c6e1eac9445836f1c5a7c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 06:19:33 +0100 Subject: [PATCH 100/327] Revert "Revert "Check docs on Travis"" This reverts commit cc6d2ddc1dbfefb1314abb06d5384fb63c1931e9. --- .travis.yml | 2 ++ scripts/dev/ci/install.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 37f06769b..ccb2d8e3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,8 @@ matrix: env: TESTENV=pylint - os: linux env: TESTENV=flake8 + - os: linux + env: TESTENV=docs - os: linux env: TESTENV=vulture - os: linux diff --git a/scripts/dev/ci/install.py b/scripts/dev/ci/install.py index 7130305c5..4f08ea502 100644 --- a/scripts/dev/ci/install.py +++ b/scripts/dev/ci/install.py @@ -43,7 +43,7 @@ except ImportError: TESTENV = os.environ.get('TESTENV', None) TRAVIS_OS = os.environ.get('TRAVIS_OS_NAME', None) INSTALL_PYQT = TESTENV in ('py34', 'py35', 'py34-cov', 'py35-cov', - 'unittests-nodisp', 'vulture', 'pylint') + 'unittests-nodisp', 'vulture', 'pylint', 'docs') XVFB = TRAVIS_OS == 'linux' and TESTENV == 'py34' pip_packages = ['tox'] if TESTENV is not None and TESTENV.endswith('-cov'): @@ -128,6 +128,8 @@ elif TRAVIS_OS == 'linux': pkgs += ['python3-pyqt5', 'python3-pyqt5.qtwebkit'] if TESTENV == 'eslint': pkgs += ['npm', 'nodejs', 'nodejs-legacy'] + if TESTENV == 'docs': + pkgs += ['asciidoc'] if pkgs: fix_sources_list() From 236572e0f54e47fcf14ec35d292726253a20c30a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 06:22:36 +0100 Subject: [PATCH 101/327] Check docs on Travis, take two We don't regenerate the authors there, as that doesn't work due to Travis cloning with --depth=50 --- scripts/dev/ci/travis_run.sh | 5 ++++- scripts/dev/src2asciidoc.py | 5 +++-- tox.ini | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/dev/ci/travis_run.sh b/scripts/dev/ci/travis_run.sh index ddedb0099..e4b0bb054 100644 --- a/scripts/dev/ci/travis_run.sh +++ b/scripts/dev/ci/travis_run.sh @@ -4,5 +4,8 @@ if [[ $DOCKER ]]; then docker build -t img misc/docker/$DOCKER docker run --privileged -v $PWD:/outside img else - tox -e $TESTENV + args=() + [[ $TESTENV == docs ]] && args=('--no-authors') + + tox -e $TESTENV "${args[@]}" fi diff --git a/scripts/dev/src2asciidoc.py b/scripts/dev/src2asciidoc.py index 746a2ceaf..3b4660069 100755 --- a/scripts/dev/src2asciidoc.py +++ b/scripts/dev/src2asciidoc.py @@ -491,8 +491,9 @@ def main(): generate_settings('doc/help/settings.asciidoc') print("Generating command help...") generate_commands('doc/help/commands.asciidoc') - print("Generating authors in README...") - regenerate_authors('README.asciidoc') + if '--no-authors' not in sys.argv: + print("Generating authors in README...") + regenerate_authors('README.asciidoc') if '--html' in sys.argv: asciidoc2html.main() diff --git a/tox.ini b/tox.ini index 8aff26f7f..66875ebb2 100644 --- a/tox.ini +++ b/tox.ini @@ -202,7 +202,7 @@ deps = -r{toxinidir}/requirements.txt commands = {envpython} scripts/link_pyqt.py --tox {envdir} - {envpython} scripts/dev/src2asciidoc.py + {envpython} scripts/dev/src2asciidoc.py {posargs} {envpython} scripts/dev/check_doc_changes.py {envpython} scripts/asciidoc2html.py {posargs} From 0eb12b8fa02e340aacfdb66423cf5f5a536ee0d7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 06:23:39 +0100 Subject: [PATCH 102/327] Fix spelling --- scripts/dev/check_doc_changes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dev/check_doc_changes.py b/scripts/dev/check_doc_changes.py index 6e99f94a7..85991cc08 100755 --- a/scripts/dev/check_doc_changes.py +++ b/scripts/dev/check_doc_changes.py @@ -30,6 +30,6 @@ if code != 0: print(' tox -e docs') print(' git commit -am "Update docs"') print() - print('(Or you have uncommited changes, in which case you can ignore ' + print('(Or you have uncommitted changes, in which case you can ignore ' 'this.)') sys.exit(code) From bb2847fee97c4ce90dea9d34dc048999a7ea2364 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 06:52:06 +0100 Subject: [PATCH 103/327] Fix argument passing to Travis --- scripts/dev/ci/travis_run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dev/ci/travis_run.sh b/scripts/dev/ci/travis_run.sh index e4b0bb054..9341a95cf 100644 --- a/scripts/dev/ci/travis_run.sh +++ b/scripts/dev/ci/travis_run.sh @@ -7,5 +7,5 @@ else args=() [[ $TESTENV == docs ]] && args=('--no-authors') - tox -e $TESTENV "${args[@]}" + tox -e $TESTENV -- "${args[@]}" fi From a2b9749dbfb5bd7c37fa573be6eb8d1461996374 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 06:57:44 +0100 Subject: [PATCH 104/327] docker: Don't install base-devel on Arch --- misc/docker/archlinux/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/docker/archlinux/Dockerfile b/misc/docker/archlinux/Dockerfile index 965e8d133..37038b0a6 100644 --- a/misc/docker/archlinux/Dockerfile +++ b/misc/docker/archlinux/Dockerfile @@ -17,7 +17,6 @@ RUN pacman -S --noconfirm \ qt5-base-debug \ qt5-webkit-debug \ python-pyqt5-debug \ - base-devel \ xorg-xinit \ herbstluftwm \ xorg-server-xvfb From b76886d2ff899359e38a5484a5dacf9360ce3f7d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 07:11:40 +0100 Subject: [PATCH 105/327] Ignore --no-authors in asciidoc2html.py This makes it possible to run "tox -e docs -- --no-args" with {posargs} passed to both src2asciidoc.py and asciidoc2html.py. --- scripts/asciidoc2html.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/asciidoc2html.py b/scripts/asciidoc2html.py index dfcb342a3..3a02f7c66 100755 --- a/scripts/asciidoc2html.py +++ b/scripts/asciidoc2html.py @@ -249,6 +249,7 @@ def main(colors=False): "asciidoc.py. If not given, it's searched in PATH.", nargs=2, required=False, metavar=('PYTHON', 'ASCIIDOC')) + parser.add_argument('--no-authors', help=argparse.SUPPRESS) args = parser.parse_args() try: os.mkdir('qutebrowser/html/doc') From ee4fa6c118c5f3d14e6257acd8150a011b0fb29e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 07:23:17 +0100 Subject: [PATCH 106/327] travis: Use prebuilt docker images --- scripts/dev/ci/travis_run.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/dev/ci/travis_run.sh b/scripts/dev/ci/travis_run.sh index 9341a95cf..6e4539d26 100644 --- a/scripts/dev/ci/travis_run.sh +++ b/scripts/dev/ci/travis_run.sh @@ -1,8 +1,12 @@ #!/bin/bash if [[ $DOCKER ]]; then - docker build -t img misc/docker/$DOCKER - docker run --privileged -v $PWD:/outside img + # To build a fresh image: + # docker build -t img misc/docker/$DOCKER + # docker run --privileged -v $PWD:/outside img + + docker run --privileged -v $PWD:/outside \ + thecompiler/qutebrowser-manual:$DOCKER else args=() [[ $TESTENV == docs ]] && args=('--no-authors') From abfadb56315c28ef41ed8bacae1c8de0555efe64 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 07:35:12 +0100 Subject: [PATCH 107/327] Fix asciidoc2html --no-authors --- scripts/asciidoc2html.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/asciidoc2html.py b/scripts/asciidoc2html.py index 3a02f7c66..d0a0b3537 100755 --- a/scripts/asciidoc2html.py +++ b/scripts/asciidoc2html.py @@ -249,7 +249,8 @@ def main(colors=False): "asciidoc.py. If not given, it's searched in PATH.", nargs=2, required=False, metavar=('PYTHON', 'ASCIIDOC')) - parser.add_argument('--no-authors', help=argparse.SUPPRESS) + parser.add_argument('--no-authors', help=argparse.SUPPRESS, + action='store_true') args = parser.parse_args() try: os.mkdir('qutebrowser/html/doc') From 91415105f3caea40fe2543ee128ad99212f41728 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 18:17:32 +0100 Subject: [PATCH 108/327] Regenerate docs. --- doc/help/settings.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 73ac7a4c0..652629a89 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -1585,7 +1585,7 @@ Default: +pass:[/usr/share/dict/words]+ [[hints-auto-follow]] === auto-follow -Whether to auto-follow a hint if there's only one left. +Follow a hint immediately when the hint text is completely matched. Valid values: From dad26cc39569bda3a125706bf8bd998262b4bc04 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 16 Mar 2016 19:43:18 +0100 Subject: [PATCH 109/327] Fix line length --- qutebrowser/config/configdata.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index c250cef33..fd44200ae 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -896,7 +896,8 @@ def data(readonly=False): ('auto-follow', SettingValue(typ.Bool(), 'true'), - "Follow a hint immediately when the hint text is completely matched."), + "Follow a hint immediately when the hint text is completely " + "matched."), ('next-regexes', SettingValue(typ.RegexList(flags=re.IGNORECASE), From 74706abbc1f40b39bf172d5646662f105bf5ce06 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 17 Mar 2016 22:10:58 +0100 Subject: [PATCH 110/327] Fix lint --- tests/unit/misc/test_editor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/misc/test_editor.py b/tests/unit/misc/test_editor.py index f3740523e..f9a5d4370 100644 --- a/tests/unit/misc/test_editor.py +++ b/tests/unit/misc/test_editor.py @@ -99,7 +99,7 @@ class TestFileHandling: assert os.path.exists(filename) editor._proc._proc.exitStatus = mock.Mock( - return_value=QProcess.CrashExit) + return_value=QProcess.CrashExit) editor._proc.finished.emit(1, QProcess.NormalExit) assert os.path.exists(filename) @@ -113,7 +113,7 @@ class TestFileHandling: assert os.path.exists(filename) editor._proc._proc.exitStatus = mock.Mock( - return_value=QProcess.CrashExit) + return_value=QProcess.CrashExit) editor._proc.error.emit(QProcess.Crashed) editor._proc.finished.emit(0, QProcess.CrashExit) From eed13467f3c44a9093fea53c25aae3612e949edc Mon Sep 17 00:00:00 2001 From: haxwithaxe Date: Thu, 17 Mar 2016 20:38:05 -0400 Subject: [PATCH 111/327] allow {0} in search engine specification strings to allow multiple instances of the search term in the url --- qutebrowser/config/configtypes.py | 2 +- tests/unit/config/test_configtypes.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index d79e35df1..066fb70c6 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1196,7 +1196,7 @@ class SearchEngineUrl(BaseType): self._basic_validation(value) if not value: return - elif '{}' not in value: + elif not ('{}' in value or '{0}' in value): raise configexc.ValidationError(value, "must contain \"{}\"") try: value.format("") diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index b555ad544..d9a8d9a54 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -1726,6 +1726,8 @@ class TestSearchEngineUrl: @pytest.mark.parametrize('val', [ 'http://example.com/?q={}', + 'http://example.com/?q={0}', + 'http://example.com/?q={0}&a={0}', '', # empty value with none_ok ]) def test_validate_valid(self, klass, val): From 72e081b8da63ddf16913b97b047a074925937241 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 18 Mar 2016 06:18:33 +0100 Subject: [PATCH 112/327] Regenerate authors. --- README.asciidoc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index fea89e001..75cd4af7a 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -153,16 +153,16 @@ Contributors, sorted by the number of commits in descending order: * Claude * Patric Schmitz * meles5 +* Tarcisio Fedrizzi * Artur Shaik * Nathan Isom -* Austin Anderson * Thorsten Wißmann +* Austin Anderson * Alexey "Averrin" Nabrodov * ZDarian * Milan Svoboda * John ShaggyTwoDope Jenkins * Peter Vilim -* Tarcisio Fedrizzi * Oliver Caldwell * Jonas Schürmann * Jimmy @@ -193,9 +193,12 @@ Contributors, sorted by the number of commits in descending order: * Corentin Jule * zwarag * xd1le +* haxwithaxe * evan * dylan araps +* Tomasz Kramkowski * Tomas Orsava +* Tobias Werth * Tim Harder * Thiago Barroso Perrotta * Stefan Tatschner From e72e7dbf5fb2043d66b5fa1ef3c6631c823f2deb Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 18 Mar 2016 06:35:52 +0100 Subject: [PATCH 113/327] Update changelog --- CHANGELOG.asciidoc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index ca46d31cc..eb3f2bbdf 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -29,6 +29,7 @@ Added - New mode `word` for `hints -> mode` which uses a dictionary and link-texts for hints instead of single characters. - New `--all` argument for `:download-cancel` to cancel all running downloads. +- New `password_fill` userscript to fill passwords using the `pass` executable. Changed ~~~~~~~ @@ -40,6 +41,8 @@ Changed - Shift-Insert now also pastes primary selection for prompts. - `:download-remove --all` got un-deprecated to provide symmetry with `:download-cancel --all`. It does the same as `:download-clear`. +- Improved detection of URLs/search terms when pasting multiple lines. +- Don't remove `qutebrowser-editor-*` temporary file if editor subprocess crashed Fixed ~~~~~ @@ -55,6 +58,9 @@ Fixed - Fixed validation of duplicate values in `hints -> chars`. - Fixed crash when PDF.js was partially installed. - Fixed crash when XDG_DOWNLOAD_DIR was not an absolute path. +- Fixed very long filenames when downloading `data://`-URLs. +- Fixed ugly UI fonts on Windows when Liberation Mono is installed +- Fixed crash when unbinding key from a section which doesn't exist in the config v0.5.1 ------ From 4c8f84f97de105952e194c9a45e8cd926f3b1634 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 18 Mar 2016 22:41:42 +0100 Subject: [PATCH 114/327] tox: Update to pytest 2.9.1 - Improve error message when a plugin fails to load. - pytest.fail with non-ascii characters raises an internal pytest error. - junit parses report.nodeid incorrectly, when params IDs contain ::. - SyntaxErrors containing non-ascii lines at the point of failure generated an internal py.test error. - When passing in a bytestring regex pattern to parameterize attempt to decode it as utf-8 ignoring errors. - parametrized test nodes cannot be specified to run on the command line. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 66875ebb2..980acfe46 100644 --- a/tox.ini +++ b/tox.ini @@ -26,7 +26,7 @@ deps = parse==1.6.6 parse-type==0.3.4 py==1.4.31 - pytest==2.9.0 + pytest==2.9.1 pytest-bdd==2.16.0 pytest-catchlog==1.2.2 pytest-cov==2.2.1 From fdce4e96926257983af4f3e3f99c6a6ffa16ddf9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 19 Mar 2016 10:41:36 +0100 Subject: [PATCH 115/327] tox: Update pytest-bdd to 2.16.1 - Cleaned up hooks of the plugin - Fixed report serialization --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 980acfe46..544f1dcd2 100644 --- a/tox.ini +++ b/tox.ini @@ -27,7 +27,7 @@ deps = parse-type==0.3.4 py==1.4.31 pytest==2.9.1 - pytest-bdd==2.16.0 + pytest-bdd==2.16.1 pytest-catchlog==1.2.2 pytest-cov==2.2.1 pytest-faulthandler==1.3.0 From 93e0f292541fd1c790ce6ef2e38b663a44dcb8de Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 19 Mar 2016 10:58:16 +0100 Subject: [PATCH 116/327] travis: Allow OS X to fail for now --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index ccb2d8e3f..4952fddcc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,6 +39,9 @@ matrix: env: TESTENV=check-manifest - os: linux env: TESTENV=eslint + allow_failures: + - os: osx + env: TESTENV=py35 cache: directories: From 8000af1664d2feefb16e3be992cb211f0e5aa818 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sun, 20 Mar 2016 10:49:33 +0100 Subject: [PATCH 117/327] Generalize bookmarks import This change adds `firefox` and `ie` as possible arguments to the importer script. --- scripts/importer.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/scripts/importer.py b/scripts/importer.py index 51e01c106..027d48264 100755 --- a/scripts/importer.py +++ b/scripts/importer.py @@ -21,7 +21,7 @@ """Tool to import data from other browsers. -Currently only importing bookmarks from Chromium is supported. +Currently only importing bookmarks from Netscape Bookmark files is supported. """ @@ -30,24 +30,27 @@ import argparse def main(): args = get_args() - if args.browser == 'chromium': - import_chromium(args.bookmarks) + if args.browser in ['chromium', 'firefox', 'ie']: + import_netscape_bookmarks(args.bookmarks) def get_args(): """Get the argparse parser.""" parser = argparse.ArgumentParser( - epilog="To import bookmarks from Chromium, export them to HTML in " - "Chromium's bookmark manager.") - parser.add_argument('browser', help="Which browser?", choices=['chromium'], + epilog="To import bookmarks from Chromium, Firefox or IE, " + "export them to HTML in your browsers bookmark manager.") + parser.add_argument('browser', help="Which browser?", + choices=['chromium', 'firefox', 'ie'], metavar='browser') parser.add_argument('bookmarks', help="Bookmarks file") args = parser.parse_args() return args +def import_netscape_bookmarks(bookmarks_file): + """Import bookmarks from a NETSCAPE-Bookmark-file v1 -def import_chromium(bookmarks_file): - """Import bookmarks from a HTML file generated by Chromium.""" + Generated by Chromium, Firefox, Internet Explorer and possibly more browsers + """ import bs4 with open(bookmarks_file, encoding='utf-8') as f: soup = bs4.BeautifulSoup(f, 'html.parser') From 573660f36da64492303e3d810b63537d184423f8 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sun, 20 Mar 2016 12:08:26 +0100 Subject: [PATCH 118/327] Fix lint issue --- scripts/importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/importer.py b/scripts/importer.py index 027d48264..a6c17846d 100755 --- a/scripts/importer.py +++ b/scripts/importer.py @@ -49,7 +49,7 @@ def get_args(): def import_netscape_bookmarks(bookmarks_file): """Import bookmarks from a NETSCAPE-Bookmark-file v1 - Generated by Chromium, Firefox, Internet Explorer and possibly more browsers + Generated by Chromium, Firefox, IE and possibly more browsers """ import bs4 with open(bookmarks_file, encoding='utf-8') as f: From a50363ca6736fc85ed5fa59cfeef61c2d79402ac Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sun, 20 Mar 2016 13:02:04 +0100 Subject: [PATCH 119/327] Fix flake8 issues --- scripts/importer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/importer.py b/scripts/importer.py index a6c17846d..44453ea92 100755 --- a/scripts/importer.py +++ b/scripts/importer.py @@ -46,8 +46,9 @@ def get_args(): args = parser.parse_args() return args + def import_netscape_bookmarks(bookmarks_file): - """Import bookmarks from a NETSCAPE-Bookmark-file v1 + """Import bookmarks from a NETSCAPE-Bookmark-file v1. Generated by Chromium, Firefox, IE and possibly more browsers """ From 2d152fd036de3d1e0eb4ba3a1720868b4d95ddc8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 21 Mar 2016 12:56:55 +0100 Subject: [PATCH 120/327] Regenerate authors. --- README.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/README.asciidoc b/README.asciidoc index 75cd4af7a..1c8c6dcf9 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -180,6 +180,7 @@ Contributors, sorted by the number of commits in descending order: * neeasade * jnphilipp * Tobias Patzl +* Philipp Hansch * Peter Michely * Link * Larry Hynes From 20799f97408c9ded0c874138f3bbed09acbc9493 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 21 Mar 2016 21:05:01 +0100 Subject: [PATCH 121/327] tox: Update astroid/pylint to 1.4.5/1.5.5 astroid ------- 2016-03-21 -- 1.4.5 * decoratornames() does not leak InferenceError anymore. * wildcard_imported_names() got replaced by _public_names() Our understanding of wildcard imports through __all__ was half baked to say at least, since we couldn't account for modifications of the list, which results in tons of false positives. Instead, we replaced it with _public_names(), a method which returns all the names that are publicly available in a module, that is that don't start with an underscore, even though this means that there is a possibility for other names to be leaked out even though they are not present in the __all__ variable. The method is private in 1.4.X. pylint ------ 2016-03-21 -- 1.5.5 * Let visit_importfrom from Python 3 porting checker be called when everything is disabled Because the visit method was filtering the patterns it was expecting to be activated, it didn't run when everything but one pattern was disabled, leading to spurious false positives * Don't emit unsubscriptable-value for classes with unknown base classes. * Use an OrderedDict for storing the configuration elements This fixes an issue related to impredictible order of the disable / enable elements from a config file. In certain cases, the disable was coming before the enable which resulted in classes of errors to be enabled, even though the intention was to disable them. The best example for this was in the context of running multiple processes, each one of it having different enables / disables that affected the output. * Don't consider bare and broad except handlers as ignoring NameError, AttributeError and similar exceptions, in the context of checkers for these issues. --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 544f1dcd2..49d59e616 100644 --- a/tox.ini +++ b/tox.ini @@ -126,8 +126,8 @@ passenv = deps = {[testenv]deps} {[testenv:misc]deps} - astroid==1.4.4 - pylint==1.5.4 + astroid==1.4.5 + pylint==1.5.5 requests==2.9.1 ./scripts/dev/pylint_checkers commands = From bc20b7c313646565a0d3318d269fcba1078e45f1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 23 Mar 2016 11:20:25 +0100 Subject: [PATCH 122/327] Add crowdfunding banner to website --- www/header.asciidoc | 3 +++ www/qute.css | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/www/header.asciidoc b/www/header.asciidoc index d16b07ccf..2e5a846cc 100644 --- a/www/header.asciidoc +++ b/www/header.asciidoc @@ -14,4 +14,7 @@ Contributing GitHub +
+qutebrowser is currently running a crowdfunding campaign to add support for the QtWebEngine backend, which fixes many issues. Please check it out! +
+++ diff --git a/www/qute.css b/www/qute.css index 7c4c46c41..082a76221 100644 --- a/www/qute.css +++ b/www/qute.css @@ -44,12 +44,17 @@ body { color: #666666; } +#crowdfunding { + padding: 10px 10px; + background-color: #a6dfff; + margin-bottom: 10px; +} + #menu { padding: 0px 20px; background-color: #555555; color: #CCC; overflow: auto; - margin-bottom: 10px; -webkit-user-select: none; -moz-user-select: none; @@ -178,4 +183,4 @@ table td { -