Home

Script: nma.py

Receive notifications in Notify My Android (android phone app). (for WeeChat ≥ 0.3.0, requires: pynma.py: https://github.com/uskr/pynma)
Author: sitaktif, version 1.0.7, GPL2 — added: 2011-10-04, updated: 2014-05-10
  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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# -*- coding: utf-8 -*-
# Author: sitaktif <romainchossart AT gmail DOT com>
# This plugin calls the pynma bindings via python when somebody says your
# nickname, sends you a query, etc.
#
# Requires:
# Weechat 0.3.0
# pynma.py (NMA python bindings) - This is the python API for NMA.  Take it
#   from https://raw.github.com/sitaktif/weechat_plugins_nma/master/pynma.py
#   and put it in the same direactory as nma.py.
#   Note: the pynma.py script is taken from https://github.com/uskr/pynma and
#     is not modified. The only reason you should use the one in the weechat
#     plugin repo (as opposed to the pynma repo) is that you are guaranteed
#     that pynma.py is at a version that is compatible with the weechat plugin.
#
# License: Released under GNU GPL v2
#
# Acknowledgements: Based on lavaramano's script "notify.py" v. 0.0.5 (thanks!)
#
# 2014-05-10, Sébastien Helleu <flashcode@flashtux.org>
#     version 1.0.7: change hook_print callback argument type of
#                    displayed/highlight (WeeChat >= 1.0)
# 2013-10-06, sitaktif
#     version 1.0.6: Add a "test" action. Take API key config changes dynamically.
# 2012-09-24, sitaktif
#     version 1.0.5: Do not send a notification when one is *sending* a query
#     message.
# 2012-05-06, sitaktif
#     version 1.0.4: Add an option to send everything in push. Also change
#     default delimiters with brackets and make lines 80 chars wide.
# 2012-05-05, sitaktif
#     version 1.0.3: Manage (non-ASCII) UTF8 chars
# 2012-01-05, Ac-town
#     version 1.0.2: Fixes a few typos I ran into and adds only_away. Only_away
#     only sends notifications if you are marked away.
# 2011-09-19, sitaktif
#     version 1.0.1: Corrected a bug with debug functions
# 2011-07-22, sitaktif
#     version 1.0.0: Initial release

import re
import weechat as w

w.register("nma", "sitaktif", "1.0.7", "GPL2",
    "nma: Receive notifications on NotifyMyAndroid app.", "", "")

# script options
settings = {
    "apikey"               : ("",      "Your NMA API key"),
    "nick_separator_left"  : ("(",     "Left separator for the nick that highlighted you"),
    "nick_separator_right" : (") ",    "Right separator for the nick that highlighted you"),
    "emergency_hilights"   : ("-1",    "Emergency of the highlight notifications (-2 is lowest, 2 is highest)"),
    "emergency_priv_msg"   : ("0",     "Emergency of the query notifications (-2 is lowest, 2 is highest)"),
    "activated"            : ("on",    "Whether the plugin will send notifications or not"),
    "notify_hilights"      : ("on",    "Send NMA notifications when you get highlights"),
    "notify_priv_msg"      : ("on",    "Send NMA notifications when you get a query message"),
    "use_push_if_possible" : ("on",    "If on, will try to fit the whole message in the title, which is send with the PUSH protocol. This makes you receive queries more quickly."),
    "smart_notification"   : ("off",   "Don't send notifications if you are focusing the channel (default: off)"),
    "only_away"            : ("off",   "Only send notifications if you are away"),
    "debug"                : ("off",   "Print debug messages"),
}

#severity_t = {
#    "emergency" : 2,
#    "high" : 1,
#    "normal" : 0,
#    "moderate" : -1,
#    "low": -2
#}

"""
Init
"""

for option, (default_value, description) in settings.items():
    if w.config_get_plugin(option) == "":
        w.config_set_plugin(option, default_value)
    if description:
        w.config_set_desc_plugin(option, description)

if w.config_get_plugin("apikey") == "":
    w.prnt("", "[nma] - You haven't set your API key. Use /set "
            "plugins.var.python.nma.apikey \"you_nma_api_token\" "
            "to fix that.")


"""
Hooks
"""

# Hook command
w.hook_command("nma", "Activate NotifyMyAndroid notifications",
        "on | off | test",
        """    on : Activate notifications
    off : Deactivate notifications
    test : Test a notification\n
        """,
        "on || off || test",
        "nma_cmd_cb", "");
# Hook privmsg/hilights
w.hook_print("", "irc_privmsg", "", 1, "priv_msg_cb", "")

from pynma import PyNMA
p = PyNMA()

"""
Helpers
"""

def _debug(text):
    if w.config_string_to_boolean(w.config_get_plugin("debug")):
        w.prnt("", "[nma] - %s" % text)

def nma_get_instance():
    global p
    for k in p._apikey:
        p.delkey(k)
    key = w.config_get_plugin("apikey")
    if key:
        p.addkey(key)
    else:
        w.prnt("", "[nma] - Cannot do anyting without an API key.")
        return None
    return p


"""
Functions
"""

# /nma command callback. Arguments: bool (on/off)
def nma_cmd_cb(data, buffer, args):
    if args.strip() == "test":
        send_notification("This is a weechat nma plugin test",
                "If you receive that, your configuration is ok", 0)
        return w.WEECHAT_RC_OK

    bool_arg = w.config_string_to_boolean(args)
    status = "%sactivated" % ("" if bool_arg else "de")
    ret = w.config_set_plugin('activated', args)
    if ret == w.WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE:
        w.prnt("", "...NMA was already %s" % status)
    elif ret == w.WEECHAT_CONFIG_OPTION_SET_ERROR:
        w.prnt("", "Error while setting the config.")
        return w.WEECHAT_RC_ERROR
    else:
        w.prnt("", "Notify My Android notifications %s." % status)
    return w.WEECHAT_RC_OK


def priv_msg_cb(data, bufferp, uber_empty, tagsn, isdisplayed,
        ishilight, prefix, message):
    """Sends highlighted message to be printed on notification"""

    if not w.config_string_to_boolean(w.config_get_plugin('activated')):
        _debug('Plugin not activated. Not sending.')
        return w.WEECHAT_RC_OK

    if (w.config_string_to_boolean(w.config_get_plugin('smart_notification')) and
            bufferp == w.current_buffer()):
        _debug('"smart_notification" option set but you are on this buffer already. Not sending.')
        return w.WEECHAT_RC_OK

    if (w.config_string_to_boolean(w.config_get_plugin('only_away')) and not
            w.buffer_get_string(bufferp, 'localvar_away')):
        _debug('"only_away" option set but you are not away. Not sending.')
        return w.WEECHAT_RC_OK

    notif_body = u"%s%s%s%s" % (
            w.config_get_plugin('nick_separator_left').decode('utf-8'),
            prefix.decode('utf-8'),
            w.config_get_plugin('nick_separator_right').decode('utf-8'),
            message.decode('utf-8'))


    # Check that it's in a "/q" buffer and that I'm not the one writing the msg
    is_pm = w.buffer_get_string(bufferp, "localvar_type") == "private"
    is_notify_private = re.search(r'(^|,)notify_private(,|$)', tagsn) is not None
    # PM (query)
    if (is_pm and is_notify_private and
            w.config_string_to_boolean(w.config_get_plugin('notify_priv_msg'))):
        send_notification("IRC private message",
        notif_body, int(w.config_get_plugin("emergency_priv_msg")))


    # Highlight (your nick is quoted)
    elif (int(ishilight) and
            w.config_string_to_boolean(w.config_get_plugin('notify_hilights'))):
        bufname = (w.buffer_get_string(bufferp, "short_name") or
                w.buffer_get_string(bufferp, "name"))
        send_notification(bufname.decode('utf-8'), notif_body,
                int(w.config_get_plugin("emergency_hilights")))

    return w.WEECHAT_RC_OK


def send_notification(chan, message, priority):
    p = nma_get_instance()
    if not(p):
        w.prnt("", "[nma] - Problem with NMA instance. Not sending notification")
        return None

    _debug("Sending notif with chan '%s', message '%s' and priority '%s'." %
            (chan, message, priority))
    if w.config_string_to_boolean(w.config_get_plugin('use_push_if_possible')):
        # So far, the length is hardcoded in pynma.py...
        if len(chan) + len(message) < 1021:
            chan = "%s - %s" % (chan, message)
            message = ""
    ret = p.push("[IRC]", chan, message, '', priority, batch_mode=False)
    if ret is not None:
        _debug("Message sent: %s. Return: %s." % (message, ret))

# vim: autoindent expandtab smarttab shiftwidth=4