Script: away_action.py

Run command on highlight and privmsg when away.
Author: xt — Version: 0.7 — License: GPL3
For WeeChat ≥ 0.3.0.
Tags: away, py2, py3
Added: 2010-03-17 — Updated: 2020-02-01

Download GitHub Repository

  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
# -*- coding: utf-8 -*-
###
# Copyright (c) 2010 by xt <xt@bash.no>
# Parts from inotify.py by Elián Hanisch <lambdae2@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
###
#   * plugins.var.python.away_action.ignore_channel:
#   Comma separated list of patterns for define ignores. Notifications from channels where its name
#   matches any of these patterns will be ignored.
#   Wildcards '*', '?' and char groups [..] can be used.
#   An ignore exception can be added by prefixing '!' in the pattern.
#
#       Example:
#       *ubuntu*,!#ubuntu-offtopic
#       any notifications from a 'ubuntu' channel will be ignored, except from #ubuntu-offtopic
#
#   * plugins.var.python.away_action.ignore_nick:
#   Same as ignore_channel, but for nicknames.
#
#       Example:
#       troll,b[0o]t
#       will ignore notifications from troll, bot and b0t
#
#   * plugins.var.python.away_action.ignore_text:
#   Same as ignore_channel, but for the contents of the message.

###
#
#
#   History:
#   2020-01-31:
#   version 0.7: add include_text option - contributed by dargad
#   2019-10-02:
#   version 0.6: make compatible with python 3
#   2014-05-10:
#   version 0.5: change hook_print callback argument type of
#                displayed/highlight (WeeChat >= 1.0)
#   2013-05-18:
#   version 0.4: add include_channel option - contributed by Atluxity
#   2010-11-04:
#   version 0.3: minor cleanups, fix import, add hook info
#   2010-03-17:
#   version 0.2: add force on option
#   2010-03-11
#   version 0.1: initial release
#
###

from __future__ import print_function

SCRIPT_NAME    = "away_action"
SCRIPT_AUTHOR  = "xt <xt@bash.no>"
SCRIPT_VERSION = "0.7"
SCRIPT_LICENSE = "GPL3"
SCRIPT_DESC    = "Run command on highlight and privmsg when away"

### Default Settings ###
settings = {
'ignore_channel' : '',
'ignore_nick'    : '',
'ignore_text'    : '',
'command'        : '/mute msg ', # Command to be ran, nick and message will be inserted at the end
'force_enabled'  : 'off',
'include_channel': 'off', # Option to include channel in insert after command.
'include_text'   : 'on', # Option to include message text in insert after command.
}

ignore_nick, ignore_text, ignore_channel = (), (), ()
last_buffer = ''
try:
    import weechat
    w = weechat
    WEECHAT_RC_OK = weechat.WEECHAT_RC_OK
    import_ok = True
    from fnmatch import fnmatch
except:
    print("This script must be run under WeeChat.")
    print("Get WeeChat now at: http://www.weechat.org/")
    import_ok = False

class Ignores(object):
    def __init__(self, ignore_type):
        self.ignore_type = ignore_type
        self.ignores = []
        self.exceptions = []
        self._get_ignores()

    def _get_ignores(self):
        assert self.ignore_type is not None
        ignores = weechat.config_get_plugin(self.ignore_type).split(',')
        ignores = [ s.lower() for s in ignores if s ]
        self.ignores = [ s for s in ignores if s[0] != '!' ]
        self.exceptions = [ s[1:] for s in ignores if s[0] == '!' ]

    def __contains__(self, s):
        s = s.lower()
        for p in self.ignores:
            if fnmatch(s, p):
                for e in self.exceptions:
                    if fnmatch(s, e):
                        return False
                return True
        return False

config_string = lambda s : weechat.config_string(weechat.config_get(s))
def get_nick(s):
    """Strip nickmodes and prefix, suffix."""
    if not s: return ''
    # prefix and suffix
    prefix = config_string('irc.look.nick_prefix')
    suffix = config_string('irc.look.nick_suffix')
    if s[0] == prefix:
        s = s[1:]
    if s[-1] == suffix:
        s = s[:-1]
    # nick mode
    modes = '~+@!%'
    s = s.lstrip(modes)
    return s

def away_cb(data, buffer, time, tags, display, hilight, prefix, msg):

    global ignore_nick, ignore_text, ignore_channel, last_buffer

    # Check if we are either away or force_enabled is on
    if not w.buffer_get_string(buffer, 'localvar_away') and \
       not w.config_get_plugin('force_enabled') == 'on':
        return WEECHAT_RC_OK

    if (int(hilight) or 'notify_private' in tags) and int(display):
        channel = weechat.buffer_get_string(buffer, 'short_name')
        prefix = get_nick(prefix)
        if prefix not in ignore_nick \
                and channel not in ignore_channel \
                and msg not in ignore_text:
            last_buffer = w.buffer_get_string(buffer, 'plugin') + '.' + \
                          w.buffer_get_string(buffer, 'name')
            command = weechat.config_get_plugin('command')
            if not command.startswith('/'):
                w.prnt('', '%s: Error: %s' %(SCRIPT_NAME, 'command must start with /'))
                return WEECHAT_RC_OK

            format = "{command}"
            data = {
                'command': command,
                'nick': prefix,
                'channel': channel,
                'message': msg
            }

            if 'channel' in locals() and \
                w.config_get_plugin('include_channel') == 'on':
                format += " {channel}"

            format += " {nick}"

            if w.config_get_plugin('include_text') == 'on':
                format += " {message}"

            w.command('', format.format(**data))
    return WEECHAT_RC_OK

def ignore_update(*args):
    ignore_channel._get_ignores()
    ignore_nick._get_ignores()
    ignore_text._get_ignores()
    return WEECHAT_RC_OK


def info_hook_cb(data, info_name, arguments):
    global last_buffer
    return last_buffer


if __name__ == '__main__' and import_ok and \
        weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC,
        '', ''):


    for opt, val in settings.items():
        if not weechat.config_is_set_plugin(opt):
            weechat.config_set_plugin(opt, val)

    ignore_channel = Ignores('ignore_channel')
    ignore_nick = Ignores('ignore_nick')
    ignore_text = Ignores('ignore_text')
    weechat.hook_config('plugins.var.python.%s.ignore_*' %SCRIPT_NAME, 'ignore_update', '')

    weechat.hook_print('', '', '', 1, 'away_cb', '')
    w.hook_info('%s_buffer' %SCRIPT_NAME, '', '', 'info_hook_cb', '')


# vim:set shiftwidth=4 tabstop=4 softtabstop=4 expandtab textwidth=100: