1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import os, traceback
16
17 import dico, base64, cjson
18 from copy import copy
19 from creole3 import upgrade
20 from creole.error import TypeEoleError
21 from zephir.config import charset
22 from creole import eosfunc, cfgparser
23 from glob import glob
24
25
26 from creole3.var_loader import CreoleVarLoader
27 from creole3.loader import config_save_values, config_load_values, \
28 config_get_values, config_load_store, modes_level
29 from tiramisu.value import Multi
30 from tiramisu.option import ChoiceOption, OptionDescription, BoolOption, IntOption
31 from tiramisu.error import PropertiesOptionError
32 from tiramisu.setting import owners
33 from tiramisu.config import Config
34 type_option_convert = {BoolOption: bool, IntOption: int}
35
36
37 eosfunc.containers_file = '/usr/share/zephir/dictionnaires/fake_containers.conf'
38 cfgparser.config.containers_file = '/usr/share/zephir/dictionnaires/fake_containers.conf'
39 EDict = cfgparser.EoleDict
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
61 """regarde si une famille/variable creole 3 est cachée
62 """
63 hidden_properties = set(['hidden', 'disabled'])
64 if hidden_properties.intersection(properties):
65 return True
66 return False
67
69 """sert de wrapper par dessus les dictionnaires creole1 et creole2
70 """
71
72 - def __init__(self, dicos=[], confdir='', mode='config', version='creole2'):
73 """initialise un objet dictionnaire avec la bonne api
74 """
75 self.version = version
76 self.separators = {}
77 self.multivars = []
78 self.autovars = []
79 self.confdir = confdir
80 self.mode = mode
81 self.index = 0
82
83 if self.version == "creole2":
84 self.dico = EDict(logfile='/dev/null')
85 elif self.version == "creole3":
86 self.creoledirs = []
87 elif self.version == "creole1":
88 self.dico_zephir = None
89 self.dico = None
90 self.dicos = []
91
92 if self.version != 'creole1':
93
94 for creoledir in dicos:
95 if os.path.isdir(creoledir):
96 list_dic = glob(creoledir + '/*.xml')
97 list_dic.sort()
98 self.dicos.extend(list_dic)
99 if self.version == 'creole2':
100 self.dico.read_dir(creoledir)
101 if self.version == 'creole2':
102 self._update_vars()
103 self.load_values(mode, dicos)
104
106 """calcule le nom du fichier de configuration a utiliser en fonction du mode
107 write : si True, indique qu'on cherche à sauvegarder le fichier
108 si False, recherche le fichier à lire pour récupérer les valeurs déjà connues
109 """
110 config_file = ""
111 if self.confdir != '':
112
113
114
115 serv_file = os.path.join(self.confdir, 'zephir.eol')
116 mod_file = os.path.join(self.confdir, 'module.eol')
117 var_file = os.path.join(self.confdir, 'dico.eol')
118 migration_file = os.path.join(self.confdir, 'migration.eol')
119 if mode == 'modif_config' and os.path.isfile(serv_file):
120 config_file = serv_file
121 elif mode in ['config','modif_config','modif_dico']:
122 if os.path.isfile(var_file):
123 config_file = var_file
124 elif os.path.isfile(mod_file):
125 config_file = mod_file
126 elif mode in ['migration', 'modif_migration'] and os.path.isfile(migration_file):
127 config_file = migration_file
128 return config_file
129
131 """spécifique creole3 : initialise le propriétaire d'une valeur
132 """
133 if self.dico is not None:
134 if owner not in dir(owners):
135 owners.addowner(owner)
136 self.dico.cfgimpl_get_settings().setowner(getattr(owners, owner))
137
139
140 self.dico = CreoleVarLoader()
141 if from_zephir:
142 self.creoledirs = []
143 dicos = [base64.decodestring(dico_zeph) for dico_zeph in dicos[:-1]]
144
145 self.dico.read_string(dicos, 'creole')
146 self.groups = self.dico.groups
147 elif dicos:
148 self.creoledirs = dicos
149 self.dico.read_dir(dicos, 'creole')
150
151 self.separators = {}
152 for sep, data in self.dico.separators.items():
153 self.separators[sep] = (data[0], data[1] is not None)
154
155 self.groups = self.dico.groups
156
157
158 self.dico = self.dico.get_config()
159 self.dico.read_write()
160
161
162 self.dico.cfgimpl_get_settings().remove('hidden')
163
165 """fonction de migration d'une configuration creole2 vers creole3
166 pour creole3, le fonctionnement est le suivant
167 - stockage des valeurs par défaut de module/variante de la version cible dans un dictionnaire python
168 - chargement de l'ancien fichier de configuration avec le loader creole (appel auto des fonctions de migration)
169 et récupération des valeurs dans un dictionnaire
170 - fusion des valeurs par défaut et des valeurs migrées
171 - rechargement de la configuration avec ces valeurs
172 """
173
174 current_eol = os.path.join(self.confdir, 'zephir.eol')
175 migration_eol = os.path.join(self.confdir, 'migration.eol')
176
177 def_values = {}
178 for path_conf in dicos:
179 for conf_file in ('module.eol','dico.eol'):
180 fic_defaults = os.path.join(os.path.dirname(path_conf),conf_file)
181 if os.path.isfile(fic_defaults):
182 try:
183 new_vals = cjson.decode(open(fic_defaults).read().strip(), all_unicode = True)
184 def_values.update(new_vals)
185 except:
186 pass
187
188 serv_prefix = '-'.join(self.confdir.split(os.path.sep)[-2:])
189
190 upgrade.log.name = "creole3.upgrade.{0}".format(serv_prefix)
191 migration_values, version = upgrade.upgrade(self.dico, unicode(current_eol, charset))
192 def_values.update(migration_values)
193
194 settings = self.dico.cfgimpl_get_settings()
195 settings.remove('disabled')
196 settings.remove('frozen')
197 config_load_store(self.dico, 'creole', def_values, unset_default=True)
198 self.dico.impl_set_information('upgrade', version)
199
200 settings.append('frozen')
201 settings.append('disabled')
202
204 if dicos:
205 self.load_dicos_creole3(dicos)
206
207 elif self.creoledirs:
208
209
210 cfg_descr = self.dico.cfgimpl_get_description()
211 self.dico = Config(cfg_descr)
212 self.dico.impl_set_information('creole', unicode(config_file, charset))
213 self.dico.read_write()
214 self.dico.cfgimpl_get_settings().remove('hidden')
215
216 if mode == 'migration':
217 self.migrate_creole3(dicos)
218 elif config_file:
219 store_values = {}
220 config_files = [config_file]
221
222
223 if os.path.basename(config_file) == 'dico.eol':
224 config_files.insert(0, os.path.join(os.path.dirname(config_file), 'module.eol'))
225 for conf_file in config_files:
226 if os.path.isfile(conf_file):
227 try:
228 store_values.update(cjson.decode(open(conf_file).read().strip(), all_unicode = True))
229 except:
230 pass
231
232 settings = self.dico.cfgimpl_get_settings()
233 settings.remove('frozen')
234 settings.remove('disabled')
235
236 config_load_store(self.dico, 'creole', store_values)
237 settings.append('disabled')
238 settings.append('frozen')
239 if hasattr(self, 'dico'):
240 self._update_vars()
241
243
244 self.dico.reset_defaults()
245 if config_file != "" and mode != 'migration':
246 self.dico.load_values(config_file, check=False)
247 elif mode in ['migration', 'modif_migration']:
248
249 for path_conf in dicos:
250 for conf_file in ('module.eol','dico.eol'):
251 if os.path.isfile(os.path.join(os.path.dirname(path_conf),conf_file)):
252 self.dico.load_values(os.path.join(os.path.dirname(path_conf),conf_file), check=False)
253
254 if os.path.isfile(self.confdir+os.sep+'zephir.eol'):
255
256 first_line = open(self.confdir+os.sep+'zephir.eol').read().strip().split('\n')[0]
257 if not (first_line.startswith('[') and first_line.endswith(']')):
258
259 res = self.dico.import_values_creole1(self.confdir+os.sep+'zephir.eol')
260 else:
261
262 res = self.dico.import_values(self.confdir+os.sep+'zephir.eol')
263 elif os.path.isfile(self.confdir+os.sep+'module.eol'):
264
265 self.dico.load_values(self.confdir+os.sep+'module.eol', check=False)
266
268 if dicos == [] and self.dico_zephir:
269 dicos = self.dico_zephir
270
271
272 self.dico = dico.DicoEole(dico_zephir=dicos)
273
274 self.dico_zephir = dicos
275
276 dico_actuel = None
277 if config_file != "":
278 fic = open(config_file)
279 data = fic.readlines()
280 lines = [ unicode(line,'ISO-8859-1').encode(charset) for line in data ]
281 fic.close()
282
283 dico_actuel = dico.DicoEole(dico_zephir=[lines]).ParseDico()
284
285 if dico_actuel is not None:
286
287 dico_final = {}
288
289 for variable, data in self.dico.dictionnaire.items():
290
291 if dico_actuel.has_key(data[0]):
292 data[1] = dico_actuel[data[0]][0]
293 dico_final[variable] = data
294
295 self.dico.dictionnaire = dico_final
296 self.liste_vars = self.dico.liste_vars
297
298 - def load_values(self, mode, dicos=[], config_file=None):
299
300 if config_file is None:
301 config_file = self.get_config_file(mode)
302 if self.version == 'creole3':
303 self._load_values_creole3(mode, dicos, config_file)
304 elif self.version != 'creole1':
305 self._load_values_creole2(mode, dicos, config_file)
306 else:
307 self._load_values_creole1(mode, dicos, config_file)
308 self.mode = mode
309
310 - def get_help(self, name, family=False):
311 """Récupère l'aide de la variable
312 - définie dans une balise help pour creole2 (chaine vide si non défini)
313 - pour creole 1, on renvoie une chaine vide
314 """
315 if self.version == 'creole3':
316 try:
317 if family:
318 opt = self.dico.unwrap_from_path('creole.' + name)
319 else:
320 opt = self.dico.vars[self.dico.liste_vars[name]]
321 except:
322 opt = None
323 if opt: return opt.impl_getdoc()
324 elif self.version == 'creole2':
325 if family:
326 section = 'families'
327 else:
328 section = 'variables'
329 if name in self.dico.helps.get(section, {}):
330 return self.dico.helps[section][name]
331 return ""
332
334 """charge les dictionnaire depuis une liste de chaines xml
335 @param dicos: contenu des dictionnaires à implémenter + valeurs actuelles en fin de liste
336 """
337
338 self.mode = None
339 if self.version != 'creole1':
340 if self.dicos == []:
341
342 if self.version == 'creole3':
343 self.load_dicos_creole3(dicos, True)
344 else:
345 self.dico = EDict(logfile='/dev/null')
346 self.dicos = [base64.decodestring(dico_zeph) for dico_zeph in dicos[:-1]]
347
348 for xml_dict in self.dicos:
349 self.dico.read_string(xml_dict)
350
351 if self.version == "creole3":
352 values = eval(dicos[-1])
353 settings = self.dico.cfgimpl_get_settings()
354
355 settings.remove('frozen')
356 settings.remove('disabled')
357 config_load_store(self.dico, 'creole', values)
358 self.dico.impl_set_information('orig_values', values)
359 settings.append('frozen')
360 settings.append('disabled')
361 else:
362
363 val_dict = eval(dicos[-1])
364 self.dico.store._sections = val_dict
365 self.dico._load_values()
366 if len(dicos) > 1:
367
368
369 self._update_vars()
370 else:
371 dicos = base64.decodestring(dicos)
372 dicos = [dicos.splitlines(True)]
373 self.dico = dico.DicoEole(dico_zephir=dicos)
374 self.liste_vars = self.dico.liste_vars
375
377 """regénère les structures après chargement des dictionnaires
378 """
379 if self.version != 'creole1':
380
381 self.index = 0
382 self.vars = []
383
384 self.liste_vars = {}
385 ind = 0
386 if self.version == 'creole3':
387
388 self.var_paths = {}
389
390 self.families = []
391 self.expert_families = []
392
393
394 descr_cache = self.dico.cfgimpl_get_description()._cache_paths
395 for cache_index, descr in enumerate(descr_cache[0]):
396 if isinstance(descr, OptionDescription):
397 if getattr(descr, '_group_type', '') == 'family':
398 current_mode = 'normal'
399
400 if 'expert' in descr._properties:
401 self.expert_families.append(descr)
402 current_mode = 'expert'
403 else:
404 self.families.append(descr)
405 else:
406 current_path = descr_cache[1][cache_index]
407 self.vars.append(descr)
408 self.liste_vars[descr._name] = ind
409 self.var_paths[descr._name] = (current_path, current_mode)
410 ind += 1
411 else:
412
413 for family in self.dico.family_order:
414 for var in self.dico.families[family]['vars']:
415 self.vars.append(var)
416 self.liste_vars[var] = ind
417 ind += 1
418 if self.dico.variables[var].multi == True:
419 self.multivars.append(var)
420 self.multivars.extend(self.dico.groups.get(var,[]))
421 if self.dico.variables[var].auto != []:
422 self.autovars.append(var)
423
424 self.separators = self.dico.separators
425
427 if self.version == 'creole3':
428
429 try:
430 val = getattr(self.dico, self.var_paths[var][0]) or ''
431 except PropertiesOptionError, e:
432 val = ''
433 if not val:
434
435
436 val = ['']
437 elif type(val) == Multi:
438 val = list(val)
439 elif type(val) not in (unicode, str):
440 val = [str(val)]
441 else:
442 val = [val]
443 else:
444 val = self.dico.get_value(var)
445 return val
446
448 vals = []
449 allow_other = False
450 if self.version == 'creole3':
451 try:
452 option = self.vars[self.liste_vars[var]]
453 except AttributeError, e:
454 option = None
455 if option and isinstance(option, ChoiceOption):
456 vals = list(option.impl_get_values())
457 allow_other = option.impl_is_openvalues()
458 elif self.version != 'creole1':
459 eolvar = self.dico.get_variable(var)
460 checks = eolvar.checks
461 for check in checks:
462 if check[0] == u'valid_enum':
463
464 for param in check[1]:
465 if param['name'] == 'checkval':
466 if param['value'] == "False":
467 allow_other = True
468 else:
469 vals.extend(eval(param['value']))
470 else:
471 conditions = self.dico.dictionnaire[self.dico.liste_vars[var]][3]
472
473 for cond in conditions:
474 if cond.startswith('enumeration'):
475 try:
476 vals = eval(cond.split('??')[1])
477 except:
478
479 vals = ['oui','non']
480 break
481 return vals, allow_other
482
484 """retourne les paramètres de la variable nom,valeur,libelle,variable cachée
485 """
486 if self.version == 'creole1':
487 self.dico.get_first()
488 else:
489 self.index = 0
490 try:
491 return self._get_var_details()
492 except PropertiesOptionError, e:
493
494
495 return self.get_next()
496
498 if self.version == 'creole1':
499 self.dico.get_next()
500 else:
501 prev_index = self.index
502 self.index = self.index + 1
503 try:
504 return self._get_var_details()
505 except PropertiesOptionError, e:
506
507 return self.get_next()
508 except (KeyError, IndexError), e:
509 self.index = prev_index
510 raise dico.PositionError, 'fin de la liste des variables'
511
513 """retourne les paramètres d'une variable
514 """
515 try:
516 return self._get_var_details(varname)
517 except PropertiesOptionError, e:
518
519 return ['']
520
522 """adapte la représentation des variables
523 """
524
525 if self.version == 'creole3':
526
527
528
529 if varname != None:
530 self.index = self.liste_vars[varname]
531 opt = self.vars[self.index]
532
533 if 'expert' in opt._properties:
534 mode = 'expert'
535 else:
536
537 mode = 'normal'
538 hidden = check_hidden(opt._properties)
539 obligatoire = 'mandatory' in opt._properties
540 mime = opt._opt_type
541 val = getattr(self.dico, self.var_paths[opt._name][0])
542 if not val:
543 if isinstance(val, Multi):
544 val = ['']
545 else:
546 val = ''
547 data = opt._name, val, opt.impl_getdoc(), hidden, obligatoire, mime, mode
548 elif self.version == 'creole2':
549 if varname != None:
550 var = self.dico.get_variable(varname)
551 self.index = self.vars.index(varname)
552 else:
553 var = self.dico.get_variable(self.vars[self.index])
554 obligatoire = False
555 if 'obligatoire' in [ check[0] for check in var.checks ]:
556 obligatoire = True
557 mime = var.mime
558 mode = var.mode
559 val = var.get_value()
560 if type(val) != list:
561 val = [val]
562 if val == []:
563 val = ['']
564 data = var.name, val, var.description, var.hidden, obligatoire, mime, mode
565 elif self.version == 'creole1':
566 if varname != None:
567 name, val, description, hidden = self.dico.get_var(varname)
568 else:
569 name, val, description, hidden = self.dico.get_current()
570 checks = self.dico.dictionnaire[self.dico.liste_vars[name]][3]
571 if 'obligatoire' in checks:
572 obligatoire = True
573 liste_funcs = copy(checks)
574 liste_funcs.remove('obligatoire')
575
576 else:
577 obligatoire = False
578 liste_funcs = checks
579
580 mode = 'normal'
581 data = name, [val], description, hidden, obligatoire, liste_funcs, mode
582 return data
583
585 """ renvoit la valeur précédente """
586 if self.version != 'creole1':
587 try:
588 value = self.dico.get_prec_value(varname)
589 except:
590 value = ''
591 else:
592 try:
593 value = self.dico.get_var(varname)[1]
594 except:
595 value = ''
596 return value
597
599 """ renvoit la valeur par défaut """
600 try:
601 if self.version == 'creole3':
602 value = self.vars[self.liste_vars[varname]].impl_getdefault()
603 else:
604 value = self.dico.get_var(varname)[1]
605 except:
606 value = ''
607 return value
608
609 - def set_value(self, value, invisible=False, force=False):
610 if self.version == 'creole3':
611 def convert_value(option, value):
612 _type = type(option)
613 if _type in type_option_convert:
614 if option.impl_is_multi():
615 vals = []
616 for val in value:
617 if val is None:
618 vals.append(val)
619 else:
620 vals.append(type_option_convert[_type](val))
621 return vals
622 else:
623 if value is not None:
624 return type_option_convert[_type](value)
625 else:
626
627 if option.impl_is_multi():
628 vals = []
629 for val in value:
630 if type(val) == str:
631 vals.append(unicode(val, charset))
632 else:
633 vals.append(val)
634 return vals
635 else:
636 if type(value) == str:
637 return unicode(value, charset)
638 return value
639 try:
640 option = self.vars[self.index]
641 varname = option._name
642
643 value = convert_value(option, value)
644 self.dico.cfgimpl_get_settings().setpermissive(tuple(modes_level), opt=option)
645 setattr(self.dico, self.var_paths[varname][0], value)
646
647 self._update_vars()
648 except Exception, e:
649 raise dico.InvalidDataError, e.args[0]
650 elif self.version != 'creole1':
651 try:
652 self.dico.set_value(self.vars[self.index], value, force=force)
653 except Exception, e:
654 raise dico.InvalidDataError, e.args[0]
655 else:
656 if type(value) == list:
657 value = value[0]
658 self.dico.set_value(value, invisible, force=force)
659
660 - def save(self, eol_file='/dev/null', force=False, encode=False):
661 if self.version == 'creole3':
662
663 check_mandatory=not force
664 if eol_file and eol_file != '/dev/null':
665
666 config_save_values(self.dico, 'creole', eol_file=eol_file, check_mandatory=check_mandatory)
667 data = [str(config_get_values(self.dico, 'creole', check_mandatory))]
668 elif self.version != 'creole1':
669
670 self.dico.save_values(eol_file,force=force)
671
672 data = [str(self.dico.store._sections)]
673 else:
674 data = self.dico.save(eol_file, encode=encode)
675 return data
676
678
679 data = []
680 if self.version != 'creole1':
681 for dic in self.dicos:
682 f = open(dic)
683 content = f.read()
684 f.close()
685 data.append(base64.encodestring(content))
686 if self.version == 'creole3':
687 val_store = config_get_values(self.dico, 'creole', check_mandatory=False, ignore_autofreeze=True)
688 data.append(str(val_store))
689 else:
690
691
692 for varname in self.dico.variables.keys():
693 var = self.dico.variables[varname]
694 if var.val == [] or var.val == ['']:
695
696
697 var.val = var.get_value(default=True)
698
699 for list_val in [var.val, var.valprec, var.valdefault]:
700 for ind in range(len(list_val)):
701 if type(list_val[ind]) == unicode:
702 list_val[ind] = list_val[ind].encode(charset)
703
704 if not self.dico.store.has_section(varname):
705 self.dico.store.add_section(varname)
706 self.dico.store.set(varname, 'val', var.val)
707 self.dico.store.set(varname, 'valprec', var.valprec)
708 self.dico.store.set(varname, 'valdefault', var.valdefault)
709 data.append(str(self.dico.store._sections))
710 return data
711 else:
712 return [base64.encodestring(self.save())]
713
715 """retourne les familles et les variables dans l'ordre de saisie
716 @param expert: mode de saisie (non expert par défaut)
717 @return: renvoie une liste ordonnée de familles [famille, liste_vars]
718 """
719 families = []
720 expert_families = []
721 menu = []
722 if self.version != 'creole1':
723 if self.version == 'creole3':
724 for family in self.families:
725 childs = family._children[0]
726 hidden = check_hidden(self.dico.unwrap_from_path('creole.%s' % family._name)._properties)
727 families.append([family._name.encode(charset), hidden, childs])
728 if expert:
729 for family in self.expert_families:
730 childs = family._children[0]
731 hidden = check_hidden(self.dico.unwrap_from_path('creole.%s' % family._name)._properties)
732 expert_families.append([family._name.encode(charset), hidden, childs])
733 else:
734
735 for family in self.dico.family_order:
736 data = self.dico.families[family]
737 if not data['mode'] == 'expert':
738
739 families.append([family.encode(charset), data['hidden'], data['vars']])
740
741 elif expert == True:
742 expert_families.append([family.encode(charset), data['hidden'], data['vars']])
743 menu = families + expert_families
744 else:
745
746 middle = len(self.dico.dictionnaire)/2
747 end = len(self.dico.dictionnaire)-middle
748 vars1 = [self.dico.dictionnaire[numvar][0] for numvar in range(middle)]
749 vars2 = [self.dico.dictionnaire[middle + numvar][0] for numvar in range(end)]
750 menu.append(['general', False, vars1])
751 menu.append(['general_1', False, vars2])
752 return menu
753
755
756 data = {}
757 if self.version == 'creole3':
758
759 data_dict = self.dico.make_dict(flatten=True)
760
761 for varname, vals in data_dict.items():
762 if not vals:
763
764 vals = ''
765 elif isinstance(vals, Multi):
766 str_vals = []
767 for val in vals:
768 if type(val) == unicode:
769 str_vals.append(val.encode(charset))
770 else:
771 str_vals.append(str(val))
772 vals = separator.join(str_vals)
773 elif type(vals) == unicode:
774 vals = vals.encode(charset)
775 else:
776 vals = str(vals)
777 data[varname] = vals
778 elif self.version != 'creole1':
779 for varname in self.dico.variables.keys():
780 data[varname] = separator.join(self.dico.get_value(varname))
781 else:
782 for varname, values in self.dico.ParseDico().items():
783 data[varname] = values[0]
784 return data
785