Package zephir :: Package backend :: Module etabs_rpc
[frames] | no frames]

Source Code for Module zephir.backend.etabs_rpc

  1  # -*- coding: UTF-8 -*- 
  2  ########################################################################### 
  3  # Eole NG - 2007 
  4  # Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon) 
  5  # Licence CeCill  cf /root/LicenceEole.txt 
  6  # eole@ac-dijon.fr 
  7  # 
  8  # etabs_rpc.py 
  9  # 
 10  # fonctions xmlrpc pour la gestion des etablissement sous Zephir 
 11  # 
 12  ########################################################################### 
 13  from zephir.backend import config 
 14  from zephir.backend.config import u, log 
 15  from zephir.backend.db_utils import * 
 16  from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC 
 17   
 18  # import relatifs aux tables 
 19  import psycopg2 as PgSQL 
 20   
 21  import sys,os,shutil 
 22   
23 -class RPCEtabs(XMLRPC):
24 """serveur XMLRPC zephir pour la gestion des établissements 25 """ 26
27 - def __init__(self,parent):
28 # connexion à la base de données zephir 29 self.dbpool = db_connect() 30 self.dbpool.noisy = 0 31 XMLRPC.__init__(self) 32 self.parent = parent
33 34
35 - def _got_etabs(self, etabs, cred_user):
36 """formate la sortie de la table etablissements 37 """ 38 l=[] 39 for etab in etabs: 40 try: 41 self.parent.s_pool.check_etab_credential(cred_user, etab[0]) 42 except: 43 continue 44 l.append({'rne':etab[0], 45 'libelle':etab[1], 46 'adresse':etab[2], 47 'ville':etab[9], 48 'cp':etab[10], 49 'tel':etab[3], 50 'fax':etab[4], 51 'mail':etab[5], 52 'responsable':etab[6], 53 'remarques':etab[7], 54 'type':etab[8] 55 }) 56 return 1,u(l)
57
58 - def _got_libelle_ville_etabs(self,etabs):
59 """formate la sortie de la table etablissements 60 """ 61 l1=[] 62 l2=[] 63 for etab in etabs: 64 l1.append(etab[0]) 65 if etab[1] not in l2: 66 l2.append(etab[1]) 67 return 1,u([l1,l2])
68
69 - def _got_types(self,types_etab):
70 """formate la sortie des types d'établissement 71 """ 72 d={} 73 for t in types_etab: 74 d[str(t[0])]=u(t[1]) 75 return 1,[d]
76
77 - def xmlrpc_get_etab(self,cred_user, rne=None):
78 """Récupération des données d'un établissement (ou de tous) 79 """ 80 if rne: 81 query = """select * from etablissements where rne ilike %s""" 82 return self.dbpool.runQuery(query, (rne,)).addCallbacks(self._got_etabs,db_client_failed,callbackArgs=[cred_user]) 83 else: 84 # si pas de rne demandé, on renvoie tous les établissements connus 85 query = """select * from etablissements""" 86 return self.dbpool.runQuery(query).addCallbacks(self._got_etabs,db_client_failed,callbackArgs=[cred_user])
87
88 - def xmlrpc_get_libelle_etab(self,cred_user):
89 """Récupération des données d'un établissement (ou de tous) 90 """ 91 query = """select libelle, ville from etablissements order by ville""" 92 return self.dbpool.runQuery(query).addCallbacks(self._got_libelle_ville_etabs,db_client_failed)
93
94 - def _load_types(self,cx):
95 """lit les types établissement et renvoie un dictionnaire 96 """ 97 cursor=cx.cursor() 98 # on lit la base 99 cursor.execute("""select id,libelle from types_etab""") 100 result = cursor.fetchall() 101 cursor.close() 102 num_types = {} 103 # correspondance libelle -> n° 104 for row in result: 105 num_types[row[1].upper()]=row[0] 106 107 return num_types
108 109
110 - def xmlrpc_import_etab(self,cred_user,data):
111 """importe des établissements depuis un fichier csv""" 112 # recherche des types d'établissement 113 # from nomenclature import nomenclature_ramses 114 # correspondances des types etab 115 query = """select rne from etablissements""" 116 return self.dbpool.runQuery(query).addCallbacks(self._import_etab,db_client_failed,callbackArgs=[cred_user,data])
117
118 - def _import_etab(self,liste_rne,cred_user,data):
119 # mise à plat de la liste des rnes existants 120 existants = [rne[0] for rne in liste_rne] 121 nouveaux = [] 122 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD) 123 num_types = self._load_types(cx) 124 cx.close() 125 errors=[] 126 # on commence par vérifier les types d'établissement 127 missing=[] 128 for etab in data: 129 libelle = etab[3] 130 if libelle.strip() == "": 131 libelle = "INDEFINI" 132 etab[3] = libelle 133 if libelle.upper() not in num_types.keys(): 134 if libelle.upper() not in missing: 135 missing.append(libelle.upper()) 136 137 if missing != []: 138 dict_miss = [] 139 for miss in missing: 140 dict_miss.append({'miss':miss}) 141 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD) 142 cursor=cx.cursor() 143 # on ajoute les types non existants 144 cursor.executemany("insert into types_etab (libelle) values (%(miss)s)", dict_miss) 145 cursor.close() 146 cx.commit() 147 # on relit la base 148 num_types = self._load_types(cx) 149 cx.close() 150 151 # on ajoute/met à jour les etablissements 152 for etab in data: 153 rne = etab[0] 154 # type_etab = nomenclature_ramses[etab[1] + '_' + etab[2]] 155 libelle = etab[3] + " " + etab[4] 156 cp = etab[5] 157 adresse = " " 158 ville = etab[6] 159 telephone = etab[9] 160 fax = etab[8] 161 mail = etab[7] 162 responsable = "inconnu" 163 remarques = "" 164 # on récupère son n° de type 165 if num_types.has_key(etab[3].upper()): 166 type_etab = num_types[etab[3].upper()] 167 if rne in existants: 168 # mise à jour d'un établissement existant 169 update_infos = {'libelle':libelle, 170 'adresse':adresse, 171 'ville':ville, 172 'cp':cp, 173 'tel':telephone, 174 'fax':fax, 175 'mail':mail, 176 'responsable':responsable, 177 'remarques':remarques, 178 'type':type_etab} 179 res = self.xmlrpc_edit_etab(cred_user, rne, update_infos) 180 # on le supprime de la liste des rnes pour conserver ceux 181 # qui ne sont plus dans le fichier 182 existants.remove(rne) 183 else: 184 try: 185 res = self.xmlrpc_add_etab(cred_user,rne,libelle,adresse,ville,cp,telephone,fax,mail,responsable,remarques,type_etab) 186 nouveaux.append([rne, libelle]) 187 except: 188 log.msg("Erreur à la création de l'établissement %s" % rne) 189 traceback.print_exc() 190 if errors != []: 191 return 0,u('erreur : %s' % errors) 192 else: 193 return 1, u((existants, nouveaux))
194 195
196 - def xmlrpc_add_etab(self,cred_user,rne,libelle,adresse,ville,cp,telephone,fax,mail,responsable,remarques,type_etab):
197 """ajoute un établissement""" 198 # on vérifie que les données obligatoires sont remplies 199 if (rne and libelle and type_etab): 200 # objet etab 201 query = """insert into etablissements values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)""" 202 params = (rne, libelle, adresse, telephone, fax, mail, responsable, remarques, type_etab, ville.upper(), cp) 203 # on effectue l'insertion (l'existence est à tester dans l'application cliente) 204 return self.dbpool.runOperation(query, params).addCallbacks(self._add_etab, db_client_failed,callbackArgs=[rne, cred_user]) 205 else: 206 # des attributs manquent 207 return 0,u('arguments manquants')
208
209 - def _add_etab(self,resultat, rne, cred_user):
210 """met en place l'arborescence zephir de l'établissement """ 211 # si nécessaire, on donne les droits d'accès à l'établissement pour la personne qui l'a créé 212 try: 213 self.parent.s_pool.check_etab_credential(cred_user, rne) 214 except: 215 log.msg("acces non permis , ajout d'une restriction") 216 self.parent.s_pool.add_restriction(cred_user,'rne',rne) 217 # création de l'arborescence de l'établissement 218 etab_dir = os.path.abspath(config.PATH_ZEPHIR)+'/conf/'+rne 219 try: 220 os.makedirs(etab_dir) 221 except: 222 return 0,u("erreur de création du répertoire de l'établissement") 223 else: 224 return 1,u(rne)
225
226 - def xmlrpc_del_etab(self,cred_user,rne):
227 """supprime un établissement""" 228 self.parent.s_pool.check_etab_credential(cred_user, rne) 229 # on vérifie qu'il ne reste pas de serveurs 230 query = """select id from serveurs where rne=%s""" 231 return self.dbpool.runQuery(query, (rne,)).addCallbacks(self._del_etab, db_client_failed,callbackArgs=[rne])
232
233 - def _del_etab(self,data,rne):
234 """supprime l'établissement dans la base de données""" 235 if len(data) > 0: 236 # on n'autorise pas la supression si il reste des serveurs 237 return 0, u("Suppression impossible, il existe des serveurs rattachés à cet établissement") 238 239 # on supprime la configuration uucp de tous les serveurs correspondants 240 try: 241 file_conf = open('/etc/uucp/config_zephir','r') 242 conf_uucp = file_conf.readlines() 243 file_conf.close() 244 except: 245 return 0, u("""erreur de lecture de /etc/uucp/config_zephir""") 246 try: 247 for sysfile in os.listdir('/etc/uucp/serveurs'): 248 if sysfile.startswith(rne+'-'): 249 # on supprime le fichier de définition du serveur 250 os.unlink('/etc/uucp/serveurs'+os.sep+sysfile) 251 # on supprime la référence à ce fichier dans /etc/uucp/config 252 conf_uucp.remove('sysfile /etc/uucp/serveurs/'+sysfile+'\n') 253 except: 254 # si pas encore de serveurs -> pas de répertoire 255 pass 256 257 # supression des logins/mots de passes correpondants 258 try: 259 # lecture des infos de login 260 file_pwd = open('/etc/uucp/passwd_zephir','r') 261 pwd_uucp = file_pwd.readlines() 262 file_pwd.close() 263 # supression des lignes pour cet étab 264 for line in pwd_uucp: 265 if line.startswith(rne+'-'): 266 pwd_uucp.remove(line) 267 # sauvegarde de la liste 268 file_pwd = open('/etc/uucp/passwd_zephir','w') 269 file_pwd.writelines(pwd_uucp) 270 file_pwd.close() 271 except: 272 return 0, u("""erreur de mise à jour du fichier des mots de passe""") 273 274 # mise à jour du fichier /etc/uucp/config_zephir 275 try: 276 file_conf = open('/etc/uucp/config_zephir','w') 277 file_conf.writelines(conf_uucp) 278 file_conf.close() 279 except: 280 return 0, u("""erreur d'écriture dans /etc/uucp/config_zephir""") 281 282 query = """delete from etablissements where rne=%s""" 283 return self.dbpool.runOperation(query, (rne,)).addCallbacks(self._del_etab2, db_client_failed,callbackArgs=[rne])
284
285 - def _del_etab2(self,resultat,rne):
286 """supprime l'arborescence de l'établissement""" 287 etab_dir = os.path.abspath(config.PATH_ZEPHIR)+'/conf/'+rne 288 # supression de ce répertoire ? 289 try: 290 shutil.rmtree(etab_dir) 291 except: 292 return 0,u("""erreur de supression du répertoire de l'établissement""") 293 else: 294 log.msg("établissement %s supprimé" % rne) 295 return 1,u('ok')
296 297 # modification d'un etablissement
298 - def xmlrpc_edit_etab(self,cred_user,rne,dico_modifs):
299 """modification d'un établissement 300 cette fonction prend en compte un dictionnaire qui indique les 301 champs à modifier et leur nouvelle valeur. l'application cliente 302 doit s'assurer que ces champs existent dans la base 303 ex: zephir.etabs.edit_etab('R620001X',{'libelle':'bla bla','type':1})""" 304 self.parent.s_pool.check_etab_credential(cred_user, rne) 305 # on vérifie que l'identifiant n'est pas modifié 306 if dico_modifs == {}: 307 return 1,u('ok') 308 if 'rne' in dico_modifs.keys(): 309 return 0,u('modification du rne interdit') 310 # construction de la requête SQL de modification 311 query=["update etablissements set "] 312 params = [] 313 for cle in dico_modifs.keys(): 314 query.append(str(cle)) 315 query.append("=%s") 316 params.append(str(dico_modifs[cle])) 317 query.append(", ") 318 string_fin=""" where rne=%s""" 319 params.append(rne) 320 query="".join(query)[:-2] 321 query += string_fin 322 return self.dbpool.runOperation(query, params).addCallbacks(lambda x:(1,'ok'), db_client_failed)
323
324 - def xmlrpc_rech_etab(self,cred_user,d):
325 """Recherche multi-critères d'un établissement 326 select * from etablissements where nom_champ like '%%libelle%%' 327 { rne, libelle, cp, type, ville } 328 """ 329 # construction de la requête SQL de recherche 330 query=["select * from etablissements where "] 331 params = [] 332 for nom_champ in d.keys(): 333 if d[nom_champ] != "": 334 if nom_champ == 'type': 335 query.append(str(nom_champ) + " = %s and ") 336 params.append(int(d[nom_champ])) 337 else: 338 query.append(str(nom_champ) + " ilike %s and ") 339 params.append(str(d[nom_champ])) 340 341 query = "".join(query)[:-4] 342 query += "order by RNE" 343 return self.dbpool.runQuery(query, params).addCallbacks(self._got_etabs, db_client_failed, callbackArgs=[cred_user])
344
345 - def xmlrpc_get_types(self,cred_user):
346 """Récupération des types d'établissement existants 347 """ 348 query = """select * from types_etab order by libelle""" 349 return self.dbpool.runQuery(query).addCallbacks(self._got_types,db_client_failed)
350 351
352 - def xmlrpc_add_type(self,cred_user,libelle):
353 """ajoute un type d'établissement dans la base de données""" 354 # on vérifie que les données obligatoires sont remplies 355 if (libelle): 356 query = """insert into types_etab (libelle) values (%s)""" 357 # on effectue l'insertion (l'existence est à tester dans l'application cliente) 358 return self.dbpool.runOperation(query, (libelle,)).addCallbacks(lambda x:(1,'ok'), db_client_failed) 359 else: 360 # des attributs manquent 361 return 0,u('libellé manquant')
362
363 - def xmlrpc_del_type(self,cred_user,id_type):
364 """ajoute un type d'établissement dans la base de données""" 365 # on vérifie que les données obligatoires sont remplies 366 if (id_type): 367 query = """delete from types_etab where id=%s""" 368 # on effectue l'insertion (l'existence est à tester dans l'application cliente) 369 return self.dbpool.runOperation(query, (int(id_type),)).addCallbacks(lambda x:(1,'ok'), db_client_failed) 370 else: 371 # des attributs manquent 372 return 0,u('identifiant manquant')
373