IrssiNotifier push notifications with end-to-end encryption.
Author: Caspar Clemens Mierau
— Version: 0.9
— License: GPL-3.0-or-later
For WeeChat ≥ 0.3.7, requires: openssl.
Tags: irssi, notify, py2, py3
Added: 2013-01-18
— Updated: 2018-11-11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | # -*- coding: utf-8 -*- # Author: Caspar Clemens Mierau <ccm@screenage.de> # Homepage: https://github.com/leitmedium/weechat-irssinotifier # Derived from: notifo # Author: ochameau <poirot.alex AT gmail DOT com> # Homepage: https://github.com/ochameau/weechat-notifo # And from: notify # Author: lavaramano <lavaramano AT gmail DOT com> # Improved by: BaSh - <bash.lnx AT gmail DOT com> # Ported to Weechat 0.3.0 by: Sharn - <sharntehnub AT gmail DOT com) # And from: notifo_notify # Author: SAEKI Yoshiyasu <laclef_yoshiyasu@yahoo.co.jp> # Homepage: http://bitbucket.org/laclefyoshi/weechat/ # # This plugin brings IrssiNotifier to your Weechat. Setup and install # IrssiNotifier first: https://irssinotifier.appspot.com # # Requires Weechat >= 0.3.7, openssl # Released under GNU GPL v3 # # 2018-10-02, Pol Van Aubel <dev@polvanaubel.com> # version 0.9: - Make python3-compatible. # 2017-05-17, das_aug <wct@fnanp.in-ulm.de> # version 0.8.1 - change openssl commandline to how the android app uses it now # (add "-md md5") # 2017-05-11, paalka <paal@128.no> # version 0.8: - add the ability to store the API token and # encryption key as secured data. # 2016-01-11, dbendit <david@ibendit.com> # version 0.7: - ignore_nicks option # 2014-05-10, Sébastien Helleu <flashcode@flashtux.org> # version 0.6.3: - change hook_print callback argument type of # displayed/highlight (WeeChat >= 1.0) # 2013-12-07, zigdon # version 0.6.2: - support ignoring all buffers in a server, add help text. # 2013-08-20, balu # version 0.6.1: - support for every private notification not only irc (especialy also jabber) # 2013-08-16, kang@insecure.ws # version 0.6: - only_away option (only notify if set away) # 2013-01-18, ccm <ccm@screenage.de>: # version 0.5: - removed version check and legacy curl usage # 2012-12-27, ccm <ccm@screenage.de>: # version 0.4: - use non-blocking hook_process_hashtable for url call # for weechat >= 0.3.7 # 2012-12-22, ccm <ccm@screenage.de>: # version 0.3: - no longer notifies if the message comes from the user # itself # - removed curl dependency # - cleaned up openssl call # - no more crashes due to missing escaping # - Kudos to Juergen "@tante" Geuter <tante@the-gay-bar.com> # for the patches! # 2012-10-27, ccm <ccm@screenage.de>: # version 0.2: - curl uses secure command call (decreases risk of command # injection) # - correct split of nick and channel name in a hilight # 2012-10-26, ccm <ccm@screenage.de>: # version 0.1: - initial release - working proof of concept import weechat, os, shlex from subprocess import Popen, PIPE import sys # Only required for python version check. PY3 = not sys.version_info < (3,) if PY3: from urllib.parse import urlencode else: from urllib import urlencode weechat.register("irssinotifier", "Caspar Clemens Mierau <ccm@screenage.de>", "0.9", "GPL3", "irssinotifier: Send push notifications to Android's IrssiNotifier about your private message and highligts.", "", "") settings = { "api_token": "API token from http://irssinotifier.appspot.com.", "encryption_password": "Your password, same as on the phone's client.", "only_away": "Only send notifications when set as away.", "ignore_buffers": "Comma separated list of buffers to ignore.", "ignore_servers": "Comma separated list of servers to ignore.", "ignore_nicks": "Comma separated list of nicks to ignore.", } required_settings = ["api_token", "encryption_password"] for option, help_text in list(settings.items()): if not weechat.config_is_set_plugin(option): weechat.config_set_plugin(option, "") if option in required_settings and weechat.config_get_plugin(option) == "": weechat.prnt("", weechat.prefix("error") + "irssinotifier: Please set option: %s" % option) weechat.prnt("", "irssinotifier: /set plugins.var.python.irssinotifier.%s STRING" % option) weechat.config_set_desc_plugin(option, help_text) # Hook privmsg/hilights weechat.hook_print("", "notify_message", "", 1, "notify_show", "") weechat.hook_print("", "notify_private", "", 1, "notify_show", "") # Functions def notify_show(data, bufferp, uber_empty, tagsn, isdisplayed, ishilight, prefix, message): # irc PMs are caught by notify_private, but we need notify_message to # capture hilights in channels. if 'notify_message' in tagsn and not ishilight: return weechat.WEECHAT_RC_OK # are we away? away = weechat.buffer_get_string(bufferp,"localvar_away") if (away == "" and weechat.config_get_plugin("only_away") == "on"): return weechat.WEECHAT_RC_OK # get local nick for buffer mynick = weechat.buffer_get_string(bufferp,"localvar_nick") # get buffer info name = weechat.buffer_get_string(bufferp,"name") server = weechat.buffer_get_string(bufferp, "localvar_server") channel = weechat.buffer_get_string(bufferp, "localvar_channel") # ignore buffers on ignorelists if not (server in weechat.config_get_plugin("ignore_servers").split(",") or name in weechat.config_get_plugin("ignore_buffers").split(",") or prefix in weechat.config_get_plugin("ignore_nicks").split(",")): # only notify if the message was not sent by myself if (weechat.buffer_get_string(bufferp, "localvar_type") == "private") and (prefix!=mynick): show_notification(channel, prefix, message) elif int(ishilight): buffer = (weechat.buffer_get_string(bufferp, "short_name") or name) show_notification(buffer, prefix, message) return weechat.WEECHAT_RC_OK def encrypt(text): encryption_password = weechat.config_get_plugin("encryption_password") # decrypt the password if it is stored as secured data if encryption_password.startswith("${sec."): encryption_password = weechat.string_eval_expression(encryption_password, {}, {}, {}) if PY3: text = text.encode("UTF-8") command="openssl enc -aes-128-cbc -salt -base64 -md md5 -A -pass env:OpenSSLEncPW" opensslenv = os.environ.copy(); # Unknown whether the encryption password should or should not be # (UTF8-)encoded before being passed to the environment in python 3. opensslenv['OpenSSLEncPW'] = encryption_password output, errors = Popen(shlex.split(command), stdin=PIPE, stdout=PIPE, stderr=PIPE,env=opensslenv).communicate(text + b" ") output = output.replace(b"/", b"_") output = output.replace(b"+", b"-") output = output.replace(b"=", b"") if PY3: output = output.decode("UTF-8") return output def show_notification(chan, nick, message): API_TOKEN = weechat.config_get_plugin("api_token") # decrypt the API token if it is stored as secured data if API_TOKEN.startswith("${sec."): API_TOKEN = weechat.string_eval_expression(API_TOKEN, {}, {}, {}) if API_TOKEN != "": url = "https://irssinotifier.appspot.com/API/Message" postdata = urlencode({'apiToken' : API_TOKEN, 'nick' : encrypt(nick), 'channel' : encrypt(chan), 'message' : encrypt(message), 'version' : 13}) version = weechat.info_get("version_number", "") or 0 hook1 = weechat.hook_process_hashtable("url:" + url, {"postfields": postdata}, 2000, "", "") # vim: autoindent expandtab smarttab shiftwidth=4 |