reorganization of the library

develop
Самоукин Алексей 14 years ago
parent 3dd26c94fe
commit b2a0679a60

@ -4,9 +4,10 @@ INSTALL
------- -------
calculate-lib needs the following library version installed, in order to run: calculate-lib needs the following library version installed, in order to run:
Python >= 2.6 python >= 2.5
python-ldap >= 2.0.0 python-ldap >= 2.0.0
pyxml >= 0.8 pyxml >= 0.8
py-smbpasswd >= 1.0
To install calculate-lib , just execute the install script 'setup.py'. To install calculate-lib , just execute the install script 'setup.py'.
Example: Example:

@ -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):
'''Заместить значение переменных значениями из ини файлов
Возвращаемые значения:
оварь импортированных переменных - переменные считаны
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

@ -17,11 +17,197 @@
import re import re
import os import os
import types import types
from cl_overriding import exit import filecmp
import cl_utils import cl_datavars
import cl_data
class fillVars(object, cl_data.glob_attr): class clLocale:
lang = {
#Belarussian
'be_BY' : {
'locale':'be_BY.UTF-8',
'keymap':'by',
'dumpkeys_charset': 'koi8-u',
'consolefont':'Cyr_a8x16',
'xkblayout':'us,by',
'language':'ru',
},
#Belgian
'fr_BE' : {
'locale':'fr_BE.UTF-8',
'keymap':'be-latin1',
'dumpkeys_charset':'',
'consolefont':'lat9w-16',
'xkblayout':'us,be',
'language':'en_US',
},
#Brazilian Portuguese
'pt_BR' : {
'locale':'pt_BR.UTF-8',
'keymap':'br-abnt2',
'dumpkeys_charset':'',
'consolefont':'lat9w-16',
'xkblayout':'pt,us',
'language':'pt_BR',
},
#Canadian French
'fr_CA' : {
'locale':'fr_CA.UTF-8',
'keymap':'cf',
'dumpkeys_charset':'',
'consolefont':'default8x16',
'xkblayout':'us,ca_enhanced',
'language':'en_US',
},
#Danish
'da_DK' : {
'locale':'da_DK.UTF-8',
'keymap':'dk-latin1',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'us,dk',
'language':'da',
},
#French
'fr_FR' : {
'locale':'fr_FR.UTF-8',
'keymap':'fr-latin9',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'fr,us',
'language':'en_US',
},
#German
'de_DE' : {
'locale':'de_DE.UTF-8',
'keymap':'de-latin1',
'dumpkeys_charset':'',
'consolefont':'lat9w-16',
'xkblayout':'de,us',
'language':'de',
},
#Icelandic
'is_IS' : {
'locale':'is_IS.UTF-8',
'keymap':'is-latin1',
'dumpkeys_charset':'',
'consolefont':'cp850-8x16',
'xkblayout':'us,is',
'language':'en_US',
},
#Italian
'it_IT' : {
'locale':'it_IT.UTF-8',
'keymap':'it',
'dumpkeys_charset':'',
'consolefont':'default8x16',
'xkblayout':'us,it',
'language':'it',
},
#Norwegian
'nn_NO' : {
'locale':'nn_NO.UTF-8',
'keymap':'no-latin1',
'dumpkeys_charset':'',
'consolefont':'lat9w-16',
'xkblayout':'us,no',
'language':'nn',
},
#Polish
'pl_PL' : {
'locale':'pl_PL.UTF-8',
'keymap':'pl',
'dumpkeys_charset':'',
'consolefont':'lat2-16',
'xkblayout':'us,pl',
'language':'pl',
},
#Russian
'ru_RU' : {
'locale':'ru_RU.UTF-8',
'keymap':'-u ruwin_cplk-UTF-8',
'dumpkeys_charset':'',
'consolefont':'ter-k14n',
'xkblayout':'us,ru(winkeys)',
'language':'ru',
},
#Spanish
'es_ES' : {
'locale':'es_ES.UTF-8',
'keymap':'es euro2',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'es,us',
'language':'es',
},
#Swedish
'sv_SE' : {
'locale':'sv_SE.UTF-8',
'keymap':'sv-latin1',
'dumpkeys_charset':'',
'consolefont':'lat0-16',
'xkblayout':'us,se',
'language':'sv',
},
#Ukrainian
'uk_UA' : {
'locale':'uk_UA.UTF-8',
'keymap':'ua-utf',
'dumpkeys_charset':'koi8-u',
'consolefont':'ter-v14n',
'xkblayout':'us,ua(winkeys)',
'language':'uk',
},
#United Kingdom/British
'en_GB' : {
'locale':'en_GB.UTF-8',
'keymap':'uk',
'dumpkeys_charset':'',
'consolefont':'LatArCyrHeb-16',
'xkblayout':'us,gb',
'language':'en_US',
},
#United State/English
'en_US' : {
'locale':'en_US.UTF-8',
'keymap':'us',
'dumpkeys_charset':'',
'consolefont':'LatArCyrHeb-16',
'xkblayout':'us',
'language':'en_US',
}
}
def getLangs(self):
return self.lang.keys()
def isLangExists(self,lang):
return lang in self.lang.keys()
def getFields(self,field):
return [ l[1][field] for l in self.lang.items() ]
def getFieldByLang(self,field,lang):
return self.lang.get(lang, self.lang['en_US'])[field]
def getFieldByKeymap(self,field,keymap):
return self.lang.get(self.getLangByField('keymap',keymap),
self.lang['en_US'])[field]
def getLangByField(self,field,value):
langs = [lang[0] for lang in self.lang.items()
if lang[1][field] == value ]
if not langs:
return 'en_US'
else:
return langs[0]
def getdirlist(s_path):
#Получить список директорий по указаному пути
fdir=filecmp.dircmp(s_path, s_path)
dir_list=fdir.common_dirs
return dir_list
class fillVars(object, cl_datavars.glob_attr):
def get_os_net_domain(self): def get_os_net_domain(self):
''' Определим домен''' ''' Определим домен'''
@ -29,7 +215,7 @@ class fillVars(object, cl_data.glob_attr):
if not domain: if not domain:
print _("Error:") + " " +_("Not found domain name") print _("Error:") + " " +_("Not found domain name")
print _("Command 'hostname -d' returns an empty value") print _("Command 'hostname -d' returns an empty value")
exit(1) cl_base.exit(1)
elif re.search("^hostname: ",domain): elif re.search("^hostname: ",domain):
return "local" return "local"
else: else:
@ -61,6 +247,7 @@ class fillVars(object, cl_data.glob_attr):
if linuxShortName: if linuxShortName:
dictLinuxName = {"CLD":"Calculate Linux Desktop", dictLinuxName = {"CLD":"Calculate Linux Desktop",
"CLDX":"Calculate Linux Desktop", "CLDX":"Calculate Linux Desktop",
"CLDG":"Calculate Linux Desktop",
"CDS":"Calculate Directory Server", "CDS":"Calculate Directory Server",
"Gentoo":"Gentoo"} "Gentoo":"Gentoo"}
if linuxShortName in dictLinuxName.keys(): if linuxShortName in dictLinuxName.keys():
@ -74,7 +261,7 @@ class fillVars(object, cl_data.glob_attr):
"""постфикс к названию системы""" """постфикс к названию системы"""
linuxShortName = self.Get("os_linux_shortname") linuxShortName = self.Get("os_linux_shortname")
if linuxShortName: if linuxShortName:
dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE"} dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE", "CLDG":"GNOME"}
if linuxShortName in dictLinuxSubName.keys(): if linuxShortName in dictLinuxSubName.keys():
return dictLinuxSubName[linuxShortName] return dictLinuxSubName[linuxShortName]
else: else:
@ -100,7 +287,7 @@ class fillVars(object, cl_data.glob_attr):
systemVersion = "" systemVersion = ""
flagGentoo = False flagGentoo = False
if os.path.exists(gentooFile): if os.path.exists(gentooFile):
gentooLink = "/etc/make.template" gentooLink = "/etc/make.profile"
if os.path.islink(gentooLink): if os.path.islink(gentooLink):
systemVersion = os.readlink(gentooLink).rpartition("/")[2] systemVersion = os.readlink(gentooLink).rpartition("/")[2]
flagGentoo = True flagGentoo = True
@ -130,7 +317,7 @@ class fillVars(object, cl_data.glob_attr):
def get_os_net_ip(self): def get_os_net_ip(self):
"""все ip компьютера, разделитель запятая""" """все ip компьютера, разделитель запятая"""
IPs = [] IPs = []
netInterfaces=cl_utils.getdirlist("/sys/class/net/") netInterfaces=getdirlist("/sys/class/net/")
for i in netInterfaces: for i in netInterfaces:
res = self._runos("/sbin/ifconfig %s"%i) res = self._runos("/sbin/ifconfig %s"%i)
if not res: if not res:
@ -165,7 +352,7 @@ class fillVars(object, cl_data.glob_attr):
%(x>>24, x>>16&255, x>>8&255, x&255, nMask(maskNumb)) %(x>>24, x>>16&255, x>>8&255, x&255, nMask(maskNumb))
networks=[] networks=[]
netInterfaces=cl_utils.getdirlist("/sys/class/net/") netInterfaces=getdirlist("/sys/class/net/")
flagError = False flagError = False
for i in netInterfaces: for i in netInterfaces:
res = self._runos("/sbin/ifconfig %s"%i) res = self._runos("/sbin/ifconfig %s"%i)
@ -181,85 +368,6 @@ class fillVars(object, cl_data.glob_attr):
return "" return ""
return ",".join(networks) return ",".join(networks)
def get_os_locale_locale(self):
"""локаль (прим: ru_RU.UTF-8)"""
if os.environ.has_key("LANG"):
return os.environ["LANG"]
else:
return "en_US.UTF-8"
def get_os_locale_lang(self):
"""язык (прим: ru_RU)"""
locale = self.Get("os_locale_locale")
if locale:
return locale.split(".")[0]
return ""
def get_os_locale_language(self):
"""язык (прим: ru)"""
lang = self.Get("os_locale_lang")
if lang:
return lang.split("_")[0]
return ""
def get_os_locale_xkb(self):
"""раскладка клавиатуры для X"""
path = '/etc/conf.d/keymaps'
mapDict={"by":"us,by",
"be-latin1":"be,us",
"br-abnt2":"br,us",
"cf":"ca,us",
"dk-latin1":"dk,us",
"fr-latin9":"fr,us",
"de-latin1":"de,us",
"is-latin1":"is,us",
"it":"it,us",
"no-latin1":"no,us",
"pl":"pl,us",
"-u ru4":"us,ru(winkeys)",
"es euro2":"es,us",
"sv-latin1":"se,us",
"ua-utf":"us,ua(winkeys)",
"uk":"gb,us",
"us":"us"}
if os.path.exists(path):
FD = open(path)
data = FD.readlines()
FD.close()
shortNameList = filter(lambda y:y,
map(lambda x:\
len(x.split("="))==2 and\
x.split("=")[0]=="KEYMAP" and\
x.split("=")[1].replace('"',"").strip(),\
data))
if shortNameList:
if shortNameList[0] in mapDict.keys():
return mapDict[shortNameList[0]]
lang = self.Get("os_locale_lang")
# Языки:
# Португальский - pt_BR
# Французский - fr_FR
# Немецкий - de_DE
# Итальянский - it_IT
# Польский - pl_PL
# Русский - ru_RU
# Испанский - es_ES
# Украинский - uk_UA
# Английский - en_US
xkbDict = {'pt_BR':'br,us',
'fr_FR':'fr,us',
'de_DE':'de,us',
'it_IT':'it,us',
'pl_PL':'pl,us',
'ru_RU':'us,ru(winkeys)',
'es_ES':'es,us',
'uk_UA':'us,ua(winkeys)',
'en_US':'us'}
if lang:
if xkbDict.has_key(lang):
return xkbDict[lang]
return ""
def get_os_locale_xkbname(self): def get_os_locale_xkbname(self):
"""названия используемых раскладок клавиатуры для X""" """названия используемых раскладок клавиатуры для X"""
localeXkb = self.Get("os_locale_xkb") localeXkb = self.Get("os_locale_xkb")
@ -344,3 +452,151 @@ class fillVars(object, cl_data.glob_attr):
virtName = virtSysDict[vName] virtName = virtSysDict[vName]
break break
return virtName return virtName
def getValueFromConfig(self,config,name):
"""Get value of parameter from bash type file
Parameters:
config config file name
name param name
"""
reMatch = re.compile("^%s\s*=\s*\"?(.*)\"?$"%name, re.I)
try:
if os.path.exists(config):
for line in open(config,"r").readlines():
match = reMatch.match(line)
if match:
return group().strip()
except:
pass
return False
def getValueFromCmdLine(self,option,num):
"""Get value of parameter from boot params
Parameters:
option param name
num number part of value parameter (, split)
"""
cmdLine = "/proc/cmdline"
calculateParam = "calculate"
# try get timezone from kernel calculate param
try:
for param in open(cmdLine,"r").read().split(" "):
parname,op,value = param.partition("=")
if parname == calculateParam and op == "=":
values = value.split(",")
if len(values) > num and values[num].strip():
return values[num].strip()
except IOError,e:
return ""
def get_hr_board_model(self):
"""motherboard model"""
modelFile = "/sys/class/dmi/id/board_name"
try:
return open(modelFile,"r").read().strip()
except:
return ""
def get_hr_board_vendor(self):
"""motherboard vendor"""
vendorFile = "/sys/class/dmi/id/board_vendor"
try:
return open(vendorFile,"r").read().strip()
except:
return ""
def get_hr_cpus(self):
"""processors count"""
cpuinfoFile = "/proc/cpuinfo"
try:
return len(["" for line in open(cpuinfoFile,"r").readlines()
if "processor" in line])
except:
return 1
def get_os_locale_locale(self):
"""locale (example: ru_RU.UTF-8)"""
locale = clLocale()
# get locale from boot calculate param
localeVal = self.getValueFromCmdLine("calculate",0)
if locale.isLangExists(localeVal):
return locale.getFieldByLang('locale',localeVal)
elif os.environ.has_key("LANG"):
return os.environ["LANG"]
else:
return locale.getFieldByLang("locale","default")
def get_os_locale_lang(self):
"""lang (example: ru_RU)"""
locale = clLocale()
return locale.getLangByField("locale",self.Get('os_locale_locale'))
def get_os_locale_language(self):
"""language (example: ru)"""
locale = clLocale()
return locale.getFieldByLang("language",self.Get('os_locale_lang'))
def get_os_locale_xkb(self):
"""xkb layouts (example: en,ru)"""
locale = clLocale()
# is specified keymap support by locale hash
if self.Get('os_locale_keymap') in locale.getFields('keymap'):
return locale.getFieldByKeymap("xkblayout",
self.Get('os_locale_keymap'))
else:
return locale.getFieldByLang("xkblayout",
self.Get('os_locale_lang'))
def get_os_locale_keymap(self):
"""keymap of locale (used for /etc/conf.d/keymaps)"""
locale = clLocale()
# get keymap from boot calculate param (keymap specified
# by lang)
keymapConfd = '/etc/conf.d/keymaps'
keymap = self.getValueFromCmdLine("calculate",1)
if locale.isLangExists(keymap):
return locale.getFieldByLang('keymap',keymap)
# get keymap by os_locale_lang
keymap = self.getValueFromConfig(keymapConfd,'KEYMAP')
if keymap:
return keymap
return locale.getFieldByLang("keymap",self.Get("os_locale_lang"))
def get_os_locale_dumpkeys(self):
"""dumpkeys charset for keymap"""
locale = clLocale()
# is specified keymap support by locale hash
if self.Get('os_locale_keymap') in locale.getFields('keymap'):
return locale.getFieldByKeymap("dumpkeys_charset",
self.Get('os_locale_keymap'))
else:
return locale.getFieldByLang("dumpkeys_charset",
self.Get('os_locale_lang'))
def get_os_clock_timezone(self):
"""timezone for clock"""
zoneinfodir = "/usr/share/zoneinfo/"
localtimefile = "/etc/localtime"
# try get timezone from kernel calculate param
timezone = self.getValueFromCmdLine("calculate",2)
if timezone and \
os.path.exists(os.path.join(zoneinfodir,timezone)):
return timezone
# get timezone from localtime symlink
if os.path.lexists(localtimefile):
return os.readlink(localtimefile).replace(zoneinfodir,"")
return "UTC"
def get_os_clock_type(self):
"""type of clock (UTC or local)"""
clockTypeFile = ['/etc/conf.d/clock','/etc/conf.d/hwclock']
for f in clockTypeFile:
clock = self.getValueFromConfig(f,"clock")
if clock:
if clock.upper() == 'UTC':
return clock.upper()
elif clock.lower() == 'local':
return clock.lower()
return "local"

@ -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):
"""Получить тип раздела по его имени
Параметры:
nameChapter название раздела
Возвращаемые параметры:
строка тип раздела
Flase(Boolean) такой раздел отсутствует
"""
# фильтруем список по имени раздела, помещаем в список тип раздела
filtered = [typeChapter for name, na, na, na, typeChapter \
in self.chapter if name == nameChapter]
# если среди фильтрованных есть хоть один элемент
if len(filtered) > 0:
# возвращаем - он запрашиваемый
return filtered[0]
else:
# такой раздел отсутствует
return False
def clearAllOpt(self):
"""Очистить все опции, полученные посредством getAllOpt"""
if len(self.shortOpt) > 0:
self.shortOpt = []
if len(self.longOpt) > 0:
self.longOpt = []
return True
def getAllOpt(self,typeOpt="all", optionsChapters=False):
"""Получить все доступные опции
Параметры:
typeOpt 'short'/'long'/'all', вернуть короткие или длинные
опции или все (возвращаются кортежем)
optionsChapters фильтр для опций по типам разделов (список,кортеж)
Возвращаемые параметры:
строка коротки или список строк длинных опций ('hb:c:wg:G:k:ms:u:')
"""
# Выдать все действующие опции
if typeOpt=="short" or typeOpt=="all":
if len(self.shortOpt) == 0:
for par in self.data:
if optionsChapters and\
self.getTypeChapter(par['helpChapter'])=="options":
if not (par['helpChapter'] in optionsChapters):
continue
if par.has_key("shortOption") and self.access(par):
if par.has_key("optVal"):
self.shortOpt.append(par["shortOption"]+':')
else:
self.shortOpt.append(par["shortOption"])
if typeOpt=="long" or typeOpt=="all":
if len(self.longOpt) == 0:
for par in self.data:
if optionsChapters and\
self.getTypeChapter(par['helpChapter'])=="options":
#print par["longOption"]
if not (par['helpChapter'] in optionsChapters):
continue
if par.has_key("longOption") and self.access(par):
if par.has_key("optVal"):
self.longOpt.append(par["longOption"]+'=')
else:
self.longOpt.append(par["longOption"])
if typeOpt=="short":
return "".join(self.shortOpt)
elif typeOpt=="long":
return self.longOpt
elif typeOpt=="all":
return ("".join(self.shortOpt),self.longOpt)
def getShortOpt(self,option):
"""Из любой опции получить короткую опцию.
Фильтрация также происходит и по названию команды.
Параметры:
option запрашиваемая опция
Возвращаемые параметры:
короткая опция, если же для длинной опции нет короткой, возвращается
пустая строка.
"""
# Из любой опции получаем короткую опцию
for par in self.data:
if par.has_key("shortOption") and self.access(par):
if (par.has_key("longOption") and\
par["longOption"] == option) or \
par["shortOption"] == option:
return par["shortOption"]
return ""

@ -1,40 +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 sys
from cl_utils import removeDir
from cl_print import color_print
import cl_lang
tr = cl_lang.lang()
tr.setLocalDomain('cl_lib')
tr.setLanguage(sys.modules[__name__])
class shareFile(color_print):
"""Общие методы для работы с файлами"""
def removeDir(self, rmDir):
"""Рекурсивное удаление директории
входной параметр директория или результат сканирования файлов (объект)
"""
try:
removeDir(rmDir)
except (OSError, Exception), e:
print e
self.printERROR(_("Can not delete dir: " ) + rmDir)
return False
return True

@ -13,7 +13,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os import os
import time import time

@ -21,7 +21,7 @@ def __findFileMO(domain, localedir=None, languages=None, all=0):
замена gettext.find""" замена gettext.find"""
if localedir is None: if localedir is None:
localedir = _default_localedir localedir = gettext._default_localedir
if languages is None: if languages is None:
languages = [] languages = []
for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'): for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):

File diff suppressed because it is too large Load Diff

@ -14,20 +14,30 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import subprocess
import string import string
from random import choice from random import choice
import os import os
import types import types
import stat import subprocess
def _toUNICODE(val): class _error:
"""перевод текста в юникод""" # Здесь ошибки, если они есть
if type(val) == types.UnicodeType: error = []
return val def getError(self):
else: """Выдать ошибки"""
return str(val).decode('UTF-8') if not self.error:
return False
error = ""
for e in self.error:
error += e + "\n"
return error
def setError(self, error):
"""Установка ошибки"""
self.error.append(error)
return True
def runOsCommand(cmd, inStr=None, ret_first=None, env_dict=None): def runOsCommand(cmd, inStr=None, ret_first=None, env_dict=None):
"""Выполняет внешнюю программу """Выполняет внешнюю программу
@ -65,21 +75,8 @@ def runOsCommand(cmd, inStr=None, ret_first=None, env_dict=None):
return retcode, res return retcode, res
return retcode, None return retcode, None
def getpathenv():
"""вернуть пути для запуска программ"""
bindir=['/sbin','/bin','/usr/sbin','/usr/bin']
env=os.environ
if env and env.has_key('PATH'):
lpath=env['PATH'].split(":")
npath=[]
for dirname in bindir:
if os.path.exists(dirname) and dirname not in lpath:
npath.append(dirname)
lpath=npath+lpath
return ":".join(lpath)
def genpassword(passlen=9): def genpassword(passlen=9):
'''Вернуть случайный пароль указанной длины '''Вернуть случайный пассворд указанной длины
Параметры: Параметры:
passlen длина пароля который нужно сгенерировать passlen длина пароля который нужно сгенерировать
@ -95,6 +92,18 @@ def fillstr(char, width):
'''Заполнить строку указанным числом символов. Псеводоним символ*кол-во''' '''Заполнить строку указанным числом символов. Псеводоним символ*кол-во'''
return str(char) * width return str(char) * width
def getpathenv():
"""Вернуть пути для запуска утилит"""
bindir=['/sbin','/bin','/usr/sbin','/usr/bin']
env=os.environ
if env and env.has_key('PATH'):
lpath=env['PATH'].split(":")
npath=[]
for dirname in bindir:
if os.path.exists(dirname) and dirname not in lpath:
npath.append(dirname)
lpath=npath+lpath
return ":".join(lpath)
def list2str(list): def list2str(list):
'''Функция переводит список в строку''' '''Функция переводит список в строку'''
@ -138,120 +147,9 @@ def convertStrListDict(val):
else: else:
return val return val
def getdirlist(s_path): def _toUNICODE(val):
"""Получить список директорий по указаному пути""" """перевод текста в юникод"""
return filter(lambda x: os.path.isdir(x), os.listdir(s_path)) if type(val) == types.UnicodeType:
return val
class _error: else:
# Здесь ошибки, если они есть return str(val).decode('UTF-8')
error = []
def getError(self):
"""Выдать ошибки"""
if not self.error:
return False
error = ""
for e in self.error:
error += e + "\n"
return error
def setError(self, error):
"""Установка ошибки"""
if not error in self.error:
self.error.append(error)
return True
class scan:
"""Класс для сканирования директорий"""
class _dir:
"""Класс для хранения директорий"""
def __init__(self):
# Базовая директория
self.baseDir = False
# Все директории в базовой включая вложенные
self.dirs = []
# Все файлы внутри базовой директории
self.files = []
# Все ссылки внутри базовой директории
self.links = []
# Все сокеты внутри базовой директории
self.sockets = []
def __scanDir(self, scanDir, dirObj, flagDir=False):
"""Сканирование одной директории"""
if flagDir or stat.S_ISDIR(os.lstat(scanDir)[stat.ST_MODE]):
for fileOrDir in os.listdir(scanDir):
absPath = os.path.join(scanDir,fileOrDir)
statInfo = os.lstat(absPath)[stat.ST_MODE]
if stat.S_ISDIR(statInfo):
dirObj.dirs.append(absPath)
self.__scanDir(absPath, dirObj, True)
elif stat.S_ISLNK(statInfo):
dest = absPath
src = os.readlink(absPath)
dirObj.links.append((src,dest))
elif stat.S_ISREG(statInfo):
dirObj.files.append(absPath)
elif stat.S_ISSOCK(statInfo):
dirObj.sockets.append(absPath)
return dirObj
def scanDirs(self, scanDirs):
"""Сканирование директорий на вход список
Выход список объктов _dirProf
"""
dirs = []
for scanDir in scanDirs:
dirP = scan._dir()
try:
self.__scanDir(scanDir, dirP)
except OSError, e:
print e.strerror, e.filename
return []
dirP.baseDir = scanDir
dirs.append(dirP)
return dirs
def removeDir(rmDir):
"""Рекурсивное удаление директории
входной параметр директория для удаления
Ошибки по except
"""
if not os.path.exists(rmDir):
raise Exception(_("Not found remove dir %s") %rmDir)
fileObj = scan()
# Сканируем директорию
scanObjs = fileObj.scanDirs([rmDir])
for socketRm in scanObjs[0].sockets:
# Удаляем сокеты
if os.path.exists(socketRm):
os.remove(socketRm)
for linkRm in scanObjs[0].links:
# Удаляем ссылки
os.unlink(linkRm[1])
for fileRm in scanObjs[0].files:
# Удаляем файлы
os.remove(fileRm)
scanObjs[0].dirs.sort(lambda x, y: cmp(len(y), len(x)))
for dirRm in scanObjs[0].dirs:
# Удаляем директории
os.rmdir(dirRm)
if os.path.exists(rmDir):
os.rmdir(rmDir)
return True
def getModeFile(nameFile):
"""Выдает информацию о файле
права файла, владелец, группа файла (777,test, group)
"""
fd = os.open(nameFile, os.O_RDONLY)
fst = os.fstat(fd)
uid = fst.st_uid
gid = fst.st_gid
mode = stat.S_IMODE(fst.st_mode)
os.close(fd)
return (mode,uid,gid)

@ -14,7 +14,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
#Допустимые ключи значений #Допустимые ключи значений
# mode - режим переменной r-не переназначается из командной строки, # mode - режим переменной r-не переназначается из командной строки,
# w-переназначается из командной строки # w-переназначается из командной строки
@ -55,13 +54,25 @@ class Data:
# названия используемых раскладок клавиатуры для X # названия используемых раскладок клавиатуры для X
os_locale_xkbname = {} os_locale_xkbname = {}
# keymap of locale (used for /etc/conf.d/keymaps)
os_locale_keymap = {}
# dumpkeys_charset for keymap
os_locale_dumpkeys = {}
# timezone for clock
os_clock_timezone = {}
# type of clock (UTC or local)
os_clock_type = {}
# архитектура компьютера (i686,x86_64) # архитектура компьютера (i686,x86_64)
os_arch_machine = {} os_arch_machine = {}
#проход при наложении шаблонов 1,2,3,4,5 и.т д #проход при наложении профилей 1,2,3,4,5 и.т д
cl_pass_step = {'mode':"w"} cl_pass_step = {'mode':"w"}
# обрабатываемый файл шаблона # обрабатываемый файл профиля
cl_pass_file = {'mode':"w"} cl_pass_file = {'mode':"w"}
# корневой раздел файловой системы # корневой раздел файловой системы
@ -76,14 +87,26 @@ class Data:
# постфикс к названию системы # постфикс к названию системы
os_linux_subname = {} os_linux_subname = {}
# motherboard model
hr_board_model = {}
# motherboard vendor
hr_board_vendor = {}
# processors count
hr_cpus = {}
# название виртуальной машины (virtualbox, vmware, qemu) # название виртуальной машины (virtualbox, vmware, qemu)
hr_virtual = {} hr_virtual = {}
# версия системы # версия системы
os_linux_ver = {} os_linux_ver = {}
# Тип шаблона # Тип профиля
cl_pass_type = {'mode':"w"} cl_pass_type = {'mode':"w"}
# Действие программы # Действие программы
cl_pass_run = {'mode':"w"} cl_pass_run = {'mode':"w"}
#Логин пользователя
ur_login = {'mode':"w"}

@ -215,4 +215,5 @@ class apache(bind):
if not areas: if not areas:
return docObj return docObj
self.createXML(areas, docObj.getNodeBody(), docObj) self.createXML(areas, docObj.getNodeBody(), docObj)
return docObj return docObj

@ -313,3 +313,5 @@ class bind(objShare):
"""Объединяем конфигурации""" """Объединяем конфигурации"""
if isinstance(bindObj, bind): if isinstance(bindObj, bind):
self.docObj.joinDoc(bindObj.doc) self.docObj.joinDoc(bindObj.doc)

@ -98,3 +98,5 @@ class dhcp(bind):
"""Объединяем конфигурации""" """Объединяем конфигурации"""
if isinstance(dhcpObj, dhcp): if isinstance(dhcpObj, dhcp):
self.docObj.joinDoc(dhcpObj.doc) self.docObj.joinDoc(dhcpObj.doc)

@ -62,4 +62,6 @@ class dovecot(bind):
self.docObj.joinDoc(dovecotObj.doc) self.docObj.joinDoc(dovecotObj.doc)
# Для добавления перевода строки перед закрывающим тегом # Для добавления перевода строки перед закрывающим тегом
# конфигурационного файла # конфигурационного файла
self.postXML() self.postXML()

@ -130,31 +130,10 @@ class kde(samba):
#print docObj.doc.toprettyxml() #print docObj.doc.toprettyxml()
return docObj return docObj
def postXML(self):
"""Последующая постобработка XML"""
# Для добавления перевода строки между областями если его нет
#print self.docObj.body.toprettyxml()
xmlAreas = xpath.Evaluate("child::area", self.docObj.body)
for xmlArea in xmlAreas:
if xmlArea.previousSibling and\
self.docObj.getTypeField(xmlArea.previousSibling) == "br":
continue
firstArea = False
xmlFields = xpath.Evaluate("child::field", xmlArea)
if not (xmlFields and\
(self.docObj.getTypeField(xmlFields[-1]) == "br" or\
self.docObj.getTypeField(xmlFields[-1]) == "comment")):
if xmlArea.nextSibling:
parentNode = xmlArea.parentNode
nextNode = xmlArea.nextSibling
parentNode.insertBefore(self.docObj.createField("br",
[],"",[],
False,False),
nextNode)
def join(self, kdeObj): def join(self, kdeObj):
"""Объединяем конфигурации""" """Объединяем конфигурации"""
if isinstance(kdeObj, kde): if isinstance(kdeObj, kde):
self.docObj.joinDoc(kdeObj.doc) self.docObj.joinDoc(kdeObj.doc)
self.postXML() self.postXML()

@ -181,3 +181,4 @@ class ldap(samba):
z += 1 z += 1
#print docObj.doc.toprettyxml() #print docObj.doc.toprettyxml()
return docObj return docObj

@ -446,6 +446,26 @@ class plasma(samba):
rootNode.appendChild(fieldXML) rootNode.appendChild(fieldXML)
#rootNode.appendChild(areaXML) #rootNode.appendChild(areaXML)
def createTxtConfig(self, strHeader, dictVar):
"""Cоздает область с заголовком
создает текст конфигурационного файла в формате samba из
заголовка (строка) и словаря переменных
"""
if not strHeader:
return ""
if type(strHeader) in (tuple, list):
outTxt = "".join(map(lambda x: "["+x+"]",strHeader))
if not outTxt:
return ""
outTxt += "\n"
else:
outTxt = "[" + strHeader + "]\n"
for key in dictVar.keys():
outTxt += "%s=%s\n" %(key,dictVar[key])
return outTxt
def _textToXML(self): def _textToXML(self):
"""Преобразуем текст в XML""" """Преобразуем текст в XML"""
areas = [] areas = []
@ -480,7 +500,7 @@ class plasma(samba):
elif len(quotes) == 1: elif len(quotes) == 1:
quotes.append("") quotes.append("")
return quotes return quotes
xmlAreas = xpath.Evaluate("descendant::area", self.docObj.body) xmlAreas = xpath.Evaluate("descendant::area", self.docObj.body)
#print "-------------------------------------------------------" #print "-------------------------------------------------------"
#print xmlAreas #print xmlAreas
@ -507,7 +527,7 @@ class plasma(samba):
parentNode.removeChild(xmlArea.nextSibling.nextSibling) parentNode.removeChild(xmlArea.nextSibling.nextSibling)
parentNode.removeChild(xmlArea.nextSibling) parentNode.removeChild(xmlArea.nextSibling)
continue continue
# Собираем поля в кучку # Собираем поля в кучку
xmlChildAreas = xpath.Evaluate("child::area", xmlArea) xmlChildAreas = xpath.Evaluate("child::area", xmlArea)
if xmlChildAreas: if xmlChildAreas:
@ -535,6 +555,15 @@ class plasma(samba):
"br": "br":
xmlArea.insertBefore(childNodes[it], xmlArea.insertBefore(childNodes[it],
firstChildArea) firstChildArea)
# Добавление перевода строк в если его нет между полями
if self.docObj.getTypeField(node) == "var" and\
node.previousSibling and\
not (self.docObj.getTypeField(node.previousSibling) in\
("br","comment")):
xmlArea.insertBefore(self.docObj.createField("br",
[],"",[],
False,False),
node)
# Добавляем BR если его нет первым полем # Добавляем BR если его нет первым полем
xmlFields = xpath.Evaluate("child::field", xmlArea) xmlFields = xpath.Evaluate("child::field", xmlArea)
@ -581,17 +610,10 @@ class plasma(samba):
parentNode = xmlArea.nextSibling.parentNode parentNode = xmlArea.nextSibling.parentNode
parentNode.removeChild(xmlArea.nextSibling) parentNode.removeChild(xmlArea.nextSibling)
#xmlName = xpath.Evaluate("child::caption/name", xmlArea)[0]
#print "------------------------------------"
#print "Name =", xmlName.firstChild
#if xmlArea.previousSibling:
#print "PR_TYPE =", self.docObj.getTypeField(xmlArea.previousSibling)
def join(self, kdeObj): def join(self, kdeObj):
"""Объединяем конфигурации""" """Объединяем конфигурации"""
if isinstance(kdeObj, plasma): if isinstance(kdeObj, plasma):
self.docObj.joinDoc(kdeObj.doc) self.docObj.joinDoc(kdeObj.doc)
self.postXML() self.postXML()

@ -115,3 +115,4 @@ class postfix(apache):
fields.append(field) fields.append(field)
field = fieldData() field = fieldData()
return fields return fields

@ -62,6 +62,21 @@ class samba(objShare):
[],"",[], [],"",[],
False,False), False,False),
nextNode) nextNode)
# Удаление лишних переводов строк
childNodes = self.docObj.getFieldsArea(self.docObj.body)
lenBr = 0
removeBrNodes = []
for node in childNodes:
if node.tagName == "field" and\
self.docObj.getTypeField(node) == "br":
lenBr += 1
if lenBr > 2:
removeBrNodes.append(node)
else:
lenBr = 0
# Удаление
for rmNode in removeBrNodes:
self.docObj.body.removeChild(rmNode)
def join(self, sambaObj): def join(self, sambaObj):
@ -258,4 +273,4 @@ class samba(objShare):
z += 1 z += 1
#print docObj.doc.toprettyxml() #print docObj.doc.toprettyxml()
return docObj return docObj

@ -84,3 +84,4 @@ class squid(procmail):
if isinstance(squidObj, squid): if isinstance(squidObj, squid):
#print squidObj.getConfig() #print squidObj.getConfig()
self.docObj.joinDoc(squidObj.doc) self.docObj.joinDoc(squidObj.doc)

@ -25,7 +25,6 @@ tr = lang()
tr.setLocalDomain('cl_lib') tr.setLocalDomain('cl_lib')
tr.setLanguage(sys.modules[__name__]) tr.setLanguage(sys.modules[__name__])
class xml_gconf(xml_xfce): class xml_gconf(xml_xfce):
"""Класс для объединения gconf-xml файлов""" """Класс для объединения gconf-xml файлов"""
# root нода # root нода
@ -42,6 +41,8 @@ class xml_gconf(xml_xfce):
_comment = ("<!--","-->") _comment = ("<!--","-->")
# поддерживаемые аттрибуты тега entry. Пример <entry type="int"/> # поддерживаемые аттрибуты тега entry. Пример <entry type="int"/>
supportEntryTypes = ("int", "bool", "float", "string", "list", "pair") supportEntryTypes = ("int", "bool", "float", "string", "list", "pair")
# регулярное выражения для поиска \t в начале строки (преобразование xml)
reStartTabs = re.compile("^(\t+)(.*)$")
def __init__(self, text): def __init__(self, text):
self.text = text self.text = text
@ -81,7 +82,8 @@ class xml_gconf(xml_xfce):
"""Сравнение содержимого двух списков XML нод""" """Сравнение содержимого двух списков XML нод"""
getTextsNodes = lambda y: map(lambda x:\ getTextsNodes = lambda y: map(lambda x:\
x.toxml().replace(" ","").replace("\t","").replace("\n",""), x.toxml().replace(" ","").replace("\t","").replace("\n",""),
map(lambda x: x.removeAttribute("mtime") or x, map(lambda x: x.hasAttribute("mtime") and\
x.removeAttribute("mtime") or x,
map(lambda x: x.cloneNode(True), map(lambda x: x.cloneNode(True),
filter(lambda x: x.nodeType==x.ELEMENT_NODE, y)))) filter(lambda x: x.nodeType==x.ELEMENT_NODE, y))))
if set(getTextsNodes(listXmlA))==set(getTextsNodes(listXmlB)): if set(getTextsNodes(listXmlA))==set(getTextsNodes(listXmlB)):
@ -103,13 +105,16 @@ class xml_gconf(xml_xfce):
nName = u'' nName = u''
nType = u'' nType = u''
nValue = u'' nValue = u''
nSchema = u''
attrName = '' attrName = ''
attrType = ''
if flagRootNode: if flagRootNode:
if not tagName == "gconf": if not tagName == "gconf":
self.setError(_("The text is not a valid gconf-XML format \ self.setError(_("The text is not a valid gconf-XML format \
(not found '<gconf>...</gconf>')")) (not found '<gconf>...</gconf>')"))
return False return False
flagType = False
flagValue = False
flagSchema = False
else: else:
if not tagName == "entry": if not tagName == "entry":
self.setError(_("The text is not a valid gconf-XML format \ self.setError(_("The text is not a valid gconf-XML format \
@ -118,20 +123,27 @@ class xml_gconf(xml_xfce):
if not n.hasAttribute("name"): if not n.hasAttribute("name"):
self.setError(_('Not found arrtibute "name" in tag entry')) self.setError(_('Not found arrtibute "name" in tag entry'))
return False return False
if not n.hasAttribute("type"): flagType = n.hasAttribute("type")
flagValue = False
flagSchema = n.hasAttribute("schema")
if flagSchema:
nSchema = n.getAttribute("schema")
if not flagType and not flagSchema:
self.setError(_('Not found arrtibute "type" in tag entry')) self.setError(_('Not found arrtibute "type" in tag entry'))
return False return False
nName = n.getAttribute("name") nName = n.getAttribute("name")
attrName = u"attribute::name='%s'"%nName attrName = u"attribute::name='%s'"%nName
nType = n.getAttribute("type") if flagType:
# Проверка правильности аттрибута type flagValue = n.hasAttribute("value")
if not nType in self.supportEntryTypes: nType = n.getAttribute("type")
self.setError(\ # Проверка правильности аттрибута type
_('Incorrect arrtibute "type" - <entry type="%s"/>')%nType) if not nType in self.supportEntryTypes:
return False self.setError(\
attrType = u"attribute::type='%s'"%nType _('Incorrect arrtibute "type" - <entry type="%s"/>')\
if n.hasAttribute("value"): %nType)
nValue = n.getAttribute("value") return False
if flagValue:
nValue = n.getAttribute("value")
if n.hasAttribute("action"): if n.hasAttribute("action"):
nAction = n.getAttribute("action") nAction = n.getAttribute("action")
if not nAction in ("join","replace","drop"): if not nAction in ("join","replace","drop"):
@ -142,13 +154,9 @@ Valid values attribute 'action': \
self.setError(textError) self.setError(textError)
return False return False
if xmlOldNode.parentNode: if xmlOldNode.parentNode:
findStr = u"child::%s"%tagName findAttrStr = ""
strAttr = [attrName, attrType] if attrName:
findAttr = filter(lambda x: x, strAttr) findAttrStr = "[%s]"%attrName
findAttrStr = ''
if findAttr:
strAttr = u' and '.join(findAttr)
findAttrStr = "[%s]"%strAttr
findPath = u"child::%s%s"%(tagName,findAttrStr) findPath = u"child::%s%s"%(tagName,findAttrStr)
# Рабочая нода # Рабочая нода
if flagRootNode: if flagRootNode:
@ -156,16 +164,19 @@ Valid values attribute 'action': \
else: else:
workNode = xmlOldNode workNode = xmlOldNode
oldNodes = xpath.Evaluate(findPath, workNode) oldNodes = xpath.Evaluate(findPath, workNode)
# Новая нода список # По умолчанию - объединение
flagArray = False
if nType == "list" or nType == "pair":
flagArray = True
flagDrop = False
flagJoin = True flagJoin = True
flagReplace = False flagReplace = False
flagDrop = False
# Замещаем ноду
if nType=="string" or nAction=="replace": if nType=="string" or nAction=="replace":
flagJoin = False flagJoin = False
flagReplace = True flagReplace = True
# Замещаем ноду в случае массива
elif nType == "list" or nType == "pair":
flagJoin = False
flagReplace = True
# Удаляем ноду
elif nAction == "drop": elif nAction == "drop":
flagJoin = False flagJoin = False
flagDrop = True flagDrop = True
@ -180,29 +191,34 @@ the same nodes at one level")
self.setError(textError) self.setError(textError)
return False return False
nextOldNode = oldNodes[0] nextOldNode = oldNodes[0]
# Замещаем ноду в случае массива
if flagArray and not flagDrop:
replaceXmlNode = xmlNode.cloneNode(True)
# Сравнение содержимого нод
if not self.cmpListsNodesEntry([replaceXmlNode],
[nextOldNode]):
replaceXmlNode.setAttribute("mtime",
self.currentTime)
if nAction:
replaceXmlNode.removeAttribute("action")
workNode.replaceChild(replaceXmlNode,
nextOldNode)
flagJoin = False
flagReplace = False
childNodes = False
# Объединение нод # Объединение нод
if flagJoin: if flagJoin:
if nextOldNode.hasAttribute("value"): if flagType and flagValue:
oValue = nextOldNode.getAttribute("value") flagChange = False
if nValue != oValue: foundValue = nextOldNode.hasAttribute("value")
if foundValue:
oValue = nextOldNode.getAttribute("value")
if nValue != oValue:
flagChange = True
else:
flagChange = True
if flagChange:
nextOldNode.setAttribute("mtime", nextOldNode.setAttribute("mtime",
self.currentTime) self.currentTime)
nextOldNode.setAttribute("value",nValue) nextOldNode.setAttribute("value",nValue)
elif flagSchema:
flagChange = False
foundValue = nextOldNode.hasAttribute("schema")
if foundValue:
oSchema = nextOldNode.getAttribute("schema")
if nSchema != oSchema:
flagChange = True
else:
flagChange = True
if flagChange:
nextOldNode.setAttribute("mtime",
self.currentTime)
nextOldNode.setAttribute("schema",nSchema)
# Замещение ноды # Замещение ноды
elif flagReplace: elif flagReplace:
replaceXmlNode = xmlNode.cloneNode(True) replaceXmlNode = xmlNode.cloneNode(True)
@ -252,11 +268,31 @@ the same nodes at one level")
self.joinDoc(xml_gconfObj.doc) self.joinDoc(xml_gconfObj.doc)
except: except:
self.setError(_("Can not join template")) self.setError(_("Can not join template"))
return False return False
return True return True
def getConfig(self): def getConfig(self):
"""Получение текстового файла из XML документа""" """Получение текстового файла из XML документа"""
def expandStartTabs(s):
if s.startswith("\t"):
res = self.reStartTabs.search(s)
return res.group(1).replace("\t"," ") + res.group(2)
else:
return s
data = self.doc.toprettyxml().split("\n") data = self.doc.toprettyxml().split("\n")
data = filter(lambda x: x.strip(), data) data = map(lambda x: expandStartTabs(x),
return "\n".join(data).replace("\t"," ") filter(lambda x: x.strip(), data))
dataOut = []
z = 0
lenData = len(data)
lenM2 = lenData - 2
for i in xrange(lenData):
if z>0:
z -= 1
continue
if i < lenM2 and data[i].endswith(">") and not "<" in data[i+1]:
dataOut.append(data[i] + data[i+1].strip() + data[i+2].strip())
z = 2
continue
dataOut.append(data[i])
return "\n".join(dataOut)

@ -158,7 +158,6 @@ Valid values attribute 'action': \
self.setError(textError) self.setError(textError)
return False return False
if xmlOldNode.parentNode: if xmlOldNode.parentNode:
findStr = u"child::%s"%path
strAttr = [attrName, attrType] strAttr = [attrName, attrType]
findAttr = filter(lambda x: x, strAttr) findAttr = filter(lambda x: x, strAttr)
findAttrStr = '' findAttrStr = ''
@ -266,3 +265,4 @@ the same nodes at one level")
data = self.doc.toprettyxml(encoding='UTF-8').split("\n") data = self.doc.toprettyxml(encoding='UTF-8').split("\n")
data = filter(lambda x: x.strip(), data) data = filter(lambda x: x.strip(), data)
return "\n".join(data).replace("\t"," ").decode("UTF-8") return "\n".join(data).replace("\t"," ").decode("UTF-8")

@ -43,7 +43,7 @@ class xml_xfcepanel(xml_xfce):
try: try:
self.doc = xml.dom.minidom.parseString(self.text) self.doc = xml.dom.minidom.parseString(self.text)
except: except:
self.setError(_("Can not text profile is XML")) self.setError(_("Can not text template is XML"))
return False return False
self.rootNode = self.doc.documentElement self.rootNode = self.doc.documentElement
self.bodyNode = self.rootNode self.bodyNode = self.rootNode
@ -54,7 +54,7 @@ class xml_xfcepanel(xml_xfce):
return True return True
def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0): def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0):
"""Объединение корневой ноды профиля и корневой ноды файла""" """Объединение корневой ноды шаблона и корневой ноды файла"""
xmlNode = xmlNewNode xmlNode = xmlNewNode
childNodes = xmlNode.childNodes childNodes = xmlNode.childNodes
nextOldNode = xmlOldNode nextOldNode = xmlOldNode
@ -80,14 +80,13 @@ class xml_xfcepanel(xml_xfce):
if n.hasAttribute("action"): if n.hasAttribute("action"):
nAction = n.getAttribute("action") nAction = n.getAttribute("action")
if not nAction in ("join","replace","drop"): if not nAction in ("join","replace","drop"):
textError = _('''In the text, XML profile, look \ textError = _('''In the text, XML template, look \
for a reserved attribute 'action' with the incorrect value.\n\ for a reserved attribute 'action' with the incorrect value.\n\
Valid values attribute 'action': \ Valid values attribute 'action': \
(action="join", action="replace", action="drop")''') (action="join", action="replace", action="drop")''')
self.setError(textError) self.setError(textError)
return False return False
if xmlOldNode.parentNode: if xmlOldNode.parentNode:
findStr = u"child::%s"%path
findAttrStr = "" findAttrStr = ""
if attrName: if attrName:
findAttrStr = "[%s]"%attrName findAttrStr = "[%s]"%attrName
@ -120,7 +119,7 @@ Valid values attribute 'action': \
self.panelNumbers[levelNumber] = 0 self.panelNumbers[levelNumber] = 0
if oldNodes: if oldNodes:
if len(oldNodes)>1 and path != "panel": if len(oldNodes)>1 and path != "panel":
textError = _("The uncertainty in this profile are \ textError = _("The uncertainty in this template are \
the same nodes at one level") the same nodes at one level")
self.setError(textError) self.setError(textError)
return False return False
@ -194,6 +193,7 @@ the same nodes at one level")
try: try:
self.joinDoc(xml_xfceObj.doc) self.joinDoc(xml_xfceObj.doc)
except: except:
self.setError(_("Can not join profile")) self.setError(_("Can not join template"))
return False return False
return True return True

@ -1,178 +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 sys
import os
import hashlib
import crypt
import string
import time
from random import choice
from base64 import urlsafe_b64encode as b64encode
from cl_print import color_print
from server.users import users
from server.utils import execProg
import cl_lang
# Перевод модуля
tr = cl_lang.lang()
tr.setLocalDomain('cl_lib')
tr.setLanguage(sys.modules[__name__])
class encrypt(color_print):
"""Класс хранения общих методов используемых для настройки сервисов
Методы шифрования, создания сертификатов и.т. д
"""
def __GenCryptSalt__(self):
"""Генерация соли для хеширования пароля (CRYPT)"""
chars = string.letters + string.digits + "./"
salt = ""
for i in range(2):
salt = salt + choice(chars)
return salt
def getHashPasswd(self, password, crypt):
"""Генерация хеша пароля,
Поддерживаемые алгоритмы шифрования пароля:
plain, md5, smd5, crypt, sha, ssha
"""
if not password:
self.printERROR(_("ERROR") + " getHashPasswd: " +\
_("password empty"))
return False
hashPwd = ""
if crypt == "plain":
hashPwd = password
elif crypt == "md5":
h = hashlib.md5(password)
hashPwd = "{MD5}" + b64encode(h.digest())
elif crypt == "smd5":
salt = os.urandom(4)
h = hashlib.md5(password)
h.update(salt)
hashPwd = "{SMD5}" + b64encode(h.digest() + salt)
elif crypt == "crypt":
salt = self.__GenCryptSalt__()
hashPwd = "{CRYPT}" + crypt.crypt(password, salt)
elif crypt == "sha":
h = hashlib.sha1(password)
hashPwd = "{SHA}" + b64encode(h.digest())
elif crypt == "ssha":
salt = os.urandom(4)
h = hashlib.sha1(password)
h.update(salt)
hashPwd = "{SSHA}" + b64encode(h.digest() + salt)
else:
self.printERROR(_("ERROR") + " getHashPasswd: " +\
_("Can not support '%s' crypto algoritm")%crypt)
return False
return hashPwd
def createCertificate(self, sslCountry="US",
sslState="California",
sslLocality="Santa Barbara",
sslOrganization="SSL Server",
sslUnit="For Testing Purposes Only",
sslCommonName="localhost",
sslEmail="root@localhost",
nsCertType="server",
sslDays=730,
sslBits=1024,
userName="root",groupName="root",
certFile="/tmp/server.pem",
certFileMode=0400,
keyFile="/tmp/server.key",
keyFileMode=0400):
"""Создает сертификат"""
certAndKeyFiles = [certFile, keyFile]
foundCertFiles = filter(lambda x: os.path.exists(x), certAndKeyFiles)
if len(foundCertFiles)==2:
return True
# Удаляем файл сертификата
map(lambda x: os.remove(x), foundCertFiles)
# Объект для работы с пользователями
usersObj = users()
# получаем id и gid пользователя
uidAndGid = usersObj.getUserUidAndGid(userName, groupName)
if not uidAndGid:
return False
uid, gid = uidAndGid
textCnf="""[ req ]
prompt = no
default_bits = %s
distinguished_name = req_dn
[ req_dn ]
C = %s
ST = %s
L = %s
O = %s
OU = %s
CN = %s
emailAddress = %s
[ cert_type ]
nsCertType = %s
"""%(sslBits, sslCountry, sslState, sslLocality, sslOrganization, sslUnit,
sslCommonName, sslEmail, nsCertType)
# генерируем название файла конфигурации
strData = time.strftime("%Y%m%d%H%M%S",time.localtime(time.time()))
cnfFile = "/tmp/%s.cnf" %strData
sslFile = "/usr/bin/openssl"
if not os.path.exists(sslFile):
self.printERROR(_("Can not found %s")%sslFile)
return False
# Cоздание директорий
for fileName in certAndKeyFiles:
dirName = os.path.split(fileName)[0]
if not os.path.exists(dirName):
self.createUserDir(0, 0, dirName, 0755)
# Создание конфигурационного файла
usersObj.createUserFile(cnfFile, textCnf, 0, 0, 0600)
# Создание сертификата
textLine = execProg(\
"%s req -new -x509 -nodes -config %s -days %s -out %s -keyout %s"\
%(sslFile, cnfFile, sslDays, certFile, keyFile))
# Удаление конфигурационного файла
if os.path.exists(cnfFile):
os.remove(cnfFile)
# Меняем права
if os.path.exists(certFile):
os.chown(certFile, uid,gid)
os.chmod(certFile, certFileMode)
if os.path.exists(keyFile):
os.chown(keyFile, uid,gid)
os.chmod(keyFile, keyFileMode)
if textLine == False:
self.printERROR(_("Can not create certificate %s")%certFile)
return False
# Проверка сертификата
textLine = execProg("%s x509 -subject -fingerprint -noout -in %s"\
%(sslFile, certFile))
if textLine == False:
self.printERROR(_("Can not create certificate %s")%certFile)
return False
return True

@ -104,7 +104,7 @@ class iniLdapParser(iniParser):
if not os.path.exists(pathIniFile): if not os.path.exists(pathIniFile):
os.makedirs(pathIniFile) os.makedirs(pathIniFile)
class ldap(_error, color_print, shareVars): class shareldap(_error, color_print, shareVars):
"""Общие методы для работы с LDAP для серверных программ""" """Общие методы для работы с LDAP для серверных программ"""
# DN сервисов относительно базового # DN сервисов относительно базового

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# setup.py --- Setup script for calculate-server # setup.py --- Setup script for calculate-lib
# Copyright 2008-2010 Mir Calculate Ltd. http://www.calculate-linux.org # Copyright 2008-2010 Mir Calculate Ltd. http://www.calculate-linux.org
# #
@ -30,7 +30,7 @@ setup(
url = "http://calculate-linux.org", url = "http://calculate-linux.org",
license = "http://www.apache.org/licenses/LICENSE-2.0", license = "http://www.apache.org/licenses/LICENSE-2.0",
package_dir = {'calculate-lib': "."}, package_dir = {'calculate-lib': "."},
packages = ['calculate-lib.pym','calculate-lib.pym.format'], packages = ['calculate-lib.pym'],
data_files = [("/usr/share/calculate/i18n",['i18n/cl_lib_ru.mo']), data_files = [("/usr/share/calculate/i18n",['i18n/cl_lib_ru.mo']),
("/var/calculate/remote",[])], ("/var/calculate/remote",[])],
) )

Loading…
Cancel
Save