Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ffd3edb5d | ||
|
|
49b9144cf0 | ||
|
|
0a882739c8 | ||
|
|
14205ae14f | ||
|
|
727b418d8b | ||
|
|
b3adbec23e | ||
|
|
689f87d596 | ||
|
|
048d8ef794 | ||
|
|
53afa4275c | ||
|
|
e24c723700 | ||
|
|
3b59c35b35 | ||
|
|
a5c1903247 | ||
|
|
40057c26f5 | ||
|
|
94f2b6bdb8 | ||
|
|
df3e41db9b | ||
|
|
d817818fb8 | ||
|
|
45da910d23 | ||
|
|
d1093d1c1d | ||
|
|
ea026b5ecb | ||
|
|
e102551f9f | ||
|
|
b9e3d3cab9 | ||
|
|
274b66ec46 | ||
|
|
ae32b79d54 | ||
|
|
e80e695a56 | ||
|
|
0a31e19eda |
5
.github/CONTRIBUTING.asciidoc
vendored
5
.github/CONTRIBUTING.asciidoc
vendored
@@ -1,3 +1,8 @@
|
||||
IMPORTANT: I'm currently (July 2018) more busy than usual until September,
|
||||
because of exams coming up. Review of non-trivial pull requests will thus be
|
||||
delayed until then. If you're reading this note after mid-September, please
|
||||
open an issue.
|
||||
|
||||
- Before you start to work on something, please leave a comment on the relevant
|
||||
issue (or open one). This makes sure there is no duplicate work done.
|
||||
|
||||
|
||||
@@ -65,6 +65,10 @@ matrix:
|
||||
env: TESTENV=shellcheck
|
||||
services: docker
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
# https://github.com/qutebrowser/qutebrowser/issues/4055
|
||||
- os: linux
|
||||
env: TESTENV=py36-pyqt510
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
||||
@@ -15,6 +15,28 @@ breaking changes (such as renamed commands) can happen in minor releases.
|
||||
// `Fixed` for any bug fixes.
|
||||
// `Security` to invite users to upgrade in case of vulnerabilities.
|
||||
|
||||
v1.5.0 (unreleased)
|
||||
-------------------
|
||||
|
||||
Added
|
||||
~~~~~
|
||||
|
||||
- The qute-pass userscript now has optional OTP support.
|
||||
|
||||
v1.4.1 (unreleased)
|
||||
-------------------
|
||||
|
||||
Fixed
|
||||
~~~~~
|
||||
|
||||
- Rare crash when an error occurs in downloads.
|
||||
- Newlines are now stripped from the :version pastebin URL.
|
||||
- There's a new `mkvenv-pypi-old` environment in `tox.ini` which installs an
|
||||
older Qt, which is needed on Ubuntu 16.04.
|
||||
- Worked around a Qt issue which redirects to a `chrome-error://` page when
|
||||
trying to use U2F.
|
||||
- The `link_pyqt.py` script now works correctly with PyQt 5.11.
|
||||
|
||||
v1.4.0
|
||||
------
|
||||
|
||||
|
||||
@@ -5,6 +5,11 @@ The Compiler <mail@qutebrowser.org>
|
||||
:data-uri:
|
||||
:toc:
|
||||
|
||||
IMPORTANT: I'm currently (July 2018) more busy than usual until September,
|
||||
because of exams coming up. Review of non-trivial pull requests will thus be
|
||||
delayed until then. If you're reading this note after mid-September, please
|
||||
open an issue.
|
||||
|
||||
I `<3` footnote:[Of course, that says `<3` in HTML.] contributors!
|
||||
|
||||
This document contains guidelines for contributing to qutebrowser, as well as
|
||||
|
||||
@@ -392,6 +392,10 @@ https://docs.python.org/3/library/venv.html[virtual environment]:
|
||||
$ tox -e mkvenv-pypi
|
||||
----
|
||||
|
||||
If your system comes with Python 3.5.3 or older (such as Ubuntu 16.04 LTS), use
|
||||
`tox -e mkvenv-pypi-old` instead. This installs an older Qt version (5.10) due
|
||||
to bugs in newer versions.
|
||||
|
||||
This installs all needed Python dependencies in a `.venv` subfolder.
|
||||
|
||||
This comes with an up-to-date Qt/PyQt including QtWebEngine, but has a few
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
appdirs==1.4.3
|
||||
packaging==17.1
|
||||
pyparsing==2.2.0
|
||||
setuptools==39.2.0
|
||||
setuptools==40.0.0
|
||||
six==1.11.0
|
||||
wheel==0.31.1
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
Jinja2
|
||||
Pygments
|
||||
pyPEG2
|
||||
PyYAML!=4.1
|
||||
PyYAML
|
||||
colorama
|
||||
cssutils
|
||||
attrs
|
||||
|
||||
#@ filter: PyYAML != 4.1
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
attrs==18.1.0
|
||||
beautifulsoup4==4.6.0
|
||||
cheroot==6.3.2
|
||||
cheroot==6.3.2.post0
|
||||
click==6.7
|
||||
# colorama==0.3.9
|
||||
coverage==4.5.1
|
||||
@@ -11,7 +11,7 @@ fields==5.0.0
|
||||
Flask==1.0.2
|
||||
glob2==0.6
|
||||
hunter==2.0.2
|
||||
hypothesis==3.65.0
|
||||
hypothesis==3.66.1
|
||||
itsdangerous==0.24
|
||||
# Jinja2==2.10
|
||||
Mako==1.0.7
|
||||
@@ -22,7 +22,7 @@ parse-type==0.4.2
|
||||
pluggy==0.6.0
|
||||
py==1.5.4
|
||||
py-cpuinfo==4.0.0
|
||||
pytest==3.6.2
|
||||
pytest==3.6.3
|
||||
pytest-bdd==2.21.0
|
||||
pytest-benchmark==3.1.1
|
||||
pytest-cov==2.5.1
|
||||
@@ -36,5 +36,5 @@ pytest-travis-fold==1.3.0
|
||||
pytest-xvfb==1.1.0
|
||||
PyVirtualDisplay==0.2.1
|
||||
six==1.11.0
|
||||
vulture==0.27
|
||||
vulture==0.28
|
||||
Werkzeug==0.14.1
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
pluggy==0.6.0
|
||||
py==1.5.4
|
||||
six==1.11.0
|
||||
tox==3.0.0
|
||||
tox==3.1.1
|
||||
virtualenv==16.0.0
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
vulture==0.27
|
||||
vulture==0.28
|
||||
|
||||
@@ -25,9 +25,17 @@ demonstration can be seen here: https://i.imgur.com/KN3XuZP.gif.
|
||||
USAGE = """The domain of the site has to appear as a segment in the pass path, for example: "github.com/cryzed" or
|
||||
"websites/github.com". How the username and password are determined is freely configurable using the CLI arguments. The
|
||||
login information is inserted by emulating key events using qutebrowser's fake-key command in this manner:
|
||||
[USERNAME]<Tab>[PASSWORD], which is compatible with almost all login forms."""
|
||||
[USERNAME]<Tab>[PASSWORD], which is compatible with almost all login forms.
|
||||
|
||||
EPILOG = """Dependencies: tldextract (Python 3 module), pass.
|
||||
Suggested bindings similar to Uzbl's `formfiller` script:
|
||||
|
||||
config.bind('<z><l>', 'spawn --userscript qute-pass')
|
||||
config.bind('<z><u><l>', 'spawn --userscript qute-pass --username-only')
|
||||
config.bind('<z><p><l>', 'spawn --userscript qute-pass --password-only')
|
||||
config.bind('<z><o><l>', 'spawn --userscript qute-pass --otp-only')
|
||||
"""
|
||||
|
||||
EPILOG = """Dependencies: tldextract (Python 3 module), pass, pass-otp (optional).
|
||||
For issues and feedback please use: https://github.com/cryzed/qutebrowser-userscripts.
|
||||
|
||||
WARNING: The login details are viewable as plaintext in qutebrowser's debug log (qute://log) and might be shared if
|
||||
@@ -66,6 +74,7 @@ argument_parser.add_argument('--merge-candidates', '-m', action='store_true',
|
||||
group = argument_parser.add_mutually_exclusive_group()
|
||||
group.add_argument('--username-only', '-e', action='store_true', help='Only insert username')
|
||||
group.add_argument('--password-only', '-w', action='store_true', help='Only insert password')
|
||||
group.add_argument('--otp-only', '-o', action='store_true', help='Only insert OTP code')
|
||||
|
||||
stderr = functools.partial(print, file=sys.stderr)
|
||||
|
||||
@@ -98,11 +107,19 @@ def find_pass_candidates(domain, password_store_path):
|
||||
return candidates
|
||||
|
||||
|
||||
def pass_(path, encoding):
|
||||
process = subprocess.run(['pass', path], stdout=subprocess.PIPE)
|
||||
def _run_pass(command, encoding):
|
||||
process = subprocess.run(command, stdout=subprocess.PIPE)
|
||||
return process.stdout.decode(encoding).strip()
|
||||
|
||||
|
||||
def pass_(path, encoding):
|
||||
return _run_pass(['pass', path], encoding)
|
||||
|
||||
|
||||
def pass_otp(path, encoding):
|
||||
return _run_pass(['pass', 'otp', path], encoding)
|
||||
|
||||
|
||||
def dmenu(items, invocation, encoding):
|
||||
command = shlex.split(invocation)
|
||||
process = subprocess.run(command, input='\n'.join(items).encode(encoding), stdout=subprocess.PIPE)
|
||||
@@ -169,6 +186,9 @@ def main(arguments):
|
||||
fake_key_raw(username)
|
||||
elif arguments.password_only:
|
||||
fake_key_raw(password)
|
||||
elif arguments.otp_only:
|
||||
otp = pass_otp(selection, arguments.io_encoding)
|
||||
fake_key_raw(otp)
|
||||
else:
|
||||
# Enter username and password using fake-key and <Tab> (which seems to work almost universally), then switch
|
||||
# back into insert-mode, so the form can be directly submitted by hitting enter afterwards
|
||||
|
||||
@@ -681,7 +681,6 @@ class Quitter:
|
||||
@cmdutils.argument('session', completion=miscmodels.session)
|
||||
def quit(self, save=False, session=None):
|
||||
"""Quit qutebrowser.
|
||||
|
||||
Args:
|
||||
save: When given, save the open windows even if auto_save.session
|
||||
is turned off.
|
||||
|
||||
@@ -29,7 +29,7 @@ from PyQt5.QtCore import pyqtSlot, pyqtSignal, QTimer
|
||||
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
|
||||
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import message, usertypes, log, urlutils, utils
|
||||
from qutebrowser.utils import message, usertypes, log, urlutils, utils, debug
|
||||
from qutebrowser.browser import downloads
|
||||
from qutebrowser.browser.webkit import http
|
||||
from qutebrowser.browser.webkit.network import networkmanager
|
||||
@@ -307,7 +307,14 @@ class DownloadItem(downloads.AbstractDownloadItem):
|
||||
"""Handle QNetworkReply errors."""
|
||||
if code == QNetworkReply.OperationCanceledError:
|
||||
return
|
||||
self._die(self._reply.errorString())
|
||||
|
||||
if self._reply is None:
|
||||
error = "Unknown error: {}".format(
|
||||
debug.qenum_key(QNetworkReply, code))
|
||||
else:
|
||||
error = self._reply.errorString()
|
||||
|
||||
self._die(error)
|
||||
|
||||
@pyqtSlot()
|
||||
def _on_read_timer_timeout(self):
|
||||
|
||||
@@ -37,6 +37,7 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
|
||||
if qtutils.version_check('5.11', compiled=False):
|
||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-63378
|
||||
profile.installUrlSchemeHandler(b'chrome-error', self)
|
||||
profile.installUrlSchemeHandler(b'chrome-extension', self)
|
||||
|
||||
def requestStarted(self, job):
|
||||
"""Handle a request for a qute: scheme.
|
||||
@@ -49,7 +50,7 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
|
||||
"""
|
||||
url = job.requestUrl()
|
||||
|
||||
if url.scheme() == 'chrome-error':
|
||||
if url.scheme() in ['chrome-error', 'chrome-extension']:
|
||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-63378
|
||||
job.fail(QWebEngineUrlRequestJob.UrlInvalid)
|
||||
return
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
aliases:
|
||||
default:
|
||||
w: session-save
|
||||
q: quit
|
||||
wq: quit --save
|
||||
q: close
|
||||
qa: quit
|
||||
wqa: quit --save
|
||||
type:
|
||||
name: Dict
|
||||
keytype:
|
||||
|
||||
@@ -484,6 +484,7 @@ def pastebin_version(pbclient=None):
|
||||
|
||||
def _on_paste_version_success(url):
|
||||
global pastebin_url
|
||||
url = url.strip()
|
||||
_yank_url(url)
|
||||
pbclient.deleteLater()
|
||||
pastebin_url = url
|
||||
|
||||
@@ -7,4 +7,4 @@ Jinja2==2.10
|
||||
MarkupSafe==1.0
|
||||
Pygments==2.2.0
|
||||
pyPEG2==2.15.2
|
||||
PyYAML==3.13b1 # rq.filter: != 4.1
|
||||
PyYAML==3.13
|
||||
|
||||
@@ -136,7 +136,15 @@ def link_pyqt(executable, venv_path):
|
||||
executable: The python executable where the source files are present.
|
||||
venv_path: The path to the virtualenv site-packages.
|
||||
"""
|
||||
sip_file = get_lib_path(executable, 'sip')
|
||||
try:
|
||||
get_lib_path(executable, 'PyQt5.sip')
|
||||
except Error:
|
||||
# There is no PyQt5.sip, so we need to copy the toplevel sip.
|
||||
sip_file = get_lib_path(executable, 'sip')
|
||||
else:
|
||||
# There is a PyQt5.sip, it'll get copied with the PyQt5 dir.
|
||||
sip_file = None
|
||||
|
||||
sipconfig_file = get_lib_path(executable, 'sipconfig', required=False)
|
||||
pyqt_dir = os.path.dirname(get_lib_path(executable, 'PyQt5.QtCore'))
|
||||
|
||||
|
||||
@@ -987,11 +987,12 @@ def test_pastebin_version(pbclient, message_mock, monkeypatch, qtbot):
|
||||
monkeypatch.setattr('qutebrowser.utils.utils.log_clipboard', True)
|
||||
|
||||
version.pastebin_version(pbclient)
|
||||
pbclient.success.emit("test")
|
||||
pbclient.success.emit("https://www.example.com/\n")
|
||||
|
||||
msg = message_mock.getmsg(usertypes.MessageLevel.info)
|
||||
assert msg.text == "Version url test yanked to clipboard."
|
||||
assert version.pastebin_url == "test"
|
||||
expected_text = "Version url https://www.example.com/ yanked to clipboard."
|
||||
assert msg.text == expected_text
|
||||
assert version.pastebin_url == "https://www.example.com/"
|
||||
|
||||
|
||||
def test_pastebin_version_twice(pbclient, monkeypatch):
|
||||
@@ -1000,16 +1001,16 @@ def test_pastebin_version_twice(pbclient, monkeypatch):
|
||||
lambda: "dummy")
|
||||
|
||||
version.pastebin_version(pbclient)
|
||||
pbclient.success.emit("test")
|
||||
pbclient.success.emit("https://www.example.com/\n")
|
||||
|
||||
pbclient.url = None
|
||||
pbclient.data = None
|
||||
version.pastebin_url = "test2"
|
||||
version.pastebin_url = "https://www.example.org/"
|
||||
|
||||
version.pastebin_version(pbclient)
|
||||
assert pbclient.url is None
|
||||
assert pbclient.data is None
|
||||
assert version.pastebin_url == "test2"
|
||||
assert version.pastebin_url == "https://www.example.org/"
|
||||
|
||||
|
||||
def test_pastebin_version_error(pbclient, caplog, message_mock, monkeypatch):
|
||||
|
||||
13
tox.ini
13
tox.ini
@@ -62,6 +62,19 @@ deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/misc/requirements/requirements-pyqt.txt
|
||||
|
||||
# Older PyQt for Python 3.5
|
||||
# 5.11.2: https://www.riverbankcomputing.com/pipermail/pyqt/2018-July/040511.html
|
||||
# 5.10.1: https://github.com/qutebrowser/qutebrowser/issues/3662
|
||||
[testenv:mkvenv-pypi-old]
|
||||
basepython = {env:PYTHON:python3.5}
|
||||
envdir = {toxinidir}/.venv
|
||||
commands = {envpython} -c ""
|
||||
usedevelop = true
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
PyQt5==5.10
|
||||
sip==4.19.8
|
||||
|
||||
[testenv:misc]
|
||||
ignore_errors = true
|
||||
basepython = {env:PYTHON:python3}
|
||||
|
||||
Reference in New Issue
Block a user