1import wx 2import irclib 3import threading 4import wx.lib.newevent 5import time 6 7(AppendMsgEvent, EVT_APPEND_MSG) = wx.lib.newevent.NewEvent() 8 9class IrcPanel(wx.Panel): 10 def __init__(self, parent, server, nick, channel): 11 wx.Panel.__init__(self, parent, -1) 12 p = wx.Panel(self) 13 ps = wx.BoxSizer(wx.HORIZONTAL) 14 p.SetSizer(ps) 15 l = wx.StaticText(p, -1, "Message:") 16 l.SetForegroundColour(wx.Color(255,255,255)) 17 ps.Add(l, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) 18 self.message = wx.TextCtrl(p, -1, '', style=wx.TE_PROCESS_ENTER) 19 self.Bind(wx.EVT_TEXT_ENTER, self.on_say, self.message) 20 ps.Add(self.message, wx.EXPAND, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) 21 b = wx.Button(p, -1, "Say") 22 self.Bind(wx.EVT_BUTTON, self.on_say, b) 23 ps.Add(b, 0, wx.ALL, 5) 24 sz = wx.BoxSizer(wx.VERTICAL) 25 self.SetSizer(sz) 26 self.area = wx.TextCtrl(self, -1, style=wx.TE_READONLY|wx.TE_MULTILINE) 27 sz.Add(self.area, wx.EXPAND, wx.EXPAND|wx.ALL, 5) 28 sz.Add(p, 0, wx.EXPAND|wx.ALL, 5) 29 self.Bind(EVT_APPEND_MSG, self.on_append) 30 self.worker = WorkerThread(self, server, nick, channel) 31 self.worker.start() 32 def on_say(self, evt): 33 self.worker.send_message(self.message.GetValue()) 34 self.message.SetValue('') 35 def on_append(self, evt): 36 self.area.AppendText("[%s] %s\n" 37 % (time.strftime("%H:%M:%S"), evt.message)) 38 def append(self, str): 39 wx.PostEvent(self, AppendMsgEvent(message = str)) 40 def Destroy(self): 41 self.worker.kill() 42 wx.Panel.Destroy(self) 43 44class WorkerThread(threading.Thread): 45 def __init__(self, panel, server, nick, channel): 46 threading.Thread.__init__(self) 47 self.ui = panel 48 self.server = server 49 self.nick = nick 50 self.realnick = nick 51 self.channel = channel 52 self.index = 0 53 self.namreply = '' 54 self.die = False 55 def kill(self): 56 self.die = True 57 self.connection.quit() 58 def run(self): 59 irc = irclib.IRC() 60 for m in filter(lambda x: x.startswith('on_'), dir(self)): 61 irc.add_global_handler(m[3:], getattr(self, m)) 62 c = irc.server() 63 self.connection = c 64 c.connect(self.server, 6667, self.nick) 65 while not self.die: 66 irc.process_once(0.2) 67 c.disconnect() 68 def send_message(self, str): 69 self.connection.privmsg(self.channel, str) 70 msg = "%s: %s" % (self.realnick, str) 71 self.ui.append(msg) 72 def on_welcome(self, c, evt): 73 self.ui.append("Welcome to channel %s on %s. Here you can ask questions about xpilot or just chat with the friendly xpilot people." % (self.channel, self.server)) 74 c.join(self.channel) 75 def on_nicknameinuse(self, c, evt): 76 self.index += 1 77 self.realnick = "%s_%d" % (self.nick, self.index) 78 c.nick(self.realnick) 79 def on_namreply(self, c, evt): 80 self.namreply += evt.arguments()[2] 81 def on_endofnames(self, c, evt): 82 msg = "Currently online: %s" % self.namreply 83 self.namreply = '' 84 self.ui.append(msg) 85 def on_privmsg(self, c, evt): 86 msg = "%s->%s: %s" % (irclib.nm_to_n(evt.source()), 87 evt.target(), evt.arguments()[0]) 88 self.ui.append(msg) 89 def on_pubmsg(self, c, evt): 90 msg = "%s: %s" % (irclib.nm_to_n(evt.source()), evt.arguments()[0]) 91 self.ui.append(msg) 92 def on_join(self, c, evt): 93 msg = "%s has joined %s" % (irclib.nm_to_n(evt.source()), evt.target()) 94 self.ui.append(msg) 95 def on_part(self, c, evt): 96 msg = "%s has left %s" % (irclib.nm_to_n(evt.source()), evt.target()) 97 self.ui.append(msg) 98 def on_quit(self, c, evt): 99 msg = "%s has quit" % irclib.nm_to_n(evt.source()) 100 self.ui.append(msg) 101 102class Frame(wx.Frame): 103 def __init__( 104 self, parent, ID, title, pos=wx.DefaultPosition, 105 size=(800,600), style=wx.DEFAULT_FRAME_STYLE): 106 wx.Frame.__init__(self, parent, ID, title, pos, size, style) 107 box = wx.BoxSizer(wx.VERTICAL) 108 box.Add(IrcPanel(self, "irc.freenode.net", "foobar", "#xpilottest"), 109 wx.EXPAND, wx.EXPAND, 0, 0) 110 self.SetSizer(box) 111 112class App(wx.App): 113 def OnInit(self): 114 frame = Frame(None, -1, "") 115 self.SetTopWindow(frame) 116 frame.Show(True) 117 return True 118 119if __name__ == '__main__': 120 app = App(0) 121 app.MainLoop() 122