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