def check_message(word, word_eol, userdata): nick = word[0] line = word[1] if nick == '\x0326fijal': nick = ' fijal' xchat.emit_print("Channel Message", nick, line) return xchat.EAT_XCHAT
def do_endwas(word, word_eol, userdata): """Display error if nickname cannot be resolved""" for p in pending: if p.target == word[3]: xchat.emit_print("Server Error", "%s could not be found" % p.target) pending.remove(p)
def translate_cm_cb(word, word_eol, userdata): global custom_emit if(custom_emit): return xchat.EAT_NONE result = translate(word[1],word[0],'incoming') translation = result[0] if(translation != None): if(pyVersion >= 3): translation = translation.decode('utf-8') if(displayMode == 'both'): text = '--- Original ---\n'+word[1]+'\n--- Translation ---\n'+translation elif(displayMode == 'replace'): text = translation elif(displayMode == 'compressed'): text = word[1]+'\napertium '+result[1][0]+'-'+result[1][1]+': '+translation else: text = word[1] custom_emit = True xchat.emit_print('Channel Message', word[0], text.replace('\t',' ')) custom_emit = False return xchat.EAT_ALL
def whois_callback(word, word_eol, userdata): global capture_whois if capture_whois: return xchat.EAT_NONE # Response format: # :server 311 yournick othersnick ~othersuser others/host * :Other's Realname _, _, _, nickname, username, host = word[0:6] raw_real_name = word_eol[7][1:] # Get the real name without pronouns. If they don't have their pronouns # specified in their WHOIS information, it simply shows their real name # string as-is. real_name = strip_pronouns(raw_real_name) # Get their pronouns, or None. pronouns = get_pronouns(raw_real_name) # Print the first line of the WHOIS response, sans pronouns snippet at the end, # exactly how XChat would print it otherwise. xchat.emit_print("WhoIs Name Line", nickname, username, host, real_name) # Print their pronouns as the second line of the WHOIS information, # if they specified anything. Otherwise, do nothing. if pronouns is not None: xchat.emit_print("WhoIs Identified", nickname, "Pronouns: " + pronouns) # Stop XChat from printing the default first WHOIS line. return xchat.EAT_XCHAT
def run(self): """Perform our actions""" if debug: xchat.emit_print('Server Text', "Running " + str(self)) kwargs = dict(self.__dict__.items()) if self.do_bans: xchat.emit_print('Server Text', "Bans matching %s!%s@%s (r:%s, a:%s)" % (self.target_nick, self.target_ident, self.target_host, self.target_name, self.target_account)) if self.do_unban or self.do_bans: for b in bans[self.channel]: if self.match(b): if self.do_bans: xchat.emit_print('Server Text', b) else: self.actions.append('mode %s -b %s' % (self.channel, b)) for b in quiets[self.channel]: if self.match(b): if self.do_bans: xchat.emit_print('Server Text', b + ' (quiet)') else: self.actions.append('mode %s -q %s' % (self.channel, b)) # Perform all registered actions for action in self.actions: if '%(target_account)s' in action and not self.target_account: xchat.emit_print('Server Text', "Can't do an account ban for %s, not identified" % self.target_nick) continue self.context.command(action % kwargs) self.done()
def schedule(self, update_stamp=False): """Request information and add ourselves to the queue""" if debug: xchat.emit_print('Server Text', "Scheduling " + str(self)) if update_stamp: self.stamp = time.time() pending.append(self) # Am I opped? self.am_op = False for user in self.context.get_list('users'): if user.nick == self.me and user.prefix == '@': self.am_op = True self.deop = False if self.needs_op and not self.am_op: self.context.command("chanserv op %s" % self.channel) # Find needed information if ('a' in self.bans or 'r' in self.bans) and valid_mask(self.target) and not self.target.startswith('$'): xchat.emit_print('Server Error', "Invalid argument %s for account/realname ban" % self.target) return xchat.EAT_ALL if self.do_ban or self.do_unban or self.do_bans: self.resolve_nick() else: self.target_nick = self.target if self.do_unban or self.do_bans: self.fetch_bans() run_pending() return xchat.EAT_ALL
def done(self): """Finaliazation and cleanup""" # Done! if debug: xchat.emit_print('Server Text', "Done " + str(self)) pending.remove(self) # Deop? if not self.am_op or not self.needs_op: return for p in pending: if p.channel == self.channel and p.needs_op or not p.deop: self.deop = False break if self.deop: self.context.command("chanserv deop %s" % self.channel) # Schedule removal? if self.timer and (self.channel not in can_do_akick or self.banmode == 'q'): action = Action(self.channel, self.me, self.context) action.deop = self.deop action.actions = [x.replace('+','-',1) for x in self.actions] action.target = self.target action.target_nick = self.target_nick action.target_ident = self.target_ident action.target_host = self.target_host action.target_name = self.target_name action.target_name_bannable = self.target_name_bannable action.target_account = self.target_account action.resolved = True action.banmode = self.banmode action.needs_op = True xchat.hook_timer(self.timer * 1000, lambda act: act.schedule(update_stamp=True) and False, action)
def schedule(self, update_stamp=False): """Request information and add ourselves to the queue""" if debug: xchat.emit_print('Server Text', "Scheduling " + str(self)) if update_stamp: self.stamp = time.time() pending.append(self) # Am I opped? self.am_op = False for user in self.context.get_list('users'): if user.nick == self.me and user.prefix == '@': self.am_op = True self.deop = False if self.needs_op and not self.am_op: self.context.command("chanserv op %s" % self.channel) # Find needed information if ('a' in self.bans or 'r' in self.bans) and valid_mask( self.target) and not self.target.startswith('$'): xchat.emit_print( 'Server Error', "Invalid argument %s for account/realname ban" % self.target) return xchat.EAT_ALL if self.do_ban or self.do_unban or self.do_bans: self.resolve_nick() else: self.target_nick = self.target if self.do_unban or self.do_bans: self.fetch_bans() run_pending() return xchat.EAT_ALL
def colour_words(word, word_eol, userdata): " Recolour some users's messages " del(userdata) # shoosh, pylint # if the incoming message is ":nick!name@host PRIVMSG :message payload" # then word = ["nick","message payload"] # and word_eol = ["nick message payload", "message payload"] # word_eol omits '!name@host PRIVMSG :' but does NOT break the message # payload on whitespace, like it does with '/command'. Weird. nick = word[0] mesg = word[1] old_mesg = mesg for high in HIGHLIGHTS: mesg = high[0].sub(r'%s\1%s' % (high[1], MIRC_COLOUR_RESET), mesg) if mesg == old_mesg : # no change, maybe because we've already seen it return xchat.EAT_NONE else: # I had to go to the GUI to dig out the params for 'Channel Message' # why is this not documented? And why is "mode char" unused, but # "identified text" is where I expect the user's mode char to be? # Channel Message - 1:Nickname, 2:The text, 3:Mode char, 4:Identified text # Result - %C18%H<%H$4$1%H>%H%O$t$2 xchat.emit_print("Channel Message", nick, mesg, nick_to_prefix(nick), '') return xchat.EAT_ALL return xchat.EAT_NONE
def cocktography_cb(word, word_eol, userdata): text = RE_cocks.search(word[1]) if not text: return xchat.EAT_NONE message = text.group(0) if message.startswith(choder.START) or message.startswith(choder.MARK): history = '' if word[0] in buffer: history = buffer[word[0]] if message.endswith(choder.STOP): if message.startswith( choder.START): # we have a single line enchoded message dechoded, _ = choder.dechode(message) formatted = RE_cocks.sub(dechoded, word[1]) xchat.emit_print("Channel Message", '\0034\002\037' + word[0] + '\0034\002\037', formatted.encode('utf-8'), "") return xchat.EAT_XCHAT else: enchoded = "{} {}".format(history, message) if history else message dechoded, _ = choder.dechode(enchoded) formatted = RE_cocks.sub(dechoded, word[1]) del buffer[word[0]] xchat.emit_print("Channel Message", '\0034\002\037' + word[0] + '\0034\002\037', formatted.encode('utf-8'), "") return xchat.EAT_XCHAT else: buffer[word[0]] = "{} {}".format(history, message) if history else message return xchat.EAT_XCHAT
def messagebuffer(dunno): global list_ #Makes sure we have locked the list so that we start on a new list if we send messages during execution tmplist = list_ list_ = None #Get's the current channel, so we know where we should send messages channel = xchat.get_info('channel') #If the list is shorter than the pastelimit, just send them one by one to the irc-server if len(tmplist) <= settings['limit']: for i in tmplist: #send the actual string xchat.command("PRIVMSG %s :%s" % (channel, i)) #recreate the output from a regular message, as this is just a regular message xchat.emit_print("Your Message", xchat.get_info('nick'), i, "@") else: #Add all the lines together into a string str_ = "" for i in tmplist: str_ += i + "\n" # do the paste pastie_url = do_pastie(str_[:-1]) xchat.command("PRIVMSG %s :%s" % (xchat.get_info('channel'), pastie_url)) xchat.emit_print("Your Message", xchat.get_info('nick'), pastie_url, "@") return 0 # Return 0 so we don't repeat the timer.
def colour_words(word, word_eol, userdata): " Recolour some users's messages " del (userdata) # shoosh, pylint # if the incoming message is ":nick!name@host PRIVMSG :message payload" # then word = ["nick","message payload"] # and word_eol = ["nick message payload", "message payload"] # word_eol omits '!name@host PRIVMSG :' but does NOT break the message # payload on whitespace, like it does with '/command'. Weird. nick = word[0] mesg = word[1] old_mesg = mesg for high in HIGHLIGHTS: mesg = high[0].sub(r'%s\1%s' % (high[1], MIRC_COLOUR_RESET), mesg) if mesg == old_mesg: # no change, maybe because we've already seen it return xchat.EAT_NONE else: # I had to go to the GUI to dig out the params for 'Channel Message' # why is this not documented? And why is "mode char" unused, but # "identified text" is where I expect the user's mode char to be? # Channel Message - 1:Nickname, 2:The text, 3:Mode char, 4:Identified text # Result - %C18%H<%H$4$1%H>%H%O$t$2 xchat.emit_print("Channel Message", nick, mesg, nick_to_prefix(nick), '') return xchat.EAT_ALL return xchat.EAT_NONE
def ShowPlaylist (self, start=0, maxlength=250): """ Display content of the playlist """ tracklist = self.Bmp.GetTracklist() if start < 0 or maxlength < 0 or start >= len(tracklist): xchat.emit_print('Motd', 'Out of range! There are only %d tracks in the playlist' % int(len(tracklist)-1)) return False x = len(str(len(tracklist))) if maxlength > len(tracklist): maxlength = len(tracklist) - start for track in xrange(start, start+maxlength): label = '' meta = self.Bmp.GetMetadataForListItem(track) if self.TupleKeyTest(meta, 'location'): if 'file://' in meta['location']: if self.TupleKeyTest(meta, 'artist') and self.TupleKeyTest(meta, 'artist') != '': label = meta['artist'].encode('utf8') + ' - ' if self.TupleKeyTest(meta, 'title'): label += meta['title'].encode('utf8') if label == '': label = meta['location'] elif 'http://' in meta['location'] and self.TupleKeyTest(meta, 'title'): label = meta['title'] # Using markups makes XChat-Python plugin go crazy and segfault sometimes print self.XChatColors(self.DecodePalette('%P1[%P1%P4%*d%P4%P1]%P1 %P5%s%P5')) % (x, track, label) if (track - start) >= maxlength: break # Solved most of the instability problem by giving it a nice sleep delay sleep(0.14)
def ShowMatchingTracks (self, name, maxlength=500): """ Display tracks matching name """ x = len(str(len(self.Bmp.GetTracklist()))) xchat.emit_print('Notice', self.Bmp.Identity(), self.XChatColors('%USearching for "%s":%U (This can take a while)') % name) matchdict = self.FindMatchingTracks(name, maxlength) if len(matchdict) > 0: for trackid in matchdict: label = '' meta = self.Bmp.GetMetadataForListItem(trackid) if self.TupleKeyTest(meta, 'location'): if 'file://' in meta['location']: if self.TupleKeyTest(meta, 'artist') and self.TupleKeyTest(meta, 'artist') != '': label = meta['artist'] + ' - ' if self.TupleKeyTest(meta, 'title') and self.TupleKeyTest(meta, 'artist') != '': label += meta['title'] if label == '': label = meta['location'] elif 'http://' in meta['location'] and self.TupleKeyTest(meta, 'title'): label = meta['title'] # Using markups makes XChat-Python plugin go crazy and segfault sometimes print self.XChatColors(self.DecodePalette('%P1[%P1%P4%*d%P4%P1]%P1 %P5%s%P5')) % (x, trackid, label) # Solved most of the instability problem by giving it a nice sleep delay sleep(0.14) else: xchat.emit_print('Notice', self.Bmp.Identity(), self.XChatColors('%C4Found nothing%C4'))
def decolor_cb(word, word_eol, userdata, attributes): # Fast ignore any irrelevant lines, also ignores any messages we emit if not (word[1].startswith('\x03') and word[1].count('\x03') == 1): return # Emit the new line xchat.emit_print(userdata, word[0], rm_color(word[1]), *word[2:]) # And eat all, so other plugins don't get double lines return xchat.EAT_ALL
def nonotify_callback(word, word_eol, userdata): if xchat.get_info("channel") in channel_list: xchat.emit_print( 'Channel Message', '%s%s' % (red, word[0]), '%sNotification Suppressed: %s%s' % (green, red, word[1])) return xchat.EAT_ALL else: return xchat.EAT_NONE
def print_msg(arg1, arg2, arg3, arg4): global channel cnc = None arg3 = str_decode(arg3) cnc = xchat.find_context(channel='#%s'%channel) if cnc is not None: cnc.emit_print(arg1, arg2, arg3, arg4) else: xchat.emit_print(arg1, arg2, arg3, arg4)
def keyword_highlight(privmsg, privmsg_slice, xchat_data): user = privmsg[0].split('!')[0][1:] privmsg[3] = privmsg[3][1:] msg = privmsg[3:] for word in enumerate(msg): if word[1].strip(punctuation) in KEYWORDS: msg[word[0]] = '\002' + word[1] + '\002' xchat.emit_print('Channel Message', user, ' '.join(i for i in msg)) return xchat.EAT_XCHAT
def ToggleRepeat (self): """ Toggle repeat mode """ if self.Bmp.RepeatGet(): self.Bmp.RepeatSet(False) mode = 'off' else: self.Bmp.RepeatSet(True) mode = 'on' xchat.emit_print('Notice', self.Bmp.Identity(), 'Repeat mode is now: %s' % mode)
def ToggleShuffle (self): """ Toggle shuffle mode """ if self.Bmp.ShuffleGet(): self.Bmp.ShuffleSet(False) mode = 'off' else: self.Bmp.ShuffleSet(True) mode = 'on' xchat.emit_print('Notice', self.Bmp.Identity(), 'Shuffle mode is now: %s' % mode)
def run(self): """Perform our actions""" if debug: xchat.emit_print('Server Text', "Running " + str(self)) kwargs = dict(self.__dict__.items()) if self.do_bans: xchat.emit_print( 'Server Text', "Bans matching %s!%s@%s (r:%s, a:%s)" % (self.target_nick, self.target_ident, self.target_host, self.target_name, self.target_account)) if self.do_unban or self.do_bans: for b in bans[self.channel]: if self.match(b): if self.do_bans: xchat.emit_print('Server Text', b) else: if '$# akick' in b: b = b[:b.find('$#')] if b.endswith('!*@*'): b = b[:-4] self.actions.append('quote cs akick %s del %s' % (self.channel, b)) else: self.actions.append('mode %s -b %s' % (self.channel, b)) for b in quiets[self.channel]: if self.match(b): if self.do_bans: xchat.emit_print('Server Text', b + ' (quiet)') else: self.actions.append('mode %s -q %s' % (self.channel, b)) # Perform all registered actions for action in self.actions: if '%(target_account)s' in action and not self.target_account: xchat.emit_print( 'Server Text', "Can't do an account ban for %s, not identified" % self.target_nick) continue action = action % kwargs if self.channel in can_do_akick and self.timer and ' +b ' in action: timer = math.ceil(self.timer / 60.0) ban = action.split()[-1] self.context.command("chanserv akick %s ADD %s !T %d" % (self.channel, ban, timer)) else: self.context.command(action) self.done()
def irc_speak(word, word_eol, users): """Checks to see if a user is set to be voiced, and if so synthesizes their text""" if word[0] in options: # check to see if the user is in the options dictionary (word[0] == their nick) [espeak.set_parameter(aliases[arg], options[word[0]]["args"][arg]) for arg in options[word[0]]["args"]] # options[word[0]]["args"][arg] is the same as options[nickname]["args"][arg] (where arg is some one of the names in aliases # which corresponds to some integer value in options[nick][args]) espeak.set_voice(name=options[word[0]]["language"]) espeak.synth(word[1]) xchat.emit_print("Channel", word[0], word[1]) return xchat.EAT_NONE return xchat.EAT_NONE # return nothing because they weren't in the options dictionary
def decolor_cb(word, word_eol, event, attr): global edited #Ignore our own events, bouncer playback, empty messages if edited or attr.time or not len(word) > 1: return result = stripper.match(word[1]) if result: edited = True xchat.emit_print(event,word[0],result.group(1),*word[2:]) edited = False return xchat.EAT_ALL
def test_cb(word, word_eol, userdata): global FLAG if FLAG == 0 and m.currentState == "MSGSTATE_ENCRYPTED": FLAG = 1 m.t0 = time.clock() f = open('myfile.dat', 'w+') f.write(str(m.t0)) print str(m.t0) xchat.emit_print("Channel Message", xchat.get_prefs("irc_nick1"), word_eol[0], "@") encrypted_broadcast(xchat.get_list("users"), word_eol[0], m.groupkey) return xchat.EAT_ALL
def chanmessage(word, word_eol, userdata): nick = word[0] message = word[1] if (xchat.nickcmp(xchat.strip(nick), "B") == 0 or xchat.nickcmp(xchat.strip(nick), "BridgeBabe") == 0) and message.startswith("("): name = "." + message[1:message.index(')')] message = message[message.index(')') + 2:] mode = name[1] if name[1] in "@+&~%" else "" xchat.emit_print(userdata, name, message, mode) return xchat.EAT_ALL return xchat.EAT_NONE
def decolor_cb(word, word_eol, event, attr): global edited #Ignore our own events, bouncer playback, empty messages if edited or attr.time or not len(word) > 1: return result = stripper.match(word[1]) if result: edited = True xchat.emit_print(event, word[0], result.group(1), *word[2:]) edited = False return xchat.EAT_ALL
def enchode_cb(word, word_eol, userdata): input = word_eol[1][:150] s = choder.enchode(input, 2, 340) buffer["input"] = s.splitlines() for dongs in buffer["input"]: xchat.get_context().command('say ' + dongs) del buffer["input"] xchat.emit_print( "Channel Message", '\0034\002\037' + xchat.get_info('nick') + '\0034\002\037', input, "") return xchat.EAT_XCHAT
def ToggleMute (self): """ Toggle volume mute on/off """ if not self.mute_state: self.volume_state = int(self.Bmp.VolumeGet()) self.Bmp.VolumeSet(int(0)) self.mute_state = True xchat.emit_print('Notice', self.Bmp.Identity(), 'Audio output is muted') elif self.mute_state: self.Bmp.VolumeSet(int(self.volume_state)) self.mute_state = False xchat.emit_print('Notice', self.Bmp.Identity(), 'Audio output is unmuted')
def acceptGribbleMessages(word, word_eol, event): if word[0] == 'gribble': m = re.match( r'(?i)^Request successful for user .*?\. Your challenge string is: ([a-f0-9]*)$', word[1]) if m: # Print what gribble said xchat.emit_print(event, word[0], word[1] + ' ') cs = m.group(1) #xchat.emit_print(event,'otc-gpg',"Challenge: {0}".format(cs)) resp = __clearsign(cs) # Sign the string if not resp: xchat.emit_print(event, 'otc-gpg', "Error: empty response from gpg!") xchat.emit_print(event, 'otc-gpg', resp) # Pastebin the resp url = __pastebin(data=resp) xchat.emit_print(event, 'otc-gpg', "Uploaded to {0}".format(url)) # Tell gribble xchat.command('msg gribble ;;gpg verify {0}'.format(url)) return xchat.EAT_XCHAT return xchat.EAT_NONE
def translate(word, word_eol, userdata): """This must be non-reentrable, because it is triggered by the 'Channel Message' event, but will itself trigger this event.""" nick, text = word[0:2] xchat.emit_print("Channel Message", nick, text) for pair in active_pairs: #print dark_grey("[%s]" % pair), grey(translator.translate(pair, {}, text)) xchat.emit_print("Channel Message", grey("[%s] %s" % (pair, nick)), grey(translator.translate(pair, {}, text))) return xchat.EAT_XCHAT
def decolor_cb(word, word_eol, event, attr): global edited nick = stripper.sub('', word[0]) #Ignore our own events, empty messages, and # other things that don't concern us #note: nickcmp should probably be used, but I want to stay sane #and might not work in python2 if edited or not len(word) > 1 or nick.lower() not in users.keys(): return edited = True xchat.emit_print(event, "\003{:02}{}".format(users[nick.lower()], nick), word[1], *word[2:]) edited = False return xchat.EAT_ALL
def MLQRequest (self, uri, clean, autoplay): """ Media Library Query """ uri_str = re.sub('^mlq:///\?', '', uri) newlist = [] for keys in uri_str.split('&'): newval = [] for vals in keys.split('='): newval += [string.strip(vals)] newlist += [string.join(newval, '=')] uri_str = urllib.quote('mlq:///?' + string.join(newlist, '&')) for c in [':', '?', '&', '=', '%', ]: uri_str = re.sub(urllib.quote(c), urllib.unquote(c), uri_str) xchat.emit_print('Notice', self.Bmp.Identity(), 'Adding tracks to playlist using Media Library Query:\n[ %s ]' % uri_str) self.Bmp.AddUriList([uri_str], len(self.Bmp.GetTracklist()), clean, autoplay, -1)
def SetLayout (self, arg): """ Set Layout theme """ lay = self.preference.Getint('settings', 'layout') if re.search('^list', arg, re.IGNORECASE): self.ListLayout() elif re.search('[0-9]+', arg, re.IGNORECASE): if int(arg) < len(__layout__): self.preference.Set('settings', 'layout', arg) lay = self.preference.Getint('settings', 'layout') xchat.emit_print('Motd', 'Layout nr.%d selected for track information display' % int(arg)) else: xchat.prnt('Layout value is out of range!') else: xchat.emit_print('Motd', 'Layout nr.%d selected for track information display' % int(lay))
def encode(self, word, word_eol, userdata): #print "encode", word, word_eol interlocutor = xchat.get_context().get_info("channel") sigue = False for friend in self.friends: if xchat.nickcmp(interlocutor, friend) == 0: sigue = True if not sigue: #Send text as it comes (unencrypted to a no-friend) return xchat.EAT_NONE prefix = word_eol[0][0:PREFIXSIZE] conversation = self.conversations.get(interlocutor) if prefix in PREFIXES.itervalues(): #Send text as it comes (formated for a friend) return xchat.EAT_NONE if conversation["sndpublickey"]: #Send public key, invisible to user (raw) MsgWrapper.wrap("pub", self.pubKey, interlocutor) conversation["sndpublickey"] = False if self.keys.has_key(interlocutor): text = word_eol[0] txtKey, encryptedTxt = self.cipher(text, interlocutor) if txtKey is not None: txtSignature = self.sign(txtKey) #Send key pubkey = None if conversation["publickey"] is not None: pubkey = conversation["publickey"] else: pubkey = self.keys[interlocutor] MsgWrapper.wrap("key", pubkey.encrypt(txtKey, "")[0], interlocutor) #Send signature MsgWrapper.wrap("sig", txtSignature[0], interlocutor) #Send real message encrypted raw MsgWrapper.wrap("enc", encryptedTxt, interlocutor) #Show real message unencrypted on chat screen xchat.emit_print("Your Message", self.KEY_SYMBOL + xchat.get_info("nick"), text) return xchat.EAT_ALL else: return xchat.EAT_NONE
def colorize_message(word, word_eol, userdata): """ Callback for message printing events. Scans contents of a message for both URLs and nicks and colorizes them. This colorized output is sent along to the client """ if len(word) < 2: return xchat.EAT_NONE message = word[1] # This prevents recursive printing if is_colorized(message): return xchat.EAT_NONE current_channel = xchat.get_info('channel') # Private messages - the channel is the nick if not current_channel.startswith('#'): nicks = [current_channel, xchat.get_info('nick')] else: nicks = [u.nick for u in xchat.get_list('users')] # Only perform nick coloring if the setting is enabled if color_enabled(): output = [] # Split up the message delimited by a possible nick for token in nick_pat.split(message): if token in nicks: token = colorize_string(token) output.append(token) output = ''.join(output) else: output = message # Colorize URLs for url in url_pat.findall(output): output = output.replace(url, '\037\00328%s\017' % xchat.strip(url, len(url), 3)) # This is a bit of a hack where we tag the message with a non-printing # color so we don't recurse forever if not is_colorized(output): output = '%s%s' % (output, colorize_string('')) xchat.command('gui color 2') xchat.emit_print(userdata, word[0], output) return xchat.EAT_ALL
def convert(self, word, word_eol, userdata): if self._ignore_receive: return event, pos = userdata charset = xchat.get_info('charset') if charset and charset.lower() in CHARSETS_8BIT: for p in pos: word[p] = self._convert_piece(word[p], charset) self._ignore_receive = True xchat.emit_print(event, *word) self._ignore_receive = False return xchat.EAT_ALL else: host = xchat.get_info('host') print MSG_WRONGENC % (charset, host) xchat.command('CHARSET latin1')
def check_msg(word, word_eol, userdata): server_tab = xchat.find_context(channel=server_name) if word[0] in bad_nick: return xchat.EAT_NONE if len(word_eol) > 1: for reg in regexps: r = re.compile(reg, re.IGNORECASE) if r.search(word_eol[1]): xchat.command('gui color 3') xchat.emit_print( 'Channel Msg Hilight', word[0], word[1]) server_tab.prnt('02[%s02] 05<%s> %s' % (xchat.get_info('channel'), word[0], word_eol[1])) return xchat.EAT_ALL else: continue return xchat.EAT_NONE
def run(self): """Perform our actions""" if debug: xchat.emit_print('Server Text', "Running " + str(self)) kwargs = dict(self.__dict__.items()) if self.do_bans: xchat.emit_print('Server Text', "Bans matching %s!%s@%s (r:%s, a:%s)" % (self.target_nick, self.target_ident, self.target_host, self.target_name, self.target_account)) if self.do_unban or self.do_bans: for b in bans[self.channel]: if self.match(b): if self.do_bans: xchat.emit_print('Server Text', b) else: if '$# akick' in b: b = b[:b.find('$#')] if b.endswith('!*@*'): b = b[:-4] self.actions.append('quote cs akick %s del %s' % (self.channel, b)) else: self.actions.append('mode %s -b %s' % (self.channel, b)) for b in quiets[self.channel]: if self.match(b): if self.do_bans: xchat.emit_print('Server Text', b + ' (quiet)') else: self.actions.append('mode %s -q %s' % (self.channel, b)) # Perform all registered actions for action in self.actions: if '%(target_account)s' in action and not self.target_account: xchat.emit_print('Server Text', "Can't do an account ban for %s, not identified" % self.target_nick) continue action = action % kwargs if self.channel in can_do_akick and self.timer and ' +b ' in action: timer = math.ceil(self.timer/60.0) ban = action.split()[-1] self.context.command("chanserv akick %s ADD %s !T %d" % (self.channel, ban, timer)) else: self.context.command(action) self.done()
def ircrypt_encrypt_hook(word, word_eol, userdata): global ircrypt_keys, ircrypt_ciphers, ircrypt_options, ircrypt_gpg_binary # Get context con = xchat.get_context() # Get channel and server from context channel = con.get_info('channel') server = con.get_info('server') target = '%s/%s' % (server, channel) if target in ircrypt_keys: # Get cipher cipher = ircrypt_ciphers.get('%s/%s' % (server, channel)) if not cipher: cipher = ircrypt_options['CIPHER'] # encrypt message p = subprocess.Popen([ircrypt_gpg_binary, '--batch', '--no-tty', '--quiet', '--symmetric', '--cipher-algo', cipher, '--passphrase-fd', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.stdin.write('%s\n' % ircrypt_keys[target]) p.stdin.write(word_eol[0]) p.stdin.close() encrypted = base64.b64encode(p.stdout.read()) p.stdout.close() # Get and print GPG errors/warnings err = p.stderr.read() p.stderr.close() if err: con.prnt('GPG reported error:\n%s' % err) xchat.emit_print('Your Message', xchat.get_info('nick'), word_eol[0]) # If too long for one message, split and send if len(encrypted) > MAX_PART_LEN: xchat.command('PRIVMSG %s :>CRY-1 %s' % (channel, encrypted[MAX_PART_LEN:])) # Send (rest) xchat.command('PRIVMSG %s :>CRY-0 %s' % (channel, encrypted)) return xchat.EAT_ALL
def check_message(word, word_eol, userdata): nick_with_color = word[0] line_with_color = word[1] nick = colorRe.sub("",nick_with_color) line = colorRe.sub("",line_with_color) # Maintain userList if nick in userList: userList.remove(nick) if len(userList) > 200: del userList[0] userList.append(nick) # We do not do anything with lines which already contain color-codes. # This is important to avoid infinitely re-processing the message! See below. if line != line_with_color: return xchat.EAT_NONE # I was using xchat.get_list("users") here to get an up-to-date userlist for # the channel, but it caused a memory leak! (X-Chat 2.8.6-2.1) # Iterate through all nick-like words in the message # Build up newLine along the way iterator = nickRe.finditer(line) newLine = "" reached = 0 # How much of the input string we have copied so far for match in iterator: word = match.group() # Check if the word is actually a user in the channel if word in userList: col = color_of(word) newWord = "" + str(col) + word + normal_color newLine = newLine + line[reached:match.span()[0]] + newWord reached = match.span()[1] newLine = newLine + line[reached:len(line)] newLineWithoutColor = colorRe.sub("",newLine) if (newLineWithoutColor == newLine or newLine == line_with_color): # If we didn't adjust the line, then there is no need to re-emit it. return xchat.EAT_NONE else: # Warning: This will get re-checked by check_message()! But it should # reject it next time because now the line contains color codes. xchat.emit_print("Channel Message", nick, newLine) return xchat.EAT_ALL
def SendCurrent (self, nick=None): """ Transmit current file or stream to another user or channel """ if nick: # BMP returns Uri quoted in unicode string currentUri = urllib.unquote(self.Bmp.GetCurrentUri().encode('utf8')) # DCC the current track if it's a local file if urlparse(currentUri)[0] == 'file': xchat.command('dcc send %s "%s"' % (nick, urlparse(currentUri)[2])) # Send a notice if we are playing a stream elif urlparse(currentUri)[0] == 'http': xchat.command('NOTICE %s Tune your media player to %s' % (nick, currentUri)) # We cannot send a song if we're not playing any elif currentUri == '': xchat.emit_print('Notice', self.Bmp.Identity(), 'You are not playing any song!') # A BMP Oddessey elif not nick: xchat.emit_print('Notice', self.Bmp.Identity(), 'Sorry Dave, But i cannot do that.')
def SetVolume (self, volume=None): """ Display and control BMP volume level """ try: if volume != None: volume = int(volume) if volume <= 0: self.ToggleMute() elif volume > 100: raise ValueError elif volume: self.Bmp.VolumeSet(volume) volume_level = int(round(float(self.Bmp.VolumeGet())/5)) * '|' silence_level = int(round(float(100 - self.Bmp.VolumeGet())/5)) * '-' xchat.emit_print('Notice', self.Bmp.Identity(), self.XChatColors(self.DecodePalette('%TVolume%T %P1[%P1%P6%s%P6%P5%s%P5%P1]%P1 %P4%d%%%P4')) % (volume_level, silence_level, self.Bmp.VolumeGet())) except ValueError: xchat.emit_print('Notice', self.Bmp.Identity(), 'Valid volume values are 0 to 100')
def getLocationCB(word, word_eol, userdata): if len(word) < 2: xchat.emit_print("Server Error", __module_name__.upper() + " :Not enough parameters") else: channel = xchat.get_info("channel") if channel.startswith("#"): users = xchat.get_list('users') found = False for user in users: if not xchat.nickcmp(user.nick, word[1]): found = True loc = user.host.split('@')[1] printLocationLine(word[1], loc) if not found: xchat.emit_print("Server Error", "Can't find user %s" % word[1]) else: xchat.command('whois %s' % word[1]) return xchat.EAT_ALL
def run(self): """Perform our actions""" if debug: xchat.emit_print('Server Text', "Running " + str(self)) kwargs = dict(self.__dict__.items()) if self.do_bans: xchat.emit_print( 'Server Text', "Bans matching %s!%s@%s (r:%s, a:%s)" % (self.target_nick, self.target_ident, self.target_host, self.target_name, self.target_account)) if self.do_unban or self.do_bans: for b in bans[self.channel]: if self.match(b): if self.do_bans: xchat.emit_print('Server Text', b) else: self.actions.append('mode %s -b %s' % (self.channel, b)) for b in quiets[self.channel]: if self.match(b): if self.do_bans: xchat.emit_print('Server Text', b + ' (quiet)') else: self.actions.append('mode %s -q %s' % (self.channel, b)) # Perform all registered actions for action in self.actions: if '%(target_account)s' in action and not self.target_account: xchat.emit_print( 'Server Text', "Can't do an account ban for %s, not identified" % self.target_nick) continue self.context.command(action % kwargs) self.done()
def getLocationCB(word, word_eol, userdata): all_users = not len(word) > 1 channel = xchat.get_info("channel") if channel.startswith("#"): users = xchat.get_list('users') found = False or all_users for user in users: loc = user.host.split('@')[1] if not all_users and not xchat.nickcmp(user.nick, word[1]): found = True if found: printLocationLine(user.nick, loc) if found and not all_users: break if not found: xchat.emit_print("Server Error", "Can't find user %s" % word[1]) elif not all_users: xchat.command('whois %s' % word[1]) else: xchat.emit_print("Generic Message", "@", "no username given or not in a channel") return xchat.EAT_ALL
def done(self): """Finaliazation and cleanup""" # Done! if debug: xchat.emit_print('Server Text', "Done " + str(self)) pending.remove(self) # Deop? if not self.am_op or not self.needs_op: return for p in pending: if p.channel == self.channel and p.needs_op or not p.deop: self.deop = False break if self.deop: self.context.command("chanserv deop %s" % self.channel) # Schedule removal? if self.timer and (self.channel not in can_do_akick or self.banmode == 'q'): action = Action(self.channel, self.me, self.context) action.deop = self.deop action.actions = [x.replace('+', '-', 1) for x in self.actions] action.target = self.target action.target_nick = self.target_nick action.target_ident = self.target_ident action.target_host = self.target_host action.target_name = self.target_name action.target_name_bannable = self.target_name_bannable action.target_account = self.target_account action.resolved = True action.banmode = self.banmode action.needs_op = True xchat.hook_timer( self.timer * 1000, lambda act: act.schedule(update_stamp=True) and False, action)
def catch_hilight(word, word_eol, userdata): if ONLY_AWAY: # If you are not away if xchat.get_info("away") is None: return xchat.EAT_NONE channel = xchat.get_info("channel") server = xchat.get_info("server") # used to find the context timestamp = strftime(TIME_FORMAT) nick, message = word[:2] mode = word[2] if len(word) >= 3 else "" data = { "channel": channel, "time": timestamp, "mode": mode, "nick": nick, "text": message } # Turns off automatic focusing of new tabs. xchat.command("set -quiet tab_new_to_front 0") # Opens a new window if there is none already. xchat.command("query -nofocus %s" % WINDOW_NAME) # Resets the focusing settings. xchat.command("set -quiet tab_new_to_front %d" % DEFAULT_SET_VALUE) # Fetches the context object of the window. context = xchat.find_context(server=server, channel=WINDOW_NAME) if context is not None: context.emit_print("Generic Message", OUT[userdata][0] % data, OUT[userdata][1] % data) else: # this should never happen xchat.emit_print("Generic Message", __module_name__, "Unknown error: Unable to create context object") return xchat.EAT_NONE
def colour_someone(word, word_eol, userdata): """ Recolour some users's messages If there's a match, strip out existing colour codes and put in our own """ del(userdata) # shoosh, pylint # if the incoming message is ":nick!name@host PRIVMSG :message payload" # then word = ["nick","message payload"] nick = word[0] who = nick_to_fullname(nick) chan = xchat.get_info('channel') found_who = None for i in PEOPLE: if PEOPLE[i]['regexp'].match(who): if 'channel' in PEOPLE[i] : if chan in PEOPLE[i]['channel'] : found_who = i break else: found_who = i break if found_who: colour = PEOPLE[found_who]['colour'] if isinstance(colour, int): colour = '\003%d' % colour elif colour in MIRC_COLOURS: colour = MIRC_COLOURS[colour] mesg = word_eol[1] # print('... firstchar %d lastchar %d' % (ord(mesg[0]), ord(mesg[-1]))) if mesg.startswith(colour): # probably one of ours return xchat.EAT_NONE else: mesg = colour + MIRC_COLOUR_FIND.sub('', mesg.strip()) + MIRC_COLOUR_RESET xchat.emit_print("Channel Message", nick, mesg, '', nick_to_prefix(nick)) return xchat.EAT_ALL return xchat.EAT_NONE
def cs(word, word_eol, userdata): """Main command dispatcher""" if len(word) == 1: return xchat.EAT_ALL command = word[1].lower() if command not in all_commands: return xchat.EAT_NONE args = dict(enumerate(word_eol[2:])) me = xchat.get_info('nick') action = Action(channel=xchat.get_info('channel'), me=me, context=xchat.get_context()) # The simple ones: op/voice if command in simple_commands: action.target = args.get(0, me) action.deop = (action.target != me) action.needs_op = False command = expansions.get(command, command) action.actions.append('chanserv %s %%(channel)s %%(target_nick)s' % command) return action.schedule() # Usage check if len(word) < 3: if command in all_commands: xchat.emit_print("Server Error", "Not enough arguments for %s" % command) return xchat.EAT_ALL return xchat.EAT_NONE if command in ('t', 'topic'): action.actions.append('chanserv TOPIC %%(channel)s %s' % args[0]) action.needs_op = False return action.schedule() if command in ('m', 'mode') and args[0][0] in '+=-': action.actions.append('MODE %%(channel)s %s' % args[0]) return action.schedule() if command in ('i', 'invite'): target = args[0] if target.startswith('#'): action.needs_op = False action.actions.append('chanserv INVITE %s' % target) else: if target.lower() in [ x.nick.lower() for x in action.context.get_list('users') ]: xchat.emit_print( "Server Error", "%s is already in %s" % (target, action.channel)) return xchat.EAT_ALL action.actions.append('INVITE %s %%(channel)s' % target) return action.schedule() # Kick/ban/forward/mute handling if len(word) < 4 and command in forward_commands: xchat.emit_print("Server Error", "Not enough arguments for %s" % command) return xchat.EAT_ALL # Command dispatch # Check for -nihra argument if command in ban_commands: args_start = 3 while args[0].startswith('-'): if args[0].startswith('-t'): try: action.timer = int(args[0][2:].split(None, 1)[0]) except ValueError: pass else: action.bans = args[0][1:].split(None, 1)[0] args = dict(enumerate(word_eol[args_start:])) args_start += 1 if command in ('lart', 'l'): action.bans = 'nihra' # Set target action.target = args[0].split(None, 1)[0] if not valid_nickname(action.target) and not valid_mask(action.target): xchat.emit_print("Server Error", "Invalid target: %s" % action.target) return xchat.EAT_ALL if action.bans and not valid_nickname(action.target): xchat.emit_print( "Server Error", "Ban types and lart can only be used with nicks, not with complete masks" ) return xchat.EAT_ALL if valid_mask(action.target): action.bans = 'f' if not action.bans: action.bans = 'h' # Find forward channel if command in forward_commands: action.forward_to = '$' + args[1].split(None, 1)[0] # Kludge if not valid_channel(action.forward_to[1:]): xchat.emit_print("Server Error", "Invalid channel: %s" % action.forward_to[1:]) return xchat.EAT_ALL # Check if target is there and schedule kick if command in kick_commands: if action.target.lower() not in [ x.nick.lower() for x in action.context.get_list('users') ]: xchat.emit_print( "Server Error", "%s is not in %s" % (action.target, action.channel)) return xchat.EAT_ALL action.reason = args.get(1, 'Goodbye') action.actions.append('remove %(channel)s %(target_nick)s :%(reason)s') if command in ('m', 'mute'): action.banmode = 'q' if command in ban_commands: action.do_ban = True if 'n' in action.bans: action.actions.append( 'mode %(channel)s +%(banmode)s %(target_nick)s!*@*%(forward_to)s' ) if 'i' in action.bans: action.actions.append( 'mode %(channel)s +%(banmode)s *!%(target_ident)s@*%(forward_to)s' ) if 'h' in action.bans: action.actions.append( 'mode %(channel)s +%(banmode)s *!*@%(target_host)s%(forward_to)s' ) if 'r' in action.bans: action.actions.append( 'mode %(channel)s +%(banmode)s $r:%(target_name_bannable)s%(forward_to)s' ) if 'a' in action.bans: action.actions.append( 'mode %(channel)s +%(banmode)s $a:%(target_account)s%(forward_to)s' ) if 'f' in action.bans: action.actions.append( 'mode %(channel)s +%(banmode)s %(target)s%(forward_to)s') if command in ('u', 'unban'): action.do_unban = True if command == 'bans': action.do_bans = True action.needs_op = False return action.schedule()
pending.remove(p) xchat.hook_server('406', do_endwas) def endofwhois(word, word_eol, userdata): """Process the queue after nickname resolution""" run_pending() xchat.hook_server('318', endofwhois) xchat.hook_server('369', endofwhois) xchat.hook_server( '482', lambda word, word_eol, userdata: xchat.emit_print( 'Server Error', '%s in %s' % (word_eol[4][1:], word[3]))) def do_ban(word, word_eol, userdata): """Process banlists""" channel, ban = word[3:5] if channel in collecting_bans: bans[channel].append(ban) return xchat.EAT_ALL return xchat.EAT_NONE xchat.hook_server('367', do_ban) def do_quiet(word, word_eol, userdata):
def notice(self, text): xchat.emit_print("Server Notice", text, "Hush")
def mydebug(msg): xchat.emit_print('Channel Message', 'debug', msg, '@')
def printLine(user, location): line = colordecode("%C8%B%s%O %U%s") % (user, location) xchat.emit_print("Generic Message", colordecode("%C8*%O"), line)
def test_fijal(): xchat.emit_print("Channel Message", "fijal", "hello world")