Store QUTE_TEXT/QUTE_HTML in files for userscripts.

Fixes #644.
This commit is contained in:
Florian Bruhin 2015-04-20 07:50:47 +02:00
parent 9442fd4b75
commit f93eef848c
5 changed files with 66 additions and 17 deletions

View File

@ -14,6 +14,14 @@ This project adheres to http://semver.org/[Semantic Versioning].
// `Fixed` for any bug fixes.
// `Security` to invite users to upgrade in case of vulnerabilities.
v0.3.0 (unreleased)
-------------------
Changed
~~~~~~~
- `QUTE_HTML` and `QUTE_TEXT` for userscripts now don't store the contents directly, and instead contain a filename.
https://github.com/The-Compiler/qutebrowser/releases/tag/v0.2.1[v0.2.1]
-----------------------------------------------------------------------

View File

@ -24,8 +24,8 @@ The following environment variables will be set when an userscript is launched:
command or key binding).
- `QUTE_USER_AGENT`: The currently set user agent.
- `QUTE_FIFO`: The FIFO or file to write commands to.
- `QUTE_HTML`: The HTML source of the current page.
- `QUTE_TEXT`: The plaintext of the current page.
- `QUTE_HTML`: Path of a file containing the HTML source of the current page.
- `QUTE_TEXT`: Path of a file containing the plaintext of the current page.
In `command` mode:

View File

@ -876,14 +876,13 @@ class CommandDispatcher:
env['QUTE_TITLE'] = tabbed_browser.page_title(idx)
webview = tabbed_browser.currentWidget()
if webview is not None:
if webview is None:
mainframe = None
else:
if webview.hasSelection():
env['QUTE_SELECTED_TEXT'] = webview.selectedText()
env['QUTE_SELECTED_HTML'] = webview.selectedHtml()
mainframe = webview.page().mainFrame()
if mainframe is not None:
env['QUTE_HTML'] = mainframe.toHtml()
env['QUTE_TEXT'] = mainframe.toPlainText()
try:
url = tabbed_browser.current_url()
@ -892,6 +891,7 @@ class CommandDispatcher:
else:
env['QUTE_URL'] = url.toString(QUrl.FullyEncoded)
env.update(userscripts.store_source(mainframe))
userscripts.run(cmd, *args, win_id=self._win_id, env=env)
@cmdutils.register(instance='command-dispatcher', scope='window')

View File

@ -523,12 +523,11 @@ class HintManager(QObject):
'QUTE_MODE': 'hints',
'QUTE_SELECTED_TEXT': str(elem),
'QUTE_SELECTED_HTML': elem.toOuterXml(),
'QUTE_HTML': frame.toHtml(),
'QUTE_TEXT': frame.toPlainText(),
}
url = self._resolve_url(elem, context.baseurl)
if url is not None:
env['QUTE_URL'] = url.toString(QUrl.FullyEncoded)
env.update(userscripts.store_source(frame))
userscripts.run(cmd, *args, win_id=self._win_id, env=env)
def _spawn(self, url, context):

View File

@ -101,6 +101,7 @@ class _BaseUserscriptRunner(QObject):
self._win_id = win_id
self._filepath = None
self._proc = None
self._env = None
def _run_process(self, cmd, *args, env):
"""Start the given command via QProcess.
@ -110,6 +111,7 @@ class _BaseUserscriptRunner(QObject):
*args: The arguments to hand to the command
env: A dictionary of environment variables to add.
"""
self._env = env
self._proc = QProcess(self)
procenv = QProcessEnvironment.systemEnvironment()
procenv.insert('QUTE_FIFO', self._filepath)
@ -122,17 +124,26 @@ class _BaseUserscriptRunner(QObject):
self._proc.start(cmd, args)
def _cleanup(self):
"""Clean up the temporary file."""
log.procs.debug("Deleting temporary file {}.".format(self._filepath))
try:
os.remove(self._filepath)
except OSError as e:
# NOTE: Do not replace this with "raise CommandError" as it's
# executed async.
message.error(self._win_id,
"Failed to delete tempfile... ({})".format(e))
"""Clean up temporary files."""
tempfiles = [self._filepath]
if self._env is not None:
if 'QUTE_HTML' in self._env:
tempfiles.append(self._env['QUTE_HTML'])
if 'QUTE_TEXT' in self._env:
tempfiles.append(self._env['QUTE_TEXT'])
for fn in tempfiles:
log.procs.debug("Deleting temporary file {}.".format(fn))
try:
os.remove(fn)
except OSError as e:
# NOTE: Do not replace this with "raise CommandError" as it's
# executed async.
message.error(
self._win_id, "Failed to delete tempfile {} ({})!".format(
fn, e))
self._filepath = None
self._proc = None
self._env = None
def run(self, cmd, *args, env=None):
"""Run the userscript given.
@ -305,6 +316,37 @@ else:
UserscriptRunner = _DummyUserscriptRunner
def store_source(frame):
"""Store HTML/plaintext in files.
This writes files containing the HTML/plaintext source of the page, and
returns a dict with the paths as QUTE_HTML/QUTE_TEXT.
Args:
frame: The QWebFrame to get the info from, or None to do nothing.
Return:
A dictionary with the needed environment variables.
Warning:
The caller is responsible to delete the files after using them!
"""
if frame is None:
return {}
env = {}
with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8',
suffix='.html',
delete=False) as html_file:
html_file.write(frame.toHtml())
env['QUTE_HTML'] = html_file.name
with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8',
suffix='.txt',
delete=False) as txt_file:
txt_file.write(frame.toPlainText())
env['QUTE_TEXT'] = txt_file.name
return env
def run(cmd, *args, win_id, env):
"""Convenience method to run an userscript.