def deleteExtension(extension): filename = UTILS_Fichiers.GetRepExtensions(extension) if os.path.isfile(filename): os.remove(filename)
def ModifierFichier(self, titre=""): """ Modifier un fichier """ if UTILS_Utilisateurs.VerificationDroitsUtilisateurActuel( "fichier_fichier", "modifier") == False: return if self.mode == "reseau": dlg = wx.MessageDialog( self, _(u"Il est impossible de modifier le nom d'un fichier réseau !" ), _(u"Désolé"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return # Demande de confirmation 1 dlg = wx.MessageDialog( None, _(u"Souhaitez-vous vraiment modifier le nom du fichier '%s' ?") % titre, _(u"Modifier un fichier"), wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_QUESTION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES: return # Demande le nouveau nom du fichier dlg = wx.TextEntryDialog( self, _(u"Saisissez un nouveau nom pour le fichier '%s' :") % titre, _(u"Modifier le nom"), titre) if dlg.ShowModal() == wx.ID_OK: nouveauTitre = dlg.GetValue() dlg.Destroy() else: dlg.Destroy() return if nouveauTitre == "": dlg = wx.MessageDialog( self, _(u"Le nom que vous avez saisi ne semble pas valide !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return # Demande de confirmation 2 dlg = wx.MessageDialog( None, _(u"Vous êtes vraiment sûr de vouloir changer le nom du fichier '%s' en '%s' ?" ) % (titre, nouveauTitre), _(u"Modifier un fichier"), wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_EXCLAMATION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES: return # Modifier un fichier local for suffixe in ("DATA", "DOCUMENTS", "PHOTOS"): try: source = UTILS_Fichiers.GetRepData(u"%s_%s.dat" % (titre, suffixe)) destination = UTILS_Fichiers.GetRepData( u"%s_%s.dat" % (nouveauTitre, suffixe)) os.rename(source, destination) except Exception as err: print(suffixe, "Erreur dans le renommage de fichier : ", err) self.Remplissage()
def Envoyer(self): # Demande de confirmation dlg = wx.MessageDialog(self, _(u"Confirmez-vous l'envoi du message vers %d numéros ?") % len(self.dictDonnees["liste_telephones"]), _(u"Confirmation"), wx.YES_NO|wx.YES_DEFAULT|wx.CANCEL|wx.ICON_QUESTION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES : return False # --------------------- CONTACT EVERYONE BY ORANGE BUSINESS --------------------- if self.dictDonnees["plateforme"] == "contact_everyone" : # Récupération adresse d'expédition IDadresse = self.dictDonnees["adresse_expedition_email"] dictAdresse = UTILS_Envoi_email.GetAdresseExp(IDadresse=IDadresse) # Génération de la pièce jointe liste_lignes = [] for ligne in self.dictDonnees["message"].split("\n") : liste_lignes.append(u"T-%s" % ligne) for numero in self.dictDonnees["liste_telephones"] : numero = numero.replace(".", "") liste_lignes.append(u"#-%s" % numero) texte = "\n".join(liste_lignes) cheminFichier = UTILS_Fichiers.GetRepTemp(fichier="sms.txt") fichier = open(cheminFichier, 'w') fichier.write(texte.encode("iso-8859-15")) fichier.close() # Préparation du message message = UTILS_Envoi_email.Message(destinataires=[self.dictDonnees["orange_adresse_destination_email"],], sujet=self.dictDonnees["objet"], texte_html=_(u"Envoi de SMS"), fichiers=[cheminFichier,]) # Envoi de l'email resultat = self.EnvoyerEmail(message=message, dictAdresse=dictAdresse) if resultat == False: return False # --------------------- CLEVER SMS --------------------- if self.dictDonnees["plateforme"] == "cleversms" : # Récupération adresse d'expédition IDadresse = self.dictDonnees["adresse_expedition_email"] dictAdresse = UTILS_Envoi_email.GetAdresseExp(IDadresse=IDadresse) # Génération de la pièce jointe liste_lignes = [] message = self.dictDonnees["message"].replace("\n", "") for numero in self.dictDonnees["liste_telephones"] : numero = numero.replace(".", "") liste_lignes.append(u"%s;%s" % (numero, message)) texte = "\n".join(liste_lignes) cheminFichier = UTILS_Fichiers.GetRepTemp(fichier="sms.txt") fichier = open(cheminFichier, 'w') fichier.write(texte.encode("iso-8859-15")) fichier.close() # Préparation du message message = UTILS_Envoi_email.Message(destinataires=[self.dictDonnees["cleversms_adresse_destination_email"],], sujet=self.dictDonnees["objet"], texte_html=_(u"Envoi de SMS"), fichiers=[cheminFichier,]) # Envoi de l'email resultat = self.EnvoyerEmail(message=message, dictAdresse=dictAdresse) if resultat == False: return False # --------------------- CLEVER MULTIMEDIAS --------------------- if self.dictDonnees["plateforme"] == "clevermultimedias" : # Récupération adresse d'expédition IDadresse = self.dictDonnees["adresse_expedition_email"] dictAdresse = UTILS_Envoi_email.GetAdresseExp(IDadresse=IDadresse) # Génération de la pièce jointe liste_lignes = ["NUM;MESSAGE",] message = self.dictDonnees["message"].replace("\n", "") for numero in self.dictDonnees["liste_telephones"] : numero = numero.replace(".", "") numero = "+33" + numero[1:] liste_lignes.append(u"%s;%s" % (numero, message)) texte = "\n".join(liste_lignes) cheminFichier = UTILS_Fichiers.GetRepTemp(fichier="sms.txt") fichier = open(cheminFichier, 'w') fichier.write(texte.encode("iso-8859-15")) fichier.close() # Préparation du message message = UTILS_Envoi_email.Message(destinataires=[self.dictDonnees["clevermultimedias_adresse_destination_email"],], sujet=self.dictDonnees["objet"], texte_html=_(u"Envoi de SMS"), fichiers=[cheminFichier,]) # Envoi de l'email resultat = self.EnvoyerEmail(message=message, dictAdresse=dictAdresse) if resultat == False: return False # Confirmation d'envoi dlg = wx.MessageDialog(self, _(u"Envoi des SMS effectué avec succès."), _(u"Confirmation"), wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() return True
import importlib import wx import Data import traceback VERSION = "_v2.0.2" ext = "py" mainFile = "ext_Extensions_automatiques.py" listeErreurs = {} # Ajouter la version du bootstrap dans le repertoire des extensions chargées Data.extensionsAutomatiques = ["Utils__init__" + VERSION] # Ajouter le repertoire des extensions au PATH sys.path.append(UTILS_Fichiers.GetRepExtensions()) def getFileList(): """Récupére la liste des fichiers d'extensions""" dossierExtensions = UTILS_Fichiers.GetRepExtensions() if not os.path.isdir(dossierExtensions): return () fichiers = os.listdir(dossierExtensions) fichiers.sort() return fichiers def launch(fichier): """Execute les Initialisation des extensions et collecte les erreurs""" if not fichier.endswith(ext):
def OnBoutonOk(self, event): dictParametres = self.ctrl_notebook.GetParametres() # Récupération et vérification des données listeActivites = dictParametres["liste_activites"] if len(listeActivites) == 0: self.ctrl_notebook.AffichePage("generalites") dlg = wx.MessageDialog( self, _(u"Vous devez obligatoirement cocher au moins une activité !" ), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Récupération et vérification des données listeGroupes = dictParametres["liste_groupes"] if len(dictParametres["liste_groupes"]) == 0: self.ctrl_notebook.AffichePage("generalites") dlg = wx.MessageDialog( self, _(u"Vous devez obligatoirement cocher au moins un groupe !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Thème global IMAGE_FOND if dictParametres["theme"] != None: IMAGE_FOND = Chemins.GetStaticPath(THEMES[dictParametres["theme"]]) else: IMAGE_FOND = None # Création du PDF self.taille_page = A4 self.orientation = "PORTRAIT" if self.orientation == "PORTRAIT": self.hauteur_page = self.taille_page[1] self.largeur_page = self.taille_page[0] else: self.hauteur_page = self.taille_page[0] self.largeur_page = self.taille_page[1] # Création des conditions pour les requêtes SQL conditionsPeriodes = GetSQLdates(dictParametres["liste_periodes"]) if len(listeActivites) == 0: conditionActivites = "()" elif len(listeActivites) == 1: conditionActivites = "(%d)" % listeActivites[0] else: conditionActivites = str(tuple(listeActivites)) if len(listeGroupes) == 0: conditionGroupes = "()" elif len(listeGroupes) == 1: conditionGroupes = "(%d)" % listeGroupes[0] else: conditionGroupes = str(tuple(listeGroupes)) # Récupération des noms des groupes dictGroupes = dictParametres["dict_groupes"] DB = GestionDB.DB() # Récupération des individus grâce à leurs consommations self.EcritStatusBar(_(u"Recherche des individus...")) # ------------ MODE PRESENTS --------------------------------- if dictParametres["mode"] == "presents": # Récupération de la liste des groupes ouverts sur cette période req = """SELECT IDouverture, IDactivite, IDunite, IDgroupe FROM ouvertures WHERE ouvertures.IDactivite IN %s AND %s AND IDgroupe IN %s ; """ % (conditionActivites, conditionsPeriodes, conditionGroupes) DB.ExecuterReq(req) listeOuvertures = DB.ResultatReq() dictOuvertures = {} for IDouverture, IDactivite, IDunite, IDgroupe in listeOuvertures: if dictOuvertures.has_key(IDactivite) == False: dictOuvertures[IDactivite] = [] if IDgroupe not in dictOuvertures[IDactivite]: dictOuvertures[IDactivite].append(IDgroupe) # Récupération des individus grâce à leurs consommations req = """SELECT individus.IDindividu, IDcivilite, nom, prenom, date_naiss FROM consommations LEFT JOIN individus ON individus.IDindividu = consommations.IDindividu WHERE consommations.etat IN ("reservation", "present") AND IDactivite IN %s AND %s GROUP BY individus.IDindividu ORDER BY nom, prenom ;""" % (conditionActivites, conditionsPeriodes) DB.ExecuterReq(req) listeIndividus = DB.ResultatReq() # ------------ MODE INSCRITS --------------------------------- if dictParametres["mode"] == "inscrits": dictOuvertures = {} for IDgroupe, dictGroupe in dictGroupes.iteritems(): IDactivite = dictGroupe["IDactivite"] if dictOuvertures.has_key(IDactivite) == False: dictOuvertures[IDactivite] = [] if IDgroupe not in dictOuvertures[IDactivite]: dictOuvertures[IDactivite].append(IDgroupe) # Récupération des individus inscrits req = """SELECT individus.IDindividu, IDcivilite, nom, prenom, date_naiss FROM individus LEFT JOIN inscriptions ON inscriptions.IDindividu = individus.IDindividu WHERE inscriptions.statut='ok' AND IDactivite IN %s GROUP BY individus.IDindividu ORDER BY nom, prenom ;""" % conditionActivites DB.ExecuterReq(req) listeIndividus = DB.ResultatReq() DB.Close() if len(listeIndividus) == 0: dlg = wx.MessageDialog( self, _(u"Aucun individu n'a été trouvé avec les paramètres spécifiés !" ), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() self.EcritStatusBar(u"") return dictIndividus = {} listeIDindividus = [] dictAnniversaires = {} self.EcritStatusBar(_(u"Recherche des dates de naissance...")) for IDindividu, IDcivilite, nom, prenom, date_naiss in listeIndividus: if date_naiss != None: date_naiss = UTILS_Dates.DateEngEnDateDD(date_naiss) age = GetAge(date_naiss) jour = date_naiss.day mois = date_naiss.month # Mémorisation de l'individu dictIndividus[IDindividu] = { "IDcivilite": IDcivilite, "nom": nom, "prenom": prenom, "age": age, "date_naiss": date_naiss, } # Mémorisation du IDindividu if dictAnniversaires.has_key(mois) == False: dictAnniversaires[mois] = {} if dictAnniversaires[mois].has_key(jour) == False: dictAnniversaires[mois][jour] = [] dictAnniversaires[mois][jour].append(IDindividu) if IDindividu not in listeIDindividus: listeIDindividus.append(IDindividu) # Récupération des photos individuelles dictPhotos = {} taillePhoto = 128 if dictParametres["taille_photo"] != 0: index = 0 for IDindividu in listeIDindividus: self.EcritStatusBar( _(u"Recherche des photos... %d/%d") % (index, len(listeIDindividus))) IDcivilite = dictIndividus[IDindividu]["IDcivilite"] nomFichier = Chemins.GetStaticPath( "Images/128x128/%s" % DICT_CIVILITES[IDcivilite]["nomImage"]) IDphoto, bmp = CTRL_Photo.GetPhoto(IDindividu=IDindividu, nomFichier=nomFichier, taillePhoto=(taillePhoto, taillePhoto), qualite=100) # Création de la photo dans le répertoire Temp nomFichier = UTILS_Fichiers.GetRepTemp( fichier="photoTmp%d.jpg" % IDindividu) bmp.SaveFile(nomFichier, type=wx.BITMAP_TYPE_JPEG) img = Image(nomFichier, width=dictParametres["taille_photo"], height=dictParametres["taille_photo"]) dictPhotos[IDindividu] = img index += 1 # ---------------- Création du PDF ------------------- self.EcritStatusBar(_(u"Création du PDF...")) # Initialisation du PDF nomDoc = FonctionsPerso.GenerationNomDoc("ANNIVERSAIRES", "pdf") if sys.platform.startswith("win"): nomDoc = nomDoc.replace("/", "\\") doc = BaseDocTemplate(nomDoc, pagesize=(self.largeur_page, self.hauteur_page), topMargin=30, bottomMargin=30, showBoundary=False) doc.addPageTemplates( MyPageTemplate(pageSize=(self.largeur_page, self.hauteur_page))) story = [] # Mois listeMois = dictAnniversaires.keys() listeMois.sort() for numMois in listeMois: # Mémorise le numéro de mois pour le titre de la page nomMois = LISTE_NOMS_MOIS[numMois - 1] story.append(DocAssign("numMois", numMois)) # Jours dictJours = dictAnniversaires[numMois] listeJours = dictJours.keys() listeJours.sort() for numJour in listeJours: # Initialisation du tableau dataTableau = [] largeursColonnes = [] # Recherche des entêtes de colonnes : if dictParametres["taille_photo"] != 0: largeursColonnes.append(dictParametres["taille_photo"] + 6) # Colonne nom de l'individu largeursColonnes.append(LARGEUR_COLONNE - sum(largeursColonnes)) # Label numéro de jour ligne = [] ligne.append(str(numJour)) if dictParametres["taille_photo"] != 0: ligne.append(u"") dataTableau.append(ligne) # Individus listeIndividus = dictAnniversaires[numMois][numJour] for IDindividu in listeIndividus: ligne = [] # Photo if dictParametres[ "taille_photo"] != 0 and IDindividu in dictPhotos: img = dictPhotos[IDindividu] ligne.append(img) # Nom nom = dictIndividus[IDindividu]["nom"] prenom = dictIndividus[IDindividu]["prenom"] ligne.append(u"%s %s" % (nom, prenom)) # Ajout de la ligne individuelle dans le tableau dataTableau.append(ligne) couleurFondJour = (0.8, 0.8, 1) # Vert -> (0.5, 1, 0.2) couleurFondTableau = (1, 1, 1) style = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), # Centre verticalement toutes les cases ('BACKGROUND', (0, 0), (-1, -1), couleurFondTableau ), # Donne la couleur de fond du titre de groupe ('FONT', (0, 0), (-1, -1), "Helvetica", 7), # Donne la police de caract. + taille de police ('GRID', (0, 0), (-1, -1), 0.25, colors.black ), # Crée la bordure noire pour tout le tableau ('ALIGN', (0, 1), (-1, -1), 'CENTRE'), # Centre les cases ( 'SPAN', (0, 0), (-1, 0) ), # Fusionne les lignes du haut pour faire le titre du groupe ( 'FONT', (0, 0), (0, 0), "Helvetica-Bold", 10 ), # Donne la police de caract. + taille de police du titre de groupe ('BACKGROUND', (0, 0), (-1, 0), couleurFondJour ), # Donne la couleur de fond du titre de groupe ]) # Création du tableau tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0, 10)) # Saut de page après un mois story.append(PageBreak()) # Enregistrement du PDF doc.build(story) # Affichage du PDF FonctionsPerso.LanceFichierExterne(nomDoc) self.EcritStatusBar(u"")
def __init__(self, liste_labelsColonnes=[], listeValeurs=[], listeSelections=[]): """ Imprime la liste de personnes """ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle from reportlab.rl_config import defaultPageSize from reportlab.lib.units import inch, cm from reportlab.lib.pagesizes import A4, portrait, landscape from reportlab.lib import colors hauteur_page = defaultPageSize[0] largeur_page = defaultPageSize[1] largeur_ligne = largeur_page - (75 * 2) # Initialisation du PDF nomDoc = UTILS_Fichiers.GetRepTemp("liste_personnes.pdf") if "win" in sys.platform: nomDoc = nomDoc.replace("/", "\\") doc = SimpleDocTemplate(nomDoc, pagesize=landscape(A4)) story = [] # Création du titre du document dataTableau = [] largeursColonnes = ((620, 100)) dateDuJour = DateEngFr(str(datetime.date.today())) dataTableau.append( (_(u"Liste de personnes"), _(u"Edité le %s") % dateDuJour)) style = TableStyle([ ('BOX', (0, 0), (-1, -1), 0.25, colors.black), ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('ALIGN', (0, 0), (0, 0), 'LEFT'), ('FONT', (0, 0), (0, 0), "Helvetica-Bold", 16), ('ALIGN', (1, 0), (1, 0), 'RIGHT'), ('FONT', (1, 0), (1, 0), "Helvetica", 6), ]) tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0, 20)) # Tableau de données dataTableau = [] # Création des colonnes largeursColonnes = [] labelsColonnes = [] index = 0 for labelCol, alignement, largeur, nomChamp in liste_labelsColonnes: largeursColonnes.append(largeur / 2) labelsColonnes.append(labelCol) index += 1 dataTableau.append(labelsColonnes) # Création des lignes for valeurs in listeValeurs: ligne = [] if int(valeurs[0]) in listeSelections: for valeur in valeurs: ligne.append(valeur) dataTableau.append(ligne) # Style du tableau style = TableStyle([ ('GRID', (0, 0), (-1, -1), 0.25, colors.black), # Crée la bordure noire pour tout le tableau ('ALIGN', (0, 0), (-1, -1), 'LEFT'), # Titre du groupe à gauche ('FONT', (0, 0), (-1, -1), "Helvetica", 6), # Donne la police de caract. + taille de police ]) # Création du tableau tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0, 20)) # Enregistrement du PDF doc.build(story) # Affichage du PDF FonctionsPerso.LanceFichierExterne(nomDoc)
def Envoyer_mail(self, commentaires="", joindre_journal=False): """ Envoi d'un mail avec pièce jointe """ from Utils import UTILS_Envoi_email # Expéditeur dictExp = self.GetAdresseExpDefaut() if dictExp == None : dlg = wx.MessageDialog(self, _(u"Vous devez d'abord saisir une adresse d'expéditeur depuis le menu Paramétrage > Adresses d'expédition d'Emails. Sinon, postez votre rapport de bug dans le forum de Noethys."), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False moteur = dictExp["moteur"] adresseExpediteur = dictExp["adresse"] serveur = dictExp["smtp"] port = dictExp["port"] auth = dictExp["auth"] startTLS = dictExp["startTLS"] motdepasse = dictExp["motdepasse"] utilisateur = dictExp["utilisateur"] parametres = dictExp["parametres"] if adresseExpediteur == None : dlg = wx.MessageDialog(self, _(u"L'adresse d'expédition ne semble pas valide. Veuillez la vérifier."), _(u"Envoi impossible"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Attacher le journal d'erreurs fichiers = [] if joindre_journal == True : customize = UTILS_Customize.Customize() nom_journal = UTILS_Fichiers.GetRepUtilisateur(customize.GetValeur("journal", "nom", "journal.log")) fichiers.append(nom_journal) # Préparation du message IDrapport = datetime.datetime.now().strftime("%Y%m%d%H%M%S") texteRapport = self.ctrl_rapport.GetValue().replace("\n","<br/>") if len(commentaires) == 0 : commentaires = _(u"Aucun") texte_html = _(u"<u>Rapport de bug %s :</u><br/><br/>%s<br/><u>Commentaires :</u><br/><br/>%s") % (IDrapport, texteRapport, commentaires) sujet = _(u"Rapport de bug Noethys n°%s") % IDrapport message = UTILS_Envoi_email.Message(destinataires=["noe" + "thys" + "@" + "gm" + "ail" + ".com",], sujet=sujet, texte_html=texte_html, fichiers=fichiers) # Envoi du mail try : messagerie = UTILS_Envoi_email.Messagerie(backend=moteur, hote=serveur, port=port, utilisateur=utilisateur, motdepasse=motdepasse, email_exp=adresseExpediteur, use_tls=startTLS, parametres=parametres) messagerie.Connecter() messagerie.Envoyer(message) messagerie.Fermer() except Exception as err : dlg = wx.MessageDialog(self, _(u"Le message n'a pas pu être envoyé. Merci de poster votre rapport de bug sur le forum de Noethys.\n\nErreur : %s !") % err, _(u"Envoi impossible"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Message de confirmation dlg = wx.MessageDialog(self, _(u"Le rapport d'erreur a été envoyé avec succès."), _(u"Rapport envoyé"), wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() return True
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
def OnBoutonOk(self, event): dictParametres = self.ctrl_notebook.GetParametres() # Récupération et vérification des données listeActivites = dictParametres["liste_activites"] if len(listeActivites) == 0 : self.ctrl_notebook.AffichePage("generalites") dlg = wx.MessageDialog(self, _(u"Vous devez obligatoirement cocher au moins une activité !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Récupération et vérification des données listeGroupes = dictParametres["liste_groupes"] if len(dictParametres["liste_groupes"]) == 0 : self.ctrl_notebook.AffichePage("generalites") dlg = wx.MessageDialog(self, _(u"Vous devez obligatoirement cocher au moins un groupe !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Vérification qu'il y a des colonnes if not dictParametres["colonnes"]: dlg = wx.MessageDialog(self, _(u"Vous devez obligatoirement créer au moins une colonne !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Recherche les catégories utilisées liste_categories_utilisees = [] for nom_categorie, categories in dictParametres["colonnes"]: for IDcategorie in UTILS_Texte.ConvertStrToListe(categories): if IDcategorie not in liste_categories_utilisees : liste_categories_utilisees.append(IDcategorie) # Création du PDF from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak from reportlab.platypus.flowables import ParagraphAndImage, Image from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.styles import ParagraphStyle self.taille_page = A4 if dictParametres["orientation"] == "portrait" : self.hauteur_page = self.taille_page[1] self.largeur_page = self.taille_page[0] else: self.hauteur_page = self.taille_page[0] self.largeur_page = self.taille_page[1] # Création des conditions pour les requêtes SQL conditionsPeriodes = GetSQLdates(dictParametres["liste_periodes"]) if len(listeActivites) == 0 : conditionActivites = "()" elif len(listeActivites) == 1 : conditionActivites = "(%d)" % listeActivites[0] else : conditionActivites = str(tuple(listeActivites)) if len(listeGroupes) == 0 : conditionGroupes = "()" elif len(listeGroupes) == 1 : conditionGroupes = "(%d)" % listeGroupes[0] else : conditionGroupes = str(tuple(listeGroupes)) # Récupération des noms des groupes dictGroupes = dictParametres["dict_groupes"] dictActivites = dictParametres["dict_activites"] DB = GestionDB.DB() # ------------ MODE PRESENTS --------------------------------- if dictParametres["mode"] == "presents" : # Récupération de la liste des groupes ouverts sur cette période req = """SELECT IDouverture, IDactivite, IDunite, IDgroupe FROM ouvertures WHERE ouvertures.IDactivite IN %s AND %s AND IDgroupe IN %s ; """ % (conditionActivites, conditionsPeriodes, conditionGroupes) DB.ExecuterReq(req) listeOuvertures = DB.ResultatReq() dictOuvertures = {} for IDouverture, IDactivite, IDunite, IDgroupe in listeOuvertures : if (IDactivite in dictOuvertures) == False : dictOuvertures[IDactivite] = [] if IDgroupe not in dictOuvertures[IDactivite] : dictOuvertures[IDactivite].append(IDgroupe) # Récupération des individus grâce à leurs consommations req = """SELECT individus.IDindividu, IDactivite, IDgroupe, IDcivilite, nom, prenom, date_naiss FROM consommations LEFT JOIN individus ON individus.IDindividu = consommations.IDindividu WHERE consommations.etat IN ("reservation", "present") AND IDactivite IN %s AND %s GROUP BY individus.IDindividu, IDactivite, IDgroupe ORDER BY nom, prenom ;""" % (conditionActivites, conditionsPeriodes) DB.ExecuterReq(req) listeIndividus = DB.ResultatReq() # ------------ MODE INSCRITS --------------------------------- if dictParametres["mode"] == "inscrits" : dictOuvertures = {} for IDgroupe, dictGroupe in dictGroupes.items() : IDactivite = dictGroupe["IDactivite"] if (IDactivite in dictOuvertures) == False : dictOuvertures[IDactivite] = [] if IDgroupe not in dictOuvertures[IDactivite] : dictOuvertures[IDactivite].append(IDgroupe) # Récupération des individus grâce à leurs consommations req = """SELECT individus.IDindividu, IDactivite, IDgroupe, IDcivilite, nom, prenom, date_naiss FROM individus LEFT JOIN inscriptions ON inscriptions.IDindividu = individus.IDindividu WHERE inscriptions.statut='ok' AND IDactivite IN %s GROUP BY individus.IDindividu, IDactivite, IDgroupe ORDER BY nom, prenom ;""" % conditionActivites DB.ExecuterReq(req) listeIndividus = DB.ResultatReq() # Analyse des individus dictIndividus = {} listeIDindividus = [] for IDindividu, IDactivite, IDgroupe, IDcivilite, nom, prenom, date_naiss in listeIndividus: if date_naiss != None: date_naiss = UTILS_Dates.DateEngEnDateDD(date_naiss) age = self.GetAge(date_naiss) # Mémorisation de l'individu dictIndividus[IDindividu] = { "IDcivilite": IDcivilite, "nom": nom, "prenom": prenom, "age": age, "date_naiss": date_naiss, "IDgroupe": IDgroupe, "IDactivite": IDactivite, } # Mémorisation du IDindividu if IDindividu not in listeIDindividus: listeIDindividus.append(IDindividu) # Dict Informations médicales req = """SELECT IDprobleme, IDindividu, IDtype, intitule, date_debut, date_fin, description, traitement_medical, description_traitement, date_debut_traitement, date_fin_traitement, eviction, date_debut_eviction, date_fin_eviction FROM problemes_sante WHERE diffusion_listing_enfants=1 ;""" DB.ExecuterReq(req) listeInformations = DB.ResultatReq() DB.Close() dictInfosMedicales = {} for IDprobleme, IDindividu, IDtype, intitule, date_debut, date_fin, description, traitement_medical, description_traitement, date_debut_traitement, date_fin_traitement, eviction, date_debut_eviction, date_fin_eviction in listeInformations : if (IDindividu in dictInfosMedicales) == False : dictInfosMedicales[IDindividu] = [] dictTemp = { "IDprobleme" : IDprobleme, "IDcategorie" : IDtype, "intitule" : intitule, "date_debut" : date_debut, "date_fin" : date_fin, "description" : description, "traitement_medical" : traitement_medical, "description_traitement" : description_traitement, "date_debut_traitement" : date_debut_traitement, "date_fin_traitement" : date_fin_traitement, "eviction" : eviction, "date_debut_eviction" : date_debut_eviction, "date_fin_eviction" : date_fin_eviction, } dictInfosMedicales[IDindividu].append(dictTemp) # Récupération des photos individuelles dictPhotos = {} taillePhoto = 128 if dictParametres["afficher_photos"] == "petite" : tailleImageFinal = 16 if dictParametres["afficher_photos"] == "moyenne" : tailleImageFinal = 32 if dictParametres["afficher_photos"] == "grande" : tailleImageFinal = 64 if dictParametres["afficher_photos"] != "non" : for IDindividu in listeIDindividus : IDcivilite = dictIndividus[IDindividu]["IDcivilite"] nomFichier = Chemins.GetStaticPath("Images/128x128/%s" % DICT_CIVILITES[IDcivilite]["nomImage"]) IDphoto, bmp = CTRL_Photo.GetPhoto(IDindividu=IDindividu, nomFichier=nomFichier, taillePhoto=(taillePhoto, taillePhoto), qualite=100) # Création de la photo dans le répertoire Temp nomFichier = UTILS_Fichiers.GetRepTemp(fichier="photoTmp%d.jpg" % IDindividu) bmp.SaveFile(nomFichier, type=wx.BITMAP_TYPE_JPEG) img = Image(nomFichier, width=tailleImageFinal, height=tailleImageFinal) dictPhotos[IDindividu] = img # ---------------- Création du PDF ------------------- # Initialisation du PDF nomDoc = FonctionsPerso.GenerationNomDoc("LISTE_INFORMATIONS_MEDICALES", "pdf") if sys.platform.startswith("win") : nomDoc = nomDoc.replace("/", "\\") doc = SimpleDocTemplate(nomDoc, pagesize=(self.largeur_page, self.hauteur_page), topMargin=30, bottomMargin=30) story = [] largeurContenu = self.largeur_page - 75 # Création du titre du document def Header(): dataTableau = [] largeursColonnes = ( (largeurContenu-100, 100) ) dateDuJour = UTILS_Dates.DateEngFr(str(datetime.date.today())) dataTableau.append( (_(u"Informations médicales"), _(u"%s\nEdité le %s") % (UTILS_Organisateur.GetNom(), dateDuJour)) ) style = TableStyle([ ('BOX', (0,0), (-1,-1), 0.25, colors.black), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('ALIGN', (0,0), (0,0), 'LEFT'), ('FONT',(0,0),(0,0), "Helvetica-Bold", 16), ('ALIGN', (1,0), (1,0), 'RIGHT'), ('FONT',(1,0),(1,0), "Helvetica", 6), ]) tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0,20)) # Insère un header Header() # Activités for IDactivite in listeActivites : # Groupes if IDactivite in dictOuvertures : nbreGroupes = len(dictOuvertures[IDactivite]) indexGroupe = 1 for IDgroupe in dictOuvertures[IDactivite] : nomGroupe = dictGroupes[IDgroupe]["nom"] if isinstance(dictActivites[IDactivite], dict): nomActivite = dictActivites[IDactivite]["nom"] else: nomActivite = dictActivites[IDactivite] # Initialisation du tableau dataTableau = [] largeursColonnes = [] labelsColonnes = [] # Recherche des entêtes de colonnes : if dictParametres["afficher_photos"] != "non" : labelsColonnes.append(_(u"Photo")) largeursColonnes.append(tailleImageFinal+6) labelsColonnes.append(_(u"Nom - prénom")) if dictParametres["largeur_colonne_nom"] == "automatique" : largeursColonnes.append(120) else : largeursColonnes.append(int(dictParametres["largeur_colonne_nom"])) if dictParametres["afficher_age"] == True : labelsColonnes.append(_(u"Âge")) if dictParametres["largeur_colonne_age"] == "automatique": largeursColonnes.append(20) else: largeursColonnes.append(int(dictParametres["largeur_colonne_age"])) # Calcule la largeur restante largeurRestante = largeurContenu - sum(largeursColonnes) # Calcul des largeurs de colonnes largeurColonnes = largeurRestante * 1.0 / len(dictParametres["colonnes"]) for nom_categorie, categories in dictParametres["colonnes"]: labelsColonnes.append(nom_categorie) largeursColonnes.append(largeurColonnes) # Création de l'entete de groupe ligne = [u"%s - %s" % (nomActivite, nomGroupe),] for x in range(0, len(labelsColonnes)-1): ligne.append("") dataTableau.append(ligne) # Création des entêtes ligne = [] for label in labelsColonnes : ligne.append(label) dataTableau.append(ligne) # --------- Création des lignes ----------- # Création d'une liste temporaire pour le tri listeIndividus = [] if IDactivite in dictOuvertures : if IDgroupe in dictOuvertures[IDactivite] : for IDindividu in listeIDindividus : dictIndividu = dictIndividus[IDindividu] if dictIndividu["IDgroupe"] == IDgroupe : valeursTri = (IDindividu, dictIndividu["nom"], dictIndividu["prenom"], dictIndividu["age"]) # + Sélection uniquement des individus avec infos if dictParametres["individus_avec_infos"] == False or (dictParametres["individus_avec_infos"] == True and IDindividu in dictInfosMedicales ) : listeIndividus.append(valeursTri) if dictParametres["tri"] == "nom" : paramTri = 1 # Nom if dictParametres["tri"] == "prenom" : paramTri = 2 # Prénom if dictParametres["tri"] == "age" : paramTri = 3 # Age if dictParametres["ordre"] == "croissant" : ordreDecroissant = False else: ordreDecroissant = True listeIndividus = sorted(listeIndividus, key=operator.itemgetter(paramTri), reverse=ordreDecroissant) # Récupération des lignes individus for IDindividu, nom, prenom, age in listeIndividus : dictIndividu = dictIndividus[IDindividu] ligne = [] # Photo if dictParametres["afficher_photos"] != "non" and IDindividu in dictPhotos : img = dictPhotos[IDindividu] ligne.append(img) # Nom ligne.append(u"%s %s" % (nom, prenom)) # Age if dictParametres["afficher_age"] == True : if age != None : ligne.append(age) else: ligne.append("") # Informations médicales paraStyle = ParagraphStyle(name="infos", fontName="Helvetica", fontSize=7, leading=8, spaceAfter=2, ) # Création des colonnes has_infos = False for nom_categorie, categories in dictParametres["colonnes"]: liste_categories = UTILS_Texte.ConvertStrToListe(categories) case = [] # Recherche s'il y a une info médicale dans cette case if IDindividu in dictInfosMedicales: for infoMedicale in dictInfosMedicales[IDindividu] : IDcategorie = infoMedicale["IDcategorie"] if IDcategorie in liste_categories or (0 in liste_categories and IDcategorie not in liste_categories_utilisees) : intitule = infoMedicale["intitule"] description = infoMedicale["description"] traitement = infoMedicale["traitement_medical"] description_traitement = infoMedicale["description_traitement"] date_debut_traitement = infoMedicale["date_debut_traitement"] date_fin_traitement = infoMedicale["date_fin_traitement"] # Intitulé et description if description != None and description != "": texteInfos = u"<b>%s</b> : %s" % (intitule, description) else: texteInfos = u"%s" % intitule if len(texteInfos) > 0 and texteInfos[-1] != ".": texteInfos += u"." # Traitement médical if traitement == 1 and description_traitement != None and description_traitement != "": texteDatesTraitement = u"" if date_debut_traitement != None and date_fin_traitement != None: texteDatesTraitement = _(u" du %s au %s") % (UTILS_Dates.DateEngFr(date_debut_traitement), UTILS_Dates.DateEngFr(date_fin_traitement)) if date_debut_traitement != None and date_fin_traitement == None: texteDatesTraitement = _(u" à partir du %s") % UTILS_Dates.DateEngFr(date_debut_traitement) if date_debut_traitement == None and date_fin_traitement != None: texteDatesTraitement = _(u" jusqu'au %s") % UTILS_Dates.DateEngFr(date_fin_traitement) texteInfos += _(u"Traitement%s : %s.") % (texteDatesTraitement, description_traitement) # Création du paragraphe case.append(Paragraph(texteInfos, paraStyle)) has_infos = True # Ajoute la case à la ligne ligne.append(case) # Ajout de la ligne individuelle dans le tableau if dictParametres["individus_avec_infos"] == False or (dictParametres["individus_avec_infos"] == True and has_infos == True): dataTableau.append(ligne) # Création des lignes vierges for x in range(0, dictParametres["nbre_lignes_vierges"]): ligne = [] for col in labelsColonnes : ligne.append("") dataTableau.append(ligne) # Style du tableau couleur_fond_entetes = UTILS_Divers.ConvertCouleurWXpourPDF(dictParametres["couleur_fond_entetes"]) style = TableStyle([ ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), # Centre verticalement toutes les cases ('FONT',(0,0),(-1,-1), "Helvetica", 7), # Donne la police de caract. + taille de police ('GRID', (0,0), (-1,-1), 0.25, colors.black), # Crée la bordure noire pour tout le tableau ('ALIGN', (0,1), (-2,-1), 'CENTRE'), # Centre les cases ('ALIGN', (0,1), (-1,1), 'CENTRE'), # Ligne de labels colonne alignée au centre ('FONT',(0,1),(-1,1), "Helvetica", 6), # Donne la police de caract. + taille de police des labels ('SPAN',(0,0),(-1,0)), # Fusionne les lignes du haut pour faire le titre du groupe ('FONT',(0,0),(0,0), "Helvetica-Bold", 10), # Donne la police de caract. + taille de police du titre de groupe ('BACKGROUND', (0,0), (-1,0), couleur_fond_entetes), # Donne la couleur de fond du titre de groupe ]) # Création du tableau tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0,20)) # Saut de page après un groupe if dictParametres["saut_page_groupe"] == True : story.append(PageBreak()) # Insère un header if indexGroupe < nbreGroupes : Header() indexGroupe += 1 # Enregistrement du PDF doc.build(story) # Affichage du PDF FonctionsPerso.LanceFichierExterne(nomDoc)
def MAJ(self): cochesPrecedents = self.GetCoches() self.DeleteAllItems() self.root = self.AddRoot(_(u"Données")) # Fichiers locaux listeFichiersLocaux = self.GetListeFichiersLocaux() if len(listeFichiersLocaux) > 0 and self.parent.check_locaux.GetValue( ) == True: brancheType = self.AppendItem(self.root, _(u"Fichiers locaux"), ct_type=1) self.SetPyData(brancheType, _(u"locaux")) self.SetItemBold(brancheType) for nomFichier in listeFichiersLocaux: brancheNom = self.AppendItem(brancheType, nomFichier, ct_type=1) self.SetPyData(brancheNom, nomFichier) for nomCategorie, codeCategorie in LISTE_CATEGORIES: fichier = u"%s_%s.dat" % (nomFichier, codeCategorie) brancheFichier = self.AppendItem(brancheNom, nomCategorie, ct_type=1) self.SetPyData(brancheFichier, fichier) if os.path.isfile( UTILS_Fichiers.GetRepData(fichier)) == False: brancheFichier.Enable(False) # Fichiers réseaux listeFichiersReseau, listeBases = self.GetListeFichiersReseau() if len(listeFichiersReseau) > 0 and self.parent.check_reseau.GetValue( ) == True: brancheType = self.AppendItem(self.root, _(u"Fichiers réseau"), ct_type=1) self.SetPyData(brancheType, _(u"reseau")) self.SetItemBold(brancheType) for nomFichier in listeFichiersReseau: brancheNom = self.AppendItem(brancheType, nomFichier, ct_type=1) self.SetPyData(brancheNom, nomFichier) for nomCategorie, codeCategorie in LISTE_CATEGORIES: fichier = u"%s_%s" % (nomFichier, codeCategorie.lower()) brancheFichier = self.AppendItem(brancheNom, nomCategorie, ct_type=1) self.SetPyData(brancheFichier, fichier) if fichier not in listeBases: brancheFichier.Enable(False) self.ExpandAll() # Rétablit les coches précédents if len(cochesPrecedents) > 0: self.SetCoches(cochesPrecedents) self.AfficheNbreElements()
def Restauration(parent=None, fichier="", listeFichiersLocaux=[], listeFichiersReseau=[], dictConnexion=None): """ Restauration à partir des listes de fichiers locaux et réseau """ listeFichiersRestaures = [] # Initialisation de la barre de progression fichierZip = zipfile.ZipFile(fichier, "r") #fichierZip = MyZipFile(fichier, "r") # Restauration des fichiers locaux Sqlite ------------------------------------------------------------------------------ if len(listeFichiersLocaux) > 0 : # Vérifie qu'on les remplace bien listeExistantsTemp = [] for fichier in listeFichiersLocaux : if os.path.isfile(UTILS_Fichiers.GetRepData(fichier)) == True : listeExistantsTemp.append(fichier) if len(listeExistantsTemp) > 0 : if len(listeExistantsTemp) == 1 : message = _(u"Le fichier '%s' existe déjà.\n\nSouhaitez-vous vraiment le remplacer ?") % listeExistantsTemp[0] else : message = _(u"Les fichiers suivants existent déjà :\n\n - %s\n\nSouhaitez-vous vraiment les remplacer ?") % "\n - ".join(listeExistantsTemp) dlg = wx.MessageDialog(parent, message, "Attention !", wx.YES_NO | wx.CANCEL |wx.NO_DEFAULT | wx.ICON_EXCLAMATION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES : return False # Restauration nbreEtapes = len(listeFichiersLocaux) dlgprogress = wx.ProgressDialog(_(u"Merci de patienter"), _(u"Lancement de la restauration..."), maximum=nbreEtapes, parent=parent, style= wx.PD_SMOOTH | wx.PD_AUTO_HIDE | wx.PD_APP_MODAL) numEtape = 1 for fichier in listeFichiersLocaux : dlgprogress.Update(numEtape, _(u"Restauration du fichier %s...") % fichier);numEtape += 1 try : # buffer = fichierZip.read(fichier) # f = open(UTILS_Fichiers.GetRepData(fichier), "wb") # f.write(buffer) # f.close() fichierZip.extract(fichier, UTILS_Fichiers.GetRepData()) except Exception as err: dlgprogress.Destroy() print(err) dlg = wx.MessageDialog(None, _(u"La restauration du fichier '%s' a rencontré l'erreur suivante : \n%s") % (fichier, err), "Erreur", wx.OK| wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False listeFichiersRestaures.append(fichier[:-4]) # Restauration des fichiers réseau MySQL ------------------------------------------------------------------------------------------------------------------------- if len(listeFichiersReseau) > 0 : # Récupération de la liste des fichiers MySQL de l'ordinateur listeFichiersExistants = GetListeFichiersReseau(dictConnexion) # Recherche du répertoire d'installation de MySQL repMySQL = GetRepertoireMySQL(dictConnexion) if repMySQL == None : dlgErreur = wx.MessageDialog(None, _(u"Noethys n'a pas réussi à localiser MySQL sur votre ordinateur.\nNotez bien que MySQL doit être installé obligatoirement pour créer une restauration réseau."), _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False # Vérifie qu'on les remplace bien listeExistantsTemp = [] for fichier in listeFichiersReseau : fichier = fichier[:-4] if fichier in listeFichiersExistants : listeExistantsTemp.append(fichier) if len(listeExistantsTemp) > 0 : if len(listeExistantsTemp) == 1 : message = _(u"Le fichier '%s' existe déjà.\n\nSouhaitez-vous vraiment le remplacer ?") % listeExistantsTemp[0] else : message = _(u"Les fichiers suivants existent déjà :\n\n - %s\n\nSouhaitez-vous vraiment les remplacer ?") % "\n - ".join(listeExistantsTemp) dlg = wx.MessageDialog(parent, message, "Attention !", wx.YES_NO | wx.CANCEL |wx.NO_DEFAULT | wx.ICON_EXCLAMATION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES : return False # Création du répertoire temporaire repTemp = UTILS_Fichiers.GetRepTemp(fichier="restoretemp") if os.path.isdir(repTemp) == True : shutil.rmtree(repTemp) os.mkdir(repTemp) # 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) # Restauration nbreEtapes = len(listeFichiersReseau) dlgprogress = wx.ProgressDialog(_(u"Merci de patienter"), _(u"Lancement de la restauration..."), maximum=nbreEtapes, parent=parent, style= wx.PD_SMOOTH | wx.PD_AUTO_HIDE | wx.PD_APP_MODAL) numEtape = 1 for fichier in listeFichiersReseau: fichier = fichier[:-4] # Création de la base si elle n'existe pas if fichier not in listeFichiersExistants : nomFichier = u"%s;%s;%s;%s[RESEAU]%s" % (dictConnexion["port"], dictConnexion["host"], dictConnexion["user"], dictConnexion["password"], fichier) DB = GestionDB.DB(suffixe=None, nomFichier=nomFichier, modeCreation=True) DB.Close() # Copie du fichier SQL dans le répertoire Temp / restoretemp # buffer = fichierZip.read(u"%s.sql" % fichier) # f = open(fichierRestore, "wb") # f.write(buffer) # f.close() fichierZip.extract(u"%s.sql" % fichier, repTemp) fichierRestore = u"%s/%s.sql" % (repTemp, fichier) # Importation du fichier SQL dans MySQL dlgprogress.Update(numEtape, _(u"Restauration du fichier %s...") % fichier);numEtape += 1 args = u""""%sbin/mysql" --defaults-extra-file="%s" %s < "%s" """ % (repMySQL, nomFichierLoginTemp, fichier, fichierRestore) print(("Chemin mysql =", args)) if six.PY2: args = args.encode("iso-8859-15") 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(("subprocess de restauration mysql :", out)) if six.PY2: out = str(out).decode("iso-8859-15") dlgprogress.Destroy() dlgErreur = wx.MessageDialog(None, _(u"Une erreur a été détectée dans la procédure de restauration !\n\nErreur : %s") % out, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False listeFichiersRestaures.append(fichier) # Supprime le répertoire temp shutil.rmtree(repTemp) # Fin de la procédure dlgprogress.Destroy() fichierZip.close() return listeFichiersRestaures
def OnBoutonOk(self, event): # Récupération et vérification des données listePeriodes = self.ctrl_calendrier.GetDatesSelections() listeActivites = self.ctrl_activites.GetListeActivites() if len(listeActivites) == 0: dlg = wx.MessageDialog( self, _(u"Vous devez obligatoirement cocher au moins une activité !" ), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False listeGroupes = self.ctrl_groupes.GetListeGroupes() if len(listeGroupes) == 0: dlg = wx.MessageDialog( self, _(u"Vous devez obligatoirement cocher au moins un groupe !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return False # Création du PDF from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak from reportlab.platypus.flowables import ParagraphAndImage, Image from reportlab.rl_config import defaultPageSize from reportlab.lib.pagesizes import A4 from reportlab.lib.units import inch, cm from reportlab.lib.utils import ImageReader from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle self.taille_page = A4 self.orientation = "PAYSAGE" if self.orientation == "PORTRAIT": self.hauteur_page = self.taille_page[1] self.largeur_page = self.taille_page[0] else: self.hauteur_page = self.taille_page[0] self.largeur_page = self.taille_page[1] # Création des conditions pour les requêtes SQL conditionsPeriodes = GetSQLdates(listePeriodes) if len(listeActivites) == 0: conditionActivites = "()" elif len(listeActivites) == 1: conditionActivites = "(%d)" % listeActivites[0] else: conditionActivites = str(tuple(listeActivites)) if len(listeGroupes) == 0: conditionGroupes = "()" elif len(listeGroupes) == 1: conditionGroupes = "(%d)" % listeGroupes[0] else: conditionGroupes = str(tuple(listeGroupes)) # Récupération des noms des groupes dictGroupes = self.ctrl_groupes.GetDictGroupes() # Récupération des noms d'activités dictActivites = self.ctrl_activites.GetDictActivites() # Récupération de la liste des groupes ouverts sur cette période DB = GestionDB.DB() req = """SELECT IDouverture, IDactivite, IDunite, IDgroupe FROM ouvertures WHERE ouvertures.IDactivite IN %s AND %s AND IDgroupe IN %s ; """ % (conditionActivites, conditionsPeriodes, conditionGroupes) DB.ExecuterReq(req) listeOuvertures = DB.ResultatReq() dictOuvertures = {} for IDouverture, IDactivite, IDunite, IDgroupe in listeOuvertures: if dictOuvertures.has_key(IDactivite) == False: dictOuvertures[IDactivite] = [] if IDgroupe not in dictOuvertures[IDactivite]: dictOuvertures[IDactivite].append(IDgroupe) # Récupération des individus grâce à leurs consommations DB = GestionDB.DB() req = """SELECT individus.IDindividu, IDactivite, IDgroupe, etat, IDcivilite, nom, prenom, date_naiss FROM consommations LEFT JOIN individus ON individus.IDindividu = consommations.IDindividu WHERE etat IN ("reservation", "present") AND IDactivite IN %s AND %s GROUP BY individus.IDindividu ORDER BY nom, prenom ;""" % (conditionActivites, conditionsPeriodes) DB.ExecuterReq(req) listeIndividus = DB.ResultatReq() dictIndividus = {} listeIDindividus = [] for IDindividu, IDactivite, IDgroupe, etat, IDcivilite, nom, prenom, date_naiss in listeIndividus: if date_naiss != None: date_naiss = DateEngEnDateDD(date_naiss) age = self.GetAge(date_naiss) # Mémorisation de l'individu dictIndividus[IDindividu] = { "IDcivilite": IDcivilite, "nom": nom, "prenom": prenom, "age": age, "date_naiss": date_naiss, "IDgroupe": IDgroupe, "IDactivite": IDactivite, } # Mémorisation du IDindividu if IDindividu not in listeIDindividus: listeIDindividus.append(IDindividu) # Dict Informations médicales req = """SELECT IDprobleme, IDindividu, IDtype, intitule, date_debut, date_fin, description, traitement_medical, description_traitement, date_debut_traitement, date_fin_traitement, eviction, date_debut_eviction, date_fin_eviction FROM problemes_sante WHERE diffusion_listing_enfants=1 ;""" DB.ExecuterReq(req) listeInformations = DB.ResultatReq() DB.Close() dictInfosMedicales = {} for IDprobleme, IDindividu, IDtype, intitule, date_debut, date_fin, description, traitement_medical, description_traitement, date_debut_traitement, date_fin_traitement, eviction, date_debut_eviction, date_fin_eviction in listeInformations: if dictInfosMedicales.has_key(IDindividu) == False: dictInfosMedicales[IDindividu] = [] dictTemp = { "IDprobleme": IDprobleme, "IDtype": IDtype, "intitule": intitule, "date_debut": date_debut, "date_fin": date_fin, "description": description, "traitement_medical": traitement_medical, "description_traitement": description_traitement, "date_debut_traitement": date_debut_traitement, "date_fin_traitement": date_fin_traitement, "eviction": eviction, "date_debut_eviction": date_debut_eviction, "date_fin_eviction": date_fin_eviction, } dictInfosMedicales[IDindividu].append(dictTemp) # Récupération des photos individuelles dictPhotos = {} taillePhoto = 128 if self.ctrl_taille_photos.GetSelection() == 0: tailleImageFinal = 16 if self.ctrl_taille_photos.GetSelection() == 1: tailleImageFinal = 32 if self.ctrl_taille_photos.GetSelection() == 2: tailleImageFinal = 64 if self.checkbox_photos.GetValue() == True: for IDindividu in listeIDindividus: IDcivilite = dictIndividus[IDindividu]["IDcivilite"] nomFichier = Chemins.GetStaticPath( "Images/128x128/%s" % DICT_CIVILITES[IDcivilite]["nomImage"]) IDphoto, bmp = CTRL_Photo.GetPhoto(IDindividu=IDindividu, nomFichier=nomFichier, taillePhoto=(taillePhoto, taillePhoto), qualite=100) # Création de la photo dans le répertoire Temp nomFichier = UTILS_Fichiers.GetRepTemp( fichier="photoTmp%d.jpg" % IDindividu) bmp.SaveFile(nomFichier, type=wx.BITMAP_TYPE_JPEG) img = Image(nomFichier, width=tailleImageFinal, height=tailleImageFinal) dictPhotos[IDindividu] = img # ---------------- Création du PDF ------------------- # Initialisation du PDF nomDoc = FonctionsPerso.GenerationNomDoc( "LISTE_INFORMATIONS_MEDICALES", "pdf") if sys.platform.startswith("win"): nomDoc = nomDoc.replace("/", "\\") doc = SimpleDocTemplate(nomDoc, pagesize=(self.largeur_page, self.hauteur_page), topMargin=30, bottomMargin=30) story = [] largeurContenu = self.largeur_page - 75 #520 # Création du titre du document def Header(): dataTableau = [] largeursColonnes = ((largeurContenu - 100, 100)) dateDuJour = DateEngFr(str(datetime.date.today())) dataTableau.append( (_(u"Informations médicales"), _(u"%s\nEdité le %s") % (UTILS_Organisateur.GetNom(), dateDuJour))) style = TableStyle([ ('BOX', (0, 0), (-1, -1), 0.25, colors.black), ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('ALIGN', (0, 0), (0, 0), 'LEFT'), ('FONT', (0, 0), (0, 0), "Helvetica-Bold", 16), ('ALIGN', (1, 0), (1, 0), 'RIGHT'), ('FONT', (1, 0), (1, 0), "Helvetica", 6), ]) tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0, 20)) # Insère un header Header() # Activités for IDactivite in listeActivites: nomActivite = dictActivites[IDactivite]["nom"] # Groupes if dictOuvertures.has_key(IDactivite): nbreGroupes = len(dictOuvertures[IDactivite]) indexGroupe = 1 for IDgroupe in dictOuvertures[IDactivite]: nomGroupe = dictGroupes[IDgroupe]["nom"] # Initialisation du tableau dataTableau = [] largeursColonnes = [] labelsColonnes = [] # Recherche des entêtes de colonnes : if self.checkbox_photos.GetValue() == True: labelsColonnes.append(_(u"Photo")) largeursColonnes.append(tailleImageFinal + 6) labelsColonnes.append(_(u"Nom - prénom")) largeursColonnes.append(120) if self.checkbox_age.GetValue() == True: labelsColonnes.append(_(u"Âge")) largeursColonnes.append(20) # Calcule la largeur restante largeurRestante = largeurContenu - sum(largeursColonnes) labelsColonnes.append(_(u"Informations alimentaires")) largeursColonnes.append(largeurRestante / 2.0) labelsColonnes.append(_(u"Informations diverses")) largeursColonnes.append(largeurRestante / 2.0) # Création de l'entete de groupe ligne = [ nomGroupe, ] for x in range(0, len(labelsColonnes) - 1): ligne.append("") dataTableau.append(ligne) # Création des entêtes ligne = [] for label in labelsColonnes: ligne.append(label) dataTableau.append(ligne) # --------- Création des lignes ----------- # Création d'une liste temporaire pour le tri listeIndividus = [] if dictOuvertures.has_key(IDactivite): if IDgroupe in dictOuvertures[IDactivite]: for IDindividu in listeIDindividus: dictIndividu = dictIndividus[IDindividu] if dictIndividu["IDgroupe"] == IDgroupe: valeursTri = (IDindividu, dictIndividu["nom"], dictIndividu["prenom"], dictIndividu["age"]) # + Sélection uniquement des individus avec infos if self.checkbox_nonvides.GetValue( ) == False or ( self.checkbox_nonvides.GetValue() == True and dictInfosMedicales. has_key(IDindividu)): listeIndividus.append(valeursTri) if self.ctrl_tri.GetSelection() == 0: paramTri = 1 # Nom if self.ctrl_tri.GetSelection() == 1: paramTri = 2 # Prénom if self.ctrl_tri.GetSelection() == 2: paramTri = 3 # Age if self.ctrl_ordre.GetSelection() == 0: ordreDecroissant = False else: ordreDecroissant = True listeIndividus = sorted(listeIndividus, key=operator.itemgetter(paramTri), reverse=ordreDecroissant) # Récupération des lignes individus for IDindividu, nom, prenom, age in listeIndividus: dictIndividu = dictIndividus[IDindividu] ligne = [] # Photo if self.checkbox_photos.GetValue( ) == True and IDindividu in dictPhotos: img = dictPhotos[IDindividu] ligne.append(img) # Nom ligne.append(u"%s %s" % (nom, prenom)) # Age if self.checkbox_age.GetValue() == True: if age != None: ligne.append(age) else: ligne.append("") # Informations médicales paraStyle = ParagraphStyle( name="infos", fontName="Helvetica", fontSize=7, leading=8, spaceAfter=2, ) listeInfosAlim = [] listeInfosDivers = [] if dictInfosMedicales.has_key(IDindividu): for infoMedicale in dictInfosMedicales[IDindividu]: intitule = infoMedicale["intitule"] description = infoMedicale["description"] traitement = infoMedicale["traitement_medical"] description_traitement = infoMedicale[ "description_traitement"] date_debut_traitement = infoMedicale[ "date_debut_traitement"] date_fin_traitement = infoMedicale[ "date_fin_traitement"] IDtype = infoMedicale["IDtype"] # Intitulé et description if description != None and description != "": texteInfos = u"<b>%s</b> : %s" % ( intitule, description) else: texteInfos = u"%s" % intitule if len(texteInfos ) > 0 and texteInfos[-1] != ".": texteInfos += u"." # Traitement médical if traitement == 1 and description_traitement != None and description_traitement != "": texteDatesTraitement = u"" if date_debut_traitement != None and date_fin_traitement != None: texteDatesTraitement = _( u" du %s au %s" ) % (DateEngFr(date_debut_traitement), DateEngFr(date_fin_traitement)) if date_debut_traitement != None and date_fin_traitement == None: texteDatesTraitement = _( u" à partir du %s") % DateEngFr( date_debut_traitement) if date_debut_traitement == None and date_fin_traitement != None: texteDatesTraitement = _( u" jusqu'au %s") % DateEngFr( date_fin_traitement) texteInfos += _(u"Traitement%s : %s.") % ( texteDatesTraitement, description_traitement) # Création du paragraphe img = DICT_TYPES_INFOS[IDtype]["img"] p = ParagraphAndImage( Paragraph(texteInfos, paraStyle), Image(Chemins.GetStaticPath( "Images/16x16/%s" % img), width=8, height=8), xpad=1, ypad=0, side="left") if infoMedicale["IDtype"] == 2: listeInfosAlim.append(p) else: listeInfosDivers.append(p) ligne.append(listeInfosAlim) ligne.append(listeInfosDivers) # Ajout de la ligne individuelle dans le tableau dataTableau.append(ligne) # Création des lignes vierges if self.checkbox_lignes_vierges.GetValue() == True: for x in range( 0, self.ctrl_nbre_lignes.GetSelection() + 1): ligne = [] for col in labelsColonnes: ligne.append("") dataTableau.append(ligne) # Style du tableau colPremiere = 1 if self.checkbox_photos.GetValue() == True: colPremiere += 1 if self.checkbox_age.GetValue() == True: colPremiere += 1 couleurFond = (0.8, 0.8, 1) # Vert -> (0.5, 1, 0.2) style = TableStyle([ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), # Centre verticalement toutes les cases ('FONT', (0, 0), (-1, -1), "Helvetica", 7), # Donne la police de caract. + taille de police ('GRID', (0, 0), (-1, -1), 0.25, colors.black ), # Crée la bordure noire pour tout le tableau ('ALIGN', (0, 1), (-2, -1), 'CENTRE'), # Centre les cases ('ALIGN', (0, 1), (-1, 1), 'CENTRE' ), # Ligne de labels colonne alignée au centre ( 'FONT', (0, 1), (-1, 1), "Helvetica", 6 ), # Donne la police de caract. + taille de police des labels ( 'SPAN', (0, 0), (-1, 0) ), # Fusionne les lignes du haut pour faire le titre du groupe ( 'FONT', (0, 0), (0, 0), "Helvetica-Bold", 10 ), # Donne la police de caract. + taille de police du titre de groupe ('BACKGROUND', (0, 0), (-1, 0), couleurFond ), # Donne la couleur de fond du titre de groupe ]) # Création du tableau tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(style) story.append(tableau) story.append(Spacer(0, 20)) # Saut de page après un groupe if self.checkbox_page_groupe.GetValue() == True: story.append(PageBreak()) # Insère un header if indexGroupe < nbreGroupes: Header() indexGroupe += 1 # Enregistrement du PDF doc.build(story) # Affichage du PDF FonctionsPerso.LanceFichierExterne(nomDoc) self.MemoriserParametres()
def ExportExcel(listview=None, grid=None, titre=_(u"Liste"), listeColonnes=None, listeValeurs=None, autoriseSelections=True): """ Export de la liste au format Excel """ # Plus de sélection pour éviter les bugs !!!! autoriseSelections = False # Vérifie si données bien présentes if (listview != None and len(listview.donnees) == 0) or (grid != None and (grid.GetNumberRows() == 0 or grid.GetNumberCols() == 0)): dlg = wx.MessageDialog(None, _(u"Il n'y a aucune donnée dans la liste !"), "Erreur", wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return # Récupération des valeurs if listview != None and listeColonnes == None and listeValeurs == None : listeColonnes, listeValeurs = GetValeursListview(listview, format="original") if grid != None and listeColonnes == None and listeValeurs == None : autoriseSelections = False listeColonnes, listeValeurs = GetValeursGrid(grid) # Selection des lignes if autoriseSelections == True : dlg = DLG_Selection_liste.Dialog(None, listeColonnes, listeValeurs, type="exportExcel") if dlg.ShowModal() == wx.ID_OK: listeSelections = dlg.GetSelections() dlg.Destroy() else: dlg.Destroy() return False # Choix Action dlg = DLG_Choix_action(None) reponse = dlg.ShowModal() dlg.Destroy() if reponse == 100 : mode = "enregistrer" elif reponse == 200 : mode = "email" else : return # Définit le nom et le chemin du fichier nomFichier = "ExportExcel_%s.xls" % datetime.datetime.now().strftime("%Y%m%d%H%M%S") # Mode Enregistrer if mode == "enregistrer" : # Demande à l'utilisateur le nom de fichier et le répertoire de destination wildcard = "Fichier Excel (*.xls)|*.xls|" \ "All files (*.*)|*.*" sp = wx.StandardPaths.Get() cheminDefaut = sp.GetDocumentsDir() dlg = wx.FileDialog( None, message = _(u"Veuillez sélectionner le répertoire de destination et le nom du fichier"), defaultDir=cheminDefaut, defaultFile = nomFichier, wildcard = wildcard, style = wx.SAVE ) dlg.SetFilterIndex(0) if dlg.ShowModal() == wx.ID_OK: cheminFichier = dlg.GetPath() dlg.Destroy() else: dlg.Destroy() return # Le fichier de destination existe déjà : if os.path.isfile(cheminFichier) == True : dlg = wx.MessageDialog(None, _(u"Un fichier portant ce nom existe déjà. \n\nVoulez-vous le remplacer ?"), "Attention !", wx.YES_NO | wx.NO_DEFAULT | wx.ICON_EXCLAMATION) if dlg.ShowModal() == wx.ID_NO : return False dlg.Destroy() else: dlg.Destroy() # Mode Envoyer par Email if mode == "email" : cheminFichier = UTILS_Fichiers.GetRepTemp(fichier=nomFichier) # Export import pyExcelerator # Création d'un classeur wb = pyExcelerator.Workbook() # Création d'une feuille ws1 = wb.add_sheet(titre) # Remplissage de la feuille al = pyExcelerator.Alignment() al.horz = pyExcelerator.Alignment.HORZ_LEFT al.vert = pyExcelerator.Alignment.VERT_CENTER ar = pyExcelerator.Alignment() ar.horz = pyExcelerator.Alignment.HORZ_RIGHT ar.vert = pyExcelerator.Alignment.VERT_CENTER styleEuros = pyExcelerator.XFStyle() styleEuros.num_format_str = '"$"#,##0.00_);("$"#,##' styleEuros.alignment = ar styleDate = pyExcelerator.XFStyle() styleDate.num_format_str = 'DD/MM/YYYY' styleDate.alignment = ar styleHeure = pyExcelerator.XFStyle() styleHeure.num_format_str = "[hh]:mm" styleHeure.alignment = ar # Création des labels de colonnes x = 0 y = 0 for labelCol, alignement, largeur, nomChamp in listeColonnes : try : if "CheckState" in unicode(nomChamp) : nomChamp = "Coche" except : pass ws1.write(x, y, labelCol) ws1.col(y).width = largeur*42 y += 1 # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # Création des lignes def RechercheFormatFromChaine(valeur): """ Recherche le type de la chaîne """ if valeur.endswith(SYMBOLE) : # Si c'est un montant en euros try : if valeur.startswith("- ") : valeur = valeur.replace("- ", "-") if valeur.startswith("+ ") : valeur = valeur.replace("+ ", "") nbre = float(valeur[:-1]) return (nbre, styleEuros) except : pass # Si c'est un nombre try : if valeur.startswith("- ") : valeur = valeur.replace("- ", "-") nbre = float(valeur) return (nbre, None) except : pass # Si c'est une date try : if len(valeur) == 10 : if valeur[2] == "/" and valeur[5] == "/" : return (valeur, styleDate) except : pass if type(valeur) == datetime.timedelta : return (valeur, styleHeure) # Si c'est une heure try : if len(valeur) > 3 : if ":" in valeur : separateur = ":" elif "h" in valeur : separateur = "h" else : separateur = None if separateur != None : heures, minutes = valeur.split(separateur) valeur = datetime.timedelta(minutes= int(heures)*60 + int(minutes)) # valeur = datetime.time(hour=int(valeur.split(separateur)[0]), minute=int(valeur.split(separateur)[1])) return (valeur, styleHeure) except : pass return unicode(valeur), None # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- def RechercheFormat(valeur): """ Recherche le type de la donnée """ if type(valeur) == decimal.Decimal : valeur = float(valeur) return (valeur, styleEuros) if type(valeur) == float : return (valeur, None) if type(valeur) == int : return (valeur, None) if type(valeur) == datetime.date : valeur = UTILS_Dates.DateDDEnFr(valeur) return (valeur, styleDate) if type(valeur) == datetime.timedelta : return (valeur, styleHeure) try : if len(valeur) > 3 : if ":" in valeur : separateur = ":" elif "h" in valeur : separateur = "h" else : separateur = None if separateur != None : donnees = valeur.split(separateur) if len(donnees) == 2 : heures, minutes = donnees if len(donnees) == 3 : heures, minutes, secondes = donnees valeur = datetime.timedelta(minutes= int(heures)*60 + int(minutes)) # valeur = datetime.time(hour=int(valeur.split(separateur)[0]), minute=int(valeur.split(separateur)[1])) return (valeur, styleHeure) except : pass if type(valeur) in (str, unicode) : if len(valeur) == 10 : if valeur[2] == "/" and valeur[5] == "/" : return (valeur, styleDate) if valeur[4] == "-" and valeur[7] == "-" : return (UTILS_Dates.DateEngFr(valeur), styleDate) return unicode(valeur), None # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- x = 1 y = 0 for valeurs in listeValeurs : if autoriseSelections == False or int(valeurs[0]) in listeSelections : for valeur in valeurs : if valeur == None : valeur = u"" # Recherche s'il y a un format de nombre ou de montant if listview != None : valeur, format = RechercheFormat(valeur) #RechercheFormatFromChaine(valeur) else : valeur, format = RechercheFormatFromChaine(valeur) # Enregistre la valeur if format != None : ws1.write(x, y, valeur, format) else: ws1.write(x, y, valeur) y += 1 x += 1 y = 0 # Finalisation du fichier xls try : wb.save(cheminFichier) except : dlg = wx.MessageDialog(None, _(u"Il est impossible d'enregistrer le fichier Excel. Veuillez vérifier que ce fichier n'est pas déjà ouvert en arrière-plan."), "Erreur", wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return # Confirmation de création du fichier et demande d'ouverture directe dans Excel if mode == "enregistrer" : txtMessage = _(u"Le fichier Excel a été créé avec succès. Souhaitez-vous l'ouvrir dès maintenant ?") dlgConfirm = wx.MessageDialog(None, txtMessage, _(u"Confirmation"), wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION) reponse = dlgConfirm.ShowModal() dlgConfirm.Destroy() if reponse == wx.ID_NO: return else: FonctionsPerso.LanceFichierExterne(cheminFichier) # Envoyer par Email if mode == "email" : import DLG_Mailer dlg = DLG_Mailer.Dialog(None) dlg.ChargerModeleDefaut() dlg.SetPiecesJointes([cheminFichier,]) dlg.ShowModal() dlg.Destroy()
def Importer(self, event): """ Importer un fichier de langue """ # Ouverture de la fenêtre de dialogue wildcard = "Fichiers de langue (*.lang, *.xlang)|*.lang;*.xlang|Tous les fichiers (*.*)|*.*" sp = wx.StandardPaths.Get() dlg = wx.FileDialog( self, message=_(u"Choisissez un fichier de langue à importer"), defaultDir=sp.GetDocumentsDir(), defaultFile="", wildcard=wildcard, style=wx.OPEN ) if dlg.ShowModal() == wx.ID_OK: nomFichierCourt = dlg.GetFilename() nomFichierLong = dlg.GetPath() dlg.Destroy() else: dlg.Destroy() return # Vérifie si un fichier existe déjà if os.path.isfile(UTILS_Fichiers.GetRepLang(nomFichierCourt)) == False : shutil.copyfile(nomFichierLong, UTILS_Fichiers.GetRepLang(nomFichierCourt)) self.MAJ() else : dlg = DLG_Messagebox.Dialog(self, titre=_(u"Importer"), introduction=_(u"Ce fichier est déjà présent !"), detail=None, conclusion=_(u"Souhaitez-vous le remplacer ou les fusionner ?"), icone=wx.ICON_EXCLAMATION, boutons=[_(u"Fusionner"), _(u"Remplacer"), _(u"Annuler")]) reponse = dlg.ShowModal() dlg.Destroy() if reponse == 0 : # Fusionner dlg = wx.MessageDialog(self, _(u"Souhaitez-vous vraiment fusionner les deux fichiers ?"), _(u"Confirmation"), wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) reponse = dlg.ShowModal() dlg.Destroy() if reponse == wx.ID_NO : return # Lecture des 2 fichiers dictDonnees = {} for nomFichier in [UTILS_Fichiers.GetRepLang(nomFichierCourt), nomFichierLong] : fichier = shelve.open(nomFichier, "r") for key, valeur in fichier.iteritems() : dictDonnees[key] = valeur fichier.close() # Ecriture du fichier final nomFichier = UTILS_Fichiers.GetRepLang(nomFichierCourt) if os.path.isfile(nomFichier) : flag = "w" else : flag = "n" fichier = shelve.open(nomFichier, flag) fichier.clear() for key, valeur in dictDonnees.iteritems() : fichier[key] = valeur fichier.close() self.MAJ() dlg = wx.MessageDialog(self, _(u"Le fichier a été importé avec succès !"), _(u"Confirmation"), wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() if reponse == 1 : # Remplacer dlg = wx.MessageDialog(self, _(u"Souhaitez-vous vraiment remplacer le fichier ?"), _(u"Confirmation"), wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) reponse = dlg.ShowModal() dlg.Destroy() if reponse == wx.ID_NO : return # Copie du fichier vers le répertoire Lang os.remove(UTILS_Fichiers.GetRepLang(nomFichierCourt)) shutil.copyfile(nomFichierLong, UTILS_Fichiers.GetRepLang(nomFichierCourt)) self.MAJ() dlg = wx.MessageDialog(self, _(u"Le fichier a été importé avec succès !"), _(u"Confirmation"), wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() if reponse == 2 : return False
def GetTracks(self): """ Récupération des données """ DB = GestionDB.DB() # Lecture Individus req = """SELECT IDindividu, nom, prenom FROM individus;""" DB.ExecuterReq(req) listeIndividus = DB.ResultatReq() dictIndividus = {} for IDindividu, nom, prenom in listeIndividus: if prenom == None: prenom = "" dictIndividus[IDindividu] = u"%s %s" % (nom, prenom) # Lecture unités req = """SELECT IDunite, nom, abrege FROM unites ORDER BY ordre;""" DB.ExecuterReq(req) listeUnites = DB.ResultatReq() dictUnites = {} for IDunite, nom, abrege in listeUnites: dictUnites[IDunite] = nom DB.Close() # Récupération du IDfichier IDfichier = FonctionsPerso.GetIDfichier() # Lecture des fichiers du répertoire SYNC listeFichiers = os.listdir(UTILS_Fichiers.GetRepSync()) listeListeView = [] listeDictTempTraites = [] for nomFichier in listeFichiers: if nomFichier.startswith("actions_%s" % IDfichier) and ( nomFichier.endswith(".dat") and self.listeFichiers == None) or (self.listeFichiers != None and nomFichier in self.listeFichiers): nomFichierCourt = nomFichier.replace(".dat", "").replace( ".archive", "") if nomFichier not in self.listeFichiersTrouves: self.listeFichiersTrouves.append(nomFichier) # Taille fichier tailleFichier = os.path.getsize( UTILS_Fichiers.GetRepSync(nomFichier)) # Horodatage horodatage = nomFichierCourt.split("_")[2] horodatage = UTILS_Dates.HorodatageEnDatetime(horodatage) # Lecture du contenu du fichier DB = GestionDB.DB( suffixe=None, nomFichier=UTILS_Fichiers.GetRepSync(nomFichier), modeCreation=False) req = """SELECT IDparametre, nom, valeur FROM parametres;""" DB.ExecuterReq(req) listeParametres = DB.ResultatReq() dictParametres = {} for IDparametre, nom, valeur in listeParametres: dictParametres[nom] = valeur if ("nom_appareil" in dictParametres) == False: dictParametres["nom_appareil"] = "Appareil inconnu" if ("ID_appareil" in dictParametres) == False: dictParametres["ID_appareil"] = "IDAppareil inconnu" # Mémorise l'IDappareil self.dictIDappareil[nomFichierCourt] = dictParametres[ "ID_appareil"] # Lecture des consommations req = """SELECT IDconso, horodatage, action, IDindividu, IDactivite, IDinscription, date, IDunite, IDgroupe, heure_debut, heure_fin, consommations.etat, date_saisie, IDutilisateur, IDcategorie_tarif, IDcompte_payeur, quantite, IDfamille FROM consommations;""" DB.ExecuterReq(req) listeConsommations = DB.ResultatReq() for IDconso, horodatage, action, IDindividu, IDactivite, IDinscription, date, IDunite, IDgroupe, heure_debut, heure_fin, etat, date_saisie, IDutilisateur, IDcategorie_tarif, IDcompte_payeur, quantite, IDfamille in listeConsommations: horodatage = UTILS_Dates.HorodatageEnDatetime( horodatage, separation="-") date = UTILS_Dates.DateEngEnDateDD(date) date_saisie = UTILS_Dates.DateEngEnDateDD(date_saisie) dictTemp = { "categorie": "consommation", "IDconso": IDconso, "horodatage": horodatage, "action": action, "IDindividu": IDindividu, "IDactivite": IDactivite, "IDinscription": IDinscription, "date": date, "IDunite": IDunite, "IDgroupe": IDgroupe, "heure_debut": heure_debut, "heure_fin": heure_fin, "etat": etat, "quantite": quantite, "date_saisie": date_saisie, "IDutilisateur": IDutilisateur, "IDcategorie_tarif": IDcategorie_tarif, "IDcompte_payeur": IDcompte_payeur, "IDfamille": IDfamille, } # Vérifie que cette action n'est pas déjà dans la liste if dictTemp not in listeDictTempTraites: listeListeView.append( Track(dictTemp, dictIndividus=dictIndividus, dictUnites=dictUnites, dictParametres=dictParametres, nomFichier=nomFichier)) if self.cacher_doublons == True: listeDictTempTraites.append(dictTemp) # Lecture des mémos journaliers req = """SELECT IDmemo, horodatage, action, IDindividu, date, texte FROM memo_journee;""" DB.ExecuterReq(req) listeMemosJournees = DB.ResultatReq() for IDmemo, horodatage, action, IDindividu, date, texte in listeMemosJournees: horodatage = UTILS_Dates.HorodatageEnDatetime( horodatage, separation="-") date = UTILS_Dates.DateEngEnDateDD(date) dictTemp = { "categorie": "memo_journee", "IDmemo": IDmemo, "horodatage": horodatage, "action": action, "IDindividu": IDindividu, "date": date, "texte": texte, } # Vérifie que cette action n'est pas déjà dans la liste if dictTemp not in listeDictTempTraites: listeListeView.append( Track(dictTemp, dictIndividus=dictIndividus, dictParametres=dictParametres, nomFichier=nomFichier)) if self.cacher_doublons == True: listeDictTempTraites.append(dictTemp) DB.Close() return listeListeView
class Dialog(wx.Dialog, Base): def __init__(self, parent): wx.Dialog.__init__(self, parent, -1, name="DLG_Envoi_sms", style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.MAXIMIZE_BOX|wx.MINIMIZE_BOX) Base.__init__(self) self.parent = parent titre = _(u"Envoi de SMS") intro = _(u"Vous pouvez envoyer ici des SMS aux individus ou familles à condition que votre plateforme d'envoi ait été intégrée à cette fonctionnalité. Consultez la liste des prestataires pris en charge dans la liste déroulante Plateforme de la page des paramètres.") self.SetTitle(titre) self.ctrl_bandeau = CTRL_Bandeau.Bandeau(self, titre=titre, texte=intro, hauteurHtml=30, nomImage="Images/32x32/Sms.png") # Initialisation des pages self.InitPages(self) self.static_line = wx.StaticLine(self, -1) self.bouton_aide = CTRL_Bouton_image.CTRL(self, texte=_(u"Aide"), cheminImage="Images/32x32/Aide.png") self.bouton_retour = CTRL_Bouton_image.CTRL(self, texte=_(u"Retour"), cheminImage="Images/32x32/Fleche_gauche.png") self.bouton_suite = CTRL_Bouton_image.CTRL(self, texte=_(u"Suite"), cheminImage="Images/32x32/Fleche_droite.png", margesImage=(0, 0, 4, 0), positionImage=wx.RIGHT) self.bouton_annuler = CTRL_Bouton_image.CTRL(self, texte=_(u"Annuler"), cheminImage="Images/32x32/Annuler.png") self.__set_properties() self.__do_layout() self.Bind(wx.EVT_BUTTON, self.Onbouton_aide, self.bouton_aide) self.Bind(wx.EVT_BUTTON, self.Onbouton_retour, self.bouton_retour) self.Bind(wx.EVT_BUTTON, self.Onbouton_suite, self.bouton_suite) self.Bind(wx.EVT_BUTTON, self.OnBoutonAnnuler, self.bouton_annuler) self.Bind(wx.EVT_CLOSE, self.OnClose) self.bouton_retour.Enable(False) self.nbrePages = len(self.listePages) self.pageVisible = 0 # Création des pages self.Creation_Pages() self.GetPage("parametres").MAJ() def Creation_Pages(self): """ Creation des pages """ self.dictPages = {} index = 0 for dictPage in self.listePages : self.sizer_pages.Add(dictPage["ctrl"], 1, wx.EXPAND, 0) if index > 0 : dictPage["ctrl"].Show(False) index += 1 self.sizer_pages.Layout() def __set_properties(self): self.bouton_aide.SetToolTip(wx.ToolTip(_(u"Cliquez ici pour obtenir de l'aide"))) self.bouton_retour.SetToolTip(wx.ToolTip(_(u"Cliquez ici pour revenir à la page précédente"))) self.bouton_suite.SetToolTip(wx.ToolTip(_(u"Cliquez ici pour passer à l'étape suivante"))) self.bouton_annuler.SetToolTip(wx.ToolTip(_(u"Cliquez pour annuler"))) self.SetMinSize((770, 650)) def __do_layout(self): grid_sizer_base = wx.FlexGridSizer(rows=4, cols=1, vgap=0, hgap=0) # Bandeau grid_sizer_base.Add(self.ctrl_bandeau, 1, wx.EXPAND, 0) # Contenu sizer_base = wx.BoxSizer(wx.VERTICAL) sizer_pages = wx.BoxSizer(wx.VERTICAL) grid_sizer_base.Add(sizer_pages, 1, wx.EXPAND, 0) grid_sizer_base.Add(self.static_line, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 10) # Boutons grid_sizer_boutons = wx.FlexGridSizer(rows=1, cols=6, vgap=10, hgap=10) grid_sizer_boutons.Add(self.bouton_aide, 0, 0, 0) grid_sizer_boutons.Add((20, 20), 0, wx.EXPAND, 0) grid_sizer_boutons.Add(self.bouton_retour, 0, 0, 0) grid_sizer_boutons.Add(self.bouton_suite, 0, 0, 0) grid_sizer_boutons.Add(self.bouton_annuler, 0, wx.LEFT, 10) grid_sizer_boutons.AddGrowableCol(1) grid_sizer_base.Add(grid_sizer_boutons, 1, wx.ALL|wx.EXPAND, 10) grid_sizer_base.AddGrowableRow(1) grid_sizer_base.AddGrowableCol(0) self.SetSizer(grid_sizer_base) grid_sizer_base.Fit(self) self.Layout() self.CenterOnScreen() self.sizer_pages = sizer_pages def Onbouton_aide(self, event): from Utils import UTILS_Aide UTILS_Aide.Aide("") def AfficherPage(self, numPage=0): # rend invisible la page affichée page = self.listePages[self.pageVisible]["ctrl"] page.Sauvegarde() page.Show(False) # Fait apparaître nouvelle page self.pageVisible = numPage page = self.listePages[self.pageVisible]["ctrl"] page.MAJ() page.Show(True) self.sizer_pages.Layout() def Onbouton_retour(self, event): # Affiche nouvelle page self.AfficherPage(self.pageVisible - 1) # Si on quitte l'avant-dernière page, on active le bouton Suivant if self.pageVisible == self.nbrePages-1: self.bouton_suite.Enable(True) self.bouton_suite.SetImage(Chemins.GetStaticPath("Images/32x32/Valider.png")) self.bouton_suite.SetTexte(_(u"Valider")) else: self.bouton_suite.Enable(True) self.bouton_suite.SetImage(Chemins.GetStaticPath("Images/32x32/Fleche_droite.png")) self.bouton_suite.SetTexte(_(u"Suite")) # Si on revient à la première page, on désactive le bouton Retour if self.pageVisible == 0 : self.bouton_retour.Enable(False) def Onbouton_suite(self, event): # Vérifie que les données de la page en cours sont valides validation = self.ValidationPages() if validation == False : return # Si on est déjà sur la dernière page : on termine if self.pageVisible == self.nbrePages-1 : self.listePages[self.pageVisible]["ctrl"].Sauvegarde() self.Terminer() return # Affiche nouvelle page self.AfficherPage(self.pageVisible + 1) # Si on arrive à la dernière page, on désactive le bouton Suivant if self.pageVisible == self.nbrePages-1 : self.bouton_suite.SetImage(Chemins.GetStaticPath("Images/32x32/Valider.png")) self.bouton_suite.SetTexte(_(u"Envoyer")) # Si on quitte la première page, on active le bouton Retour if self.pageVisible > 0 : self.bouton_retour.Enable(True) def OnClose(self, event): self.OnBoutonAnnuler() def OnBoutonAnnuler(self, event=None): self.Annuler() def Annuler(self): """ Annulation des modifications """ self.EndModal(wx.ID_CANCEL) def ValidationPages(self) : """ Validation des données avant changement de pages """ return self.listePages[self.pageVisible]["ctrl"].Validation() def Terminer(self): # Envoi du message if self.Envoyer() != True : return False # Fermeture self.EndModal(wx.ID_OK) def Envoyer(self): # Demande de confirmation dlg = wx.MessageDialog(self, _(u"Confirmez-vous l'envoi du message vers %d numéros ?") % len(self.dictDonnees["liste_telephones"]), _(u"Confirmation"), wx.YES_NO|wx.YES_DEFAULT|wx.CANCEL|wx.ICON_QUESTION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES : return False # CONTACT EVERYONE BY ORANGE BUSINESS if self.dictDonnees["plateforme"] == "contact_everyone" : # Récupération adresse d'expédition IDadresse = self.dictDonnees["adresse_expedition_email"] dictAdresse = UTILS_Envoi_email.GetAdresseExp(IDadresse=IDadresse) # Génération de la pièce jointe liste_lignes = [] for ligne in self.dictDonnees["message"].split("\n") : liste_lignes.append(u"T-%s" % ligne) for numero in self.dictDonnees["liste_telephones"] : numero = numero.replace(".", "") liste_lignes.append(u"#-%s" % numero) texte = "\n".join(liste_lignes) cheminFichier = UTILS_Fichiers.GetRepTemp(fichier="sms.txt") fichier = open(cheminFichier, 'w') fichier.write(texte.encode("iso-8859-15")) fichier.close() # Envoi de l'email try : etat = UTILS_Envoi_email.Envoi_mail( adresseExpediteur=dictAdresse["adresse"], listeDestinataires=[self.dictDonnees["orange_adresse_destination_email"],], sujetMail=self.dictDonnees["objet"], texteMail=_(u"Envoi de SMS"), listeFichiersJoints=[cheminFichier,], serveur=dictAdresse["smtp"], port=dictAdresse["port"], avecAuthentification=dictAdresse["auth"], avecStartTLS=dictAdresse["startTLS"], motdepasse=dictAdresse["motdepasse"], utilisateur=dictAdresse["utilisateur"], ) except Exception, err: print (err,) err = str(err).decode("iso-8859-15") dlgErreur = wx.MessageDialog(None, _(u"Une erreur a été détectée dans l'envoi de l'Email !\n\nErreur : %s") % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False # CLEVER SMS if self.dictDonnees["plateforme"] == "cleversms" : # Récupération adresse d'expédition IDadresse = self.dictDonnees["adresse_expedition_email"] dictAdresse = UTILS_Envoi_email.GetAdresseExp(IDadresse=IDadresse) # Génération de la pièce jointe liste_lignes = [] message = self.dictDonnees["message"].replace("\n", "") for numero in self.dictDonnees["liste_telephones"] : numero = numero.replace(".", "") liste_lignes.append(u"%s;%s" % (numero, message)) texte = "\n".join(liste_lignes) cheminFichier = UTILS_Fichiers.GetRepTemp(fichier="sms.txt") fichier = open(cheminFichier, 'w') fichier.write(texte.encode("iso-8859-15")) fichier.close() # Envoi de l'email try : etat = UTILS_Envoi_email.Envoi_mail( adresseExpediteur=dictAdresse["adresse"], listeDestinataires=[self.dictDonnees["cleversms_adresse_destination_email"],], sujetMail=self.dictDonnees["objet"], texteMail=_(u"Envoi de SMS"), listeFichiersJoints=[cheminFichier,], serveur=dictAdresse["smtp"], port=dictAdresse["port"], avecAuthentification=dictAdresse["auth"], avecStartTLS=dictAdresse["startTLS"], motdepasse=dictAdresse["motdepasse"], utilisateur=dictAdresse["utilisateur"], ) except Exception, err: print (err,) err = str(err).decode("iso-8859-15") dlgErreur = wx.MessageDialog(None, _(u"Une erreur a été détectée dans l'envoi de l'Email !\n\nErreur : %s") % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlgErreur.ShowModal() dlgErreur.Destroy() return False
def ArchiverFichiers(self): """ Archivage des fichiers traités """ archiver = False # Récupère stats nbreTotal = 0 nbreTraites = 0 nbreNonTraites = 0 nbreOk = 0 nbreErreurs = 0 for track in self.ctrl_donnees.donnees: nbreTotal += 1 if track.statut != None: nbreTraites += 1 if track.statut == None: nbreNonTraites += 1 if track.statut == "ok": nbreOk += 1 if track.statut == "erreur": nbreErreurs += 1 #print nbreTotal, nbreTraites, nbreNonTraites, nbreOk, nbreErreurs # Si aucun traités if nbreTraites == 0: return True # Si des erreurs ont été trouvées if nbreErreurs > 0 or nbreNonTraites > 0: if nbreErreurs > 0 and nbreNonTraites == 0: intro = _( u"%d erreurs ont été trouvées lors de l'importation. " ) % nbreErreurs if nbreErreurs == 0 and nbreNonTraites > 0: intro = _( u"%d actions n'ont pas été traitées. ") % nbreNonTraites if nbreErreurs > 0 and nbreNonTraites > 0: intro = _( u"%d actions n'ont pas été traitées et %d erreurs ont été trouvées. " ) % (nbreErreurs, nbreNonTraites) dlg = wx.MessageDialog( self, _(u"%s\n\nConfirmez-vous tout de même l'archivage des fichiers de synchronisation traités ?\n(Si vous choisissez Non, les fichiers seront conservés)" ) % intro, _(u"Archivage"), wx.YES_NO | wx.CANCEL | wx.YES_DEFAULT | wx.ICON_QUESTION) reponse = dlg.ShowModal() dlg.Destroy() if reponse == wx.ID_CANCEL: return False if reponse == wx.ID_YES: archiver = True # Si tous ont été traités avec succès if nbreOk == nbreTotal: archiver = True # Archivage if archiver == True: # Récupération de la liste des fichiers if self.listeFichiers == None: listeFichiers = self.ctrl_donnees.listeFichiersTrouves else: listeFichiers = self.listeFichiers DB = GestionDB.DB() for nomFichier in listeFichiers: # Renommage et archivage if nomFichier.endswith(".archive") == False: # Renommage nomTemp = UTILS_Fichiers.GetRepSync( nomFichier.replace(".dat", ".archive")) if os.path.isfile(nomTemp) == True: os.remove(nomTemp) os.rename(UTILS_Fichiers.GetRepSync(nomFichier), nomTemp) # Mémorisation de l'archivage dans la base nomFichierTemp = nomFichier.replace(".dat", "").replace( ".archive", "") ID_appareil = self.ctrl_donnees.dictIDappareil[ nomFichierTemp] IDarchive = DB.ReqInsert("nomade_archivage", [("nom_fichier", nomFichierTemp), ("ID_appareil", ID_appareil), ("date", datetime.date.today())]) DB.Close()
def ConversionReseauLocal(parent, nomFichier=""): # Demande le nom du nouveau fichier local from Dlg import DLG_Nouveau_fichier dlg = DLG_Nouveau_fichier.MyDialog(parent) dlg.SetTitle(_(u"Conversion d'un fichier réseau en fichier local")) dlg.radio_local.SetValue(True) dlg.OnRadioLocal(None) dlg.radio_local.Enable(False) dlg.radio_reseau.Enable(False) dlg.radio_internet.Enable(False) dlg.checkbox_details.Show(False) dlg.hyperlink_details.Show(False) dlg.DesactiveIdentite() dlg.CentreOnScreen() if dlg.ShowModal() == wx.ID_OK: nouveauFichier = dlg.GetNomFichier() dlg.Destroy() else: dlg.Destroy() return False # Vérifie que le fichier n'est pas déjà utilisé if os.path.isfile(UTILS_Fichiers.GetRepData(u"%s_DATA.dat" % nomFichier)) == True: dlg = wx.MessageDialog(parent, _(u"Le fichier existe déjà."), _(u"Erreur de création de fichier"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False nomFichierReseauFormate = nomFichier[nomFichier.index("[RESEAU]" ):].replace( "[RESEAU]", "") # Demande une confirmation pour la conversion message = _( u"Confirmez-vous la conversion du fichier réseau '%s' en fichier local portant le nom '%s' ? \n\nCette opération va durer quelques instants...\n\n(Notez que le fichier original sera toujours conservé)" ) % (nomFichierReseauFormate, nouveauFichier) dlg = wx.MessageDialog(parent, message, _(u"Confirmation de la conversion"), wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_YES: dlg.Destroy() else: dlg.Destroy() return False # Lance la conversion parent.SetStatusText( _(u"Conversion du fichier en cours... Veuillez patienter...")) resultat = GestionDB.ConversionReseauLocal(nomFichier, nouveauFichier, parent) if resultat[0] == True: parent.SetStatusText(_(u"La conversion s'est terminée avec succès.")) dlg = wx.MessageDialog( None, _(u"La conversion s'est terminée avec succès. Le nouveau fichier a été créé." ), _(u"Information"), wx.OK | wx.ICON_INFORMATION) else: parent.SetStatusText(_(u"Erreur de conversion")) dlg = wx.MessageDialog(None, resultat[1], _(u"Erreur de conversion"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() parent.SetStatusText("") return True
def Impression(self, listeLocations=[], nomDoc=None, afficherDoc=True, dictOptions=None, repertoire=None, repertoireTemp=False): """ Impression des locations """ from Utils import UTILS_Impression_location # Récupération des données à partir des IDlocation resultat = self.GetDonneesImpression(listeLocations) if resultat == False: return False dictLocations, dictChampsFusion = resultat # Récupération des paramètres d'affichage if dictOptions == None: if afficherDoc == False: dlg = DLG_Apercu_location.Dialog( None, titre=_(u"Sélection des paramètres de la location"), intro= _(u"Sélectionnez ici les paramètres d'affichage de la location." )) dlg.bouton_ok.SetImageEtTexte("Images/32x32/Valider.png", _("Ok")) else: dlg = DLG_Apercu_location.Dialog(None) if dlg.ShowModal() == wx.ID_OK: dictOptions = dlg.GetParametres() dlg.Destroy() else: dlg.Destroy() return False # Création des PDF à l'unité def CreationPDFunique(repertoireCible=""): dictPieces = {} dlgAttente = wx.BusyInfo( _(u"Génération des PDF à l'unité en cours..."), None) try: index = 0 for IDlocation, dictLocation in dictLocations.items(): if dictLocation["select"] == True: nomTitulaires = self.Supprime_accent( dictLocation["{FAMILLE_NOM}"]) nomFichier = _(u"Location %d - %s") % (IDlocation, nomTitulaires) cheminFichier = u"%s/%s.pdf" % (repertoireCible, nomFichier) dictComptesTemp = {IDlocation: dictLocation} self.EcritStatusbar( _(u"Edition de la location %d/%d : %s") % (index, len(dictLocation), nomFichier)) UTILS_Impression_location.Impression( dictComptesTemp, dictOptions, IDmodele=dictOptions["IDmodele"], ouverture=False, nomFichier=cheminFichier) dictPieces[IDlocation] = cheminFichier index += 1 self.EcritStatusbar("") del dlgAttente return dictPieces except Exception as err: del dlgAttente traceback.print_exc(file=sys.stdout) dlg = wx.MessageDialog( None, _(u"Désolé, le problème suivant a été rencontré dans l'édition des locations : \n\n%s" ) % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False # Répertoire souhaité par l'utilisateur if repertoire != None: resultat = CreationPDFunique(repertoire) if resultat == False: return False # Répertoire TEMP (pour Emails) dictPieces = {} if repertoireTemp == True: dictPieces = CreationPDFunique(UTILS_Fichiers.GetRepTemp()) if dictPieces == False: return False # Sauvegarde dans un porte-documents if dictOptions["questionnaire"] != None: # Création des PDF if len(dictPieces) == 0: dictPieces = CreationPDFunique(UTILS_Fichiers.GetRepTemp()) # Recherche des IDreponse IDquestion = dictOptions["questionnaire"] DB = GestionDB.DB() req = """SELECT IDreponse, IDdonnee FROM questionnaire_reponses WHERE IDquestion=%d ;""" % IDquestion DB.ExecuterReq(req) listeReponses = DB.ResultatReq() DB.Close() dictReponses = {} for IDreponse, IDlocation in listeReponses: dictReponses[IDlocation] = IDreponse DB = GestionDB.DB(suffixe="DOCUMENTS") for IDlocation, cheminFichier in dictPieces.items(): # Préparation du blob fichier = open(cheminFichier, "rb") data = fichier.read() fichier.close() buffer = six.BytesIO(data) blob = buffer.read() # Recherche l'IDreponse if IDlocation in dictReponses: IDreponse = dictReponses[IDlocation] else: # Création d'une réponse de questionnaire listeDonnees = [ ("IDquestion", IDquestion), ("reponse", "##DOCUMENTS##"), ("type", "location"), ("IDdonnee", IDlocation), ] DB2 = GestionDB.DB() IDreponse = DB2.ReqInsert("questionnaire_reponses", listeDonnees) DB2.Close() # Sauvegarde du document listeDonnees = [("IDreponse", IDreponse), ("type", "pdf"), ("label", dictOptions["nomModele"]), ("last_update", datetime.datetime.now())] IDdocument = DB.ReqInsert("documents", listeDonnees) DB.MAJimage(table="documents", key="IDdocument", IDkey=IDdocument, blobImage=blob, nomChampBlob="document") DB.Close() # Fabrication du PDF global if repertoireTemp == False: dlgAttente = wx.BusyInfo(_(u"Création du PDF en cours..."), None) self.EcritStatusbar( _(u"Création du PDF des locations en cours... veuillez patienter..." )) try: UTILS_Impression_location.Impression( dictLocations, dictOptions, IDmodele=dictOptions["IDmodele"], ouverture=afficherDoc, nomFichier=nomDoc) self.EcritStatusbar("") del dlgAttente except Exception as err: del dlgAttente traceback.print_exc(file=sys.stdout) dlg = wx.MessageDialog( None, u"Désolé, le problème suivant a été rencontré dans l'édition des locations : \n\n%s" % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False return dictChampsFusion, dictPieces
def GetNomFichierConfig(nomFichier="Config.json"): return UTILS_Fichiers.GetRepUtilisateur(nomFichier)
def __init__(self, IDpersonne=1, nomPersonne=_(u"LUCAS Noémie"), annee=2009, afficher_we=True, afficher_vacances=True, afficher_feries=True, afficher_heures=True, afficher_couleurs_categories=True, afficher_legende=True, afficher_heures_mois=True): self.IDpersonne = IDpersonne self.nomPersonne = nomPersonne self.annee = annee global AFFICHER_WE, AFFICHER_VACANCES, AFFICHER_FERIES, AFFICHER_HEURES, AFFICHER_COULEUR_CATEGORIES, AFFICHER_LEGENDE, AFFICHER_HEURES_MOIS AFFICHER_WE = afficher_we AFFICHER_VACANCES = afficher_vacances AFFICHER_FERIES = afficher_feries AFFICHER_HEURES = afficher_heures AFFICHER_COULEUR_CATEGORIES = afficher_couleurs_categories AFFICHER_LEGENDE = afficher_legende AFFICHER_HEURES_MOIS = afficher_heures_mois largeurMois = 55 espaceMois = 5 # Paramètres du PDF nomDoc = UTILS_Fichiers.GetRepTemp("Impression_calendrier_annuel.pdf") if "win" in sys.platform: nomDoc = nomDoc.replace("/", "\\") taillePage = landscape(A4) HAUTEUR_PAGE = defaultPageSize[0] LARGEUR_PAGE = defaultPageSize[1] doc = SimpleDocTemplate(nomDoc, pagesize=taillePage, topMargin=50, bottomMargin=50) story = [] # Création du titre du document largeursColonnesTitre = ((615, 100)) dateDuJour = DatetimeDateEnStr(datetime.date.today()) dataTableauTitre = [ (_(u"Planning %d de %s") % (self.annee, self.nomPersonne), _(u"Edité le %s") % dateDuJour), ] styleTitre = TableStyle([ ('BOX', (0, 0), (-1, -1), 0.25, colors.black), ('VALIGN', (0, 0), (-1, -1), 'TOP'), ('ALIGN', (0, 0), (0, 0), 'LEFT'), ('FONT', (0, 0), (0, 0), "Helvetica-Bold", 16), ('ALIGN', (1, 0), (1, 0), 'RIGHT'), ('FONT', (1, 0), (1, 0), "Helvetica", 6), ]) tableauTitre = Table(dataTableauTitre, largeursColonnesTitre) tableauTitre.setStyle(styleTitre) story.append(tableauTitre) story.append(Spacer(0, 20)) # Récupération des données self.dictPresences, self.dictTotauxCategories = self.ImportPresences( self.IDpersonne, self.annee) global DICT_CATEGORIES, LISTE_VACANCES, LISTE_FERIES DICT_CATEGORIES = self.ImportCategories() LISTE_VACANCES = self.Importation_Vacances() LISTE_FERIES = self.Importation_Feries() # Création du tableau dataTableau = [] enteteTableau = [] largeursColonnes = [] styleTableau = [] listeMois = (_(u"Janvier"), _(u"Février"), _(u"Mars"), _(u"Avril"), _(u"Mai"), _(u"Juin"), _(u"Juillet"), _(u"Août"), _(u"Septembre"), _(u"Octobre"), _(u"Novembre"), _(u"Décembre")) listeJours = (u"L", u"M", u"M", u"J", u"V", u"S", u"D") # Création de l'entete du tableau index = 1 for nomMois in listeMois: largeursColonnes.append(largeurMois) if index != 12: largeursColonnes.append(espaceMois) enteteTableau.append(nomMois) if index != 12: enteteTableau.append("") index += 1 dataTableau.append(enteteTableau) styleTableau.append(('ALIGN', (0, 0), (-1, 0), 'CENTRE')) styleTableau.append(('FONT', (0, 0), (-1, 0), "Helvetica-Bold", 8)) # Création des lignes vides for x in range(1, 33): ligne = [] for case in range(0, 23): ligne.append(None) dataTableau.append(ligne) # Style général du tableau styleTableau.append(('FONT', (0, 1), (-1, -1), "Helvetica", 7)) styleTableau.append(('LEFTPADDING', (0, 1), (-1, -1), 0)) styleTableau.append(('RIGHTPADDING', (0, 1), (-1, -1), 0)) styleTableau.append(('TOPPADDING', (0, 1), (-1, -1), 0)) styleTableau.append(('BOTTOMPADDING', (0, 1), (-1, -1), 0)) # Remplissage du tableau numMois = 1 for nomMois in listeMois: # Création d'un mois totalMinutesMois = 0 numWeekDay, nbreJoursMois = calendar.monthrange( self.annee, numMois) numCol = (numMois * 2) - 2 for numJour in range(1, nbreJoursMois + 1): # Création des labels des dates dateDD = datetime.date(year=self.annee, month=numMois, day=numJour) nomJour = listeJours[dateDD.weekday()] labelDate = u"%s %d" % (nomJour, numJour) # Création du contenu de chaque case if dateDD in self.dictPresences: dictBarres = self.dictPresences[dateDD] else: dictBarres = {} case = CaseDate(xoffset=0, hauteurCase=10, largeurCase=largeurMois, dateDD=dateDD, labelDate=labelDate, dictBarres=dictBarres) dataTableau[numJour][numCol] = case # Calcule le nbre d'heures du mois if dateDD in self.dictPresences: totalMinutesMois += self.dictPresences[dateDD]["totalJour"] # Ecrit le nombre d'heures du mois if AFFICHER_HEURES_MOIS == True and totalMinutesMois != 0: numJour += 1 dataTableau[numJour][numCol] = minutesEnHeures( totalMinutesMois) styleTableau.append(('FONT', (numCol, numJour), (numCol, numJour), "Helvetica", 5)) styleTableau.append( ('ALIGN', (numCol, numJour), (numCol, numJour), "RIGHT")) styleTableau.append( ('VALIGN', (numCol, numJour), (numCol, numJour), "TOP")) # Définit le style du tableau styleTableau.append(('GRID', (numCol, 0), (numCol, nbreJoursMois), 0.25, colors.black)) numMois += 1 tableau = Table(dataTableau, largeursColonnes) tableau.setStyle(TableStyle(styleTableau)) story.append(tableau) story.append(Spacer(0, 25)) # Légendes des catégories dataTableauLegende = [] largeursColonnesLegende = [] styleTableauLegende = [] # Création des lignes vides du tableau des légendes nbreLignesLegendes = 5 nbreColonnesLegendes = 4 largeurColonneLegende = 178.75 for numLigne in range(0, nbreLignesLegendes): ligne = [] for numCol in range(0, nbreColonnesLegendes): ligne.append(None) dataTableauLegende.append(ligne) # Création de la liste des largeurs des colonnes for x in range(0, nbreColonnesLegendes): largeursColonnesLegende.append(largeurColonneLegende) # Remplissage du tableau des légendes nbre_legendes = 0 total_heures = 0 numLigne = 0 numCol = 0 if AFFICHER_VACANCES == True: dataTableauLegende[numLigne][numCol] = CaseLegende( 0, 10, _(u"Vacances"), COULEUR_VACANCES, None) numLigne += 1 if AFFICHER_WE == True: dataTableauLegende[numLigne][numCol] = CaseLegende( 0, 10, _(u"Week-ends"), COULEUR_WE, None) numLigne += 1 if AFFICHER_FERIES == True: dataTableauLegende[numLigne][numCol] = CaseLegende( 0, 10, _(u"Jours fériés"), COULEUR_FERIES, None) numLigne += 1 for IDcategorie, nbreHeures in self.dictTotauxCategories.items(): if IDcategorie != "totalAnnee": nom_categorie, ordre, couleur = DICT_CATEGORIES[IDcategorie] legende = CaseLegende(0, 10, nom_categorie, couleur, nbreHeures) dataTableauLegende[numLigne][numCol] = legende nbre_legendes += 1 total_heures += nbreHeures numLigne += 1 if numLigne == nbreLignesLegendes: numLigne = 0 numCol += 1 if nbre_legendes > 1: # Ajoute un total d'heures pour l'année legende = CaseLegende(0, 10, _(u"Total pour l'année"), None, total_heures) dataTableauLegende[numLigne][numCol] = legende styleTableauLegende.append(('FONT', (0, 1), (-1, -1), "Helvetica", 6)) styleTableauLegende.append(('LEFTPADDING', (0, 0), (-1, -1), 0)) styleTableauLegende.append(('RIGHTPADDING', (0, 0), (-1, -1), 0)) styleTableauLegende.append(('TOPPADDING', (0, 0), (-1, -1), 0)) styleTableauLegende.append(('BOTTOMPADDING', (0, 0), (-1, -1), 0)) tableauLegende = Table(dataTableauLegende, largeursColonnesLegende) tableauLegende.setStyle(TableStyle(styleTableauLegende)) if AFFICHER_LEGENDE == True: story.append(tableauLegende) # Enregistrement du PDF doc.build(story) # Affichage du PDF FonctionsPerso.LanceFichierExterne(nomDoc)
def GetTracks(self): """ Récupération des données """ # Récupération du IDfichier IDfichier = FonctionsPerso.GetIDfichier() # Lecture des fichiers du répertoire SYNC listeFichiers = os.listdir(UTILS_Fichiers.GetRepSync()) listeListeView = [] for nomFichier in listeFichiers: if nomFichier.startswith("actions_%s" % IDfichier) and ( nomFichier.endswith(".dat") or (nomFichier.endswith(".archive") and self.inclure_archives == True)): nomFichierCourt = nomFichier.replace(".dat", "").replace( ".archive", "") # Taille fichier tailleFichier = os.path.getsize( UTILS_Fichiers.GetRepSync(nomFichier)) # Horodatage horodatage = nomFichierCourt.split("_")[2] horodatage = UTILS_Dates.HorodatageEnDatetime(horodatage) # Lecture du contenu du fichier DB = GestionDB.DB( suffixe=None, nomFichier=UTILS_Fichiers.GetRepSync(nomFichier), modeCreation=False) req = """SELECT IDparametre, nom, valeur FROM parametres;""" DB.ExecuterReq(req) listeParametres = DB.ResultatReq() dictParametres = {} for IDparametre, nom, valeur in listeParametres: dictParametres[nom] = valeur if dictParametres.has_key("nom_appareil") == False: dictParametres["nom_appareil"] = "Appareil inconnu" if dictParametres.has_key("ID_appareil") == False: dictParametres["ID_appareil"] = "IDAppareil inconnu" liste_details_actions = [] req = """SELECT IDconso, horodatage, action FROM consommations;""" DB.ExecuterReq(req) listeConsommations = DB.ResultatReq() if len(listeConsommations) > 0: liste_details_actions.append( _(u"%d actions sur les consommations") % len(listeConsommations)) req = """SELECT IDmemo, horodatage, action FROM memo_journee;""" DB.ExecuterReq(req) listeMemosJournees = DB.ResultatReq() if len(listeMemosJournees) > 0: liste_details_actions.append( _(u"%d actions sur les mémos journaliers") % len(listeMemosJournees)) DB.Close() detail_actions = ", ".join(liste_details_actions) if detail_actions == "": detail_actions = _(u"Aucune action") dictTemp = { "nom_fichier": nomFichier, "taille_fichier": tailleFichier, "nom_appareil": dictParametres["nom_appareil"], "ID_appareil": dictParametres["ID_appareil"], "horodatage": horodatage, "detail_actions": detail_actions } listeListeView.append(Track(dictTemp)) return listeListeView
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 OnBoutonImporter(self, event): # Récupération de la langue dictLangue = self.ctrl_langues.GetCode() if dictLangue == None: dlg = wx.MessageDialog( self, _(u"Vous devez sélectionner une langue dans la liste !"), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return nom_langue = dictLangue["nom"] code_langue = dictLangue["code"] textes_langue = dictLangue["textes"] # Récupération des fichiers fichier_original = self.ctrl_fichier_importer_original.GetValue() if fichier_original == "": dlg = wx.MessageDialog( self, _(u"Vous devez sélectionner un fichier de textes originaux !" ), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return fichier_traduction = self.ctrl_fichier_importer_traduction.GetValue() if fichier_traduction == "": dlg = wx.MessageDialog( self, _(u"Vous devez sélectionner un fichier de textes traduits !"), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return # Lecture des textes fichier = open(fichier_original, "r") lignesOriginal = fichier.readlines() fichier.close() fichier = open(fichier_traduction, "r") lignesTraduction = fichier.readlines() fichier.close() if len(lignesOriginal) != len(lignesTraduction): dlg = wx.MessageDialog( self, _(u"Le nombre de lignes des deux fichiers doit être identique !" ), _(u"Erreur"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return # Demande de confirmation dlg = wx.MessageDialog( None, _(u"Confirmez-vous l'insertion de %d textes traduits dans le fichier '%s' ?" ) % (len(lignesOriginal), nom_langue), "Confirmation", wx.YES_NO | wx.YES_DEFAULT | wx.ICON_EXCLAMATION) if dlg.ShowModal() == wx.ID_NO: return False dlg.Destroy() else: dlg.Destroy() # Fusion des traductions dictTraductions = {} indexLigne = 0 for texte in lignesOriginal: if len(texte) > 0: dictTraductions[texte[:-1]] = lignesTraduction[indexLigne][:-1] indexLigne += 1 # Création du fichier de traduction perso nomFichier = UTILS_Fichiers.GetRepLang(u"%s.xlang" % code_langue) if os.path.isfile(nomFichier): flag = "w" else: flag = "n" fichier = shelve.open(nomFichier, flag) # Remplissage du fichier fichier["###INFOS###"] = { "nom_langue": nom_langue, "code_langue": code_langue } for texte, traduction in dictTraductions.iteritems(): fichier[texte] = traduction if "Bienvenue" in texte: print texte, " --> ", (traduction, ) # Clôture du fichier fichier.close() # Confirmation dlg = wx.MessageDialog( self, _(u"L'importation des traductions s'est déroulée avec succès !" ), _(u"Succès"), wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy()
def GetListeFichiersLocal(self): """ Récupère la liste des fichiers locaux à afficher """ # Lit le répertoire chemin = UTILS_Fichiers.GetRepData() fichiers = os.listdir(chemin) fichiers.sort() listeFichiers = [] for fichier in fichiers: nomFichier = os.path.split(fichier)[1] titre = nomFichier[:-9] cheminFichier = chemin + "/" + fichier if (self.prefixe == None and nomFichier.endswith("_DATA.dat")) or ( self.prefixe != None and nomFichier.endswith("_DATA.dat") and nomFichier.startswith(self.prefixe)): # Taille des 3 bases de données taille = 0 for suffixe in ("DATA", "DOCUMENTS", "PHOTOS"): fichierTemp = u"%s/%s_%s.dat" % (chemin, titre, suffixe) if os.path.isfile(fichierTemp): taille += os.path.getsize(fichierTemp) taille = FormatFileSize(taille) # Date dernière modification t = os.path.getmtime(cheminFichier) date = datetime.datetime.fromtimestamp(t) dateModif = date.strftime("%d/%m/%Y %H:%M") # Ouverture de la base de données pour récupérer les infos sur le fichier logo = None description = u"" try: connexion = sqlite3.connect(cheminFichier.encode('utf-8')) cursor = connexion.cursor() req = "SELECT nom, logo FROM organisateur WHERE IDorganisateur=1;" cursor.execute(req) description, logo = cursor.fetchone() connexion.close() except: pass if logo != None: try: io = six.BytesIO(logo) if 'phoenix' in wx.PlatformInfo: img = wx.Image(io, wx.BITMAP_TYPE_ANY) else: img = wx.ImageFromStream(io, wx.BITMAP_TYPE_ANY) img = RecadreImg(img) image = img.ConvertToBitmap() except: image = None else: image = None # Mémorisation listeFichiers.append({ "titre": titre, "image": image, "description": description, "taille": taille, "dateModif": dateModif }) return listeFichiers
def Impression(self, listeRappels=[], nomDoc=None, afficherDoc=True, dictOptions=None, repertoire=None, repertoireTemp=False): """ Impression des factures """ # Récupération des données à partir des IDrappel resultat = self.GetDonneesImpression(listeRappels) if resultat == False: return False dictRappels, dictChampsFusion = resultat # Récupération des paramètres d'affichage if dictOptions == None: if afficherDoc == False: dlg = DLG_Apercu_rappel.Dialog( None, titre=_( u"Sélection des paramètres de la lettre de rappel"), intro= _(u"Sélectionnez ici les paramètres d'affichage du rappel à envoyer par Email." )) dlg.bouton_ok.SetImageEtTexte("Images/32x32/Valider.png", _("Ok")) else: dlg = DLG_Apercu_rappel.Dialog(None) if dlg.ShowModal() == wx.ID_OK: dictOptions = dlg.GetParametres() dlg.Destroy() else: dlg.Destroy() return False # Création des PDF à l'unité def CreationPDFunique(repertoireCible=""): dictPieces = {} dlgAttente = wx.BusyInfo( _(u"Génération des lettres de rappel à l'unité au format PDF..." ), None) if 'phoenix' not in wx.PlatformInfo: wx.Yield() try: index = 0 for IDrappel, dictRappel in dictRappels.items(): if dictRappel["select"] == True: num_rappel = dictRappel["num_rappel"] nomTitulaires = self.Supprime_accent( dictRappel["nomSansCivilite"]) nomFichier = _(u"Lettre de rappel %d - %s") % ( num_rappel, nomTitulaires) cheminFichier = u"%s/%s.pdf" % (repertoireCible, nomFichier) dictComptesTemp = {IDrappel: dictRappel} self.EcritStatusbar( _(u"Edition de la lettre de rappel %d/%d : %s") % (index, len(dictRappel), nomFichier)) UTILS_Impression_rappel.Impression( dictComptesTemp, dictOptions, IDmodele=dictOptions["IDmodele"], ouverture=False, nomFichier=cheminFichier) dictPieces[IDrappel] = cheminFichier index += 1 self.EcritStatusbar("") del dlgAttente return dictPieces except Exception as err: del dlgAttente traceback.print_exc(file=sys.stdout) dlg = wx.MessageDialog( None, _(u"Désolé, le problème suivant a été rencontré dans l'édition des lettres de rappel : \n\n%s" ) % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False # Répertoire souhaité par l'utilisateur if repertoire != None: resultat = CreationPDFunique(repertoire) if resultat == False: return False # Répertoire TEMP (pour Emails) dictPieces = {} if repertoireTemp == True: dictPieces = CreationPDFunique(UTILS_Fichiers.GetRepTemp()) if dictPieces == False: return False # Fabrication du PDF global if repertoireTemp == False: dlgAttente = wx.BusyInfo( _(u"Création du PDF des lettres de rappel..."), None) if 'phoenix' not in wx.PlatformInfo: wx.Yield() self.EcritStatusbar( _(u"Création du PDF des lettres de rappel en cours... veuillez patienter..." )) try: UTILS_Impression_rappel.Impression( dictRappels, dictOptions, IDmodele=dictOptions["IDmodele"], ouverture=afficherDoc, nomFichier=nomDoc) self.EcritStatusbar("") del dlgAttente except Exception as err: del dlgAttente traceback.print_exc(file=sys.stdout) err = str(err).decode("iso-8859-15") dlg = wx.MessageDialog( None, _(u"Désolé, le problème suivant a été rencontré dans l'édition des lettres de rappel : \n\n%s" ) % err, _(u"Erreur"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False return dictChampsFusion, dictPieces
def SupprimerFichier(self, titre=""): """ Supprimer un fichier """ if UTILS_Utilisateurs.VerificationDroitsUtilisateurActuel( "fichier_fichier", "supprimer") == False: return # Demande de confirmation dlg = wx.MessageDialog( None, _(u"Souhaitez-vous vraiment supprimer le fichier '%s' ?") % titre, _(u"Supprimer un fichier"), wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_QUESTION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES: return dlg = wx.MessageDialog( None, _(u"Attention, la suppression est irreversible !!! \n\n Vous êtes vraiment sûr de vouloir supprimer le fichier '%s' ?" ) % titre, _(u"Supprimer un fichier"), wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_EXCLAMATION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES: return # Supprimer un fichier local if self.mode == "local": for suffixe in ("DATA", "DOCUMENTS", "PHOTOS"): try: os.remove( UTILS_Fichiers.GetRepData(u"%s_%s.dat" % (titre, suffixe))) except Exception as err: pass # Supprime un fichier réseau if self.mode == "reseau": hote = self.codesReseau["hote"] utilisateur = self.codesReseau["utilisateur"] motdepasse = self.codesReseau["motdepasse"] port = self.codesReseau["port"] DB = GestionDB.DB(nomFichier=u"%s;%s;%s;%s[RESEAU]" % (port, hote, utilisateur, motdepasse)) if DB.echec == 1: dlg = wx.MessageDialog( self, _(u"Erreur de connexion MySQL !\n\n%s") % DB.erreur, _(u"Erreur de connexion"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return for suffixe in ("data", "documents", "photos"): DB.ExecuterReq("""DROP DATABASE IF EXISTS %s_%s;""" % (titre, suffixe)) DB.Close() self.Remplissage()
def Installer(self): """ Installation de Connecthys """ dlg = wx.MessageDialog(None, _(u"Confirmez-vous l'installation du portail internet Connecthys ?\n\nRemarque : Ce processus peut nécessiter plusieurs dizaines de minutes (selon votre connexion internet)"), _(u"Installation"), wx.YES_NO|wx.YES_DEFAULT|wx.CANCEL|wx.ICON_QUESTION) reponse = dlg.ShowModal() dlg.Destroy() if reponse != wx.ID_YES : return False try : # Recherche la taille du fichier à télécharger sur Github num_essai = 1 taille_fichier = 0 while num_essai < 3 : taille_fichier = AffichetailleFichier(self.url_telechargement) if taille_fichier > 0 : break else : time.sleep(1) if taille_fichier == 0 : raise Abort(u"Impossible de trouver le source de Connecthys sur internet ! ") # Téléchargement de la source sur Github self.parent.EcritLog(_(u"Téléchargement des fichiers source Connecthys")) self.Telecharger() # Dézippage du fichier self.parent.EcritLog(_(u"Décompression des fichiers source Connecthys")) self.Dezipper(self.nom_fichier_dest, UTILS_Fichiers.GetRepTemp()) # Envoi des fichiers dans le répertoire d installation self.parent.EcritLog(_(u"Upload des fichiers Connecthys")) source_repertoire = UTILS_Fichiers.GetRepTemp("Connecthys-master/connecthys") self.Upload(source_repertoire) except Abort : wx.Yield() if self.dlgprogress != None : self.dlgprogress.Destroy() del self.dlgprogress time.sleep(2) dlg = wx.MessageDialog(None, _(u"Procédure d'installation interrompue."), "Erreur", wx.OK | wx.ICON_EXCLAMATION) dlg.Raise() dlg.ShowModal() dlg.Destroy() return False except Exception, err : wx.Yield() if self.dlgprogress != None : self.dlgprogress.Destroy() del self.dlgprogress traceback.print_exc() print "Erreur dans l'installation de l'application : " print err time.sleep(2) dlg = wx.MessageDialog(None, _(u"Une erreur a été rencontrée !"), "Erreur", wx.OK | wx.ICON_ERROR) dlg.Raise() dlg.ShowModal() dlg.Destroy() return False
def OnBoutonOk(self, event): index = self.ctrl_fichiers.GetFirstSelected() if index == -1 : dlg = wx.MessageDialog(self, _(u"Vous devez sélectionner un fichier dans la liste !"), _(u"Erreur de saisie"), wx.OK | wx.ICON_EXCLAMATION) dlg.ShowModal() dlg.Destroy() return titre = self.ctrl_fichiers.GetItemPyData(index)["titre"] nomFichier = self.GetNomFichier() listeOptions = self.ctrl_options.GetIDcoches() # Demande de confirmation nbreFamilles = self.GetNbreFamilles() if nbreFamilles > 0 : dlg = wx.MessageDialog(self, _(u"Attention, %d fiches familles sont déjà saisies dans ce fichier. Si vous utilisez la fonction d'importation, TOUTES les fiches actuelles seront écrasées !!!\n\nSouhaitez-vous tout de même continuer ?") % nbreFamilles, _(u"Avertissement"), wx.YES_NO|wx.NO_DEFAULT|wx.CANCEL|wx.ICON_EXCLAMATION) if dlg.ShowModal() != wx.ID_YES : dlg.Destroy() return False dlg.Destroy() dlg = wx.MessageDialog(self, _(u"Souhaitez-vous vraiment lancer l'importation des familles du fichier '%s' ?\n\nAttention, toutes les données actuelles seront écrasées !") % titre, _(u"Confirmation"), wx.YES_NO|wx.NO_DEFAULT|wx.CANCEL|wx.ICON_EXCLAMATION) if dlg.ShowModal() != wx.ID_YES : dlg.Destroy() return False dlg.Destroy() # Importation des tables listeTables = [ "comptes_payeurs", "familles", "individus", "liens", "medecins", "payeurs", "categories_travail", "caisses", "rattachements", "regimes", "secteurs", "types_sieste", "problemes_sante", "types_maladies", "types_vaccins", "vaccins", "vaccins_maladies", ] if "abonnements" in listeOptions : listeTables.extend(["abonnements", "listes_diffusion"]) if "scolarite" in listeOptions : listeTables.extend(["classes", "ecoles", "niveaux_scolaires", "scolarite"]) if "questionnaire" in listeOptions : listeTables.extend(["questionnaire_categories", "questionnaire_choix", "questionnaire_filtres", "questionnaire_questions", "questionnaire_reponses"]) if "pieces" in listeOptions : listeTables.extend(["pieces", "types_pieces"]) if "messages" in listeOptions : listeTables.extend(["messages", "messages_categories"]) if "quotients" in listeOptions : listeTables.extend(["quotients",]) if "mandats" in listeOptions : listeTables.extend(["mandats",]) DB = GestionDB.DB() for nomTable in listeTables : # Réinitialisation de la table print "Reinitialisation de la table %s..." % nomTable DB.ExecuterReq("DROP TABLE %s;" % nomTable) DB.Commit() DB.CreationTable(nomTable, Tables.DB_DATA) # Importation des données print "Importation de la table %s..." % nomTable if self.radio_local.GetValue() == True : DB.Importation_table(nomTable=nomTable, nomFichierdefault=UTILS_Fichiers.GetRepData(u"%s_DATA.dat" % nomFichier)) else : DB.Importation_table(nomTable=nomTable, nomFichierdefault=nomFichier+"_data", mode="reseau") DB.Close() # Fin nbreFamilles = self.GetNbreFamilles() dlg = wx.MessageDialog(self, _(u"La procédure d'importation est terminée !\n\n%d familles ont été importées avec succès.") % nbreFamilles, _(u"Confirmation"), wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() self.EndModal(wx.ID_OK)
def __init__(self, parent, listeChamps) : self.parent = parent self.listeChamps = listeChamps self.nomDocument = UTILS_Fichiers.GetRepTemp("Impression_DUE") if "win" in sys.platform : self.nomDocument = self.nomDocument.replace("/", "\\") threading.Thread.__init__(self)