Package zephir :: Package backend :: Module modules_rpc
[hide private]
[frames] | no frames]

Source Code for Module zephir.backend.modules_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  # modules_rpc.py 
   9  #   
  10  # fonctions xmlrpc pour la gestion des modules dans Zephir 
  11  #        
  12  ########################################################################### 
  13  """module de gestion des modules Eole 
  14  """ 
  15  from twisted.python import log 
  16  from twisted.internet import reactor 
  17  from zephir.backend.db_utils import * 
  18  from zephir.backend import config 
  19  from zephir.backend.config import u 
  20  from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC 
  21  from zephir.backend.lib_backend import ResourceAuthError, istextfile, cx_pool 
  22  from zephir.utils.creolewrap import ZephirDict 
  23   
  24  # import relatifs aux tables 
  25  from twisted.enterprise import adbapi 
  26  import sys,os,shutil,md5,time,dico,base64,ConfigParser 
  27  from zephir.eolerpclib import xmlrpclib 
  28  from creole.cfgparser import EoleDict, eosfunc 
  29   
30 -class RPCModules(XMLRPC):
31 """serveur XMLRPC zephir pour la gestion des modules Eole 32 """ 33
34 - def __init__(self,parent,bdd='zephir-parc'):
35 self.dbpool = db_connect() 36 self.dbpool.noisy = 0 37 self.parent = parent 38 # mise à jour des modules si besoin 39 XMLRPC.__init__(self)
40
41 - def xmlrpc_update_modules(self,cred_user=''):
42 """vérification de la liste des modules""" 43 cursor = cx_pool.create() 44 try: 45 cursor.execute("""select libelle from modules""") 46 modules_actuels = [module[0] for module in cursor.fetchall()] 47 except: 48 cx_pool.close(cursor) 49 # Erreur de lecture des modules 50 print "\nErreur de lecture de la liste des modules\n" 51 return 0, u("Erreur de lecture de la liste des modules") 52 cx_pool.close(cursor) 53 new_modules = [] 54 for module in config.liste_modules: 55 if module not in modules_actuels: 56 if module in config.OLD_MODULES: 57 version = 1 58 else: 59 version = 2 60 # ajout d'un nouveau module 61 try: 62 new_modules.append(module) 63 self.xmlrpc_add_module("", module, version) 64 except: 65 return 0, u("erreur d'ajout du module %s" % module) 66 # log de la création des modules 67 if len(new_modules) > 0: 68 print "\nNouveaux modules: %s\n" % ", ".join(new_modules) 69 return 1, u("Nouveaux modules : %s" % ", ".join(new_modules)) 70 else: 71 return 1, u("OK")
72
73 - def _got_modules(self,modules,cred_user):
74 """Récupération de la table module depuis le backend 75 """ 76 l=[] 77 for module in modules: 78 try: 79 self.parent.s_pool.check_mod_credential(cred_user, module[0]) 80 except ResourceAuthError: 81 # non autorisé : module suivant 82 continue 83 if module[2] == None: 84 version = 1 85 else: 86 version = module[2] 87 l.append({'id':module[0],'libelle':module[1],'version':version}) 88 return 1,u(l)
89 90 ############################## 91 ## gestion de la table modules 92 ############################## 93 94
95 - def xmlrpc_add_module(self,cred_user, libelle, version=2):
96 """ajoute un module dans la base de données et crée l'arborescence correspondante""" 97 # on vérifie que les données obligatoires sont remplies 98 if libelle: 99 query = """insert into modules (libelle, version) values ('%s',%s)""" % (libelle.replace("'","\\\'"),int(version)) 100 # on effectue l'insertion (l'existence est à tester dans l'application cliente) 101 return self.dbpool.runOperation(query).addCallbacks(self._add_module1,db_client_failed,callbackArgs=[libelle, version]) 102 else: 103 # des attributs manquent 104 return 0, u("""donnez un libellé""")
105
106 - def _add_module1(self,resultat,libelle,version):
107 """récupère l'id du module créé""" 108 # requête pour récupérer l'id 109 query="""select id from modules where libelle ilike '%s'""" % libelle.replace("'","\\\'") 110 return self.dbpool.runQuery(query).addCallbacks(self._add_module2,db_client_failed,callbackArgs=[libelle,version])
111
112 - def _add_module2(self,row,libelle,version):
113 """crée la variante standard d'un nouveau module""" 114 if row ==[]: 115 return 0,u('erreur de création du module dans la base') 116 else: 117 id_module=row[0][0] 118 # on crée la variante standard du module 119 query = """insert into variantes (module,libelle) values (%s, 'standard')""" % id_module 120 return self.dbpool.runOperation(query).addCallbacks(self._add_module3,db_client_failed,callbackArgs=[id_module,libelle,version])
121
122 - def _add_module3(self,resultat,id_module,libelle,version):
123 """récupère l'id de la variante standard""" 124 query = """select id,module from variantes where module = %s and libelle = 'standard'""" % id_module 125 return self.dbpool.runQuery(query).addCallbacks(self._add_module4,db_client_failed,callbackArgs=[libelle,version])
126 127
128 - def _add_module4(self,row,libelle,version):
129 """met en place l'arborescence du nouveau module et de ses variantes""" 130 if row == []: 131 return 0,u('erreur de creation de la variante par défaut dans la base') 132 else: 133 id_variante = row[0][0] 134 id_module = row[0][1] 135 # on créé l'arborescence pour le module 136 module_dir = os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module) 137 try: 138 os.makedirs(module_dir) 139 # lien du(des) dictionnaire(s) 140 if int(version) == 1: 141 dico_module=os.path.abspath(config.ROOT_DIR)+'/dictionnaires/dico-%s' % libelle 142 os.system('ln -s %s %s' % (dico_module,module_dir+os.sep+'dictionnaire')) 143 else: 144 # module eole 2 145 dico_module=os.path.abspath(config.ROOT_DIR)+'/dictionnaires/%s' % libelle 146 if os.path.isdir(dico_module): 147 # modules de base eole 148 os.system('ln -s %s %s' % (dico_module, os.path.join(module_dir,'dicos'))) 149 # création d'un fichier de valeurs par défaut 150 d = EoleDict() 151 d.read_dir(os.path.join(module_dir,'dicos')) 152 # sauvegarde des valeurs sans vérifications pour créer le fichier 153 d.save_values(os.path.join(module_dir,'module.eol'),True) 154 else: 155 # module additionnel 156 os.makedirs(os.path.join(module_dir,'dicos')) 157 # on crée la variante par défaut (module standard) 158 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dicos') 159 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'patchs') 160 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_perso') 161 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_zephir') 162 except: 163 try: 164 shutil.rmtree(module_dir) 165 except: 166 # aucun répertoire créé 167 pass 168 query = """delete from variantes where module = %s""" % id_module 169 self.dbpool.runOperation(query) 170 query = """delete from modules where id = %s""" % id_module 171 self.dbpool.runOperation(query) 172 return 0, u("""erreur de creation de l'arborescence du module""") 173 # on récupère les données 174 # self.upload_module(id,adresse_donnees) 175 return 1, u(id_module)
176
177 - def xmlrpc_del_module(self,cred_user,id_module):
178 """supprime un module et ses variantes""" 179 if int(id_module) >= 0: 180 self.parent.s_pool.check_mod_credential(cred_user, id_module) 181 # suppression des variantes dans la base de données 182 query = "delete from variantes where module = %d" % int(id_module) 183 return self.dbpool.runOperation(query).addCallbacks(self._del_module,db_client_failed,callbackArgs=[id_module]) 184 else: 185 return 0, u("""donnez l'id d'un module (nombre entier)""")
186
187 - def _del_module(self,retour,id_module):
188 """supprime de la base les services liés au module""" 189 query = "delete from services where module = %d" % int(id_module) 190 return self.dbpool.runOperation(query).addCallbacks(self._del_module1,db_client_failed,callbackArgs=[id_module])
191
192 - def _del_module1(self,retour,id_module):
193 """supprime le module dans la base de données""" 194 query = "delete from modules where id = %s" % id_module 195 return self.dbpool.runOperation(query).addCallbacks(self._del_module2,db_client_failed,callbackArgs=[id_module])
196
197 - def _del_module2(self,retour,id_module):
198 """supprime l'arborescence du module dans l'arborescence zephir""" 199 module_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module) 200 try: 201 shutil.rmtree(module_dir) 202 except: 203 return 1,u("""erreur de supression du répertoire du module""") 204 return 1,u('ok')
205
206 - def xmlrpc_edit_module(self,cred_user,id_module,dico_modifs):
207 """modification d'un module 208 cette fonction prend en compte un dictionnaire qui indique les 209 champs à modifier et leur nouvelle valeur. l'application cliente 210 doit s'assurer que ces champs existent dans la base""" 211 self.parent.s_pool.check_mod_credential(cred_user, id_module) 212 if dico_modifs == {}: 213 return 1,u("""aucune modification demandée""") 214 # on vérifie que l'identifiant n'est pas modifié 215 if 'id' in dico_modifs.keys(): 216 return 0,u("""l'identifiant ne peut pas être modifié""") 217 # construction de la requête SQL de modification 218 requete=["update modules set "] 219 for cle in dico_modifs.keys(): 220 requete.append(str(cle)) 221 requete.append("='") 222 requete.append(str(dico_modifs[cle]).replace("'","\\\'")) 223 requete.append("', ") 224 string_fin=""" where id='%s'""" % id_module 225 query="".join(requete)[:-2] 226 query += string_fin 227 return self.dbpool.runOperation(query).addCallbacks(lambda x:(1,'ok'), db_client_failed)
228
229 - def xmlrpc_get_module(self,cred_user, id_module=None):
230 """récupère un module précis dans la base ou tous les modules""" 231 if id_module : 232 # on récupère le module demandé 233 query = """select id, libelle, version from modules where id = %s""" % id_module 234 return self.dbpool.runQuery(query).addCallbacks(self._got_modules,db_client_failed,callbackArgs=[cred_user]) 235 else : 236 # sinon on renvoie tous les modules 237 query = """select id, libelle, version from modules order by id""" 238 return self.dbpool.runQuery(query).addCallbacks(self._got_modules,db_client_failed,callbackArgs=[cred_user])
239
240 - def xmlrpc_get_dico(self,cred_user,id_module,id_variante=None):
241 """récupération du dictionnaire d'un module (valeurs par défaut)""" 242 # recherche du répertoire ou le dictionnaire est stocké 243 try: 244 query = "select version from modules where id = %d" % int(id_module) 245 except: 246 return 0, u("""donnez l'id d'un module (nombre entier)""") 247 return self.dbpool.runQuery(query).addCallbacks(self._get_dico,db_client_failed,callbackArgs=[id_module, id_variante])
248
249 - def _get_dico(self,data,id_module,id_variante=None):
250 # détection version de créole 251 try: 252 version = int(data[0][0]) 253 except: 254 version = 2 255 256 # dictionnaire de base du module 257 if version == 1: 258 # module Eole1 259 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'dictionnaire' 260 # envoi des fichiers de configuration au programme de saisie 261 try: 262 fic = open(path_dico,'r') 263 except: 264 return 0, u("""dictionnaire non présent""") 265 266 # dictionnaire du module 267 lines = fic.readlines() 268 fic.close() 269 dictionnaire = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ] 270 # dictionnaires additionnels 271 if id_variante is not None: 272 dicos=os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dicos' 273 for nom_fic in os.listdir(dicos): 274 if nom_fic.endswith('.eol') or nom_fic.endswith('.xml'): 275 # ajout d'un dictionnaire 276 fic = open(dicos+os.sep+nom_fic,'r') 277 lines = fic.readlines() 278 fic.close() 279 dictionnaire.extend([ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]) 280 281 # dictionnaire complet (dictionnaire module + dico locaux) 282 dic_complet=dico.DicoEole(dico_zephir=[dictionnaire]) 283 284 # si un dico.eol existait déjà, on reprend les anciennes valeurs 285 if id_variante is not None: 286 path_dicovar = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dico.eol' 287 if os.path.isfile(path_dicovar): 288 # on instancie un dictionnaire depuis dico.eol 289 # et un autre avec le dictionnaire complet 290 f=file(path_dicovar) 291 lines = f.readlines() 292 f.close() 293 data = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ] 294 # dictionnaire des valeurs actuelles 295 dic_actuel=dico.DicoEole(dico_zephir=[data]).ParseDico() 296 dico_final = {} 297 # on réinsère les données existantes dans le dictionnaire 298 for variable, data in dic_complet.dictionnaire.items(): 299 # si la variable existait déjà, on reprend sa valeur 300 if dic_actuel.has_key(data[0]): 301 data[1] = dic_actuel[data[0]][0] 302 dico_final[variable]=data 303 # on remet le dictionnaire modifié en place dans dico_serveur 304 dic_complet.dictionnaire = dico_final 305 306 dicos=[base64.encodestring(dic_complet.save("/dev/null"))] 307 else: 308 # version creole2 309 # chargement de configuration pour un serveur Eole2 310 path_module = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module) 311 path_dico = path_module+os.sep+'dicos' 312 # définition des dictionnaires à charger 313 dict_dirs = [path_dico] 314 if id_variante is not None: 315 dict_dirs.append(os.path.join(path_module,'variantes',str(id_variante),'dicos')) 316 # création de l'objet ZephirDict et lecture des valeurs existantes 317 dict_zeph = ZephirDict(dicos=dict_dirs, confdir=path_dico, mode='config', version='creole2') 318 if os.path.isfile(os.path.join(path_module,'module.eol')): 319 dict_zeph.dico.load_values(os.path.join(path_module,'module.eol')) 320 # traitement de la variable si demandé 321 if id_variante is not None: 322 path_var = os.path.join(path_module,'variantes',str(id_variante),'dico.eol') 323 dict_zeph.dico.load_values(os.path.join(path_var)) 324 dicos = dict_zeph.get_dict() 325 if dicos == None: 326 dicos = [] 327 328 return 1,u(dicos)
329
330 - def xmlrpc_get_vars(self,cred_user,id_module):
331 """récupération des libellés/familles des variables eole pour un module""" 332 # recherche du répertoire ou le dictionnaire est stocké 333 try: 334 query = "select id,version from modules where id = %d" % int(id_module) 335 except: 336 return 0, u("""donnez l'id d'un module (nombre entier)""") 337 return self.dbpool.runQuery(query).addCallbacks(self._get_vars,db_client_failed)
338
339 - def _get_vars(self,data):
340 # détection version de créole 341 try: 342 id_module = int(data[0][0]) 343 except: 344 return 0, u("""module non trouvé""") 345 try: 346 version = int(data[0][1]) 347 except: 348 version = 2 349 # dictionnaire de base du module 350 if version == 1: 351 # module Eole1 352 creole_files = [os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'dictionnaire'] 353 # récupération des familles de variables 354 dicos = [] 355 for dic in creole_files: 356 try: 357 # lecture du contenu des dictionnaires 358 fic = open(dic,'r') 359 lines = fic.readlines() 360 fic.close() 361 data = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ] 362 # stockage du contenu du dictionnaire 363 dicos.append(data) 364 except OSError: 365 pass 366 dict_zeph = ZephirDict(dicos=dicos, confdir='', mode='dico', version='creole1') 367 families = {} 368 else: 369 # version creole2 370 # chargement de configuration pour un serveur Eole2 371 path_module = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module) 372 path_dico = path_module+os.sep+'dicos' 373 # définition des dictionnaires à charger 374 dict_dirs = [path_dico] 375 # création de l'objet ZephirDict et lecture des valeurs existantes 376 dict_zeph = ZephirDict(dicos=dict_dirs, confdir=path_dico, mode='config', version='creole2') 377 families = {} 378 menu = dict_zeph.get_menu(True) 379 for family in menu: 380 for var in family[2]: 381 families[var] = family[0] 382 383 # dictionnaire variable, libelle 384 vars_dict = {} 385 try: 386 var_data = dict_zeph.get_first() 387 while 1: 388 if families.has_key(var_data[0]): 389 family = families[var_data[0]] 390 else: 391 family = '' 392 vars_dict[var_data[0]] = [var_data[2],family] 393 var_data = dict_zeph.get_next() 394 except: 395 # on arrive en fin de dictionnaire 396 pass 397 398 return 1,u(vars_dict)
399
400 - def xmlrpc_save_dico(self,cred_user,dico_b64,id_module,id_variante=None):
401 """mise à jour du dictionnaire d'un module (valeurs par défaut)""" 402 # recherche du libellé du module 403 self.parent.s_pool.check_mod_credential(cred_user, id_module) 404 if id_variante is not None: 405 self.parent.s_pool.check_var_credential(cred_user, id_variante) 406 query = """select id, libelle, version from modules where id=%s""" % id_module 407 return self.dbpool.runQuery(query).addCallbacks(self._save_dico, db_client_failed, callbackArgs=[dico_b64,id_variante])
408
409 - def _save_dico(self,data,dico_b64,id_variante=None):
410 if data == []: 411 return 0,u("""module non retrouvé""") 412 # récupération id et libellé module 413 id_module = data[0][0] 414 libelle = data[0][1] 415 version = data[0][2] 416 # gestion des différentes versions de creole 417 if int(version) == 1: 418 try: 419 # décodage du dictionnaire 420 dico = base64.decodestring(dico_b64) 421 # creole 1 -> encodage en latin-1 422 dico = unicode(dico,'UTF-8').encode('ISO-8859-1') 423 # sauvegarde 424 if id_variante is None: 425 path_dico = os.path.abspath(config.ROOT_DIR)+'/dictionnaires/dico-%s' % libelle 426 else: 427 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dico.eol' 428 fic_zephir = open(path_dico,'w') 429 fic_zephir.write(dico) 430 fic_zephir.close() 431 except: 432 return 0,u("""erreur de sauvegarde du dictionnaire""") 433 elif int(version) == 2: 434 if id_variante is None: 435 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'module.eol' 436 else: 437 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dico.eol' 438 values = eval(dico_b64[-1]) 439 try: 440 parser = ConfigParser.ConfigParser() 441 parser._sections = values 442 fic_zephir = open(path_dico,'w') 443 parser.write(fic_zephir) 444 fic_zephir.close() 445 except: 446 return 0,u("""erreur de sauvegarde du dictionnaire""") 447 448 return 1,u('ok')
449
450 - def xmlrpc_get_mod_dict(self,cred_user,id_module):
451 """renvoie la liste des dictionnaires d'un module. 452 utile pour les modules eole2 (fichier fixé pour les modules eole1) 453 """ 454 self.parent.s_pool.check_mod_credential(cred_user, id_module) 455 query = "select id, version from modules where id=%s" % int(id_module) 456 return self.dbpool.runQuery(query).addCallbacks(self._get_mod_dict, db_client_failed)
457
458 - def _get_mod_dict(self,data):
459 # définition du chemin vers les dictionnaires 460 id_module, version = data[0] 461 if version == 1: 462 # non géré sur creole1 463 return 1, [] 464 try: 465 dest_dir=os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos") 466 content = [] 467 # cas d'un répertoire 468 for dict in os.listdir(dest_dir): 469 if dict.endswith('.xml'): 470 content.append(dict) 471 return 1, u(content) 472 except: 473 return 0,u("""erreur de parcours du répertoire des dictionnaires""")
474
475 - def xmlrpc_del_mod_dict(self,cred_user,id_module,dico_name):
476 """renvoie la liste des dictionnaires d'un module. 477 utile pour les modules eole2 (fichier fixé pour les modules eole1) 478 """ 479 # définition du chemin vers les dictionnaires 480 self.parent.s_pool.check_mod_credential(cred_user, id_module) 481 try: 482 fic_dest = os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos",dico_name) 483 assert os.path.isfile(fic_dest) 484 except: 485 return 0,u("""dictionnaire inexistant %s""" % dico_name) 486 # on supprime le fichier 487 try: 488 os.unlink(fic_dest) 489 return 1, "OK" 490 except: 491 return 0,u("""erreur lors de la suppression du dictionnaire""")
492 493 #################################### 494 ## gestion des variantes des modules 495 #################################### 496
497 - def _got_variantes(self,variantes,cred_user):
498 """formate les données lues dans la table variantes pour 499 l'envoyer à une application zephir (liste de dictionnaires)""" 500 l=[] 501 for variante in variantes: 502 owner = variante[3] 503 if owner == None: 504 owner = "" 505 try: 506 self.parent.s_pool.check_var_credential(cred_user, variante[0]) 507 except ResourceAuthError: 508 # non autorisé : module suivant 509 continue 510 l.append({'id':variante[0],'module':variante[1],'libelle':variante[2],'owner':owner}) 511 return 1,u(l)
512
513 - def xmlrpc_copy_variante(self,cred_user,module,id_variante,libelle,passmd5):
514 """Copie une variante exisante sur une nouvelle variante""" 515 # recherche des données de l'ancienne variante 516 try: 517 id_variante=int(id_variante) 518 module=int(module) 519 assert libelle != "" 520 except: 521 return 0, u("""paramètres invalides""") 522 523 query = """insert into variantes (module,libelle,owner,passmd5) values (%s,'%s','%s','%s')""" % (module,libelle.replace("'","\\\'"),cred_user,passmd5) 524 # id assigné automatiquement dans postgresql 525 # on effectue l'insertion 526 return self.dbpool.runOperation(query).addCallbacks(self._copy_variante, db_client_failed,callbackArgs=[libelle,module,id_variante])
527
528 - def _copy_variante(self,data,libelle,module,id_variante):
529 """recherche de l'id de la variante créée""" 530 # on récupère l'id de la variante créée 531 query = """select * from variantes where libelle = '%s' and module = %s""" % (libelle.replace("'","\\\'"), module) 532 return self.dbpool.runQuery(query).addCallbacks(self._copy_variante2, db_client_failed,callbackArgs=[id_variante])
533
534 - def _copy_variante2(self,data,var_src):
535 """copie l'arborescence de la variante source""" 536 try: 537 var_dest = data[0][0] 538 module = data[0][1] 539 libelle = data[0][2] 540 except: 541 # variante créée non trouvée dans la base 542 return 0,u("""nouvelle variante non retrouvée dans la base""") 543 else: 544 # on recopie l'arborescence de la variante source 545 rep_src=os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(var_src) 546 rep_dest=os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(var_dest) 547 try: 548 shutil.copytree(rep_src,rep_dest) 549 except: 550 return 0,u("""erreur de copie de l'arborescence de la variante""") 551 return 1,var_dest
552 553
554 - def xmlrpc_add_variante(self,cred_user, module, libelle, pass_var=""):
555 """ajoute une variante à un module""" 556 self.parent.s_pool.check_mod_credential(cred_user, module) 557 # on vérifie qu'on a bien récupéré un module 558 if module and libelle: 559 query = """insert into variantes (module,libelle,owner,passmd5) values (%s,'%s','%s','%s')""" % (module,libelle.replace("'","\\\'"),cred_user,pass_var) 560 # id assigné automatiquement dans postgresql 561 # on effectue l'insertion 562 return self.dbpool.runOperation(query).addCallbacks(self._add_variante1, db_client_failed,callbackArgs=[libelle,module]) 563 else: 564 # des attributs manquent 565 return 0, u("""donnez un id de module et un libellé""")
566
567 - def _add_variante1(self,data,libelle,module):
568 """recherche de l'id de la variante créée""" 569 # on récupère l'id de la variante créée 570 query = """select * from variantes where libelle ilike '%s' and module = %s""" % (libelle.replace("'","\\\'"), module) 571 return self.dbpool.runQuery(query).addCallbacks(self._add_variante2,db_client_failed)
572
573 - def _add_variante2(self,variante):
574 """met en place l'arborescence d'une nouvelle variante""" 575 try: 576 id_variante = variante[0][0] 577 module = variante[0][1] 578 libelle = variante[0][2] 579 except: 580 # variante créée non trouvée dans la base 581 return 0,u("""nouvelle variante non retrouvée dans la base""") 582 else: 583 # on créé l'arborescence de la variante dans les modules 584 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)) 585 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'patchs') 586 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dicos') 587 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_perso') 588 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_zephir') 589 return 1,id_variante
590 591
592 - def xmlrpc_del_variante(self,cred_user,id_variante):
593 """suppression d'une variante de la base zephir""" 594 self.parent.s_pool.check_var_credential(cred_user, id_variante) 595 if id_variante: 596 query = """select * from variantes where id = %s""" % id_variante 597 # on récupère les données de la variante 598 return self.dbpool.runQuery(query).addCallbacks(self._del_variante, db_client_failed) 599 else: 600 return 0,u("""donnez un identifiant de variante""")
601
602 - def _del_variante(self,variante):
603 """supprime la variante de la base de données""" 604 try: 605 id_variante = variante[0][0] 606 id_module = variante[0][1] 607 libelle = variante[0][2] 608 except: 609 # variante non trouvée dans la base 610 return 0,u("""variante non trouvée dans la base""") 611 else: 612 # on interdit la supression de la variante standard 613 if libelle == 'standard': 614 return 0, u("""la variante standard ne peut pas être supprimée""") 615 # suppression variante dans la base 616 query = """delete from variantes where id = %s""" % id_variante 617 return self.dbpool.runOperation(query).addCallbacks(self._del_variante2, db_client_failed,callbackArgs=[id_module,id_variante])
618
619 - def _del_variante2(self,result,id_module,id_variante):
620 """supression de l'arborescence de la variante""" 621 # ok, on supprime son arborescence dans zephir/modules/variantes/id_variante 622 variante_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante) 623 try: 624 shutil.rmtree(variante_dir) 625 except: 626 # remonter code -1 si supression de répertoire impossible ? 627 return 0,u("""erreur de supression du répertoire de la variante""") 628 return 1, u('ok')
629
630 - def xmlrpc_fichiers_variante(self,cred_user,id_variante):
631 """ retourne la liste des fichiers personnalisés pour cette variante """ 632 self.parent.s_pool.check_var_credential(cred_user, id_variante) 633 query = """select id,module from variantes where id = %s""" % id_variante 634 return self.dbpool.runQuery(query).addCallbacks(self._fichiers_zephir,db_client_failed)
635
636 - def _fichiers_zephir(self,data):
637 """recherche les fichiers liés à une variante""" 638 if data == []: 639 return 0,u("serveur inconnu de zephir") 640 else: 641 id_variante = int(data[0][0]) 642 id_module = int(data[0][1]) 643 # répertoire de stockage de la variante sur zephir 644 variante_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante) 645 # création du dictionnaire de listes des différents fichiers 646 dico_res={} 647 try: 648 # dictionnaires additionnels 649 liste_dicos = [] 650 liste_dicos_var = [] 651 for fic in os.listdir(variante_dir+os.sep+'dicos'): 652 if fic.endswith('.eol') or fic.endswith('.xml'): 653 liste_dicos_var.append(fic) 654 dico_res['dicos_var'] = liste_dicos_var 655 except OSError: 656 dico_res['dicos_var'] = ['répertoire non trouvé !'] 657 try: 658 # fichiers templates variante 659 dico_res['persos_var'] = (os.listdir(variante_dir+os.sep+'fichiers_perso')) 660 except OSError: 661 dico_res['persos_var'] = ['répertoire non trouvé !'] 662 try: 663 # patchs variante 664 dico_res['patchs_var'] = os.listdir(variante_dir+os.sep+'patchs') 665 except OSError: 666 dico_res['patchs_var'] = ['répertoire non trouvé !'] 667 try: 668 # RPMS variante 669 # lecture de la liste des rpms supplémentaires 670 fic = open(variante_dir+'/fichiers_zephir/fichiers_variante') 671 data = fic.read().split("\n") 672 fic.close() 673 # recherche de la section des RPMS 674 liste_pkg_var = [] 675 section_rpm = 0 676 for ligne in data: 677 ligne = ligne.strip() 678 if section_rpm == 1: 679 # on regarde si on a bien affaire à un paquetage 680 if not ligne.startswith('#') and ligne != '': 681 # on affiche le nom du paquetage 682 liste_pkg_var.append(ligne) 683 if ligne == '%%': 684 section_rpm = 1 685 dico_res['rpms_var'] = liste_pkg_var 686 except IOError: 687 dico_res['rpms_var'] = [] 688 try: 689 # fichiers du module 690 liste_fic=[] 691 try: 692 f=open(variante_dir+os.sep+'fichiers_zephir/fichiers_variante') 693 old_content=f.read() 694 f.close() 695 fichiers=old_content.split('%%\n')[0] 696 except: 697 fichiers="" 698 for f in fichiers.split('\n'): 699 if f.strip().startswith("""/"""): 700 liste_fic.append(f) 701 dico_res['fichiers_var'] = liste_fic 702 # for fic in os.listdir(variante_dir+os.sep+'fichiers_zephir'): 703 # if fic != 'fichiers_variante': 704 # liste_dicos.append(fic) 705 # dico_res['fichiers_var'] = liste_dicos 706 except: 707 dico_res['fichiers_var'] = ['répertoire non trouvé !'] 708 return 1,u(dico_res)
709
710 - def xmlrpc_get_variante_perms(self, cred_user, id_variante, filepath=""):
711 """renvoie les informations de permissions associées à un(des) fichier(s) 712 """ 713 # on recherche le répertoire ou la variante est stockée 714 query = """select id,module from variantes where id=%s""" % id_variante 715 return self.dbpool.runQuery(query).addCallbacks(self._get_variante_perms,db_client_failed,callbackArgs=[filepath])
716
717 - def _get_variante_perms(self, data, filepath):
718 """crée l'archive de la variante et la renvoie""" 719 if data != []: 720 id_variante = data[0][0] 721 id_module = data[0][1] 722 # répertoire de la variante 723 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante) 724 try: 725 id_var = int(id_variante) 726 727 except KeyError, ValueError: 728 return 0, u("""variante inconnue : %s""" % str(id_var)) 729 else: 730 result = self.parent.s_pool.get_file_perms(var_dir, filepath) 731 return 1, u(result)
732
733 - def xmlrpc_del_variante_perms(self, cred_user, id_variante, filepath=""):
734 """supprime les informations de permissions associées à un(des) fichier(s) 735 """ 736 # on recherche le répertoire ou la variante est stockée 737 query = """select id,module from variantes where id=%s""" % id_variante 738 return self.dbpool.runQuery(query).addCallbacks(self._del_variante_perms,db_client_failed,callbackArgs=[filepath])
739
740 - def _del_variante_perms(self, data, filepath):
741 """crée l'archive de la variante et la renvoie""" 742 if data != []: 743 id_variante = data[0][0] 744 id_module = data[0][1] 745 # répertoire de la variante 746 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante) 747 try: 748 id_var = int(id_variante) 749 except KeyError, ValueError: 750 return 0, u("""variante inconnue : %s""" % str(id_var)) 751 else: 752 result = self.parent.s_pool.del_file_perms(var_dir, filepath) 753 return 1, u(result)
754
755 - def xmlrpc_set_variante_perms(self, cred_user, id_variante, rights):
756 """enregistre les informations de permissions associées à un(des) fichier(s) 757 @param rights: dictionnaire au format suviant : {'filepath':[mode,ownership]} 758 """ 759 # on recherche le répertoire ou la variante est stockée 760 query = """select id,module from variantes where id=%s""" % id_variante 761 return self.dbpool.runQuery(query).addCallbacks(self._set_variante_perms,db_client_failed,callbackArgs=[rights])
762
763 - def _set_variante_perms(self, data, rights):
764 """crée l'archive de la variante et la renvoie""" 765 if data != []: 766 id_variante = data[0][0] 767 id_module = data[0][1] 768 # répertoire de la variante 769 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante) 770 try: 771 id_var = int(id_variante) 772 except KeyError, ValueError: 773 return 0, u("""variante inconnue : %s""" % str(id_var)) 774 else: 775 res = self.parent.s_pool.set_file_perms(rights, var_dir) 776 if res: 777 return 1,"OK" 778 else: 779 return 0, u("""erreur d'enregistrement des permissions""")
780
781 - def xmlrpc_get_variante(self,cred_user,id_variante=None):
782 """récupère la liste d'une variante (ou toutes)""" 783 if id_variante : 784 query = """select * from variantes where id = %s """ % id_variante 785 return self.dbpool.runQuery(query).addCallbacks(self._got_variantes,db_client_failed,callbackArgs=[cred_user]) 786 else : 787 query = """select * from variantes""" 788 return self.dbpool.runQuery(query).addCallbacks(self._got_variantes,db_client_failed,callbackArgs=[cred_user])
789
790 - def xmlrpc_edit_variante(self,cred_user,id_variante,dico_modifs):
791 """modification d'une variante 792 cette fonction prend en compte un dictionnaire qui indique les 793 champs à modifier et leur nouvelle valeur. l'application cliente 794 doit s'assurer que ces champs existent dans la base""" 795 self.parent.s_pool.check_var_credential(cred_user, id_variante) 796 # on vérifie que l'identifiant n'est pas modifié 797 if dico_modifs == {}: 798 return 1,u("""aucune modification demandée""") 799 if ('id' in dico_modifs.keys()) or ('module' in dico_modifs.keys()): 800 return 0,u("""l'identifiant et le module ne peuvent pas être modifiés""") 801 if ('owner' in dico_modifs.keys()) or ('passmd5' in dico_modifs.keys()): 802 return 0,u("""modification du propriétaire ou mot de passe interdits""") 803 # construction de la requête SQL de modification 804 requete=["update variantes set "] 805 for cle in dico_modifs.keys(): 806 requete.append(str(cle)) 807 requete.append("='") 808 requete.append(str(dico_modifs[cle]).replace("'","\\\'")) 809 requete.append("', ") 810 string_fin=""" where id='%s'""" % id_variante 811 query="".join(requete)[:-2] 812 query += string_fin 813 return self.dbpool.runOperation(query).addCallbacks(lambda x:(1,'ok'), db_client_failed)
814
815 - def xmlrpc_add_files(self,cred_user,id_variante,dico_files,passwd="",encode=False):
816 """ajoute des fichiers, patchs, dictionnaires à une variante 817 """ 818 self.parent.s_pool.check_var_credential(cred_user, id_variante) 819 query="select modules.version,variantes.id,variantes.module,variantes.owner,variantes.passmd5 from variantes,modules where variantes.id=%s and modules.id=variantes.module" % id_variante 820 return self.dbpool.runQuery(query).addCallbacks(self._add_files,db_client_failed,callbackArgs=[dico_files,cred_user,passwd,encode])
821
822 - def _add_files(self,data,dico_files,cred_user,passwd,encode):
823 """ajoute des fichiers, patchs, dictionnaires,rpms à une variante 824 """ 825 mod_version = data[0][0] 826 id_variante = data[0][1] 827 id_module = data[0][2] 828 owner = data[0][3] 829 pass_var = data[0][4] 830 # si la variante ne nous appartient pas, on interdit la modification si mauvais mot de passe 831 if owner != cred_user: 832 # vérification du mot de passe 833 if passwd != pass_var and pass_var not in [None,'']: 834 # mauvais mot de passe 835 return 0,u('mot de passe incorrect pour cette variante') 836 # on met en place les différents types de fichiers 837 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante) 838 # dans le cas d'un serveur eole1, on encode le contenu des fichiers en iso8859 si nécessaire 839 if int(mod_version) == 1 and encode == True: 840 for type_f, files in dico_files.items(): 841 if type_f in ['dicos_var','patchs_var','persos_var','fichiers_var']: 842 encoded_files = [] 843 for fichier in dico_files[type_f]: 844 content = unicode(base64.decodestring(fichier[1]),config.charset).encode('ISO-8859-1') 845 localpath = "" 846 if len(fichier) == 3: 847 localpath = fichier[2] 848 encoded_files.append([fichier[0], base64.encodestring(content),localpath]) 849 dico_files[type_f] = encoded_files 850 # dictionnaires locaux 851 for dico in dico_files['dicos_var']: 852 try: 853 if dico[0] != "": 854 f=open(dest_dir+os.sep+'dicos'+os.sep+os.path.basename(dico[0].replace("\\","/")),'w') 855 f.write(base64.decodestring(dico[1])) 856 f.close() 857 except: 858 return 0,u("erreur de sauvegarde de %s" % dico) 859 for template in dico_files['persos_var']: 860 try: 861 if template[0] != "": 862 f=open(dest_dir+os.sep+'fichiers_perso'+os.sep+os.path.basename(template[0].replace("\\","/")),'w') 863 f.write(base64.decodestring(template[1])) 864 f.close() 865 except: 866 return 0,u("erreur de sauvegarde de %s" % template) 867 for patch in dico_files['patchs_var']: 868 try: 869 if patch[0] != "": 870 f=open(dest_dir+os.sep+'patchs'+os.sep+os.path.basename(patch[0].replace("\\","/")),'w') 871 f.write(base64.decodestring(patch[1])) 872 f.close() 873 except: 874 return 0,u("erreur de sauvegarde de %s" % patch) 875 # on reprend la liste des fichiers existants 876 try: 877 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante') 878 old_content=f.read() 879 f.close() 880 fichiers=old_content.split('%%\n')[0] 881 rpms=old_content.split('%%\n')[1] 882 except: 883 fichiers="""# section 1 884 # liste des fichiers à sauvegarder+# (ne pas modifier sauf pour créer ou mettre à jour la variante)""" 885 rpms="""# section 2 886 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur 887 # (ils doivent être présents sur le serveur de mise à jour)""" 888 889 for fichier in dico_files['fichiers_var']: 890 # on ajoute le fichier à la liste si il n'est pas déjà présent 891 localpath = "" 892 if len(fichier) == 3: 893 localpath = fichier[2] 894 # on ajoute le fichier à la liste si il n'est pas déjà présent et si il n'est pas dans un sous répertoire 895 nom_fic = fichier[0].replace("\\","/") 896 # on supprime les séparateurs en fin de ligne 897 if fichier[0].endswith('/'): 898 nom_fic = fichier[0][:-1] 899 if fichier[0].endswith("\\"): 900 nom_fic = fichier[0][:-2] 901 if nom_fic not in fichiers.split('\n') and localpath == "": 902 fichiers = fichiers.strip() + '\n' + nom_fic +'\n' 903 # on écrit le contenu du fichier 904 try: 905 if nom_fic != "": 906 if localpath == "": 907 f=open(os.path.join(dest_dir,'fichiers_zephir',os.path.basename(nom_fic)),'w') 908 else: 909 f=open(os.path.join(dest_dir,localpath,os.path.basename(nom_fic)),'w') 910 f.write(base64.decodestring(fichier[1])) 911 f.close() 912 except: 913 return 0,u("erreur de sauvegarde de %s" % fichier) 914 915 # rpms 916 for rpm in dico_files['rpms_var']: 917 # on ajoute le rpm si il n'est pas présent 918 if rpm not in rpms.split('\n'): 919 rpms = rpms.strip() + '\n' + rpm +'\n' 920 921 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante','w') 922 f.write(fichiers+"%%\n"+rpms) 923 f.close() 924 return 1,u("ok")
925
926 - def xmlrpc_del_files(self,cred_user,id_variante,dico_files,passwd=None):
927 """suppression de fichiers, patchs, dictionnaires d'une variante 928 """ 929 self.parent.s_pool.check_var_credential(cred_user, id_variante) 930 query="select id,module,owner,passmd5 from variantes where id=%s" % id_variante 931 return self.dbpool.runQuery(query).addCallbacks(self._del_files,db_client_failed,callbackArgs=[dico_files,cred_user,passwd])
932
933 - def _del_files(self,data,dico_files,cred_user,passwd):
934 """supression de fichiers, patchs, dictionnaires,rpms d'une variante 935 """ 936 id_variante = data[0][0] 937 id_module = data[0][1] 938 owner = data[0][2] 939 pass_var = data[0][3] 940 # si la variante ne nous appartient pas, on interdit la modification si mauvais mot de passe 941 if owner != cred_user: 942 # vérification du mot de passe 943 if passwd != pass_var and pass_var not in [None,'']: 944 # mauvais mot de passe 945 return 0,u('mot de passe incorrect pour cette variante') 946 # on met en place les différents types de fichiers 947 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante) 948 # dictionnaires locaux 949 for dico in dico_files['dicos_var']: 950 try: 951 if dico != "": 952 os.unlink(dest_dir+os.sep+'dicos'+os.sep+dico) 953 except: 954 return 0,u("erreur de suppression de %s" % dico) 955 for template in dico_files['persos_var']: 956 try: 957 if template != "": 958 os.unlink(dest_dir+os.sep+'fichiers_perso'+os.sep+template) 959 except: 960 return 0,u("erreur de supression de %s" % template) 961 # on supprime les droits associés si nécessaire 962 self.parent.s_pool.del_file_perms(dest_dir,'fichiers_perso'+os.sep+template) 963 964 for patch in dico_files['patchs_var']: 965 try: 966 if patch != "": 967 os.unlink(dest_dir+os.sep+'patchs'+os.sep+patch) 968 except: 969 return 0,u("erreur de suppression de %s" % patch) 970 # on reprend la liste des fichiers existants 971 try: 972 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante') 973 old_content=f.read() 974 f.close() 975 fichiers=old_content.split('%%\n')[0] 976 rpms=old_content.split('%%\n')[1] 977 except: 978 fichiers="""# section 1 979 # liste des fichiers à sauvegarder pour la variante 980 # (ne pas modifier sauf pour créer ou mettre à jour la variante)""" 981 rpms="""# section 2 982 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur 983 # (ils doivent être présents sur le serveur de mise à jour)""" 984 985 for fichier in dico_files['fichiers_var']: 986 # on supprime le fichier de la liste 987 liste=fichiers.split('\n') 988 if fichier in liste: 989 liste.remove(fichier) 990 fichiers = "\n".join(liste) 991 fic_path = os.path.join(dest_dir,'fichiers_zephir',os.path.basename(fichier.replace("\\","/"))) 992 else: 993 fic_path = os.path.join(dest_dir,fichier) 994 # on efface le fichier 995 try: 996 if fichier != "": 997 if os.path.isdir(fic_path): 998 shutil.rmtree(fic_path) 999 else: 1000 os.unlink(fic_path) 1001 except: 1002 return 0,u("erreur de suppression de %s" % fichier) 1003 if fichier.startswith('/'): 1004 fic_sup = 'fichiers_zephir/'+os.path.basename(fichier.replace("\\","/")) 1005 else: 1006 fic_sup = fichier 1007 self.parent.s_pool.del_file_perms(dest_dir,fic_sup,True) 1008 1009 # rpms 1010 for rpm in dico_files['rpms_var']: 1011 # on supprime le rpm si il existe 1012 liste=rpms.split('\n') 1013 if rpm in liste: 1014 liste.remove(rpm) 1015 rpms = "\n".join(liste) 1016 else: 1017 return 0,u("rpm non trouvé dans la liste : %s" % rpm) 1018 1019 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante','w') 1020 f.write(fichiers+"%%\n"+rpms) 1021 f.close() 1022 return 1,u("ok")
1023
1024 - def xmlrpc_get_var_file(self,cred_user,id_var,id_module,path):
1025 """renvoie le contenu d'un fichier de variante""" 1026 # définition du chemin de la variante 1027 self.parent.s_pool.check_var_credential(cred_user, id_var) 1028 query="select variantes.id,variantes.module,modules.version from variantes,modules where variantes.id=%s and modules.id=variantes.module" % id_var 1029 return self.dbpool.runQuery(query).addCallbacks(self._get_var_file,db_client_failed,callbackArgs=[path])
1030
1031 - def _get_var_file(self,data,path):
1032 id_var = data[0][0] 1033 id_module = data[0][1] 1034 mod_version = data[0][2] 1035 try: 1036 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_var) 1037 except: 1038 return 0,u("""lecture du fichier: paramètres non valides""") 1039 # on lit le fichier 1040 try: 1041 # cas d'un répertoire 1042 if os.path.isdir(dest_dir + os.sep + path): 1043 content = os.listdir(dest_dir + os.sep + path) 1044 return 1, u(content) 1045 else: 1046 if istextfile(dest_dir + os.sep + path): 1047 f=file(dest_dir + os.sep + path) 1048 content=f.read() 1049 f.close() 1050 # on encode le contenu en base64 1051 if int(mod_version) == 1: 1052 try: 1053 content = unicode(content,'ISO-8859-1').encode(config.charset) 1054 except: 1055 # le fichier n'est pas en unicode ?? 1056 print "echec d'encoding du fichier %s provenant d'un serveur eole1" % path 1057 content = base64.encodestring(content) 1058 else: 1059 content = "BINARY" 1060 return 1, content 1061 except: 1062 return 0,u("""erreur de lecture du fichier""")
1063
1064 - def xmlrpc_export_variante(self,cred_user,id_variante):
1065 """envoie le contenu d'une variante sur un autre zephir""" 1066 # on recherche le répertoire ou la variante est stockée 1067 query = """select id,module from variantes where id=%s""" % id_variante 1068 return self.dbpool.runQuery(query).addCallbacks(self._export_variante,db_client_failed)
1069
1070 - def _export_variante(self,data):
1071 """crée l'archive de la variante et le renvoie""" 1072 if data != []: 1073 id_variante = data[0][0] 1074 id_module = data[0][1] 1075 # répertoire de la variante 1076 parent_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes" 1077 var_dir=parent_dir+os.sep+str(id_variante) 1078 # on crée une archive de ce répertoire 1079 archive=str(time.time()) 1080 if os.path.isdir(var_dir): 1081 # création du fichier tar à envoyer 1082 cmd_tar = ['cd ',var_dir,';','tar','-chzf','/tmp/'+archive+'.tgz','*'] 1083 cmd_tar.append('2>&1 >/dev/null') 1084 # exécution de tar 1085 res=os.system(" ".join(cmd_tar)) 1086 if res != 0: 1087 return 0, u("""erreur de création de l'archive %s.tgz dans /tmp""" % (archive)) 1088 else: 1089 # calcul et stockage d'un checksum md5 de l'archive 1090 cmd_checksum = """cd /tmp/; md5sum -b %s.tgz > %s.md5""" % (archive,archive) 1091 res=os.system(cmd_checksum) 1092 # on stocke en mémoire les données 1093 try: 1094 # le checksum 1095 f = open('/tmp'+os.sep+archive+'.md5') 1096 data1 = f.read() 1097 f.close() 1098 os.unlink('/tmp'+os.sep+archive+'.md5') 1099 # l'archive 1100 f = open('/tmp'+os.sep+archive+'.tgz') 1101 data2 = f.read() 1102 f.close() 1103 os.unlink('/tmp'+os.sep+archive+'.tgz') 1104 return 1,u([archive,base64.encodestring(data1),base64.encodestring(data2)]) 1105 except Exception, e: 1106 return 0,u("""erreur lors de l'envoi de l'archive : %s""" % str(e)) 1107 else: 1108 return 0, u("""répertoire %s introuvable""" % var_dir) 1109 else: 1110 return 0, u("""variante inexistante""")
1111
1112 - def xmlrpc_import_variante(self,cred_user,pwd_var,id_local,id_distant,zephir_distant,login_distant,pwd_distant):
1113 """récupère le contenu d'une variante sur un autre zephir""" 1114 # création d'un proxy vers le serveur zephir distant 1115 z=xmlrpclib.ServerProxy("https://%s:%s@%s:%s" % (login_distant,pwd_distant,zephir_distant,config.PORT_ZEPHIR)) 1116 # on vérifie l'existence des variantes des 2 cotés 1117 try: 1118 res=z.modules.get_variante(id_distant) 1119 except: 1120 return 0,u("""permissions insuffisantes""") 1121 if res[0] == 0: 1122 return 0,u("""erreur lors de la recherche de la variante d'origine""") 1123 1124 # on recherche le module de la variante locale 1125 query = """select id, module, owner, passmd5 from variantes where id=%s""" % id_local 1126 return self.dbpool.runQuery(query).addCallbacks(self._import_variante,db_client_failed,callbackArgs=[z,id_distant,cred_user,pwd_var])
1127
1128 - def _import_variante(self,data,proxy,id_distant,cred_user,pwd_var):
1129 """demande l'envoi de l'archive et met en place les fichiers""" 1130 if data == []: 1131 return 0, u("""variante locale non trouvée""") 1132 else: 1133 id_variante = data[0][0] 1134 id_module = data[0][1] 1135 owner = data[0][2] 1136 passmd5 = data[0][3] 1137 # on vérifie le mot de passe de la variante 1138 if owner != cred_user and pwd_var != passmd5: 1139 return 0,u("""mauvais mot de passe de variante""") 1140 else: 1141 # définition du chemin de destination 1142 parent_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes" 1143 var_dir = parent_dir+os.sep+str(id_variante) 1144 # on regarde si des fichiers existent déjà 1145 if not os.path.exists(var_dir): 1146 return 0,u("""répertoire de la variante de destination non trouvé""") 1147 # onrécupère les données de la variante source 1148 res=proxy.modules.export_variante(id_distant) 1149 if res[0]==0: 1150 return 0,u("""erreur lors de la récupération de la variante""") 1151 else: 1152 # nom de l'archive 1153 archive=res[1][0] 1154 # somme md5 1155 var_data=base64.decodestring(res[1][1]) 1156 # contenu de l'archive 1157 md5_data=base64.decodestring(res[1][2]) 1158 try: 1159 # on supprime l'ancien répertoire de la variante 1160 shutil.rmtree(var_dir) 1161 # on recrée un répertoire vide 1162 os.makedirs(var_dir) 1163 # on recrée l'archive et le fichier md5 1164 f=open(var_dir+os.sep+archive+'.tgz','w') 1165 f.write(md5_data) 1166 f.close() 1167 f=open(var_dir+os.sep+archive+'.md5','w') 1168 f.write(var_data) 1169 f.close() 1170 # on vérifie la somme md5 1171 cmd_md5 = """cd %s; md5sum -c %s.md5 2>&1 > /dev/null""" % (var_dir,archive) 1172 res=os.system(cmd_md5) 1173 if res != 0: 1174 return 0,u("""archive corrompue""") 1175 # on décompresse l'archive 1176 cmd_tar = """cd %s ; tar -xzf %s.tgz > /dev/null""" % (var_dir,archive) 1177 res=os.system(cmd_tar) 1178 if res != 0: 1179 return 0,u("""erreur de décompression de l'archive""") 1180 # on supprime les fichiers temporaires 1181 os.unlink(var_dir+os.sep+archive+'.tgz') 1182 os.unlink(var_dir+os.sep+archive+'.md5') 1183 except Exception, e: 1184 return 0,u("""erreur de mise en place des fichiers de la variante : %s""" % str(e)) 1185 # l'import s'est terminé correctement 1186 return 1,u("ok")
1187