0.0.1
asamoukin 16 years ago
parent d8cbdaef88
commit b27c7b2e78

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

@ -0,0 +1,15 @@
AUTHOR: Calculate Pack <support@calculate.ru>
INSTALL
-------
calculate-lib needs the following library version installed, in order to run:
Python >= 2.3
python-ldap >= 2.0.0
pyxml >= 0.8
calculate-lib >= 0.0.1
To install calculate-lib , just execute the install script 'setup.py'.
Example:
./setup.py install

Binary file not shown.

@ -0,0 +1,943 @@
#-*- coding: utf-8 -*-
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
# 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 gettext
import os
import getopt
import sys
##############################################################################
import re
import copy
import types
import string
#import os
import filecmp
import ConfigParser
import time
import socket
#import sys
import random
import string
import cl_utils
import cl_devices
import imp
##############################################################################
_expand_lang = gettext._expand_lang
def __findFileMO(domain, localedir=None, languages=None, all=0):
# Модифицинрованный метод модуля gettext ищет файл перевода
if localedir is None:
localedir = _default_localedir
if languages is None:
languages = []
for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
val = os.environ.get(envar)
if val:
languages = val.split(':')
break
if 'C' not in languages:
languages.append('C')
# now normalize and expand the languages
nelangs = []
for lang in languages:
for nelang in _expand_lang(lang):
if nelang not in nelangs:
nelangs.append(nelang)
# select a language
if all:
result = []
else:
result = None
for lang in nelangs:
if lang == 'C':
break
mofile = os.path.join(localedir, '%s_%s.mo' % (domain,lang))
if os.path.exists(mofile):
if all:
result.append(mofile)
else:
return mofile
return result
gettext.find = __findFileMO
class GlobalParam(type):
""" Метакласс для глобальных параметров
"""
def __init__(cls, *args):
cls.GP = []
cls.GP.append("")
class lang:
"""Класс многоязыковой поддержки lang для перевода сообщений программ на
другие языки.
Типичное использование:
import sys
import lang
# язык сообщений английский
tr = lang.lang(en)
# язык определяется системой
#tr = lang.lang()
#Установка домена переводаldap
# в последующем можно не использовать - задается глобально
tr.setGlobalDomain('calc')
# задается локально для одного файла
#tr.setLocalDomain('calc')
# Установка метода перевода для текущего модуля
tr.setLanguage(sys.modules[__name__])
Где:
tr -- объект перевода
'en' -- язык выводимых сообщений
sys.modules[__name__] -- модуль сообщения которого переводятся
calc - домен перевода - имя файла перевода без расширения
Если файл перевода не найден то сообщения не переводятся
Если в модуле сообщения которого переводим, экспортируются другие модули то
они тоже переводятся.
По умолчанию директория в которой находятся переводы: 'lang/i18h' относительно
исполняемого файла названия файлов перевода совпадают с названиями модулей
если не определен методом setDomainTranslate() - домен перевода.
"""
__metaclass__ = GlobalParam
def __init__(self,l=''):
self.nameDomain = self.GP[0]
#self.nameDomain = ''
""" Название файла перевода (Домен) если используется 1 файл перевода
"""
self.__catalog = os.path.abspath('/usr/share/calculate/i18n')
""" Путь к каталогу переводов (в этом каталоге
ru_RU/LC_MESSAGES в котором файл перевода)
"""
env = os.environ
if l == "" and env.has_key('LANG'):
l = env['LANG'].split('.')[0].split("_")[0]
""" Определение языка """
self.__modnames = {}
""" Словарь переведенных модулей
ключ --- имя модуля
значение --- был ли модуль переведен (1 или 0)
"""
self.__l = l
"""Язык перевода для всех модулей"""
def __translate(self,message):
"""Метод translate возвращает полученное значение без
изменений"""
return message
def setLanguage(self,module):
""" Установка языка перевода для модуля module.
параметр --- экспортируемый модуль python
если в этом модуле экспортируются другие модули
то язык устанавливается и для них
Метод запускается после экспорта модуля который будем переводить
"""
t = vars(module)
for i in dir(module):
q = str(t[i])
if 'module' in q and not '__' in i and not '/usr/lib' in q\
and not 'built-in' in q :
mod = vars(module)[i]
self.__setLang(mod)
return self.__setLang(module)
def __setLang(self,module):
""" Установка языка перевода для модуля module.
В случае нахождения файла перевода возвращает истину.
Во всех случаях устанавливает метод перевода для модуля.
Если нет файла перевода метод перевода возвращает то же
значение что получает
"""
if module.__name__ in self.__modnames.keys():
return True
if self.nameDomain == '':
if module.__name__ == "__main__":
nameDomain = module.__file__.split('.')[0]
else:
nameDomain = module.__name__
else:
nameDomain = self.nameDomain
if self.__l == 'en':
module._ = self.__translate
ret = 1
else:
la = []
la.append(self.__l)
if gettext.find(nameDomain,self.__catalog,la):
"""Если найден словарь то инициализируем переводчик"""
transl = gettext.translation(nameDomain\
,self.__catalog,la)
#module._ = transl.ugettext
module._ = transl.gettext
ret = 1
else:
module._ = self.__translate
ret = 0
self.__modnames[module.__name__] = ret
return ret
def getTranslatorByName(self,namemodule):
""" Метод который по имени модуля определяет, был ли модуль с этим
именем переведен
"""
if self.__modnames.has_key(namemodule):
return self.__modnames[namemodule]
return 0
def setGlobalDomain(self, nameDomain):
""" Метод для установки домена перевода (глобально для всех файлов)
"""
self.GP[0] = nameDomain
self.nameDomain = self.GP[0]
return True
def setLocalDomain(self, nameDomain):
""" Метод для установки домена перевода (локально для одного файла)
"""
self.nameDomain = nameDomain
return True
##############################################################################
# Перевод модуля на другой язык
tr = lang()
tr.setLocalDomain('cl_lib')
tr.setLanguage(sys.modules[__name__])
##############################################################################
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
###############################################################################
import cl_profile
class iniParser(cl_profile._error):
"""Класс для работы с ini файлами
"""
def __init__(self, iniFile):
# название ini файла
self.iniFile = iniFile
# права создаваемого ini-файла
self.mode = 0644
# Cоответствует ли формат файла нужному
self.checkIni = None
def setMode(self, mode):
"""установка прав создаваемого ini-файла"""
self.mode = mode
def openIniFile(self):
if not os.path.exists(self.iniFile):
return ""
FD = open(self.iniFile, "r")
textIni = FD.read()
FD.close()
return textIni
def writeIniFile(self, txtConfig):
if not os.path.exists(self.iniFile):
fd = os.open(self.iniFile, os.O_CREAT)
os.close(fd)
os.chmod(self.iniFile, self.mode)
if not os.path.exists(self.iniFile):
self.setError(_("Unable to create file") + ": " + self.iniFile)
return False
FD = open(self.iniFile, "r+")
FD.truncate(0)
FD.seek(0)
FD.write(txtConfig)
FD.close()
def setVar(self, strHeader, dictVar):
"""Заменяет или добавляет область и переменные
Добавляет область в ini-файл или объединяет с существующей
strHeader - имя области
dictVar - словарь переменных
"""
textIni = self.openIniFile()
if not self.checkIniFile(textIni):
return False
# создаем объект типа samba и записываем в него содержимое ini-файла
objIni = cl_profile.samba(textIni)
# создаем текст в формате samba из строки заголовка и
# словаря переменных области
txtConfig = objIni.createTxtConfig(strHeader, dictVar)
# создаем объект типа samba и записываем в него текст
objIniAdd = cl_profile.samba(txtConfig)
# объединяем объекты для получения результирующего текста
objIni.join(objIniAdd)
# получаем текст
txtConfig = objIni.getConfig().encode("UTF-8")
# записываем его в ini файл
self.writeIniFile(txtConfig)
return True
def isEmptyFile(self, textIni):
"""Является ли файл пустым"""
if not textIni.strip():
return True
else:
return False
def checkIniFile(self, textIni):
"""Проверка на правильность формата файла"""
if self.checkIni == None:
# Ошибка
if textIni == False:
self.checkIni = False
return False
self.checkIni = True
# В файле есть данные
if not self.isEmptyFile(textIni):
objIni = cl_profile.samba(textIni)
xmlBody = objIni.docObj.getNodeBody()
if not xmlBody.firstChild:
self.checkIni = False
return self.checkIni
def delVar(self, strHeader, nameVar):
"""Удаляем переменную из ini файла"""
delNameVar = "!%s" %(nameVar)
dictVar = {delNameVar:"del"}
res = self.setVar(strHeader, dictVar)
return res
def delArea(self, strHeader):
"""Удаляем область из ini файла"""
delStrHeader = "!%s" %(strHeader)
dictVar = {"del":"del"}
res = self.setVar(delStrHeader, dictVar)
return res
def getVar(self, strHeader, nameVar):
"""Получаем значение переменной из ini-файла"""
textIni = self.openIniFile()
if not self.checkIniFile(textIni):
return False
# создаем объект типа samba и записываем в него содержимое ini-файла
objIni = cl_profile.samba(textIni)
# получаем ноду body
xmlBody = objIni.docObj.getNodeBody()
# находим в области переменную
res = objIni.docObj.getAreaFieldValues(strHeader, nameVar, xmlBody)
if res == False:
return None
else:
return res
def getAreaVars(self,strHeader):
"""Получаем все переменнные области из ini-файла"""
textIni = self.openIniFile()
if not self.checkIniFile(textIni):
return False
# создаем объект типа samba и записываем в него содержимое ini-файла
objIni = cl_profile.samba(textIni)
# получаем ноду body
xmlBody = objIni.docObj.getNodeBody()
# если находим область то выдаем словарем все переменные иначе False
res = objIni.docObj.getAreaFields(strHeader, xmlBody)
if res == False:
return {}
else:
return res
def getAllSectionNames(self):
"""Получаем все имена секций определенных в ini файле"""
textIni = self.openIniFile()
if not self.checkIniFile(textIni):
return False
# создаем объект типа samba и записываем в него содержимое ini-файла
objIni = cl_profile.samba(textIni)
# получаем ноду body
xmlBody = objIni.docObj.getNodeBody()
xmlNodes = objIni.docObj.getFieldsArea(xmlBody)
# Имена секций ini файла
namesSection = []
for xmlNode in xmlNodes:
if xmlNode.tagName == "area":
nSect = objIni.docObj.getNameArea(xmlNode)
if nSect:
namesSection.append(nSect)
return namesSection
##############################################################################
class var:
'''Объект "Переменная окружения"'''
# название сервиса которому принадлежит переменная
#(Global, Builder, Client, Server итд)
service = None
# значение переменной
value = None
# режим записи (атрибут 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 self.value == None:
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):
# добавляем пути к модулям если они не добавлены
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():
print _("Unsupported section %s")%section
exit(1)
modVar = self.__modlist[section][0]
modFill = self.__modlist[section][1]
# Импортируем класс описания переменных и класс заполнения
try:
exec ("import %s" % (modVar))
except ImportError, e:
print _("Error in import module %s")%modVar
print _("error") + ": " +str(e)
exit(1)
flagFindFillModule = True
try:
exec ("import %s" % (modFill))
except ImportError, e:
if "No module named" in str(e):
flagFindFillModule = False
else:
print _("Error in import module %s")%modFill
print _("error") + ": " +str(e)
exit(1)
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:
print _("Not found variable %s")%nameVar
if e:
print _("error") + ": " +str(e)
exit(1)
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)):
print _("error initalize variable %s, incorrect data")%nameVar
exit(1)
for nameAttr in dict.keys():
setattr(var,nameAttr, dict[nameAttr])
return True
def __Get(self, nameVar):
ret = None
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()
else:
ret = None
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():
#print name
for nameLink in links[name].keys():
val = self.__getattribute__(nameLink).Get()
self.__getattribute__(name).dependValues[nameLink] = val
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] = None
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):
'''Записать значение в calculate.ini
Параметры:
vname имя переменной
val значение переменной
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]
try:
# проверяем чтобы путь до ини файла существовал
if not os.path.exists(onlydir):
# создаем его если отсутствует
os.makedirs(onlydir)
except OSError (nerr,msg):
print nerr, msg
return False
config = iniParser(name_calculate_ini)
# Получаем секцию конфигурационного файла
header = self.__getSection(vname)
return config.setVar(header,{vname: cl_utils.convertStrListDict(val)})
def Write(self, vname, val, force=False, location='default'):
'''Установить и записать значение переменной в ini файл
Параметры:
vname имя переменной
val значение переменной
force "принудительный режим"
location расположение ini файла ('default', 'local', 'remote')
'''
if self.__Set(vname, val, force):
self.__writeVarValue(vname, val, location)
return True
return False
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):
'''Заместить значение переменных значениями из ини файла
Возвращаемые значения:
True переменные считаны
False файл не был обнаружен
'''
calculate_ini = self.__getPathCalculateIni()
# активные секции (секции из которых будут использованы переменные)
act_section = self.__getActiveSections()
set_act_section = set(act_section)
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)
# получаем все переменные из всех секций
for section in act_sect:
allvars = config.getAreaVars(section)
#allvars = config.getAreaVars(self.__getCurrentHeaderName())
if allvars == False:
return False
# принудительно переписать все переменные окружения
# полученные из ini
for (k,v) in allvars.items():
k = k.encode("UTF-8")
v = v.encode("UTF-8")
self.Set(k, cl_utils.convertStrListDict(v), True)
return True
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 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
cl_utils.columnWrite( i, mlen_name, var[i].mode.lower(),
mlen_mode,
#str(var[i].type),
#mlen_type,
p_val)
print br
##############################################################################
class glob_attr:
"""Глобальные аттрибуты для методов заполнения переменных"""
path_env = cl_utils.getpathenv()
def _runos(self,cmd,ret_first=None):
"""Вернуть результат выполнения команды ОС"""
return cl_utils.runOsCommand(cmd, None, ret_first)

@ -0,0 +1,66 @@
#-*- coding: utf-8 -*-
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
# 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 re
import glob
import cl_utils
#класс для работы с видео устройствами
class Video:
#получить список видеокарт
def getcards(self):
card_names=[]
g_path=cl_utils.getpathenv()
s_cmd='%s lspci | grep VGA' % g_path
lines=os.popen(s_cmd).readlines()
if lines:
for line in lines:
re_res=re.search(\
'[0-9\:\.]+\sVGA compatible controller:(.+)$',line)
if re_res:
card_names.append(re_res.group(1))
if len(card_names)>0:
return card_names
else:
return None
#работа с блочными устройствами
class block_dev:
_dev_list=[]
def __init__(self):
self._getlist()
def _getlist(self):
devlist=[]
for dev in ('sd','hd'):
devlist+=glob.glob('/sys/block/%s*'%dev)
for dev in devlist:
self._dev_list.append(dev.split('/')[-1])
#получить список устройств
def get_listdev(self):
return self._dev_list
#проверить на извлекаемое устройство
def isremovable(self, dev):
if dev in self.get_listdev():
res=int(open('/sys/block/%s/removable'%dev).read().split()[0])
return res
else:
return None

@ -0,0 +1,127 @@
#-*- coding: utf-8 -*-
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
# 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 re
import os
import cl_utils
import cl_base
class fillVars(object, cl_base.glob_attr):
def get_os_net_domain(self):
''' Определим домен'''
domain=self._runos("%s hostname -d 2>&1"%self.path_env)
if re.search("^hostname: ",domain):
return "local"
else:
return domain
def get_os_linux_shortname(self):
'''Получить переменную короткого названия системы'''
path = '/etc/issue'
sp="""Welcome to \\\\n.\\\\O \(([a-zA-Z ]+) ([^\s\)]+)"""
res=self._runos('%scat %s | grep "Welcome to "'%\
(self.path_env, path))
dist_ver = {'CLD':"Calculate Linux Desktop",
'CDS':"Calculate Directory Server",
'AcoolA':"Calculate Web Server"}
if res:
if re.search(sp,res):
vals=re.search(sp,res).groups()
issuename=vals[0]
for i in dist_ver.keys():
if dist_ver[i]==issuename:
return i
spl=issuename.split(" ")
nname=""
if len(spl)>1:
for i in spl:
nname+=i[1]
return nname
else:
return issuename
return "CLD"
def get_os_net_hostname(self):
'''Считать имя компьютера net_host'''
hostname=self._runos("""%s hostname -s 2>&1"""%self.path_env)
#Set('net_host',hostname, True)
#упрощенный вариант, следует выполнять только если не указан домен
#в системе
if re.search("^hostname: ",hostname):
hostname=self._runos("""%s hostname 2>&1"""%self.path_env)
if re.search("^hostname: ",hostname):
return self.Get('os_linux_shortname')
else:
if hostname=='livecd':
return self.Get('os_linux_shortname')
return hostname
# Разрешенные сети (в данном случае все сети)
def get_os_net_allow(self):
"""Разрешенные сети"""
net={'255.255.0.0':'/16',
'255.255.255.0':'/24',
'255.255.255.128':'/25',
'255.255.255.252':'/30',
'255.255.255.255':''}
networks=""
netInterfaces=cl_utils.getdirlist("/sys/class/net/")
for i in netInterfaces:
res=self._runos("/sbin/ifconfig %s"%i)
for j in res:
s_ip=re.search('addr:([0-9\.]+).+Bcast:.+Mask:([0-9\.]+)'\
,j)
if s_ip:
ip, netmask=s_ip.groups()
ip=ip.split('.');
if ip[0]=='10' or\
(ip[0]=='172' and int(ip[1])>=16 and int(ip[1])<=31)or\
(ip[0]=='192' and ip[1]=='168'):
if netmask=='255.255.255.255':
networks+=ip+" "
elif netmask=='255.255.255.252':
networks+=ip[0]+"."+ip[1]+"."+ip[2]+"."+"252"+\
net[netmask]
elif netmask=='255.255.255.128':
networks+=ip[0]+"."+ip[1]+"."+ip[2]+"."+"128"+\
net[netmask]
elif netmask=='255.255.255.0':
networks+=ip[0]+"."+ip[1]+"."+ip[2]+"."+"0"+\
net[netmask]
elif netmask=='255.255.0.0':
networks+=ip[0]+"."+ip[1]+".0.0"+net[netmask]
return 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]
def get_os_locale_language(self):
"""язык (прим: ru)"""
lang = self.Get("os_locale_lang")
if lang:
return lang.split("_")[0]

File diff suppressed because it is too large Load Diff

@ -0,0 +1,501 @@
#-*- coding: utf-8 -*-
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
# 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 filecmp
import string
from random import choice
from re import search, compile, S
import os
import types
import popen2
import types
def getdirlist(s_path):
#Получить список директорий по указаному пути
fdir=filecmp.dircmp(s_path, s_path)
dir_list=fdir.common_dirs
return dir_list
def prettyColumnStr(*cols):
'''Функция преобразования строк в текстовые колонки. Если указанный текст
не помещается в колонку, то строка переносится на следующую этой же колонки
перенос текста идет по словам, и текст выравнивается по ширине колонки за
счет дополнительных пробелов между словами. Если в строке используется
перенос строки, то текст переносится не просто на следующую строку, а также
на следующую строку колонки, причем если используется \r текст выравнива-
ется по ширине, а если \n, то просто перевод строки.
Параметры:
cols множестово пар: текст, ширина колонки, причем, если у последней
колонки не указывать ширину, то она будет выведена вся.
Возвращаемые параметры:
строка, которую можно использовать для вывода на экран
Пример: columnWrite( "Some text", 10, "Next column", 20 )
'''
# шаблон поиска переводов строк
wherenr = compile( '[\n\r]', S )
retstr = ""
# перевести кортеж в список, т.к. изменяется
cols = list(cols)
# перевести текст в юникод, заодно перевести числа в строку
noconvert = False
space = u' '
nospace = u''
for i in xrange(0,len(cols),2):
cols[i] = _toUNICODE(cols[i])
# флаг "есть еще текст для вывода"
repeat = True
while repeat:
# сбросить итератор на первый элемент
q = 0
repeat = False
# пока не закончили перебирать параметры (перебираем по парам)
while q < len(cols):
# если это последний параметр, и для него не указана ширина
if q == len(cols)-1:
# выводим его полностью не смотря на ширину окна
retstr += cols[q] + " "
cols[q] = ''
else:
# вывести часть строки не больше указанной ширины колонки
partstr = cols[q][:cols[q+1]]
# искать перевод строки с полученной части
brfind = wherenr.search(partstr)
# если это не последняя колонка
if q + 2 < len(cols):
# добавить разделитель между колонками
cellspacing = space
else:
# разделитель не нужен
cellspacing = nospace
# если перевод строки найден, то
if brfind != None:
# для текущего вывода в колонку
# берем часть строки до перевода
partstr = partstr[:brfind.start()]
# остальная часть идет в остаток (без перевода)
cols[q] = cols[q][brfind.start()+1:]
# # если используется перевод каретки
# if brfind.group() == '\r':
# # то выравниваем по ширине колонки
# partstr = partstr.ljust(cols[q+1], ' ')
# else:
# # добавить отступы чтобы закончить колонку
partstr = partstr.ljust(cols[q+1], ' ')
# если взята часть строки
elif len(partstr) == cols[q+1] and partstr != cols[q]:
# если взята часть строки (разрыв в слове)
if cols[q][cols[q+1]] != ' ':
# ищем ближайший пробел справа
spacepos = partstr.rfind(' ')
# если пробел найти не удалось
if spacepos == -1:
# то на вывод идет часть строки равной ширине
cols[q] = cols[q][cols[q+1]:]
# если пробел найден
else:
# обрезаем строку до найденного пробела
partstr = partstr[:spacepos]
cols[q] = cols[q][spacepos+1:]
# если взята часть строки (разрыв на пробеле)
else:
# ислючить переносной пробел
cols[q] = cols[q][cols[q+1]+1:]
# выровнить текст по ширине колонки
partstr = partstr.ljust(cols[q+1], ' ')
#partstr = justify(partstr, cols[q+1])
# остатки строки
else:
# добавить отступы чтобы закончить колонку
partstr = partstr.ljust(cols[q+1], ' ')
cols[q] = ''
retstr+= partstr + cellspacing
# остальную часть строки оставить на следующую итерацию
# если от строки что то осаталось
if len(cols[q]) > 0:
# отметить запуск еще одной итерации по параметрам
repeat = True
# следующая пара
q += 2
# колонки отображены
retstr += "\n"
return retstr.encode('utf8')
def columnStr(*cols):
'''Вывод данных по колонкам, причем, если данные не вмещаются в указнаную
колонку, то они переносятся на следующую строку в нужную колонку. В строку.
Параметры:
cols множестово пар: текст, ширина колонки, причем, если у последней
колонки не указывать ширину, то она будет выведена вся.
Возвращаемые параметры:
строка, которую можно использовать для вывода на экран
Пример: columnWrite( "Some text", 10, "Next column", 20 )
'''
retstr = ""
# перевести кортеж в список, т.к. изменяется
cols = list(cols)
# перевести текст в юникод, заодно перевести числа в строку
for i in xrange(0,len(cols),2):
cols[i] = (str(cols[i])).decode('utf8')
# флаг "есть еще текст для вывода"
repeat = True
while repeat:
# сбросить итератор на первый элемент
q = 0
repeat = False
# пока не закончили перебирать параметры (перебираем по парам)
while q < len(cols):
# если это последний параметр, и для него не указана ширина
if q == len(cols)-1:
# выводим его полностью не смотря на ширину окна
retstr += cols[q] + " "
cols[q] = ''
else:
# вывести часть строки не больше указанной ширины колонки
retstr+=(cols[q][:cols[q+1]].ljust(cols[q+1])).encode('utf8') \
+ " "
# остальную часть строки оставить на следующую итерацию
cols[q] = cols[q][cols[q+1]:]
# если от строки что то осаталось
if len(cols[q]) > 0:
# отметить запуск еще одной итерации по параметрам
repeat = True
# следующая пара
q += 2
# колонки отображены
retstr += "\n"
return retstr
def columnWrite(*cols):
'''Вывод данных по колонкам, причем, если данные не вмещаются в указнаную
колонку, то они переносятся на следующую строку в нужную колонку.
Параметры:
cols множестово пар: текст, ширина колонки, причем, если у последней
колонки не указывать ширину, то она будет выведена вся.
Пример: columnWrite( "Some text", 10, "Next column", 20 )
'''
# перевести кортеж в список, т.к. изменяется
cols = list(cols)
# перевести текст в юникод, заодно перевести числа в строку
for i in xrange(0,len(cols),2):
cols[i] = (str(cols[i])).decode('utf8')
# флаг "есть еще текст для вывода"
repeat = True
while repeat:
# сбросить итератор на первый элемент
q = 0
repeat = False
# пока не закончили перебирать параметры (перебираем по парам)
while q < len(cols):
# если это последний параметр, и для него не указана ширина
if q == len(cols)-1:
# выводим его полностью не смотря на ширину окна
print cols[q],
cols[q] = ''
else:
# вывести часть строки не больше указанной ширины колонки
print (cols[q][:cols[q+1]].ljust(cols[q+1])).encode('utf8'),
# остальную часть строки оставить на следующую итерацию
cols[q] = cols[q][cols[q+1]:]
# если от строки что то осаталось
if len(cols[q]) > 0:
# отметить запуск еще одной итерации по параметрам
repeat = True
# следующая пара
q += 2
# колонки отображены
print
def justify(s,width):
'''Выровнить текст по ширине
Параметры:
s выводимая строка
width ширина на которую надо выровнить строку
Возвращаямые параметры:
Выровненная строка
'''
# если подана строка без пробелов - прекратить обработку
if s.find(' ') == -1:
return s
pos = 0
# переводим в юникод для правильного вычисления длины
try:
s = s.decode( 'utf-8' )
# пропуск если это не utf-8
except UnicodeEncodeError:
pass
# пока длина строки меньше указанной
while len(s) < width:
# находим очередной пробел
pos = s.find( ' ', pos )
# если не найден искать сначала
if pos == -1:
pos = s.find(' ')
# вставить в позицию еще один пробел
s = s[:pos] +' ' +s[pos:]
# оставить удвоенный пробел
pos += 3
# вернуть строку в utf8 если она пришла в utf8
return s.encode('utf-8')
def runOsCommand(cmd, inStr=None, ret_first=None):
"""Выполняет внешнюю программу
Параметры:
cmdStrProg внешняя программа
inStr данные передаваемые программе на страндартный вход.
ret_first вернуть только первую строку
Возвращаемые параметры:
строка/строки которую выведет внешняя программа
"""
fout, fin = popen2.popen4(cmd)
# если есть данные на вход, передать их
if inStr:
fin.write(inStr)
fin.close()
res = fout.readlines()
fout.close()
if res:
if len(res) > 1:
if ret_first:
return res[0]
else:
return res
else:
return res[0].strip()
def genpassword(passlen=9):
'''Вернуть случайный пассворд указанной длины
Параметры:
passlen длина пароля который нужно сгенерировать
Возвращаемые параметры:
Сгенерированный пароль указанной длины
'''
res=''.join([choice(string.ascii_letters+string.digits)\
for i in xrange(passlen)])
return res
def fillstr(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 "PATH="+":".join(lpath)+" && "
#класс для работы с установленными пакетами
class pakages:
#путь к директории установленнх пакетов
pkgdir="/var/db/pkg/"
#список установленных пакетов
pkglist={}
#Объект содержащий параметры пакета
class pakage(object):
#имя пакета с версией
fullname=""
#имя пакета
name=""
#версия
ver=""
#тип пакета в портижах
portdir=""
def __init__(self, **args):
for atname,atvalue in args.items():
setattr(self,atname, atvalue)
def __init__(self):
self.pkglist=self.__getpkglist()
#разбить имя пакета на тип и имя
def __getpkgver(self, fname):
res=search('^(.+)\-([0-9]+.*)$',fname)
if res:
return res.groups()
else:
return (None,None)
#собрать установленные в системе пакеты
def __getpkglist(self):
portageDirs=[]
instaledPkg={}
#проверим на существование директории с установленными пакетами
if os.path.exists(self.pkgdir):
#получим список типов пакетов
portageDirs=getdirlist(self.pkgdir)
if len(portageDirs)>0:
#обрабатываем содержимое каждого из типов
for portageDir in portageDirs:
pkgList=getdirlist(self.pkgdir+portageDir)
for pkg in pkgList:
fullname=pkg
pkgName,pkgVer= self.__getpkgver(pkg)
pobj=self.pakage(fullname=fullname,
name=pkgName, \
ver=pkgVer,\
portdir=portageDir)
fpkg=portageDir+"/"+pkgName
if instaledPkg.has_key(fpkg):
instaledPkg[fpkg].append(pobj)
else:
instaledPkg[fpkg]=[pobj]
return instaledPkg
#разбить pkgname на составляющие имени пакета
def __partname(self, pkgname):
if not pkgname.strip():
return False
res=search('^(.+\/)?(.+)',pkgname)
tname=None
if res.group(1):
tname=res.group(1)
if res.group(2):
res2=search('^(.+)(\-[0-9]+.+$)',res.group(2))
if res2:
name=res2.group(1)
ver=res2.group(2)
else:
name=res.group(2)
ver=None
if res:
if name and name[-1:]=='-':
name=name[:-1]
if tname and tname[-1:]=='/':
tname=tname[:-1]
if ver and ver[0]=='-':
ver=ver[1:]
return [tname, name, ver]
#проверить установленн ли пакет
#isinstalled('dev-db/postgresql')
def isinstalled(self, pkgname):
res=self.getinstpkg(pkgname)
if len(res)>0:
return True
else:
return False
#вернуть список объектов pakage() соответствующих pkgname
#getinstpkg('dev-db/postgresql')
#в случае отсутствия пакетов возвращает пустой список
def getinstpkg(self, pkgname):
pinfo=self.__partname(pkgname)
if pinfo:
ret=[]
if pinfo[0] and pinfo[1] and pinfo[2]:
if not self.pkglist.has_key(pinfo[0]+'/'+pinfo[1]):
return []
fpkg=self.pkglist[pinfo[0]+'/'+pinfo[1]]
ret=[]
for i in fpkg:
if i.ver==pinfo[2]:
ret.append(i)
return ret
elif pinfo[0] and pinfo[1]:
if not self.pkglist.has_key(pinfo[0]+'/'+pinfo[1]):
return []
return self.pkglist[pinfo[0]+'/'+pinfo[1]]
elif pinfo[1] and pinfo[2]:
for i in self.pkglist.keys():
if search('^.+\/%s$'%(pinfo[1]),i):
for el in self.pkglist[i]:
if el.ver==pinfo[2]:
ret.append(el)
return ret
elif pinfo[1]:
for i in self.pkglist.keys():
if search('^.+\/%s$'%(pinfo[1]),i):
ret+=self.pkglist[i]
return ret
return []
def getListPkg(self):
return self.pkglist
def list2str(list):
'''Функция переводит список в строку'''
return '['+','.join(list)+']'
def str2list(s):
'''Функция переводит строку в список'''
return s[1:-1].split(',')
def dict2str(dict):
'''Функция перводит словарь в строку'''
return '{'+','.join(["%s:%s" % (str(k),str(v)) \
for (k,v) in dict.items()])+'}' #:
def str2dict(s):
'''Функция переводит строку в словарь'''
dict = {}
for i in s[1:-1].split(','):
k,v = i.split(':')
dict[k] = v
return dict
def convertStrListDict(val):
'''Функция определеяется что на входе (строка, список, словарь)
и переводит их в строку и обратно'''
# если подан список
if type(val) == types.ListType:
return list2str(val)
# если подан словарь
elif type(val) == types.DictType:
return dict2str(val)
# если подана строка
else:
# если подная строка содержит словарь
if ':' in val and '{' in val:
return str2dict(val)
# если поданная строка содержит список
elif ',' in val and '[' in val:
return str2list(val)
# если это просто строка
else:
return val
def _toUNICODE(val):
"""перевод текста в юникод"""
if type(val) == types.UnicodeType:
return val
else:
return str(val).decode('UTF-8')

@ -0,0 +1,551 @@
#-*- coding: utf-8 -*-
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
# 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.
Version = "calculate-server 0.0.1"
import sys
sys.path.append('/var/tmp/calculate2/calculate-lib/trunk/pym')
import cStringIO
import cl_base
import struct
import termios
import fcntl
import cl_utils
import cl_profile
import ldap
class ldapFun(cl_profile._error):
'''Объект для работы с LDAP сервером
подключение к серверу и поиск данных
'''
def __init__(self, dnUser, password, host="localhost"):
self.conLdap = False
# Получаем соединение с LDAP
try:
self.conLdap = self.__ldapConnect(dnUser, password, host)
except ldap.LDAPError, e:
self.setError(e[0]['desc'])
def __ldapConnect(self, dnUser, password, host):
"""Соединение с LDAP сервером"""
conLdap = ldap.initialize('ldap://%s'%host)
conLdap.simple_bind_s(dnUser, password)
return conLdap
def ldapSearch(self,baseDN, searchScope, searchFilter, retrieveAttributes):
try:
ldap_result_id = self.conLdap.search(baseDN, searchScope,
searchFilter,
retrieveAttributes)
result_set = []
while 1:
result_type, result_data = self.conLdap.result(ldap_result_id,
0)
if (result_data == []):
break
else:
if result_type == ldap.RES_SEARCH_ENTRY:
result_set.append(result_data)
except ldap.NO_SUCH_OBJECT:
return []
except:
return False
return result_set
pcs = cl_utils.prettyColumnStr
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"]
break
return ""
class cl_smartcon(object):
def getconsolewidth(self):
"""Получить ширину текущей консоли"""
s = struct.pack("HHHH", 0, 0, 0, 0)
fd_stdout = sys.stdout.fileno()
try:
x = fcntl.ioctl(fd_stdout, termios.TIOCGWINSZ, s)
except IOError:
# если ошибка то ширина 80 символов
return 80
#(rows, cols, x pixels, y pixels)
return struct.unpack("HHHH", x)[1]
def printRight(self, offsetLeft, offsetRight):
"""Добавляет необходимое количество пробелов:
количество пробелов = (ширина консоли - offsetLeft - offsetRight)
"""
cols = self.getconsolewidth()
for i in range(cols - offsetLeft - offsetRight):
sys.stdout.write(" ")
def colorPrint(self,attr,fg,bg,string):
"""Раскрашивает выводимое сообщение
Параметры:
attr - это атрибут
fg - цвет символа
bg - цвет фона
в случае если параметр равен "" то он не изменяется
attr может принимать следующие значения:
0 сбросить все атрибуты (вернуться в нормальный режим)
1 яркий (обычно включает толстый шрифт)
2 тусклый
3 подчёркнутый
5 мигающий
7 реверсный
8 невидимый
fg может принимать следующие значения:
30 чёрный
31 красный
32 зелёный
33 жёлтый
34 синий
35 фиолетовый
36 голубой
37 белый
bg может принимать следующие значения:
40 чёрный
41 красный
42 зелёный
43 жёлтый
44 синий
45 фиолетовый
46 голубой
47 белый
"""
lst = []
if attr:
lst.append(attr)
if fg:
lst.append(fg)
if bg:
lst.append(bg)
sys.stdout.write("\033[%sm%s\033[0m" %(";".join(lst),string))
def redBrightPrint(self, string):
"""Печатает яркое красное сообщение"""
self.colorPrint("1","31","",string)
def greenBrightPrint(self, string):
"""Печатает яркое зеленое сообщение"""
self.colorPrint("1","32","",string)
def yellowBrightPrint(self, string):
"""Печатает яркое желтое сообщение"""
self.colorPrint("1","33","",string)
def blueBrightPrint(self, string):
"""Печатает яркое cинее сообщение"""
self.colorPrint("1","34","",string)
def lenString(self, string):
"""Получаем длинну строки"""
stringUnicode = cl_utils._toUNICODE(string)
lenString = len(stringUnicode)
return lenString
def defaultPrint(self, string):
sys.stdout.write(string)
sys.stdout.flush()
def printLine(self, argL, argR):
"""Печатает справа и слева консоли цветные сообщения"""
#Допустимые цвета
colorDict = {\
# цвет по умолчанию
'':self.defaultPrint,
# ярко зеленый
'greenBr':self.greenBrightPrint,
# ярко голубой
'blueBr':self.blueBrightPrint,
# ярко красный
'redBr':self.redBrightPrint,
# ярко желтый
'yellowBr':self.yellowBrightPrint,
}
# cмещение от левого края консоли
offsetL = 0
for color,leftString in argL:
offsetL += self.lenString(leftString)
if colorDict.has_key(color):
# печатаем и считаем смещение
colorDict[color](leftString)
else:
colorDict[''](leftString)
# cмещение от правого края консоли
offsetR = 0
for color,rightString in argR:
offsetR += self.lenString(rightString)
# Добавляем пробелы
self.printRight(offsetL, offsetR)
for color,rightString in argR:
if colorDict.has_key(color):
# печатаем и считаем смещение
colorDict[color](rightString)
else:
colorDict[''](rightString)
print ""
def printNotOK(self, string):
"""Вывод на печать в случае сбоя"""
self.printLine((('greenBr',' * '),
('',string),
),
(('blueBr','['),
('redBr',' !! '),
('blueBr',']'),
)
)
def printOK(self, string):
"""Вывод на печать в случае успеха"""
self.printLine((('greenBr',' * '),
('',string),
),
(('blueBr','['),
('greenBr',' ok '),
('blueBr',']'),
)
)
def printWARNING(self, string):
"""Вывод на печать предупреждения"""
self.printLine((('yellowBr',' * '),
('',string),
),
(('',''),
)
)
def printERROR(self, string):
"""Вывод на печать предупреждения"""
self.printLine((('redBr',' * '),
('',string),
),
(('',''),
)
)
def printSUCCESS(self, string):
"""Вывод на печать в случае успеха без [ok] справа"""
self.printLine((('greenBr',' * '),
('',string),
),
(('',''),
)
)

@ -0,0 +1,56 @@
#-*- coding: utf-8 -*-
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
# 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.
#Допустимые ключи значений
# mode - режим переменной r-не переназначается из командной строки,
# w-переназначается из командной строки
# type - тип переменной состоит из двух элементов(что это и для чего
# это)
# value - значение переменной
class Data:
##имя компьютера
#net_host
os_net_hostname = {'mode':"w"}
##текущая сеть
# разрешенные сети
#net_networks
os_net_allow = {}
##короткое название системы (CLD)
#setup_sys_shortname
os_linux_shortname={}
##домен
#sys_domain
os_net_domain = {'mode':"w"}
# Пути к ini файлам
cl_env_path = {'value':['/var/calculate/remote/calculate.env',
'/var/calculate/calculate.env',
'/etc/calculate/calculate.env']}
# локаль (прим: ru_RU.UTF-8)
os_locale_locale = {}
# язык (прим: ru_RU)
os_locale_lang = {}
# язык (прим: ru)
os_locale_language = {}
## поддерживаемые языки (пример: be be_BY da de en и т.д.)
#os_locale_linguas = {'value':'be be_BY da de en en_GB es fr it nb nn pl \
#pt_BR ru se sv uk'}

@ -0,0 +1,3 @@
[install]
install-purelib=/usr/lib/calculate
install-platlib=/usr/lib/calculate

@ -0,0 +1,36 @@
#!/usr/bin/env python
# setup.py --- Setup script for calculate-server
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
# 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 distutils.core import setup
setup(
name = 'calculate-lib',
version = "0.0.1",
description = "The library for Calculate 2",
author = "Calculate Pack",
author_email = "support@calculate.ru",
url = "http://calculate-linux.ru",
license = "http://www.apache.org/licenses/LICENSE-2.0",
package_dir = {'calculate-lib': "."},
packages = ['calculate-lib.pym'],
data_files = [("/usr/share/calculate/i18n",['i18n/cl_lib_ru.mo']),
("/var/calculate/remote/patch",[])],
)
Loading…
Cancel
Save