You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1157 lines
47 KiB

  1. #-*- coding: utf-8 -*-
  2. # Copyright 2008-2010 Mir Calculate. http://www.calculate-linux.org
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import gettext
  16. import os
  17. import getopt
  18. import sys
  19. ##############################################################################
  20. import re
  21. import copy
  22. import types
  23. import string
  24. #import os
  25. import filecmp
  26. import ConfigParser
  27. import time
  28. import socket
  29. #import sys
  30. import random
  31. import string
  32. import cl_utils
  33. ##############################################################################
  34. _expand_lang = gettext._expand_lang
  35. def exit(codeExit):
  36. """Метод выхода из программы"""
  37. sys.exit(codeExit)
  38. def __findFileMO(domain, localedir=None, languages=None, all=0):
  39. # Модифицинрованный метод модуля gettext ищет файл перевода
  40. if localedir is None:
  41. localedir = _default_localedir
  42. if languages is None:
  43. languages = []
  44. for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
  45. val = os.environ.get(envar)
  46. if val:
  47. languages = val.split(':')
  48. break
  49. if 'C' not in languages:
  50. languages.append('C')
  51. # now normalize and expand the languages
  52. nelangs = []
  53. for lang in languages:
  54. for nelang in _expand_lang(lang):
  55. if nelang not in nelangs:
  56. nelangs.append(nelang)
  57. # select a language
  58. if all:
  59. result = []
  60. else:
  61. result = None
  62. for lang in nelangs:
  63. if lang == 'C':
  64. break
  65. mofile = os.path.join(localedir, '%s_%s.mo' % (domain,lang))
  66. if os.path.exists(mofile):
  67. if all:
  68. result.append(mofile)
  69. else:
  70. return mofile
  71. return result
  72. gettext.find = __findFileMO
  73. class GlobalParam(type):
  74. """ Метакласс для глобальных параметров
  75. """
  76. def __init__(cls, *args):
  77. cls.GP = []
  78. cls.GP.append("")
  79. class lang:
  80. """Класс многоязыковой поддержки lang для перевода сообщений программ на
  81. другие языки.
  82. Типичное использование:
  83. import sys
  84. import lang
  85. # язык сообщений английский
  86. tr = lang.lang(en)
  87. # язык определяется системой
  88. #tr = lang.lang()
  89. #Установка домена переводаldap
  90. # в последующем можно не использовать - задается глобально
  91. tr.setGlobalDomain('calc')
  92. # задается локально для одного файла
  93. #tr.setLocalDomain('calc')
  94. # Установка метода перевода для текущего модуля
  95. tr.setLanguage(sys.modules[__name__])
  96. Где:
  97. tr -- объект перевода
  98. 'en' -- язык выводимых сообщений
  99. sys.modules[__name__] -- модуль сообщения которого переводятся
  100. calc - домен перевода - имя файла перевода без расширения
  101. Если файл перевода не найден то сообщения не переводятся
  102. Если в модуле сообщения которого переводим, экспортируются другие модули то
  103. они тоже переводятся.
  104. По умолчанию директория в которой находятся переводы: 'lang/i18h' относительно
  105. исполняемого файла названия файлов перевода совпадают с названиями модулей
  106. если не определен методом setDomainTranslate() - домен перевода.
  107. """
  108. __metaclass__ = GlobalParam
  109. def __init__(self,l=''):
  110. self.nameDomain = self.GP[0]
  111. #self.nameDomain = ''
  112. """ Название файла перевода (Домен) если используется 1 файл перевода
  113. """
  114. self.__catalog = os.path.abspath('/usr/share/calculate-2.0/i18n')
  115. """ Путь к каталогу переводов (в этом каталоге
  116. ru_RU/LC_MESSAGES в котором файл перевода)
  117. """
  118. env = os.environ
  119. if l == "" and env.has_key('LANG'):
  120. l = env['LANG'].split('.')[0].split("_")[0]
  121. """ Определение языка """
  122. self.__modnames = {}
  123. """ Словарь переведенных модулей
  124. ключ --- имя модуля
  125. значение --- был ли модуль переведен (1 или 0)
  126. """
  127. self.__l = l
  128. """Язык перевода для всех модулей"""
  129. def __translate(self,message):
  130. """Метод translate возвращает полученное значение без
  131. изменений"""
  132. return message
  133. def setLanguage(self,module):
  134. """ Установка языка перевода для модуля module.
  135. параметр --- экспортируемый модуль python
  136. если в этом модуле экспортируются другие модули
  137. то язык устанавливается и для них
  138. Метод запускается после экспорта модуля который будем переводить
  139. """
  140. t = vars(module)
  141. for i in dir(module):
  142. q = str(t[i])
  143. if 'module' in q and not '__' in i and not '/usr/lib' in q\
  144. and not 'built-in' in q :
  145. mod = vars(module)[i]
  146. self.__setLang(mod)
  147. return self.__setLang(module)
  148. def __setLang(self,module):
  149. """ Установка языка перевода для модуля module.
  150. В случае нахождения файла перевода возвращает истину.
  151. Во всех случаях устанавливает метод перевода для модуля.
  152. Если нет файла перевода метод перевода возвращает то же
  153. значение что получает
  154. """
  155. if module.__name__ in self.__modnames.keys():
  156. return True
  157. if self.nameDomain == '':
  158. if module.__name__ == "__main__":
  159. nameDomain = module.__file__.split('.')[0]
  160. else:
  161. nameDomain = module.__name__
  162. else:
  163. nameDomain = self.nameDomain
  164. if self.__l == 'en':
  165. module._ = self.__translate
  166. ret = 1
  167. else:
  168. la = []
  169. la.append(self.__l)
  170. if gettext.find(nameDomain,self.__catalog,la):
  171. """Если найден словарь то инициализируем переводчик"""
  172. transl = gettext.translation(nameDomain\
  173. ,self.__catalog,la)
  174. #module._ = transl.ugettext
  175. module._ = transl.gettext
  176. ret = 1
  177. else:
  178. module._ = self.__translate
  179. ret = 0
  180. self.__modnames[module.__name__] = ret
  181. return ret
  182. def getTranslatorByName(self,namemodule):
  183. """ Метод который по имени модуля определяет, был ли модуль с этим
  184. именем переведен
  185. """
  186. if self.__modnames.has_key(namemodule):
  187. return self.__modnames[namemodule]
  188. return 0
  189. def setGlobalDomain(self, nameDomain):
  190. """ Метод для установки домена перевода (глобально для всех файлов)
  191. """
  192. self.GP[0] = nameDomain
  193. self.nameDomain = self.GP[0]
  194. return True
  195. def setLocalDomain(self, nameDomain):
  196. """ Метод для установки домена перевода (локально для одного файла)
  197. """
  198. self.nameDomain = nameDomain
  199. return True
  200. ##############################################################################
  201. # Перевод модуля на другой язык
  202. tr = lang()
  203. tr.setLocalDomain('cl_lib')
  204. tr.setLanguage(sys.modules[__name__])
  205. ##############################################################################
  206. class opt:
  207. def __init__(self,shortOpt,longOpt = []):
  208. """ Длинные и короткие опции командной строки допустимые в программе
  209. a - короткая опция
  210. >program -a
  211. a: - короткая опциия со значением
  212. >program -a 10
  213. a:: - короткая опциия у которой может быть или не быть значение
  214. >program -a
  215. >program -a 15
  216. "ha:" - значение параметра shortOpt
  217. две опции h - без значения, a - со значением
  218. help - длинная опция без значения
  219. test= - длинная опция со значением
  220. ["help","test="] - значение парамера longOpt
  221. >program -a
  222. две опции help - без значения, test - со значением
  223. """
  224. self.shortOpt = shortOpt
  225. self.longOpt = longOpt
  226. self.sysArgv = sys.argv[1:]
  227. def getopt(self):
  228. try:
  229. opts, args = getopt.getopt(self.sysArgv,self.shortOpt,self.longOpt)
  230. except getopt.GetoptError:
  231. self.handlerErrOpt()
  232. sys.exit(1)
  233. for option, value in opts:
  234. if len(option) == 2:
  235. option = option[1:]
  236. else:
  237. option = option[2:]
  238. self.handlerOpt(option,value)
  239. for param in args:
  240. self.handlerParam(param)
  241. def handlerErrOpt(self):
  242. # Обработчик в случае неправильных параметров
  243. pass
  244. def handlerOpt(self,option,value):
  245. # Обработчик (параметр значение)
  246. pass
  247. def handlerParam(self,param):
  248. # Обработчик хвостов (значение)
  249. pass
  250. ###############################################################################
  251. import cl_profile
  252. class iniParser(cl_profile._error):
  253. """Класс для работы с ini файлами
  254. """
  255. def __init__(self, iniFile):
  256. # название ini файла
  257. self.iniFile = iniFile
  258. # права создаваемого ini-файла
  259. self.mode = 0640
  260. # Cоответствует ли формат файла нужному
  261. self.checkIni = None
  262. def setMode(self, mode):
  263. """установка прав создаваемого ini-файла"""
  264. self.mode = mode
  265. def openIniFile(self):
  266. if not os.access(self.iniFile, os.R_OK):
  267. return ""
  268. FD = open(self.iniFile, "r")
  269. textIni = FD.read()
  270. FD.close()
  271. return textIni
  272. def writeIniFile(self, txtConfig):
  273. if not os.path.exists(self.iniFile):
  274. fd = os.open(self.iniFile, os.O_CREAT)
  275. os.close(fd)
  276. os.chmod(self.iniFile, self.mode)
  277. if not os.path.exists(self.iniFile):
  278. self.setError(_("Unable to create file") + ": " + self.iniFile)
  279. return False
  280. FD = open(self.iniFile, "r+")
  281. FD.truncate(0)
  282. FD.seek(0)
  283. FD.write(txtConfig)
  284. FD.close()
  285. def setVar(self, strHeader, dictVar):
  286. """Заменяет или добавляет область и переменные
  287. Добавляет область в ini-файл или объединяет с существующей
  288. strHeader - имя области
  289. dictVar - словарь переменных
  290. """
  291. textIni = self.openIniFile()
  292. nameFomat = self.checkIniFile(textIni)
  293. if not nameFomat:
  294. return False
  295. if type(strHeader) in (tuple, list):
  296. # формат plasma
  297. classObj = cl_profile.plasma
  298. else:
  299. if nameFomat == "plasma":
  300. self.setError(_("In the file %s (format - 'plasma'), \
  301. write the variable in the format 'samba'")\
  302. %self.iniFile)
  303. return False
  304. # формат samba
  305. classObj = cl_profile.samba
  306. # создаем объект
  307. # и записываем в него содержимое ini-файла
  308. objIni = classObj(textIni)
  309. # создаем текст из строки заголовка и
  310. # словаря переменных области
  311. txtConfig = objIni.createTxtConfig(strHeader, dictVar)
  312. # создаем объект и записываем в него текст
  313. objIniAdd = classObj(txtConfig)
  314. # объединяем объекты для получения результирующего текста
  315. objIni.join(objIniAdd)
  316. # получаем текст
  317. txtConfig = objIni.getConfig().encode("UTF-8")
  318. # записываем его в ini файл
  319. self.writeIniFile(txtConfig)
  320. return True
  321. def isEmptyFile(self, textIni):
  322. """Является ли файл пустым"""
  323. if not textIni.strip():
  324. return True
  325. else:
  326. return False
  327. def checkIniFile(self, textIni):
  328. """Проверка на правильность формата файла"""
  329. if self.checkIni == None:
  330. # Ошибка
  331. if textIni == False:
  332. self.checkIni = False
  333. return False
  334. self.checkIni = "samba"
  335. # В файле есть данные
  336. if not self.isEmptyFile(textIni):
  337. try:
  338. objIni = cl_profile.plasma(textIni)
  339. except:
  340. self.setError(_("Incorrect format file") + ": " + \
  341. self.iniFile)
  342. self.checkIni = False
  343. return self.checkIni
  344. allAreas = objIni.docObj.getAllAreas()
  345. for xmlArea in allAreas:
  346. parentNode = xmlArea.parentNode
  347. if parentNode and parentNode.tagName == "area":
  348. self.checkIni = "plasma"
  349. break
  350. if self.checkIni == "samba":
  351. objIni = cl_profile.samba(textIni)
  352. xmlBody = objIni.docObj.getNodeBody()
  353. if not xmlBody.firstChild:
  354. self.checkIni = False
  355. return self.checkIni
  356. def delVar(self, strHeader, nameVar):
  357. """Удаляем переменную из ini файла"""
  358. delNameVar = "!%s" %(nameVar)
  359. dictVar = {delNameVar:"del"}
  360. res = self.setVar(strHeader, dictVar)
  361. return res
  362. def delArea(self, strHeader):
  363. """Удаляем область из ini файла"""
  364. if type(strHeader) in (tuple, list):
  365. # Формат plasma
  366. delStrHeader = strHeader[:]
  367. delStrHeader[-1] = "!%s"%delStrHeader[-1]
  368. else:
  369. # Формат samba
  370. delStrHeader = "!%s" %(strHeader)
  371. dictVar = {"del":"del"}
  372. res = self.setVar(delStrHeader, dictVar)
  373. return res
  374. def getVar(self, strHeader, nameVar):
  375. """Получаем значение переменной из ini-файла"""
  376. textIni = self.openIniFile()
  377. nameFomat = self.checkIniFile(textIni)
  378. if not nameFomat:
  379. return False
  380. formatPlasma = False
  381. if type(strHeader) in (tuple, list):
  382. # формат plasma
  383. classObj = cl_profile.plasma
  384. formatPlasma = True
  385. else:
  386. if nameFomat == "plasma":
  387. self.setError(_("In the file %s (format - 'plasma'), \
  388. get the variable in the format 'samba'")\
  389. %self.iniFile)
  390. return False
  391. # формат samba
  392. classObj = cl_profile.samba
  393. # создаем объект и записываем в него содержимое ini-файла
  394. objIni = classObj(textIni)
  395. # получаем ноду body
  396. xmlBody = objIni.docObj.getNodeBody()
  397. flagFound, xmlBody = self.getLastNode(objIni, xmlBody, strHeader,
  398. formatPlasma)
  399. if flagFound and xmlBody:
  400. if formatPlasma:
  401. strHeader = strHeader[-1]
  402. # находим в области переменную
  403. res = objIni.docObj.getAreaFieldValues(strHeader, nameVar, xmlBody)
  404. else:
  405. res = False
  406. if res is False:
  407. return ""
  408. else:
  409. return res
  410. def getLastNode(self, objIni, xmlBody, strHeader, formatPlasma):
  411. """Ищет область в XML в которой область с переменными"""
  412. flagFound = True
  413. lenStrHeader = len(strHeader)
  414. if formatPlasma and lenStrHeader>0:
  415. xmlAreas = [xmlBody]
  416. for i in xrange(lenStrHeader-1):
  417. flagFound = False
  418. for xmlArea in xmlAreas:
  419. xmlAreas = objIni.docObj.getArea(strHeader[i], xmlArea)
  420. if xmlAreas:
  421. flagFound = True
  422. break
  423. if xmlAreas:
  424. xmlBody = xmlAreas[0]
  425. return flagFound,xmlBody
  426. def getAreaVars(self, strHeader):
  427. """Получаем все переменнные области из ini-файла"""
  428. textIni = self.openIniFile()
  429. nameFomat = self.checkIniFile(textIni)
  430. if not nameFomat:
  431. return False
  432. formatPlasma = False
  433. if type(strHeader) in (tuple, list):
  434. # формат plasma
  435. classObj = cl_profile.plasma
  436. formatPlasma = True
  437. else:
  438. if nameFomat == "plasma":
  439. self.setError(_("In the file %s (format - 'plasma'), \
  440. get all variables in the format 'samba'")\
  441. %self.iniFile)
  442. return False
  443. # формат samba
  444. classObj = cl_profile.samba
  445. # создаем объект типа samba и записываем в него содержимое ini-файла
  446. objIni = classObj(textIni)
  447. # получаем ноду body
  448. xmlBody = objIni.docObj.getNodeBody()
  449. flagFound, xmlBody = self.getLastNode(objIni, xmlBody, strHeader,
  450. formatPlasma)
  451. if flagFound and xmlBody:
  452. if formatPlasma:
  453. strHeader = strHeader[-1]
  454. # если находим область то выдаем словарем все переменные иначе False
  455. res = objIni.docObj.getAreaFields(strHeader, xmlBody)
  456. else:
  457. res = False
  458. if res is False:
  459. return {}
  460. else:
  461. return res
  462. def getAllSectionNames(self):
  463. """Получаем все имена секций определенных в ini файле
  464. Если формат ini файла plasma то имя секции -
  465. имена нескольких секций через запятую
  466. """
  467. textIni = self.openIniFile()
  468. nameFomat = self.checkIniFile(textIni)
  469. if not nameFomat:
  470. return False
  471. if nameFomat == "samba":
  472. # создаем объект типа samba и записываем в него содержимое ini-файла
  473. objIni = cl_profile.samba(textIni)
  474. elif nameFomat == "plasma":
  475. # создаем объект типа plasma и записываем в него содержимое
  476. # ini-файла
  477. objIni = cl_profile.plasma(textIni)
  478. else:
  479. return []
  480. xmlNodes = objIni.docObj.getAllAreas()
  481. # Имена секций ini файла
  482. namesSection = []
  483. if nameFomat == "plasma":
  484. for xmlNode in xmlNodes:
  485. nSect = objIni.docObj.getNameArea(xmlNode)
  486. if nSect:
  487. namesSect = [nSect]
  488. parentNode = xmlNode.parentNode
  489. while parentNode != objIni.docObj.body:
  490. nameSect = objIni.docObj.getNameArea(parentNode)
  491. if nameSect:
  492. namesSect.append(nameSect)
  493. parentNode = parentNode.parentNode
  494. else:
  495. return []
  496. namesSection.append(",".join(reversed(namesSect)))
  497. elif nameFomat == "samba":
  498. # получаем ноду body
  499. for xmlNode in xmlNodes:
  500. nSect = objIni.docObj.getNameArea(xmlNode)
  501. if nSect:
  502. namesSection.append(nSect)
  503. return namesSection
  504. ##############################################################################
  505. class var:
  506. '''Объект "Переменная окружения"'''
  507. # название сервиса которому принадлежит переменная
  508. #(Global, Builder, Client, Server итд)
  509. service = None
  510. # значение переменной
  511. value = ""
  512. # режим записи (атрибут mode)
  513. mode = "r"
  514. # переменная для внутреннего использования (official)
  515. official = False
  516. # количество вызовов метода заполнения
  517. countFill = 0
  518. # объект в котором создан этот объект
  519. parentObj = None
  520. # запускать или нет метод заполнения
  521. fillStart = True
  522. # dynamic = True то переменная динамическая при повтороном запуске
  523. # запускается метод заполнения
  524. # метод заполнения не запускается только если fillStart = False
  525. # (осторожно возможно зацикливание программы если методы заполнения
  526. # переменных используют методы друг друга)
  527. dynamic = False
  528. def __init__(self, parentObj):
  529. # словарь зависимых переменных {имя:значение}
  530. self.dependValues = {}
  531. # тип переменной (атрибут type)
  532. self.type = ('default')
  533. # список допустимых значений переменных (select)
  534. self.select = ()
  535. # объект который создал этот объект
  536. self.parentObj = parentObj
  537. def is_update(self):
  538. #Нужно ли перезапускать метод заполнения (если зависимые переменные
  539. #обновились то нужно)
  540. upd = False
  541. for depVarName in self.dependValues.keys():
  542. value = self.parentObj.__getattribute__(depVarName).Get()
  543. if self.dependValues[depVarName] != value:
  544. self.dependValues[depVarName] =\
  545. self.parentObj.__getattribute__(depVarName).value
  546. upd = True
  547. break
  548. return upd
  549. def Get(self):
  550. """Получение значения переменной"""
  551. if not self.fillStart:
  552. return self.value
  553. if self.dynamic:
  554. self.value = self.Fill()
  555. return self.value
  556. if not self.value:
  557. if self.countFill>0:
  558. return self.value
  559. self.countFill += 1
  560. self.value = self.Fill()
  561. if self.dependValues and self.is_update():
  562. self.countFill += 1
  563. self.value = self.Fill()
  564. return self.value
  565. def Set(self, value):
  566. """Запись значения переменной"""
  567. self.value = value
  568. return self.value
  569. def Fill(self):
  570. """Заполнение переменной в далнейшем заменяем методом заполнения"""
  571. return self.value
  572. class DataVars(object):
  573. class DataVarsError(Exception):
  574. """Класс ошибок"""
  575. pass
  576. # добавляем пути к модулям если они не добавлены
  577. if not os.path.abspath(\
  578. '/usr/lib/calculate/calculate-server/pym') in sys.path:
  579. sys.path.insert(0,os.path.abspath(\
  580. '/usr/lib/calculate/calculate-server/pym'))
  581. if not os.path.abspath(\
  582. '/usr/lib/calculate/calculate-lib/pym') in sys.path:
  583. sys.path.insert(0,os.path.abspath(\
  584. '/usr/lib/calculate/calculate-lib/pym'))
  585. if not os.path.abspath(\
  586. '/usr/lib/calculate/calculate-builder/pym') in sys.path:
  587. sys.path.insert(0,os.path.abspath(\
  588. '/usr/lib/calculate/calculate-builder/pym'))
  589. # Импортируемые модули - (раздел: модуль переменных, модуль заполнения
  590. #переменных)
  591. __modlist={'Global':('cl_vars','cl_fill'),
  592. 'Server':('cl_vars_server','cl_fill_server'),
  593. 'Builder':('cl_vars_builder','cl_fill_builder'),
  594. 'Client':('cl_vars_client','cl_fill_client'),
  595. }
  596. def __init__(self):
  597. #self.t1 = fillVars()
  598. #self.t1.Get = self.Get
  599. #self.t1.Set = self.Set
  600. # Для нахождения зависимостей переменных
  601. self.__levelNumber = 0
  602. self.__LevelsVar = []
  603. # Для хранения импортированных модулей и объектов
  604. #[(cекция,импортированный модуль переменных, объект заполнения),]
  605. self._importList = []
  606. self._importData("Global")
  607. def _importData(self, section):
  608. """Импортирует модули с переменными и модули с функциями заполнения
  609. section секция раздела (Global, Server, Client итд)
  610. создает необходимые структуры данных
  611. """
  612. if not section in self.__modlist.keys():
  613. raise self.DataVarsError(_("Unsupported section %s")%section)
  614. modVar = self.__modlist[section][0]
  615. modFill = self.__modlist[section][1]
  616. # Импортируем класс описания переменных и класс заполнения
  617. try:
  618. exec ("import %s" % (modVar))
  619. except ImportError, e:
  620. err1 = _("Error in import module %s")%modVar
  621. err2 = _("error") + ": " +str(e)
  622. raise self.DataVarsError("%s\n%s"%(err1,err2))
  623. flagFindFillModule = True
  624. try:
  625. exec ("import %s" % (modFill))
  626. except ImportError, e:
  627. if "No module named" in str(e):
  628. flagFindFillModule = False
  629. else:
  630. err1 = _("Error in import module %s")%modFill
  631. err2 = _("error") + ": " +str(e)
  632. raise self.DataVarsError("%s\n%s"%(err1,err2))
  633. if flagFindFillModule:
  634. # Создаем объект с методами заполнения переменных
  635. exec("fillObj = %s.fillVars()" %modFill)
  636. # Подключаем методы получения и записи переменных
  637. fillObj.Get = self.Get
  638. fillObj.Set = self.Set
  639. else:
  640. fillObj = False
  641. # Заполняем self._importList
  642. exec("self._importList.insert(0,(section,%s,fillObj))"%(modVar))
  643. def __findVarData(self, nameVar):
  644. """Находит данные для создания объекта переменная в модулях и
  645. объектах
  646. """
  647. # Ищем переменную в модуле
  648. dataVar = False
  649. e = False
  650. for section, moduleVar, fillobj in self._importList:
  651. try:
  652. exec("dataVar=moduleVar.Data.%s"%nameVar)
  653. except AttributeError, e:
  654. pass
  655. if dataVar:
  656. break
  657. if dataVar == False:
  658. err1 = _("Not found variable %s")%nameVar
  659. err2 = ""
  660. if e:
  661. err2 = _("error") + ": " +str(e)
  662. raise self.DataVarsError("%s\n%s"%(err1,err2))
  663. dataVar['service'] = section
  664. # Ищем метод в объекте методов заполнения
  665. nameMethod = "get_" + nameVar
  666. flagFindMetod = False
  667. for section, moduleVar, fillobj in self._importList:
  668. if fillobj:
  669. if nameMethod in dir(fillobj):
  670. flagFindMetod = True
  671. method = fillobj.__getattribute__(nameMethod)
  672. break
  673. if flagFindMetod:
  674. return (dataVar,method)
  675. else:
  676. return (dataVar,False)
  677. def __setAttributesVar(self, var ,nameVar, dict):
  678. """Установка аттрибутов для созданного объекта var
  679. название аттрибута и его значение берется из словаря dict
  680. """
  681. dict['type'] = nameVar.split('_')
  682. if not set(dict.keys()) <= set(dir(var)):
  683. raise self.DataVarsError(\
  684. _("error initalize variable %s, incorrect data")%nameVar)
  685. for nameAttr in dict.keys():
  686. setattr(var,nameAttr, dict[nameAttr])
  687. return True
  688. def __Get(self, nameVar):
  689. ret = ""
  690. self.__LevelsVar.append((self.__levelNumber, nameVar))
  691. self.__levelNumber += 1
  692. #nameMethod = "get_" + nameVar
  693. if hasattr(self, nameVar):
  694. ret = self.__getattribute__(nameVar).Get()
  695. elif self.__findVarData(nameVar):
  696. dictVar, methodFill =self.__findVarData(nameVar)
  697. varobj = var(self)
  698. # Устанавливаем аттрибуты
  699. self.__setAttributesVar(varobj, nameVar, dictVar)
  700. if methodFill:
  701. varobj.Fill = methodFill
  702. self.__setattr__(nameVar, varobj)
  703. ret = self.__getattribute__(nameVar).Get()
  704. self.__levelNumber -= 1
  705. if self.__levelNumber == 0 and\
  706. self.__getattribute__(nameVar).fillStart and\
  707. len(self.__LevelsVar)>1:
  708. links = self.__getLinks(self.__LevelsVar)
  709. for name in links.keys():
  710. for nameLink in links[name].keys():
  711. val = self.__getattribute__(nameLink).Get()
  712. self.__getattribute__(name).dependValues[nameLink] = val
  713. if self.__levelNumber == 0:
  714. self.__LevelsVar = []
  715. return ret
  716. def Get(self, nameVar):
  717. return self.__Get(nameVar)
  718. def __Set(self, nameVar, value, force=False):
  719. nameMethod = "get_" +nameVar
  720. if not hasattr(self, nameVar) and self.__findVarData(nameVar):
  721. dictVar, methodFill =self.__findVarData(nameVar)
  722. varobj = var(self)
  723. # Устанавливаем аттрибуты
  724. self.__setAttributesVar(varobj, nameVar, dictVar)
  725. if methodFill:
  726. varobj.Fill = methodFill
  727. self.__setattr__(nameVar, varobj)
  728. if hasattr(self, nameVar):
  729. if not force and "r" in getattr(self, nameVar).mode:
  730. print _("Attempt to rewrite a variable for reading:%s")\
  731. %nameVar
  732. return False
  733. self.__getattribute__(nameVar).fillStart = False
  734. return self.__getattribute__(nameVar).Set(value)
  735. def Set(self, nameVar, value, force=False):
  736. return self.__Set(nameVar, value, force)
  737. def __frame(self, lVar):
  738. """получить список областей зависимости переменных"""
  739. data = []
  740. if not lVar:
  741. return data
  742. firstLevel = lVar[0][0]
  743. for level, name in lVar[1:]:
  744. if level> firstLevel:
  745. data.append((level, name))
  746. else:
  747. break
  748. return data
  749. def __getLinks(self, lVar):
  750. """Получить список переменных и от каких переменных они зависят
  751. на вход список [(уровень рекурсии, название переменной),]
  752. """
  753. links = {}
  754. frames = {}
  755. levelLinks = {}
  756. lVarFr = lVar
  757. for level, name in lVar:
  758. fr = self.__frame(lVarFr)
  759. if not frames.has_key(name):
  760. frames[name] = fr
  761. levelLinks[name] = level+1
  762. lVarFr = lVarFr[1:]
  763. for name in frames.keys():
  764. level = levelLinks[name]
  765. fr = frames[name]
  766. links[name] = {}
  767. for lv, nm in fr:
  768. if level == lv:
  769. links[name][nm] = ""
  770. return links
  771. def __getPathCalculateIni(self):
  772. """Получить пути до ini файлов"""
  773. return self.Get('cl_env_path')
  774. def __getSection(self, vname):
  775. """секция для записи в ini файл переменной
  776. vname - имя переменной
  777. """
  778. if hasattr(self, vname):
  779. if getattr(self, vname).service == 'Global':
  780. return 'calculate'
  781. else:
  782. return getattr(self, vname).service.lower()
  783. def __writeVarValue(self, vname, val, location, header):
  784. '''Записать значение в calculate.ini
  785. Параметры:
  786. vname имя переменной
  787. val значение переменной
  788. location расположение ini файла ('default', 'local', 'remote')
  789. header раздел ini файла ('client', 'server', 'calculate')
  790. Возвращаемые значение:
  791. True запись успешна
  792. False запись не удалсь
  793. '''
  794. # получаем все пути до ini файлов
  795. calculate_ini = self.__getPathCalculateIni()
  796. # получаем полный путь до файла ini
  797. if location == 'default':
  798. name_calculate_ini = calculate_ini[2]
  799. elif location == 'local':
  800. name_calculate_ini = calculate_ini[1]
  801. elif location == 'remote':
  802. name_calculate_ini = calculate_ini[0]
  803. else:
  804. return False
  805. # извлекаем из полного имени файла путь
  806. onlydir = os.path.split(name_calculate_ini)[0]
  807. try:
  808. # проверяем чтобы путь до ини файла существовал
  809. if not os.path.exists(onlydir):
  810. # создаем его если отсутствует
  811. os.makedirs(onlydir)
  812. except OSError (nerr,msg):
  813. print nerr, msg
  814. return False
  815. config = iniParser(name_calculate_ini)
  816. # Получаем секцию конфигурационного файла
  817. if not header:
  818. header = self.__getSection(vname)
  819. return config.setVar(header,{vname: cl_utils.convertStrListDict(val)})
  820. def __deleteVarValue(self, vname, location, header):
  821. '''Удалить переменную в calculate.ini
  822. Параметры:
  823. vname имя переменной
  824. location расположение ini файла ('default', 'local', 'remote')
  825. header раздел ini файла ('client', 'server', 'calculate')
  826. Возвращаемые значение:
  827. True удалено успешно
  828. False удаление не удалсь
  829. '''
  830. # получаем все пути до ini файлов
  831. calculate_ini = self.__getPathCalculateIni()
  832. # получаем полный путь до файла ini
  833. if location == 'default':
  834. name_calculate_ini = calculate_ini[2]
  835. elif location == 'local':
  836. name_calculate_ini = calculate_ini[1]
  837. elif location == 'remote':
  838. name_calculate_ini = calculate_ini[0]
  839. else:
  840. return False
  841. # извлекаем из полного имени файла путь
  842. onlydir = os.path.split(name_calculate_ini)[0]
  843. # проверяем чтобы путь до ини файла существовал
  844. if not os.path.exists(onlydir):
  845. return False
  846. config = iniParser(name_calculate_ini)
  847. # Получаем секцию конфигурационного файла
  848. if not header:
  849. header = self.__getSection(vname)
  850. if not header:
  851. self.Get(vname)
  852. header = self.__getSection(vname)
  853. # Удаляем переменную
  854. retDelVar = config.delVar(header, vname)
  855. retDelArea = True
  856. if not config.getAreaVars(header):
  857. retDelArea = config.delArea(header)
  858. if retDelArea and retDelVar:
  859. return True
  860. else:
  861. return False
  862. def Write(self, vname, val, force=False, location='default',header=False):
  863. '''Установить и записать значение переменной в ini файл
  864. Параметры:
  865. vname имя переменной
  866. val значение переменной
  867. force "принудительный режим"
  868. location расположение ini файла ('default', 'local', 'remote')
  869. header раздел ini файла ('client', 'server', 'calculate')
  870. '''
  871. if self.__Set(vname, val, force)!= False:
  872. if not val.strip():
  873. self.__deleteVarValue(vname, location, header)
  874. self.__writeVarValue(vname, val, location, header)
  875. return True
  876. return False
  877. def Delete(self, vname, location='default', header=False):
  878. '''Удалить переменную в calculate.ini
  879. Параметры:
  880. vname имя переменной
  881. location расположение ini файла ('default', 'local', 'remote')
  882. Возвращаемые значение:
  883. True удалено успешна
  884. False удаление не удалсь
  885. '''
  886. return self.__deleteVarValue(vname, location, header)
  887. def __getActiveSections(self):
  888. """активные секции в ini файле"""
  889. act_section = []
  890. for service,t,t in self._importList:
  891. if service == "Global":
  892. act_section.append('calculate')
  893. else:
  894. act_section.append(service.lower())
  895. return act_section
  896. def flIniFile(self):
  897. '''Заместить значение переменных значениями из ини файлов
  898. Возвращаемые значения:
  899. cловарь импортированных переменных - переменные считаны
  900. False - файл не был обнаружен
  901. '''
  902. #Cловарь переменных из ini файлов
  903. importVars = {}
  904. calculate_ini = self.__getPathCalculateIni()
  905. # активные секции (секции из которых будут использованы переменные)
  906. act_section = self.__getActiveSections()
  907. set_act_section = set(act_section)
  908. i = 0
  909. locations = ['remote','local','default']
  910. for name_calculate_ini in calculate_ini:
  911. # проверить сущестование ini файла
  912. if os.path.exists(name_calculate_ini):
  913. # получить объект настроенный на ini
  914. config = iniParser(name_calculate_ini)
  915. # получаем все секции из конфигурационного файла
  916. allsect = config.getAllSectionNames()
  917. if not allsect:
  918. continue
  919. # находим встречающиеся у обоих секции
  920. act_sect = tuple(set(allsect)& set_act_section)
  921. # словарь переменных для ini - файла
  922. importFileVars = {}
  923. # получаем все переменные из всех секций
  924. for section in act_sect:
  925. allvars = config.getAreaVars(section)
  926. if allvars == False:
  927. return False
  928. # словарь переменных для ini - файла
  929. importFileVars = {}
  930. # принудительно переписать все переменные окружения
  931. # полученные из ini
  932. for (k,v) in allvars.items():
  933. k = k.encode("UTF-8")
  934. value = cl_utils.convertStrListDict(v.encode("UTF-8"))
  935. self.Set(k, value, True)
  936. importFileVars[k] = value
  937. if i < 3:
  938. importVars[locations[i]] = importFileVars
  939. i += 1
  940. return importVars
  941. def flServer(self, **args):
  942. '''Заполнить конфигурацию переменных, для ldap'''
  943. # заполнить переменные окружения алгоритмом по умолнанию
  944. self._importData("Server")
  945. def flClient(self, **args):
  946. '''Заполнить конфигурацию переменных, для клиента'''
  947. # заполнить переменные окружения алгоритмом по умолнанию
  948. self._importData("Client")
  949. def flBuilder(self, **args):
  950. '''Заполнить конфигурацию переменных, для билдера'''
  951. self.Set('setup_pass','builder',True)
  952. # заполнить переменные окружения алгоритмом по умолнанию
  953. self._importData("Builder")
  954. def flInstall(self, **args):
  955. '''Заполнить конфигурацию переменных для инсталятора'''
  956. self.Set('setup_pass','install',True)
  957. def defined(self, vname):
  958. return True
  959. def exists(self, nameVar):
  960. """ Определяет существует ли переменная с таким имененм
  961. """
  962. if hasattr(self, nameVar):
  963. return True
  964. foundVar = False
  965. # Ищем переменную в импортируемых модулях
  966. for section, moduleVar, fillobj in self._importList:
  967. if moduleVar.Data.__dict__.has_key(nameVar):
  968. foundVar = True
  969. break
  970. return foundVar
  971. def getVars(self, type_names=None):
  972. ret = {}
  973. for section, moduleVar, fillobj in self._importList:
  974. dataVar=moduleVar.Data
  975. dictVars = dir(dataVar)
  976. for nameVar in dictVars:
  977. if not "__" in nameVar:
  978. if not (getattr(dataVar,nameVar).has_key("official") and\
  979. getattr(dataVar,nameVar)['official']):
  980. self.Get(nameVar)
  981. if type_names:
  982. #type_names.sort()
  983. varType =list(getattr(dataVar,nameVar)['type'])
  984. #varType.sort()
  985. #print type_names
  986. #print varType
  987. #print
  988. if not set(type_names)<=set(varType):
  989. continue
  990. ret[nameVar] = getattr(self,nameVar)
  991. return ret
  992. #распечатать список переменных с значениями
  993. def printVars(self,type_names=None):
  994. var=None
  995. var=self.getVars(type_names)
  996. mlen_name=0;
  997. mlen_type=0;
  998. mlen_mode=0;
  999. for i,j in var.items():
  1000. if len(i)>mlen_name:
  1001. mlen_name=len(i)
  1002. #if len(str(j.type))>mlen_type:
  1003. #mlen_type=len(str(j.type))
  1004. vtype=str(type(var[i].value)).split(" ")[1][1]
  1005. if not '[' in var[i].mode:
  1006. if vtype in ['d','l']:
  1007. mode="[%s%s]"%(var[i].mode.lower(),vtype)
  1008. else:
  1009. mode="[%s]"%(var[i].mode.lower())
  1010. var[i].mode=mode
  1011. if len(mode)>mlen_mode:
  1012. mlen_mode=len(mode)
  1013. plist=var.keys()
  1014. plist.sort()
  1015. br = cl_utils.fillstr("-",mlen_name) + " " +\
  1016. cl_utils.fillstr("-",mlen_mode) + " " + cl_utils.fillstr("-",10)
  1017. #cl_utils.fillstr("-",mlen_type) + " " +\
  1018. print "The list of variables:"
  1019. print "var name".center(mlen_name),\
  1020. "Mode","Value"
  1021. #"Type".center(mlen_type),\
  1022. print br
  1023. for i in plist:
  1024. #if var[i].value is None:
  1025. #continue
  1026. p_val=var[i].value
  1027. if var[i].official:
  1028. continue
  1029. cl_utils.columnWrite( i, mlen_name, var[i].mode.lower(),
  1030. mlen_mode,
  1031. #str(var[i].type),
  1032. #mlen_type,
  1033. p_val)
  1034. print br
  1035. ##############################################################################
  1036. class glob_attr:
  1037. """Глобальные аттрибуты для методов заполнения переменных"""
  1038. def _runos(self,cmd, ret_first=None, env={}):
  1039. """Вернуть результат выполнения команды ОС"""
  1040. if not env:
  1041. envDict = {}
  1042. env.update(os.environ.items() + [("PATH",cl_utils.getpathenv())] +\
  1043. env.items())
  1044. retCode, programOut = cl_utils.runOsCommand(cmd, None, ret_first, env)
  1045. if not retCode:
  1046. return programOut
  1047. return False