| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957 |
- 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 = "<font color=\"blue\">{} : </font> {}".format(self.co.pseudo, msg)
- else:
- pseudo = self.co.autresCo["{}".format(emetteur)]
- txt = "<font color=\"green\">{} : </font> {}".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 = "<font color=\"green\">{}</font>".format(msg)
- elif nature == "id":
- txt = "<font color=\"red\">{}</font>".format(msg)
- elif nature[:1] == "f":
- txt = "<font color=\"blue\">{}</font>".format(msg)
- elif nature[:1] == "v":
- txt = "<font color=\"orange\">{}</font>".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), "<img src=\"{}\"/>".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'
-
-
-
-
-
|