From 3b7f65d9565fc9200c6936ca255be3d15347710c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 28 Oct 2016 18:40:55 +0200 Subject: [PATCH] Show URL in most questions --- qutebrowser/browser/commands.py | 3 +- qutebrowser/browser/urlmarks.py | 5 ++- qutebrowser/browser/webkit/downloads.py | 15 +++++--- .../browser/webkit/network/networkmanager.py | 22 +++++++++-- qutebrowser/browser/webkit/webpage.py | 37 +++++++++++++------ qutebrowser/utils/message.py | 4 +- tests/end2end/features/downloads.feature | 10 ++--- tests/end2end/features/misc.feature | 2 +- tests/end2end/features/test_downloads_bdd.py | 2 +- 9 files changed, 68 insertions(+), 32 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 960915123..2c0e01b5f 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1355,7 +1355,8 @@ class CommandDispatcher: if dest is None: suggested_fn = self._current_title() + ".mht" suggested_fn = utils.sanitize_filename(suggested_fn) - filename, q = downloads.ask_for_filename(suggested_fn, parent=tab) + filename, q = downloads.ask_for_filename(suggested_fn, parent=tab, + url=tab.url()) if filename is not None: mhtml.start_download_checked(filename, tab=tab) else: diff --git a/qutebrowser/browser/urlmarks.py b/qutebrowser/browser/urlmarks.py index 16d9f7bd6..fc727a284 100644 --- a/qutebrowser/browser/urlmarks.py +++ b/qutebrowser/browser/urlmarks.py @@ -26,6 +26,7 @@ to a file on shutdown, so it makes sense to keep them as strings here. """ import os +import html import os.path import functools import collections @@ -171,7 +172,9 @@ class QuickmarkManager(UrlMarkManager): urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded) message.ask_async( "Add quickmark:", usertypes.PromptMode.text, - functools.partial(self.quickmark_add, urlstr)) + functools.partial(self.quickmark_add, urlstr), + text="Please enter a quickmark name for
{}".format( + html.escape(url.toDisplayString()))) @cmdutils.register(instance='quickmark-manager') def quickmark_add(self, url, name): diff --git a/qutebrowser/browser/webkit/downloads.py b/qutebrowser/browser/webkit/downloads.py index a9c6153f8..d25c363ea 100644 --- a/qutebrowser/browser/webkit/downloads.py +++ b/qutebrowser/browser/webkit/downloads.py @@ -28,6 +28,7 @@ import shutil import functools import tempfile import collections +import html import sip from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QTimer, @@ -119,7 +120,7 @@ def create_full_filename(basename, filename): return None -def ask_for_filename(suggested_filename, *, parent=None, +def ask_for_filename(suggested_filename, *, url, parent=None, prompt_download_directory=None): """Prepare a question for a download-path. @@ -133,6 +134,7 @@ def ask_for_filename(suggested_filename, *, parent=None, Args: suggested_filename: The "default"-name that is pre-entered as path. + url: The URL the download originated from. parent: The parent of the question (a QObject). prompt_download_directory: If this is something else than None, it will overwrite the @@ -150,6 +152,8 @@ def ask_for_filename(suggested_filename, *, parent=None, q = usertypes.Question(parent) q.title = "Save file to:" + q.text = "Please enter a location for {}".format( + html.escape(url.toDisplayString())) q.mode = usertypes.PromptMode.text q.completed.connect(q.deleteLater) q.default = _path_suggestion(suggested_filename) @@ -604,13 +608,14 @@ class DownloadItem(QObject): if os.path.isfile(self._filename): # The file already exists, so ask the user if it should be # overwritten. - txt = self._filename + " already exists. Overwrite?" + txt = "{} already exists. Overwrite?".format( + html.escape(self._filename)) self._ask_confirm_question("Overwrite existing file?", txt) # FIFO, device node, etc. Make sure we want to do this elif (os.path.exists(self._filename) and not os.path.isdir(self._filename)): - txt = (self._filename + " already exists and is a special file. " - "Write to this?") + txt = ("{} already exists and is a special file. Write to " + "it anyways?".format(html.escape(self._filename))) self._ask_confirm_question("Overwrite special file?", txt) else: self._create_fileobj() @@ -955,7 +960,7 @@ class DownloadManager(QObject): filename, q = ask_for_filename( suggested_filename, parent=self, prompt_download_directory=prompt_download_directory, - ) + url=reply.url()) # User doesn't want to be asked, so just use the download_dir if filename is not None: diff --git a/qutebrowser/browser/webkit/network/networkmanager.py b/qutebrowser/browser/webkit/network/networkmanager.py index d54eca76d..00d945982 100644 --- a/qutebrowser/browser/webkit/network/networkmanager.py +++ b/qutebrowser/browser/webkit/network/networkmanager.py @@ -22,6 +22,7 @@ import os import collections import netrc +import html from PyQt5.QtCore import (pyqtSlot, pyqtSignal, PYQT_VERSION, QCoreApplication, QUrl, QByteArray) @@ -279,7 +280,15 @@ class NetworkManager(QNetworkAccessManager): return if ssl_strict == 'ask': - err_string = '\n'.join('- ' + err.errorString() for err in errors) + err_list = [] + for err in errors: + err_list.append('
  • {}
  • '.format( + html.escape(err.errorString()))) + err_string = ("Errors while loading {}:
    " + "".format( + html.escape(reply.url().toDisplayString()), + '\n'.join(err_list))) + answer = self._ask('SSL errors - continue?', err_string, mode=usertypes.PromptMode.yesno, owner=reply, default=False) @@ -340,9 +349,11 @@ class NetworkManager(QNetworkAccessManager): if user is None: # netrc check failed + msg = '{} says:
    {}'.format( + html.escape(reply.url().toDisplayString()), + html.escape(authenticator.realm())) answer = self._ask("Authentication required", - authenticator.realm(), - mode=usertypes.PromptMode.user_pwd, + text=msg, mode=usertypes.PromptMode.user_pwd, owner=reply) if answer is not None: user, password = answer.user, answer.password @@ -359,8 +370,11 @@ class NetworkManager(QNetworkAccessManager): authenticator.setUser(user) authenticator.setPassword(password) else: + msg = '{} says:
    {}'.format( + html.escape(proxy.hostName()), + html.escape(authenticator.realm())) answer = self._ask( - "Proxy authentication required", authenticator.realm(), + "Proxy authentication required", msg, mode=usertypes.PromptMode.user_pwd) if answer is not None: authenticator.setUser(answer.user) diff --git a/qutebrowser/browser/webkit/webpage.py b/qutebrowser/browser/webkit/webpage.py index 92a9b9dfb..00b253766 100644 --- a/qutebrowser/browser/webkit/webpage.py +++ b/qutebrowser/browser/webkit/webpage.py @@ -19,6 +19,7 @@ """The main browser widgets.""" +import html import functools from PyQt5.QtCore import pyqtSlot, pyqtSignal, PYQT_VERSION, Qt, QUrl, QPoint @@ -93,11 +94,14 @@ class BrowserPage(QWebPage): # of a bug in PyQt. # See http://www.riverbankcomputing.com/pipermail/pyqt/2014-June/034385.html - def javaScriptPrompt(self, _frame, msg, default): + def javaScriptPrompt(self, _frame, js_msg, default): """Override javaScriptPrompt to use the statusbar.""" if (self._is_shutting_down or config.get('content', 'ignore-javascript-prompt')): return (False, "") + msg = '{} asks:
    {}'.format( + html.escape(self.mainFrame().url().toDisplayString()), + html.escape(js_msg)) answer = message.ask('Javascript prompt', msg, mode=usertypes.PromptMode.text, default=default, @@ -140,7 +144,8 @@ class BrowserPage(QWebPage): scheme = url.scheme() message.confirm_async( title="Open external application for {}-link?".format(scheme), - text="URL: {}".format(url.toDisplayString()), + text="URL: {}".format( + html.escape(url.toDisplayString())), yes_action=functools.partial(QDesktopServices.openUrl, url)) return True elif (info.domain, info.error) in ignored_errors: @@ -171,11 +176,11 @@ class BrowserPage(QWebPage): log.webview.debug("Error domain: {}, error code: {}".format( info.domain, info.error)) title = "Error loading page: {}".format(urlstr) - html = jinja.render( + error_html = jinja.render( 'error.html', title=title, url=urlstr, error=error_str, icon='', qutescheme=False) - errpage.content = html.encode('utf-8') + errpage.content = error_html.encode('utf-8') errpage.encoding = 'utf-8' return True @@ -320,8 +325,8 @@ class BrowserPage(QWebPage): host = frame.url().host() if host: - text = "Allow the website at {} to {}?".format( - frame.url().host(), msgs[feature]) + text = "Allow the website at {} to {}?".format( + html.escape(frame.url().toDisplayString()), msgs[feature]) else: text = "Allow the website to {}?".format(msgs[feature]) @@ -442,26 +447,34 @@ class BrowserPage(QWebPage): return super().extension(ext, opt, out) return handler(opt, out) - def javaScriptAlert(self, frame, msg): + def javaScriptAlert(self, frame, js_msg): """Override javaScriptAlert to use the statusbar.""" - log.js.debug("alert: {}".format(msg)) + log.js.debug("alert: {}".format(js_msg)) if config.get('ui', 'modal-js-dialog'): - return super().javaScriptAlert(frame, msg) + return super().javaScriptAlert(frame, js_msg) if (self._is_shutting_down or config.get('content', 'ignore-javascript-alert')): return + + msg = 'From {}:
    {}'.format( + html.escape(self.mainFrame().url().toDisplayString()), + html.escape(js_msg)) message.ask('Javascript alert', msg, mode=usertypes.PromptMode.alert, abort_on=[self.loadStarted, self.shutting_down]) - def javaScriptConfirm(self, frame, msg): + def javaScriptConfirm(self, frame, js_msg): """Override javaScriptConfirm to use the statusbar.""" - log.js.debug("confirm: {}".format(msg)) + log.js.debug("confirm: {}".format(js_msg)) if config.get('ui', 'modal-js-dialog'): - return super().javaScriptConfirm(frame, msg) + return super().javaScriptConfirm(frame, js_msg) if self._is_shutting_down: return False + + msg = 'From {}:
    {}'.format( + html.escape(self.mainFrame().url().toDisplayString()), + html.escape(js_msg)) ans = message.ask('Javascript confirm', msg, mode=usertypes.PromptMode.yesno, abort_on=[self.loadStarted, self.shutting_down]) diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py index 62261f498..368bb8289 100644 --- a/qutebrowser/utils/message.py +++ b/qutebrowser/utils/message.py @@ -110,7 +110,7 @@ def ask(*args, **kwargs): return answer -def ask_async(text, mode, handler, **kwargs): +def ask_async(title, mode, handler, **kwargs): """Ask an async question in the statusbar. Args: @@ -120,7 +120,7 @@ def ask_async(text, mode, handler, **kwargs): default: The default value to display. text: Additional text to show. """ - question = _build_question(text, mode=mode, **kwargs) + question = _build_question(title, mode=mode, **kwargs) question.answered.connect(handler) question.completed.connect(question.deleteLater) global_bridge.ask(question, blocking=False) diff --git a/tests/end2end/features/downloads.feature b/tests/end2end/features/downloads.feature index dd8419671..9a868cd57 100644 --- a/tests/end2end/features/downloads.feature +++ b/tests/end2end/features/downloads.feature @@ -63,7 +63,7 @@ Feature: Downloading things from a website. And I set storage -> prompt-download-directory to true And I open data/downloads/issue1243.html And I hint with args "links download" and follow a - And I wait for "Asking question text=None title='Save file to:'>, *" in the log + And I wait for "Asking question text=* title='Save file to:'>, *" in the log Then the error "Download error: No handler found for qute://!" should be shown Scenario: Downloading a data: link (issue 1214) @@ -71,7 +71,7 @@ Feature: Downloading things from a website. And I set storage -> prompt-download-directory to true And I open data/downloads/issue1214.html And I hint with args "links download" and follow a - And I wait for "Asking question text=None title='Save file to:'>, *" in the log + And I wait for "Asking question text=* title='Save file to:'>, *" in the log And I run :leave-mode Then no crash should happen @@ -338,7 +338,7 @@ Feature: Downloading things from a website. When I set storage -> prompt-download-directory to true And I open data/downloads/issue1725.html And I run :click-element id long-link - And I wait for "Asking question text=None title='Save file to:'>, *" in the log + And I wait for "Asking question text=* title='Save file to:'>, *" in the log And I directly open the download And I wait until the download is finished Then "Opening * with [*python*]" should be logged @@ -488,9 +488,9 @@ Feature: Downloading things from a website. Scenario: Answering a question for a cancelled download (#415) When I set storage -> prompt-download-directory to true And I run :download http://localhost:(port)/data/downloads/download.bin - And I wait for "Asking question text=None title='Save file to:'>, *" in the log + And I wait for "Asking question text=* title='Save file to:'>, *" in the log And I run :download http://localhost:(port)/data/downloads/download2.bin - And I wait for "Asking question text=None title='Save file to:'>, *" in the log + And I wait for "Asking question text=* title='Save file to:'>, *" in the log And I run :download-cancel with count 2 And I run :prompt-accept And I wait until the download is finished diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index e0b60f9af..46e4dc287 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -324,7 +324,7 @@ Feature: Various utility commands. 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=None title='Save file to:'>, *" in the log + And I wait for "Asking question text=* title='Save file to:'>, *" in the log And I run :leave-mode Then no crash should happen diff --git a/tests/end2end/features/test_downloads_bdd.py b/tests/end2end/features/test_downloads_bdd.py index 76e1584ab..ac82aa04f 100644 --- a/tests/end2end/features/test_downloads_bdd.py +++ b/tests/end2end/features/test_downloads_bdd.py @@ -31,7 +31,7 @@ pytestmark = pytest.mark.qtwebengine_todo("Downloads not implemented yet", PROMPT_MSG = ("Asking question text=None " + "default={!r} mode= text=* " "title='Save file to:'>, *")