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