summaryrefslogtreecommitdiff
path: root/.weechat/python/notify_send.py
diff options
context:
space:
mode:
authorVito Graffagnino <vito@graffagnino.xyz>2020-09-08 18:10:49 +0100
committerVito Graffagnino <vito@graffagnino.xyz>2020-09-08 18:10:49 +0100
commit3b0142cedcde39e4c2097ecd916a870a3ced5ec6 (patch)
tree2116c49a845dfc0945778f2aa3e2118d72be428b /.weechat/python/notify_send.py
parent8cc927e930d5b6aafe3e9862a61e81705479a1b4 (diff)
Added the relevent parts of the .config directory. Alss add ssh config
Diffstat (limited to '.weechat/python/notify_send.py')
-rw-r--r--.weechat/python/notify_send.py755
1 files changed, 755 insertions, 0 deletions
diff --git a/.weechat/python/notify_send.py b/.weechat/python/notify_send.py
new file mode 100644
index 0000000..30b6c48
--- /dev/null
+++ b/.weechat/python/notify_send.py
@@ -0,0 +1,755 @@
+# -*- coding: utf-8 -*-
+#
+# Project: weechat-notify-send
+# Homepage: https://github.com/s3rvac/weechat-notify-send
+# Description: Sends highlight and message notifications through notify-send.
+# Requires libnotify.
+# License: MIT (see below)
+#
+# Copyright (c) 2015 by Petr Zemek <s3rvac@gmail.com> and contributors
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+from __future__ import print_function
+
+import os
+import re
+import subprocess
+import sys
+import time
+
+
+# Ensure that we are running under WeeChat.
+try:
+ import weechat
+except ImportError:
+ sys.exit('This script has to run under WeeChat (https://weechat.org/).')
+
+
+# Name of the script.
+SCRIPT_NAME = 'notify_send'
+
+# Author of the script.
+SCRIPT_AUTHOR = 's3rvac'
+
+# Version of the script.
+SCRIPT_VERSION = '0.9 (dev)'
+
+# License under which the script is distributed.
+SCRIPT_LICENSE = 'MIT'
+
+# Description of the script.
+SCRIPT_DESC = 'Sends highlight and message notifications through notify-send.'
+
+# Name of a function to be called when the script is unloaded.
+SCRIPT_SHUTDOWN_FUNC = ''
+
+# Used character set (utf-8 by default).
+SCRIPT_CHARSET = ''
+
+# Script options.
+OPTIONS = {
+ 'notify_on_highlights': (
+ 'on',
+ 'Send notifications on highlights.'
+ ),
+ 'notify_on_privmsgs': (
+ 'on',
+ 'Send notifications on private messages.'
+ ),
+ 'notify_on_filtered_messages': (
+ 'off',
+ 'Send notifications also on filtered (hidden) messages.'
+ ),
+ 'notify_when_away': (
+ 'on',
+ 'Send also notifications when away.'
+ ),
+ 'notify_for_current_buffer': (
+ 'on',
+ 'Send also notifications for the currently active buffer.'
+ ),
+ 'notify_on_all_messages_in_buffers': (
+ '',
+ 'A comma-separated list of buffers for which you want to receive '
+ 'notifications on all messages that appear in them.'
+ ),
+ 'notify_on_all_messages_in_buffers_that_match': (
+ '',
+ 'A comma-separated list of regex patterns of buffers for which you '
+ 'want to receive notifications on all messages that appear in them.'
+ ),
+ 'notify_on_messages_that_match': (
+ '',
+ 'A comma-separated list of regex patterns that you want to receive '
+ 'notifications on when message matches.'
+ ),
+ 'min_notification_delay': (
+ '500',
+ 'A minimal delay between successive notifications from the same '
+ 'buffer (in milliseconds; set to 0 to show all notifications).'
+ ),
+ 'ignore_messages_tagged_with': (
+ ','.join([
+ 'notify_none', # Buffer with line is not added to hotlist
+ 'irc_join', # Joined IRC
+ 'irc_quit', # Quit IRC
+ 'irc_part', # Parted a channel
+ 'irc_status', # Status messages
+ 'irc_nick_back', # A nick is back on server
+ 'irc_401', # No such nick/channel
+ 'irc_402', # No such server
+ ]),
+ 'A comma-separated list of message tags for which no notifications '
+ 'should be shown.'
+ ),
+ 'ignore_buffers': (
+ '',
+ 'A comma-separated list of buffers from which no notifications should '
+ 'be shown.'
+ ),
+ 'ignore_buffers_starting_with': (
+ '',
+ 'A comma-separated list of buffer prefixes from which no '
+ 'notifications should be shown.'
+ ),
+ 'ignore_nicks': (
+ '',
+ 'A comma-separated list of nicks from which no notifications should '
+ 'be shown.'
+ ),
+ 'ignore_nicks_starting_with': (
+ '',
+ 'A comma-separated list of nick prefixes from which no '
+ 'notifications should be shown.'
+ ),
+ 'hide_messages_in_buffers_that_match': (
+ '',
+ 'A comma-separated list of regex patterns for names of buffers from '
+ 'which you want to receive notifications without messages.'
+ ),
+ 'nick_separator': (
+ ': ',
+ 'A separator between a nick and a message.'
+ ),
+ 'escape_html': (
+ 'on',
+ "Escapes the '<', '>', and '&' characters in notification messages."
+ ),
+ 'max_length': (
+ '72',
+ 'Maximal length of a notification (0 means no limit).'
+ ),
+ 'ellipsis': (
+ '[..]',
+ 'Ellipsis to be used for notifications that are too long.'
+ ),
+ 'icon': (
+ '/usr/share/icons/hicolor/32x32/apps/weechat.png',
+ 'Path to an icon to be shown in notifications.'
+ ),
+ 'desktop_entry': (
+ 'weechat',
+ 'Name of the desktop entry for WeeChat.'
+ ),
+ 'timeout': (
+ '5000',
+ 'Time after which the notification disappears (in milliseconds; '
+ 'set to 0 to disable).'
+ ),
+ 'transient': (
+ 'on',
+ 'When a notification expires or is dismissed, remove it from the '
+ 'notification bar.'
+ ),
+ 'urgency': (
+ 'normal',
+ 'Urgency (low, normal, critical).'
+ )
+}
+
+
+class Notification(object):
+ """A representation of a notification."""
+
+ def __init__(self, source, message, icon, desktop_entry, timeout, transient, urgency):
+ self.source = source
+ self.message = message
+ self.icon = icon
+ self.desktop_entry = desktop_entry
+ self.timeout = timeout
+ self.transient = transient
+ self.urgency = urgency
+
+
+def default_value_of(option):
+ """Returns the default value of the given option."""
+ return OPTIONS[option][0]
+
+
+def add_default_value_to(description, default_value):
+ """Adds the given default value to the given option description."""
+ # All descriptions end with a period, so do not add another period.
+ return '{} Default: {}.'.format(
+ description,
+ default_value if default_value else '""'
+ )
+
+
+def nick_that_sent_message(tags, prefix):
+ """Returns a nick that sent the message based on the given data passed to
+ the callback.
+ """
+ # 'tags' is a comma-separated list of tags that WeeChat passed to the
+ # callback. It should contain a tag of the following form: nick_XYZ, where
+ # XYZ is the nick that sent the message.
+ for tag in tags:
+ if tag.startswith('nick_'):
+ return tag[5:]
+
+ # There is no nick in the tags, so check the prefix as a fallback.
+ # 'prefix' (str) is the prefix of the printed line with the message.
+ # Usually (but not always), it is a nick with an optional mode (e.g. on
+ # IRC, @ denotes an operator and + denotes a user with voice). We have to
+ # remove the mode (if any) before returning the nick.
+ # Strip also a space as some protocols (e.g. Matrix) may start prefixes
+ # with a space. It probably means that the nick has no mode set.
+ if prefix.startswith(('~', '&', '@', '%', '+', '-', ' ')):
+ return prefix[1:]
+
+ return prefix
+
+
+def parse_tags(tags):
+ """Parses the given "list" of tags (str) from WeeChat into a list."""
+ return tags.split(',')
+
+
+def message_printed_callback(data, buffer, date, tags, is_displayed,
+ is_highlight, prefix, message):
+ """A callback when a message is printed."""
+ is_displayed = int(is_displayed)
+ is_highlight = int(is_highlight)
+ tags = parse_tags(tags)
+ nick = nick_that_sent_message(tags, prefix)
+
+ if notification_should_be_sent(buffer, tags, nick, is_displayed, is_highlight, message):
+ notification = prepare_notification(buffer, nick, message)
+ send_notification(notification)
+
+ return weechat.WEECHAT_RC_OK
+
+
+def notification_should_be_sent(buffer, tags, nick, is_displayed, is_highlight, message):
+ """Should a notification be sent?"""
+ if notification_should_be_sent_disregarding_time(buffer, tags, nick,
+ is_displayed, is_highlight, message):
+ # The following function should be called only when the notification
+ # should be sent (it updates the last notification time).
+ if not is_below_min_notification_delay(buffer):
+ return True
+ return False
+
+
+def notification_should_be_sent_disregarding_time(buffer, tags, nick,
+ is_displayed, is_highlight, message):
+ """Should a notification be sent when not considering time?"""
+ if not nick:
+ # A nick is required to form a correct notification source/message.
+ return False
+
+ if i_am_author_of_message(buffer, nick):
+ return False
+
+ if not is_displayed:
+ if not notify_on_filtered_messages():
+ return False
+
+ if buffer == weechat.current_buffer():
+ if not notify_for_current_buffer():
+ return False
+
+ if is_away(buffer):
+ if not notify_when_away():
+ return False
+
+ if ignore_notifications_from_messages_tagged_with(tags):
+ return False
+
+ if ignore_notifications_from_nick(nick):
+ return False
+
+ if ignore_notifications_from_buffer(buffer):
+ return False
+
+ if is_private_message(buffer):
+ return notify_on_private_messages()
+
+ if is_highlight:
+ return notify_on_highlights()
+
+ if notify_on_messages_that_match(message):
+ return True
+
+ if notify_on_all_messages_in_buffer(buffer):
+ return True
+
+ return False
+
+
+def is_below_min_notification_delay(buffer):
+ """Is a notification in the given buffer below the minimal delay between
+ successive notifications from the same buffer?
+
+ When called, this function updates the time of the last notification.
+ """
+ # We store the time of the last notification in a buffer-local variable to
+ # make it persistent over the lifetime of this script.
+ LAST_NOTIFICATION_TIME_VAR = 'notify_send_last_notification_time'
+ last_notification_time = buffer_get_float(
+ buffer,
+ 'localvar_' + LAST_NOTIFICATION_TIME_VAR
+ )
+
+ min_notification_delay = weechat.config_get_plugin('min_notification_delay')
+ # min_notification_delay is in milliseconds (str). To compare it with
+ # last_notification_time (float in seconds), we have to convert it to
+ # seconds (float).
+ min_notification_delay = float(min_notification_delay) / 1000
+
+ current_time = time.time()
+
+ # We have to update the last notification time before returning the result.
+ buffer_set_float(
+ buffer,
+ 'localvar_set_' + LAST_NOTIFICATION_TIME_VAR,
+ current_time
+ )
+
+ return (min_notification_delay > 0 and
+ current_time - last_notification_time < min_notification_delay)
+
+
+def buffer_get_float(buffer, property):
+ """A variant of weechat.buffer_get_x() for floats.
+
+ This variant is needed because WeeChat supports only buffer_get_string()
+ and buffer_get_int().
+ """
+ value = weechat.buffer_get_string(buffer, property)
+ return float(value) if value else 0.0
+
+
+def buffer_set_float(buffer, property, value):
+ """A variant of weechat.buffer_set() for floats.
+
+ This variant is needed because WeeChat supports only integers and strings.
+ """
+ weechat.buffer_set(buffer, property, str(value))
+
+
+def names_for_buffer(buffer):
+ """Returns a list of all names for the given buffer."""
+ # The 'buffer' parameter passed to our callback is actually the buffer's ID
+ # (e.g. '0x2719cf0'). We have to check its name (e.g. 'freenode.#weechat')
+ # and short name (e.g. '#weechat') because these are what users specify in
+ # their configs.
+ buffer_names = []
+
+ full_name = weechat.buffer_get_string(buffer, 'name')
+ if full_name:
+ buffer_names.append(full_name)
+
+ short_name = weechat.buffer_get_string(buffer, 'short_name')
+ if short_name:
+ buffer_names.append(short_name)
+ # Consider >channel and #channel to be equal buffer names. The reason
+ # is that the https://github.com/rawdigits/wee-slack script replaces
+ # '#' with '>' to indicate that someone in the buffer is typing. This
+ # fixes the behavior of several configuration options (e.g.
+ # 'notify_on_all_messages_in_buffers') when weechat_notify_send is used
+ # together with the wee_slack script.
+ #
+ # Note that this is only needed to be done for the short name. Indeed,
+ # the full name always stays unchanged.
+ if short_name.startswith('>'):
+ buffer_names.append('#' + short_name[1:])
+
+ return buffer_names
+
+
+def notify_for_current_buffer():
+ """Should we also send notifications for the current buffer?"""
+ return weechat.config_get_plugin('notify_for_current_buffer') == 'on'
+
+
+def notify_on_highlights():
+ """Should we send notifications on highlights?"""
+ return weechat.config_get_plugin('notify_on_highlights') == 'on'
+
+
+def notify_on_private_messages():
+ """Should we send notifications on private messages?"""
+ return weechat.config_get_plugin('notify_on_privmsgs') == 'on'
+
+
+def notify_on_filtered_messages():
+ """Should we also send notifications for filtered (hidden) messages?"""
+ return weechat.config_get_plugin('notify_on_filtered_messages') == 'on'
+
+
+def notify_when_away():
+ """Should we also send notifications when away?"""
+ return weechat.config_get_plugin('notify_when_away') == 'on'
+
+
+def is_away(buffer):
+ """Is the user away?"""
+ return weechat.buffer_get_string(buffer, 'localvar_away') != ''
+
+
+def is_private_message(buffer):
+ """Has a private message been sent?"""
+ return weechat.buffer_get_string(buffer, 'localvar_type') == 'private'
+
+
+def i_am_author_of_message(buffer, nick):
+ """Am I (the current WeeChat user) the author of the message?"""
+ return weechat.buffer_get_string(buffer, 'localvar_nick') == nick
+
+
+def split_option_value(option, separator=','):
+ """Splits the value of the given plugin option by the given separator and
+ returns the result in a list.
+ """
+ values = weechat.config_get_plugin(option)
+ if not values:
+ # When there are no values, return the empty list instead of [''].
+ return []
+
+ return [value.strip() for value in values.split(separator)]
+
+
+def ignore_notifications_from_messages_tagged_with(tags):
+ """Should notifications be ignored for a message tagged with the given
+ tags?
+ """
+ ignored_tags = split_option_value('ignore_messages_tagged_with')
+ for ignored_tag in ignored_tags:
+ for tag in tags:
+ if tag == ignored_tag:
+ return True
+ return False
+
+
+def ignore_notifications_from_buffer(buffer):
+ """Should notifications from the given buffer be ignored?"""
+ buffer_names = names_for_buffer(buffer)
+
+ for buffer_name in buffer_names:
+ if buffer_name and buffer_name in ignored_buffers():
+ return True
+
+ for buffer_name in buffer_names:
+ for prefix in ignored_buffer_prefixes():
+ if prefix and buffer_name.startswith(prefix):
+ return True
+
+ return False
+
+
+def ignored_buffers():
+ """A generator of buffers from which notifications should be ignored."""
+ for buffer in split_option_value('ignore_buffers'):
+ yield buffer
+
+
+def ignored_buffer_prefixes():
+ """A generator of buffer prefixes from which notifications should be
+ ignored.
+ """
+ for prefix in split_option_value('ignore_buffers_starting_with'):
+ yield prefix
+
+
+def ignore_notifications_from_nick(nick):
+ """Should notifications from the given nick be ignored?"""
+ if nick in ignored_nicks():
+ return True
+
+ for prefix in ignored_nick_prefixes():
+ if prefix and nick.startswith(prefix):
+ return True
+
+ return False
+
+
+def ignored_nicks():
+ """A generator of nicks from which notifications should be ignored."""
+ for nick in split_option_value('ignore_nicks'):
+ yield nick
+
+
+def ignored_nick_prefixes():
+ """A generator of nick prefixes from which notifications should be
+ ignored.
+ """
+ for prefix in split_option_value('ignore_nicks_starting_with'):
+ yield prefix
+
+
+def notify_on_messages_that_match(message):
+ """Should we send a notification for the given message, provided it matches
+ any of the requested patterns?
+ """
+ message_patterns = split_option_value('notify_on_messages_that_match')
+ for pattern in message_patterns:
+ if re.search(pattern, message):
+ return True
+
+ return False
+
+
+def buffers_to_notify_on_all_messages():
+ """A generator of buffer names in which the user wants to be notified for
+ all messages.
+ """
+ for buffer in split_option_value('notify_on_all_messages_in_buffers'):
+ yield buffer
+
+
+def buffer_patterns_to_notify_on_all_messages():
+ """A generator of buffer-name patterns in which the user wants to be
+ notifier for all messages.
+ """
+ for pattern in split_option_value('notify_on_all_messages_in_buffers_that_match'):
+ yield pattern
+
+
+def notify_on_all_messages_in_buffer(buffer):
+ """Does the user want to be notified for all messages in the given buffer?
+ """
+ buffer_names = names_for_buffer(buffer)
+
+ # Option notify_on_all_messages_in_buffers:
+ for buf in buffers_to_notify_on_all_messages():
+ if buf in buffer_names:
+ return True
+
+ # Option notify_on_all_messages_in_buffers_that_match:
+ for pattern in buffer_patterns_to_notify_on_all_messages():
+ for buf in buffer_names:
+ if re.search(pattern, buf):
+ return True
+
+ return False
+
+
+def buffer_patterns_to_hide_messages():
+ """A generator of buffer-name patterns in which the user wants to hide
+ messages.
+ """
+ for pattern in split_option_value('hide_messages_in_buffers_that_match'):
+ yield pattern
+
+
+def hide_message_in_buffer(buffer):
+ """Should we hide messages in the given buffer?"""
+ buffer_names = names_for_buffer(buffer)
+
+ for pattern in buffer_patterns_to_hide_messages():
+ for buf in buffer_names:
+ if re.search(pattern, buf):
+ return True
+
+ return False
+
+
+def prepare_notification(buffer, nick, message):
+ """Prepares a notification from the given data."""
+ if is_private_message(buffer):
+ source = nick
+ else:
+ source = (weechat.buffer_get_string(buffer, 'short_name') or
+ weechat.buffer_get_string(buffer, 'name'))
+ message = nick + nick_separator() + message
+
+ if hide_message_in_buffer(buffer):
+ message = ''
+
+ max_length = int(weechat.config_get_plugin('max_length'))
+ if max_length > 0:
+ ellipsis = weechat.config_get_plugin('ellipsis')
+ message = shorten_message(message, max_length, ellipsis)
+
+ if weechat.config_get_plugin('escape_html') == 'on':
+ message = escape_html(message)
+
+ message = escape_slashes(message)
+
+ icon = weechat.config_get_plugin('icon')
+ desktop_entry = weechat.config_get_plugin('desktop_entry')
+ timeout = weechat.config_get_plugin('timeout')
+ transient = should_notifications_be_transient()
+ urgency = weechat.config_get_plugin('urgency')
+
+ return Notification(source, message, icon, desktop_entry, timeout, transient, urgency)
+
+
+def should_notifications_be_transient():
+ """Should the sent notifications be transient, i.e. should they be removed
+ from the notification bar once they expire or are dismissed?
+ """
+ return weechat.config_get_plugin('transient') == 'on'
+
+
+def nick_separator():
+ """Returns a nick separator to be used."""
+ separator = weechat.config_get_plugin('nick_separator')
+ return separator if separator else default_value_of('nick_separator')
+
+
+def shorten_message(message, max_length, ellipsis):
+ """Shortens the message to at most max_length characters by using the given
+ ellipsis.
+ """
+ # In Python 2, we need to decode the message and ellipsis into Unicode to
+ # correctly (1) detect their length and (2) shorten the message. Failing to
+ # do that could make the shortened message invalid and cause notify-send to
+ # fail. For example, when we have bytes, we cannot guarantee that we do not
+ # split the message inside of a multibyte character.
+ if sys.version_info.major == 2:
+ try:
+ message = message.decode('utf-8')
+ ellipsis = ellipsis.decode('utf-8')
+ except UnicodeDecodeError:
+ # Either (or both) of the two cannot be decoded. Continue in a
+ # best-effort manner.
+ pass
+
+ message = shorten_unicode_message(message, max_length, ellipsis)
+
+ if sys.version_info.major == 2:
+ if not isinstance(message, str):
+ message = message.encode('utf-8')
+
+ return message
+
+
+def shorten_unicode_message(message, max_length, ellipsis):
+ """An internal specialized version of shorten_message() when the both the
+ message and ellipsis are str (in Python 3) or unicode (in Python 2).
+ """
+ if max_length <= 0 or len(message) <= max_length:
+ # Nothing to shorten.
+ return message
+
+ if len(ellipsis) >= max_length:
+ # We cannot include any part of the message.
+ return ellipsis[:max_length]
+
+ return message[:max_length - len(ellipsis)] + ellipsis
+
+
+def escape_html(message):
+ """Escapes HTML characters in the given message."""
+ # Only the following characters need to be escaped
+ # (https://wiki.ubuntu.com/NotificationDevelopmentGuidelines).
+ message = message.replace('&', '&amp;')
+ message = message.replace('<', '&lt;')
+ message = message.replace('>', '&gt;')
+ return message
+
+
+def escape_slashes(message):
+ """Escapes slashes in the given message."""
+ # We need to escape backslashes to prevent notify-send from interpreting
+ # them, e.g. we do not want to print a newline when the message contains
+ # '\n'.
+ return message.replace('\\', r'\\')
+
+
+def send_notification(notification):
+ """Sends the given notification to the user."""
+ notify_cmd = ['notify-send', '--app-name', 'weechat']
+ if notification.icon:
+ notify_cmd += ['--icon', notification.icon]
+ if notification.desktop_entry:
+ notify_cmd += ['--hint', 'string:desktop-entry:{}'.format(notification.desktop_entry)]
+ if notification.timeout:
+ notify_cmd += ['--expire-time', str(notification.timeout)]
+ if notification.transient:
+ notify_cmd += ['--hint', 'int:transient:1']
+ if notification.urgency:
+ notify_cmd += ['--urgency', notification.urgency]
+ # We need to add '--' before the source and message to ensure that
+ # notify-send considers the remaining parameters as the source and the
+ # message. This prevents errors when a source or message starts with '--'.
+ notify_cmd += [
+ '--',
+ # notify-send fails with "No summary specified." when no source is
+ # specified, so ensure that there is always a non-empty source.
+ notification.source or '-',
+ notification.message
+ ]
+
+ # Prevent notify-send from messing up the WeeChat screen when occasionally
+ # emitting assertion messages by redirecting the output to /dev/null (users
+ # would need to run /redraw to fix the screen).
+ # In Python < 3.3, there is no subprocess.DEVNULL, so we have to use a
+ # workaround.
+ with open(os.devnull, 'wb') as devnull:
+ try:
+ subprocess.check_call(
+ notify_cmd,
+ stderr=subprocess.STDOUT,
+ stdout=devnull,
+ )
+ except Exception as ex:
+ error_message = '{} (reason: {!r}). {}'.format(
+ 'Failed to send the notification via notify-send',
+ '{}: {}'.format(ex.__class__.__name__, ex),
+ 'Ensure that you have notify-send installed in your system.',
+ )
+ print(error_message, file=sys.stderr)
+
+
+if __name__ == '__main__':
+ # Registration.
+ weechat.register(
+ SCRIPT_NAME,
+ SCRIPT_AUTHOR,
+ SCRIPT_VERSION,
+ SCRIPT_LICENSE,
+ SCRIPT_DESC,
+ SCRIPT_SHUTDOWN_FUNC,
+ SCRIPT_CHARSET
+ )
+
+ # Initialization.
+ for option, (default_value, description) in OPTIONS.items():
+ description = add_default_value_to(description, default_value)
+ weechat.config_set_desc_plugin(option, description)
+ if not weechat.config_is_set_plugin(option):
+ weechat.config_set_plugin(option, default_value)
+
+ # Catch all messages on all buffers and strip colors from them before
+ # passing them into the callback.
+ weechat.hook_print('', '', '', 1, 'message_printed_callback', '')