From 945ff82bfa5a7bd3c39c272dedad28d4556a12fa Mon Sep 17 00:00:00 2001 From: Adrian L Lange Date: Fri, 10 Feb 2017 19:01:01 +0100 Subject: [PATCH] :sparkles: --- LICENSE.txt | 19 ++++++ README.md | 46 +++++++++++++ pushjet.py | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 pushjet.py diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..e58429f --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2017 Adrian L Lange + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ff03f67 --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +# weechat-pushjet + +A [WeeChat](https://weechat.org/) plugin that sends highlights and/or private message notifications through [Pushjet](https://pushjet.io/). + +### Installation + +In WeeChat install the script by typing the following: +``` +/script install pushjet.py +``` + +If you're using the public push server, all you have to do is set the _`secret`_ option in the configuration. + +### Options + +The plugin allows you to set a few options through the normal WeeChat settings system. +You'll find all of them under _`plugins.var.python.pushjet`_, and all of them have helpful descriptions. + +To set them use _`/set plugins.var.python.pushjet.foo bar`_ or through the [iset.pl](https://weechat.org/scripts/source/iset.pl.html) plugin. + +- `host` + - host for the pushjet api (default: "https://api.pushjet.io") +- `secret` + - secret for the pushjet api (default: "") +- `level` + - severity level for the message, from 1 to 5 (low to high) (default: 4) +- `timeout` + - timeout for the message sending in seconds (>= 1) (default: 30) +- `separator` + - separator between nick and message in notifications (default: ": ") +- `notify_on_highlight` + - push notifications for highlights in buffers (on/off) (default: "on") +- `notify_on_privmsg` + - push notifications for private messages (on/off) (default: "on") +- `notify_when` + - when to push notifications (away/detached/always/never) (default: "always") +- `ignore_buffers` + - comma-separated list of buffers to ignore (default: "") +- `ignore_nicks` + - comma-separated list of users to not push notifications from (default: "") + +### Issues + +- The currently available version of Pushjet is sending the wrong error codes for errors. + This means that if your settings are invalid it's very hard to find out exactly what is wrong. +- Away status can't be checked when receiving private messages diff --git a/pushjet.py b/pushjet.py new file mode 100644 index 0000000..6de354d --- /dev/null +++ b/pushjet.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- + +# https://github.com/p3lim/weechat-pushjet + +try: + import weechat +except ImportError: + from sys import exit + print('This script has to run under WeeChat (https://weechat.org/).') + exit(1) + +from urllib import urlencode + +SCRIPT_NAME = 'pushjet' +SCRIPT_AUTHOR = 'p3lim' +SCRIPT_VERSION = '0.1.0' +SCRIPT_LICENSE = 'MIT' +SCRIPT_DESC = 'Send highlights and mentions through Pushjet.io' + +SETTINGS = { + 'host': ( + 'https://api.pushjet.io', + 'host for the pushjet api'), + 'secret': ( + '', + 'secret for the pushjet api'), + 'level': ( + '4', + 'severity level for the message, from 1 to 5 (low to high)'), + 'timeout': ( + '30', + 'timeout for the message sending in seconds (>= 1)'), + 'separator': ( + ': ', + 'separator between nick and message in notifications'), + 'notify_on_highlight': ( + 'on', + 'push notifications for highlights in buffers (on/off)'), + 'notify_on_privmsg': ( + 'on', + 'push notifications for private messages (on/off)'), + 'notify_when': ( + 'always', + 'when to push notifications (away/detached/always/never)'), + 'ignore_buffers': ( + '', + 'comma-separated list of buffers to ignore'), + 'ignore_nicks': ( + '', + 'comma-separated list of users to not push notifications from'), +} + +def send_message(title, message): + secret = weechat.config_get_plugin('secret') + if secret != '': + data = { + 'secret': secret, + 'level': int(weechat.config_get_plugin('level')), + 'title': title, + 'message': message, + } + + host = weechat.config_get_plugin('host').rstrip('/') + '/message' + timeout = int(weechat.config_get_plugin('timeout')) * 1000 + + if timeout <= 0: + timeout = 1 + + data = urlencode(data) + cmd = 'python -c \'from urllib2 import Request, urlopen; r = urlopen(Request("%s", "%s")); print r.getcode()\'' % (host, data) + weechat.hook_process(cmd, timeout, 'send_message_callback', '') + +def send_message_callback(data, command, return_code, out, err): + if return_code != 0: + # something went wrong + return weechat.WEECHAT_RC_ERROR + + return weechat.WEECHAT_RC_OK + +def get_sender(tags, prefix): + # attempt to find sender from tags + # nicks are always prefixed with 'nick_' + for tag in tags: + if tag.startswith('nick_'): + return tag[5:] + + # fallback method to find sender from prefix + # nicks in prefixes are prefixed with optional modes (e.g @ for operators) + # so we have to strip away those first, if they exist + if prefix.startswith(('~', '&', '@', '%', '+', '-', ' ')): + return prefix[1:] + + return prefix + +def get_buffer_names(buffer): + buffer_names = [] + buffer_names.append(weechat.buffer_get_string(buffer, 'short_name')) + buffer_names.append(weechat.buffer_get_string(buffer, 'name')) + return buffer_names + +def should_send(buffer, tags, nick, highlighted): + if not nick: + # a nick is required to form a correct message, bail + return False + + if highlighted: + if weechat.config_get_plugin('notify_on_highlight') != 'on': + # notifying on highlights is disabled, bail + return False + elif weechat.buffer_get_string(buffer, 'localvar_type') == 'private': + if weechat.config_get_plugin('notify_on_privmsg') != 'on': + # notifying on private messages is disabled, bail + return False + else: + # not a highlight or private message, bail + return False + + notify_when = weechat.config_get_plugin('notify_when') + if notify_when == 'never': + # user has opted to not be notified, bail + return False + elif notify_when == 'away': + # user has opted to only be notified when away + infolist_args = ( + weechat.buffer_get_string(buffer, 'localvar_channel'), + weechat.buffer_get_string(buffer, 'localvar_server'), + weechat.buffer_get_string(buffer, 'localvar_nick') + ) + + if not None in infolist_args: + infolist = weechat.infolist_get('irc_nick', '', ','.join(infolist_args)) + if infolist: + away_status = weechat.infolist_integer(infolist, 'away') + if not away_status: + # user is not away, bail + return False + elif notify_when == 'detached': + # user has opted to only be notified when detached (relays) + num_relays = weechat.info_get('relay_client_count', 'connected') + if num_relays == 0: + # no relays connected, bail + return False + + if nick == weechat.buffer_get_string(buffer, 'localvar_nick'): + # the sender was the current user, bail + return False + + if nick in weechat.config_get_plugin('ignore_nicks').split(','): + # the sender was on the ignore list, bail + return False + + for buffer_name in get_buffer_names(buffer): + if buffer_name in weechat.config_get_plugin('ignore_buffers').split(','): + # the buffer was on the ignore list, bail + return False + + return True + +def message_callback(data, buffer, date, tags, displayed, highlight, prefix, message): + nick = get_sender(tags, prefix) + + if should_send(buffer, tags, nick, int(highlight)): + message = '%s%s%s' % (nick, weechat.config_get_plugin('separator'), message) + + if int(highlight): + buffer_names = get_buffer_names(buffer) + send_message(buffer_names[0] or buffer_names[1], message) + else: + send_message('Private Message', message) + + return weechat.WEECHAT_RC_OK + +# register plugin +weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, '', '') + +# grab all messages in any buffer +weechat.hook_print('', '', '', 1, 'message_callback', '') + +# register configuration defaults +for option, value in SETTINGS.items(): + if not weechat.config_is_set_plugin(option): + weechat.config_set_plugin(option, value[0]) + + weechat.config_set_desc_plugin(option, '%s (default: "%s")' % (value[1], value[0]))