#!/usr/bin/env python
#-*- encoding: utf-8 -*-
"""
local area network chatting program
"""
import os
import wx
import socket
import threading
#import SocketServer
#import time
FILE_PORT = 7777
BROADCAST_PORT = 8888
CHAT_PORT = 9999
#get hostname and host ip address
hostname = socket.gethostname()
hostip = socket.gethostbyname(hostname)
#get local broadcast address
list = hostip.split('.')
list[-1] = '255'
broadcast = ".".join(list)
#broadcast = "255.255.255.255"
#print local information
print "host name: ", hostname
print "host ip address: ", hostip
print "broadcast address: ", broadcast
#directory usrdir used to store user information
userdir = {"lilong" : hostip, "NONE" : "192.168.1.1"}
#gui class
class MainWindow(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size = (800, 600))# , style=wx.SYSTEM_MENU|wx.MINIMIZE_BOX|wx.CLOSE_BOX|wx.CAPTION)
#panel = wx.Panel(self, -1)
self.SetBackgroundColour(wx.Color(255, 255, 255))
self.chat = None
self.msgList = []
self.userList = []
self.statusBar = self.CreateStatusBar()
self.StatusBar.SetStatusText("Local area network chatting room")
#listbox list all the local user
self.listBox = wx.ListBox(self, -1, \
choices = userdir.keys(), style = wx.LB_DEFAULT)
self.msgTextCtrl = wx.TextCtrl(self, -1,\
style = wx.TE_MULTILINE | wx.TE_READONLY)
self.editTextCtrl = wx.TextCtrl(self, -1,\
style = wx.TE_MULTILINE | wx.TE_PROCESS_ENTER)
self.nullLabel1 = wx.StaticText(self, -1)
#self.nullLabel2 = wx.StaticText(self, -1)
self.msgButton = wx.Button(self, -1, "No Message Received")
self.sendButton = wx.Button(self, -1, "Send")
self.closeButton = wx.Button(self, -1, "Close")
self.fileButton = wx.Button(self, -1, "Send File")
self.refreshButton = wx.Button(self, -1, "Refresh")
self.recordButton = wx.Button(self, -1, "Records")
#button layout
hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
hsizer2.Add(self.recordButton, proportion = 0, flag = wx.RIGHT)
hsizer2.Add(self.fileButton, proportion = 0, flag = wx.RIGHT)
#hsizer2.Add(self.nullLabel2, proportion = 1, flag = wx.RIGHT)
#button layout
hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
hsizer1.Add(self.nullLabel1, proportion = 1, flag = wx.EXPAND | wx.BOTTOM)
hsizer1.Add(self.refreshButton, proportion = 0, flag = wx.EXPAND | wx.RIGHT | wx.BOTTOM)
#hsizer.Add(self.recordButton, proportion = 0, flag = wx.RIGHT | wx.BOTTOM)
hsizer1.Add(self.sendButton, proportion = 0, flag = wx.RIGHT | wx.BOTTOM)
hsizer1.Add(self.closeButton, proportion = 0, flag = wx.RIGHT | wx.BOTTOM)
#text control layout
vsizer1 = wx.BoxSizer(wx.VERTICAL)
vsizer1.Add(self.msgTextCtrl, 1, wx.EXPAND)
vsizer1.Add(hsizer2, 0, wx.EXPAND)
vsizer1.Add(self.editTextCtrl, 1, wx.EXPAND)
vsizer1.Add(hsizer1, 0, wx.EXPAND)
#list and button layout
vsizer2 = wx.BoxSizer(wx.VERTICAL)
vsizer2.Add(self.listBox, 1, wx.EXPAND)
vsizer2.Add(self.msgButton, 0, wx.EXPAND)
#all widgets layout
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(vsizer2, 1, wx.EXPAND)
sizer.Add(vsizer1, 2, wx.EXPAND)
#add layout
self.SetSizer(sizer)
self.SetAutoLayout(1)
sizer.Fit(self)
#bind
self.Bind(wx.EVT_LISTBOX, self.OnListBox, self.listBox)
self.Bind(wx.EVT_LISTBOX_DCLICK, self.DListBox, self.listBox)
#button action
self.Bind(wx.EVT_BUTTON, self.MsgRecvd, self.msgButton)
self.Bind(wx.EVT_BUTTON, self.OnRefresh, self.refreshButton)
self.Bind(wx.EVT_BUTTON, self.OnSend, self.sendButton)
self.Bind(wx.EVT_BUTTON, self.OnClose, self.closeButton)
self.Bind(wx.EVT_BUTTON, self.OnFile, self.fileButton)
#text changed and save chatting records
self.Bind(wx.EVT_TEXT, self.SaveRecord, self.msgTextCtrl)
#press enter and send the message
self.Bind(wx.EVT_TEXT_ENTER, self.OnSend, self.editTextCtrl)
self.Show()
#received message
def MsgRecvd(self, event):
if len(self.msgList):
print "This is message received: ", self.msgList[0]
if os.name == 'nt':
self.msgList[0] = self.msgList[0].decode('gbk')
elif os.name == 'posix':
self.msgList[0] = self.msgList[0].decode('gb2312')
else:
print "unknown OS"
pass
self.msgTextCtrl.AppendText(self.msgList[0])
del self.msgList[0]
if len(self.userList):
print type(self.userList[0])
string = str(self.userList[0])
print string
id = self.listBox.FindString(string)
print id
self.listBox.Select(id)
del self.userList[0]
if not len(self.userList):
self.msgButton.SetLabel("No Message Received")
#send file
def OnFile(self, event):
sendfile = fileClient("sendFile")
sendfile.setDaemon(True)
sendfile.start()
#time.sleep(1)
# try:
# sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# sock.connect((userdir[self.chat], FILE_PORT))
# dirname = ''
# filedlg = wx.FileDialog(self, "choose a file", dirname, "", "*.*", wx.OPEN)
# if filedlg.ShowModal() == wx.ID_OK and filedlg.GetFilename():
# print "hellO"
# filename = filedlg.GetFilename()
# dirname = filedlg.GetDirectory()
# print "FILENAME:", filename
# if filename:
# path = os.path.join(dirname, filename)
# sock.send(filename)
# ack = sock.recv(12)
# print ack
# filedes = open(path, "rb")
# while True:
# data = filedes.read(8192)
# #print data
# if not data:
# break
# while len(data) > 0:
# sent = sock.send(data)
# #print sent
# data = data[sent:]
# ack = sock.recv(12)
# if ack == "ACK":
# self.showMsg("the file send successfully")
## d = wx.MessageDialog(self, "The file send successfully", style = wx.OK)
## #create a message dialog
## d.ShowModal() #show dialog
## d.Destroy()
# print ack
# except socket.error:
# d = wx.MessageDialog(self, "Create socket error", style = wx.OK)
# #create a message dialog
# d.ShowModal() #show dialog
# d.Destroy()
# finally:
# sock.close()
def SaveRecord(self, event):
#write the chatting records to the local file
print "MAIN WINDOW save"
def OnListBox(self, event):
user = event.GetString()
#print "user = %s" % user
#self.Title = "Double click chat to %s" % user
self.StatusBar.SetStatusText("Double click chat to %s" % user)
#double click user name and chat to him/her
def DListBox(self, event):