From 4999a59470dbc08de7179ea3955c90b6cd8acdd8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 6 May 2014 15:36:15 +0200 Subject: [PATCH] Add pastebin button to crash dialog --- qutebrowser/app.py | 7 +++++++ qutebrowser/utils/misc.py | 23 +++++++++++++++++++++++ qutebrowser/widgets/crash.py | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index e0e561e00..be935f887 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -399,6 +399,13 @@ class QuteBrowser(QApplication): self._quit_status['crash'] = False + # Give key input back for crash dialog + try: + self.removeEventFilter(self.modeman) + except AttributeError: + # self.modeman could be None + pass + if exctype is BdbQuit or not issubclass(exctype, Exception): # pdb exit, KeyboardInterrupt, ... try: diff --git a/qutebrowser/utils/misc.py b/qutebrowser/utils/misc.py index caecb4599..92f955874 100644 --- a/qutebrowser/utils/misc.py +++ b/qutebrowser/utils/misc.py @@ -20,6 +20,8 @@ import re import sys import shlex +import urllib.request +from urllib.parse import urljoin, urlencode from functools import reduce from pkg_resources import resource_string @@ -110,3 +112,24 @@ def shell_escape(s): # use single quotes, and put single quotes into double quotes # the string $'b is then quoted as '$'"'"'b' return "'" + s.replace("'", "'\"'\"'") + "'" + + +def pastebin(text): + """Paste the text into a pastebin and return the URL.""" + api_url = 'http://paste.the-compiler.org/api/' + data = { + 'text': text, + 'title': "qutebrowser crash", + 'name': "qutebrowser", + } + encoded_data = urlencode(data).encode('utf-8') + create_url = urljoin(api_url, 'create') + headers = { + 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' + } + request = urllib.request.Request(create_url, encoded_data, headers) + response = urllib.request.urlopen(request) + url = response.read().decode('utf-8').rstrip() + if not url.startswith('http'): + raise ValueError("Got unexpected response: {}".format(url)) + return url diff --git a/qutebrowser/widgets/crash.py b/qutebrowser/widgets/crash.py index 1e4c6179b..cb1c05689 100644 --- a/qutebrowser/widgets/crash.py +++ b/qutebrowser/widgets/crash.py @@ -19,11 +19,15 @@ import sys import traceback +from urllib.error import URLError +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QClipboard from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton, - QVBoxLayout, QHBoxLayout) + QVBoxLayout, QHBoxLayout, QApplication) import qutebrowser.config.config as config +import qutebrowser.utils.misc as utils from qutebrowser.utils.version import version @@ -39,6 +43,8 @@ class CrashDialog(QDialog): _hbox: The QHboxLayout containing the buttons _btn_quit: The quit button _btn_restore: the restore button + _btn_pastebin: the pastebin button + _url: Pastebin URL QLabel. """ def __init__(self, pages, cmdhist, exc): @@ -59,7 +65,7 @@ class CrashDialog(QDialog): text = ("Argh! qutebrowser crashed unexpectedly.
" "Please review the info below to remove sensitive data and " "then submit it to " - "crash@qutebrowser.org.

") + "crash@qutebrowser.org or click 'pastebin'.

") if pages: text += ("You can click \"Restore tabs\" to attempt to reopen " "your open tabs.") @@ -68,15 +74,25 @@ class CrashDialog(QDialog): self._vbox.addWidget(self._lbl) self._txt = QTextEdit() - self._txt.setReadOnly(True) + #self._txt.setReadOnly(True) self._txt.setText(self._crash_info(pages, cmdhist, exc)) self._vbox.addWidget(self._txt) + self._url = QLabel() + self._url.setTextInteractionFlags(Qt.TextSelectableByMouse | + Qt.TextSelectableByKeyboard | + Qt.LinksAccessibleByMouse | + Qt.LinksAccessibleByKeyboard) + self._vbox.addWidget(self._url) + self._hbox = QHBoxLayout() self._hbox.addStretch() self._btn_quit = QPushButton() self._btn_quit.setText("Quit") self._btn_quit.clicked.connect(self.reject) + self._btn_pastebin = QPushButton() + self._btn_pastebin.setText("Pastebin") + self._btn_pastebin.clicked.connect(self.pastebin) self._hbox.addWidget(self._btn_quit) if pages: self._btn_restore = QPushButton() @@ -84,6 +100,7 @@ class CrashDialog(QDialog): self._btn_restore.clicked.connect(self.accept) self._btn_restore.setDefault(True) self._hbox.addWidget(self._btn_restore) + self._hbox.addWidget(self._btn_pastebin) self._vbox.addLayout(self._hbox) @@ -116,3 +133,15 @@ class CrashDialog(QDialog): chunks.append('\n'.join([h, body])) return '\n\n'.join(chunks) + + def pastebin(self): + """Paste the crash info into the pastebin.""" + try: + url = utils.pastebin(self._txt.toPlainText()) + except (URLError, ValueError) as e: + self._url.setText('Error while pasting: {}'.format(e)) + return + self._btn_pastebin.setEnabled(False) + self._url.setText("URL copied to clipboard: " + "{}".format(url, url)) + QApplication.clipboard().setText(url, QClipboard.Clipboard)