class PesterIRC(QtCore.QThread): def __init__(self, config, window): QtCore.QThread.__init__(self) self.mainwindow = window self.config = config self.registeredIRC = False self.stopIRC = None self.NickServ = services.NickServ() self.ChanServ = services.ChanServ() def IRCConnect(self): server = self.config.server() port = self.config.port() self.cli = IRCClient(PesterHandler, host=server, port=int(port), nick=self.mainwindow.profile().handle, real_name='pcc31', blocking=True, timeout=120) self.cli.command_handler.parent = self self.cli.command_handler.mainwindow = self.mainwindow self.cli.connect() self.conn = self.cli.conn() def run(self): try: self.IRCConnect() except socket.error, se: self.stopIRC = se return while 1: res = True try: logging.debug("updateIRC()") res = self.updateIRC() except socket.timeout, se: logging.debug("timeout in thread %s" % (self)) self.cli.close() self.stopIRC = se return except socket.error, se: if self.registeredIRC: self.stopIRC = None else: self.stopIRC = se logging.debug("socket error, exiting thread") return
def main(): logging.basicConfig(level=logging.DEBUG) cli = IRCClient(MyHandler, host=HOST, port=PORT, nick=NICK)#,connect_cb=connect_cb) conn = cli.connect() i = 0 while True: if i < 1000000: i+=1 if i == 1000: print 'joining' helpers.join(cli, CHANNEL) if i == 1000000: print 'joining' helpers.join(cli, CHANNEL) helpers.msg(cli, CHANNEL, 'connected') i+=1 try: item = status_queue.get(False) print str(item.author.screen_name) if str(item.author.screen_name) != NICK: helpers.msg(cli, CHANNEL, str(item.author.screen_name)+' -- '+str(item.text)) api.update_status(str(item.author.screen_name)+' -- '+str(item.text)) except: pass conn.next() ## python 2
def connect(self): cli = IRCClient(MsgHandler, host=self.host, port=self.port, nick=self.nick, connect_cb=self.on_connect) conn = cli.connect() while self.running: conn.next()
def ircinit(): global conn global cli ## Setting IRC cli. ## logging.basicConfig(level=logging.DEBUG) cli = IRCClient(MyHandler, host=HOST, port=PORT, nick=NICK) # ,connect_cb=connect_cb) conn = cli.connect()
def main(): logging.basicConfig(level=logging.DEBUG) cli = IRCClient(MyHandler, host=HOST, port=PORT, nick=NICK, connect_cb=connect_cb) conn = cli.connect() while True: conn.next() ## python 2
class IRCInterface(threading.Thread): def __init__(self, server, port, nick, channels, msg_handler, stopped_handler): threading.Thread.__init__(self) self.must_run = True self.connected = False self.msg_handler = msg_handler self.stopped_handler = stopped_handler self.nick = nick self.host = server self.port = port self.channels = channels self.send_queue = Queue() self.channels_joined = {} for c in self.channels: self.channels_joined[c] = False self.cli = IRCClient(Handler, host=self.host, port=self.port, nick=self.nick, connect_cb=self.connect_callback) self.cli.command_handler.set_irc_interface(self) @catch_them_all def connect_callback(self, cli): self.server_connected = True def pending_channels(self): result = True for k, v in self.channels_joined.items(): if not v: result = False break return result def joined(self, channel): self.channels_joined[channel] = True info("Joined channel %s" % channel) def parted(self, channel): self.channels_joined[channel] = False info("Left channel %s" % channel) if self.must_run: self.join_channels() def connect(self): info("Connecting to server") self.server_connected = False self.conn = self.cli.connect() while not self.server_connected: if not self.must_run: raise Exception("Must stop") self.conn.next() info("Connected to server") def next(self): try: self.conn.next() except Exception, e: time.sleep(0.05) error("Couldn't process connection: %s" % e) self.connect()
class IRCInterface(threading.Thread): def __init__(self, server, port, nick, owner, channels, msg_handler, stopped_handler): threading.Thread.__init__(self) self.must_run = True self.connected = False self.server_spamcheck = False self.spamcheck_enabled = True self.msg_handler = msg_handler self.stopped_handler = stopped_handler self.nick = nick self.host = server self.port = port self.channels = channels self.owner = 'Owner:'+owner+'' self.send_queue = Queue() self.channels_joined = {} for c in self.channels: self.channels_joined[c] = False self.cli = IRCClient(Handler, host=self.host, port=self.port, nick=self.nick, connect_cb=self.connect_callback, real_name=self.owner) self.cli.command_handler.set_irc_interface(self) @catch_them_all def connect_callback(self, cli): self.server_connected = True def pending_channels(self): result = True for k,v in self.channels_joined.items(): if not v: result = False break return result def joined(self, channel): self.channels_joined[channel] = True info(2, "Joined channel %s" %channel) def parted(self, channel): self.channels_joined[channel] = False info(2, "Left channel %s" %channel) if self.must_run: self.join_channels() def connect(self): info(2, "Connecting to server") self.server_connected = False self.conn = self.cli.connect() while not self.server_connected: if not self.must_run: raise Exception("Must stop") try: self.conn.next() except Exception, e: error("Problems while connecting to IRC server: %s" %e) self.stop() self.disconnected() info(2, "Connected to server") info(3, "Setting Botmode on IRC queue") self.send_queue.put("MODE %s +B" %self.nick)
def get_connected_client(activity, host, port, nick, channels1, handler=BasicHandler): global channels channels = channels1.split(",") cli = IRCClient( handler, host=host, port=port, nick=nick, connect_cb=connect_cb) conn = cli.connect() return conn
def _start(self, widget, nick, server, channels, port): self.channels = [c.strip() for c in channels.split(",")] client = IRCClient(BasicHandler, host=server, port=port, nick=nick, connect_cb=self.connect_cb) client.get_handler().set_activity(self) self._connection = client.connect() GObject.idle_add(self._next_con) self.irc_widget = IRCWidget() self.set_canvas(self.irc_widget)
def get_connected_client(activity, host, port, nick, channels1, handler=BasicHandler): global channels channels = channels1.split(",") cli = IRCClient(handler, host=host, port=port, nick=nick, connect_cb=connect_cb) conn = cli.connect() return conn
def _start(self, widget, nick, server, channels, port): self.channels = [c.strip() for c in channels.split(",")] client = IRCClient( BasicHandler, host=server, port=port, nick=nick, connect_cb=self.connect_cb) client.get_handler().set_activity(self) self._connection = client.connect() GObject.idle_add(self._next_con) self.irc_widget = IRCWidget() self.set_canvas(self.irc_widget)
class IrcEar(Ear): def write(self, text): helpers.msg(self.client, self.config['channel'], text) def connect(self): class Handler(DefaultCommandHandler): def privmsg(self_handler, nick, chan, msg): user = nick.decode().split('!')[0] text = msg.decode() self.handle_message(user, text) def connectcb(client): helpers.join(client, self.config['channel']) self.client = IRCClient(Handler, host=self.config['host'], port=self.config['port'], nick=self.config['nick'], connect_cb=connectcb) self.connection = self.client.connect() def sync(self): next(self.connection)
class IRCMain(object): def __init__(self,server='irc.freenode.net',port=6667,channel='#i3detroit', nick='i3ircterm',realname='IRC Terminal at i3Detroit', user='******',password=None,printer=None): logger = logging.getLogger('IRCTerm.IRCMain') # setting up connection parameters self.server = server self.port = port self.channel = channel self.nick = nick self.realname = realname self.user = user self.password = password self.printer = printer self.cli = None if self.printer is None: logger.warn('No printer in use, using console instead') def connect(self): logger = logging.getLogger('IRCTerm.IRCMain.connect') if self.cli is None: logger.debug('Connecting to %s:%s as %s'%\ (self.server,self.port,self.nick)) self.cli = IRCClient(IRCHandler, host=self.server, port=self.port, nick=self.nick, connect_cb=self.connect_callback) self.cli.command_handler.printer = self.printer self.conn = self.cli.connect() else: logger.warn('Already connected...') return self.conn def connect_callback(self,cli): logger = logging.getLogger('IRCTerm.IRCMain.connect_callback') logger.debug('user %s realname %s nick %s'%\ (self.user,self.realname,self.nick)) helpers.user(self.cli,self.user,self.realname) if self.password is not None: logger.debug('Identifying %s with %s'%(self.nick,self.password)) helpers.identify(self.cli,self.password) else: logger.debug('No identify required') logger.info('Joining %s'%self.channel) helpers.join(self.cli,self.channel)
def main(): loglevel = config.get('yamms', 'loglevel') if (loglevel == "error"): logging.basicConfig(level=logging.ERROR) elif (loglevel == "info"): logging.basicConfig(level=logging.INFO) elif (loglevel == "debug"): logging.basicConfig(level=logging.DEBUG) host = config.get('yamms', 'server') port = config.getint('yamms', 'port') nick = config.get('yamms', 'nick') bot = IRCClient(BotHandler, host=host, port=port, nick=nick, connect_cb=connect_callback) conn = bot.connect() while True: conn.next() # stop sucking up the cpus! time.sleep(.1)
def _connect_and_run(self): cli = IRCClient(IRCThreadCallbackHandler, host=self.irc_host, port=self.irc_port, nick=self.irc_nick) self.ping_last_reply = time.time() self.ping_sent_at = False self.pong_queue.clear() conn = cli.connect() while True: next(conn) while len(self.cmd_queue) > 0: cmd = self.cmd_queue.popleft() target = cmd[1] msg = cmd[2] logging.info('Handling event (%s) -> (%s, %s)' % (cmd, target, msg)) helpers.msg(cli, target, msg) self._check_connection(cli) time.sleep(0.2)
class PesterIRC(QtCore.QThread): def __init__(self, config, window): QtCore.QThread.__init__(self) self.mainwindow = window self.config = config self.registeredIRC = False self.stopIRC = None self.NickServ = services.NickServ() self.ChanServ = services.ChanServ() def IRCConnect(self): server = self.config.server() port = self.config.port() self.cli = IRCClient(PesterHandler, host=server, port=int(port), nick=self.mainwindow.profile().handle, real_name='pcc31', blocking=True, timeout=120) self.cli.command_handler.parent = self self.cli.command_handler.mainwindow = self.mainwindow self.cli.connect() self.conn = self.cli.conn() def run(self): try: self.IRCConnect() except socket.error as se: self.stopIRC = se return while 1: res = True try: logging.debug("updateIRC()") res = self.updateIRC() except socket.timeout as se: logging.debug("timeout in thread %s" % (self)) self.cli.close() self.stopIRC = se return except socket.error as se: if self.registeredIRC: self.stopIRC = None else: self.stopIRC = se logging.debug("socket error, exiting thread") return else: if not res: logging.debug("false Yield: %s, returning" % res) return def setConnected(self): self.registeredIRC = True self.connected.emit() def setConnectionBroken(self): logging.debug("setconnection broken") self.reconnectIRC() #self.brokenConnection = True @QtCore.pyqtSlot() def updateIRC(self): try: res = next(self.conn) except socket.timeout as se: if self.registeredIRC: return True else: raise se except socket.error as se: raise se except StopIteration: self.conn = self.cli.conn() return True else: return res @QtCore.pyqtSlot() def reconnectIRC(self): logging.debug("reconnectIRC() from thread %s" % (self)) self.cli.close() @QtCore.pyqtSlot(PesterProfile) def getMood(self, *chums): self.cli.command_handler.getMood(*chums) @QtCore.pyqtSlot(PesterList) def getMoods(self, chums): self.cli.command_handler.getMood(*chums) @QtCore.pyqtSlot(QString, QString) def sendNotice(self, text, handle): h = str(handle) t = str(text) try: helpers.notice(self.cli, h, t) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString, QString) def sendMessage(self, text, handle): h = str(handle) textl = [str(text)] def splittext(l): if len(l[0]) > 450: space = l[0].rfind(" ", 0,430) if space == -1: space = 450 elif l[0][space+1:space+5] == "</c>": space = space+4 a = l[0][0:space+1] b = l[0][space+1:] if a.count("<c") > a.count("</c>"): # oh god ctags will break!! D= hanging = [] usedends = [] c = a.rfind("<c") while c != -1: d = a.find("</c>", c) while d in usedends: d = a.find("</c>", d+1) if d != -1: usedends.append(d) else: f = a.find(">", c)+1 hanging.append(a[c:f]) c = a.rfind("<c",0,c) # end all ctags in first part for i in range(a.count("<c")-a.count("</c>")): a = a + "</c>" #start them up again in the second part for c in hanging: b = c + b if len(b) > 0: return [a] + splittext([b]) else: return [a] else: return l textl = splittext(textl) try: for t in textl: helpers.msg(self.cli, h, t) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString, bool) def startConvo(self, handle, initiated): h = str(handle) try: helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd())) if initiated: helpers.msg(self.cli, h, "PESTERCHUM:BEGIN") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString) def endConvo(self, handle): h = str(handle) try: helpers.msg(self.cli, h, "PESTERCHUM:CEASE") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot() def updateProfile(self): me = self.mainwindow.profile() handle = me.handle try: helpers.nick(self.cli, handle) except socket.error: self.setConnectionBroken() self.mainwindow.closeConversations(True) self.mainwindow.doAutoIdentify() self.mainwindow.autoJoinDone = False self.mainwindow.doAutoJoins() self.updateMood() @QtCore.pyqtSlot() def updateMood(self): me = self.mainwindow.profile() try: helpers.msg(self.cli, "#pesterchum", "MOOD >%d" % (me.mood.value())) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot() def updateColor(self): #logging.debug("irc updateColor (outgoing)") me = self.mainwindow.profile() for h in list(self.mainwindow.convos.keys()): try: helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd())) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString) def blockedChum(self, handle): h = str(handle) try: helpers.msg(self.cli, h, "PESTERCHUM:BLOCK") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString) def unblockedChum(self, handle): h = str(handle) try: helpers.msg(self.cli, h, "PESTERCHUM:UNBLOCK") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString) def requestNames(self, channel): c = str(channel) try: helpers.names(self.cli, c) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot() def requestChannelList(self): try: helpers.channel_list(self.cli) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString) def joinChannel(self, channel): c = str(channel) try: helpers.join(self.cli, c) helpers.mode(self.cli, c, "", None) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString) def leftChannel(self, channel): c = str(channel) try: helpers.part(self.cli, c) self.cli.command_handler.joined = False except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString, QString) def kickUser(self, handle, channel): l = handle.split(":") c = str(channel) h = str(l[0]) if len(l) > 1: reason = str(l[1]) if len(l) > 2: for x in l[2:]: reason += str(":") + str(x) else: reason = "" try: helpers.kick(self.cli, h, c, reason) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString, QString, QString) def setChannelMode(self, channel, mode, command): c = str(channel) m = str(mode) cmd = str(command) if cmd == "": cmd = None try: helpers.mode(self.cli, c, m, cmd) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString) def channelNames(self, channel): c = str(channel) try: helpers.names(self.cli, c) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString, QString) def inviteChum(self, handle, channel): h = str(handle) c = str(channel) try: helpers.invite(self.cli, h, c) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot() def pingServer(self): try: self.cli.send("PING %s" % int(time())) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(bool) def setAway(self, away=True): try: if away: self.cli.send("AWAY Idle") else: self.cli.send("AWAY") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(QString, QString) def killSomeQuirks(self, channel, handle): c = str(channel) h = str(handle) try: helpers.ctcp(self.cli, c, "NOQUIRKS", h) except socket.error: self.setConnectionBroken() def quit_dc(self): helpers.quit(self.cli, _pcVersion + " <3") #def getMask(self): # This needs to be updated when our hostname is changed. # Nevermind this entire thing, actually. moodUpdated = QtCore.pyqtSignal('QString', Mood) colorUpdated = QtCore.pyqtSignal('QString', QtGui.QColor) messageReceived = QtCore.pyqtSignal('QString', 'QString') memoReceived = QtCore.pyqtSignal('QString', 'QString', 'QString') noticeReceived = QtCore.pyqtSignal('QString', 'QString') inviteReceived = QtCore.pyqtSignal('QString', 'QString') timeCommand = QtCore.pyqtSignal('QString', 'QString', 'QString') namesReceived = QtCore.pyqtSignal('QString', PesterList) channelListReceived = QtCore.pyqtSignal(PesterList) nickCollision = QtCore.pyqtSignal('QString', 'QString') myHandleChanged = QtCore.pyqtSignal('QString') chanInviteOnly = QtCore.pyqtSignal('QString') modesUpdated = QtCore.pyqtSignal('QString', 'QString') connected = QtCore.pyqtSignal() userPresentUpdate = QtCore.pyqtSignal('QString', 'QString', 'QString') cannotSendToChan = QtCore.pyqtSignal('QString', 'QString') tooManyPeeps = QtCore.pyqtSignal() quirkDisable = QtCore.pyqtSignal('QString', 'QString', 'QString')
import sys from oyoyo.client import IRCClient from constants import SETTINGS_FILE from handler import KevinBotCommandHandler # Main program if __name__ == '__main__': try: f = open(SETTINGS_FILE, 'r') settings = json.load(f) except (IOError, ValueError): print >> sys.stderr,\ ('File %s is missing or unreadable, or has an invalid format' % SETTINGS_FILE) exit(1) finally: f.close() # HACK: IRCClient.__init__ is expecting a class name that it can use to # construct a new handler object. This lambda expression allows us to # pass parameters to the handler's constructor, avoiding the need for # global variables. cli = IRCClient(lambda client: KevinBotCommandHandler(client, settings), host=settings['host'], port=settings['port'], nick=settings['nick'], blocking=True) conn = cli.connect() while True: conn.next() print 'Exiting.'
import sys from oyoyo.client import IRCClient from constants import SETTINGS_FILE from handler import KevinBotCommandHandler # Main program if __name__ == '__main__': try: f = open(SETTINGS_FILE, 'r') settings = json.load(f) except (IOError, ValueError): print >> sys.stderr,\ ('File %s is missing or unreadable, or has an invalid format' % SETTINGS_FILE) exit(1) finally: f.close() # HACK: IRCClient.__init__ is expecting a class name that it can use to # construct a new handler object. This lambda expression allows us to # pass parameters to the handler's constructor, avoiding the need for # global variables. cli = IRCClient(lambda client: KevinBotCommandHandler(client, settings), host = settings['host'], port = settings['port'], nick = settings['nick'], blocking = True) conn = cli.connect() while True: conn.next() print 'Exiting.'
class IRC: def __init__(self): self.running = False self.stopping = False self.nick_number = 0 self.channels = {} self.my_nick = "" self.client = None # FIXME: should not be hardcoded here self.default_channel = LOBBY_CHANNEL self.active_channel_name = self.default_channel self.connection = None def message(self, message, color=None): self.channel(self.active_channel_name).message(message, color) def warning(self, message): self.message(message, IRCColor.WARNING) def info(self, message): self.message(message, IRCColor.INFO) @staticmethod def is_channel(name): return len(name) > 0 and name[0] in "&#+!" def channel(self, name): # FIXME: name should be checked case independently if not name: name = self.default_channel from .channel import Channel try: return self.channels[name] except KeyError: print("new channel", repr(name)) self.channels[name] = Channel(self, name) print("channels are now", repr(self.channels)) # self.set_active_channel(name) IRCBroadcaster.broadcast("channel_list", {"added": name}) return self.channels[name] def active_channel(self): return self.channel(self.active_channel_name) def set_active_channel_name(self, name): self.active_channel_name = name IRCBroadcaster.broadcast("active_channel", {"channel": name}) def connect(self): self.start() def start(self): self.stopping = False if self.running: print("IRC.start - already running") return threading.Thread(target=self.irc_thread, name="IRCThread").start() self.running = True def stop(self): if not self.running: return self.stopping = True helpers.quit(self.client, "Exited") # self.client.quit() def irc_thread(self): try: self.irc_main() except Exception as e: def func(): self.warning(repr(e)) call_after(func) import traceback traceback.print_exc() self.running = False @staticmethod def nick(spec): nick = spec.split("!")[0] nick = nick.strip("@+") return nick def me(self, spec): nick = spec.split("!")[0] return nick == self.my_nick @staticmethod def get_irc_server_host(): return LauncherSettings.get_irc_server() def irc_main(self): def func(): self.message("connecting to {0}...".format( self.get_irc_server_host())) call_after(func) self.client = IRCClient( CommandHandler, host=self.get_irc_server_host(), port=6667, nick=self.generate_nick(True), blocking=True, connect_cb=self.connect_callback) self.client.handler = self self.connection = self.client.connect() while not self.stopping: next(self.connection) print("irc_main done") self.running = False def connect_callback(self, client): def func(): self.message("connected to {0}".format(self.get_irc_server_host())) call_after(func) def post_message(self, command, args): # command = command.decode("UTF-8", errors="replace") if self.stopping: print("ignoring message", command, "because we're stopping") return # print("post_message", command, args) # self.on_message(command, args) # print(command, args) args = list(args) # for i, arg in enumerate(args): # if arg is not None: # args[i] = arg.decode("UTF-8", errors="replace") def func(): # if IRC.broadcast(command, args): # return if self.irc_server_message(command, args): return name = "irc_" + command try: method = getattr(self, name) except AttributeError: self.info(" ".join([command] + args)) pass else: method(*args) call_after(func) def privmsg(self, destination, message): helpers.msg(self.client, destination, message) def notice(self, destination, message): self.client.send("notice {0} :{1}".format(destination, message)) def generate_nick(self, reset=False): if reset: self.nick_number = 0 self.nick_number += 1 if self.nick_number == 1: nick = LauncherSettings.get_irc_nick() else: nick = LauncherSettings.get_irc_nick() + str(self.nick_number) self.my_nick = nick return nick def append_text(self, message): self.message(message) def handle_command(self, message): if message.startswith("/"): return self.handle_command_string(message) else: if not self.active_channel_name: self.warning("no active channel") else: self.channel(self.active_channel_name).privmsg(message) def handle_command_string(self, message): message = message[1:] parts = message.split(" ") command = parts[0].lower() args = parts[1:] name = "command_" + command try: method = getattr(self, name) except AttributeError: self.warning(command + ": unknown command") return False else: method(args) return True def command_raw(self, args): if len(args) >= 1: self.client.send(" ".join(args)) else: self.warning("usage: /raw <raw irc message>") # noinspection SpellCheckingInspection def command_whois(self, args): if len(args) >= 1: self.client.send("whois {0}".format(" ".join(args))) else: self.warning("usage: /whois <nick>") def command_away(self, args): if len(args) == 0: self.client.send("away") else: self.client.send("away {0}".format(" ".join(args))) def command_back(self, args): if len(args) == 0: self.client.send("away") else: self.warning("usage: /back") def command_msg(self, args): if len(args) >= 2: channel = args[0] message = " ".join(args[1:]) # self.channel(channel).privmsg(message) # self.channel(channel).message("<{0}> {1}".format(self.my_nick, # message), IRCColor.MY_MESSAGE) self.client.send("privmsg {0} :{1}".format(channel, message)) else: self.warning("usage: /msg <nick|channel> <message>") def command_notice(self, args): if len(args) >= 2: channel = args[0] message = " ".join(args[1:]) # self.channel(channel).notice(message) self.client.send("notice {0} :{1}".format(channel, message)) else: self.warning("usage: /notice <nick|channel> <message>") # noinspection SpellCheckingInspection def command_oper(self, args): if len(args) == 2: self.client.send("oper {0} {1}".format(args[0], args[1])) else: self.warning("usage: /oper <user> <password>") def command_slap(self, args): if len(args) == 1: message = "slaps {0} around a bit with a large trout".format( args[0]) self.channel(self.active_channel_name).action(message) else: self.warning("usage: /slap <nick>") def command_me(self, args): if len(args) > 0: message = " ".join(args) self.channel(self.active_channel_name).action(message) else: self.warning("usage: /me <message>") def command_mode(self, args): if len(args) >= 2: self.client.send("mode {0}".format(" ".join(args))) else: self.warning("usage: /mode <channel|nick> <parameters...>") def command_kick(self, args): if not self.is_channel(self.active_channel_name): self.warning("cannot kick - not in a channel") return if len(args) >= 1: self.kick(self.active_channel_name, args[0], " ".join(args[1:])) else: self.warning("usage: /kick <nick> [<message>]") def kick(self, channel, nick, message="kicked"): self.client.send("KICK", channel, nick, ":{0}".format(message)) def command_join(self, args): if len(args) == 1: self.join(args[0]) else: self.warning("join: invalid arguments") def join(self, channel): helpers.join(self.client, channel) def command_leave(self, args): return self.command_part(args) def command_part(self, args): if len(args) == 1: self.part(args[0]) else: self.warning("part: invalid arguments") def part(self, channel): helpers.part(self.client, channel) # noinspection SpellCheckingInspection def irc_server_message(self, command, args): commands = [ "yourhost", "created", "luserclient", "luserchannels", "luserme", "n_local", "n_global", "luserconns", "motdstart", "motd", "nomotd", "endofmotd" ] if command in commands: self.message(args[2]) return 1 return 0 # noinspection SpellCheckingInspection def irc_featurelist(self, server, nick, *features): self.message(" ".join(features)) def irc_welcome(self, server, nick, message): self.message(message) password = LauncherSettings.get_irc_nickserv_pass() if password: self.privmsg("nickserv", "identify {0}".format(password)) self.join(LOBBY_CHANNEL) # convenience for development... for arg in sys.argv: if arg.startswith("--netplay-game="): self.join("&" + arg[15:]) break @classmethod def filter_nick(cls, full): nick = full.split("!")[0] return nick def irc_privmsg(self, sender, destination, message): nick = self.filter_nick(sender) if self.is_channel(destination): channel = destination else: channel = self.filter_nick(sender) self.channel(channel).on_privmsg(nick, message) IRCBroadcaster.broadcast("privmsg", { "channel": channel, "message": message, "nick": nick}) def irc_notice(self, sender, destination, message): if sender: nick = self.filter_nick(sender) else: nick = "(server)" if self.is_channel(destination): channel = destination else: channel = self.active_channel_name self.channel(channel).on_notice(nick, message) IRCBroadcaster.broadcast("notice", { "channel": channel, "message": message, "nick": nick}) def irc_kick(self, kicker, channel, who, why): self.channel(channel).on_kick(self.filter_nick(kicker), who, why) def irc_part(self, who, channel, *_): self.channel(channel).on_part(self.filter_nick(who)) def irc_join(self, who, channel): self.channel(channel).on_join(self.filter_nick(who)) # noinspection SpellCheckingInspection def irc_endofnames(self, sender, recipient, channel, message): pass # noinspection SpellCheckingInspection def irc_namreply(self, server, who, equals, channel, nicks): self.channel(channel).on_namreply(nicks.split(" ")) # noinspection SpellCheckingInspection def irc_currenttopic(self, sender, recipient, channel, topic): self.channel(channel).on_currenttopic(topic) # noinspection SpellCheckingInspection def irc_topicinfo(self, sender, recipient, channel, who, when): pass # noinspection SpellCheckingInspection def irc_cannotsendtochan(self, server, who, channel, message): self.channel(channel).warning("cannot send to channel: " + message) def irc_topic(self, who, channel, topic): self.channel(channel).on_topic(who, topic) def irc_mode(self, who, destination, *args): if self.is_channel(destination): self.channel(destination).on_mode(self.filter_nick(who), args) else: self.message("{0} set mode {1} {2}".format( who, destination, " ".join(args))) def irc_quit(self, who, reason): for name in self.channels: self.channel(name).on_quit(self.filter_nick(who), reason)
class IRC: def __init__(self): self.running = False self.stopping = False self.nick_number = 0 self.channels = {} self.my_nick = "" self.client = None # FIXME: should not be hardcoded here self.default_channel = LOBBY_CHANNEL self.active_channel_name = self.default_channel self.connection = None def message(self, message, color=None): self.channel(self.active_channel_name).message(message, color) def warning(self, message): self.message(message, IRCColor.WARNING) def info(self, message): self.message(message, IRCColor.INFO) @staticmethod def is_channel(name): return len(name) > 0 and name[0] in "&#+!" def channel(self, name): # FIXME: name should be checked case independently if not name: name = self.default_channel from .channel import Channel try: return self.channels[name] except KeyError: print("new channel", repr(name)) self.channels[name] = Channel(self, name) print("channels are now", repr(self.channels)) # self.set_active_channel(name) IRCBroadcaster.broadcast("channel_list", {"added": name}) return self.channels[name] def active_channel(self): return self.channel(self.active_channel_name) def set_active_channel_name(self, name): self.active_channel_name = name IRCBroadcaster.broadcast("active_channel", {"channel": name}) def connect(self): self.start() def start(self): self.stopping = False if self.running: print("IRC.start - already running") return threading.Thread(target=self.irc_thread, name="IRCThread").start() self.running = True def stop(self): if not self.running: return self.stopping = True helpers.quit(self.client, "Exited") # self.client.quit() def irc_thread(self): try: self.irc_main() except Exception as e: import traceback traceback.print_exc() # Bind exception to local variable, so the inline function below # can access it. exception = e def func(): self.warning(repr(exception)) call_after(func) self.running = False @staticmethod def nick(spec): nick = spec.split("!")[0] nick = nick.strip("@+") return nick def me(self, spec): nick = spec.split("!")[0] return nick == self.my_nick @staticmethod def get_irc_server_host(): return LauncherSettings.get_irc_server() def irc_main(self): def func(): self.message("connecting to {0}...".format( self.get_irc_server_host())) call_after(func) self.client = IRCClient(CommandHandler, host=self.get_irc_server_host(), port=6667, nick=self.generate_nick(True), blocking=True, connect_cb=self.connect_callback) self.client.handler = self self.connection = self.client.connect() while not self.stopping: next(self.connection) print("irc_main done") self.running = False def connect_callback(self, client): def func(): self.message("connected to {0}".format(self.get_irc_server_host())) call_after(func) def post_message(self, command, args): # command = command.decode("UTF-8", errors="replace") if self.stopping: print("ignoring message", command, "because we're stopping") return # print("post_message", command, args) # self.on_message(command, args) # print(command, args) args = list(args) # for i, arg in enumerate(args): # if arg is not None: # args[i] = arg.decode("UTF-8", errors="replace") def func(): # if IRC.broadcast(command, args): # return if self.irc_server_message(command, args): return name = "irc_" + command try: method = getattr(self, name) except AttributeError: self.info(" ".join([command] + args)) pass else: method(*args) call_after(func) def privmsg(self, destination, message): helpers.msg(self.client, destination, message) def notice(self, destination, message): self.client.send("notice {0} :{1}".format(destination, message)) def generate_nick(self, reset=False): if reset: self.nick_number = 0 self.nick_number += 1 if self.nick_number == 1: nick = LauncherSettings.get_irc_nick() else: nick = LauncherSettings.get_irc_nick() + str(self.nick_number) self.my_nick = nick return nick def append_text(self, message): self.message(message) def handle_command(self, message): if message.startswith("/"): return self.handle_command_string(message) else: if not self.active_channel_name: self.warning("no active channel") else: self.channel(self.active_channel_name).privmsg(message) def handle_command_string(self, message): message = message[1:] parts = message.split(" ") command = parts[0].lower() args = parts[1:] name = "command_" + command try: method = getattr(self, name) except AttributeError: self.warning(command + ": unknown command") return False else: method(args) return True def command_raw(self, args): if len(args) >= 1: self.client.send(" ".join(args)) else: self.warning("usage: /raw <raw irc message>") # noinspection SpellCheckingInspection def command_whois(self, args): if len(args) >= 1: self.client.send("whois {0}".format(" ".join(args))) else: self.warning("usage: /whois <nick>") def command_away(self, args): if len(args) == 0: self.client.send("away") else: self.client.send("away {0}".format(" ".join(args))) def command_back(self, args): if len(args) == 0: self.client.send("away") else: self.warning("usage: /back") def command_msg(self, args): if len(args) >= 2: channel = args[0] message = " ".join(args[1:]) # self.channel(channel).privmsg(message) # self.channel(channel).message("<{0}> {1}".format(self.my_nick, # message), IRCColor.MY_MESSAGE) self.client.send("privmsg {0} :{1}".format(channel, message)) else: self.warning("usage: /msg <nick|channel> <message>") def command_notice(self, args): if len(args) >= 2: channel = args[0] message = " ".join(args[1:]) # self.channel(channel).notice(message) self.client.send("notice {0} :{1}".format(channel, message)) else: self.warning("usage: /notice <nick|channel> <message>") # noinspection SpellCheckingInspection def command_oper(self, args): if len(args) == 2: self.client.send("oper {0} {1}".format(args[0], args[1])) else: self.warning("usage: /oper <user> <password>") def command_slap(self, args): if len(args) == 1: message = "slaps {0} around a bit with a large trout".format( args[0]) self.channel(self.active_channel_name).action(message) else: self.warning("usage: /slap <nick>") def command_me(self, args): if len(args) > 0: message = " ".join(args) self.channel(self.active_channel_name).action(message) else: self.warning("usage: /me <message>") def command_mode(self, args): if len(args) >= 2: self.client.send("mode {0}".format(" ".join(args))) else: self.warning("usage: /mode <channel|nick> <parameters...>") def command_kick(self, args): if not self.is_channel(self.active_channel_name): self.warning("cannot kick - not in a channel") return if len(args) >= 1: self.kick(self.active_channel_name, args[0], " ".join(args[1:])) else: self.warning("usage: /kick <nick> [<message>]") def kick(self, channel, nick, message="kicked"): self.client.send("KICK", channel, nick, ":{0}".format(message)) def command_join(self, args): if len(args) == 1: self.join(args[0]) else: self.warning("join: invalid arguments") def join(self, channel): helpers.join(self.client, channel) def command_leave(self, args): return self.command_part(args) def command_part(self, args): if len(args) == 1: self.part(args[0]) else: self.warning("part: invalid arguments") def part(self, channel): helpers.part(self.client, channel) # noinspection SpellCheckingInspection def irc_server_message(self, command, args): commands = [ "yourhost", "created", "luserclient", "luserchannels", "luserme", "n_local", "n_global", "luserconns", "motdstart", "motd", "nomotd", "endofmotd" ] if command in commands: self.message(args[2]) return 1 return 0 # noinspection SpellCheckingInspection def irc_featurelist(self, server, nick, *features): self.message(" ".join(features)) def irc_welcome(self, server, nick, message): self.message(message) password = LauncherSettings.get_irc_nickserv_pass() if password: self.privmsg("nickserv", "identify {0}".format(password)) self.join(LOBBY_CHANNEL) # convenience for development... for arg in sys.argv: if arg.startswith("--netplay-game="): self.join("&" + arg[15:]) break @classmethod def filter_nick(cls, full): nick = full.split("!")[0] return nick def irc_privmsg(self, sender, destination, message): nick = self.filter_nick(sender) if self.is_channel(destination): channel = destination else: channel = self.filter_nick(sender) self.channel(channel).on_privmsg(nick, message) IRCBroadcaster.broadcast("privmsg", { "channel": channel, "message": message, "nick": nick }) def irc_notice(self, sender, destination, message): if sender: nick = self.filter_nick(sender) else: nick = "(server)" if self.is_channel(destination): channel = destination else: channel = self.active_channel_name self.channel(channel).on_notice(nick, message) IRCBroadcaster.broadcast("notice", { "channel": channel, "message": message, "nick": nick }) def irc_kick(self, kicker, channel, who, why): self.channel(channel).on_kick(self.filter_nick(kicker), who, why) def irc_part(self, who, channel, *_): self.channel(channel).on_part(self.filter_nick(who)) def irc_join(self, who, channel): self.channel(channel).on_join(self.filter_nick(who)) # noinspection SpellCheckingInspection def irc_endofnames(self, sender, recipient, channel, message): pass # noinspection SpellCheckingInspection def irc_namreply(self, server, who, equals, channel, nicks): self.channel(channel).on_namreply(nicks.split(" ")) # noinspection SpellCheckingInspection def irc_currenttopic(self, sender, recipient, channel, topic): self.channel(channel).on_currenttopic(topic) # noinspection SpellCheckingInspection def irc_topicinfo(self, sender, recipient, channel, who, when): pass # noinspection SpellCheckingInspection def irc_cannotsendtochan(self, server, who, channel, message): self.channel(channel).warning("cannot send to channel: " + message) def irc_topic(self, who, channel, topic): self.channel(channel).on_topic(who, topic) def irc_mode(self, who, destination, *args): if self.is_channel(destination): self.channel(destination).on_mode(self.filter_nick(who), args) else: self.message("{0} set mode {1} {2}".format(who, destination, " ".join(args))) def irc_quit(self, who, reason): for name in self.channels: self.channel(name).on_quit(self.filter_nick(who), reason)
def send(self, text, **kwargs): server, channel = self.contact_info.split("/") try: server, port = server.split(":") except: port = "6667" server = server.strip().lower() channel = channel.strip() port = int(port.strip()) # for referencing in active_connectoins key = "%s:%d" % (server, port) # do we already have an existing connection? active = self.active_connections.get(key, None) if active: self.log.info("found existing connection to %s" % key) conn, client = active client.started = time.time() client.command_handler.channel_cache[channel] = self.channel client.connected_event.wait() helpers.join(client, channel) helpers.msg(client, channel, text) # or do we need a new connection? else: def connect_cb(client): self.log.info("called connect callback") client.connected_event.send() eventlet.spawn_n(join_cb, client) def join_cb(client): self.log.info("called join callback") client.got_nick_event.wait() helpers.join(client, channel) helpers.msg(client, channel, text) self.log.info("we need a new irc connection to %s", key) client = IRCClient( IRCHandler, host=server, port=port, nick="PanoptaOutage", connect_cb=connect_cb, blocking=True ) client.connected_event = eventlet.event.Event() client.got_nick_event = eventlet.event.Event() client.command_handler.channel_cache[channel] = self.channel client.command_handler.log = self.log client.command_handler.server = server client.started = time.time() client.blocking = False self.log.info("connecting to %s", key) conn = client.connect() self.active_connections[key] = (conn, client) # this will disconnect after 60 seconds def persist_in_background(): client.started = time.time() self.log.info("idling connection to %s for %d seconds" % (key, IRC.timeout)) while client.started + IRC.timeout > time.time() and conn.next(): time.sleep(0.5) self.log.info("disconnecting from %s" % key) del self.active_connections[key] quit_messages = [ "herpderp", "I want to die peacefully in my sleep, like my grandfather.. Not screaming like the passengers in his car.", "Do not argue with an idiot. He will drag you down to his level and beat you with experience.", "If I agreed with you we'd both be wrong.", "The early bird might get the worm, but the second mouse gets the cheese.", "I thought I wanted a career, turns out I just wanted paychecks.", "I didn't say it was your fault, I said I was blaming you.", ] helpers.quit(client, random.choice(quit_messages)) eventlet.spawn_n(persist_in_background) return "irc message to %s" % self.contact_info
class PesterIRC(QtCore.QThread): def __init__(self, config, window): QtCore.QThread.__init__(self) self.mainwindow = window self.config = config self.registeredIRC = False self.stopIRC = None self.NickServ = services.NickServ() self.ChanServ = services.ChanServ() def IRCConnect(self): server = self.config.server() port = self.config.port() self.cli = IRCClient(PesterHandler, host=server, port=int(port), nick=self.mainwindow.profile().handle, real_name='pcc31', blocking=True, timeout=120) self.cli.command_handler.parent = self self.cli.command_handler.mainwindow = self.mainwindow self.cli.connect() self.conn = self.cli.conn() def run(self): try: self.IRCConnect() except socket.error as se: self.stopIRC = se return while 1: res = True try: logging.debug("updateIRC()") res = self.updateIRC() except socket.timeout as se: logging.debug("timeout in thread %s" % (self)) self.cli.close() self.stopIRC = se return except socket.error as se: if self.registeredIRC: self.stopIRC = None else: self.stopIRC = se logging.debug("socket error, exiting thread") return else: if not res: logging.debug("false Yield: %s, returning" % res) return def setConnected(self): self.registeredIRC = True self.connected.emit() def setConnectionBroken(self): logging.debug("setconnection broken") self.reconnectIRC() #self.brokenConnection = True @QtCore.pyqtSlot() def updateIRC(self): try: res = next(self.conn) except socket.timeout as se: if self.registeredIRC: return True else: raise se except socket.error as se: raise se except StopIteration: self.conn = self.cli.conn() return True else: return res @QtCore.pyqtSlot() def reconnectIRC(self): logging.debug("reconnectIRC() from thread %s" % (self)) self.cli.close() @QtCore.pyqtSlot(PesterProfile) def getMood(self, *chums): self.cli.command_handler.getMood(*chums) @QtCore.pyqtSlot(PesterList) def getMoods(self, chums): self.cli.command_handler.getMood(*chums) @QtCore.pyqtSlot('QString', 'QString') def sendNotice(self, text, handle): h = str(handle) t = str(text) try: helpers.notice(self.cli, h, t) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString', 'QString') def sendMessage(self, text, handle): h = str(handle) textl = [str(text)] def splittext(l): if len(l[0]) > 450: space = l[0].rfind(" ", 0,430) if space == -1: space = 450 elif l[0][space+1:space+5] == "</c>": space = space+4 a = l[0][0:space+1] b = l[0][space+1:] if a.count("<c") > a.count("</c>"): # oh god ctags will break!! D= hanging = [] usedends = [] c = a.rfind("<c") while c != -1: d = a.find("</c>", c) while d in usedends: d = a.find("</c>", d+1) if d != -1: usedends.append(d) else: f = a.find(">", c)+1 hanging.append(a[c:f]) c = a.rfind("<c",0,c) # end all ctags in first part for i in range(a.count("<c")-a.count("</c>")): a = a + "</c>" #start them up again in the second part for c in hanging: b = c + b if len(b) > 0: return [a] + splittext([b]) else: return [a] else: return l textl = splittext(textl) try: for t in textl: helpers.msg(self.cli, h, t) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString', bool) def startConvo(self, handle, initiated): h = str(handle) try: if initiated: helpers.msg(self.cli, h, "PESTERCHUM:BEGIN") helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd())) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString') def endConvo(self, handle): h = str(handle) try: helpers.msg(self.cli, h, "PESTERCHUM:CEASE") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot() def updateProfile(self): me = self.mainwindow.profile() handle = me.handle try: helpers.nick(self.cli, handle) except socket.error: self.setConnectionBroken() self.mainwindow.closeConversations(True) self.mainwindow.doAutoIdentify() self.mainwindow.autoJoinDone = False self.mainwindow.doAutoJoins() self.updateMood() @QtCore.pyqtSlot() def updateMood(self): me = self.mainwindow.profile() try: helpers.msg(self.cli, "#pesterchum", "MOOD >%d" % (me.mood.value())) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot() def updateColor(self): me = self.mainwindow.profile() for h in self.mainwindow.convos.keys(): try: helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd())) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString') def blockedChum(self, handle): h = str(handle) try: helpers.msg(self.cli, h, "PESTERCHUM:BLOCK") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString') def unblockedChum(self, handle): h = str(handle) try: helpers.msg(self.cli, h, "PESTERCHUM:UNBLOCK") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString') def requestNames(self, channel): c = str(channel) try: helpers.names(self.cli, c) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot() def requestChannelList(self): try: helpers.channel_list(self.cli) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString') def joinChannel(self, channel): c = str(channel) try: helpers.join(self.cli, c) helpers.mode(self.cli, c, "", None) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString') def leftChannel(self, channel): c = str(channel) try: helpers.part(self.cli, c) self.cli.command_handler.joined = False except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString', 'QString') def kickUser(self, handle, channel): l = handle.split(":") c = str(channel) h = str(l[0]) if len(l) > 1: reason = str(l[1]) if len(l) > 2: for x in l[2:]: reason += str(":") + str(x) else: reason = "" try: helpers.kick(self.cli, h, c, reason) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString', 'QString', 'QString') def setChannelMode(self, channel, mode, command): c = str(channel) m = str(mode) cmd = str(command) if cmd == "": cmd = None try: helpers.mode(self.cli, c, m, cmd) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString') def channelNames(self, channel): c = str(channel) try: helpers.names(self.cli, c) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString', 'QString') def inviteChum(self, handle, channel): h = str(handle) c = str(channel) try: helpers.invite(self.cli, h, c) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot() def pingServer(self): try: self.cli.send("PING %s" % int(time())) except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot(bool) def setAway(self, away=True): try: if away: self.cli.send("AWAY Idle") else: self.cli.send("AWAY") except socket.error: self.setConnectionBroken() @QtCore.pyqtSlot('QString', 'QString') def killSomeQuirks(self, channel, handle): c = str(channel) h = str(handle) try: helpers.ctcp(self.cli, c, "NOQUIRKS", h) except socket.error: self.setConnectionBroken() moodUpdated = QtCore.pyqtSignal('QString', Mood) colorUpdated = QtCore.pyqtSignal('QString', QtGui.QColor) messageReceived = QtCore.pyqtSignal('QString', 'QString') memoReceived = QtCore.pyqtSignal('QString', 'QString', 'QString') noticeReceived = QtCore.pyqtSignal('QString', 'QString') inviteReceived = QtCore.pyqtSignal('QString', 'QString') timeCommand = QtCore.pyqtSignal('QString', 'QString', 'QString') namesReceived = QtCore.pyqtSignal('QString', PesterList) channelListReceived = QtCore.pyqtSignal(PesterList) nickCollision = QtCore.pyqtSignal('QString', 'QString') myHandleChanged = QtCore.pyqtSignal('QString') chanInviteOnly = QtCore.pyqtSignal('QString') modesUpdated = QtCore.pyqtSignal('QString', 'QString') connected = QtCore.pyqtSignal() userPresentUpdate = QtCore.pyqtSignal('QString', 'QString', 'QString') cannotSendToChan = QtCore.pyqtSignal('QString', 'QString') tooManyPeeps = QtCore.pyqtSignal() quirkDisable = QtCore.pyqtSignal('QString', 'QString', 'QString')