Simplify userscript running.
This commit is contained in:
parent
b83dd59469
commit
425a7fd7c4
@ -45,6 +45,7 @@ import qutebrowser.utils.log as log
|
|||||||
import qutebrowser.utils.version as version
|
import qutebrowser.utils.version as version
|
||||||
import qutebrowser.utils.url as urlutils
|
import qutebrowser.utils.url as urlutils
|
||||||
import qutebrowser.utils.message as message
|
import qutebrowser.utils.message as message
|
||||||
|
import qutebrowser.commands.userscripts as userscripts
|
||||||
from qutebrowser.config.config import ConfigManager
|
from qutebrowser.config.config import ConfigManager
|
||||||
from qutebrowser.keyinput.modeman import ModeManager
|
from qutebrowser.keyinput.modeman import ModeManager
|
||||||
from qutebrowser.widgets.mainwindow import MainWindow
|
from qutebrowser.widgets.mainwindow import MainWindow
|
||||||
@ -136,6 +137,8 @@ class Application(QApplication):
|
|||||||
quickmarks.init()
|
quickmarks.init()
|
||||||
log.init.debug("Initializing proxy...")
|
log.init.debug("Initializing proxy...")
|
||||||
proxy.init()
|
proxy.init()
|
||||||
|
log.init.debug("Initializing userscripts...")
|
||||||
|
userscripts.init()
|
||||||
log.init.debug("Initializing cookies...")
|
log.init.debug("Initializing cookies...")
|
||||||
self.cookiejar = CookieJar(self)
|
self.cookiejar = CookieJar(self)
|
||||||
log.init.debug("Initializing commands...")
|
log.init.debug("Initializing commands...")
|
||||||
|
@ -37,10 +37,10 @@ import qutebrowser.utils.webelem as webelem
|
|||||||
import qutebrowser.browser.quickmarks as quickmarks
|
import qutebrowser.browser.quickmarks as quickmarks
|
||||||
import qutebrowser.utils.log as log
|
import qutebrowser.utils.log as log
|
||||||
import qutebrowser.utils.url as urlutils
|
import qutebrowser.utils.url as urlutils
|
||||||
|
import qutebrowser.commands.userscripts as userscripts
|
||||||
from qutebrowser.utils.qt import check_overflow, check_print_compat
|
from qutebrowser.utils.qt import check_overflow, check_print_compat
|
||||||
from qutebrowser.utils.editor import ExternalEditor
|
from qutebrowser.utils.editor import ExternalEditor
|
||||||
from qutebrowser.commands.exceptions import CommandError
|
from qutebrowser.commands.exceptions import CommandError
|
||||||
from qutebrowser.commands.userscripts import UserscriptRunner
|
|
||||||
from qutebrowser.utils.usertypes import KeyMode
|
from qutebrowser.utils.usertypes import KeyMode
|
||||||
|
|
||||||
|
|
||||||
@ -57,7 +57,6 @@ class CommandDispatcher:
|
|||||||
Attributes:
|
Attributes:
|
||||||
_tabs: The TabbedBrowser object.
|
_tabs: The TabbedBrowser object.
|
||||||
_editor: The ExternalEditor object.
|
_editor: The ExternalEditor object.
|
||||||
_userscript_runners: A list of userscript runners.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
@ -66,7 +65,6 @@ class CommandDispatcher:
|
|||||||
Args:
|
Args:
|
||||||
parent: The TabbedBrowser for this dispatcher.
|
parent: The TabbedBrowser for this dispatcher.
|
||||||
"""
|
"""
|
||||||
self._userscript_runners = []
|
|
||||||
self._tabs = parent
|
self._tabs = parent
|
||||||
self._editor = None
|
self._editor = None
|
||||||
|
|
||||||
@ -603,7 +601,7 @@ class CommandDispatcher:
|
|||||||
self.openurl(config.get('general', 'startpage')[0])
|
self.openurl(config.get('general', 'startpage')[0])
|
||||||
|
|
||||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||||
def run_userscript(self, cmd, *args, url=None):
|
def run_userscript(self, cmd, *args):
|
||||||
"""Run an userscript given as argument.
|
"""Run an userscript given as argument.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -611,15 +609,8 @@ class CommandDispatcher:
|
|||||||
args: Arguments to pass to the userscript.
|
args: Arguments to pass to the userscript.
|
||||||
url: A custom QUrl to use instead of the current url.
|
url: A custom QUrl to use instead of the current url.
|
||||||
"""
|
"""
|
||||||
if url is None:
|
|
||||||
url = self._tabs.current_url()
|
url = self._tabs.current_url()
|
||||||
# We don't remove the password in the URL here, as it's probably safe
|
userscripts.run(cmd, *args, url=url)
|
||||||
# to pass via env variable.
|
|
||||||
urlstr = url.toString(QUrl.FullyEncoded)
|
|
||||||
runner = UserscriptRunner(self._tabs)
|
|
||||||
runner.got_cmd.connect(self._tabs.got_cmd)
|
|
||||||
runner.run(cmd, *args, env={'QUTE_URL': urlstr})
|
|
||||||
self._userscript_runners.append(runner)
|
|
||||||
|
|
||||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||||
def quickmark_save(self):
|
def quickmark_save(self):
|
||||||
|
@ -31,6 +31,7 @@ import qutebrowser.config.config as config
|
|||||||
import qutebrowser.keyinput.modeman as modeman
|
import qutebrowser.keyinput.modeman as modeman
|
||||||
import qutebrowser.utils.message as message
|
import qutebrowser.utils.message as message
|
||||||
import qutebrowser.utils.webelem as webelem
|
import qutebrowser.utils.webelem as webelem
|
||||||
|
import qutebrowser.commands.userscripts as userscripts
|
||||||
from qutebrowser.commands.exceptions import CommandError
|
from qutebrowser.commands.exceptions import CommandError
|
||||||
from qutebrowser.utils.usertypes import enum, KeyMode
|
from qutebrowser.utils.usertypes import enum, KeyMode
|
||||||
from qutebrowser.utils.log import hints as logger
|
from qutebrowser.utils.log import hints as logger
|
||||||
@ -111,9 +112,6 @@ class HintManager(QObject):
|
|||||||
download_get: Download an URL.
|
download_get: Download an URL.
|
||||||
arg 0: The URL to download, as QUrl.
|
arg 0: The URL to download, as QUrl.
|
||||||
arg 1: The QWebPage to download the URL in.
|
arg 1: The QWebPage to download the URL in.
|
||||||
run_userscript: Emitted when a custom userscript should be run.
|
|
||||||
arg 0: The URL which was selected.
|
|
||||||
arg 1: The userscript/args to run.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
HINT_CSS = """
|
HINT_CSS = """
|
||||||
@ -150,7 +148,6 @@ class HintManager(QObject):
|
|||||||
openurl = pyqtSignal('QUrl', bool)
|
openurl = pyqtSignal('QUrl', bool)
|
||||||
set_open_target = pyqtSignal(str)
|
set_open_target = pyqtSignal(str)
|
||||||
download_get = pyqtSignal('QUrl', 'QWebPage')
|
download_get = pyqtSignal('QUrl', 'QWebPage')
|
||||||
run_userscript = pyqtSignal('QUrl', list)
|
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
"""Constructor.
|
"""Constructor.
|
||||||
@ -369,7 +366,9 @@ class HintManager(QObject):
|
|||||||
def _call_userscript(self, url):
|
def _call_userscript(self, url):
|
||||||
"""Call an userscript from a hint."""
|
"""Call an userscript from a hint."""
|
||||||
qt_ensure_valid(url)
|
qt_ensure_valid(url)
|
||||||
self.run_userscript.emit(url, list(self._context.args))
|
cmd = self._context.args[0]
|
||||||
|
args = self._context.args[1:]
|
||||||
|
userscripts.run(cmd, *args, url=url)
|
||||||
|
|
||||||
def _spawn(self, url):
|
def _spawn(self, url):
|
||||||
"""Spawn a simple command from a hint."""
|
"""Spawn a simple command from a hint."""
|
||||||
|
@ -17,20 +17,30 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""Functions to execute an userscript."""
|
"""Functions to execute an userscript.
|
||||||
|
|
||||||
|
Module attributes:
|
||||||
|
_runners: Active userscript runners from run_userscript.
|
||||||
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import tempfile
|
import tempfile
|
||||||
from select import select
|
from select import select
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from PyQt5.QtCore import (pyqtSignal, QObject, QThread, QStandardPaths,
|
from PyQt5.QtCore import (pyqtSignal, QObject, QThread, QStandardPaths,
|
||||||
QProcessEnvironment, QProcess)
|
QProcessEnvironment, QProcess, QUrl)
|
||||||
|
|
||||||
import qutebrowser.utils.message as message
|
import qutebrowser.utils.message as message
|
||||||
from qutebrowser.utils.misc import get_standard_dir
|
from qutebrowser.utils.misc import get_standard_dir
|
||||||
from qutebrowser.utils.log import procs as logger
|
from qutebrowser.utils.log import procs as logger
|
||||||
from qutebrowser.commands.exceptions import CommandError
|
from qutebrowser.commands.exceptions import CommandError
|
||||||
|
from qutebrowser.commands.managers import CommandManager
|
||||||
|
|
||||||
|
|
||||||
|
_runners = []
|
||||||
|
_commandmanager = None
|
||||||
|
|
||||||
|
|
||||||
class _BlockingFIFOReader(QObject):
|
class _BlockingFIFOReader(QObject):
|
||||||
@ -97,9 +107,11 @@ class _BaseUserscriptRunner(QObject):
|
|||||||
|
|
||||||
Signals:
|
Signals:
|
||||||
got_cmd: Emitted when a new command arrived and should be executed.
|
got_cmd: Emitted when a new command arrived and should be executed.
|
||||||
|
finished: Emitted when the userscript finished running.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
got_cmd = pyqtSignal(str)
|
got_cmd = pyqtSignal(str)
|
||||||
|
finished = pyqtSignal()
|
||||||
|
|
||||||
PROCESS_MESSAGES = {
|
PROCESS_MESSAGES = {
|
||||||
QProcess.FailedToStart: "The process failed to start.",
|
QProcess.FailedToStart: "The process failed to start.",
|
||||||
@ -229,6 +241,7 @@ class _POSIXUserscriptRunner(_BaseUserscriptRunner):
|
|||||||
self.reader.fifo.close()
|
self.reader.fifo.close()
|
||||||
self.reader.deleteLater()
|
self.reader.deleteLater()
|
||||||
super()._cleanup()
|
super()._cleanup()
|
||||||
|
self.finished.emit()
|
||||||
|
|
||||||
def on_thread_finished(self):
|
def on_thread_finished(self):
|
||||||
"""Clean up the QThread object when the thread finished."""
|
"""Clean up the QThread object when the thread finished."""
|
||||||
@ -270,11 +283,13 @@ class _WindowsUserscriptRunner(_BaseUserscriptRunner):
|
|||||||
for line in f:
|
for line in f:
|
||||||
self.got_cmd.emit(line.rstrip())
|
self.got_cmd.emit(line.rstrip())
|
||||||
self._cleanup()
|
self._cleanup()
|
||||||
|
self.finished.emit()
|
||||||
|
|
||||||
def on_proc_error(self, error):
|
def on_proc_error(self, error):
|
||||||
"""Clean up when the process had an error."""
|
"""Clean up when the process had an error."""
|
||||||
super().on_proc_error(error)
|
super().on_proc_error(error)
|
||||||
self._cleanup()
|
self._cleanup()
|
||||||
|
self.finished.emit()
|
||||||
|
|
||||||
def run(self, cmd, *args, env=None):
|
def run(self, cmd, *args, env=None):
|
||||||
self.oshandle, self.filepath = tempfile.mkstemp(text=True)
|
self.oshandle, self.filepath = tempfile.mkstemp(text=True)
|
||||||
@ -287,10 +302,16 @@ class _DummyUserscriptRunner:
|
|||||||
|
|
||||||
Used on unknown systems since we don't know what (or if any) approach will
|
Used on unknown systems since we don't know what (or if any) approach will
|
||||||
work there.
|
work there.
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
finished: Always emitted.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
finished = pyqtSignal()
|
||||||
|
|
||||||
def run(self, _cmd, *_args, _env=None):
|
def run(self, _cmd, *_args, _env=None):
|
||||||
"""Print an error as userscripts are not supported."""
|
"""Print an error as userscripts are not supported."""
|
||||||
|
self.finished.emit()
|
||||||
raise CommandError("Userscripts are not supported on this platform!")
|
raise CommandError("Userscripts are not supported on this platform!")
|
||||||
|
|
||||||
|
|
||||||
@ -302,3 +323,21 @@ elif os.name == 'nt':
|
|||||||
UserscriptRunner = _WindowsUserscriptRunner
|
UserscriptRunner = _WindowsUserscriptRunner
|
||||||
else:
|
else:
|
||||||
UserscriptRunner = _DummyUserscriptRunner
|
UserscriptRunner = _DummyUserscriptRunner
|
||||||
|
|
||||||
|
|
||||||
|
def init():
|
||||||
|
"""Initialize the global _commandmanager."""
|
||||||
|
global _commandmanager
|
||||||
|
_commandmanager = CommandManager()
|
||||||
|
|
||||||
|
|
||||||
|
def run(cmd, *args, url):
|
||||||
|
"""Convenience method to run an userscript."""
|
||||||
|
# We don't remove the password in the URL here, as it's probably safe to
|
||||||
|
# pass via env variable..
|
||||||
|
urlstr = url.toString(QUrl.FullyEncoded)
|
||||||
|
runner = UserscriptRunner()
|
||||||
|
runner.got_cmd.connect(_commandmanager.run_safely)
|
||||||
|
runner.run(cmd, *args, env={'QUTE_URL': urlstr})
|
||||||
|
_runners.append(runner)
|
||||||
|
runner.finished.connect(partial(_runners.remove, runner))
|
||||||
|
@ -112,7 +112,6 @@ class WebView(QWebView):
|
|||||||
self.setPage(self._page)
|
self.setPage(self._page)
|
||||||
self.hintmanager = HintManager(self)
|
self.hintmanager = HintManager(self)
|
||||||
self.hintmanager.mouse_event.connect(self.on_mouse_event)
|
self.hintmanager.mouse_event.connect(self.on_mouse_event)
|
||||||
self.hintmanager.run_userscript.connect(self.run_hint_userscript)
|
|
||||||
self.hintmanager.set_open_target.connect(self.set_force_open_target)
|
self.hintmanager.set_open_target.connect(self.set_force_open_target)
|
||||||
self._page.linkHovered.connect(self.linkHovered)
|
self._page.linkHovered.connect(self.linkHovered)
|
||||||
self._page.mainFrame().loadStarted.connect(self.on_load_started)
|
self._page.mainFrame().loadStarted.connect(self.on_load_started)
|
||||||
@ -344,11 +343,6 @@ class WebView(QWebView):
|
|||||||
"""
|
"""
|
||||||
self._tabs.currentWidget().findText(text, flags)
|
self._tabs.currentWidget().findText(text, flags)
|
||||||
|
|
||||||
@pyqtSlot('QUrl', list)
|
|
||||||
def run_hint_userscript(self, url, args):
|
|
||||||
"""Glue slot to run an userscript via HintManager."""
|
|
||||||
self.tabbedbrowser.cmd.run_userscript(args[0], *args[1:], url=url)
|
|
||||||
|
|
||||||
def go_back(self):
|
def go_back(self):
|
||||||
"""Go back a page in the history."""
|
"""Go back a page in the history."""
|
||||||
if self.page().history().canGoBack():
|
if self.page().history().canGoBack():
|
||||||
|
Loading…
Reference in New Issue
Block a user