simple_notify.py 5.4 KB
Newer Older
mathieui's avatar
mathieui committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
"""
This plugin lets you execute a command, to notify you from new important
messages.

Installation and configuration
------------------------------

You need to create a plugin configuration file. Create a file named :file:`simple_notify.cfg`
into your plugins configuration directory (:file:`~/.config/poezio/plugins` by
default), and fill it like this:

First example:

.. code-block:: ini

    [simple_notify]
    command = notify-send -i /path/to/poezio/data/poezio_80.png "New message from %(from)s" "%(body)s"

Second example:

.. code-block:: ini

    [simple_notify]
24
    command = echo \\<%(from)s\\> %(body)s >> some.fifo
mathieui's avatar
mathieui committed
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
    delay = 3
    after_command = echo >> some.fifo

You can put any command, instead of these ones. You can also use the
special keywords ``%(from)s`` and ``%(body)s`` that will be replaced
directly in the command line by the author of the message, and the body.

The first example shown above will display something like this:

.. figure:: ../images/simple_notify_example.png
    :alt: Simple notify example

The second example will first write the author and the message in a
fifo, that fifo can locally be read by some other program (was tested
with the xmobar PipeReader command, which displays what is read from a
fifo into a status bar. Be careful, you have two different fifos in
that case, don’t get confused). The :term:`delay` and :term:`after_command` options
are used to erase/delete/kill the notification after a certain
delay.  In our example it is used to display an empty message in our
xmobar, erasing the notification after 3 seconds.

46 47 48 49 50 51 52
Third example:

.. code-block:: ini

    [simple_notify]
    command = notify-send -i /path/to/poezio/data/poezio_80.png "New message from %(from)s" "%(body)s"
    muc_too = true
53
    muc_list = someroom@conference.jabber.org:someotherroom@conference.jabber.org
54 55 56 57

If present and set to ``True``, the ``muc_too`` option will also trigger a
notification when a new message arrives on a Multi User Chat you've joined.

58
If present and set to a colon separated list of muc JIDs, muc_list together 
59 60 61
with muc_too = true will only notify when a new message arrives on a Multi 
User Chat, you've joined if it is present on the list.

mathieui's avatar
mathieui committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
.. note:: If you set the :term:`exec_remote` option to ``true`` into the
    main configuration file, the command will be executed remotely
    (as explained in the :ref:`link-plugin` plugin help).

Options defined
---------------

.. glossary::
    :sorted:

    command
        The command to execute (with special keywords ``%{from}s`` and ``${body}s``)

    delay
        Delay after which :term:`after_command` must be executed.

    after_command
        Command to run after :term:`delay`. You probably want to clean up things.

81 82 83 84
    muc_too
        Boolean indicating whether new messages in Multi User Chat rooms should
        trigger a notification or not.

mathieui's avatar
mathieui committed
85 86
"""

87 88 89
from poezio.plugin import BasePlugin
from poezio.xhtml import get_body_from_message_stanza
from poezio.timed_events import DelayedEvent
louiz’'s avatar
louiz’ committed
90
import shlex
91
from poezio import common
92

louiz’'s avatar
louiz’ committed
93 94 95

class Plugin(BasePlugin):
    def init(self):
96 97
        self.api.add_event_handler('private_msg', self.on_private_msg)
        self.api.add_event_handler('conversation_msg', self.on_conversation_msg)
98 99
        if self.config.get('muc_too', False):
            self.api.add_event_handler('muc_msg', self.on_muc_msg)
100
        self.api.add_event_handler('highlight', self.on_highlight)
louiz’'s avatar
louiz’ committed
101 102 103 104 105

    def on_private_msg(self, message, tab):
        fro = message['from']
        self.do_notify(message, fro)

106
    def on_highlight(self, message, tab):
107 108 109 110
        whitelist = self.config.get('muc_list', '').split(':')
        # prevents double notifications
        if message['from'].bare in whitelist:
            return
111 112 113
        fro = message['from'].resource
        self.do_notify(message, fro)

louiz’'s avatar
louiz’ committed
114 115 116 117
    def on_conversation_msg(self, message, tab):
        fro = message['from'].bare
        self.do_notify(message, fro)

118
    def on_muc_msg(self, message, tab):
119 120 121 122
        # Dont notify if message is from yourself
        if message['from'].resource == tab.own_nick:
            return

123 124
        fro = message['from'].full
        muc = message['from'].bare
125
        whitelist = self.config.get('muc_list', '').split(':')
126

127 128 129 130
        # Prevent old messages to be notified
        # find_delayed_tag(message) returns (True, the datetime) or
        # (False, None)
        if not common.find_delayed_tag(message)[0]:
131 132 133
            # Only notify if whitelist is empty or muc in whitelist
            if whitelist == [''] or muc in whitelist:
                self.do_notify(message, fro)
134

louiz’'s avatar
louiz’ committed
135
    def do_notify(self, message, fro):
136
        body = get_body_from_message_stanza(message, use_xhtml=False)
louiz’'s avatar
louiz’ committed
137 138
        if not body:
            return
louiz’'s avatar
louiz’ committed
139 140
        command_str = self.config.get('command', '').strip()
        if not command_str:
141
            self.api.information('No notification command was provided in the configuration file', 'Warning')
louiz’'s avatar
louiz’ committed
142
            return
louiz’'s avatar
louiz’ committed
143 144 145 146
        command = [arg % {'body': body.replace('\n', ' '), 'from': fro} for arg in shlex.split(command_str)]
        self.core.exec_command(command)
        after_command_str = self.config.get('after_command', '').strip()
        if not after_command_str:
147
            return
louiz’'s avatar
louiz’ committed
148 149
        after_command = [arg % {'body': body.replace('\n', ' '), 'from': fro} for arg in shlex.split(after_command_str)]
        delayed_event = DelayedEvent(self.config.get('delay', 1), self.core.exec_command, after_command)
150
        self.api.add_timed_event(delayed_event)