ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/ns_dev/Python/NinoCode/Active_prgs/Nino_Chat.py
Revision: 8
Committed: Sat May 5 04:21:19 2012 UTC (13 years, 10 months ago) by ninoborges
Content type: text/x-python
File size: 8497 byte(s)
Log Message:
Initial Import

File Contents

# User Rev Content
1 ninoborges 8 #Chat program
2    
3     from wxPython.wx import *
4     import socket,string,sys,thread,select
5    
6     ID_EXIT=101
7     ID_CONNECT=102
8     ID_DISCONNECT=103
9     ID_STARTS=104
10     ID_INPUT=105
11     ID_CBUTTON=105
12    
13     class MySocket(wxFrame):
14     def __init__(self,window):
15     self.window=window
16     self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
17     self.peer=None
18     self.is_server=0
19    
20     def start(self,bind_server=None):
21     """
22     Start the socket's activity, and set it up to be a server or
23     a client with the optional argument.
24     """
25    
26     if bind_server:
27     self.is_server=1
28     try:
29     self.sock.bind(bind_server)
30     except: return 0
31     self.sock.listen(1)
32     self.keep_running=1
33     thread.start_new_thread(self.run,())
34    
35     def stop(self):
36     self.keep_running=0
37    
38     def run(self):
39     """
40     If it is a server:
41     If there is no client connected currently, attempt an
42     accept
43     Else, attempt to read from the socket.
44     Else, if the client is connected to a socket, attempt to read
45     """
46    
47     while self.keep_running:
48     if self.is_server:
49     if not self.peer:
50     i,o,e=select.select([self.sock],[],[],0)
51     if i:
52     conn,addr=self.sock.accept()
53     self.peer=conn,addr
54     self.window.textBox.AppendText('system>> Peer connected from %s:%i.\n'%addr)
55     else:
56     i,o,e=select.select([self.peer[0]],[],[],0)
57     if i:
58     recvd=None
59     recvd=self.peer[0].recv(500)
60     if recvd:
61     self.window.textBox.AppendText('peer>> %s\n'%self.window.rot13(recvd))
62     else:
63     self.window.textBox.AppendText('system>> Peer closed the socket.\n')
64     self.peer=None
65     elif self.peer:
66     i,o,e=select.select([self.peer[0]],[],[],0)
67     if i:
68     recvd=None
69     recvd=self.peer[0].recv(500)
70     if recvd:
71     self.window.textBox.AppendText('peer>> %s\n'%self.window.rot13(recvd))
72     else:
73     self.window.textBox.AppendText('system>> Server closed the socket.\n')
74     self.sock=None
75     self.peer=None
76     self.keep_running=0
77     return
78    
79     class InputFrame(wxMiniFrame):
80     """
81     The dialog box used by self.get_saddress and self.get_caddress.
82     """
83    
84     def __init__(self,parent,id,server=0):
85     wxMiniFrame.__init__(self,parent,id,"Configuration",
86     wxDefaultPosition,wxSize(300,170),
87     wxDEFAULT_FRAME_STYLE|wxTINY_CAPTION_HORIZ)
88     self.parent=parent
89    
90     panel=wxPanel(self,-1)
91     iptext=wxStaticText(panel,-1,"IP",wxPoint(50,20))
92     porttext=wxStaticText(panel,-1,"Port",wxPoint(50,60))
93     if server:
94     iplist=socket.gethostbyname_ex(socket.gethostname())[2]
95     self.ipfield=wxChoice(panel,-1,wxPoint(100,15),wxSize(100,3),choices=iplist)
96     word='Start'
97     func=self.sbutton
98     else:
99     self.ipfield=wxTextCtrl(panel,-1,"",wxPoint(100,15),wxSize(100,30))
100     word='Connect'
101     func=self.cbutton
102     self.portfield=wxTextCtrl(panel,-1,"5000",wxPoint(100,55),wxSize(100,30))
103     button=wxButton(panel,ID_CBUTTON,"%s"%word,wxPoint(100,95))
104     EVT_BUTTON(panel,ID_CBUTTON,func)
105    
106     self.Show(1)
107     def cbutton(self,event):
108     self.parent.connect((self.ipfield.GetValue(),self.portfield.GetValue()))
109     self.Destroy()
110     def sbutton(self,event):
111     address=self.ipfield.GetStringSelection()
112     if address:
113     self.parent.starts((self.ipfield.GetStringSelection(),self.portfield.GetValue()))
114     self.Destroy()
115    
116     class MyFrame(wxFrame):
117     """
118     This is the main frame in which input is taken, and data is output.
119     """
120    
121     def __init__(self,parent,id,title):
122     wxFrame.__init__(self,parent,id,title,wxDefaultPosition,
123     wxSize(410,460),wxMINIMIZE_BOX|wxSYSTEM_MENU|
124     wxCAPTION)
125     self.app=None
126    
127     panel=wxPanel(self,-1)
128    
129     self.CreateStatusBar()
130    
131     menu=wxMenu()
132     menu.Append(ID_CONNECT,"&Connect","Connect to another user.")
133     menu.Append(ID_DISCONNECT,"&Disconnect","Disconnect from the current user.")
134     menu.Append(ID_STARTS,"&Start Server","Start a server.")
135     menu.Append(ID_EXIT,"E&xit","Terminate the program.")
136     menu.GetMenuItems()[1].Enable(0)
137     self.menuBar=wxMenuBar()
138     self.menuBar.Append(menu,"&File")
139     self.SetMenuBar(self.menuBar)
140    
141     #This is the box where the chat-text will go
142     self.textBox=wxTextCtrl(panel,-1,"",wxPoint(0,0),
143     wxSize(400,350),wxTE_MULTILINE|wxTE_READONLY)
144    
145     #This is the box where input will be taken,
146     #encrypted and sent to the other end.
147     self.inputBox=wxTextCtrl(panel,ID_INPUT,"",wxPoint(0,355),
148     wxSize(400,25),wxTE_PROCESS_ENTER)
149    
150     self.sock=None
151     self.input=None
152    
153     EVT_TEXT_ENTER(panel,ID_INPUT,self.send)
154     EVT_MENU(self,ID_CONNECT,self.get_caddress)
155     EVT_MENU(self,ID_DISCONNECT,self.disconnect)
156     EVT_MENU(self,ID_STARTS,self.get_saddress)
157     EVT_MENU(self,ID_EXIT,self.exit)
158     EVT_CLOSE(self,self.exit)
159    
160     def get_caddress(self,event):
161     """
162     Display a dialog to enter the IP address and the port number of
163     the server to connect to. Send the data to self.connect.
164     """
165    
166     self.input=InputFrame(self,-1,0)
167     #self.input = '192.168.50.107'
168    
169     def get_saddress(self,event):
170     """
171     Display a dialog to select a network device to bind the server
172     to, and to select the port number. Send the data to
173     self.starts.
174     """
175    
176     self.input=InputFrame(self,-1,1)
177    
178     def connect(self,address):
179     """
180     Attempt to connect, if it does not, return an error message.
181     """
182    
183     self.input=None
184     try:
185     address=(address[0],int(address[1]))
186     except: address=None
187     if address:
188     self.sock=MySocket(self)
189     self.sock.start()
190     try:
191     self.sock.sock.connect(address)
192     except: pass
193     if not self.sock.sock.getsockname()[0]=='0.0.0.0':
194     self.sock.peer=(self.sock.sock,address)
195     self.textBox.AppendText('system>> Connected to %s:%i.\n'%address)
196     self.menuBar.GetMenu(0).GetMenuItems()[0].Enable(0)
197     self.menuBar.GetMenu(0).GetMenuItems()[1].Enable(1)
198     self.menuBar.GetMenu(0).GetMenuItems()[2].Enable(0)
199     else:
200     self.disconnect(0)
201    
202     def disconnect(self,event):
203     """
204     If the socket is active:
205     If the socket is a server, stop the server.
206     Else, disconnect from the server it is connected to.
207     """
208    
209     if self.sock:
210     self.sock.stop()
211     self.sock=None
212     self.textBox.AppendText('system>> Socket closed.\n')
213     self.menuBar.GetMenu(0).GetMenuItems()[0].Enable(1)
214     self.menuBar.GetMenu(0).GetMenuItems()[1].Enable(0)
215     self.menuBar.GetMenu(0).GetMenuItems()[2].Enable(1)
216    
217     def starts(self,address):
218     """
219     Attempt to bind to that address, and return an error message if
220     failed.
221     """
222    
223     self.input=None
224     try:
225     address=(address[0],int(address[1]))
226     except: address=None
227     if address:
228     self.sock=MySocket(self)
229     nok=self.sock.start(address)
230    
231     if not nok:
232     self.textBox.AppendText('system>> Server started.\n')
233     self.textBox.AppendText('system>> Bound to %s:%i.\n'%self.sock.sock.getsockname())
234     self.menuBar.GetMenu(0).GetMenuItems()[0].Enable(0)
235     self.menuBar.GetMenu(0).GetMenuItems()[1].Enable(1)
236     self.menuBar.GetMenu(0).GetMenuItems()[2].Enable(0)
237     else:
238     self.textBox.AppendText('system>> Server failed to start.\n')
239    
240     def exit(self,event):
241     """
242     Disconnect and destroy windows!
243     """
244    
245     self.disconnect(0)
246     self.Destroy()
247    
248     def send(self,event):
249     """
250     Encrypt the data in the input box with rot13, display it in the
251     local text output box, then send it to the peer.
252     """
253    
254     data=self.inputBox.GetValue()
255     self.inputBox.Clear()
256     self.textBox.AppendText('local>> %s\n'%data)
257     data=self.rot13(data)
258     if self.sock.peer:
259     self.sock.peer[0].send(data)
260    
261     def rot13(self,data):
262     """
263     This is certainly no PGP or anything, but I know absolutely
264     nothing about data encryption! It just rotates the alpha
265     characters 13 places.
266     """
267    
268     case=[]
269     for letter in data:
270     if letter in string.lowercase:
271     case.append(0)
272     else:
273     case.append(1)
274     data=list(data.lower())
275     for letter in range(len(data)):
276     if data[letter] in string.lowercase:
277     for n in range(13):
278     if string.lowercase.index(data[letter])==25:
279     data[letter]='a'
280     else:
281     data[letter]=string.lowercase[string.lowercase.index(data[letter])+1]
282     for letter in range(len(data)):
283     if data[letter] in string.lowercase:
284     if case[letter]:
285     data[letter]=data[letter].upper()
286     return string.join(data,'')
287    
288     class MyChatApp(wxApp):
289     def OnInit(self):
290     self.frame=MyFrame(None,-1,"Chat")
291     self.frame.app=self
292     self.frame.Show(1)
293     self.SetTopWindow(self.frame)
294     return 1
295    
296     app=MyChatApp(0)
297     app.MainLoop()