Plugin support #30

Open
The-Compiler opened this Issue Oct 1, 2014 · 71 comments

Comments

Projects
Collaborator

The-Compiler commented Oct 1, 2014

There should be support for writing plugins which are more complex than the simple (non-js) userscripts.

Python plugins are the way to go. Javascript support would be cool but is currently hard because there's no second JS context.

WebExtensions

Support for WebExtensions is currently out-of-scope for qutebrowser. It's hard to even evaluate to which extend support for them would be possible, but if possible, it's going to be a lot of work. Partial support for often used plugin APIs (i.e. some WebExtensions) might happen some day, but currently it's too early to say if/when. The main focus is on a Python plugin API right now. Related QtWebEngine issues which might make this easier: QTBUG-51185, QTBUG-61676.

Plugin ideas

  • Adblock (probably better in core?) (implemented in core)
  • Ghostery/Disconnect
  • Certificate Patrol
  • Remove google redirects
  • Filling forms (e.g. password management with KeePassX/gnome keyring/passwordstore/... - as in #180, also form filling as in #695)
  • HoverZoom
  • speed dial
  • periodic auto-reload
  • detailed page loading bar (like otter/opera)
  • automatically spawn mpv on video pages
  • copy URLs of all pages or write them to a file
  • DownThemAll
  • Google Cloud Print (devguide)
  • Rewriting URLs to their .onion equivalents based on a list
  • Chromecast integration? (#1319)
  • autoscroll
  • decentraleyes
  • URL rewriting like PureURL for Firefox (removing things like utm_foo)
  • Open certain links (like youtube) in a handler application automatically instead of following it
  • Adding a "real" address bar
  • Adding a bookmarks bar
  • Yanking a short URL (e.g. youtube has a shortlink ref for youtu.be links)
  • Restarting failed downloads after a timeout (with bad internet connection)
  • alternative stylesheet selector
  • A way to show md5/sha/etc. for downloads or even enter the correct one.
  • also see existing dwb userscripts

Abilities that plugins should have

  • Interact with the WebElements on the page (e.g. make non-clickable links clickable).
  • Add widgets to the statusbar. (e.g. RSS or search engine symbol)
  • Register new commands (with capital letter, like vim)
  • Register new settings (in a special [plugin.foo] section probably)
  • Subscribe to Qt signals (QWebPage/QWebView)
  • Add new completions, e.g. with an external bookmark manager like cym13/bookmark
  • Create widget-tabs when #724 is done, so someone could theoretically write an RSS reader or mail client or whatever
  • Adjust page content, like Detox (and many others)
  • Maybe make it possible to interact with the command input so that adding www. and .com to an URL like in #1749 would be possible.
  • Maybe bind keys with prefixes, e.g. g# with any number
  • Custom URL schemes

Libraries

Resources

Javascript plugins

  • Javascript: QJSEngine
  • PyV8 would probably work as well for javascript extensions (and maybe be easier/more pythonic), but it's another dependency and a different javascript engine.

Possible API inspirations

Other interesting links

First ideas

Separate namespace for plugins

There should be a new qutebrowser.pluginapi namespace. Everything outside of that namespace is to be considered to be "private" for plugins, and will likely break at some point.

Only some stuff (like possibly utils.urlutils) will be exposed directly - everything else will be exposed through a wrapper, for various reasons:

  • I can change stuff without breaking plugins, if I update the wrappers accordingly.
  • The wrappers will be easier to expose to a javascript plugin API
  • They will be less complex than the qutebrowser internals, so it should be easier to get started

If something is missing from the wrappers, it should be trivial for a plugin author to open a feature request to have it added - this should be encouraged in the docs.

Qt signal based workflow

I don't think using something like pluggy will be neccessary (especially because pluggy is still expected to undergo changes, and is not packaged).

Instead of that, there's a simple function (say, plugin_init) which gets called when a plugin is loaded. The plugin gets a PluginContext object with some version information and a signals attribute.

The signals object then has many signals (perhaps also in sub-objects), like started, cmd.entered, etc. etc. Such a signals object also exists per-tab and per-window. The plugin will get the window-specific object with a global new_window signal (and something similar for new tabs).

Those events/signals are the main entry point for plugins. There will also be APIs for certain tasks (like adding an icon to the statusbar), but the majority of tasks should be possible using those signals.

For most actions, an API to call commands nicely (i.e. as functions rather than as strings) would probably already suffice.

Exposing plugin signals to userscripts

This is related to #902 - the signals mentioned above should be written to userscript FIFOs so those can react on the events - similar to herbstluftwm's hooks and herbstclient --idle.

This could possibly be implemented as a plugin by itself, which binds to all available signals - some layer to transform the signal arguments to strings will be needed either way.

A line written to the FIFO could look like this:

category sender signalname arg1 arg2 ...
  • category: For extensibility - currently always signal
  • sender: A dotted path of the sender of the signal, i.e. which signal object from above emitted the signal:
    • global: A global signal, like started
    • win0: A signal from the window with win ID 0
    • win0.tab1: A signal from the tab 1 in window 0
  • signalname: A dotted path of the signal, e.g. started or cmd.entered, etc.
  • arg1, arg2: Arguments which were passed to the signal, which need to be converted to a string in some way. Either there's a plugin which handles this argument for argument, or there's type-checking:
    • str: passed through
    • int, float: str() called on them
    • QUrl: url.toString() called on them
    • window objects -> win0
    • tab objects -> win0.tab1

Resources from BPL

resources

libraries & apps

@The-Compiler The-Compiler self-assigned this Oct 1, 2014

This comment has been minimized.

Show comment Hide comment
@noctuid

noctuid Apr 14, 2015

automatically spawn mpv on video pages

Just to contribute to this idea for a possible future plugin, it would be awesome to be able to bind a key to manually invoke mpv (or another player with :spawn) on the direct link (not the {url}) of a playing video. With pentadactyl I do this with the firefox media sniffer plugin currently.

noctuid commented Apr 14, 2015

automatically spawn mpv on video pages

Just to contribute to this idea for a possible future plugin, it would be awesome to be able to bind a key to manually invoke mpv (or another player with :spawn) on the direct link (not the {url}) of a playing video. With pentadactyl I do this with the firefox media sniffer plugin currently.

This was referenced May 18, 2015

This comment has been minimized.

Show comment Hide comment
@cwmke

cwmke Aug 22, 2015

Just thought I would throw a couple possibilities/alternatives into the mix for long term feature ideas. Ublock Origin, Umatrix, Random-Agent-Switcher. Also, pass support would be amazing. http://www.passwordstore.org/ Thanks for this incredible project. I'm really excited for its future.

cwmke commented Aug 22, 2015

Just thought I would throw a couple possibilities/alternatives into the mix for long term feature ideas. Ublock Origin, Umatrix, Random-Agent-Switcher. Also, pass support would be amazing. http://www.passwordstore.org/ Thanks for this incredible project. I'm really excited for its future.

This comment has been minimized.

Show comment Hide comment
@lamarpavel

lamarpavel Aug 22, 2015

Contributor

@cwmke The integration of password managers has come up in several suggestions before and it is unlikely that one specific password manager will be integrated into qutebrowser, rather there might be an abstract interface that can be used with many different password managers.

Until then, there are user scripts for this purpose, for example this one.

Contributor

lamarpavel commented Aug 22, 2015

@cwmke The integration of password managers has come up in several suggestions before and it is unlikely that one specific password manager will be integrated into qutebrowser, rather there might be an abstract interface that can be used with many different password managers.

Until then, there are user scripts for this purpose, for example this one.

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Sep 1, 2015

Collaborator

I added some thoughts to "First ideas" above - any feedback would be much appreciated!

Collaborator

The-Compiler commented Sep 1, 2015

I added some thoughts to "First ideas" above - any feedback would be much appreciated!

@The-Compiler The-Compiler removed their assignment Oct 1, 2015

This comment has been minimized.

Show comment Hide comment
@traverseda

traverseda Nov 19, 2015

Has any progress been made in this direction?

Has any progress been made in this direction?

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Nov 19, 2015

Collaborator

No, not yet. Tests, the QtWebEngine backend, config revolution and per-domain settings are the current main focus. After that I'll look at this, but it's probably going to take a few months.

Collaborator

The-Compiler commented Nov 19, 2015

No, not yet. Tests, the QtWebEngine backend, config revolution and per-domain settings are the current main focus. After that I'll look at this, but it's probably going to take a few months.

This comment has been minimized.

Show comment Hide comment
@traverseda

traverseda Nov 19, 2015

Seems like reasonable priorities. Just though I'd drop in and remind you that this issues exists.

A lot of projects, like django, allow you to include apps that are basically just python code. You can get a long way with monkey patching, and just providing some entry points.

Is there a reason you don't provide a quick and hacky solution? Load and run python scripts from a directory or something?

Seems like reasonable priorities. Just though I'd drop in and remind you that this issues exists.

A lot of projects, like django, allow you to include apps that are basically just python code. You can get a long way with monkey patching, and just providing some entry points.

Is there a reason you don't provide a quick and hacky solution? Load and run python scripts from a directory or something?

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Nov 19, 2015

Collaborator

Yes, because I don't like quick and hacky solutions 😉

I don't want third party plugins which break with every release, there's already Firefox for that 😉 - so I'd like to do things right.

Collaborator

The-Compiler commented Nov 19, 2015

Yes, because I don't like quick and hacky solutions 😉

I don't want third party plugins which break with every release, there's already Firefox for that 😉 - so I'd like to do things right.

This comment has been minimized.

Show comment Hide comment
@traverseda

traverseda Nov 19, 2015

Fair enough

Fair enough

This comment has been minimized.

Show comment Hide comment
@btall

btall Mar 25, 2016

👍 Ghostery/Disconnect and Remove google redirects

btall commented Mar 25, 2016

👍 Ghostery/Disconnect and Remove google redirects

This comment has been minimized.

Show comment Hide comment
@RomanSC

RomanSC Jun 8, 2016

RomanSC commented Jun 8, 2016

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Jun 8, 2016

Collaborator

@RomanSC: I think you mean the ability to use adblock-style lists rather than just hosts, because all of the default block lists are already third party, and you can add your own 😉

See #29 for that, though it's not a priority for me currently, as the simple host-blocker we have now works well enough for 95% of the cases.

Collaborator

The-Compiler commented Jun 8, 2016

@RomanSC: I think you mean the ability to use adblock-style lists rather than just hosts, because all of the default block lists are already third party, and you can add your own 😉

See #29 for that, though it's not a priority for me currently, as the simple host-blocker we have now works well enough for 95% of the cases.

@ids1024 ids1024 referenced this issue in mps-youtube/mps-youtube Jun 16, 2016

Open

WIP Plugin API Code #316

This comment has been minimized.

Show comment Hide comment
@deniss-s

deniss-s Jul 25, 2016

I would add HTTPS Everywhere to the list of useful plugins.

I would add HTTPS Everywhere to the list of useful plugins.

This comment has been minimized.

Show comment Hide comment
@haasn

haasn Aug 6, 2016

Contributor

Allow me to add FireGestures to the list of my really-want-to-have-this plugins (mostly due to muscle memory, and because I often want to alternate between using the mouse and the keyboard depending on what is more convenient at the time) :)

Edit: The third party program easystroke completely replicates all of FireGestures' functionality for me. If anybody else is missing mouse gestures, I can highly recommend it!

Edit 2: Seems like easystroke is a bit buggy overall, and can often crash X. Instead, I've adjusted to having my tab bar on the side and using the mouse wheel on the tab bar area.

Contributor

haasn commented Aug 6, 2016

Allow me to add FireGestures to the list of my really-want-to-have-this plugins (mostly due to muscle memory, and because I often want to alternate between using the mouse and the keyboard depending on what is more convenient at the time) :)

Edit: The third party program easystroke completely replicates all of FireGestures' functionality for me. If anybody else is missing mouse gestures, I can highly recommend it!

Edit 2: Seems like easystroke is a bit buggy overall, and can often crash X. Instead, I've adjusted to having my tab bar on the side and using the mouse wheel on the tab bar area.

This comment has been minimized.

Show comment Hide comment
@Elronnd

Elronnd Aug 8, 2016

Here's what I thought a simple plugin might look like, as inspiration for when/if plugins are actually implemented. Aside from that, here are some methods, not really organized, that might should be in here:

  • currpage.add_css_rule(tag, ruleslist) # str, dict
  • currpage.del_css_rule(tag, key, value) # useless, maybe, because we can currpage.add_css_rule(tag, {myrule: default})
  • currpage.move(direction) # (left|right)
  • currpage.forms[0].fill(content) # str
  • currpage is an instance of Page(), and pages is a list of those?
  • settings.store/fetch(value) # stored in DB? json? App can create its own files? All values that can be stored must be declared, and maxsize declared at beginning of plug, or in manifest.json type thing? Maybe not manifest.json, but have the user confirm (e.g. "this plug may take up to X MB of space")?
  • qb_command(command)

Elronnd commented Aug 8, 2016

Here's what I thought a simple plugin might look like, as inspiration for when/if plugins are actually implemented. Aside from that, here are some methods, not really organized, that might should be in here:

  • currpage.add_css_rule(tag, ruleslist) # str, dict
  • currpage.del_css_rule(tag, key, value) # useless, maybe, because we can currpage.add_css_rule(tag, {myrule: default})
  • currpage.move(direction) # (left|right)
  • currpage.forms[0].fill(content) # str
  • currpage is an instance of Page(), and pages is a list of those?
  • settings.store/fetch(value) # stored in DB? json? App can create its own files? All values that can be stored must be declared, and maxsize declared at beginning of plug, or in manifest.json type thing? Maybe not manifest.json, but have the user confirm (e.g. "this plug may take up to X MB of space")?
  • qb_command(command)

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Aug 8, 2016

Collaborator

So I disagree with some of that, and agree with some other points of that - but we're really still at the brainstorming state here 😉

Here is how I'd perhaps imagine a plugin reloading a given site periodically:

"""Module docstring automatically used as plugin description."""

from qutebrowser import pluginapi

@pluginapi.hook('new-tab')
def handle_new_tab(tab):
    if tab.url() == QUrl('http://example.com'):
        pluginapi.utils.setup_timer(60 * 1000, tab.refresh)

The hooks will then be named just like the same hooks for other purposes (like autocmds).

Collaborator

The-Compiler commented Aug 8, 2016

So I disagree with some of that, and agree with some other points of that - but we're really still at the brainstorming state here 😉

Here is how I'd perhaps imagine a plugin reloading a given site periodically:

"""Module docstring automatically used as plugin description."""

from qutebrowser import pluginapi

@pluginapi.hook('new-tab')
def handle_new_tab(tab):
    if tab.url() == QUrl('http://example.com'):
        pluginapi.utils.setup_timer(60 * 1000, tab.refresh)

The hooks will then be named just like the same hooks for other purposes (like autocmds).

This comment has been minimized.

Show comment Hide comment
@alem0lars

alem0lars Oct 18, 2017

I have interest in contributing to provide LastPass support. I have Python knowledge, however I don't know qutebrowser from the developer's perspective.

Atm is there a way to integrate lastpass in qutebrowser with a plugin or something else (I can write the needed code)?

The passwordfill is just a userscript, that would be the last chance if nothing else is possible.

I have interest in contributing to provide LastPass support. I have Python knowledge, however I don't know qutebrowser from the developer's perspective.

Atm is there a way to integrate lastpass in qutebrowser with a plugin or something else (I can write the needed code)?

The passwordfill is just a userscript, that would be the last chance if nothing else is possible.

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Oct 18, 2017

Collaborator

Why "just a userscript"? There currently isn't any plugin API other than that, that's why this issue is still open 😉

Collaborator

The-Compiler commented Oct 18, 2017

Why "just a userscript"? There currently isn't any plugin API other than that, that's why this issue is still open 😉

This comment has been minimized.

Show comment Hide comment
@laugh-at-me

laugh-at-me Nov 5, 2017

Contributor

HTTPS Everywhere cannot be imitated by a userscript and is essential.

Contributor

laugh-at-me commented Nov 5, 2017

HTTPS Everywhere cannot be imitated by a userscript and is essential.

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Nov 5, 2017

Collaborator

@laugh-at-me Also see #335 for that.

Collaborator

The-Compiler commented Nov 5, 2017

@laugh-at-me Also see #335 for that.

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Nov 21, 2017

Collaborator

Getting back to what @lamarpavel and @Elronnd mentioned earlier:

I think it's a good idea to take a look at e.g. the WebExtension API to get some inspiration, but at the same time, there are good reasons for our API to diverge from that:

  • It's Python, and not JavaScript. We should create an API which seems right/clean/simple/intuitive to Python programmers rather than try to mirror JavaScript APIs.
  • We regard all extensions as trusted, which is wildly different from WebExtensions (where extensions are untrusted and very limited).
  • Extensions have Python's and Qt's standard library available, so there's probably things extensions can just take from there.
  • We have a lot of concepts in qutebrowser which should be in the extension API, but don't exist that way in WebExtension APIs, and vice versa. For starters, the whole concept of commands and keybindings.

Here's roughly how I'd like to go about this issue:

  • Get extension infrastructure itself to work, at first only with qutebrowser-internal "extensions" but no public interface.
  • Expose the bare minimum of qutebrowser which is feasibly well-designed and stable. Currently, this is probably (part of) the tab API and cmdutils.
  • Move everything possible in qutebrowser's code base to use the newly exposed extension API (I'd probably call this "components" or so, and move all code only using the stable extension API to a new directory in the source tree). This is probably a good time to take care of #3319 as well.
  • Check the remaining code in qutebrowser's core, and decide what should be moved out from the core into a component. Generally, everything which can be mapped to a general-purpose stable API (say, the whole adblocking stuff) should probably move to a component, everything which can't (say, the concept of tabs) should stay in the core.
  • Gradually add more stuff to the extension API, and move stuff out of the core into "components".

Then at some point, we should already have a nice API, with real usage (qutebrowser itself, basically). Together with the use cases in the original post of this issue, this should form the extension API. As soon as it feels stable enough, it should be officially exposed as an extension API, and then gradually get more power based on what plugins people want to write (and what's reasonable).

What I'd like to avoid is the situation Firefox had with its XUL/XPCOM API - having a very powerful plugin API at the expense of painting ourselves into a corner with what changes we can make to qutebrowser's codebase.

Collaborator

The-Compiler commented Nov 21, 2017

Getting back to what @lamarpavel and @Elronnd mentioned earlier:

I think it's a good idea to take a look at e.g. the WebExtension API to get some inspiration, but at the same time, there are good reasons for our API to diverge from that:

  • It's Python, and not JavaScript. We should create an API which seems right/clean/simple/intuitive to Python programmers rather than try to mirror JavaScript APIs.
  • We regard all extensions as trusted, which is wildly different from WebExtensions (where extensions are untrusted and very limited).
  • Extensions have Python's and Qt's standard library available, so there's probably things extensions can just take from there.
  • We have a lot of concepts in qutebrowser which should be in the extension API, but don't exist that way in WebExtension APIs, and vice versa. For starters, the whole concept of commands and keybindings.

Here's roughly how I'd like to go about this issue:

  • Get extension infrastructure itself to work, at first only with qutebrowser-internal "extensions" but no public interface.
  • Expose the bare minimum of qutebrowser which is feasibly well-designed and stable. Currently, this is probably (part of) the tab API and cmdutils.
  • Move everything possible in qutebrowser's code base to use the newly exposed extension API (I'd probably call this "components" or so, and move all code only using the stable extension API to a new directory in the source tree). This is probably a good time to take care of #3319 as well.
  • Check the remaining code in qutebrowser's core, and decide what should be moved out from the core into a component. Generally, everything which can be mapped to a general-purpose stable API (say, the whole adblocking stuff) should probably move to a component, everything which can't (say, the concept of tabs) should stay in the core.
  • Gradually add more stuff to the extension API, and move stuff out of the core into "components".

Then at some point, we should already have a nice API, with real usage (qutebrowser itself, basically). Together with the use cases in the original post of this issue, this should form the extension API. As soon as it feels stable enough, it should be officially exposed as an extension API, and then gradually get more power based on what plugins people want to write (and what's reasonable).

What I'd like to avoid is the situation Firefox had with its XUL/XPCOM API - having a very powerful plugin API at the expense of painting ourselves into a corner with what changes we can make to qutebrowser's codebase.

This comment has been minimized.

Show comment Hide comment
@NoctuaNivalis

NoctuaNivalis Nov 21, 2017

Contributor

I like the roadmap.

What I'd like to avoid is the situation Firefox had with its XUL/XPCOM API - having a very powerful plugin API at the expense of painting ourselves into a corner with what changes we can make to qutebrowser's codebase.

Main difference: qutebrowser users would understand the need to update their installed/written plugins to a newer API, so we don't need really strict backwards compatability. It's usually OK to break things a bit.

Contributor

NoctuaNivalis commented Nov 21, 2017

I like the roadmap.

What I'd like to avoid is the situation Firefox had with its XUL/XPCOM API - having a very powerful plugin API at the expense of painting ourselves into a corner with what changes we can make to qutebrowser's codebase.

Main difference: qutebrowser users would understand the need to update their installed/written plugins to a newer API, so we don't need really strict backwards compatability. It's usually OK to break things a bit.

This comment has been minimized.

Show comment Hide comment
@lamarpavel

lamarpavel Nov 21, 2017

Contributor

I very much like the roadmap you fleshed out, moving stuff out of qutebrowser and into extensions as soon as the core extension API is built is a win/win/win. First, we get to test the API with real use cases, secondly the API will serve as a separation layer to restrict code entanglement (or what OO people sometimes call cross cutting concerns) and thirdly, we get an extension API (duh).

For inspiration I can recommend looking at the IRC client weechat, which has internalised this concept to the point that even the IRC related code is a module (that can even be turned off).

And one more thing: I've been somewhat invested in the Firefox 57 debacle and was forced out of my comfort zone due to all of my plugins no longer working (except for httpseverywhere) and then getting stuck with ABI incompatibility of my outdated Firefox 55 and the current icu package from repos (and then the entire dependency hell following that). So I looked a bit around and read through some discussions about the WebExtensions API. Here are some very relevant points of reference that we can learn from:

Contributor

lamarpavel commented Nov 21, 2017

I very much like the roadmap you fleshed out, moving stuff out of qutebrowser and into extensions as soon as the core extension API is built is a win/win/win. First, we get to test the API with real use cases, secondly the API will serve as a separation layer to restrict code entanglement (or what OO people sometimes call cross cutting concerns) and thirdly, we get an extension API (duh).

For inspiration I can recommend looking at the IRC client weechat, which has internalised this concept to the point that even the IRC related code is a module (that can even be turned off).

And one more thing: I've been somewhat invested in the Firefox 57 debacle and was forced out of my comfort zone due to all of my plugins no longer working (except for httpseverywhere) and then getting stuck with ABI incompatibility of my outdated Firefox 55 and the current icu package from repos (and then the entire dependency hell following that). So I looked a bit around and read through some discussions about the WebExtensions API. Here are some very relevant points of reference that we can learn from:

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Nov 21, 2017

Collaborator

For inspiration I can recommend looking at the IRC client weechat, which has internalised this concept to the point that even the IRC related code is a module (that can even be turned off).

I planned to take a look at weechat indeed. My main inspirations so far were:

I just think it's important to not make too much pluggable outright. With pytest, pretty much everything is a plugin hook, and plugins can expose their own plugin hooks - but that also gets complicated fast, and makes it harder to refactor stuff.


As for the discussions about Vimperator, I've been a part of them since pretty much the beginning 😉 It's also my main source to keep the lists of alternatives up to date.

Collaborator

The-Compiler commented Nov 21, 2017

For inspiration I can recommend looking at the IRC client weechat, which has internalised this concept to the point that even the IRC related code is a module (that can even be turned off).

I planned to take a look at weechat indeed. My main inspirations so far were:

I just think it's important to not make too much pluggable outright. With pytest, pretty much everything is a plugin hook, and plugins can expose their own plugin hooks - but that also gets complicated fast, and makes it harder to refactor stuff.


As for the discussions about Vimperator, I've been a part of them since pretty much the beginning 😉 It's also my main source to keep the lists of alternatives up to date.

This comment has been minimized.

Show comment Hide comment
@lamarpavel

lamarpavel Nov 22, 2017

Contributor

Oh and one other quick idea I had: A plugin could be added that exposes an RPC interface through something language agnostic and simply translates that to the extension API in Python. So you would expose the API to any kind of external program without having to change something in the API.

Contributor

lamarpavel commented Nov 22, 2017

Oh and one other quick idea I had: A plugin could be added that exposes an RPC interface through something language agnostic and simply translates that to the extension API in Python. So you would expose the API to any kind of external program without having to change something in the API.

This comment has been minimized.

Show comment Hide comment
@robehickman

robehickman Nov 30, 2017

Why not implement webextensions to gain access to proprietary addons like last pass? Lack of support for that rules out using any of these alternative browser projects for me.

Why not implement webextensions to gain access to proprietary addons like last pass? Lack of support for that rules out using any of these alternative browser projects for me.

This comment has been minimized.

Show comment Hide comment
@traverseda

traverseda Nov 30, 2017

Webextentions is pretty new, and wasn't an option when work on this feature started. It's probably worth opening a new issue just to discuss them.

Webextentions is pretty new, and wasn't an option when work on this feature started. It's probably worth opening a new issue just to discuss them.

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Nov 30, 2017

Collaborator

Please read the thread, or at least search for webextension in this thread 😉

Collaborator

The-Compiler commented Nov 30, 2017

Please read the thread, or at least search for webextension in this thread 😉

This comment has been minimized.

Show comment Hide comment
@traverseda

traverseda Nov 30, 2017

It might be worth opening a ticket just for web-extention support. Since python-ey plugins and webextentions are very different things with very different implementation paths.

traverseda commented Nov 30, 2017

It might be worth opening a ticket just for web-extention support. Since python-ey plugins and webextentions are very different things with very different implementation paths.

This comment has been minimized.

Show comment Hide comment
@Elronnd

Elronnd Dec 1, 2017

Guys. Webextensions aren't happening. Give it a rest.

Elronnd commented Dec 1, 2017

Guys. Webextensions aren't happening. Give it a rest.

This comment has been minimized.

Show comment Hide comment
@traverseda

traverseda Dec 1, 2017

You know what would solve people coming into this thread to talk about webextentions? Opening a ticket with the words "[feature request] implement webextentions" and a prominent comment saying "this is a long way off in the future".

Alternatively, change this tickets title to 'python-based plugin support'. People are going to talk about webextentions, and right now this is the designated place to do that. Designate another place, or make it obvious that this is the designated place to talk about python plugin support. People are going to talk about the most prominent plugin api in the thread about implementing a plugin api, it's going to keep happening. You can control where it happens though.

Do you know what happens when you search the issues for the string Webextensions? Take a guess.

I'd open such a ticket myself but someone just closed a similar ticket at #3186.

traverseda commented Dec 1, 2017

You know what would solve people coming into this thread to talk about webextentions? Opening a ticket with the words "[feature request] implement webextentions" and a prominent comment saying "this is a long way off in the future".

Alternatively, change this tickets title to 'python-based plugin support'. People are going to talk about webextentions, and right now this is the designated place to do that. Designate another place, or make it obvious that this is the designated place to talk about python plugin support. People are going to talk about the most prominent plugin api in the thread about implementing a plugin api, it's going to keep happening. You can control where it happens though.

Do you know what happens when you search the issues for the string Webextensions? Take a guess.

I'd open such a ticket myself but someone just closed a similar ticket at #3186.

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Dec 4, 2017

Collaborator

That someone would be me 😉

Feel free to discuss about WebExtensions here, if there's anything new to say. But "WebExtension support would be cool" has been said before, and doesn't change anything about it being far away and maybe not possible at all.

With ~500 open tickets, it makes no sense to have tickets around which aren't actionable at all, which is why there's no dedicated WebExtension ticket, but it fits well in here.

I added a section about WebExtensions to the first post, though.

Collaborator

The-Compiler commented Dec 4, 2017

That someone would be me 😉

Feel free to discuss about WebExtensions here, if there's anything new to say. But "WebExtension support would be cool" has been said before, and doesn't change anything about it being far away and maybe not possible at all.

With ~500 open tickets, it makes no sense to have tickets around which aren't actionable at all, which is why there's no dedicated WebExtension ticket, but it fits well in here.

I added a section about WebExtensions to the first post, though.

@The-Compiler The-Compiler referenced this issue in parkouss/webmacs Dec 14, 2017

Closed

Relation to qutebrowser #3

This comment has been minimized.

Show comment Hide comment
@oblitum

oblitum Dec 16, 2017

Just fyi, lastpass does have a terminal client, lpass, which is quite good. I still use Firefox, and use lastpass both as a Firefox addon as well as lpass in the terminal. It's the sole thing holding me back to switch to qutebrowser, if it in the future manages to use the terminal client, it will be even better than duplicate lastpass functionality via browser extension.

oblitum commented Dec 16, 2017

Just fyi, lastpass does have a terminal client, lpass, which is quite good. I still use Firefox, and use lastpass both as a Firefox addon as well as lpass in the terminal. It's the sole thing holding me back to switch to qutebrowser, if it in the future manages to use the terminal client, it will be even better than duplicate lastpass functionality via browser extension.

This comment has been minimized.

Show comment Hide comment
@pkillnine

pkillnine Dec 16, 2017

@oblitum I think support for lpass could easily be added to userscript password_fill or qute-pass.

@oblitum I think support for lpass could easily be added to userscript password_fill or qute-pass.

@The-Compiler The-Compiler referenced this issue Dec 17, 2017

Closed

surfraw #3410

This comment has been minimized.

Show comment Hide comment
@biinari

biinari Dec 18, 2017

@oblitum I've made a backend to password_fill for lpass: https://gist.github.com/biinari/e5611220f90258552cd85032c9c09021 - it could be improved upon but works reasonably well for starters.

biinari commented Dec 18, 2017

@oblitum I've made a backend to password_fill for lpass: https://gist.github.com/biinari/e5611220f90258552cd85032c9c09021 - it could be improved upon but works reasonably well for starters.

This comment has been minimized.

Show comment Hide comment
@oblitum

oblitum Dec 18, 2017

@biinari cool thanks for that.

oblitum commented Dec 18, 2017

@biinari cool thanks for that.

@The-Compiler The-Compiler added this to Backlog in HSR SA Mar 21, 2018

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Mar 22, 2018

Collaborator

Some more notes on my opinion on plugin security

Sandboxing Python in some safe way is widely regarded as impossible - instead, I think it's fine for qutebrowser to trust plugins.

Manually installed

If people dump stuff in their ~/.local/share/qutebrowser/plugins or whatever it'll be, it's their responsibility to ensure it's safe.

Plugin manager

For plugins installed via some kind of plugin manager (or something like a :plugin-install), there could be a plugin registry somewhere - for example in some JSON/YAML file in the repository, which gets downloaded by qutebrowser with a :plugin-update or so. That file could contain entries like:

exampleplugin:
  repo: https://github.com/example/qutebrowser-exampleplugin
  version: 1.0
  commit: 11a94957dc038fc27c5ff976197ad2b2d0352d20

Then when people write a new plugin or release a new version of an existing one, this happens:

  • They push their plugin to a GitHub repository
  • They open a PR against qutebrowser to update the plugin index
  • A qutebrowser maintainer does a quick review of the plugin code to make sure it doesn't do anything clearly stupid or malicious and merges the PR
  • qutebrowser uses that file to offer plugins to install, and when downloading a plugin, makes sure the commit (or possibly some hash on a GitHub .zip file, depending on implementation) matches.

That means there's at least some review of what plugins want to do (but people can still install plugins manually). It still should be documented that qutebrowser isn't responsible for whatever happens in plugins.

External libraries

It gets trickier when plugins require external (Python/C) libraries. Not even sure if qutebrowser's plugin manager will be able to install them. If not, it gets tricky for people using the macOS/Windows builds to install plugins, though...

Feedback welcome! 😄

Collaborator

The-Compiler commented Mar 22, 2018

Some more notes on my opinion on plugin security

Sandboxing Python in some safe way is widely regarded as impossible - instead, I think it's fine for qutebrowser to trust plugins.

Manually installed

If people dump stuff in their ~/.local/share/qutebrowser/plugins or whatever it'll be, it's their responsibility to ensure it's safe.

Plugin manager

For plugins installed via some kind of plugin manager (or something like a :plugin-install), there could be a plugin registry somewhere - for example in some JSON/YAML file in the repository, which gets downloaded by qutebrowser with a :plugin-update or so. That file could contain entries like:

exampleplugin:
  repo: https://github.com/example/qutebrowser-exampleplugin
  version: 1.0
  commit: 11a94957dc038fc27c5ff976197ad2b2d0352d20

Then when people write a new plugin or release a new version of an existing one, this happens:

  • They push their plugin to a GitHub repository
  • They open a PR against qutebrowser to update the plugin index
  • A qutebrowser maintainer does a quick review of the plugin code to make sure it doesn't do anything clearly stupid or malicious and merges the PR
  • qutebrowser uses that file to offer plugins to install, and when downloading a plugin, makes sure the commit (or possibly some hash on a GitHub .zip file, depending on implementation) matches.

That means there's at least some review of what plugins want to do (but people can still install plugins manually). It still should be documented that qutebrowser isn't responsible for whatever happens in plugins.

External libraries

It gets trickier when plugins require external (Python/C) libraries. Not even sure if qutebrowser's plugin manager will be able to install them. If not, it gets tricky for people using the macOS/Windows builds to install plugins, though...

Feedback welcome! 😄

This comment has been minimized.

Show comment Hide comment
@gebulmer

gebulmer Mar 22, 2018

Contributor

I don't know if it's even worth making a built-in plugin manager, just having a standard directory to dump them is enough. A plugin manager would then be simply another plugin, registering its commands in the usual (provided) way, that handles the others.

Contributor

gebulmer commented Mar 22, 2018

I don't know if it's even worth making a built-in plugin manager, just having a standard directory to dump them is enough. A plugin manager would then be simply another plugin, registering its commands in the usual (provided) way, that handles the others.

This comment has been minimized.

Show comment Hide comment
@pkillnine

pkillnine Mar 22, 2018

I do like the idea of an official qutebrowser plugin repo that is maintained, since plugins are going to be assumed to be fully trusted. Maybe a simple compromise could be to ship qutebrowser with an official plugin manager, which is simply another plugin (like @gebulmer said), with the official qutebrowser plugin repo? This way if someone wants to use a different plugin manager they can easily remove the default one.

I do like the idea of an official qutebrowser plugin repo that is maintained, since plugins are going to be assumed to be fully trusted. Maybe a simple compromise could be to ship qutebrowser with an official plugin manager, which is simply another plugin (like @gebulmer said), with the official qutebrowser plugin repo? This way if someone wants to use a different plugin manager they can easily remove the default one.

This comment has been minimized.

Show comment Hide comment
@traverseda

traverseda Mar 22, 2018

It seems to me like the obvious plugin manager is... pip. It does everything you'd need. I don't know how easy it would be to have a per-user/per-profile virtualenv, but that would certainly make things easier.

It seems to me like the obvious plugin manager is... pip. It does everything you'd need. I don't know how easy it would be to have a per-user/per-profile virtualenv, but that would certainly make things easier.

This comment has been minimized.

Show comment Hide comment
@The-Compiler

The-Compiler Mar 22, 2018

Collaborator

Yeah, I've had that in the back of my mind for a while as well. I'm not sure how well it'd work with locally installed plugins and with frozen distributions (macOS/Windows), but it's certainly worth some more thought.

Collaborator

The-Compiler commented Mar 22, 2018

Yeah, I've had that in the back of my mind for a while as well. I'm not sure how well it'd work with locally installed plugins and with frozen distributions (macOS/Windows), but it's certainly worth some more thought.

This comment has been minimized.

Show comment Hide comment
@lamarpavel

lamarpavel Mar 23, 2018

Contributor

That would mean pip becomes a qb dependency for regular users?
Also, I don't see how pip makes any guarantees about which plugins were curated by qutebrowser developers.

Contributor

lamarpavel commented Mar 23, 2018

That would mean pip becomes a qb dependency for regular users?
Also, I don't see how pip makes any guarantees about which plugins were curated by qutebrowser developers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment