#! usr/bin/env python "Import modules from python." import os, sys import math, random "Import the pygame module." try: import pygame from pygame.locals import * except ImportError: print 'This requires PyGame. You can download it at pygame.org.' "Import pygu!" try: import pygu from pygu.locals import * except ImportError: print 'This requires PyGU.' from socket import * import socket as sock import thread, time import ConfigParser, traceback from elementtree.ElementTree import * config = ConfigParser.ConfigParser() config.read("settings.ini") theme = config.get("interface", "theme") default = ["default", "Default", "DEFAULT"] if theme in default: DARK_CLR = [25, 50, 125] TEXT_CLR = [255, 255, 255] LINE_CLR = [75, 125, 255] BTTN_CLR = [50, 75, 255] BKGR_CLR = [25, 75, 200] blue = ["blue", "Blue", "BLUE"] if theme in blue: DARK_CLR = [0, 0, 100] TEXT_CLR = [255, 255, 255] LINE_CLR = [50, 100, 255] BTTN_CLR = [50, 125, 255] BKGR_CLR = [0, 0, 150] green = ["green", "Green", "GREEN"] if theme in green: DARK_CLR = [0, 75, 0] TEXT_CLR = [255, 255, 255] LINE_CLR = [25, 255, 25] BTTN_CLR = [25, 215, 25] BKGR_CLR = [0, 125, 0] red = ["red", "Red", "RED"] if theme in red: DARK_CLR = [100, 0, 0] TEXT_CLR = [255, 255, 255] LINE_CLR = [255, 0, 0] BTTN_CLR = [255, 0, 0] BKGR_CLR = [150, 0, 0] yellow = ["yellow", "Yellow", "YELLOW"] if theme in yellow: DARK_CLR = [75, 75, 0] TEXT_CLR = [255, 255, 255] LINE_CLR = [255, 255, 0] BTTN_CLR = [200, 200, 0] BKGR_CLR = [150, 150, 0] purple = ["purple", "Purple", "PURPLE"] if theme in purple: DARK_CLR = [75, 0, 75] TEXT_CLR = [255, 255, 255] LINE_CLR = [255, 0, 255] BTTN_CLR = [200, 0, 200] BKGR_CLR = [100, 0, 100] orange = ["orange", "Orange", "ORANGE"] if theme in orange: DARK_CLR = [125, 50, 0] TEXT_CLR = [255, 255, 255] LINE_CLR = [255, 150, 0] BTTN_CLR = [255, 125, 0] BKGR_CLR = [175, 75, 0] blue2 = ["blue2", "Blue2", "BLUE2"] if theme in blue2: DARK_CLR = [0, 0, 75] TEXT_CLR = [255, 255, 255] LINE_CLR = [50, 100, 255] BTTN_CLR = [75, 75, 255] BKGR_CLR = [0, 0, 0] green2 = ["green2", "Green2", "GREEN2"] if theme in green2: DARK_CLR = [0, 50, 0] TEXT_CLR = [255, 255, 255] LINE_CLR = [25, 255, 25] BTTN_CLR = [25, 150, 25] BKGR_CLR = [0, 0, 0] red2 = ["red2", "Red2", "RED2"] if theme in red2: DARK_CLR = [75, 0, 0] TEXT_CLR = [255, 255, 255] LINE_CLR = [255, 0, 0] BTTN_CLR = [150, 0, 0] BKGR_CLR = [30, 0, 0] yellow2 = ["yellow2", "Yellow2", "YELLOW2"] if theme in yellow2: DARK_CLR = [75, 75, 0] TEXT_CLR = [255, 255, 255] LINE_CLR = [255, 255, 0] BTTN_CLR = [150, 150, 0] BKGR_CLR = [0, 0, 0] purple2 = ["purple2", "Purple2", "PURPLE2"] if theme in purple2: DARK_CLR = [75, 0, 75] TEXT_CLR = [255, 255, 255] LINE_CLR = [255, 0, 255] BTTN_CLR = [150, 0, 150] BKGR_CLR = [0, 0, 0] orange2 = ["orange2", "Orange2", "ORANGE2"] if theme in orange2: DARK_CLR = [75, 50, 0] TEXT_CLR = [255, 255, 255] LINE_CLR = [255, 150, 0] BTTN_CLR = [200, 125, 0] BKGR_CLR = [0, 0, 0] class Cursor(pygu.gui.Cursor): def __init__(self): self.screen = pygu.display.screen((512, 400), 'Michael Burns - Python Powered Chat Program') pygu.gui.Cursor.__init__(self, False) self.image = pygu.image.load('data/Mouse Cursor.bmp', True) self.cursor = pygu.image.load('data/Mouse Cursor.bmp', True) self.cursor2 = pygu.image.load('data/Text Cursor.bmp', True) def change_type(self, type): if type == 'text': self.image = self.cursor2 if type == 'cursor': self.image = self.cursor def draw(self, surface): if pygame.mouse.get_focused(): surface.blit(self.image, (self.rect[0], self.rect[1]-8)) class Client: def __init__(self): self.screen = pygu.display.screen((512, 400), 'PyChat - Python Powered Chat Program') self.w = pygu.gui.MainWindow() self.clock = pygame.time.Clock() self.cursor = Cursor() pygame.mouse.set_visible(0) self.logo = pygu.image.load('data/python logo.png') self.usericon = pygu.image.load('data/user_icon.bmp', True) self.font = pygu.font.Font('data/Text Font.ttf', 16) self.font2 = pygu.font.Font('data/Title Font.ttf', 40) self.font3 = pygu.font.Font('data/Title Font.ttf', 85) self.ting = pygu.sound.load_sound("data/new_msg.wav", 0.7) config = ConfigParser.ConfigParser() config.read("settings.ini") self.nick = "" self.host = config.get("server", "host") self.port = int(config.get("server", "port")) self.buf = 1024 self.addr = (self.host, self.port) self.extra_msgs = 0 self.timer = 0 self.refresh_time = 1000 self.room = "lobby" self.usernames = [] self.menu() self.chat() def menu(self): self.w = pygu.gui.MainWindow() self.w.add_widget(pygu.gui.InputBox(max_chars=5, text=self.room, font=self.font, size=[206, 16], pos=[150, 200], fill_color=DARK_CLR, text_color=TEXT_CLR, line_color=LINE_CLR)) self.w.add_widget(pygu.gui.InputBox(font=self.font, size=[206, 16], pos=[150, 240], fill_color=DARK_CLR, text_color=TEXT_CLR, line_color=LINE_CLR)) while 1: self.clock.tick(60) event = pygame.event.poll() if event.type == QUIT: sys.exit() if event.type == KEYDOWN: if event.key == K_RETURN or event.key == K_KP_ENTER: break if self.cursor.rect.colliderect(self.w.get_widget(0).rect) or self.cursor.rect.colliderect(self.w.get_widget(1).rect): self.cursor.change_type('text') else: self.cursor.change_type('cursor') self.screen.fill(BKGR_CLR) pygame.draw.rect(self.screen, DARK_CLR, [70, 160, 365, 140]) pygame.draw.rect(self.screen, LINE_CLR, [70, 160, 365, 140], 1) self.w.render(self.screen) self.w.update(event) ren = self.font3.render("PyChat", 1, WHITE) self.screen.blit(ren, (256-ren.get_width()/2, 5)) ren = self.font.render("v0.95 created by Michael Burns and Richie Ward", 1, BLACK) self.screen.blit(ren, (257-ren.get_width()/2, 126)) ren = self.font.render("v0.95 created by Michael Burns and Richie Ward", 1, WHITE) self.screen.blit(ren, (256-ren.get_width()/2, 125)) ren = self.font.render("Copyright (C) 2007, Michael Burns", 1, BLACK) self.screen.blit(ren, (257-ren.get_width()/2, 136)) ren = self.font.render("Copyright (C) 2007, Michael Burns", 1, WHITE) self.screen.blit(ren, (256-ren.get_width()/2, 135)) ren = self.font.render("Enter a Room (5 characters only):", 1, BLACK) self.screen.blit(ren, (257-ren.get_width()/2, 186)) ren = self.font.render("Enter a Room (5 characters only):", 1, WHITE) self.screen.blit(ren, (256-ren.get_width()/2, 185)) ren = self.font.render("Enter a Nickname:", 1, BLACK) self.screen.blit(ren, (257-ren.get_width()/2, 226)) ren = self.font.render("Enter a Nickname:", 1, WHITE) self.screen.blit(ren, (256-ren.get_width()/2, 225)) ren = self.font.render("Press Enter to continue", 1, BLACK) self.screen.blit(ren, (257-ren.get_width()/2, 275)) ren = self.font.render("Press Enter to continue", 1, WHITE) self.screen.blit(ren, (256-ren.get_width()/2, 274)) self.room = self.w.get_widget(0).text self.nick = self.w.get_widget(1).text self.cursor.update() self.cursor.draw(self.screen) pygame.display.flip() def get_msg(self, msg, type): time = self.time() nick = self.nick room = self.room element = Element("message") SubElement(element, "msg").text = msg SubElement(element, "time").text = time SubElement(element, "nick").text = nick SubElement(element, "room").text = room SubElement(element, "type").text = type SubElement(element, "newnick").text = self.w.get_widget(2).text SubElement(element, "oldnick").text = self.nick string = tostring(element) string += "\r\n" return string def send(self): if self.socket.send(self.get_msg(self.w.get_widget(1).text, "normal")): self.w.get_widget(1).text = "" def send_notice(self, msg, type="notice"): self.socket.send(self.get_msg(msg, type)) def connect(self): try: self.w.get_widget(0).add_message("Connecting to: " + self.host + " at port " + str(self.port)) self.socket = socket(AF_INET, SOCK_STREAM) self.socket.connect(self.addr) self.w.get_widget(0).add_message("Connected to: " + self.host + " at port " + str(self.port)) time.sleep(0.1) self.send_notice(self.nick + " joins the chat", "newuser") time.sleep(0.1) thread.start_new(self.read, ()) except sock.error, (error, text): t = "ERROR: " + text self.w.get_widget(0).add_message(str(t)) def disconnect(self): self.socket.close() def refresh(self): self.disconnect() try: self.socket = socket(AF_INET, SOCK_STREAM) self.socket.connect(self.addr) thread.start_new(self.read, ()) except sock.error, (error, text): t = "ERROR: " + text self.w.get_widget(0).add_message(str(t)) def time(self): return time.strftime("%I:%M:%S %p",time.localtime()) def change_nick(self): newnick = self.w.get_widget(2).text for name in self.usernames: if not newnick == name: oldnick = self.nick self.send_notice(oldnick + " is now known as " + self.nick, "newnick") self.nick = newnick else: pass def read(self): try: # loop until end of command is recieved while 1: data = self.socket.recv(1024) print data.replace("\r","br ").replace("\n","bn ") print data print "------" datasplit = data.split("\r\n\r\n") datasplit.pop() print datasplit for data in datasplit: print data print "------" element = fromstring(data) thetime = element.findtext("time") nick = element.findtext("nick") msg = element.findtext("msg") type = element.findtext("type") users = element.findtext("usernames") if type == "normal": message = "[%s] <%s> %s" % (thetime, nick, msg) self.show_msg(message) elif type == "notice": message = "[%s] * %s" % (thetime, msg) self.show_msg(message) elif type == "newuser": message = "[%s] * %s" % (thetime, msg) self.show_msg(message) elif type == "users": message = "[%s] * %s" % (thetime, msg) #self.usernames = users.strip().split(",") self.ting.play() if not pygame.mouse.get_focused(): self.extra_msgs += 1 thread.start_new(self.read, ()) except: print "Exception in user code:" print '-'*60 traceback.print_exc(file=sys.stdout) print '-'*60 return def show_msg(self, msg): if not msg.startswith("New: ") and not msg.startswith("users: "): self.w.get_widget(0).add_message(msg) def restart_client(self): self.disconnect() Client() def chat(self): if self.nick == "": self.nick = "Anonymous" if self.room == "": self.room = "lobby" if len(self.room) < 5: diff = 5 - len(self.room) for i in range(diff): self.room += "." self.w = pygu.gui.MainWindow() self.w.add_widget(pygu.gui.MessageBox(font=self.font, size=[360, 290], pos=[5,50], fill_color=DARK_CLR, text_color=TEXT_CLR, line_color=LINE_CLR)) self.w.add_widget(pygu.gui.InputBox(font=self.font, size=[380, 15], pos=[40, 350], fill_color=DARK_CLR, text_color=TEXT_CLR, line_color=LINE_CLR)) self.w.add_widget(pygu.gui.InputBox(text=self.nick, font=self.font, size=[380, 15], pos=[40, 377], fill_color=DARK_CLR, text_color=TEXT_CLR, line_color=LINE_CLR)) self.w.add_widget(pygu.gui.Button(text="Send", font=self.font, command=self.send, size=[75, 20], pos=[429, 345], button_color=BTTN_CLR)) self.w.add_widget(pygu.gui.Button(text="Change", font=self.font, command=self.change_nick, size=[75, 20], pos=[429, 372], button_color=BTTN_CLR)) self.connect() self.send_notice(self.nick + " joins the chat") while 1: self.clock.tick(60) event = pygame.event.poll() if event.type == QUIT: self.send_notice(self.nick + " quit") time.sleep(0.1) self.disconnect() sys.exit() if event.type == KEYDOWN: if event.key == K_RETURN: if self.w.get_widget(1).selected: self.send() if self.w.get_widget(2).selected: self.change_nick() if event.key == K_F1: self.restart_client() if event.key == K_ESCAPE: self.send_notice(self.nick + " quit") time.sleep(0.1) self.disconnect() sys.exit() if self.cursor.rect.colliderect(self.w.get_widget(1).rect): self.cursor.change_type('text') elif self.cursor.rect.colliderect(self.w.get_widget(2).rect): self.cursor.change_type('text') else: self.cursor.change_type('cursor') self.screen.fill(BKGR_CLR) pygame.draw.rect(self.screen, DARK_CLR, [370, 50, 138, 290]) pygame.draw.rect(self.screen, LINE_CLR, [370, 50, 138, 290], 1) self.w.render(self.screen) self.w.update(event) if pygame.mouse.get_focused(): self.extra_msgs = 0 pygame.display.set_caption("PyChat - Python Powered Chat Program") if self.extra_msgs > 0: pygame.display.set_caption("[%d] PyChat - Python Powered Chat Program" % self.extra_msgs) ren = self.font2.render("PyChat", 1, WHITE) self.screen.blit(ren, (256-ren.get_width()/2, -5)) ren = self.font.render(self.time(), 1, BLACK) self.screen.blit(ren, (441, 36)) ren = self.font.render(self.time(), 1, WHITE) self.screen.blit(ren, (440, 35)) ren = self.font.render("Msg:", 1, BLACK) self.screen.blit(ren, (6, 354)) ren = self.font.render("Msg:", 1, WHITE) self.screen.blit(ren, (5, 353)) ren = self.font.render("Nick:", 1, BLACK) self.screen.blit(ren, (6, 382)) ren = self.font.render("Nick:", 1, WHITE) self.screen.blit(ren, (5, 381)) #self.screen.blit(self.logo, (5, 5)) for i in range(len(self.usernames)): ren = self.font.render(self.usernames[i], 1, TEXT_CLR) self.screen.blit(ren, (385, 55+(i*12))) self.screen.blit(self.usericon, (375, 57+(i*12))) self.cursor.update() self.cursor.draw(self.screen) pygame.display.flip() if __name__ == "__main__": Client()