def part(kenni, input): '''Part the specified channel. This is an admin-only command.''' if input.admin: sendmessage = input.group(2) sendmessage2 = [] if sendmessage: sendmessage2 = sendmessage.split(" ") if tools.isChan(input.sender, False) and (not sendmessage or not tools.isChan(sendmessage2[0], False)): kenni.write(['PART', input.sender]) kenni.channels.remove(input.sender) else: kenni.write(['PART', sendmessage2[0] + " :" ' '.join(sendmessage2[1:])]) kenni.channels.remove(sendmessage2[0])
def cycle(cenni, input): '''Part the specified channel. This is an admin-only command.''' if input.admin: sendmessage = input.group(2) sendmessage2 = [] if sendmessage: sendmessage2 = sendmessage.split(" ") if tools.isChan(input.sender, False) and (not sendmessage or not tools.isChan(sendmessage2[0], False)): cenni.write(['PART'], input.sender) cenni.join(input.sender, None) else: cenni.write(['PART', sendmessage2[0]]) cenni.join(sendmessage2[0], None)
def track_priv_change(kenni, input): if not input.sender or not tools.isChan(input.sender, False): return channel = input.sender if input.mode: add_mode = input.mode.startswith('+') del_mode = input.mode.startswith('-') # Check that this is a mode change and that it is a mode change on a user if (add_mode or del_mode) and input.mode_target and len(input.mode_target) > 0: mode_change = input.mode[1:] mode_target = input.mode_target if add_mode: if mode_change == 'o': kenni.add_op(channel, mode_target) elif mode_change == 'h': kenni.add_halfop(channel, mode_target) elif mode_change == 'v': kenni.add_voice(channel, mode_target) else: if mode_change == 'o': kenni.del_op(channel, mode_target) elif mode_change == 'h': kenni.del_halfop(channel, mode_target) elif mode_change == 'v': kenni.del_voice(channel, mode_target)
def kickban(kenni, input): """ This gives admins the ability to kickban a user. The bot must be a Channel Operator for this command to work .kickban [#chan] user1 user!*@* get out of here """ text = input.group().split() argc = len(text) channel = input.sender opt = text[1] nick = opt reasonidx = "Your behavior is not conductive to the desired environment" if tools.isChan(opt, False): channel = opt nick = text[2] if (argc > 3): reasonidx = " ".join(text[3:]) else: if (argc > 2): reasonidx = " ".join(text[2:]) if not is_chan_admin(kenni, input, channel): return kenni.say('You must be an admin to perform this operation') mask = configureHostMask(nick, kenni) if mask == '': return kenni.write(['MODE', channel, '+b', mask]) kickx(kenni, channel, nick, input.nick, reasonidx)
def roulette(cenni, input): global barrel, currentbarrel if not tools.isChan(input.sender, False): return if hasattr(cenni.config, 'rouletteC') and input.sender in cenni.config.rouletteC: if not cenni.config.rouletteC[input.sender]: return else: return random.seed() if input.sender not in barrel or barrel[input.sender] == None or ( input.group(2) and input.group(2).lower() == 'spin'): barrel[input.sender] = random.randint(1, 8) currentbarrel[input.sender] = 1 if cenni.logchan_pm: cenni.msg( cenni.logchan_pm, '[Roulette Spin] ' + input.nick + '!' + input.user + '@' + input.host + ': (' + input.sender + ') Barrel in ' + str(barrel[input.sender])) if input.group(2) and input.group(2).lower() == 'spin': return cenni.say("Feeling lucky?") if barrel[input.sender] == currentbarrel[input.sender]: if cenni.nick.lower() in cenni.ops[input.sender]: cenni.write(['KICK', input.sender, input.nick, "BANG"]) else: cenni.write(['PRIVMSG', input.sender], "\x01ACTION kicks " + input.nick + "\x01") barrel[input.sender] = None else: cenni.say("*CLICK*") currentbarrel[input.sender] += 1
def f_note(cenni, input): try: if not hasattr(cenni, 'seen'): cenni.seen = dict() if tools.isChan(input.sender, False): cenni.seen[input.nick.lower()] = (input.sender, time.time()) except Exception as e: print(e)
def deop(kenni, input): text = input.group().split() argc = len(text) nick = input.nick channel = input.sender if not tools.isChan(input.sender, False): channel = None if argc >= 2 and text[1] is not None: if tools.isChan(text[1], False): channel = text[1] if argc >= 3 and text[2] is not None: nick = text[2] else: nick = text[1] if channel is not None: if not is_chan_admin(kenni, input, channel): return kenni.say('You must be an admin to perform this operation') kenni.write(['MODE', channel, "-o", nick])
def topic(cenni, input): global oldtopic """ This gives admins the ability to change the topic. Note: One does *NOT* have to be an OP, one just has to be on the list of admins. """ text = input.group().split() argc = len(text) channel = input.sender topic = ' '.join(text[1:]) index = 1 if tools.isChan(text[1], False): if argc < 2: return channel = text[1] topic = ' '.join(text[2:]) index = 2 if not is_chan_admin(cenni, input, channel): return cenni.say('You must be an admin to perform this operation') if text[index] == 'undo': if channel in oldtopic: cenni.write(['TOPIC', channel], oldtopic[channel]) else: cenni.say("Undo not possible") return if channel not in cenni.channeltopics: currenttopic = None else: currenttopic = cenni.channeltopics[channel] oldtopic[channel] = currenttopic if currenttopic and getChanSplitChar( cenni, channel) and (len(text) > index + 1 or text[index].startswith("-")): #cenni.say(currenttopic) char = getChanSplitChar(cenni, channel) if text[index].startswith("-") and "".join( text[index][1:]).isdigit() and len( currenttopic.split(char)) >= int("".join(text[index][1:])): tmp = currenttopic.split(char) tmp.pop(int("".join(text[index][1:])) - 1) currenttopic = char.join(tmp) elif text[index].isdigit() and len(currenttopic.split(char)) >= int( text[index]): tmp = currenttopic.split(char) tmp[int(text[index]) - 1] = ' '.join(text[index + 1:]) currenttopic = char.join(tmp) elif text[index] == 'add': tmp = currenttopic.split(char) tmp.append(' '.join(text[index + 1:])) currenttopic = char.join(tmp) else: currenttopic = topic cenni.write(['TOPIC', channel], currenttopic) else: cenni.write(['TOPIC', channel], topic) return
def msg(cenni, input): if input.owner: text = input.group().split() argc = len(text) channel = input.sender msg = ' '.join(text[1:]) if argc > 2 and tools.isChan(text[1], True): channel = text[1] msg = ' '.join(text[2:]) cenni.write(['PRIVMSG', channel], msg)
def mode(kenni, input): """ """ text = input.group().split() argc = len(text) channel = input.sender if not tools.isChan(input.sender, False): channel = None if argc >= 2 and text[1] is not None: if tools.isChan(text[1], False): channel = text[1] if argc >= 3 and text[2] is not None: modex = " ".join(text[2:]) else: modex = " ".join(text[1:]) if channel is not None: if not is_chan_admin(kenni, input, channel): return kenni.say('You must be an admin to perform this operation') kenni.write(['MODE', channel, modex])
def act(cenni, input): if input.owner: text = input.group().split() argc = len(text) channel = input.sender msg = ' '.join(text[1:]) if argc > 2 and tools.isChan(text[1], False): channel = text[1] msg = ' '.join(text[2:]) cenni.write(['PRIVMSG', channel], '\x01ACTION ' + msg + '\x01')
def roulette(kenni, input): if not tools.isChan(input.sender, False): return random.seed() randnum = random.randint(1,3) if randnum == 2: if kenni.nick in kenni.ops[input.sender]: kenni.write(['KICK', input.sender, input.nick, "BANG"]) else: kenni.write(['PRIVMSG', input.sender], "\x01ACTION kicks " + input.nick +"\x01") else: kenni.say("*CLICK*")
def devoice(kenni, input): """ Command to devoice users in a room. If no nick is given, kenni will devoice the nick who sent the command """ text = input.group().split() argc = len(text) nick = input.nick channel = input.sender if not tools.isChan(input.sender, False): channel = None if argc >= 2 and text[1] is not None: if tools.isChan(text[1], False): channel = text[1] if argc >= 3 and text[2] is not None: nick = text[2] else: nick = text[1] if channel is not None: if not is_chan_admin(kenni, input, channel): return kenni.say('You must be an admin to perform this operation') kenni.write(['MODE', channel, "-v", nick])
def privs_on_join(kenni, input): if not input.mode_target or not tools.isChan(input.mode_target, False): return channel = input.mode_target if input.names and len(input.names) > 0: split_names = input.names.split() for name in split_names: nick_mode, nick = name[0], name[1:] if nick_mode == '@': kenni.add_op(channel, nick) elif nick_mode == '%': kenni.add_halfop(channel, nick) elif nick_mode == '+': kenni.add_voice(channel, nick_mode + nick)
def invite(kenni, input): """ Command to voice users in a room. If no nick is given, kenni will voice the nick who sent the command """ text = input.group().split() argc = len(text) nick = input.nick channel = input.sender if not tools.isChan(input.sender, False): channel = None if argc >= 2 and text[1] is not None: if tools.isChan(text[1], False): channel = text[1] if argc >= 3 and text[2] is not None: nick = text[2] else: nick = text[1] if channel is not None: if not is_chan_admin(kenni, input, channel): return kenni.say('You must be an admin to perform this operation') kenni.write(['PRIVMSG', channel], '\x01ACTION invites ' + nick + ' per ' + input.nick + '\x01') kenni.write(['INVITE', nick], channel)
def test_colours(kenni, input): if not input.admin and tools.isChan(input.sender, False): return output = str() keys = list(colours.keys()) keys.sort() bold_output = str() for colour in keys: output += "\x03{0}{1} ({0})\x03, ".format(colour, colours[colour]) bold_output += "\x02\x03{0}{1} ({0})\x03\x02, ".format( colour, colours[colour]) output = output[:-2] bold_output = bold_output[:-2] kenni.say(output) kenni.say(bold_output)
def slap(kenni, input): """.slap <target> - Slaps <target>""" text = input.group().split() if len(text) < 2 or tools.isChan(text[1], False): return if text[1] == kenni.nick: if (input.nick not in kenni.config.admins): text[1] = input.nick else: text[1] = 'herself' if text[1] in kenni.config.admins: if (input.nick not in kenni.config.admins): text[1] = input.nick verb = random.choice( ('slaps', 'kicks', 'destroys', 'annihilates', 'obliterates', 'drop kicks', 'curb stomps', 'backhands', 'punches', 'roundhouse kicks', 'rusty hooks', 'pwns', 'owns')) kenni.write( ['PRIVMSG', input.sender, ' :\x01ACTION', verb, text[1], '\x01'])
def topic(kenni, input): """ This gives admins the ability to change the topic. Note: One does *NOT* have to be an OP, one just has to be on the list of admins. """ text = input.group().split() argc = len(text) channel = input.sender topic = ' '.join(text[1:]) if tools.isChan(text[1], False): if argc < 2: return channel = text[1] topic = ' '.join(text[2:]) if not is_chan_admin(kenni, input, channel): return kenni.say('You must be an admin to perform this operation') if topic == '': return kenni.write(['TOPIC', channel], topic) return
def unquiet(kenni, input): """ This gives admins the ability to unquiet a user. The bot must be a Channel Operator for this command to work """ text = input.group().split() argc = len(text) if argc < 2: return opt = text[1] banmask = opt channel = input.sender if tools.isChan(opt, False): if argc < 3: return channel = opt banmask = text[2] if not is_chan_admin(kenni, input, channel): return kenni.say('You must be an admin to perform this operation') quietmask = configureHostMask(banmask, kenni) if quietmask == '': return kenni.write(['MODE', channel, '-q', quietmask])
def kick(kenni, input): text = input.group().split() argc = len(text) channel = input.sender opt = text[1] nick = opt reasonidx = "Your behavior is not conductive to the desired environment" if tools.isChan(opt, False): channel = opt nick = text[2] if (argc > 3): reasonidx = " ".join(text[3:]) else: if (argc > 2): reasonidx = " ".join(text[2:]) if not is_chan_admin(kenni, input, channel): return kenni.say('You must be an admin to perform this operation') if "," in nick: nicks = nick.split(",") for nic in nicks: kickx(kenni, channel, nic, input.nick, reasonidx) else: kickx(kenni, channel, nick, input.nick, reasonidx)
def found_terminator(self): line = self.buffer if line.endswith('\r'): line = line[:-1] if line: if self.logchan_pm: ## if logging to logging channel is enabled ## send stuff in PM to logging channel dlist = line.split() currnick = re.compile(".*" + self.nick + ".*", re.IGNORECASE) if len(dlist) >= 3: if (not tools.isChan(dlist[2], True) or dlist[1].strip() == 'NOTICE'): if dlist[1].strip() == 'NOTICE': if tools.isChan(dlist[2], True): self.msg( self.logchan_pm, '[Notice] ' + dlist[0].replace(':', '') + ': (' + dlist[2] + ') ' + ' '.join(dlist[3:]).replace(":", ""), True) else: self.msg( self.logchan_pm, '[Notice] ' + dlist[0].replace(":", "") + ': ' + ' '.join(dlist[3:]).replace(":", ""), True) elif dlist[1].strip( ) == 'PRIVMSG' and dlist[2].isalnum(): self.msg( self.logchan_pm, '[PM] ' + dlist[0].replace(":", "") + ': ' + ' '.join(dlist[3:]).replace(":", ""), True) elif dlist[1].strip() == 'INVITE': self.msg( self.logchan_pm, '[Invite] ' + dlist[0].replace(":", "") + ': ' + dlist[3].replace(":", ""), True) elif tools.isChan(dlist[2], True): if dlist[1].strip() == 'PART' and dlist[0].strip( ).startswith(":" + self.nick): if len(dlist) > 3: self.msg( self.logchan_pm, '[Part] ' + dlist[0].replace(":", "") + ': (' + dlist[2] + ') ' + ' '.join(dlist[3:]).replace(":", ""), True) else: self.msg( self.logchan_pm, '[Part] ' + dlist[0].replace(":", "") + ': (' + dlist[2] + ')', True) elif dlist[1].strip() == 'KICK' and dlist[3].strip( ) == self.nick: if len(dlist) > 3: self.msg( self.logchan_pm, '[Kick] ' + dlist[0].replace(":", "") + ': (' + dlist[2] + ') ' + ' '.join(dlist[4:]).replace(":", ""), True) else: self.msg( self.logchan_pm, '[Kick] ' + dlist[0].replace(":", "") + ': (' + dlist[2] + ') ', True) elif dlist[1].strip() == 'PRIVMSG' and dlist[2].strip( ) != self.logchan_pm and currnick.match(' '.join( dlist[3:])): self.msg( self.logchan_pm, '[Ping] ' + dlist[0].replace(':', '') + ': (' + dlist[2] + ') ' + ' '.join(dlist[3:]).replace(":", ""), True) self.buffer = '' # print line if line.startswith(':'): source, line = line[1:].split(' ', 1) else: source = None if ' :' in line: argstr, text = line.split(' :', 1) args = argstr.split() args.append(text) else: args = line.split() text = args[-1] origin = Origin(self, source, args) self.dispatch(origin, tuple([text] + args)) if args[0] == 'PING': self.write(('PONG', text))
def new_Join_Hostmask(kenni, input): if not input.sender or not tools.isChan(input.sender, False): return kenni.set_hostmask(input.nick.lower(), input.host) kenni.set_ident(input.nick.lower(), input.user)
def nws_lookup(kenni, input): ''' Look up weather watches, warnings, and advisories. ''' text = input.group(2) if not text: return kenni.say('You need to provide some input.') bits = text.split(',') master_url = False if len(bits) == 2: ## county given county = bits[0] state = bits[1] url_part1 = 'https://alerts.weather.gov' state = (state).strip().lower() county = (county).strip().lower() reverse_lookup = list() if len(state) == 2: reverse_lookup = [k for k, v in states.items() if v == state] if reverse_lookup: state = reverse_lookup[0] if state not in states and len(reverse_lookup) < 1: kenni.say('State not found.') return url1 = county_list.format(states[state]) page1 = web.get(url1).split('\n') prev1 = str() prev2 = str() url_part2 = str() for line in page1: mystr = '>' + str(county) + '<' if mystr in line.lower(): url_part2 = prev2[9:40] break prev2 = prev1 prev1 = line if not url_part2: return kenni.say('Could not find county.') master_url = 'https://alerts.weather.gov/cap/' + url_part2 location = text elif len(bits) == 1: ## zip code if bits[0]: zip_code = bits[0] zips = re_zip.findall(zip_code) if not zips: return kenni.say('ZIP is invalid.') else: try: zip_code = zips[0][0] except: return kenni.say('ZIP could not be validated.') urlz = zip_code_lookup.format(zip_code) pagez = web.get(urlz) fips = re_fips.findall(pagez.decode('utf-8', "ignore")) if fips: state = re_state.findall(pagez.decode('utf-8', "ignore")) city = re_city.findall(pagez.decode('utf-8', "ignore")) if not state and not city: return kenni.say('Could not match ZIP code to a state') try: state = state[0].lower() state = states[state].upper() location = city[0] + ', ' + state fips_combo = str(state) + 'C' + str(fips[0]) master_url = alerts.format(fips_combo) except: return kenni.say( 'Could not parse state or city from database.') else: return kenni.say('ZIP code does not exist.') if not master_url: return kenni.say( 'Invalid input. Please enter a ZIP code or a county and state pairing, such as \'Franklin, Ohio\'' ) feed = feedparser.parse(master_url) warnings_dict = dict() for item in feed.entries: if nomsg[:51] == colourize(item['title']): return kenni.say(nomsg.format(location)) else: warnings_dict[colourize(str(item['title']))] = str(item['summary']) if len(warnings_dict) > 0: ## if we have any alerts... ## let us sort it so the most recent thing is first, then second, etc... warn_keys = list(warnings_dict.keys()) find_issue = re.compile('issued (\S+) (\S+) at (\S+):(\S+)(\S)M') warn_keys_dt = dict() for warn in warn_keys: warn_dt = find_issue.findall(warn) if len(warn_dt) > 0: warn_dt = warn_dt[0] month = months[warn_dt[0]] day = int(warn_dt[1]) hour = int(warn_dt[2]) minute = int(warn_dt[3]) if warn_dt[-1] == 'P': if hour < 12: hour += 12 year = datetime.datetime.now().year hour -= 1 warn_keys_dt[warn] = datetime.datetime(year, month, day, hour, minute) warn_list_dt = sorted(warn_keys_dt, key=warn_keys_dt.get, reverse=True) #print 'warn_list_dt', warn_list_dt if tools.isChan(input.sender, False) and not (input.group(1)).startswith('nws-more'): ## if queried in channel for key in warn_list_dt: kenni.say(key) kenni.say(more_info.format(location, master_url)) else: ## if queried in private message for key in warn_list_dt: kenni.say(key) kenni.say(warnings_dict[key]) kenni.say(more_info.format(location, master_url))
def f_spamDet(cenni, input): text = input.group(1) if not tools.isChan(input.sender, True): return kickstr = "KICK" if useRemove(cenni, input.sender): kickstr = "REMOVE" spamregexes = [] spamkickmsg = [] spamregexes.append('.*just posted this.*freenode blog') spamkickmsg.append('Propoganda Spam') spamregexes.append( 'After the acquisition by Private Internet Access, Freenode is now being used' ) spamkickmsg.append('Propoganda Spam') spamregexes.append('b(L|I)og (where|by) freenode staff member') spamkickmsg.append('Propoganda Spam') spamregexes.append('freenode pedophilia scanda(l|I)') spamkickmsg.append('Propoganda Spam') spamregexes.append( 'Read what (i|l)rc (i|l)nvest(l|i)gat(l|i)ve journa[l|i][l|i]sts') spamkickmsg.append('Propoganda Spam') spamregexes.append('A fasc[i|l]nat[i|l]ng b[i|l]og where freenode staff') spamkickmsg.append('Propoganda Spam') spamregexes.append('A(L|I)+ to(L|I)d, handshake a(L|I)ms to g(L|I)ve') spamkickmsg.append('Propoganda Spam') spamregexes.append('freenode is reg(I|L)stered.*by guarantee without') spamkickmsg.append('Propoganda Spam') spamregexes.append('with our irc ad service') spamkickmsg.append('Ad Spam') spamregexes.append('wqz') spamkickmsg.append('Link Spam') spamregexes.append('LRH') spamkickmsg.append('Link Spam') spamregexes.append('ADn2IJnTRyM') spamkickmsg.append('Link Spam') spamregexes.append('A[il]+ah [li]s do[li]ng') spamkickmsg.append('Religious Spam') spamregexes.append('(moon|sun) [li]s not do[li]ng') spamkickmsg.append('Religious Spam') spamregexes.append( '(stars|p[li]anets|ga[li]ax[li]es|oceans) are not doing') spamkickmsg.append('Religious Spam') spamregexes.append('([^A-Za-z0-9 ]{2,} ){2,}') spamkickmsg.append('Graffiti Spam') spamregexes.append('.*▄.*▄.*') spamkickmsg.append('Graffiti Spam') spamregexes.append(' {4,}') spamkickmsg.append('Line Spam') spamregexes.append('[A-Za-z0-9]{25,}') spamkickmsg.append('Line Spam') spamregexes.append('( [A-Za-z0-9]){4,}') spamkickmsg.append('Line Spam') msg2 = tools.removeFormatting(text) msg2 = tools.replaceUnicode(msg2) print("[Filter] " + msg2) nicks = 0 if spamDetConfig(cenni, input.sender): for i in range(0, len(spamregexes)): if re.search(spamregexes[i], msg2, re.IGNORECASE): cenni.write( [kickstr, input.sender, input.nick, ' :', spamkickmsg[i]]) if cenni.logchan_pm: cenni.msg( cenni.logchan_pm, '[' + spamkickmsg[i] + '] ' + input.nick + '!' + input.user + '@' + input.host + ': [' + input.sender + '] ' + msg2) return for i in msg2.split(" "): if i.lower() in cenni.users[input.sender]: print(i) nicks = nicks + 1 if nicks >= 4: cenni.write([ kickstr, input.sender, input.nick, " :Mass Highlight Spam" ]) if cenni.logchan_pm: cenni.msg( cenni.logchan_pm, '[Mass Highlight Spam] ' + input.nick + '!' + input.user + '@' + input.host + ': [' + input.sender + '] ' + msg2) return
def hostmask_on_join(kenni, input): if not input.mode or not tools.isChan(input.mode, False): return kenni.set_hostmask(input.other2.lower(), input.names) kenni.set_ident(input.other2.lower(), input.mode_target)