def GetValeur(cle="", defaut="", theme=None): # lecture du thème if theme == None: theme = UTILS_Customize.GetValeur("interface", "theme", "Vert") # Lecture de la valeur if theme in DONNEES: if cle in DONNEES[theme]: return DONNEES[theme][cle] # Sinon renvoie la valeur par défaut return defaut
def Rechercher(self, event=None): # Récupération des champs saisis nom = self.ctrl_nom.GetValue() if nom == "": dlg = wx.MessageDialog(self, _(u"Vous devez renseigner le nom !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return prenom = self.ctrl_prenom.GetValue() if prenom == "": dlg = wx.MessageDialog(self, _(u"Vous devez renseigner le prénom !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return adresse = self.ctrl_adresse.GetValue() if adresse == "": dlg = wx.MessageDialog(self, _(u"Vous devez renseigner l'adresse !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return # Récupération de l'URL url = UTILS_Customize.GetValeur("referentiel", "url", None, ajouter_si_manquant=False) if url == None: dlg = wx.MessageDialog( self, _(u"Vous devez renseigner l'URL dans le fichier Customize !"), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return url = u"%s/%s* %s*" % (url, nom, prenom) # Requête try: reponse = requests.get(url) except Exception, error: self.ctrl_resultats.SetTexte(unicode(error)) return
def OnBoutonOutils(self, event): # Création du menu contextuel menuPop = wx.Menu() # Item Mesurer item = wx.MenuItem(menuPop, 10, _(u"Mesurer une distance")) item.SetBitmap(wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Transport.png"), wx.BITMAP_TYPE_PNG)) menuPop.AppendItem(item) self.Bind(wx.EVT_MENU, self.Mesurer_distance, id=10) # Contrôle if UTILS_Customize.GetValeur("referentiel", "url", None, ajouter_si_manquant=False) != None: item = wx.MenuItem(menuPop, 20, _(u"Contrôle référentiel")) item.SetBitmap(wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Personnes.png"), wx.BITMAP_TYPE_PNG)) menuPop.AppendItem(item) self.Bind(wx.EVT_MENU, self.Controle_referentiel, id=20) self.PopupMenu(menuPop) menuPop.Destroy()
def GetRepData(fichier=""): # Vérifie si un répertoire 'Portable' existe chemin = Chemins.GetMainPath("Portable") if os.path.isdir(chemin): chemin = os.path.join(chemin, "Data") if not os.path.isdir(chemin): os.mkdir(chemin) return os.path.join(chemin, fichier) # Recherche s'il existe un chemin personnalisé dans le Customize.ini chemin = UTILS_Customize.GetValeur("repertoire_donnees", "chemin", "") #chemin = chemin.decode("iso-8859-15") if chemin != "" and os.path.isdir(chemin): return os.path.join(chemin, fichier) # Recherche le chemin du répertoire des données if sys.platform == "win32" and platform.release() != "Vista": chemin = appdirs.site_data_dir(appname=None, appauthor=False) #chemin = chemin.decode("iso-8859-15") chemin = os.path.join(chemin, "teamworks") if not os.path.isdir(chemin): os.mkdir(chemin) else: chemin = appdirs.user_data_dir(appname=None, appauthor=False) #chemin = chemin.decode("iso-8859-15") chemin = os.path.join(chemin, "teamworks") if not os.path.isdir(chemin): os.mkdir(chemin) chemin = os.path.join(chemin, "Data") if not os.path.isdir(chemin): os.mkdir(chemin) # Ajoute le dirname si besoin return os.path.join(chemin, fichier)
def Rechercher(self, event=None): # Récupération des champs saisis nom = self.ctrl_nom.GetValue() if nom == "" : dlg = wx.MessageDialog(self, _(u"Vous devez renseigner le nom !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return prenom = self.ctrl_prenom.GetValue() if prenom == "" : dlg = wx.MessageDialog(self, _(u"Vous devez renseigner le prénom !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return adresse = self.ctrl_adresse.GetValue() if adresse == "" : dlg = wx.MessageDialog(self, _(u"Vous devez renseigner l'adresse !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return # Récupération de l'URL url = UTILS_Customize.GetValeur("referentiel", "url", None, ajouter_si_manquant=False) if url == None : dlg = wx.MessageDialog(self, _(u"Vous devez renseigner l'URL dans le fichier Customize !"), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return url = u"%s/%s* %s*" % (url, nom, prenom) # Requête try : reponse = requests.get(url) except Exception as error : self.ctrl_resultats.SetTexte(unicode(error)) return # Si erreur if reponse.status_code != 200: self.ctrl_resultats.SetTexte(_(u"Accès au référentiel impossible (Erreur %s)") % reponse.status_code) return # Conversion en XML root = ElementTree.fromstring(reponse.content) # Parcours le XML nbreResultats = 0 listeResultats = [] for child in root: ligne = {} for node in child.iter(): if "}nomOfficiel" in node.tag: ligne["nom"] = node.text if "}prenomUsuel" in node.tag: ligne["prenom"] = node.text if "}voieNumero" in node.tag: ligne["adresse"] = node.text nbreResultats += 1 listeResultats.append(ligne) # Analyse des résultats listeResultatsTraites = [] for dictTemp in listeResultats : texte1 = u"%s#%s#%s" % (dictTemp["nom"], dictTemp["prenom"], dictTemp["adresse"]) texte2 = u"%s#%s#%s" % (nom, prenom, adresse) pourcent = GetRatioDiffTextes(texte1, texte2) listeResultatsTraites.append((pourcent, dictTemp)) # Tri en fonction du nombre de similarités listeResultatsTraites.sort(reverse=True) # Affichage des résultats if nbreResultats > 0 : texte = _(u"<FONT SIZE=5><B>%d résultats :</B><BR></FONT><BR>") % nbreResultats else : texte = _(u"<FONT SIZE=5><B>Aucun résultat</B><BR></FONT><BR>") for pourcent, dictTemp in listeResultatsTraites : if pourcent == 100 : couleur = "GREEN" elif pourcent > 90 : couleur = "#FF8000" else : couleur = "RED" texte += _(u""" <FONT SIZE=2 COLOR='%s'>Pertinence : %s%%</FONT> <BR> Nom : <B>%s</B> <BR> Prénom : <B>%s</B> <BR> Adresse : <B>%s</B> <BR> <BR> """) % (couleur, pourcent, dictTemp["nom"], dictTemp["prenom"], dictTemp["adresse"]) # Affichage des résultats self.ctrl_resultats.SetTexte(texte)
def GetTheme(): return UTILS_Customize.GetValeur("interface", "theme", "Vert")
def Run(self, afficherDlgAttente=False): dictParametres = self.GetParametres() # Ouverture dlg d'attente if afficherDlgAttente == True: dlgAttente = wx.BusyInfo( _(u"Génération du fichier de données..."), None) try: # Génération du nom de fichier self.nomFichier = UTILS_Fichiers.GetRepTemp( fichier=u"data_%s" % dictParametres["IDfichier"]) # Vérifie si le fichier existe déj� nomFichierTemp = self.nomFichier + ".dat" if os.path.isfile(nomFichierTemp): os.remove(nomFichierTemp) # Création des tables dbdest = GestionDB.DB(suffixe=None, nomFichier=nomFichierTemp, modeCreation=True) dbdest.CreationTables(dicoDB=self.dictTables) # Enregistrement des paramètres listeParametres = [ ("IDfichier", dictParametres["IDfichier"]), ("horodatage", dictParametres["horodatage"]), ("type", "donnees"), ] self.Enregistrer(dbdest, nomTable="parametres", listeChamps=["nom", "valeur"], listeDonnees=listeParametres) # Données du dictIndividus from Utils import UTILS_Infos_individus infos = UTILS_Infos_individus.Informations() dictValeurs = infos.GetDictValeurs(mode="individu", formatChamp=False) listeDonnees = [] for ID, dictTemp in dictValeurs.items(): for champ, valeur in dictTemp.items(): if type(valeur) in (str, six.text_type) and valeur not in ( "", None): listeDonnees.append((ID, champ, valeur)) self.Enregistrer(dbdest, nomTable="informations", listeChamps=["IDindividu", "champ", "valeur"], listeDonnees=listeDonnees) # Données individus db = GestionDB.DB(suffixe="PHOTOS") req = """SELECT IDindividu, photo FROM photos;""" db.ExecuterReq(req) listePhotos = db.ResultatReq() db.Close() dictPhotos = {} for IDindividu, photo in listePhotos: dictPhotos[IDindividu] = photo db = GestionDB.DB() req = """SELECT IDindividu, IDcivilite, nom, prenom FROM individus;""" db.ExecuterReq(req) listeIndividus = db.ResultatReq() db.Close() listeDonnees = [] for IDindividu, IDcivilite, nom, prenom in listeIndividus: if IDindividu in dictPhotos: photo = sqlite3.Binary(dictPhotos[IDindividu]) else: photo = None listeDonnees.append( (IDindividu, IDcivilite, nom, prenom, photo)) self.Enregistrer(dbdest, nomTable="individus", listeChamps=[ "IDindividu", "IDcivilite", "nom", "prenom", "photo" ], listeDonnees=listeDonnees) # Données Titulaires de dossier dictTitulaires = UTILS_Titulaires.GetTitulaires() listeDonnees = [] for IDfamille, dictTemp in dictTitulaires.items(): nom = dictTitulaires[IDfamille]["titulairesSansCivilite"] listeDonnees.append((IDfamille, nom)) self.Enregistrer(dbdest, nomTable="titulaires", listeChamps=["IDfamille", "nom"], listeDonnees=listeDonnees) # Données organisateur db = GestionDB.DB() req = """SELECT IDorganisateur, nom, logo FROM organisateur;""" db.ExecuterReq(req) listeTemp = db.ResultatReq() db.Close() listeDonnees = [] for IDorganisateur, nom, logo in listeTemp: if logo != None: logo = sqlite3.Binary(logo) listeDonnees.append((IDorganisateur, nom, logo)) self.Enregistrer(dbdest, nomTable="organisateur", listeChamps=["IDorganisateur", "nom", "logo"], listeDonnees=listeDonnees) # Tables à copier en intégralité listeTables = [ "vacances", "jours_feries", "activites", "groupes", "unites", "unites_groupes", "unites_incompat", "unites_remplissage", "unites_remplissage_unites", "ouvertures", "remplissage", "inscriptions", "consommations", "memo_journee", "comptes_payeurs", "familles", "utilisateurs", "nomade_archivage", "niveaux_scolaires", "ecoles", "classes", "scolarite", ] self.CopieTables(dbdest, listeTables) # Cloture de la base dbdest.connexion.commit() dbdest.Close() # Compression fichierZip = zipfile.ZipFile(self.nomFichier + EXTENSION_DECRYPTE, "w", compression=zipfile.ZIP_DEFLATED) fichierZip.write(self.nomFichier + ".dat", "database.dat") fichierZip.close() os.remove(self.nomFichier + ".dat") # Cryptage cryptage_actif = UTILS_Config.GetParametre( "synchro_cryptage_activer", defaut=False) cryptage_mdp = base64.b64decode( UTILS_Config.GetParametre("synchro_cryptage_mdp", defaut="")) if six.PY3: cryptage_mdp = cryptage_mdp.decode() if cryptage_actif == True and cryptage_mdp != "": ancienne_methode = UTILS_Customize.GetValeur( "version_cryptage", "nomadhys", "1", ajouter_si_manquant=False) in ("1", None) UTILS_Cryptage_fichier.CrypterFichier( self.nomFichier + EXTENSION_DECRYPTE, self.nomFichier + EXTENSION_CRYPTE, cryptage_mdp, ancienne_methode=ancienne_methode) os.remove(self.nomFichier + EXTENSION_DECRYPTE) nomFichierFinal = self.nomFichier + EXTENSION_CRYPTE else: nomFichierFinal = self.nomFichier + EXTENSION_DECRYPTE except Exception as err: print("Erreur dans UTILS_Export_nomade.Run :", err) traceback.print_exc(file=sys.stdout) if afficherDlgAttente == True: del dlgAttente dlg = wx.MessageDialog( None, _(u"Désolé, l'erreur suivante a été rencontrée : ") + str(err), "Erreur ", wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return None if afficherDlgAttente == True: del dlgAttente return nomFichierFinal
def Sauvegarde(listeFichiersLocaux=[], listeFichiersReseau=[], nom="", repertoire=None, motdepasse=None, listeEmails=None, dictConnexion=None): """ Processus de de création du ZIP """ # Si aucun fichier à sauvegarder if len(listeFichiersLocaux) == 0 and len(listeFichiersReseau) == 0 : return False # Initialisation de la barre de progression nbreEtapes = 3 nbreEtapes += len(listeFichiersLocaux) nbreEtapes += len(listeFichiersReseau) if motdepasse != None : nbreEtapes += 1 if repertoire != None : nbreEtapes += 1 if listeEmails != None : nbreEtapes += 1 # Création du nom du fichier de destination if motdepasse != None : extension = EXTENSIONS["crypte"] else: extension = EXTENSIONS["decrypte"] # Vérifie si fichier de destination existe déjà if repertoire != None : fichierDest = u"%s/%s.%s" % (repertoire, nom, extension) if os.path.isfile(fichierDest) == True : dlg = wx.MessageDialog(None, _(u"Un fichier de sauvegarde portant ce nom existe déjà. \n\nVoulez-vous le remplacer ?"), "Attention !", wx.YES_NO | wx.NO_DEFAULT | wx.ICON_EXCLAMATION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES : return False # Récupération des paramètres de l'adresse d'expéditeur par défaut if listeEmails != None : dictAdresse = UTILS_Envoi_email.GetAdresseExpDefaut() if dictAdresse == None : dlgErreur = wx.MessageDialog(None, _(u"Envoi par Email impossible :\n\nAucune adresse d'expéditeur n'a été définie. Veuillez la saisir dans le menu Paramétrage du logiciel..."), _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False # Fenêtre de progression dlgprogress = wx.ProgressDialog(_(u"Sauvegarde"), _(u"Lancement de la sauvegarde..."), maximum=nbreEtapes, parent=None, style= wx.PD_SMOOTH | wx.PD_AUTO_HIDE | wx.PD_APP_MODAL) # Création du fichier ZIP temporaire nomFichierTemp = u"%s.%s" % (nom, EXTENSIONS["decrypte"]) fichierZip = zipfile.ZipFile(UTILS_Fichiers.GetRepTemp(fichier=nomFichierTemp), "w", compression=zipfile.ZIP_DEFLATED) numEtape = 1 dlgprogress.Update(numEtape, _(u"Création du fichier de compression..."));numEtape += 1 # Intégration des fichiers locaux for nomFichier in listeFichiersLocaux : dlgprogress.Update(numEtape, _(u"Compression du fichier %s...") % nomFichier);numEtape += 1 fichier = UTILS_Fichiers.GetRepData(nomFichier) if os.path.isfile(fichier) == True : fichierZip.write(fichier, nomFichier) else : dlgprogress.Destroy() dlgErreur = wx.MessageDialog(None, _(u"Le fichier '%s' n'existe plus sur cet ordinateur. \n\nVeuillez ôter ce fichier de la procédure de sauvegarde automatique (Menu Fichier > Sauvegardes automatiques)") % nomFichier, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False # Intégration des fichiers réseau if len(listeFichiersReseau) > 0 and dictConnexion != None : # Création du répertoire temporaire repTemp = UTILS_Fichiers.GetRepTemp(fichier="savetemp") if os.path.isdir(repTemp) == True : shutil.rmtree(repTemp) os.mkdir(repTemp) # Recherche du répertoire d'installation de MySQL repMySQL = GetRepertoireMySQL(dictConnexion) if repMySQL == None : dlgprogress.Destroy() dlgErreur = wx.MessageDialog(None, _(u"Noethys n'a pas réussi à localiser MySQL sur votre ordinateur.\n\nNotez bien que MySQL doit être installé obligatoirement pour créer une sauvegarde réseau."), _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False # Création du fichier de login nomFichierLoginTemp = repTemp + "/logintemp.cnf" #os.path.abspath(os.curdir) + "/" + repTemp + "/logintemp.cnf" CreationFichierLoginTemp(host=dictConnexion["host"], port=dictConnexion["port"], user=dictConnexion["user"], password=dictConnexion["password"], nomFichier=nomFichierLoginTemp) # Création du backup pour chaque fichier MySQL for nomFichier in listeFichiersReseau : dlgprogress.Update(numEtape, _(u"Compression du fichier %s...") % nomFichier);numEtape += 1 fichierSave = u"%s/%s.sql" % (repTemp, nomFichier) args = u""""%sbin/mysqldump" --defaults-extra-file="%s" --single-transaction --opt --databases %s > "%s" """ % (repMySQL, nomFichierLoginTemp, nomFichier, fichierSave) print(("Chemin mysqldump =", args)) if six.PY2: args = args.encode('utf8') proc = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE) out, temp = proc.communicate() if out not in ("", b""): print((out,)) try : if six.PY2: out = str(out).decode("iso-8859-15") except : pass dlgprogress.Destroy() dlgErreur = wx.MessageDialog(None, _(u"Une erreur a été détectée dans la procédure de sauvegarde !\n\nErreur : %s") % out, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False # Insère le fichier Sql dans le ZIP try : fichierZip.write(fichierSave.encode('utf8'), u"%s.sql" % nomFichier) except Exception as err : dlgprogress.Destroy() print(("insertion sql dans zip : ", err,)) try : if six.PY2: err = str(err).decode("iso-8859-15") except : pass dlgErreur = wx.MessageDialog(None, _(u"Une erreur est survenue dans la sauvegarde !\n\nErreur : %s") % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False # Supprime le répertoire temp shutil.rmtree(repTemp) # Finalise le fichier ZIP fichierZip.close() # Cryptage du fichier if motdepasse != None : dlgprogress.Update(numEtape, _(u"Cryptage du fichier..."));numEtape += 1 fichierCrypte = u"%s.%s" % (nom, EXTENSIONS["crypte"]) motdepasse = base64.b64decode(motdepasse) if six.PY3: motdepasse = motdepasse.decode('utf8') ancienne_methode = UTILS_Customize.GetValeur("version_cryptage", "sauvegarde", "1", ajouter_si_manquant=False) in ("1", None) UTILS_Cryptage_fichier.CrypterFichier(UTILS_Fichiers.GetRepTemp(fichier=nomFichierTemp), UTILS_Fichiers.GetRepTemp(fichier=fichierCrypte), motdepasse, ancienne_methode=ancienne_methode) nomFichierTemp = fichierCrypte extension = EXTENSIONS["crypte"] else: extension = EXTENSIONS["decrypte"] # Copie le fichier obtenu dans le répertoire donné if repertoire != None : dlgprogress.Update(numEtape, _(u"Création du fichier dans le répertoire cible..."));numEtape += 1 try : shutil.copy2(UTILS_Fichiers.GetRepTemp(fichier=nomFichierTemp), fichierDest) except : print("Le repertoire de destination de sauvegarde n'existe pas.") # Préparation du message message = UTILS_Envoi_email.Message(destinataires=listeEmails, sujet=_(u"Sauvegarde Noethys : %s") % nom, texte_html=_(u"Envoi de la sauvegarde de Noethys"), fichiers=[UTILS_Fichiers.GetRepTemp(fichier=nomFichierTemp),]) # Envoi par Email if listeEmails != None : dlgprogress.Update(numEtape, _(u"Expédition de la sauvegarde par Email..."));numEtape += 1 try : messagerie = UTILS_Envoi_email.Messagerie(backend=dictAdresse["moteur"], hote=dictAdresse["smtp"], port=dictAdresse["port"], utilisateur=dictAdresse["utilisateur"], motdepasse=dictAdresse["motdepasse"], email_exp=dictAdresse["adresse"], use_tls=dictAdresse["startTLS"], timeout=60*3, parametres=dictAdresse["parametres"]) messagerie.Connecter() messagerie.Envoyer(message) messagerie.Fermer() except Exception as err: dlgprogress.Destroy() print((err,)) if six.PY2: err = str(err).decode("iso-8859-15") dlgErreur = wx.MessageDialog(None, _(u"Une erreur a été détectée dans l'envoi par Email !\n\nErreur : %s") % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False # Suppression des répertoires et fichiers temporaires dlgprogress.Update(numEtape, _(u"Suppression des fichiers temporaires..."));numEtape += 1 fichier = UTILS_Fichiers.GetRepTemp(fichier=u"%s.%s" % (nom, EXTENSIONS["decrypte"])) if os.path.isfile(fichier) == True : os.remove(fichier) fichier = UTILS_Fichiers.GetRepTemp(fichier=u"%s.%s" % (nom, EXTENSIONS["crypte"])) if os.path.isfile(fichier) == True : os.remove(fichier) # Fin du processus dlgprogress.Update(numEtape, _(u"Sauvegarde terminée avec succès !")) dlgprogress.Destroy() return True