sopel.modules.adminchannel.configureHostMask()   B
last analyzed

Complexity

Conditions 7

Size

Total Lines 20
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 20
rs 8
c 0
b 0
f 0
cc 7
nop 1
1
# coding=utf-8
2
"""
3
adminchannel.py - Sopel Channel Admin Module
4
Copyright 2010-2011, Michael Yanovich, Alek Rollyson, and Elsie Powell
5
Copyright © 2012, Elad Alfassa <[email protected]>
6
Licensed under the Eiffel Forum License 2.
7
8
https://sopel.chat
9
"""
10
from __future__ import unicode_literals, absolute_import, print_function, division
11
12
import re
13
14
from sopel import formatting
15
from sopel.module import (
16
    commands, example, priority, OP, HALFOP, require_privilege, require_chanmsg
17
)
18
from sopel.tools import Identifier
19
20
21
def default_mask(trigger):
22
    welcome = formatting.color('Welcome to:', formatting.colors.PURPLE)
23
    chan = formatting.color(trigger.sender, formatting.colors.TEAL)
24
    topic_ = formatting.bold('Topic:')
25
    topic_ = formatting.color('| ' + topic_, formatting.colors.PURPLE)
26
    arg = formatting.color('{}', formatting.colors.GREEN)
27
    return '{} {} {} {}'.format(welcome, chan, topic_, arg)
28
29
30 View Code Duplication
@require_chanmsg
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
31
@require_privilege(OP, 'You are not a channel operator.')
32
@commands('op')
33
def op(bot, trigger):
34
    """
35
    Command to op users in a room. If no nick is given,
36
    Sopel will op the nick who sent the command
37
    """
38
    if bot.channels[trigger.sender].privileges[bot.nick] < OP:
39
        return bot.reply("I'm not a channel operator!")
40
    nick = trigger.group(2)
41
    channel = trigger.sender
42
    if not nick:
43
        nick = trigger.nick
44
    bot.write(['MODE', channel, "+o", nick])
45
46
47 View Code Duplication
@require_chanmsg
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
48
@require_privilege(OP, 'You are not a channel operator.')
49
@commands('deop')
50
def deop(bot, trigger):
51
    """
52
    Command to deop users in a room. If no nick is given,
53
    Sopel will deop the nick who sent the command
54
    """
55
    if bot.channels[trigger.sender].privileges[bot.nick] < OP:
56
        return bot.reply("I'm not a channel operator!")
57
    nick = trigger.group(2)
58
    channel = trigger.sender
59
    if not nick:
60
        nick = trigger.nick
61
    bot.write(['MODE', channel, "-o", nick])
62
63
64
@require_chanmsg
65
@require_privilege(OP, 'You are not a channel operator.')
66
@commands('voice')
67
def voice(bot, trigger):
68
    """
69
    Command to voice users in a room. If no nick is given,
70
    Sopel will voice the nick who sent the command
71
    """
72
    if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP:
73
        return bot.reply("I'm not a channel operator!")
74
    nick = trigger.group(2)
75
    channel = trigger.sender
76
    if not nick:
77
        nick = trigger.nick
78
    bot.write(['MODE', channel, "+v", nick])
79
80
81
@require_chanmsg
82
@require_privilege(OP, 'You are not a channel operator.')
83
@commands('devoice')
84
def devoice(bot, trigger):
85
    """
86
    Command to devoice users in a room. If no nick is given,
87
    Sopel will devoice the nick who sent the command
88
    """
89
    if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP:
90
        return bot.reply("I'm not a channel operator!")
91
    nick = trigger.group(2)
92
    channel = trigger.sender
93
    if not nick:
94
        nick = trigger.nick
95
    bot.write(['MODE', channel, "-v", nick])
96
97
98
@require_chanmsg
99
@require_privilege(OP, 'You are not a channel operator.')
100
@commands('kick')
101
@priority('high')
102
def kick(bot, trigger):
103
    """Kick a user from the channel."""
104
    if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP:
105
        return bot.reply("I'm not a channel operator!")
106
    text = trigger.group().split()
107
    argc = len(text)
108
    if argc < 2:
109
        return
110
    opt = Identifier(text[1])
111
    nick = opt
112
    channel = trigger.sender
113
    reasonidx = 2
114
    if not opt.is_nick():
115
        if argc < 3:
116
            return
117
        nick = text[2]
118
        channel = opt
119
        reasonidx = 3
120
    reason = ' '.join(text[reasonidx:])
121
    if nick != bot.config.core.nick:
122
        bot.kick(nick, channel, reason)
123
124
125
def configureHostMask(mask):
126
    if mask == '*!*@*':
127
        return mask
128
    if re.match('^[^.@!/]+$', mask) is not None:
129
        return '%s!*@*' % mask
130
    if re.match('^[^@!]+$', mask) is not None:
131
        return '*!*@%s' % mask
132
133
    m = re.match('^([^!@]+)@$', mask)
134
    if m is not None:
135
        return '*!%s@*' % m.group(1)
136
137
    m = re.match('^([^!@]+)@([^@!]+)$', mask)
138
    if m is not None:
139
        return '*!%s@%s' % (m.group(1), m.group(2))
140
141
    m = re.match('^([^!@]+)!(^[!@]+)@?$', mask)
142
    if m is not None:
143
        return '%s!%s@*' % (m.group(1), m.group(2))
144
    return ''
145
146
147 View Code Duplication
@require_chanmsg
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
148
@require_privilege(OP, 'You are not a channel operator.')
149
@commands('ban')
150
@priority('high')
151
def ban(bot, trigger):
152
    """Ban a user from the channel
153
154
    The bot must be a channel operator for this command to work.
155
    """
156
    if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP:
157
        return bot.reply("I'm not a channel operator!")
158
    text = trigger.group().split()
159
    argc = len(text)
160
    if argc < 2:
161
        return
162
    opt = Identifier(text[1])
163
    banmask = opt
164
    channel = trigger.sender
165
    if not opt.is_nick():
166
        if argc < 3:
167
            return
168
        channel = opt
169
        banmask = text[2]
170
    banmask = configureHostMask(banmask)
171
    if banmask == '':
172
        return
173
    bot.write(['MODE', channel, '+b', banmask])
174
175
176 View Code Duplication
@require_chanmsg
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
177
@require_privilege(OP, 'You are not a channel operator.')
178
@commands('unban')
179
def unban(bot, trigger):
180
    """Unban a user from the channel
181
182
    The bot must be a channel operator for this command to work.
183
    """
184
    if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP:
185
        return bot.reply("I'm not a channel operator!")
186
    text = trigger.group().split()
187
    argc = len(text)
188
    if argc < 2:
189
        return
190
    opt = Identifier(text[1])
191
    banmask = opt
192
    channel = trigger.sender
193
    if not opt.is_nick():
194
        if argc < 3:
195
            return
196
        channel = opt
197
        banmask = text[2]
198
    banmask = configureHostMask(banmask)
199
    if banmask == '':
200
        return
201
    bot.write(['MODE', channel, '-b', banmask])
202
203
204 View Code Duplication
@require_chanmsg
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
205
@require_privilege(OP, 'You are not a channel operator.')
206
@commands('quiet')
207
def quiet(bot, trigger):
208
    """Quiet a user
209
210
    The bot must be a channel operator for this command to work.
211
    """
212
    if bot.channels[trigger.sender].privileges[bot.nick] < OP:
213
        return bot.reply("I'm not a channel operator!")
214
    text = trigger.group().split()
215
    argc = len(text)
216
    if argc < 2:
217
        return
218
    opt = Identifier(text[1])
219
    quietmask = opt
220
    channel = trigger.sender
221
    if not opt.is_nick():
222
        if argc < 3:
223
            return
224
        quietmask = text[2]
225
        channel = opt
226
    quietmask = configureHostMask(quietmask)
227
    if quietmask == '':
228
        return
229
    bot.write(['MODE', channel, '+q', quietmask])
230
231
232 View Code Duplication
@require_chanmsg
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
233
@require_privilege(OP, 'You are not a channel operator.')
234
@commands('unquiet')
235
def unquiet(bot, trigger):
236
    """Unquiet a user
237
238
    The bot must be a channel operator for this command to work.
239
    """
240
    if bot.channels[trigger.sender].privileges[bot.nick] < OP:
241
        return bot.reply("I'm not a channel operator!")
242
    text = trigger.group().split()
243
    argc = len(text)
244
    if argc < 2:
245
        return
246
    opt = Identifier(text[1])
247
    quietmask = opt
248
    channel = trigger.sender
249
    if not opt.is_nick():
250
        if argc < 3:
251
            return
252
        quietmask = text[2]
253
        channel = opt
254
    quietmask = configureHostMask(quietmask)
255
    if quietmask == '':
256
        return
257
    bot.write(['MODE', channel, '-q', quietmask])
258
259
260
@require_chanmsg
261
@require_privilege(OP, 'You are not a channel operator.')
262
@commands('kickban', 'kb')
263
@example('.kickban [#chan] user1 user!*@* get out of here')
264
@priority('high')
265
def kickban(bot, trigger):
266
    """Kick and ban a user from the channel
267
268
    The bot must be a channel operator for this command to work.
269
    """
270
    if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP:
271
        return bot.reply("I'm not a channel operator!")
272
    text = trigger.group().split()
273
    argc = len(text)
274
    if argc < 4:
275
        return
276
    opt = Identifier(text[1])
277
    nick = opt
278
    mask = text[2]
279
    channel = trigger.sender
280
    reasonidx = 3
281
    if not opt.is_nick():
282
        if argc < 5:
283
            return
284
        channel = opt
285
        nick = text[2]
286
        mask = text[3]
287
        reasonidx = 4
288
    reason = ' '.join(text[reasonidx:])
289
    mask = configureHostMask(mask)
290
    if mask == '':
291
        return
292
    bot.write(['MODE', channel, '+b', mask])
293
    bot.kick(nick, channel, reason)
294
295
296
@require_chanmsg
297
@require_privilege(OP, 'You are not a channel operator.')
298
@commands('topic')
299
def topic(bot, trigger):
300
    """Change the channel topic
301
302
    The bot must be a channel operator for this command to work.
303
    """
304
    if bot.channels[trigger.sender].privileges[bot.nick] < HALFOP:
305
        return bot.reply("I'm not a channel operator!")
306
    if not trigger.group(2):
307
        return
308
    channel = trigger.sender.lower()
309
310
    narg = 1
311
    mask = None
312
    mask = bot.db.get_channel_value(channel, 'topic_mask')
313
    mask = mask or default_mask(trigger)
314
    mask = mask.replace('%s', '{}')
315
    narg = len(re.findall('{}', mask))
316
317
    top = trigger.group(2)
318
    args = []
319
    if top:
320
        args = top.split('~', narg)
321
322
    if len(args) != narg:
323
        message = "Not enough arguments. You gave {}, it requires {}.".format(
324
            len(args), narg)
325
        return bot.say(message)
326
    topic = mask.format(*args)
327
328
    bot.write(('TOPIC', channel + ' :' + topic))
329
330
331
@require_chanmsg
332
@require_privilege(OP, 'You are not a channel operator.')
333
@commands('tmask')
334
def set_mask(bot, trigger):
335
    """Set the topic mask to use for the current channel
336
337
    Within the topic mask, {} is used to allow substituting in chunks of text.
338
339
    This mask is used when running the 'topic' command.
340
    """
341
    bot.db.set_channel_value(trigger.sender, 'topic_mask', trigger.group(2))
342
    bot.say("Gotcha, " + trigger.nick)
343
344
345
@require_chanmsg
346
@require_privilege(OP, 'You are not a channel operator.')
347
@commands('showmask')
348
def show_mask(bot, trigger):
349
    """Show the topic mask for the current channel."""
350
    mask = bot.db.get_channel_value(trigger.sender, 'topic_mask')
351
    mask = mask or default_mask(trigger)
352
    bot.say(mask)
353