#!/usr/bin/env python3 # -*- coding: utf-8 -*- from configuration import * from gestion_erreurs import * from gestion_couleurs import * import datetime import json import unidecode import copy ############ Fonctions de conversion def convertit_jours_vers_python(chaine,liste_err): """ convertit une chaine de type 1a 3m 1s 10j en jours Renvoie un nombre de jours en float Si un des caractères n'est ni un nombre, ni une lettre "autorisée" ni une espace, on affiche un warning et on ignore ce caractère """ chainenombre = "" agejours = 0. for lettre in chaine: if lettre.isdigit(): chainenombre += lettre else: if lettre == 'a' or lettre == 'A': # On a trouvé l'année, on ajoute tout ce qui est trouvé jusque là agejours += int(chainenombre)*jours_dans_annee chainenombre = "" elif lettre == 'm' or lettre == 'M': # On a trouvé le mois agejours += int(chainenombre)*jours_dans_mois chainenombre = "" elif lettre == 's' or lettre == 'S': # la semaine agejours += int(chainenombre)*jours_dans_semaine chainenombre = "" elif lettre == 'j' or lettre == 'J': # On a trouvé le jour agejours += int(chainenombre) chainenombre = "" elif lettre != ' ': # autre caractère : bizarre ? warning("convertit_jour_vers_python : caractère invalide : "+lettre,liste_err) # à la fin s'il reste qqch on le garde dans les jours if chainenombre != "": agejours += int(chainenombre) if agejours<0: warning("L'âge est négatif !",liste_err) agejours = 0 return agejours def convertit_age_vers_texte(nombre): """ convertit un nombre de jours en un truc plus lisible en mois, années, jours et renvoie une chaîne sous la forme 3a2m1j par exemple""" annees = int(nombre / jours_dans_annee) restant = nombre - annees*jours_dans_annee mois = int(restant/jours_dans_mois) jours= round(nombre - mois*jours_dans_mois - annees*jours_dans_annee) chaine = "" if annees >0: chaine += str(annees)+"a" if mois >0: chaine += str(mois)+"m" if jours>0 or nombre ==0: # si c'est la naissance, faut beien écrire 0j quand même chaine += str(jours)+"j" return chaine ########################## def simplifie_nom(chaine): """ simplifie le nom chaine afin d'en faire une extension pour le nom du fichier. Met tout en minuscules et vire les caractères spéciaux et max 15 caractères""" chaine2 = "" for l in chaine: if l.isalpha(): chaine2+=l chaine2 = unidecode.unidecode(chaine2) return chaine2[:15] def convertit_poids_vers_python(chaine,liste_err): """ convertit une chaine vers un float qui est le poids. On gère notamment la virgule, et on enlève les espaces Un poids invalide -> on renvoie 0 avec un warning""" chaine2 = chaine.replace(",",".") chaine2 = chaine2.replace(" ","") try: poids = float(chaine2) except: warning("Poids impossible à lire : "+chaine,liste_err) poids = 0 if not( 0<=poids largeur_graphique_max: largeur = largeur_graphique_max warning("Largeur trop grande !",liste_err) elif largeur < largeur_graphique_min: largeur = largeur_graphique_min warning("Largeur trop petite !",liste_err) configuration["largeur"] = largeur hauteur = data.get("hauteur","") if hauteur == "": hauteur = DEFAUT["hauteur_graphique"] else: try: hauteur = int(hauteur) except: warning("La hauteur "+hauteur+"est invalide !",liste_err) hauteur = DEFAUT["hauteur_graphique"] if hauteur > hauteur_graphique_max: hauteur = hauteur_graphique_max warning("Hauteur trop grande !",liste_err) elif hauteur < hauteur_graphique_min: hauteur = hauteur_graphique_min warning("Hauteur trop petite !",liste_err) configuration["hauteur"] = hauteur # existence et position de la légende legende = data.get("legende","") if legende =="": legende = "non" elif legende=="on": legende = "oui" else: legende = "oui" configuration["legende"] = legende positionlegende = data.get("positionlegende","") if not(positionlegende in ['upper left','upper right','lower left','lower right']): positionlegende = "upper left" configuration["positionlegende"] = positionlegende #warning("bla"+data["couleur1"],liste_err) # coul1 = rgb_vers_tuple(data.get("couleur1",""),couleur_defaut_1_tuple,liste_err) # coul2 = rgb_vers_tuple(data.get("couleur2",""),couleur_defaut_2_tuple,liste_err) # coul3 = rgb_vers_tuple(data.get("couleur3",""),couleur_defaut_3_tuple,liste_err) # #warning("bla2"+str(coul1),liste_err) # configuration["couleur1"] = coul1 # configuration["couleur2"] = coul2 # configuration["couleur3"] = coul3 configuration["couleurs"] = {} # gérer les couleurs #warning("data : "+str(data),liste_err) for clecouleur in DEFAUT["couleurs"]: coul = rgb_vers_tuple(data.get("couleur_"+clecouleur,""),CONFIG["couleurs"][clecouleur],liste_err) configuration["couleurs"][clecouleur] = coul #warning("config : "+str(configuration["couleurs"]),liste_err) # couleur de fond # coul_fond = rgb_vers_tuple(data.get("couleur_fond",""),couleur_defaut_fond_tuple,liste_err) # configuration["couleur_fond"] = coul_fond # # # couleur d'axes et de texte # coul_cadretxt = rgb_vers_tuple(data.get("couleur_cadretxt",""),couleur_defaut_cadretxt_tuple,liste_err) # configuration["couleur_cadretxt"] = coul_cadretxt # # # couleur de la grille # coul_grille = rgb_vers_tuple(data.get("couleur_grille",""),couleur_defaut_grille_tuple,liste_err) # configuration["couleur_grille"] = coul_grille #warning(str(configuration["couleur1"]),liste_err) return configuration def gere_donneespoids(data,naissance,liste_err): """ prend en argument le dictionnaire de requête, et la date de naissance (éventuellement vide) et construit les deux listes l_jours et l_poids""" # On construit la liste des couples liste_donnees = [] i = 0 # On va chercher si y'a des données à poids_i while "poids_"+str(i) in data.keys(): if data["poids_"+str(i)] != "": poids = convertit_poids_vers_python(data["poids_"+str(i)],liste_err) age = data.get("age_"+str(i),"") if age !="": age = convertit_jours_vers_python(age,liste_err) liste_donnees.append((age,poids)) else: date = data.get("date_"+str(i),"") datep = convertit_date_vers_python(date,liste_err) # on vérifie la date if naissance == "": warning("La date de naissance n'a pas été précisée. Du coup on ne peut pas calculer l'âge de l'enfant le "+date,liste_err) elif datep != "": # la date est valide et on a une date de naissance age = delta_date(datep,naissance) liste_donnees.append((age,poids)) i+=1 # Trier la liste liste_donnees.sort(key=lambda x : x[0]) # splitter la liste l_jours = [x[0] for x in liste_donnees] l_poids = [x[1] for x in liste_donnees] return (l_jours,l_poids) def donnees_vers_json(l_jours,l_poids,config): """ retourne le json à renvoyer""" gros_dico = copy.deepcopy(config) l_jours2 = [convertit_age_vers_texte(d) for d in l_jours] gros_dico["data_j"] = l_jours2 gros_dico["data_p"] = l_poids # gérer la date de naissance if gros_dico.get("naissance","") != "": gros_dico["naissance"] = convertit_date_vers_texte(gros_dico["naissance"]) # gérer l'age maxi gros_dico["maxi"] = convertit_age_vers_texte(gros_dico["maxi"]) # gérer les couleurs # for cle in ["couleur1", "couleur2", "couleur3", "couleur_fond","couleur_grille","couleur_cadretxt"]: # gros_dico[cle] = tuple_vers_rgb(gros_dico[cle]) for clecouleur in DEFAUT["couleurs"]: gros_dico["couleurs"][clecouleur] = tuple_vers_rgb(gros_dico["couleurs"][clecouleur]) return json.dumps(gros_dico, indent=2,ensure_ascii=False ) def fichier_json_vers_configdonnees(fichier,liste_err): """ prend le json importé et l'exporte vers les valeurs du formulaire """ chaine = fichier.read() valform = json.loads(chaine) # Il faut maintenant récupérer les l_jours et l_poids puis les remettre # sous forme de age_i et poids_i l_jours= valform.get("data_j",[]) l_poids=valform.get("data_p",[]) if len(l_poids) != len(l_jours): warning("Lecture du json : les données sont incohérentes (listes de taille différentes et/ou pb de lecture") long = min(len(l_jours),len(l_poids)) else: long = len(l_jours) for i in range(long): valform["age_"+str(i)] = l_jours[i] valform["poids_"+str(i)] = l_poids[i] valform["nb_data"] = max(long +2,DEFAUT["nb_data"]) return valform