from __future__ import unicode_literals # -*- coding: utf-8 -*- import os from sys import exit, argv from time import sleep from threading import Thread from socket import socket, AF_INET, SOCK_STREAM from subprocess import Popen, PIPE import logging import cPickle as pickle #modules importes from psutil import process_iter #import de QT et des interfaces from PyQt4.QtCore import * from PyQt4.QtGui import * from ecran_connexion import Ui_ecranConnexion from ecran_chat import Ui_chat #modules persos from serveur import Serveur, ServeurVoc from lancer import jet from clientvoc import ClientVoc #fonctions potetiellement utiles: #print(psutil.connections()) #print(psutil.net_io_counters(pernic=True)) #gestion des erreurs et log logging.basicConfig(level=logging.DEBUG) logProg = logging.getLogger(__name__) handlerProg = logging.FileHandler('prog.log') handlerProg.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)s- %(message)s')) #'%(name)s' nom du thread logProg.addHandler(handlerProg) logProg.debug(" ---------------------- \n") class EcranConnexion(QGroupBox): """fenetre de connexion a l'application et module d'envoi/reception""" def __init__(self, parent=None): """initialisation de la connexion et creation de la fenetre""" super (EcranConnexion, self).__init__(parent) self.client_connecte = False self.serveur_connecte = False self.idClient = "00" self.ip = "" self.pseudo = "" self.autresCo = {} #echanges fichiers self.eFichier = {"id": "00", "chemin": "", "fichier": None, "dest": "", "envoi" : False, "annule" : False} #fichier en cours d'envoi : id fichier, chemin du fichier, fichier (objet), dest, envoi autorise, envoi annule self.destFichier = {} #liste des clients dont on attend confirmation pour l'envoi de fichier self.receptionFichier = {} #id du fichier: nom du fichier self.repReceptionFichiers = os.getcwd()+"\\FichiersRecus\\" #chat voc self.ipServeurVoc = "" self.port = 6660 #recup des param et affichage: try: logProg.info(self.recupParamCo()) except: logProg.info("pas de parametres a recuperer") self.createWidgets() def createWidgets(self): """creation de l'interface de connexion""" self.ui = Ui_ecranConnexion() self.ui.setupUi(self) if len(self.ip) > 0: self.ui.in_ip.setText(QString.fromUtf8(self.ip)) if self.port > 0: self.ui.in_port.setText(QString.fromUtf8(str(self.port))) if len(self.pseudo) > 0: self.ui.in_pseudo.setText(QString.fromUtf8(self.pseudo)) self.connect(self.ui.fermer, SIGNAL("clicked()"), self.fermer) self.connect(self.ui.creerServeur, SIGNAL("clicked()"), self.creerServeur) self.connect(self.ui.seConnecter, SIGNAL("clicked()"), self.seConnecter) def msg(self, txt): """affichage d'un message informatif sous forme de label""" self.ui.txt_msg.setText(QString.fromUtf8(txt)) QApplication.processEvents() def creerServeur(self): """instancie un serveur local""" self.pseudo = self.ui.in_pseudo.text() self.port = self.ui.in_port.text() if len(self.pseudo) == 0 or len(self.port) == 0: self.msg("Parametres incorrects") else: self.ui.in_ip.setText(QString.fromUtf8("localhost")) self.s = Serveur(int(self.ui.in_port.text())) self.serveur_connecte, txt = self.s.creer() self.msg(txt) if self.serveur_connecte: self.seConnecter() def seConnecter(self): """se connecte au serveur correspondant a l'ip et au port saisis""" self.pseudo = self.ui.in_pseudo.text() self.port = self.ui.in_port.text() self.ip = self.ui.in_ip.text() essais = 0 if len(self.pseudo) == 0 or len(self.ip) == 0 or len(self.port) == 0: self.msg("Parametres incorrects") else: self.msg("En attente du serveur...") while self.client_connecte == False: #en attente de la connexion try: self.cnn = socket(AF_INET, SOCK_STREAM) self.cnn.connect((self.ip, int(self.port))) self.client_connecte = True txt = "Connexion etablie avec le serveur sur le port {}\n".format(self.port) logProg.info(txt) except KeyboardInterrupt: break except: essais += 1 if essais > 3: txt = "Delai depasse" self.msg(txt) logProg.warning(txt) break txt = "Connexion : essai {}".format(essais) self.msg(txt) logProg.info(txt) if self.client_connecte: #demarre le fil de reception Thread(None, self.filReception, None, (), {}).start() #previent le serveur et envoie le pseudo self.envoi("ci", "sa", self.pseudo) self.msg(txt) sleep(0.01) self.close() self.emit(SIGNAL("majAffichage()")) else: txt = "Erreur: impossible de se connecter" self.msg(txt) logProg.error(txt) def filReception(self): """thread de reception des donnees du serveur, reste actif tant que l'application est active""" while self.client_connecte: recu = self.cnn.recv(1024) if len(recu) > 0: self.traitement(recu) def traitement(self, msg): """determine le traitement a apporter a un message recu, selon sa nature""" if len(msg) >= 6: emet = msg[2:4] dest = msg[4:6] categorie = msg[:1] nature = msg[:2] try: contenu = msg[6:] except: contenu = "" if nature != "fd" and nature != "ff": #on decode le message, sauf s'il contient des donnees binaires issues d'un fichier contenu = contenu.decode('utf-8') if nature == "ci": #recoit l'identifiant du client fourni par le serveur self.idClient = dest logProg.info("mon id est: {}\n".format(self.idClient)) elif nature == "cc": if contenu[0:2] != self.idClient: self.autresCo[str(contenu[0:2])] = str(contenu[2:]) #on lui envoie id+pseudo sleep(0.02) self.envoi("cp", contenu[0:2], "{}{}".format(self.idClient, self.pseudo)) logProg.info("{} s'est connecte ({})".format(contenu[2:], contenu[0:2])) self.recuInfo("cc", "{} s'est connecte ({})".format(contenu[2:], contenu[0:2])) elif nature == "cp": self.autresCo[str(contenu[0:2])] = str(contenu[2:]) sleep(0.01) logProg.info("{} est deja present ({})".format(contenu[2:], contenu[0:2])) self.recuInfo("cc", "{} est deja la ({})".format(contenu[2:], contenu[0:2])) elif nature == "cd": if contenu != self.idClient and len(contenu) == 2: logProg.info("{} s'est deconnecte ({})".format(self.autresCo[contenu], contenu)) self.recuInfo("cd", "{} s'est deconnecte ({})".format(self.autresCo[contenu], contenu)) del self.autresCo[contenu] elif categorie == "m": #afficher dans le chat logProg.info("chat: {} -> {}\n".format(emet, contenu)) self.recuMsg(emet, contenu) elif categorie == "i": #afficher dans la fenetre évènement self.recuInfo(nature, contenu) if nature == "id": #jet de dés: afficher en rouge logProg.info("jet de dé: {} -> {}\n".format(emet, contenu)) if nature == "ic": #nouveau client connecte: afficher en bleu logProg.info("info connexion: {} -> {}\n".format(emet, contenu)) elif categorie == "f": #envoi ou reception de fichier if nature == "f0": #le serveur nous renvoie l'identifiant du fichier que l'on veut envoyer if self.eFichier["id"] == "00": if len(contenu) == 2: Thread(None, self.envoiFichier_1, None, (contenu,), {}).start() else: logProg.error("erreur: id du fichier\n") else: logProg.warning("Un fichier est en cours d'envoi\n") elif nature == "fp": #un clients est pret a recevoir le fichier self.pretEnvoiFichier(emet) elif nature == "fi": #quelqu'un nous envoie un fichier if len(contenu)>2: #les 2 premiers car sont l'identifiant, puis le nom du fichier (* la taille) essai = self.nouveauFichier(contenu[0:2], contenu[2:]) logProg.info("nouveau fichier: {}".format(essai)) if len(essai) > 0: self.recuInfo(nature, "Fichier {} en cours de reception".format(contenu[2:])) #on envoie confirmation de la reception: sleep(0.001) self.envoi("fp", emet, contenu[0:2]) self.emit(SIGNAL("initRecFichier(QString, QString)"), QString.fromUtf8(essai), QString.fromUtf8("")) else: self.recuInfo(nature, "Impossible de créer le fichier à recevoir") logProg.error("Impossible de créer le fichier à recevoir") else: logProg.error("erreur reception fichier: id ou nom du fichier incorrect\n") elif nature == "fd": #on recoit les donnees a ecrire dans le fichier #print("reception: {}".format(contenu)) if len(contenu) > 2: self.receptionFichier[contenu[0:2]].write(contenu[2:]) #print("{} -> paquet recu".format(contenu[0:2])) self.emit(SIGNAL("initRecFichier(QString, QString)"), QString.fromUtf8(""), QString.fromUtf8(".")) #le client renvoie la longueur de la donnee recue a l'emetteur pour confirmation sleep(0.001) self.envoi("fp", emet, contenu[0:2]) elif len(contenu) == 2: #l'emetteur redemande confirmation, on lui envoie self.envoi("fp", emet, contenu[0:2]) else: logProg.error("erreur de reception des donnees du fichier\n") #pass elif nature == "ff": #fin de reception du fichier self.receptionFichier[contenu[0:2]].write(contenu[2:]) sleep(0.001) self.envoi("fp", emet, contenu[0:2]) self.recuInfo("ff", "Fichier {} recu\n".format(os.path.basename(self.receptionFichier[contenu[0:2]].name))) self.emit(SIGNAL("initRecFichier(QString, QString)"), QString.fromUtf8(""), QString.fromUtf8("ok")) self.emit(SIGNAL("inserImg(QString, QString)"), QString.fromUtf8(emet), QString.fromUtf8(self.receptionFichier[contenu[0:2]].name)) sleep(0.01) self.receptionFichier[contenu[0:2]].close() del self.receptionFichier[contenu[0:2]] logProg.info("Fichier recu") elif nature == "fa": #envoi annule logProg.info("Annulation de la reception du fichier") if self.receptionFichier[contenu[0:2]]: self.recuInfo("ff", "Reception {} annule \n".format(os.path.basename(self.receptionFichier[contenu[0:2]].name))) self.emit(SIGNAL("initRecFichier(QString, QString)"), QString.fromUtf8(""), QString.fromUtf8("x")) self.receptionFichier[contenu[0:2]].close() #on supprime le fichier incomplet: os.remove(self.receptionFichier[contenu[0:2]].name) del self.receptionFichier[contenu[0:2]] elif categorie == "s": #infos sur le fonctionnement du serveur principal if nature == "sd": #le serveur a ete ferme self.serveurDeco() elif categorie == "v": #infos liees au chat vocal if nature == "vs": #un serveur vocal a ete cree self.recuInfo("vs", "{} a cree un serveur vocal ({})".format(self.autresCo[emet], contenu)) self.ipServeurVoc = contenu if nature == "vi": #un client rejoint le chat vocal self.recuInfo("vi", "{} a rejoint le chat vocal".format(self.autresCo[emet])) if nature == "vq": #un client quitte le chat vocal self.recuInfo("vq", "{} a quitte le chat vocal".format(self.autresCo[emet])) if nature == "vf": #fermeture du serveur vocal self.recuInfo("vf", "{} a ferme le serveur vocal".format(self.autresCo[emet])) elif categorie == "p": if nature == "pi": #nouveau plateau créé logProg.info("nouveau plateau: {}\n".format(emet, contenu)) else: logProg.warning("Erreur: message illisible -> {}\n".format(msg)) def recuInfo(self, nature, contenu): """signale une nouvelle information""" self.emit(SIGNAL("nouvelleInfo(QString, QString)"), QString.fromUtf8(nature), QString.fromUtf8(contenu)) def recuMsg(self, emetteur, contenu): """signale un nouveau message texte pour le chat ecrit""" self.emit(SIGNAL("msgChat(QString, QString)"), QString.fromUtf8(emetteur), QString.fromUtf8(contenu)) def envoi(self, nature, dest, msg, idFichier = ""): """envoie un message au serveur TCP - longueur du message (3 car) - nature du message (2 car) - exp: id de l'expediteur (2 car) - dest: id du destinataire (2 car) - msg: contenu du message (999 car max) - un identifiant pour le fichier le cas echeant""" exp = self.idClient if self.client_connecte: try: if len(msg) <= 999: if len(idFichier) == 0: msg = unicode(msg) lg = "%003.f"%len(msg.encode('utf-8')) #la longueur apres encodage peut changer txt = "{}{}{}{}{}".format(lg, nature, exp, dest, msg) txt = txt.encode('utf-8') else: lg = "%003.f"%(len(msg)+2) txt = "{}{}{}{}{}".format(lg, nature, exp, dest, idFichier) txt = txt.encode('utf-8') + msg retour = len(txt) self.cnn.sendall(txt) else: self.recuInfo(" ","999 caracteres au max.") retour = 0 except: retour = 0 logProg.warning("Envoi impossible") else: retour = "" logProg.warning("Le client n'est pas connecte au serveur") self.recuInfo(" ","Vous n'etes pas connecte a un serveur") return retour def envoiFichier(self, chemin, dest = "ac"): """intialise l'envoi d'un fichier""" if self.eFichier["id"] == "00": # on verifie si le fichier existe: fichier = None try: fichier = open(chemin, "rb") except: logProg.error("Le fichier '{}' est introuvable.".format(fichier)) if not os.path.getsize(chemin) > 0: logProg.error("Envoi impossible - fichier vide") fichier.close() fichier == None if fichier: #on demande un identifiant au serveur self.eFichier["fichier"] = fichier self.eFichier["chemin"] = chemin self.eFichier["dest"] = dest self.eFichier["annule"] = False self.emit(SIGNAL("initEnvFichier(QString, QString)"), QString.fromUtf8(os.path.basename(chemin)), QString.fromUtf8("0")) logProg.debug(self.eFichier) if dest == "ac": for idC in self.autresCo: self.destFichier[idC] = False else: self.destFichier[dest] = False self.envoi("f0","sa","") else: self.annuleEnvoiFichier() def envoiFichier_1(self, idFichier): """le fichier est pret a etre envoye, on attend confirmation des destinataires""" if len(idFichier) == 2: dest = self.eFichier["dest"] self.eFichier["id"] = idFichier nomFichier = os.path.basename(self.eFichier["chemin"]) taille = os.path.getsize(self.eFichier["chemin"]) logProg.debug("{} a pour id {}\n".format(nomFichier, idFichier)) #on previent les destinataires, et on leur transmet l'identifiant et le nom*taille du fichier logProg.info("En attente des destinataires...") self.recuInfo("fi", "{} - En attente des destinataires...".format(nomFichier)) self.envoi("fi", dest, "{}{}".format(idFichier, nomFichier)) while not self.eFichier["envoi"] and not self.eFichier["annule"]: sleep(0.001) if not self.eFichier["annule"]: Thread(None, self.envoiFichier_2, None, (), {}).start() else: logProg.error("Erreur envoi fichier: identifiant incorrect -> {}".format(idFichier)) self.annuleEnvoiFichier() def pretEnvoiFichier(self, idClient): """signale un destinataire comme etant pret a recevoir le fichier ou le paquet de donnees""" pretEnvoi = False if self.eFichier["dest"] == "ac": self.destFichier[idClient] = True pretEnvoi = True for idC in self.destFichier: if self.destFichier[idC] == False: pretEnvoi = False #si tous les clients sont prets, on enclenche l'envoi du fichier sous forme de thread else: if idClient == self.eFichier["dest"]: pretEnvoi = True #print("{} -> {}".format(idClient, pretEnvoi)) self.eFichier["envoi"] = pretEnvoi def envoiFichier_2(self): """thread d'envoi de fichier""" if self.eFichier["envoi"] and not self.eFichier["annule"]: idFichier = self.eFichier["id"] taille = os.path.getsize(self.eFichier["chemin"]) nomFichier = os.path.basename(self.eFichier["chemin"]) dest = self.eFichier["dest"] envoye = 0 essais = 0 #on envoie les donnees data = self.eFichier["fichier"].read(512) while len(data) == 512: if self.eFichier["annule"]: #en cas d'annulation break self.envoi("fd", dest, data, idFichier) envoye += len(data) logProg.info("{} / {}".format(int(envoye/1000), int(taille/1000))) #on attend confirmation de reception: self.eFichier["envoi"] = False if dest == "ac": for idC in self.autresCo: self.destFichier[idC] = False else: self.destFichier[dest] = False while not self.eFichier["envoi"]: if self.eFichier["annule"]: break sleep(0.001) essais += 1 if essais >= 1000: #on renvoie un message pour demander confirmation self.envoi("fd", dest, b'', idFichier) essais = 0 taux = str((100*envoye)/taille) self.emit(SIGNAL("initEnvFichier(QString, QString)"), QString.fromUtf8(""), QString.fromUtf8(taux)) data = self.eFichier["fichier"].read(512) #pour dernier paquet on ajoute au drapeau: "%003.f"%len(paquet) #on signale que c'est le dernier paquet et on ajoute 3 caracteres pour en specifier la taille: if not self.eFichier["annule"]: self.envoi("ff", dest, data, idFichier) envoye += len(data) logProg.info("{} / {}".format(int(envoye/1000), int(taille/1000))) self.eFichier["envoi"] = False while not self.eFichier["envoi"]: if self.eFichier["annule"]: break sleep(0.001) essais += 1 if essais >= 1000: #on renvoie un message pour demander confirmation logProg.warning("envoi fichier - on redemande confirmation") self.envoi("fd", dest, b'', idFichier) essais = 0 taux = str((100*envoye)/taille) self.emit(SIGNAL("initEnvFichier(QString, QString)"), QString.fromUtf8(""), QString.fromUtf8(taux)) self.envoi("f1", "sa", "{}".format(idFichier)) self.recuInfo("ff", "- {} a bien ete envoye -".format(nomFichier)) self.emit(SIGNAL("inserImg(QString, QString)"), QString.fromUtf8(self.idClient), QString.fromUtf8(self.eFichier["chemin"])) logProg.info("\n- Fichier envoye -") self.eFichier = {"id": "00", "chemin": "", "fichier": None, "dest": "", "envoi" : False, "annule": False} else: self.eFichier = {"id": "00", "chemin": "", "fichier": None, "dest": "", "envoi" : False, "annule": True} else: logProg.error("Erreur envoi fichier: signal serveur non-recu -> {}".format(self.eFichier["id"])) self.eFichier = {"id": "00", "chemin": "", "fichier": None, "dest": "", "envoi" : False, "annule": False} def annuleEnvoiFichier(self): """annule l'envoi d'un fichier""" logProg.warning("Annulation de l'envoi") self.envoi("fa", self.eFichier["dest"], "{}".format(self.eFichier["id"])) self.eFichier["annule"] = True essais = 0 while not self.eFichier["id"] == "00": sleep(0.01) essais += 1 if essais > 100: logProg.error("Erreur: impossible d'annuler l'envoi") logProg.info("-> Envoi annulé") self.recuInfo("fa", "- Envoi du fichier annule -") self.emit(SIGNAL("initEnvFichier(QString, QString)"), QString.fromUtf8(""), QString.fromUtf8("x")) def nouveauFichier(self, idFichier, nomFichier): """cree le fichier a recevoir - le renomme si un fichier portant ce nom existe deja - retourne le chemin complet""" k = 1 tmp = nomFichier retour = "" try: while os.path.isfile(self.repReceptionFichiers+tmp): k += 1 tmp = nomFichier.split(".")[0]+str(k)+"."+nomFichier.split(".")[1] if k == 100: tmp = "" break if len(tmp) > 0: self.receptionFichier[idFichier] = open((self.repReceptionFichiers + tmp), "wb") retour = tmp except: logProg.error("Impossible de creer le fichier") return retour def serveurDeco(self): """le serveur a ferme - on affiche a nouveau l'ecran de connexion""" #on annule les envois de fichier en cours if self.eFichier["fichier"] != None: self.eFichier["annule"] = True self.emit(SIGNAL("initEnvFichier(QString, QString)"), QString.fromUtf8(""), QString.fromUtf8("x")) #on annule les receptions de fichiers en cours for idFichier in self.receptionFichier: logProg.warning("{} - reception annulee".format(self.receptionFichier[idFichier].name)) self.receptionFichier[idFichier].close() os.remove(self.receptionFichier[idFichier].name) self.emit(SIGNAL("initRecFichier(QString, QString)"), QString.fromUtf8(""), QString.fromUtf8("x")) self.receptionFichier = {} self.recuInfo("sd", "(!) Le serveur a mis la clef sous la porte (!)") logProg.warning("Serveur deconnecte") self.cnn.close() self.client_connecte = False self.serveur_lance = False sleep(0.01) self.show() self.msg("") def recupParamCo(self): """recupere les derniers parametres de connexion enregistres s'il existent""" try: with open("parametresCo", 'rb') as input: dico = pickle.load(input) self.pseudo = dico["pseudo"] self.port = dico["port"] self.ip = dico["ip"] self.repReceptionFichiers = dico["repReceptionFichiers"] retour = dico input.close() except IOError: retour = ("Erreur: parametresCo introuvable") return retour def sauverParamCo(self): """sauvegarde les parametres de connexion pour une prochaine utilisation""" with open("parametresCo", 'wb') as output: dico = {"pseudo": str(self.pseudo), "port" : int(self.port), "ip": str(self.ip), "repReceptionFichiers" : str(self.repReceptionFichiers)} pickle.dump(dico, output, -1) output.close() chaine = "parametres sauvegarde." return chaine def fermer(self): """fermeture de la connexion, et du serveur le cas echeant""" if self.client_connecte: try: self.envoi("cd", "sa", "") except: logProg.warning("impossible de prévenir le serveur de la deco") self.client_connecte = False self.cnn.close() if self.eFichier["fichier"] != None: self.eFichier["annule"] = True sleep(0.001) logging.info(self.sauverParamCo()) if self.serveur_connecte: self.s.stop() self.serveur_connecte = False sleep(0.001) self.close() def closeEvent(self, event): """sur fermeture de la fenetre""" if not self.client_connecte: self.fermer() class EcranChat(QGroupBox): """interface comprenant: chat ecrit, fenetre d'infos, lancer de des, echange de fichiers, lancement du chat vocal""" def __init__(self, connexion, parent=None): """initialisation de la fenetre""" super (EcranChat, self).__init__(parent) self.co = connexion self.connecte = True self.estServeurVoc = False self.estClientVoc = False self.createWidgets() def createWidgets(self): """construction de l'interface""" #construction de l'interface self.ui = Ui_chat() self.ui.setupUi(self) #connexion des commandes self.connect(self.ui.inChat, SIGNAL("returnPressed()"), self.envoiMsg) self.connect(self.ui.d20, SIGNAL("clicked()"), self.d20) self.connect(self.ui.d100, SIGNAL("clicked()"), self.d100) self.connect(self.ui.inJetDes, SIGNAL("returnPressed()"), self.autreJet) self.connect(self.ui.envoiFichier, SIGNAL("clicked()"), self.envoyerfichier) self.connect(self.ui.repReceptionFichiers, SIGNAL("clicked()"), self.repReception) self.connect(self.ui.listFichiers, SIGNAL("itemDoubleClicked(QTreeWidgetItem*, int)"), self.ouvrirFichier) self.connect(self.ui.chatVoc, SIGNAL("clicked()"), self.chatVoc) self.connect(self.ui.creerServeurVoc, SIGNAL("clicked()"), self.creerServeurVoc) #reception des signaux self.emit(SIGNAL("majAffichage()")) self.connect(self, SIGNAL("msgChat(QString, QString)"), self.ajoutChat) self.connect(self.co, SIGNAL("msgChat(QString, QString)"), self.ajoutChat) self.connect(self, SIGNAL("nouvelleInfo(QString, QString)"), self.ajoutInfo) self.connect(self.co, SIGNAL("nouvelleInfo(QString, QString)"), self.ajoutInfo) self.connect(self, SIGNAL("initRecFichier(QString, QString)"), self.afficheReception) self.connect(self.co, SIGNAL("initRecFichier(QString, QString)"), self.afficheReception) self.connect(self, SIGNAL("inserImg(QString, QString)"), self.inserImgChat) self.connect(self.co, SIGNAL("inserImg(QString, QString)"), self.inserImgChat) self.connect(self, SIGNAL("initEnvFichier(QString, QString)"), self.afficheEnvoi) self.connect(self.co, SIGNAL("initEnvFichier(QString, QString)"), self.afficheEnvoi) self.connect(self, SIGNAL("majAffichage()"), self.majStatut) self.connect(self.co, SIGNAL("majAffichage()"), self.majStatut) self.majStatut() def msg(self, txt): """affichage d'un message informatif sous forme de label""" self.ui.txt_msg.setText(QString.fromUtf8(txt)) QApplication.processEvents() def ajoutChat(self, emetteur, msg): """ajoute une nouvelle ligne au chat ecrit""" emetteur = str(emetteur) if emetteur == self.co.idClient: txt = "{} : {}".format(self.co.pseudo, msg) else: pseudo = self.co.autresCo["{}".format(emetteur)] txt = "{} : {}".format(pseudo, msg) txt = QString.fromUtf8(txt) item = QListWidgetItem(self.ui.listAffichage) self.ui.listAffichage.addItem(item) label = QLabel() label.setWordWrap(True) label.setText(txt) item.setSizeHint(QSize(120, label.heightForWidth (self.ui.listAffichage.width()) + 5)) self.ui.listAffichage.setItemWidget(item, label) QApplication.processEvents() def ajoutInfo(self, nature, msg): """ajoute une nouvelle ligne a la liste des evenements""" #couleur selon nature de l'info: if nature[:1] == "c": txt = "{}".format(msg) elif nature == "id": txt = "{}".format(msg) elif nature[:1] == "f": txt = "{}".format(msg) elif nature[:1] == "v": txt = "{}".format(msg) else: txt = msg txt = QString.fromUtf8(txt) item = QListWidgetItem(self.ui.listEvenement) self.ui.listEvenement.addItem(item) label = QLabel() label.setWordWrap(True) label.setText(txt) item.setSizeHint(QSize(120, label.heightForWidth (self.ui.listEvenement.width()) + 5)) self.ui.listEvenement.setItemWidget(item, label) QApplication.processEvents() def inserImgChat(self, emet, fichier): """insere une image dans le QListWidget chat""" emet = str(emet) fichier = str(fichier) try: typeFichier = fichier.split(".")[len(fichier.split("."))-1] except: typeFichier = "" if typeFichier.lower() in ["png", "jpeg", "jpg"]: #si c'est une image, on essaie de l'inserer dans le chat logProg.debug("ajout d'une image au chat : " + fichier) self.ajoutChat(str(emet), "".format(fichier)) def envoiMsg(self): """envoie un message pour le chat ecrit""" msg = self.ui.inChat.text() self.co.envoi("m ", "tc", msg) self.ui.inChat.clear() QApplication.processEvents() def lancerD(self, expr): """fonction de lancer de des""" res, detail = jet(expr) if res > 0: txt = "{}: {} ({}) [{}]".format(self.co.pseudo, res, detail, expr) self.co.envoi("id", "tc", txt) else: self.ajoutInfo("id", "mmmhh, pas bon le jet") return res def d20(self): """lance un D20""" self.lancerD("1d20") def d100(self): """lance un D100""" self.lancerD("1d100") def autreJet(self): """lance un jet personnalise""" expr = str(self.ui.inJetDes.text()) retour = self.lancerD(expr) self.ui.inJetDes.clear() def envoyerfichier(self): """selectionne et envoie un fichier ou annule l'envoi en cours s'il existe""" if self.co.eFichier["id"] == "00": fichier = QFileDialog.getOpenFileName( self, "Selectionnez un fichier a envoyer", "c:\\", "") if len(str(fichier)) > 0: self.co.envoiFichier(str(fichier)) else: self.co.annuleEnvoiFichier() def ouvrirFichier(self): """ouvre un fichier depuis la liste des fichiers recus/envoyes""" item = self.ui.listFichiers.currentItem() eR = item.text(0) taux = item.text(1) nom = item.text(2) if eR == "R": if taux == "ok": #try: chemin = "{}\\{}".format(self.co.repReceptionFichiers, nom) Popen(chemin, shell=True, stdout=PIPE) #from subprocess #except: # print("impossible d'ouvrir le fichier") def repReception(self): """permet de choisir son repertoire de reception des fichiers""" dossier = QFileDialog.getExistingDirectory(self) if dossier[len(dossier)-1:] != "\\": dossier += "\\" self.co.repReceptionFichiers = str(dossier) self.majStatut() def afficheReception(self, fichier, taux): """ajoute une ligne a la liste des fichiers en cours de reception""" fichier = str(fichier) taux = str(taux) if len(fichier) > 0: self.ligneRFichier = QTreeWidgetItem(self.ui.listFichiers, ["R", taux, fichier]) elif len(taux) > 0: if taux != self.ligneRFichier.text(1): self.ligneRFichier.setText(1, taux) def afficheEnvoi(self, fichier, taux): """ajoute une ligne a la liste des fichiers en cours d'envoi""" fichier = str(fichier) taux = str(taux) if len(fichier) > 0: self.ligneEFichier = QTreeWidgetItem(self.ui.listFichiers, ["E", taux, fichier]) elif len(taux) > 0: if taux != self.ligneEFichier.text(1): self.ligneEFichier.setText(1, taux) def majStatut(self): """met a jour la ligne de statut au pied de l'interface""" if self.co.serveur_connecte: txt = "Serveur : Oui" else: txt = "Serveur : Non" txt += " \ Pseudo : {}".format(self.co.pseudo) if self.estServeurVoc: txt += " \ Serveur vocal" if self.estClientVoc: txt += " \ connecte au chat vocal" self.msg(txt) self.ui.txt_repReception.setText(QString.fromUtf8("Fichiers recus : '{}'".format(self.co.repReceptionFichiers))) QApplication.processEvents() def creerServeurVoc(self): """cree un serveur vocal""" if not self.estServeurVoc: self.sVoc = ServeurVoc(6660) self.co.ipServeurVoc = "localhost" txt = self.sVoc.creer() self.ajoutInfo("vs", txt) if self.sVoc.serveur_lance: self.co.envoi("vs","ac","{}".format("localhost")) self.estServeurVoc = True self.majStatut() else: self.fermerServeurVoc() def fermerServeurVoc(self): """ferme le serveur vocal""" txt = self.sVoc.stop() self.ajoutInfo("vs", txt) if not self.sVoc.serveur_lance: self.co.envoi("vf","ac","") self.estServeurVoc = False self.majStatut() def chatVoc(self): """connexion au chat vocal""" if not self.estClientVoc: if len(self.co.ipServeurVoc) > 0: self.cVoc = ClientVoc(self.co.idClient, self.co.ipServeurVoc, 6660) txt = self.cVoc.creer() if self.cVoc.connecte: self.ajoutInfo("vi", txt) self.co.envoi("vi","ac","") self.estClientVoc = True self.majStatut() else: self.quitterChatVoc() def quitterChatVoc(self): """deconnexion du chat vocal""" if self.estClientVoc: txt = self.cVoc.stop() self.ajoutInfo("vq", txt) self.co.envoi("vq","ac","") self.estClientVoc = False self.majStatut() def closeEvent(self, event): """sur fermeture de la fenetre""" if self.estClientVoc: self.cVoc.stop() if self.estServeurVoc: self.sVoc.stop() self.co.fermer() sleep(0.01) self.connecte = False self.close() if __name__ == "__main__": demarrageOk = True #repertoire de travail et creation des dossiers necessaires: try: repCourant = os.getcwd() except: repCourant = "" if not len(repCourant) > 0: logProg.error("Impossible de determiner le repertoire courant") demarrageOk = False else: try: #repertoire media (musiques+images) if not os.path.exists(repCourant+"\\media"): os.mkdir(repCourant+"\\media") #repertoire utilisateur (sauvegardes) if not os.path.exists(repCourant+"\\svg"): os.mkdir(repCourant+"\\svg") #repertoire reception des fichiers persos if not os.path.exists(repCourant+"\\FichiersRecus"): os.mkdir(repCourant+"\\FichiersRecus") except: logProg.error("Erreur de creation des repertoires de l'application") demarrageOk = False #verif si l'appli est deja lancee: nomAppli = "DMonde.exe" compte = 0 for proc in process_iter(): #from psutil try: nomProc = proc.name() if nomProc == nomAppli: compte += 1 if compte > 1: demarrageOk = False logProg.error("Une instance de l'application est deja en cours d'execution") break except: pass if demarrageOk: #lancement de l'appli app = QApplication(argv) #'argv' vient de 'sys' connexion = EcranConnexion() connexion.show() r = app.exec_() if r == 0 and connexion.client_connecte: #si pas d'erreur et client connecte, on ouvre l'interface principale ecranChat = EcranChat(connexion) ecranChat.show() r = app.exec_() exit(r) #'exit' vient de 'sys'