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 cryptage_actif == True and cryptage_mdp != "": UTILS_Cryptage_fichier.CrypterFichier( self.nomFichier + EXTENSION_DECRYPTE, self.nomFichier + EXTENSION_CRYPTE, cryptage_mdp) 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