27 changed files with 2652 additions and 2849 deletions
-
3README
-
624pym/cl_data.py
-
432pym/cl_fill.py
-
375pym/cl_help.py
-
40pym/cl_lib.py
-
1pym/cl_log.py
-
2pym/cl_overriding.py
-
3394pym/cl_template.py
-
176pym/cl_utils.py
-
31pym/cl_vars.py
-
1pym/format/__init__.py
-
3pym/format/apache.py
-
2pym/format/bind.py
-
2pym/format/dhcp.py
-
4pym/format/dovecot.py
-
23pym/format/kde.py
-
1pym/format/ldap.py
-
42pym/format/plasma.py
-
1pym/format/postfix.py
-
17pym/format/samba.py
-
1pym/format/squid.py
-
128pym/format/xml_gconf.py
-
2pym/format/xml_xfce.py
-
12pym/format/xml_xfcepanel.py
-
178pym/server/encrypt.py
-
2pym/server/ldap.py
-
4setup.py
@ -1,624 +0,0 @@ |
|||
#-*- coding: utf-8 -*- |
|||
|
|||
# Copyright 2008-2010 Mir Calculate Ltd. http://www.calculate-linux.org |
|||
# |
|||
# Licensed under the Apache License, Version 2.0 (the "License"); |
|||
# you may not use this file except in compliance with the License. |
|||
# You may obtain a copy of the License at |
|||
# |
|||
# http://www.apache.org/licenses/LICENSE-2.0 |
|||
# |
|||
# Unless required by applicable law or agreed to in writing, software |
|||
# distributed under the License is distributed on an "AS IS" BASIS, |
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
# See the License for the specific language governing permissions and |
|||
# limitations under the License. |
|||
|
|||
import os |
|||
import sys |
|||
import cl_utils |
|||
from cl_lang import lang |
|||
from cl_template import iniParser |
|||
from cl_string import columnWrite |
|||
|
|||
# Перевод модуля на другой язык |
|||
tr = lang() |
|||
tr.setLocalDomain('cl_lib') |
|||
tr.setLanguage(sys.modules[__name__]) |
|||
|
|||
class var: |
|||
'''Объект "Переменная окружения"''' |
|||
# название сервиса которому принадлежит переменная |
|||
#(Global, Builder, Client, Server итд) |
|||
service = None |
|||
# значение переменной |
|||
value = "" |
|||
# режим записи (атрибут mode) |
|||
mode = "r" |
|||
# переменная для внутреннего использования (official) |
|||
official = False |
|||
# количество вызовов метода заполнения |
|||
countFill = 0 |
|||
# объект в котором создан этот объект |
|||
parentObj = None |
|||
# запускать или нет метод заполнения |
|||
fillStart = True |
|||
# dynamic = True то переменная динамическая при повтороном запуске |
|||
# запускается метод заполнения |
|||
# метод заполнения не запускается только если fillStart = False |
|||
# (осторожно возможно зацикливание программы если методы заполнения |
|||
# переменных используют методы друг друга) |
|||
dynamic = False |
|||
|
|||
def __init__(self, parentObj): |
|||
# словарь зависимых переменных {имя:значение} |
|||
self.dependValues = {} |
|||
# тип переменной (атрибут type) |
|||
self.type = ('default') |
|||
# список допустимых значений переменных (select) |
|||
self.select = () |
|||
# объект который создал этот объект |
|||
self.parentObj = parentObj |
|||
|
|||
def is_update(self): |
|||
#Нужно ли перезапускать метод заполнения (если зависимые переменные |
|||
#обновились то нужно) |
|||
upd = False |
|||
for depVarName in self.dependValues.keys(): |
|||
value = self.parentObj.__getattribute__(depVarName).Get() |
|||
if self.dependValues[depVarName] != value: |
|||
self.dependValues[depVarName] =\ |
|||
self.parentObj.__getattribute__(depVarName).value |
|||
upd = True |
|||
break |
|||
return upd |
|||
|
|||
def Get(self): |
|||
"""Получение значения переменной""" |
|||
if not self.fillStart: |
|||
return self.value |
|||
if self.dynamic: |
|||
self.value = self.Fill() |
|||
return self.value |
|||
if not self.value: |
|||
if self.countFill>0: |
|||
return self.value |
|||
self.countFill += 1 |
|||
self.value = self.Fill() |
|||
if self.dependValues and self.is_update(): |
|||
self.countFill += 1 |
|||
self.value = self.Fill() |
|||
return self.value |
|||
|
|||
def Set(self, value): |
|||
"""Запись значения переменной""" |
|||
self.value = value |
|||
return self.value |
|||
|
|||
def Fill(self): |
|||
"""Заполнение переменной в далнейшем заменяем методом заполнения""" |
|||
return self.value |
|||
|
|||
|
|||
class DataVars(object): |
|||
class DataVarsError(Exception): |
|||
"""Класс ошибок""" |
|||
pass |
|||
# добавляем пути к модулям если они не добавлены |
|||
if not os.path.abspath(\ |
|||
'/usr/lib/calculate/calculate-server/pym') in sys.path: |
|||
sys.path.insert(0,os.path.abspath(\ |
|||
'/usr/lib/calculate/calculate-server/pym')) |
|||
if not os.path.abspath(\ |
|||
'/usr/lib/calculate/calculate-lib/pym') in sys.path: |
|||
sys.path.insert(0,os.path.abspath(\ |
|||
'/usr/lib/calculate/calculate-lib/pym')) |
|||
if not os.path.abspath(\ |
|||
'/usr/lib/calculate/calculate-builder/pym') in sys.path: |
|||
sys.path.insert(0,os.path.abspath(\ |
|||
'/usr/lib/calculate/calculate-builder/pym')) |
|||
# Импортируемые модули - (раздел: модуль переменных, модуль заполнения |
|||
#переменных) |
|||
__modlist={'Global':('cl_vars','cl_fill'), |
|||
'Server':('cl_vars_server','cl_fill_server'), |
|||
'Builder':('cl_vars_builder','cl_fill_builder'), |
|||
'Client':('cl_vars_client','cl_fill_client'), |
|||
} |
|||
def __init__(self): |
|||
#self.t1 = fillVars() |
|||
#self.t1.Get = self.Get |
|||
#self.t1.Set = self.Set |
|||
# Для нахождения зависимостей переменных |
|||
self.__levelNumber = 0 |
|||
self.__LevelsVar = [] |
|||
# Для хранения импортированных модулей и объектов |
|||
#[(cекция,импортированный модуль переменных, объект заполнения),] |
|||
self._importList = [] |
|||
self._importData("Global") |
|||
|
|||
def _importData(self, section): |
|||
"""Импортирует модули с переменными и модули с функциями заполнения |
|||
|
|||
section секция раздела (Global, Server, Client итд) |
|||
создает необходимые структуры данных |
|||
""" |
|||
if not section in self.__modlist.keys(): |
|||
raise self.DataVarsError(_("Unsupported section %s")%section) |
|||
modVar = self.__modlist[section][0] |
|||
modFill = self.__modlist[section][1] |
|||
# Импортируем класс описания переменных и класс заполнения |
|||
try: |
|||
exec ("import %s" % (modVar)) |
|||
except ImportError, e: |
|||
err1 = _("Error in import module %s")%modVar |
|||
err2 = _("error") + ": " +str(e) |
|||
raise self.DataVarsError("%s\n%s"%(err1,err2)) |
|||
flagFindFillModule = True |
|||
try: |
|||
exec ("import %s" % (modFill)) |
|||
except ImportError, e: |
|||
if "No module named" in str(e): |
|||
flagFindFillModule = False |
|||
else: |
|||
err1 = _("Error in import module %s")%modFill |
|||
err2 = _("error") + ": " +str(e) |
|||
raise self.DataVarsError("%s\n%s"%(err1,err2)) |
|||
if flagFindFillModule: |
|||
# Создаем объект с методами заполнения переменных |
|||
exec("fillObj = %s.fillVars()" %modFill) |
|||
# Подключаем методы получения и записи переменных |
|||
fillObj.Get = self.Get |
|||
fillObj.Set = self.Set |
|||
else: |
|||
fillObj = False |
|||
# Заполняем self._importList |
|||
exec("self._importList.insert(0,(section,%s,fillObj))"%(modVar)) |
|||
|
|||
def __findVarData(self, nameVar): |
|||
"""Находит данные для создания объекта переменная в модулях и |
|||
|
|||
объектах |
|||
""" |
|||
# Ищем переменную в модуле |
|||
dataVar = False |
|||
e = False |
|||
for section, moduleVar, fillobj in self._importList: |
|||
try: |
|||
exec("dataVar=moduleVar.Data.%s"%nameVar) |
|||
except AttributeError, e: |
|||
pass |
|||
if dataVar: |
|||
break |
|||
if dataVar == False: |
|||
err1 = _("Not found variable %s")%nameVar |
|||
err2 = "" |
|||
if e: |
|||
err2 = _("error") + ": " +str(e) |
|||
raise self.DataVarsError("%s\n%s"%(err1,err2)) |
|||
dataVar['service'] = section |
|||
# Ищем метод в объекте методов заполнения |
|||
nameMethod = "get_" + nameVar |
|||
flagFindMetod = False |
|||
for section, moduleVar, fillobj in self._importList: |
|||
if fillobj: |
|||
if nameMethod in dir(fillobj): |
|||
flagFindMetod = True |
|||
method = fillobj.__getattribute__(nameMethod) |
|||
break |
|||
if flagFindMetod: |
|||
return (dataVar,method) |
|||
else: |
|||
return (dataVar,False) |
|||
|
|||
def __setAttributesVar(self, var ,nameVar, dict): |
|||
"""Установка аттрибутов для созданного объекта var |
|||
|
|||
название аттрибута и его значение берется из словаря dict |
|||
""" |
|||
dict['type'] = nameVar.split('_') |
|||
if not set(dict.keys()) <= set(dir(var)): |
|||
raise self.DataVarsError(\ |
|||
_("error initalize variable %s, incorrect data")%nameVar) |
|||
for nameAttr in dict.keys(): |
|||
setattr(var,nameAttr, dict[nameAttr]) |
|||
return True |
|||
|
|||
def __Get(self, nameVar): |
|||
ret = "" |
|||
self.__LevelsVar.append((self.__levelNumber, nameVar)) |
|||
self.__levelNumber += 1 |
|||
#nameMethod = "get_" + nameVar |
|||
if self.__dict__.has_key(nameVar): |
|||
ret = self.__getattribute__(nameVar).Get() |
|||
elif self.__findVarData(nameVar): |
|||
dictVar, methodFill =self.__findVarData(nameVar) |
|||
varobj = var(self) |
|||
# Устанавливаем аттрибуты |
|||
self.__setAttributesVar(varobj, nameVar, dictVar) |
|||
if methodFill: |
|||
varobj.Fill = methodFill |
|||
self.__setattr__(nameVar, varobj) |
|||
ret = self.__getattribute__(nameVar).Get() |
|||
self.__levelNumber -= 1 |
|||
if self.__levelNumber == 0 and\ |
|||
self.__getattribute__(nameVar).fillStart and\ |
|||
len(self.__LevelsVar)>1: |
|||
links = self.__getLinks(self.__LevelsVar) |
|||
for name in links.keys(): |
|||
for nameLink in links[name].keys(): |
|||
val = self.__getattribute__(nameLink).Get() |
|||
self.__getattribute__(name).dependValues[nameLink] = val |
|||
if self.__levelNumber == 0: |
|||
self.__LevelsVar = [] |
|||
return ret |
|||
|
|||
def Get(self, nameVar): |
|||
return self.__Get(nameVar) |
|||
|
|||
|
|||
def __Set(self, nameVar, value, force=False): |
|||
nameMethod = "get_" +nameVar |
|||
if not self.__dict__.has_key(nameVar) and self.__findVarData(nameVar): |
|||
dictVar, methodFill =self.__findVarData(nameVar) |
|||
varobj = var(self) |
|||
# Устанавливаем аттрибуты |
|||
self.__setAttributesVar(varobj, nameVar, dictVar) |
|||
if methodFill: |
|||
varobj.Fill = methodFill |
|||
self.__setattr__(nameVar, varobj) |
|||
if self.__dict__.has_key(nameVar): |
|||
if not force and "r" in getattr(self, nameVar).mode: |
|||
print _("Attempt to rewrite a variable for reading:%s")\ |
|||
%nameVar |
|||
return False |
|||
self.__getattribute__(nameVar).fillStart = False |
|||
return self.__getattribute__(nameVar).Set(value) |
|||
|
|||
def Set(self, nameVar, value, force=False): |
|||
return self.__Set(nameVar, value, force) |
|||
|
|||
def __frame(self, lVar): |
|||
"""получить список областей зависимости переменных""" |
|||
data = [] |
|||
if not lVar: |
|||
return data |
|||
firstLevel = lVar[0][0] |
|||
for level, name in lVar[1:]: |
|||
if level> firstLevel: |
|||
data.append((level, name)) |
|||
else: |
|||
break |
|||
return data |
|||
|
|||
def __getLinks(self, lVar): |
|||
"""Получить список переменных и от каких переменных они зависят |
|||
|
|||
на вход список [(уровень рекурсии, название переменной),] |
|||
""" |
|||
links = {} |
|||
frames = {} |
|||
levelLinks = {} |
|||
lVarFr = lVar |
|||
for level, name in lVar: |
|||
fr = self.__frame(lVarFr) |
|||
if not frames.has_key(name): |
|||
frames[name] = fr |
|||
levelLinks[name] = level+1 |
|||
lVarFr = lVarFr[1:] |
|||
for name in frames.keys(): |
|||
level = levelLinks[name] |
|||
fr = frames[name] |
|||
links[name] = {} |
|||
for lv, nm in fr: |
|||
if level == lv: |
|||
links[name][nm] = "" |
|||
return links |
|||
|
|||
def __getPathCalculateIni(self): |
|||
"""Получить пути до ini файлов""" |
|||
return self.Get('cl_env_path') |
|||
|
|||
def __getSection(self, vname): |
|||
"""секция для записи в ini файл переменной |
|||
|
|||
vname - имя переменной |
|||
""" |
|||
if self.__dict__.has_key(vname): |
|||
if self.__dict__[vname].service == 'Global': |
|||
return 'calculate' |
|||
else: |
|||
return self.__dict__[vname].service.lower() |
|||
|
|||
def __writeVarValue(self, vname, val, location, header): |
|||
'''Записать значение в calculate.ini |
|||
|
|||
Параметры: |
|||
vname имя переменной |
|||
val значение переменной |
|||
location расположение ini файла ('default', 'local', 'remote') |
|||
header раздел ini файла ('client', 'server', 'calculate') |
|||
|
|||
Возвращаемые значение: |
|||
True запись успешна |
|||
False запись не удалсь |
|||
''' |
|||
# получаем все пути до ini файлов |
|||
calculate_ini = self.__getPathCalculateIni() |
|||
# получаем полный путь до файла ini |
|||
if location == 'default': |
|||
name_calculate_ini = calculate_ini[2] |
|||
elif location == 'local': |
|||
name_calculate_ini = calculate_ini[1] |
|||
elif location == 'remote': |
|||
name_calculate_ini = calculate_ini[0] |
|||
else: |
|||
return False |
|||
# извлекаем из полного имени файла путь |
|||
onlydir = os.path.split(name_calculate_ini)[0] |
|||
try: |
|||
# проверяем чтобы путь до ини файла существовал |
|||
if not os.path.exists(onlydir): |
|||
# создаем его если отсутствует |
|||
os.makedirs(onlydir) |
|||
except OSError (nerr,msg): |
|||
print nerr, msg |
|||
return False |
|||
config = iniParser(name_calculate_ini) |
|||
# Получаем секцию конфигурационного файла |
|||
if not header: |
|||
header = self.__getSection(vname) |
|||
return config.setVar(header,{vname: cl_utils.convertStrListDict(val)}) |
|||
|
|||
def __deleteVarValue(self, vname, location, header): |
|||
'''Удалить переменную в calculate.ini |
|||
|
|||
Параметры: |
|||
vname имя переменной |
|||
location расположение ini файла ('default', 'local', 'remote') |
|||
|
|||
Возвращаемые значение: |
|||
True удалено успешна |
|||
False удаление не удалсь |
|||
''' |
|||
# получаем все пути до ini файлов |
|||
calculate_ini = self.__getPathCalculateIni() |
|||
# получаем полный путь до файла ini |
|||
if location == 'default': |
|||
name_calculate_ini = calculate_ini[2] |
|||
elif location == 'local': |
|||
name_calculate_ini = calculate_ini[1] |
|||
elif location == 'remote': |
|||
name_calculate_ini = calculate_ini[0] |
|||
else: |
|||
return False |
|||
# извлекаем из полного имени файла путь |
|||
onlydir = os.path.split(name_calculate_ini)[0] |
|||
# проверяем чтобы путь до ини файла существовал |
|||
if not os.path.exists(onlydir): |
|||
return False |
|||
config = iniParser(name_calculate_ini) |
|||
# Получаем секцию конфигурационного файла |
|||
if not header: |
|||
header = self.__getSection(vname) |
|||
# Удаляем переменную |
|||
retDelVar = config.delVar(header, vname) |
|||
retDelArea = True |
|||
if not config.getAreaVars(header): |
|||
retDelArea = config.delArea(header) |
|||
if retDelArea and retDelVar: |
|||
return True |
|||
else: |
|||
return False |
|||
|
|||
def Write(self, vname, val, force=False, location='default',header=False): |
|||
'''Установить и записать значение переменной в ini файл |
|||
|
|||
Параметры: |
|||
vname имя переменной |
|||
val значение переменной |
|||
force "принудительный режим" |
|||
location расположение ini файла ('default', 'local', 'remote') |
|||
header раздел ini файла ('client', 'server', 'calculate') |
|||
''' |
|||
if self.__Set(vname, val, force)!= False: |
|||
if not val.strip(): |
|||
self.__deleteVarValue(vname, location, header) |
|||
self.__writeVarValue(vname, val, location, header) |
|||
return True |
|||
return False |
|||
|
|||
def Delete(self, vname, location='default', header=False): |
|||
'''Удалить переменную в calculate.ini |
|||
|
|||
Параметры: |
|||
vname имя переменной |
|||
location расположение ini файла ('default', 'local', 'remote') |
|||
|
|||
Возвращаемые значение: |
|||
True удалено успешна |
|||
False удаление не удалсь |
|||
''' |
|||
return self.__deleteVarValue(vname, location, header) |
|||
|
|||
def __getActiveSections(self): |
|||
"""активные секции в ini файле""" |
|||
act_section = [] |
|||
for service,t,t in self._importList: |
|||
if service == "Global": |
|||
act_section.append('calculate') |
|||
else: |
|||
act_section.append(service.lower()) |
|||
return act_section |
|||
|
|||
def flIniFile(self): |
|||
'''Заместить значение переменных значениями из ини файлов |
|||
|
|||
Возвращаемые значения: |
|||
cловарь импортированных переменных - переменные считаны |
|||
False - файл не был обнаружен |
|||
''' |
|||
#Cловарь переменных из ini файлов |
|||
importVars = {} |
|||
calculate_ini = self.__getPathCalculateIni() |
|||
# активные секции (секции из которых будут использованы переменные) |
|||
act_section = self.__getActiveSections() |
|||
set_act_section = set(act_section) |
|||
i = 0 |
|||
locations = ['remote','local','default'] |
|||
for name_calculate_ini in calculate_ini: |
|||
# проверить сущестование ini файла |
|||
if os.path.exists(name_calculate_ini): |
|||
# получить объект настроенный на ini |
|||
config = iniParser(name_calculate_ini) |
|||
# получаем все секции из конфигурационного файла |
|||
allsect = config.getAllSectionNames() |
|||
if not allsect: |
|||
continue |
|||
# находим встречающиеся у обоих секции |
|||
act_sect = tuple(set(allsect)& set_act_section) |
|||
# словарь переменных для ini - файла |
|||
importFileVars = {} |
|||
# получаем все переменные из всех секций |
|||
for section in act_sect: |
|||
allvars = config.getAreaVars(section) |
|||
if allvars == False: |
|||
return False |
|||
# словарь переменных для ini - файла |
|||
importFileVars = {} |
|||
# принудительно переписать все переменные окружения |
|||
# полученные из ini |
|||
for (k,v) in allvars.items(): |
|||
k = k.encode("UTF-8") |
|||
value = cl_utils.convertStrListDict(v.encode("UTF-8")) |
|||
self.Set(k, value, True) |
|||
importFileVars[k] = value |
|||
if i < 3: |
|||
importVars[locations[i]] = importFileVars |
|||
i += 1 |
|||
return importVars |
|||
|
|||
def flServer(self, **args): |
|||
'''Заполнить конфигурацию переменных, для ldap''' |
|||
# заполнить переменные окружения алгоритмом по умолнанию |
|||
self._importData("Server") |
|||
|
|||
def flClient(self, **args): |
|||
'''Заполнить конфигурацию переменных, для клиента''' |
|||
# заполнить переменные окружения алгоритмом по умолнанию |
|||
self._importData("Client") |
|||
|
|||
def flBuilder(self, **args): |
|||
'''Заполнить конфигурацию переменных, для билдера''' |
|||
self.Set('setup_pass','builder',True) |
|||
# заполнить переменные окружения алгоритмом по умолнанию |
|||
self._importData("Builder") |
|||
|
|||
def flInstall(self, **args): |
|||
'''Заполнить конфигурацию переменных для инсталятора''' |
|||
self.Set('setup_pass','install',True) |
|||
|
|||
#def defined(self, vname): |
|||
#if vname: |
|||
#if self.__dict__.has_key(vname): |
|||
#return True |
|||
#return False |
|||
def defined(self, vname): |
|||
return True |
|||
|
|||
|
|||
|
|||
def exists(self, nameVar): |
|||
""" Определяет существует ли переменная с таким имененм |
|||
""" |
|||
if self.__dict__.has_key(nameVar): |
|||
return True |
|||
foundVar = False |
|||
# Ищем переменную в импортируемых модулях |
|||
for section, moduleVar, fillobj in self._importList: |
|||
if moduleVar.Data.__dict__.has_key(nameVar): |
|||
foundVar = True |
|||
break |
|||
return foundVar |
|||
|
|||
def getVars(self, type_names=None): |
|||
ret = {} |
|||
for section, moduleVar, fillobj in self._importList: |
|||
dataVar=moduleVar.Data |
|||
dictVars = dir(dataVar) |
|||
for nameVar in dictVars: |
|||
if not "__" in nameVar: |
|||
if not (getattr(dataVar,nameVar).has_key("official") and\ |
|||
getattr(dataVar,nameVar)['official']): |
|||
self.Get(nameVar) |
|||
if type_names: |
|||
#type_names.sort() |
|||
varType =list(getattr(dataVar,nameVar)['type']) |
|||
#varType.sort() |
|||
#print type_names |
|||
#print varType |
|||
#print |
|||
if not set(type_names)<=set(varType): |
|||
continue |
|||
ret[nameVar] = getattr(self,nameVar) |
|||
return ret |
|||
|
|||
#распечатать список переменных с значениями |
|||
def printVars(self,type_names=None): |
|||
var=None |
|||
var=self.getVars(type_names) |
|||
mlen_name=0; |
|||
mlen_type=0; |
|||
mlen_mode=0; |
|||
for i,j in var.items(): |
|||
if len(i)>mlen_name: |
|||
mlen_name=len(i) |
|||
#if len(str(j.type))>mlen_type: |
|||
#mlen_type=len(str(j.type)) |
|||
vtype=str(type(var[i].value)).split(" ")[1][1] |
|||
if not '[' in var[i].mode: |
|||
if vtype in ['d','l']: |
|||
mode="[%s%s]"%(var[i].mode.lower(),vtype) |
|||
else: |
|||
mode="[%s]"%(var[i].mode.lower()) |
|||
var[i].mode=mode |
|||
if len(mode)>mlen_mode: |
|||
mlen_mode=len(mode) |
|||
plist=var.keys() |
|||
plist.sort() |
|||
br = cl_utils.fillstr("-",mlen_name) + " " +\ |
|||
cl_utils.fillstr("-",mlen_mode) + " " + cl_utils.fillstr("-",10) |
|||
#cl_utils.fillstr("-",mlen_type) + " " +\ |
|||
|
|||
print "The list of variables:" |
|||
print "var name".center(mlen_name),\ |
|||
"Mode","Value" |
|||
#"Type".center(mlen_type),\ |
|||
|
|||
|
|||
print br |
|||
for i in plist: |
|||
#if var[i].value is None: |
|||
#continue |
|||
p_val=var[i].value |
|||
if var[i].official: |
|||
continue |
|||
columnWrite( i, mlen_name, var[i].mode.lower(), |
|||
mlen_mode, |
|||
#str(var[i].type), |
|||
#mlen_type, |
|||
p_val) |
|||
print br |
|||
|
|||
class glob_attr: |
|||
"""Глобальные аттрибуты для методов заполнения переменных""" |
|||
|
|||
def _runos(self,cmd, ret_first=None, env={}): |
|||
"""Вернуть результат выполнения команды ОС""" |
|||
if not env: |
|||
envDict = {} |
|||
env.update(os.environ.items() + [("PATH",cl_utils.getpathenv())] +\ |
|||
env.items()) |
|||
retCode, programOut = cl_utils.runOsCommand(cmd, None, ret_first, env) |
|||
if not retCode: |
|||
return programOut |
|||
return False |
@ -1,375 +0,0 @@ |
|||
#-*- coding: utf-8 -*- |
|||
|
|||
# Copyright 2008-2010 Mir Calculate Ltd. http://www.calculate-linux.org |
|||
# |
|||
# Licensed under the Apache License, Version 2.0 (the "License"); |
|||
# you may not use this file except in compliance with the License. |
|||
# You may obtain a copy of the License at |
|||
# |
|||
# http://www.apache.org/licenses/LICENSE-2.0 |
|||
# |
|||
# Unless required by applicable law or agreed to in writing, software |
|||
# distributed under the License is distributed on an "AS IS" BASIS, |
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
# See the License for the specific language governing permissions and |
|||
# limitations under the License. |
|||
|
|||
import getopt |
|||
import sys |
|||
from cl_string import prettyColumnStr |
|||
|
|||
pcs = prettyColumnStr |
|||
|
|||
class opt: |
|||
def __init__(self,shortOpt,longOpt = []): |
|||
""" Длинные и короткие опции командной строки допустимые в программе |
|||
a - короткая опция |
|||
>program -a |
|||
|
|||
a: - короткая опциия со значением |
|||
>program -a 10 |
|||
|
|||
a:: - короткая опциия у которой может быть или не быть значение |
|||
>program -a |
|||
>program -a 15 |
|||
|
|||
"ha:" - значение параметра shortOpt |
|||
две опции h - без значения, a - со значением |
|||
|
|||
help - длинная опция без значения |
|||
test= - длинная опция со значением |
|||
|
|||
["help","test="] - значение парамера longOpt |
|||
>program -a |
|||
две опции help - без значения, test - со значением |
|||
""" |
|||
self.shortOpt = shortOpt |
|||
self.longOpt = longOpt |
|||
self.sysArgv = sys.argv[1:] |
|||
|
|||
def getopt(self): |
|||
try: |
|||
opts, args = getopt.getopt(self.sysArgv,self.shortOpt,self.longOpt) |
|||
except getopt.GetoptError: |
|||
self.handlerErrOpt() |
|||
sys.exit(1) |
|||
for option, value in opts: |
|||
if len(option) == 2: |
|||
option = option[1:] |
|||
else: |
|||
option = option[2:] |
|||
self.handlerOpt(option,value) |
|||
for param in args: |
|||
self.handlerParam(param) |
|||
|
|||
def handlerErrOpt(self): |
|||
# Обработчик в случае неправильных параметров |
|||
pass |
|||
|
|||
def handlerOpt(self,option,value): |
|||
# Обработчик (параметр значение) |
|||
pass |
|||
|
|||
def handlerParam(self,param): |
|||
# Обработчик хвостов (значение) |
|||
pass |
|||
|
|||
class cl_help: |
|||
"""Объект для работы со справкой, и обработкой параметров. |
|||
|
|||
Конструктор __init__ должен определить следующие переменные: |
|||
|
|||
self.chapter список разделов справки, каждый элементы состоит из |
|||
имени раздела, флаг видимый/скрытый, кол-во переводов строк |
|||
после названия раздела, количество строк после раздела, |
|||
тип раздела |
|||
Пример: [("Copyright",False,0,2),"options"] |
|||
self.relService словарь связей сервисов и действующих опций |
|||
ключ - название сервиса, значение - список отображаемых |
|||
разделов отмеченных как "options" |
|||
Пример: {"samba":[_("Common options"), |
|||
_("Service Samba options")]} |
|||
self.relOptions словарь связей длинных опций помощи и выводимых разделов |
|||
помощи с опциями |
|||
ключ - параметр справки, значение список отображаемых |
|||
разделов справки |
|||
Пример: {"help-ldap":[_("Common options"), |
|||
_("Service LDAP options)]} |
|||
self.progName словарь имена используемых программ и их номера для |
|||
доступа к переменным |
|||
Пример: {'cl-groupadd':0, 'cl-groupdel':1} |
|||
self.data список данных для справки, каждый элемент словарь: |
|||
progAccess: список номеров программ отображающих |
|||
Пример: {'progAccess':(0,), |
|||
'shortOption':"g", |
|||
'longOption':"gid", |
|||
'optVal':"GID", |
|||
'helpChapter':_("Options"), |
|||
'help':_("use GID for the new group") |
|||
}, |
|||
после заполнения параметров необходимо выполнить |
|||
self._cl_help__setParamHelp() для заполнения справки |
|||
|
|||
""" |
|||
def __init__(self, cmdName): |
|||
# ширина консоли взята за 80 |
|||
# -1 чтобы компенсировать расстрояние между колонками |
|||
self.consolewidth = 79 |
|||
self.column_width = 32 |
|||
self.cmdName = cmdName |
|||
#короткие опции командной строки |
|||
self.shortOpt = [] |
|||
#длинные опции командной строки |
|||
self.longOpt = [] |
|||
# массив разделов (заполняется в __setParamHelp) |
|||
self.chapterBloc = [] |
|||
#optEnd = "" |
|||
#if "user" in self.cmdName and not "mod" in self.cmdName: |
|||
#optEnd = _("user") |
|||
#elif "group" in self.cmdName and not "mod" in self.cmdName: |
|||
#optEnd = _("group") |
|||
#self.__setParamHelp() |
|||
|
|||
def getChapterNumber(self,NameChapter): |
|||
"""Получить номер раздела по имени""" |
|||
num = 0 |
|||
for i in self.chapter: |
|||
if i[0] == NameChapter: |
|||
return num |
|||
num += 1 |
|||
return False |
|||
|
|||
def __setParamHelp(self): |
|||
"""Внутренняя функция формирования справки по данным |
|||
|
|||
Перебирает все элементы списка data, проверяет их на доступность |
|||
данной программы, разбирает опции на среди data и формирует |
|||
для по ним справку. |
|||
""" |
|||
# сформировать нужное количество блоков раздела |
|||
self.chapterBloc = [""]*len(self.chapter) |
|||
# |
|||
sp = {} |
|||
i = 0 |
|||
# перебираем все элементы справки собираем элементы опции |
|||
# так же формируем разделы не опции |
|||
for par in self.data: |
|||
# перебираем только те опции, которые принадлежат команде |
|||
if self.access(par): |
|||
# есть короткая (возможно есть и длинная) |
|||
if par.has_key("shortOption"): |
|||
sp[par["shortOption"]+":"+par["helpChapter"]] = i |
|||
# есть только длинная опция |
|||
elif par.has_key("longOption"): |
|||
sp[par["longOption"]+":"+par["helpChapter"]] = i |
|||
# формирование разделов не опций |
|||
else: |
|||
helpTxt = par['help'] |
|||
numChapter = self.getChapterNumber(par['helpChapter']) |
|||
self.addChapterHelp(numChapter,helpTxt) |
|||
i += 1 |
|||
# перебираем все "собранные" опции |
|||
# опции перебираются по порядку в списке date |
|||
# для сортировки по ключам следует применить код: |
|||
# for index in sorted(sp.keys()): |
|||
# par = self.data[sp[index]] |
|||
for index in sorted(sp.values()): |
|||
par = self.data[index] |
|||
numChapter = self.getChapterNumber(par['helpChapter']) |
|||
# если есть и короткая и длинная |
|||
if "shortOption" in par and "longOption" in par: |
|||
paraminfo = "-%s, --%s "%(par["shortOption"],par["longOption"]) |
|||
# если есть только короткая |
|||
elif "shortOption" in par: |
|||
paraminfo = "-%s "%par["shortOption"] |
|||
# если только длинная |
|||
else: |
|||
paraminfo = "--%s "%par["longOption"] |
|||
# если указан параметр для опции |
|||
if "optVal" in par: |
|||
optVal = par["optVal"] |
|||
else: |
|||
optVal = "" |
|||
|
|||
# вывод вида: " [-o, ][--option] [PARAM]" "helpstring" |
|||
helpTxt = pcs(" "+paraminfo+optVal, self.column_width, \ |
|||
par['help'], self.consolewidth-self.column_width) |
|||
# добавить строку в нужный раздел |
|||
self.addChapterHelp(numChapter,helpTxt) |
|||
|
|||
def getHelp(self, optionsChapters=False): |
|||
"""Выдать справку. |
|||
|
|||
Выдает справку в случае если указан optionsChapters, то фильтрует по |
|||
типу разделов. |
|||
|
|||
Параметры: |
|||
optionsChapters Flase или список опциональных разделов для |
|||
отображения |
|||
|
|||
Возвращаемые параметры: |
|||
Строка со справкой. |
|||
""" |
|||
# Выдать справку |
|||
help = "" |
|||
# перебираем все элементы справочных блоков |
|||
iterChapterBloc = iter(self.chapterBloc) |
|||
# перебираем все разделы по параметрам |
|||
for (nameChapter, visibleChapter, beforeStrChapter, \ |
|||
afterStrChapter, typeChapter) in self.chapter: |
|||
# получаем следующий блок (т.о. textChapterBloc соответ, chapter) |
|||
textChapterBloc = iterChapterBloc.next() |
|||
# если тип раздела опциональный |
|||
if optionsChapters and typeChapter=="options": |
|||
# проверяем нужно ли его отображать |
|||
if not (nameChapter in optionsChapters): |
|||
continue |
|||
bef = "\n"*beforeStrChapter |
|||
aft = "\n"*afterStrChapter |
|||
# если блок не пустой и раздел отображаемый |
|||
if len(textChapterBloc) > 0: |
|||
if visibleChapter: |
|||
help += nameChapter + ": " + bef |
|||
help += textChapterBloc + aft |
|||
help = help.rstrip()+"\n" |
|||
return help |
|||
|
|||
def addChapterHelp(self, numChapter, helpTxt): |
|||
"""Добавить в раздел помощи numChapteк тектстовую строку helpTxt |
|||
|
|||
Параметры: |
|||
numChapter номер раздела в который нужно добавить данные справки |
|||
helpTxt строка, содержащая данные |
|||
""" |
|||
self.chapterBloc[numChapter] += helpTxt |
|||
return True |
|||
|
|||
def addData(self,dataHash): |
|||
# На будущее (добавляет опции) |
|||
self.data.append(dataHash) |
|||
return True |
|||
|
|||
def handleCheckAccess(self,dataHash): |
|||
"""Замещаемый дополнительный обработчик проверки |
|||
доступности опции. |
|||
|
|||
Входные параметры: |
|||
dataHash элементы списка данных справки (self.data) |
|||
""" |
|||
return True |
|||
|
|||
def access(self,dataHash): |
|||
"""Доступна ли опция вызывающей программе |
|||
|
|||
Параметры: |
|||
dataHash словарь элемент типа self.data |
|||
|
|||
Возвращаемые параметры: |
|||
True/False доступна/недоступна |
|||
""" |
|||
# доступна ли опция вызывающей программе |
|||
# опция без progAccess доступна |
|||
numProg = self.progName[self.cmdName] |
|||
if 'progAccess' in dataHash: |
|||
if numProg in dataHash['progAccess']: |
|||
# вызов дополнительной проверки доступа к опции |
|||
return self.handleCheckAccess(dataHash) |
|||
else: |
|||
return False |
|||
else: |
|||
# вызов дополнительной проверки доступа к опции |
|||
return self.handleCheckAccess(dataHash) |
|||
|
|||
def getTypeChapter(self, nameChapter): |
|||