ba32d74a61
fix #2550
144 lines
4.4 KiB
Python
144 lines
4.4 KiB
Python
"""
|
||
Opens links in a browser.
|
||
|
||
Installation
|
||
------------
|
||
|
||
First use case: local use
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
If you use poezio on your workstation, this is for you.
|
||
You only have to load the plugin: ::
|
||
|
||
/load link
|
||
|
||
Second use case: remote use
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
If you use poezio through SSH, this is for you.
|
||
|
||
.. note:: Small explanation: Poezio will create a `Unix FIFO`_ and send the commands in,
|
||
and you will have to run a dæmon locally with ssh, to get those commands.
|
||
|
||
First, set the :term:`exec_remote` option in the config file to ``true``. Then select
|
||
the directory you want to put the fifo in (default is the current
|
||
directory, :file:`./`), the :file:`poezio.fifo` file will be created there.
|
||
|
||
After that, load the plugin: ::
|
||
|
||
/load link
|
||
|
||
And open a link with :term:`/link` (as described below), this will create the FIFO.
|
||
|
||
You need to grab poezio’s sources on your client computer, or at least the `daemon.py`_
|
||
file.
|
||
|
||
Finally, on your client computer, run the ssh command:
|
||
|
||
.. code-block:: bash
|
||
|
||
ssh toto@example.org "cat ~/poezio/poezio.fifo" | python3 daemon.py
|
||
|
||
Usage
|
||
-----
|
||
|
||
.. glossary::
|
||
|
||
/link
|
||
**Usage:** ``/link [range]``
|
||
|
||
This plugin adds a :term:`/link` command that will open the links in ``firefox``. If
|
||
you want to use another browser, you can use the :term:`/set` command to change the
|
||
:term:`browser` option.
|
||
|
||
|
||
:term:`/link` without argument will open the last link found
|
||
in the current tab, if any is found. An optional range
|
||
argument can be given, to select one or more links to
|
||
open. Examples:
|
||
``/link 1`` is equivalent to ``/link``
|
||
``/link 3`` will open the third link found in the current tab,
|
||
starting from the bottom.
|
||
``/link 1:5`` will open the last five links in the current tab
|
||
``/link :2`` will open the last two links
|
||
|
||
Options
|
||
-------
|
||
|
||
:term:`exec_remote`
|
||
|
||
To execute the command on your client
|
||
|
||
.. glossary::
|
||
|
||
browser
|
||
Set the default browser started by the plugin
|
||
|
||
.. _Unix FIFO: https://en.wikipedia.org/wiki/Named_pipe
|
||
.. _daemon.py: http://dev.louiz.org/projects/poezio/repository/revisions/master/raw/src/daemon.py
|
||
|
||
"""
|
||
import platform
|
||
import re
|
||
|
||
from plugin import BasePlugin
|
||
from xhtml import clean_text
|
||
import common
|
||
import tabs
|
||
|
||
url_pattern = re.compile(r'\b(http[s]?://(?:\S+))\b', re.I|re.U)
|
||
app_mapping = {
|
||
'Linux': 'xdg-open',
|
||
'Darwin': 'open',
|
||
}
|
||
|
||
class Plugin(BasePlugin):
|
||
def init(self):
|
||
for _class in (tabs.MucTab, tabs.PrivateTab, tabs.ConversationTab):
|
||
self.api.add_tab_command(_class, 'link', self.command_link,
|
||
usage='[num]',
|
||
help='Opens the last link from the conversation into a browser.\nIf [num] is given, then it will open the num-th link displayed.',
|
||
short='Open links into a browser')
|
||
|
||
def find_link(self, nb):
|
||
messages = self.api.get_conversation_messages()
|
||
if not messages:
|
||
return None
|
||
for message in messages[::-1]:
|
||
matches = url_pattern.findall(clean_text(message.txt))
|
||
if matches:
|
||
for url in matches[::-1]:
|
||
if nb == 1:
|
||
return url
|
||
else:
|
||
nb -= 1
|
||
return None
|
||
|
||
def command_link(self, args):
|
||
args = common.shell_split(args)
|
||
if len(args) == 1:
|
||
if args[0].find(':') == -1:
|
||
try:
|
||
start = int(args[0])
|
||
end = start
|
||
except ValueError:
|
||
return self.api.run_command('/help link')
|
||
else:
|
||
start, end = args[0].split(':', 1)
|
||
if start == '':
|
||
start = 1
|
||
try:
|
||
start = int(start)
|
||
end = int(end)
|
||
except ValueError:
|
||
return self.api.information('Invalid range: %s' % (args[0]), 'Error')
|
||
else:
|
||
start = 1
|
||
end = 1
|
||
for nb in range(start, end+1):
|
||
link = self.find_link(nb)
|
||
if not link:
|
||
return self.api.information('No URL found.', 'Warning')
|
||
default = app_mapping.get(platform.system(), 'firefox')
|
||
self.core.exec_command([self.config.get('browser', default), link])
|
||
|
||
def cleanup(self):
|
||
del self.config
|