#!/usr/bin/python
# -*- coding:Utf-8 -*-
import threading
import Variables
import time
import socket
import string
import os, math
import wx
class IRCClient(threading.Thread):
string_to_write = ""
def __init__(self):
threading.Thread.__init__(self)
self.serveur = "irc.freenode.com"
self.port = 6667
self.Nick = Variables.current_user+"-pol"
self.chanAutoJoin = "#playonlinux"
self.start()
self.freenode_tried = False
def get_list(self, chan):
if(self.ircconnected == True):
self.connexion.send('NAMES '+chan+'\r\n')
def htmlspecialchars(self, string):
self.string = string.replace("<","<")
self.string = self.string.replace(">",">")
return self.string
def connect(self): # Se connecte au serveur IRC
if(self.ircconnected == False):
try:
if(self.freenode_tried != True):
self.status_messages.append(self.html_convert(None, "Connecting ...","#AA0000","#AA0000",True))
else:
#self.status_messages.append(self.html_convert(None, "PlayOnLinux main IRC server is unavailable. Connecting to freenode service ...","#AA0000","#AA0000",True))
self.connexion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connexion.connect((self.serveur, self.port))
self.ircconnected = True
self.connexion.send('NICK' + ' ' + self.Nick + '\r\n')
self.realname = os.environ["APPLICATION_TITLE"]+" Client "+os.environ["VERSION"]
self.connexion.send('USER' + ' PlayOnLinux ' + self.Nick + ' ' + self.serveur + ' :' + self.realname + '\r\n')
except:
if(self.freenode_tried == False):
self.freenode_tried = True
self.serveur = "irc.freenode.com"
try :
self.connect()
except :
self.status_messages.append(self.html_convert(None, "Error! Unable to connect. Check your internet connexion and try again.","#AA0000","#AA0000",True))
else:
self.stop()
else:
self.status_messages.append(self.html_convert(None, "You are in offline-mode","#AA0000","#AA0000",True))
def getSettings(self):
irc_settings = {}
irc_settings['NICKNAME'] = os.environ["USER"]+"-pol"
irc_settings['AUTOCONNECT'] = "0"
irc_settings['ALERT'] = "0"
irc_settings["PLAYSOUND"] = "1"
if(os.path.exists(Variables.playonlinux_rep+"/configurations/options/irc")):
ircfile = open(Variables.playonlinux_rep+"/configurations/options/irc","r").readlines()
self.i = 0
while(self.i < len(ircfile)):
line_parsed = string.split(ircfile[self.i].replace("\n","").replace("\r",""),"=")
irc_settings[line_parsed[0]] = line_parsed[1]
self.i += 1
return irc_settings
def getNick(self, chaine):
self.nickname = string.split(chaine, "!")
self.nickname = self.nickname[0]
self.nickname = self.nickname[1:len(self.nickname)]
return self.nickname
def ChangeNick(self, nick):
if(self.ircconnected == True):
self.connexion.send("NICK :"+nick+"\r\n")
self.Nick = nick
def GenColor(self, pseudo):
self.colors = ["000","F00","00F","080","008","010","02E","02F","D60","D80","DA0","E00","E40","E50","E70","E80","F24","F42","777"
"06F","090","0A0","0AD","0C0","0F0","0CF","150","209","21F","D11","D12","D13","D20","D40","EA0","F27","F43","666"
"280","29E","300","30F","32F","34F","36F","470","560","5A0","5AF","5F0","64F","750","800","850","F28","F44","999"
"A90","A80","A00","A0F","A1E","A1C","A08","A70","C40","C30","C60","C80","CA0","D10","EC0","EC1","F29","F45","222"
"EC2","EC3","ED1","ED0","ED3","F10","F11","F12","F13","F14","F20","F21","F22","F23","F24","F26","F41","090",
"F91","F92","F93","F94","F95","F96","F97","F98","F99","F9A","F9A","F9C","F9D","F9E","F9F","0A0","0A1","0A2",
"0D0","0D1","0D2","0D3","0D4","0D5","0D6","0D7","0D8","0D9","0DA","0DA","0DC","0DD","0DE","0DF","FE0","FE1",
"FE2","FD0","FD1","FD2","160","161","162","163","164","165","166","170","171","173","174","175","176","#AAA"]
#self.colors.sort()
self.colors.reverse()
i = 0
somme = 0
max = 0
while(i < len(pseudo)):
i += 1
somme += ord(pseudo[i - 1])*i
max += 127*i
num=math.cos(somme * len(self.colors) / max) * len(self.colors)
num=int(num)
#print num
return "0x"+self.colors[num]
def smile(self, string):
self.newstring = string
self.newstring = self.newstring.replace("O:-)","")
self.newstring = self.newstring.replace(":-)","")
self.newstring = self.newstring.replace(":)","")
self.newstring = self.newstring.replace(":-(","")
self.newstring = self.newstring.replace(":(","")
self.newstring = self.newstring.replace(":'(","")
self.newstring = self.newstring.replace("(6)","")
self.newstring = self.newstring.replace("8-)","")
self.newstring = self.newstring.replace(":-O","")
self.newstring = self.newstring.replace(":-D","")
self.newstring = self.newstring.replace(":D"," ")
self.newstring = self.newstring.replace(":-*","")
self.newstring = self.newstring.replace("(monkey)","")
self.newstring = self.newstring.replace(":-|","")
self.newstring = self.newstring.replace(":|"," ")
self.newstring = self.newstring.replace(";-)"," ")
self.newstring = self.newstring.replace(";)"," ")
return self.newstring
def playsound(self):
settings = self.getSettings()
if(settings["PLAYSOUND"] == "1"):
#os.system("playsound "+Variables.playonlinux_env+"/etc/snd/snd.wav & 2> /dev/null > /dev/null")
sound = wx.Sound(Variables.playonlinux_env+"/resources/sounds/irc.wav")
sound.Play(wx.SOUND_SYNC)
def join(self, chan):
if(chan.lower() not in self.chans and self.ircconnected == True):
if(chan[0] == "#"):
self.connexion.send("JOIN :"+chan+"\r\n")
self.chans.append(chan.lower())
self.endnames.append(False)
self.names.append([])
self.messages.append([])
self.select_window = chan.lower()
#self.open_window.append(chan.lower())
#self.get_list(chan)
def leave_chan(self, chan):
if(chan.lower() in self.chans and self.ircconnected == True):
index = self.get_index(chan)
if(chan[0] == "#"):
self.connexion.send("PART :"+chan+"\r\n")
del self.messages[index]
del self.names[index]
del self.endnames[index]
del self.chans[index]
self.select_window = self.chanAutoJoin
def html_convert(self, pseudo, message, pseudocolor='#000000', messagecolor='#000000', action = False):
tps = time.strftime("%H:%M:%S")
message = message.replace(" "," ")
message = message.replace("\x1f","")
message = message.replace("\x02","")
message = self.htmlspecialchars(message)
message = self.smile(message)
if(pseudo != None):
if(action == False):
return "("+tps+") "+pseudo+": "+message+""
else:
return "("+tps+") *** "+pseudo+" "+message+""
else :
return "("+tps+") "+message+""
def get_index(self, content):
self.boucle = 0
while(self.boucle < len(self.chans)):
if(self.chans[self.boucle].lower() == content):
return self.boucle
self.boucle +=1
return -1
def getMsg(self, array, num=3):
self.boucle = num
self.chaine = ""
while(self.boucle < len(array)):
self.chaine += array[self.boucle]+" "
self.boucle += 1
return self.chaine[1:len(self.chaine)-1]
def SendMSG(self, message, chan="~current"):
if(self.ircconnected == False):
self.status_messages.append(self.html_convert(None, "You are not connected.","#FF0000","#FF0000",True))
else :
if(message[0] == "/"): # Une commande
self.message_parsed = string.split(message," ")
if(self.message_parsed[0].lower() == "/join" and len(self.message_parsed) > 1):
if(self.message_parsed[1][0] == "#"):
newchan = self.message_parsed[1].lower()
else:
newchan = "#"+self.message_parsed[1].lower()
self.join(newchan)
if(self.message_parsed[0].lower() == "/query" and len(self.message_parsed) > 1):
newchan = self.message_parsed[1].lower()
self.join(newchan)
if(self.message_parsed[0].lower() == "/kick" and len(self.message_parsed) > 1):
user = self.message_parsed[1].lower()
if(len(self.message_parsed) > 2):
self.i = 2
message = ""
while(self.i < len(self.message_parsed)):
if(self.i != 2):
message += " "
message += self.message_parsed[self.i]
self.i += 1
else :
message = self.Nick
self.connexion.send("KICK "+self.selected_window+" "+user+" "+message+"\r\n")
if(self.message_parsed[0].lower() == "/nick" and len(self.message_parsed) > 1):
self.ChangeNick(self.message_parsed[1])
if(self.message_parsed[0].lower() == "/me" and len(self.message_parsed) > 1):
if(chan == "~current"):
window = self.selected_window
else:
window = chan
self.connexion.send("PRIVMSG "+window+" :\x01ACTION "+message.replace("/me ","")+" \x01\r\n")
self.index = self.get_index(window)
self.messages[self.index].append(self.html_convert(self.Nick,message.replace("/me ",""),"#000088","#000088",True))
if((self.message_parsed[0].lower() == "/msg" or self.message_parsed[0].lower() == "/privmsg") and len(self.message_parsed) > 2):
self.join(self.message_parsed[1].lower())
self.i = 2
message = ""
while(self.i < len(self.message_parsed)):
if(self.i != 2):
message += " "
message += self.message_parsed[self.i]
self.i += 1
self.connexion.send("PRIVMSG "+self.message_parsed[1].lower()+" :"+message+"\r\n")
self.index = self.get_index(self.message_parsed[1].lower())
self.messages[self.index].append(self.html_convert(self.Nick,message,"#000088","#000088",True))
else:
if(chan == "~current"):
window = self.selected_window
else:
window = chan
self.connexion.send("PRIVMSG "+window+" :"+message+"\r\n")
self.index = self.get_index(window)
if(window[0] != "#"):
self.messages[self.index].append(self.html_convert(self.Nick,message,"#000088"))
else:
self.messages[self.index].append(self.html_convert(self.Nick,message,str(self.GenColor(self.Nick)).replace("0x","#")))
def filtrer_liste(self, liste):
self.boucle = 0
self.new_list = []
while(self.boucle < len(liste)):
self.new_list.append(liste[self.boucle].replace("@","").replace("+","").replace("&","").replace("%","").replace("~","").lower())
self.boucle += 1
return self.new_list
def traiter(self, line):
self.line = string.split(line, " ") # On parse la ligne mot par mot
# On répond aux pings
if(self.line[0] and len(self.line) > 1):
self.message_id = self.line[1]
if(self.line[0] == "PING"): # PINGS
self.connexion.send("PONG "+self.line[1]+"\r\n")
if(self.message_id == '353'): # NAMES
if(len(self.line) > 4):
self.canal = self.line[4].lower()
self.canal_index = self.get_index(self.canal)
if(self.canal_index != -1):
if(self.endnames[self.canal_index] == True):
self.names[self.canal_index] = []
self.endnames[self.canal_index] = False
self.boucle = 5
# self.names[self.canal_index].append(self.message_id[4])
while(self.boucle < len(self.line)):
if(self.line[self.boucle] != ''):
self.names[self.canal_index].append(self.line[self.boucle].replace(":",""))
self.boucle +=1
if(self.message_id == '366'): # END NAMES
if(len(self.line) > 3):
self.canal = self.line[3].lower()
self.canal_index = self.get_index(self.canal)
if(self.canal_index != -1):
self.endnames[self.canal_index] = True
if(self.message_id == '001'): # CONNECTED
self.join(self.chanAutoJoin)
if(self.message_id == '332'): # topic
self.subject = self.getMsg(self.line, 4)
if(len(self.line) > 3):
self.chan = self.line[3].lower()
self.chan_index = self.get_index(self.chan)
self.messages[self.chan_index].append(self.html_convert(None,"Welcome to "+self.chan+"","#666666","#666666",True))
self.messages[self.chan_index].append(self.html_convert(None,"The topic is : "+self.subject+"","#666666","#666666",True))
if(self.message_id == 'TOPIC'):
if(len(self.line) > 2):
self.sender = self.getNick(self.line[0])
self.chan = self.line[2].lower()
self.subject = self.getMsg(self.line)
self.messages[self.chan_index].append(self.html_convert(self.sender," has defined the topic : "+self.subject+"","#666666","#666666",True))
if(self.message_id == '474'): # Banned
if(len(self.line) > 3):
self.chan = self.line[3].lower()
self.chan_index = self.get_index(self.chanAutoJoin)
if(self.chan == self.chanAutoJoin):
self.status_messages.append(self.html_convert(None,"Unable to join the chat : You have been banned","#AA0000","#AA0000",True))
self.stop()
else:
self.messages[self.chan_index].append(self.html_convert(None,"Unable to join "+self.chan+" : You have been banned","#AA0000","#AA0000",True))
self.leave_chan(self.chan)
#[':irc.steredenn.fr', '474', 'tinou-pol', '#playonlinux', ':Cannot', 'join', 'channel', '(+b)']
if(self.message_id == 'JOIN'):
if(len(self.line) > 2):
self.sender = self.getNick(self.line[0])
self.window = self.line[2].lower().replace(":","")
self.index = self.get_index(self.window)
message = " has joined "+self.window
self.messages[self.index].append(self.html_convert(self.sender,message,"#888888","#888888",True))
self.get_list(self.chans[self.index])
if(self.message_id == 'PART'):
if(len(self.line) > 2):
self.sender = self.getNick(self.line[0])
self.window = self.line[2].lower().replace(":","")
self.index = self.get_index(self.window)
message = " has left "+self.window
self.messages[self.index].append(self.html_convert(self.sender,message,"#888888","#888888",True))
self.get_list(self.chans[self.index])
if(self.message_id == '401'): # No such nick channels
if(len(self.line) > 3):
self.msg_to = self.line[3]
message = " is offline"
self.index = self.get_index(self.msg_to)
self.messages[self.index].append(self.html_convert(self.msg_to,message,"#888888","#888888",True))
if(self.message_id == '482'): # No such nick channels
message = "Your not channel operator"
self.index = self.get_index(self.selected_window)
self.messages[self.index].append(self.html_convert(None,message,"#888888","#888888",True))
if(self.message_id == 'NICK'):
if(len(self.line) > 2):
self.sender = self.getNick(self.line[0])
self.new_nick = self.line[2].replace(":","")
message = " is known as "+self.new_nick
self.i = 0
while(self.i < len(self.chans)):
if(self.sender.lower() in self.filtrer_liste(self.names[self.i])):
self.messages[self.i].append(self.html_convert(self.sender,message,"#888888","#888888",True))
self.get_list(self.chans[self.i])
self.i += 1
if(self.message_id == 'MODE'):
if(len(self.line) > 3):
self.chan = self.line[2].lower()
if(len(self.line) > 4):
self.victime = self.line[4]
else:
self.victime = None
self.index = self.get_index(self.chan)
self.sender = self.getNick(self.line[0])
if("+v" in self.line[3] or "-v" in self.line[3]):
self.get_list(self.chan)
if("+o" in self.line[3]):
message = " has given operator acces to "+self.victime
self.messages[self.index].append(self.html_convert(self.sender,message,"#AA0000","#AA0000",True))
self.get_list(self.chan)
if("-o" in self.line[3]):
message = " has removed operator acces to "+self.victime
self.messages[self.index].append(self.html_convert(self.sender,message,"#AA0000","#AA0000",True))
self.get_list(self.chan)
if("+h" in self.line[3]):
message = " has given half-operator acces to "+self.victime
self.messages[self.index].append(self.html_convert(self.sender,message,"#AA0000","#AA0000",True))
self.get_list(self.chan)
if("-h" in self.line[3]):
message = " has removed half-operator acces to "+self.victime
self.messages[self.index].append(self.html_convert(self.sender,message,"#AA0000","#AA0000",True))
self.get_list(self.chan)
if("+b" in self.line[3]):
message = " has banned "+self.victime
self.messages[self.index].append(self.html_convert(self.sender,message,"#AA0000","#AA0000",True))
self.get_list(self.chan)
if("-b" in self.line[3]):
message = " has unbanned "+self.victime
self.messages[self.index].append(self.html_convert(self.sender,message,"#AA0000","#AA0000",True))
self.get_list(self.chan)
if(self.message_id == '433'): # Nick already in use
self.status_messages.append(self.html_convert(None, "Error : Nickname already in use","#FF0000","#FF0000",True))
self.stop()
if(self.message_id == '432'): # Nick contain illegal caracteres
self.status_messages.append(self.html_convert(None, "Error : Nickname contains illegal characters","#FF0000","#FF0000",True))
self.stop()
if(self.line[0] == 'ERROR'): # Nick contain illegal caracteres
self.stop()
if(self.message_id == "KICK"):
if(len(self.line) > 3):
self.sender = self.getNick(self.line[0])
self.kicked = self.line[3]
self.chan = self.line[2].lower()
self.index = self.get_index(self.chan)
self.raison = self.getMsg(self.line,4)
self.chan_index = self.get_index(self.chanAutoJoin)
if(self.kicked.lower() == self.Nick.lower()):
if(self.chan == self.chanAutoJoin):
self.status_messages.append(self.html_convert(self.sender," has kicked you from the chat : "+self.raison,"#FF0000","#FF0000",True))
self.stop()
else :
self.messages[self.chan_index].append(self.html_convert(self.sender," has kicked you from "+self.chan+" : "+self.raison,"#FF0000","#FF0000",True))
self.leave_chan(self.chan)
else :
self.messages[self.index].append(self.html_convert(self.sender," has been kicked "+self.kicked+" from "+self.chan+" : "+self.raison,"#888888","#888888",True))
self.get_list(self.chan)
if(self.message_id == 'QUIT'):
self.sender = self.getNick(self.line[0])
self.i = 0
message = " has quit"
while(self.i < len(self.chans)):
if(self.sender.lower() in self.filtrer_liste(self.names[self.i])):
self.messages[self.i].append(self.html_convert(self.sender,message,"#888888","#888888",True))
self.get_list(self.chans[self.i])
self.i += 1
if(self.message_id == 'PRIVMSG' or self.message_id == 'NOTICE' and len(self.line) > 2):
self.sender = self.getNick(self.line[0])
if(self.line[2][0] == "#"):
self.window = self.line[2].lower()
if(self.Nick.lower() not in self.getMsg(self.line)):
self.generated_color = str(self.GenColor(self.sender)).replace("0x","")
self.color = "#"+self.generated_color[0]+self.generated_color[0]+self.generated_color[1]+self.generated_color[1]+self.generated_color[2]+self.generated_color[2]# Pseudo normal
self.message_color = "#000000"
else :
self.color = "#EE00EE"
self.message_color = "#EE00EE"
self.playsound()
else:
self.color = "#AA0000"
self.message_color = "#000000"
self.window = self.sender.lower()
if(self.window != self.selected_window and not "." in self.window):
self.playsound()
self.old_window = self.selected_window
if(self.window not in self.chans):
self.chans.append(self.window)
self.endnames.append(False)
self.names.append([])
self.messages.append([])
if(self.old_window != ""):
self.select_window = self.old_window
self.index = self.get_index(self.window)
if("\x01ACTION" in self.getMsg(self.line)):
message = self.getMsg(self.line).replace("\x01","")
message = message[6:len(message)]
self.messages[self.index].append(self.html_convert(self.sender,message,"#000088","#000088",True))
else :
self.messages[self.index].append(self.html_convert(self.sender,self.getMsg(self.line),self.color,self.message_color))
#print self.names
def run(self):
self.ircconnected = False
self.selected_window = self.chanAutoJoin
self.names = []
self.messages = []
self.chans = []
self.endnames = []
self.select_window = ""
self.status_messages = []
# self.open_window = []
while 1:
if(self.ircconnected == True):
#select([self.connexion], [], [])
self.dataRecv = self.connexion.recv(1024)
self.contentParse_ = string.split(self.dataRecv,"\r\n")
self.k = 0
while(self.k < len(self.contentParse_)):
if(self.contentParse_[self.k]):
self.traiter(self.contentParse_[self.k])
self.k += 1
else:
time.sleep(1)
def Connexion(self):
self.connect()
def stop(self):
if(self.ircconnected == True):
# self.zone_append("("+time.strftime("%H:%M:%S")+") Disconnected")
self.ircconnected = False
self.status_messages.append(self.html_convert(None, "Disconnected","#AA0000","#AA0000",True))
self.connexion.send("QUIT :www.playonlinux.com\r\n")
self.connexion.close()
self.names = []
self.messages = []
self.chans = []
self.endnames = []