From 27667a1a19abb0b6eae32d78ffd2dace94d75459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Mon, 30 Aug 2021 10:10:12 +0300 Subject: [PATCH 01/24] py3 related changes - maps and filters to list comp, print to func, etc --- pym/cl_fill_server.py | 15 +- pym/cl_ldap.py | 1871 ++++++++++++++++++++--------------------- setup.py | 15 +- 3 files changed, 927 insertions(+), 974 deletions(-) diff --git a/pym/cl_fill_server.py b/pym/cl_fill_server.py index 04c303e..5d897f6 100644 --- a/pym/cl_fill_server.py +++ b/pym/cl_fill_server.py @@ -13,6 +13,7 @@ # 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. +from __future__ import print_function import os import cl_base import cl_utils @@ -30,7 +31,7 @@ class fillVars(object, cl_base.glob_attr): res = self._runos(runStr) if res: return res.strip() - print "Error generate hash (slappasswd)" + print("Error generate hash (slappasswd)") exit(1) def get_cl_profile_path(self): @@ -230,7 +231,7 @@ class fillVars(object, cl_base.glob_attr): for replServer in replServers: if replServer: md5hex = hashlib.md5(replServer).hexdigest() - data8bit = "".join(map(lambda x: str(int(x,16)/2),list(md5hex))) + data8bit = "".join((str(int(x,16)/2) for x in list(md5hex))) dStart = 0 dEnd = 3 dMax = 32 @@ -470,13 +471,13 @@ class fillVars(object, cl_base.glob_attr): netAllow = self.Get("sr_proxy_net_allow") if netAllow: netAllow = netAllow.split(",") - netAllow = map(lambda x: "acl localnet src %s"%x,netAllow) + netAllow = ["acl localnet src %s" % x for x in netAllow] netAllow = "\n".join(netAllow) return netAllow netAllow = self.Get("os_net_allow") if netAllow: netAllow = netAllow.split(",") - netAllow = map(lambda x: "acl localnet src %s"%x,netAllow) + netAllow = ["acl localnet src %s" % x for x in netAllow] netAllow = "\n".join(netAllow) return netAllow return "acl localnet src 127.0.0.1/32" @@ -543,14 +544,14 @@ class fillVars(object, cl_base.glob_attr): """Текст в ejabberd.cfg - имена хостов с которыми работает сервис""" jabberHosts = self.Get("sr_jabber_hosts") if jabberHosts: - return ", ".join(map(lambda x: '"'+x+'"', jabberHosts.split(","))) + return ", ".join(('"'+x+'"' for x in jabberHosts.split(","))) return "" def get_sr_jabber_hosts_yml(self): """Текст в ejabberd.cfg - имена хостов с которыми работает сервис""" jabberHosts = self.Get("sr_jabber_hosts") if jabberHosts: - return "\n".join(map(lambda x: ' - "%s"' % x, jabberHosts.split(","))) + return "\n".join((' - "%s"' % x for x in jabberHosts.split(","))) return "" def get_sr_jabber_user_name(self): @@ -591,7 +592,7 @@ class fillVars(object, cl_base.glob_attr): break if not foundLoc: netAllow.append("127.0.0.1") - netAllow = map(lambda x: "%s;"%x,netAllow) + netAllow = ["%s;" % x for x in netAllow] netAllow = " ".join(netAllow) return "listen-on { %s };"%netAllow netAllow = self.Get("sr_dns_net_allow") diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 870d4d2..fd29efa 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import print_function import os import sys import re @@ -44,6 +45,7 @@ import readline from xml import xpath # Для 32 битного целого (генерация серийного номера DNS зоны) import ctypes +from functools import reduce Version = "calculate-server 2.1.20" @@ -109,7 +111,7 @@ class report: def printReport(self): """Напечатать данные в табличном виде""" - print self.title + print(self.title) listStrSep = [] for lenCol in self.columnsWidth: listStrSep.append("-"*lenCol) @@ -123,7 +125,7 @@ class report: if printData[-1] == "\n": printData = printData[:-1] lines = printData.splitlines() - lenCols = map(lambda x: len(x), lines[0].strip().split(" ")) + lenCols = [len(x) for x in lines[0].strip().split(" ")] convLines = [] lenLines = len(lines) for i in range(lenLines): @@ -131,8 +133,8 @@ class report: if i == 0 or i == 2 or i == lenLines-1: char ="-+-" convLines.append(self._insertStrChar(lines[i], lenCols, char)) - print "\n".join(convLines) - print "(%s %s)"%(len(self.dataList), _("rows")) + print("\n".join(convLines)) + print("(%s %s)"%(len(self.dataList), _("rows"))) return True def _insertStrChar(self, line, lenCols, char): @@ -185,7 +187,7 @@ class iniLdapParser(cl_base.iniParser): self.nameIniFile = "/var/lib/calculate/calculate.ldap" cl_base.iniParser.__init__(self, self.nameIniFile) # права создаваемого ini-файла - self.setMode(0600) + self.setMode(0o600) pathIniFile = os.path.split(self.nameIniFile)[0] if not os.path.exists(pathIniFile): os.makedirs(pathIniFile) @@ -215,7 +217,7 @@ class ldapFunction(cl_utils2.ldapFun): # Записываем параметры из ldif файла в LDAP сервер parser = addLdif(strLdif,self.conLdap) parser.parse() - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.setError(e[0]['desc']) return False except: @@ -255,27 +257,27 @@ class shareIP: def getNet(self, ip, mask): """По ip и маске получаем сеть""" octetsMult = (0x1, 0x100, 0x10000, 0x1000000) - octetsIp = map(lambda x: int(x), ip.split(".")) - octetsMask = map(lambda x: int(x), mask.split(".")) + octetsIp = [int(x) for x in ip.split(".")] + octetsMask = [int(x) for x in mask.split(".")] ipNumb = 0 for i in octetsMult: - ipNumb += octetsIp.pop()*i + ipNumb += octetsIp.pop() * i maskNumb = 0 for i in octetsMult: - maskNumb += octetsMask.pop()*i + maskNumb += octetsMask.pop() * i startIpNumber = maskNumb&ipNumb x = startIpNumber - nMask = lambda y: len(filter(lambda x: y >> x &1 ,range(32))) + nMask = lambda y: len([x for x in range(32) if y >> x & 1]) return "%s.%s.%s.%s/%s"\ %(x>>24, x>>16&255, x>>8&255, x&255, nMask(maskNumb)) def getNumberIP(self, ip): """По строке ip получаем число (номер ip)""" - octetsIp = map(lambda x: int(x), ip.split(".")) + octetsIp = [int(x) for x in ip.split(".")] octetsMult = (0x1, 0x100, 0x10000, 0x1000000) ipNumb = 0 for i in octetsMult: - ipNumb += octetsIp.pop()*i + ipNumb += octetsIp.pop() * i return ipNumb def getNumberNetmask(self, netmask): @@ -490,7 +492,7 @@ in a sambaDomainName', while ldapObj.getError(): try: # Задержка - wait.next() + next(wait) except StopIteration: break # Очистка ошибки @@ -555,7 +557,7 @@ in a sambaDomainName', term = "" if resRestore == True: term = message - if not flagError and type(resRestore) == types.TupleType: + if not flagError and type(resRestore) == tuple: # Если cansel if resRestore[0] == "Cancel": # Удаляем пользователя @@ -600,7 +602,7 @@ in a sambaDomainName', "%s-%s"%(userName,strUid), service) if strUid and os.path.exists(delBackDir) and os.listdir(delBackDir): - if message == None or type(message) == types.BooleanType: + if message == None or type(message) == bool: dialogRes = message else: dialogRes = self.dialogYesNo(message) @@ -692,9 +694,9 @@ in a sambaDomainName', self.printERROR(_("ERROR") + ": " + execStr) return False else: - splLines = filter(lambda x: len(x)==2 and "default" in x[1],\ - map(lambda x: x.split("|"),textLine)) - splLines = map(lambda x: x[0].strip(), splLines) + splLines = [x for x in (y.split("|") for y in textLine) + if len(x)==2 and "default" in x[1]] + splLines = [x[0].strip() for x in splLines] return splLines @@ -782,7 +784,7 @@ in a sambaDomainName', self.printERROR(clProf.getError()) return False else: - if verbose and type(data) == types.TupleType: + if verbose and type(data) == tuple: dirs, files = data return files return True @@ -990,17 +992,17 @@ in a sambaDomainName', pwDialog - структура для вывода приглашения в режиме диалога """ userPwd = "" - if optStdIn and options.has_key(optStdIn): + if optStdIn and optStdIn in options: pwdA = sys.stdin.readline().rstrip() pwdB = pwdA - elif optDialog and options.has_key(optDialog): + elif optDialog and optDialog in options: if not pwDialog: pwDialog = [_("New password"), _("Retype new password")] pwdA = getpass.getpass(pwDialog[0]+":") pwdB = getpass.getpass(pwDialog[1]+":") - if (optStdIn and options.has_key(optStdIn)) or\ - (optDialog and options.has_key(optDialog)): + if (optStdIn and optStdIn in options) or\ + (optDialog and optDialog in options): if not pwdA or not (pwdA == pwdB): self.printERROR (_("ERROR") + ": " +\ _("password incorrect")+ ": " + _("try again")) @@ -1155,7 +1157,7 @@ in a sambaDomainName', fOut.close() if flagError: return False - if searchUser[0][0][1].has_key('jpegPhoto'): + if 'jpegPhoto' in searchUser[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'jpegPhoto', photoData)) else: modAttrs.append((ldap.MOD_ADD, 'jpegPhoto', photoData)) @@ -1204,7 +1206,7 @@ in a sambaDomainName', break return True - def createUserDir(self, uid, gid, userDir, mode=0700): + def createUserDir(self, uid, gid, userDir, mode=0o700): """Создание пользовательской директории""" if not os.path.exists(userDir): os.makedirs(userDir) @@ -1216,7 +1218,7 @@ in a sambaDomainName', self.printERROR(_("Path %s exists") %userDir) return False - def createUserFile(self, fileName, fileTxt, uid, gid, mode=0644): + def createUserFile(self, fileName, fileTxt, uid, gid, mode=0o644): """Создает пользовательский файл с содержимым Если директория файла не существует то ошибка @@ -1357,8 +1359,8 @@ in a sambaDomainName', flagError = True break else: - splIP = map(lambda x: 255>=int(x.split("/")[0]) and\ - x.split("/")[0], find.group().split(".")) + splIP = [255>=int(x.split("/")[0]) and x.split("/")[0] for x + in find.group().split(".")] if not splIP[0] or splIP[0] and int(splIP[0]) == 0: flagError = True break @@ -1400,9 +1402,9 @@ in a sambaDomainName', вывод - список доверительных сетей """ def printW(): - print _("Incorrect string allow networks") - print _("Example - allow networks: 10.0.0.0/24 10.0.10.0/24") - print _("Try again\n") + print(_("Incorrect string allow networks")) + print(_("Example - allow networks: 10.0.0.0/24 10.0.10.0/24")) + print(_("Try again\n")) strNet = self.raw_input(strPrompt, strNetAllow) i = 0 while i<3 and not self.isCorrectStringNet(strNet): @@ -1477,7 +1479,7 @@ if you want to continue to run the program again")) """Добавление узла в LDAP""" try: self.conLdap.add_s(DN, entry) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR(_("LDAP Error") + ": " + e[0]['desc'].strip()) self.printERROR(errorMessage) return False @@ -1542,7 +1544,7 @@ This command is not allowed.")) if modAttrs: try: self.conLdap.modify_s(DN, modAttrs) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR(e[0]['desc']) return False return True @@ -1553,7 +1555,7 @@ This command is not allowed.")) DN = self.addDN(relDN,self.baseDN) try: self.conLdap.modrdn_s(DN, newFirstDn) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR(e[0]['desc']) return False return True @@ -1564,7 +1566,7 @@ This command is not allowed.")) DN = self.addDN(relDN,self.baseDN) try: self.conLdap.delete_s(DN) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR(e[0]['desc']) return False return True @@ -1577,7 +1579,7 @@ This command is not allowed.")) lst.append(0) if resSearch: for scope in resSearch: - if scope[0][1].has_key(attrSearch): + if attrSearch in scope[0][1]: uid = int(scope[0][1][attrSearch][0]) if uid<=numMax and uid>=numMin: lst.append(uid) @@ -1593,7 +1595,7 @@ This command is not allowed.")) dnList = self.conLdap.search_s(DN, ldap.SCOPE_SUBTREE, ldapFilter,None) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR("fullElementDN: "+e[0]['desc']) return False FDOUT = StringIO.StringIO("") @@ -1672,7 +1674,7 @@ This command is not allowed.")) ldap.SCOPE_SUBTREE, '(objectclass=*)', ['']) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR("deleteDN: "+e[0]['desc']) return False for dn, f in dnList: @@ -1681,7 +1683,7 @@ This command is not allowed.")) for dn in delListDN: try: self.conLdap.delete_s(dn) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR("deleteDN: "+e[0]['desc']) return False return True @@ -1780,7 +1782,7 @@ This command is not allowed.")) while ldapObj.getError(): try: # Задержка - wait.next() + next(wait) except StopIteration: break # Очистка ошибки @@ -1882,11 +1884,11 @@ This command is not allowed.")) sslBits=1024, userName="root",groupName="root", certFile="/tmp/server.pem", - certFileMode=0400, + certFileMode=0o400, keyFile="/tmp/server.key", - keyFileMode=0400, + keyFileMode=0o400, dhFile=None, - dhFileMode=0400, + dhFileMode=0o400, genDH=False): """Создает сертификат""" sslFile = "/usr/bin/openssl" @@ -1897,7 +1899,7 @@ This command is not allowed.")) if genDH and dhFile: certAndKeyFiles = [dhFile, certFile, keyFile] - foundCertFiles = filter(lambda x: os.path.exists(x), certAndKeyFiles) + foundCertFiles = [x for x in certAndKeyFiles if os.path.exists(x)] if not os.path.exists(dhFile): rndFile = "/tmp/%s.rnd" %strData self.execProg("dd if=/dev/urandom of=%s count=1"%rndFile) @@ -1914,23 +1916,23 @@ This command is not allowed.")) return False if os.path.exists(rndFile): os.remove(rndFile) - foundCertFiles = filter(lambda x: os.path.exists(x), certAndKeyFiles) + foundCertFiles = [x for x in certAndKeyFiles if os.path.exists(x)] if len(foundCertFiles)==3: return True else: if genDH: keyFile = certFile certAndKeyFiles = [certFile] - foundCertFiles = filter(lambda x: os.path.exists(x),certAndKeyFiles) + foundCertFiles = [x for x in certAndKeyFiles if os.path.exists(x)] if len(foundCertFiles)==1: return True else: certAndKeyFiles = [certFile, keyFile] - foundCertFiles = filter(lambda x: os.path.exists(x), certAndKeyFiles) + foundCertFiles = [x for x in certAndKeyFiles if os.path.exists(x)] if len(foundCertFiles)==2: return True # Удаляем файл сертификата - map(lambda x: os.remove(x), foundCertFiles) + [os.remove(x) for x in foundCertFiles] uidAndGid = self.getUserUidAndGid(userName, groupName) if not uidAndGid: return False @@ -1965,9 +1967,9 @@ nsCertType = %s for fileName in certAndKeyFiles: dirName = os.path.split(fileName)[0] if not os.path.exists(dirName): - self.createUserDir(0, 0, dirName, 0755) + self.createUserDir(0, 0, dirName, 0o755) # Создание конфигурационного файла - self.createUserFile(cnfFile, textCnf, 0, 0, 0600) + self.createUserFile(cnfFile, textCnf, 0, 0, 0o600) # Создание сертификата textLine = self.execProg(\ "%s req -new -x509 -nodes -config %s -days %s -out %s -keyout %s"\ @@ -2137,7 +2139,7 @@ class servUnix(shareLdap): os.symlink(src,dst) #Изменение прав на ссылки os.lchown(dst, uid, gid) - os.chmod(homeDir, 0700) + os.chmod(homeDir, 0o700) os.chown(homeDir, uid,gid) return True @@ -2299,7 +2301,7 @@ class servUnix(shareLdap): return False else: findUsers = [] - if res[0][0][1].has_key('memberUid'): + if 'memberUid' in res[0][0][1]: usersInGroup = res[0][0][1]['memberUid'] for userName in usersNames: if userName in usersInGroup: @@ -2336,7 +2338,7 @@ class servUnix(shareLdap): return False # Если группа существует выходим без ошибки flagSearchGroups = True - if options.has_key('f'): + if 'f' in options: flagSearchGroups = False if flagSearchGroups and self.searchGroupGroupName(groupName): self.printERROR(\ @@ -2357,7 +2359,7 @@ class servUnix(shareLdap): self.clVars.Set("ur_group",groupName) # номер группы gid = str(self.getMaxGid()) - if options.has_key('g'): + if 'g' in options: gid = options['g'] try: int(gid) @@ -2378,20 +2380,20 @@ class servUnix(shareLdap): self.clVars.Set("ur_group_id", gid) # Коментарий к группе gecos = self.groupGecos - if options.has_key('c'): + if 'c' in options: gecos = options['c'] self.clVars.Set("ur_group_comment",gecos) ldifFile = self.ldifFileGroup groupLdif = self.createLdif(ldifFile) if not groupLdif: - print self.getError() + print(self.getError()) return False if not self.ldapObj.getError(): self.ldapObj.ldapAdd(groupLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False - if options.has_key('p'): + if 'p' in options: sys.stdout.write(gid) else: if printSuccess: @@ -2438,7 +2440,7 @@ class servUnix(shareLdap): #Добавляем пользователя в LDAP self.ldapObj.ldapAdd(userLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False self.printSUCCESS(_("Added machine")) return True @@ -2461,15 +2463,15 @@ class servUnix(shareLdap): self.clVars.Set("ur_name", userName) baseDir = self.baseDir # Базовая домашняя директория - if options.has_key('b'): + if 'b' in options: baseDir = options['b'] # Устанавливаем скелетную директорию - if options.has_key('k'): + if 'k' in options: skelDir = options['k'] else: skelDir = self.skelDir # Устанавливаем домашнюю директорию - if options.has_key('d'): + if 'd' in options: homeDir = options['d'] else: homeDir = os.path.join(baseDir, userName) @@ -2477,22 +2479,22 @@ class servUnix(shareLdap): fullNameUser = self.fullNameUser # Полное имя пользователя - if options.has_key('c'): + if 'c' in options: fullNameUser = options['c'] self.clVars.Set("ur_fio",fullNameUser) # По умолчанию пользователя не видно visible = '0' - if options.has_key('v'): + if 'v' in options: visible = '1' self.clVars.Set("ur_visible",visible) # Оболочка пользователя userShell = self.userShell - if options.has_key('s'): + if 's' in options: userShell = options['s'] self.clVars.Set("ur_shell", userShell) # id пользователя - if options.has_key('u'): + if 'u' in options: userId = options['u'] try: int(userId) @@ -2511,17 +2513,17 @@ class servUnix(shareLdap): self.clVars.Set("ur_id",userId) # Добавляем пользователя в группы (находим имена групп) - if options.has_key('G'): + if 'G' in options: userGroups = options['G'].split(',') data = self.servSambaObj.searchUnixAndSambaGroups(userGroups, callSamba) - if data and type(data) == types.TupleType: + if data and type(data) == tuple: userGroupNamesUnix, userGroupNamesSamba = data else: return False userGid = str(self.getMaxGid()) # Группа пользователя - if options.has_key('g'): + if 'g' in options: userGid = options['g'] retCondUnix, userGidNamesUnix, errMessUnix =\ self.searchGroupsUnix([userGid], False) @@ -2589,7 +2591,7 @@ class servUnix(shareLdap): # флаги добавления flagAdd = {} # Добавление основной группы пользователя - if options.has_key('g'): + if 'g' in options: resLdap = self.searchUnixGroupName(groupName) if not resLdap and callSamba: resLdap = self.servSambaObj.searchSambaGroupName(groupName) @@ -2617,14 +2619,14 @@ class servUnix(shareLdap): self.ldapObj.ldapAdd(userLdif) #Добавляем пользователя в дополнительные группы (опция G) - if options.has_key('G') and userGroupNamesUnix: + if 'G' in options and userGroupNamesUnix: for group in userGroupNamesUnix: if not self.addUsersGroupUnix([userName], group): flagError = True break # не переделывать на else if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) flagError = True removeHomeBack = False if not flagError: @@ -2647,14 +2649,14 @@ class servUnix(shareLdap): if not flagError and not self.setShadowLastChange(userName): flagError = True # Добавим домашнюю директорию - if not flagError and createDirHome and options.has_key('m'): + if not flagError and createDirHome and 'm' in options: if not os.path.exists(homeDir): if not self.createHomeDir(userName, homeDir, skelDir): self.printERROR (_("ERROR") + ": " +\ _("cannot create HOME dir")) flagError = True #загружаем картинку - if not flagError and options.has_key('i'): + if not flagError and 'i' in options: photoFile = options['i'] if not self.setJpegPhotoUser(userName, photoFile): self.printERROR(_("Can not add jpeg photo for user") + " " +\ @@ -2665,11 +2667,11 @@ class servUnix(shareLdap): self.printERROR (_("Can not add user")+ " " + str(userName)) return False if printSuccess: - if flagAdd.has_key('group'): + if 'group' in flagAdd: self.printSUCCESS(_("Added group in Unix service")) - if createDirHome and options.has_key('m'): + if createDirHome and 'm' in options: self.printSUCCESS(_("Created home dir %s")%homeDir) - if options.has_key('i'): + if 'i' in options: self.printSUCCESS(_("Added jpeg photo %s")% photoFile) self.printSUCCESS(_("Added user in Unix service")) return True @@ -2680,7 +2682,7 @@ class servUnix(shareLdap): if not searchUser: return True modAttrs = [] - if searchUser[0][0][1].has_key('registeredAddress'): + if 'registeredAddress' in searchUser[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'registeredAddress', jabberID)) else: modAttrs.append((ldap.MOD_ADD, 'registeredAddress', jabberID)) @@ -2698,7 +2700,7 @@ Unix service")) self.printERROR(_("User %s not found in Unix service")\ %str(userName)) return False - if searchUser[0][0][1].has_key('registeredAddress'): + if 'registeredAddress' in searchUser[0][0][1]: return searchUser[0][0][1]['registeredAddress'][0] else: return "" @@ -2722,7 +2724,7 @@ in Unix service")) %str(userName)) return False modAttrs = [] - if searchUser[0][0][1].has_key('mail'): + if 'mail' in searchUser[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'mail', mail)) else: modAttrs.append((ldap.MOD_ADD, 'mail', mail)) @@ -2739,7 +2741,7 @@ in Unix service")) self.printERROR(_("User %s not found in Unix service")\ %str(userName)) return False - if searchUser[0][0][1].has_key('mail'): + if 'mail' in searchUser[0][0][1]: return searchUser[0][0][1]['mail'][0] else: return "" @@ -2809,7 +2811,7 @@ service")) if self.isServiceSetup("samba", False): maxGidSamba = self.servSambaObj.getMaxGidSamba() maxGids.append(maxGidSamba) - maxGid = max(map(lambda x: int(x), maxGids)) + maxGid = max(int(x) for x in maxGids) if maxGid == 0: return self.minGid else: @@ -2945,10 +2947,10 @@ service")) self.printERROR (_("ERROR") + ": " +\ _("User %s is not found in Unix service") % str(userName)) return False - if options.has_key('r'): + if 'r' in options: backup = False homeDir = False - if resLdap[0][0][1].has_key('homeDirectory'): + if 'homeDirectory' in resLdap[0][0][1]: #Домашняя директория пользователя homeDir = resLdap[0][0][1]['homeDirectory'][0] if backup and os.path.exists(homeDir) and\ @@ -2964,7 +2966,7 @@ service")) # Удаляем пользователя из групп if not self.delUserInGroup(userName): return False - if resLdap[0][0][1].has_key('gidNumber'): + if 'gidNumber' in resLdap[0][0][1]: gid = resLdap[0][0][1]['gidNumber'][0] else: resPasswd = self.searchPasswdUser(userName) @@ -2980,11 +2982,10 @@ service")) if resGroupSamba: # В случае отсутствия других пользователей удаляем # основную группу в Samba сервисе - if not resGroupSamba[0][0][1].has_key('memberUid'): + if 'memberUid' not in resGroupSamba[0][0][1]: groupName = resGroupSamba[0][0][1]['cn'][0] # Находим группы у которых есть аттрибут type - groupsSambaList = filter(\ - lambda x: x[1].type, self.staticGroups.items()) + groupsSambaList = [x for x in self.staticGroups.items() if x[1].type] groupsSamba = {} groupsSamba.update(groupsSambaList) # Группы которые нельзя удалять @@ -2998,7 +2999,7 @@ service")) if resGroup: # В случае отсутствия других пользователей # удаляем основную группу в Unix сервисе - if not resGroup[0][0][1].has_key('memberUid'): + if 'memberUid' not in resGroup[0][0][1]: groupName = resGroup[0][0][1]['cn'][0] if not self.delGroupUnixServer(groupName, {}, False): return False @@ -3057,11 +3058,11 @@ service")) _("User %s is not found in Unix service")%str(userName)) return False # Новые группы в которые входит пользователь - if options.has_key('G'): + if 'G' in options: userGroups = options['G'].split(',') data = self.servSambaObj.searchUnixAndSambaGroups(userGroups, callSamba) - if data and type(data) == types.TupleType: + if data and type(data) == tuple: userGroupNamesUnix, userGroupNamesSamba = data else: return False @@ -3078,11 +3079,11 @@ service")) if printSuccess: self.printSUCCESS(_("Replaced list of supplementary group")) # Добавляем группы в которые входит пользователь - elif options.has_key('a'): + elif 'a' in options: userGroups = options['a'].split(',') data = self.servSambaObj.searchUnixAndSambaGroups(userGroups, callSamba) - if data and type(data) == types.TupleType: + if data and type(data) == tuple: userGroupNamesUnix, userGroupNamesSamba = data else: return False @@ -3099,7 +3100,7 @@ service")) # Изменяемые аттрибуты пользователя modAttrs = [] # Изменяем первичную группу пользователя - if options.has_key('g'): + if 'g' in options: newFirstGroup = options['g'] # В случае вызова из Samba объекта ищем gid в Unix и Samba if callSamba: @@ -3138,33 +3139,33 @@ service")) modAttrs += [(ldap.MOD_REPLACE, 'gidNumber', userGid)] visible = False # пользователя видно - if options.has_key('V'): + if 'V' in options: visible = '1' # пользователя не видно - if options.has_key('I'): + if 'I' in options: visible = '0' if visible: modAttrs += [(ldap.MOD_REPLACE, 'shadowFlag', visible)] # Изменяем домашнюю директорию - if options.has_key('d'): + if 'd' in options: homeDir = options['d'] modAttrs += [(ldap.MOD_REPLACE, 'homeDirectory', homeDir)] # Включаем пользователя - if options.has_key('U'): + if 'U' in options: modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "-1")] # Выключаем пользователя - if options.has_key('L'): + if 'L' in options: modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "1")] # Изменяем комментарий к пользователю - if options.has_key('c'): + if 'c' in options: comment = options['c'] - if res[0][0][1].has_key('displayName'): + if 'displayName' in res[0][0][1]: modAttrs += [(ldap.MOD_REPLACE, 'displayName', comment), (ldap.MOD_REPLACE, 'cn', comment)] else: modAttrs += [(ldap.MOD_REPLACE, 'cn', comment)] # Изменяем оболочку пользователя - if options.has_key('s'): + if 's' in options: shell = options['s'] modAttrs.append((ldap.MOD_REPLACE, 'loginShell', shell)) # Изменяем пароль пользователя @@ -3175,7 +3176,7 @@ service")) userPwdHash = self.getHashPasswd(userPwd, self.userCrypt) if not userPwdHash: return False - if res[0][0][1].has_key('userPassword'): + if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -3186,7 +3187,7 @@ service")) if not self.modAttrsDN(DN, modAttrs): return False # Переносим домашнюю директорию пользователя - if options.has_key('d') and options.has_key('m'): + if 'd' in options and 'm' in options: homeDirOld = res[0][0][1]['homeDirectory'][0] homeDirNew = homeDir textLine = self.execProg("mv %s %s" %(homeDirOld, homeDirNew)) @@ -3199,7 +3200,7 @@ service")) else: if printSuccess: self.printSUCCESS(_("Moved home directory")) - if options.has_key('P') or options.has_key('p'): + if 'P' in options or 'p' in options: # Изменим время последнего измения пароля пользователя if not self.setShadowLastChange(userName): return False @@ -3207,7 +3208,7 @@ service")) self.printSUCCESS(\ _("Modified user password of Unix service")) if printSuccess: - if options.has_key('g'): + if 'g' in options: flagInt = False try: int(newFirstGroup) @@ -3218,20 +3219,20 @@ service")) if flagInt: self.printSUCCESS(_("Modified GID primary group to %s")\ %newFirstGroup) - if options.has_key('c'): + if 'c' in options: self.printSUCCESS(_("Modified comment")) - if options.has_key('s'): + if 's' in options: self.printSUCCESS(_("Modified shell")) - if options.has_key('d'): + if 'd' in options: self.printSUCCESS(_("Modified home directory")) - if options.has_key('U'): + if 'U' in options: self.printSUCCESS(_("Unlocked user %s")% str(userName)) - if options.has_key('I'): + if 'I' in options: self.printSUCCESS(\ _("User %s is invisible")% str(userName)) - if options.has_key('V'): + if 'V' in options: self.printSUCCESS(_("User %s is visible")% str(userName)) - if options.has_key('L'): + if 'L' in options: self.printSUCCESS(_("Locked user %s")% str(userName)) return True @@ -3248,18 +3249,18 @@ service")) # Изменяемые аттрибуты пользователя modAttrs = [] # Удаляем пароль пользователя - if options.has_key('d'): - if res[0][0][1].has_key('userPassword'): + if 'd' in options: + if 'userPassword' in res[0][0][1]: modAttrs += [(ldap.MOD_DELETE, 'userPassword', None)] else: self.printERROR(\ _("User %s has not password for Unix service")%\ str(userName)) # Включаем пользователя - if options.has_key('u'): + if 'u' in options: modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "-1")] # Выключаем пользователя - elif options.has_key('l'): + elif 'l' in options: modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "1")] if not options: optPasswd = {"p":""} @@ -3272,7 +3273,7 @@ service")) userPwdHash = self.getHashPasswd(userPwd, self.userCrypt) if not userPwdHash: return False - if res[0][0][1].has_key('userPassword'): + if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -3283,14 +3284,14 @@ service")) DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False - if options.has_key('d'): + if 'd' in options: self.printSUCCESS( _("Deleted password of Unix service for user")+ " " +\ str(userName)) - if options.has_key('l'): + if 'l' in options: self.printSUCCESS(_("Locked user") + " " + str(userName) +\ " " +_("of Unix service")) - if options.has_key('u'): + if 'u' in options: self.printSUCCESS(_("Unlocked user") + " " + str(userName) +\ " " +_("of Unix service")) if not options: @@ -3310,7 +3311,7 @@ service")) self.printERROR(_("group name not found in Unix service")) return False # Добавляем список пользователей в группу - if options.has_key('a'): + if 'a' in options: # добавляемые пользователи в группу users = options['a'].split(',') res = self.addUsersGroupUnix(users, groupName) @@ -3323,7 +3324,7 @@ service")) " " + str(groupName)) return False # Удаляем список пользователей из группы - if options.has_key('d'): + if 'd' in options: # удаляемые пользователи из группы users = options['d'].split(',') res = self.delUsersGroupUnix(users, groupName) @@ -3337,7 +3338,7 @@ service")) return False modGroupName = groupName # Изменяем имя группы - if options.has_key('n'): + if 'n' in options: newGroupName = options['n'] if self.searchUnixGroupName(newGroupName): self.printERROR( @@ -3364,19 +3365,19 @@ service")) return False modAttrs = [] # Изменяем комментарий к группе - if options.has_key('c'): + if 'c' in options: gecos = options['c'] modAttrs.append((ldap.MOD_REPLACE, 'description', gecos)) if modAttrs: groupDN = self.addDN("cn=" + modGroupName, self.relGroupsDN) res = self.modAttrsDN(groupDN, modAttrs) if res: - if options.has_key('c'): + if 'c' in options: if printSuccess: self.printSUCCESS(_("Modified group comment")) return True else: - if options.has_key('c'): + if 'c' in options: self.printSUCCESS(_("Can not modify group comment")) return False @@ -3421,7 +3422,7 @@ service")) if not res : self.printERROR(_("group name is not found in Unix service")) return False - if not res[0][0][1].has_key("memberUid"): + if "memberUid" not in res[0][0][1]: if not getPrimaryUsers(): return False self.printERROR( @@ -3454,7 +3455,7 @@ service")) # Создаем объект переменных и начальная проверка if not self.initialChecksSetup(): return False - if options.has_key("f"): + if "f" in options: forceOptions = True # В случае если сервер установлен if self.clVars.Get("sr_unix_set") == "on" and\ @@ -3550,7 +3551,7 @@ service")) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False self.printOK(_("Added ldif file") + " ...") # Записываем данные администратора сервиса Unix @@ -3655,7 +3656,7 @@ class servMail(shareLdap): #почтовая директория пользователя mailDir = os.path.join(self.clVars.Get("sr_mail_path"), userName) - if options.has_key('r'): + if 'r' in options: backup = False # Делаем сохранение данных удаляемого пользователя if backup and os.path.exists(mailDir) and os.listdir(mailDir): @@ -3746,7 +3747,7 @@ for user %s in 'Replication/Mail' branch") %str(userName)) if not res : self.printERROR(_("group name is not found in Mail service")) return False - if not res[0][0][1].has_key("rfc822member"): + if "rfc822member" not in res[0][0][1]: self.printERROR(\ _("Member list of group %s is empty")%str(groupName)) return False @@ -3808,7 +3809,7 @@ for group %s in 'Replication/Mail' branch") %str(userName)) res = self.searchMailUserToName(userName) if not res: return False - if not res[0][0][1].has_key('mailAlternateAddress'): + if 'mailAlternateAddress' not in res[0][0][1]: return True modAttrs = [(ldap.MOD_DELETE, 'mailAlternateAddress', None)] userDN = self.addDN("uid=" + userName, self.relUsersDN) @@ -3825,11 +3826,11 @@ for group %s in 'Replication/Mail' branch") %str(userName)) if not searchGroup: self.printERROR(_("group name not found in Mail service")) return False - if options.has_key('n') and options.has_key('e'): + if 'n' in options and 'e' in options: self.printERROR(_("Command Line Options '-n' and '-e' are \ incompatible, use one of the options")) return False - if options.has_key('hide') and options.has_key('hide-off'): + if 'hide' in options and 'hide-off' in options: self.printERROR(_("Command Line Options '--hide' and '--hide-off' \ are incompatible, use one of the options")) return False @@ -3843,20 +3844,19 @@ are incompatible, use one of the options")) # Объект сервис репликации servReplObj = servRepl() filterHosts = [] - if options.has_key('hide'): + if 'hide' in options: filterHosts = options['hide'].split(",") - if searchGroup[0][0][1].has_key('filtersender'): + if 'filtersender' in searchGroup[0][0][1]: attrDeleteFirst.append((ldap.MOD_DELETE, 'filtersender', None)) domain = self.clVars.Get('os_net_domain') # Если необходимо добавляем домен к именам хостов - fHosts = map(lambda x: (not '.' in x and x+"."+domain) or x, - filterHosts) + fHosts = [(not '.' in x and x + "." + domain) or x for x in filterHosts] for host in fHosts: attrAppend.append((ldap.MOD_ADD, 'filtersender', host)) - if options.has_key('hide-off'): - if searchGroup[0][0][1].has_key('filtersender'): + if 'hide-off' in options: + if 'filtersender' in searchGroup[0][0][1]: attrDeleteFirst.append((ldap.MOD_DELETE, 'filtersender', None)) - if options.has_key('e'): + if 'e' in options: altMails = options['e'].split(",") email = searchGroup[0][0][1]["mail"][0] altEmails = searchGroup[0][0][1]["mailAlternateAddress"] @@ -3922,14 +3922,14 @@ mail user or group: %s")%foundReplUser) "(%s)"%", ".join(altMails) self.printERROR(errorMsg) return False - if options.has_key('hide-off'): + if 'hide-off' in options: if not servReplObj.deleteHideHosts(groupName): errorMsg = _("Can not delete hide host in mail alias,") +\ " " + _("for name %s")%groupName self.printERROR(errorMsg) return False # Добавляем список пользователей в группу - if options.has_key('a'): + if 'a' in options: # добавляемые пользователи в группу users = options['a'].split(',') res = self.addUsersGroupMail(users, groupName) @@ -3941,7 +3941,7 @@ mail user or group: %s")%foundReplUser) " " + str(groupName)) return False # Удаляем список пользователей из группы - if options.has_key('d'): + if 'd' in options: # удаляемые пользователи из группы users = options['d'].split(',') res = self.delUsersGroupMail(users, groupName) @@ -3954,7 +3954,7 @@ mail user or group: %s")%foundReplUser) return False # Изменяем имя группы modGroupName = groupName - if options.has_key('n'): + if 'n' in options: newGroupName = options['n'] if self.searchMailGroupToName(newGroupName): self.printERROR( @@ -4006,11 +4006,11 @@ in 'Replication/Mail' branch") %groupName) return False modAttrs = attrDeleteFirst + attrAppend + attrDelete # Изменяем комментарий к группе - if options.has_key('c'): + if 'c' in options: gecos = options['c'] modAttrs.append((ldap.MOD_REPLACE, 'description', gecos)) if not modAttrs: - if options.has_key('hide-off'): + if 'hide-off' in options: self.printWARNING(\ _("Hide mail hosts have already been deleted")) return True @@ -4018,23 +4018,23 @@ in 'Replication/Mail' branch") %groupName) groupDN = self.addDN("cn=" + modGroupName, self.relGroupsDN) res = self.modAttrsDN(groupDN, modAttrs) if res: - if options.has_key('c'): + if 'c' in options: self.printSUCCESS(_("Modified group comment")) - if options.has_key('e'): + if 'e' in options: self.printSUCCESS(_("Modified mail alternate address")) - if options.has_key('hide'): + if 'hide' in options: self.printSUCCESS(_("Modified hide mail hosts")) - if options.has_key('hide-off'): + if 'hide-off' in options: self.printSUCCESS(_("Deleted hide mail hosts")) return True else: - if options.has_key('c'): + if 'c' in options: self.printERROR(_("Can not modify group comment")) - if options.has_key('e'): + if 'e' in options: self.printERROR(_("Can not modify mail alternate address")) - if options.has_key('hide'): + if 'hide' in options: self.printERROR(_("Can not modify hide mail hosts")) - if options.has_key('hide-off'): + if 'hide-off' in options: self.printERROR(_("Can not delete hide mail hosts")) return False return True @@ -4052,7 +4052,7 @@ in 'Replication/Mail' branch") %groupName) str(userName)) return False # Новые группы в которые входит пользователь - if options.has_key('G'): + if 'G' in options: userGroups = options['G'].split(',') #список имен добавляемых групп userGroupNames = self.searchGroupsMail(userGroups) @@ -4070,7 +4070,7 @@ in 'Replication/Mail' branch") %groupName) return False self.printSUCCESS(_("Replaced list of supplementary group")) # Добавляем группы в которые входит пользователь - elif options.has_key('a'): + elif 'a' in options: userGroups = options['a'].split(',') #список имен добавляемых групп userGroupNames = self.searchGroupsMail(userGroups) @@ -4087,14 +4087,14 @@ in 'Replication/Mail' branch") %groupName) # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя - if options.has_key('U'): + if 'U' in options: modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "active")] # Выключаем пользователя - elif options.has_key('L'): + elif 'L' in options: modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "passive")] # Изменяем комментарий к пользователю - if options.has_key('c'): + if 'c' in options: comment = options['c'] modAttrs += [(ldap.MOD_REPLACE, 'sn', comment), (ldap.MOD_REPLACE, 'cn', comment)] @@ -4106,7 +4106,7 @@ in 'Replication/Mail' branch") %groupName) userPwdHash = self.getHashPasswd(userPwd, self.userCrypt) if not userPwdHash: return False - if res[0][0][1].has_key('userPassword'): + if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -4116,7 +4116,7 @@ in 'Replication/Mail' branch") %groupName) # Первичный почтовый адрес primaryMail = "" altMails = [] - if options.has_key('e'): + if 'e' in options: altEmails = res[0][0][1]["mailAlternateAddress"] altMails = options['e'].split(",") for altMail in altMails: @@ -4180,15 +4180,15 @@ for user %s in 'Replication/Mail' branch") %userName) DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False - if options.has_key('c'): + if 'c' in options: self.printSUCCESS(_("Modified comment")) - if options.has_key('L'): + if 'L' in options: self.printSUCCESS(_("Locked Mail user %s")%str(userName)) - if options.has_key('U'): + if 'U' in options: self.printSUCCESS(_("Unlocked Mail user %s")%str(userName)) - if options.has_key('e'): + if 'e' in options: self.printSUCCESS(_("Modified Mail alternate addresses")) - if options.has_key('P') or options.has_key('p'): + if 'P' in options or 'p' in options: self.printSUCCESS(_("Modified Mail user password")) return True @@ -4210,7 +4210,7 @@ for user %s in 'Replication/Mail' branch") %userName) #Проверяем альтернативные почтовые адреса modAttrs = [] altMails = [] - if options.has_key('e'): + if 'e' in options: altMails = options['e'].split(",") for altMail in altMails: if "@" in altMail: @@ -4239,7 +4239,7 @@ mail user or group: %s")%foundReplUser) modAttrs.append('mailAlternateAddress: %s' %mail) # Фильтр почты (hostname) fHostNames = [] - if options.has_key('hide'): + if 'hide' in options: fHostNames = options['hide'].split(",") for fHostName in fHostNames: if not "." in fHostName: @@ -4270,19 +4270,19 @@ mail user or group: %s")%foundReplUser) self.clVars.Set("ur_group", groupName) # Комментарий к группе groupGecos = self.servUnixObj.groupGecos - if options.has_key('c'): + if 'c' in options: groupGecos = options['c'] self.clVars.Set("ur_group_comment",groupGecos) ldifFile = self.ldifFileGroup groupRawLdif = self.createLdif(ldifFile) if not groupRawLdif: - print self.getError() + print(self.getError()) return False groupLdif = groupRawLdif.rstrip() + "\n" + "\n".join(modAttrs) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(groupLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False if servReplObj: # Записываем почтовые алиасы в ветку @@ -4311,10 +4311,10 @@ for user %s in 'Replication/Mail' branch") %str(primaryMail)) # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя - if options.has_key('u'): + if 'u' in options: modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "active")] # Выключаем пользователя - elif options.has_key('l'): + elif 'l' in options: modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "passive")] if not options: optPasswd = {"p":""} @@ -4324,7 +4324,7 @@ for user %s in 'Replication/Mail' branch") %str(primaryMail)) userPwdHash = self.getHashPasswd(userPwd, self.userCrypt) if not userPwdHash: return False - if res[0][0][1].has_key('userPassword'): + if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -4334,9 +4334,9 @@ for user %s in 'Replication/Mail' branch") %str(primaryMail)) DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False - if options.has_key('l'): + if 'l' in options: self.printSUCCESS(_("Locked Mail user %s")% str(userName)) - if options.has_key('u'): + if 'u' in options: self.printSUCCESS(_("Unlocked Mail user %s")% str(userName)) if not options: self.printSUCCESS(_("Changed Mail user password")) @@ -4355,7 +4355,7 @@ for user %s in 'Replication/Mail' branch") %str(primaryMail)) return False else: findUsers = [] - if res[0][0][1].has_key('rfc822member'): + if 'rfc822member' in res[0][0][1]: usersInGroup = res[0][0][1]['rfc822member'] for userName in usersNames: userMail = "%s@%s" %(userName, @@ -4459,7 +4459,7 @@ for user %s in 'Replication/Mail' branch") %str(primaryMail)) addUsers.append(user) modAttrs = [] for userName in addUsers: - userMail = "%s@%s" %(userName,self.clVars.Get("sr_mail_host")) + userMail = "%s@%s" % (userName, self.clVars.Get("sr_mail_host")) modAttrs.append((ldap.MOD_ADD, 'rfc822member', userMail)) if modAttrs: groupDN = self.addDN("cn="+groupName, self.relGroupsDN) @@ -4498,7 +4498,7 @@ for user %s in 'Replication/Mail' branch") %str(primaryMail)) modAttrs = [] primaryMail = "" altMails = [] - if options.has_key('e'): + if 'e' in options: altMails = options['e'].split(",") for altMail in altMails: if "@" in altMail: @@ -4572,7 +4572,7 @@ mail user or group: %s")%foundReplUser) # Флаг создания группы по умолчанию flagCreateUnixGroup = False # Группа пользователя - if options.has_key('g'): + if 'g' in options: optUnix['g'] = options['g'] else: optUnix['g'] = self.defaultUnixGroup["name"] @@ -4588,7 +4588,7 @@ mail user or group: %s")%foundReplUser) if not self.servUnixObj.searchUnixGroupName(optUnix['g']): flagCreateUnixGroup = True # Полное имя пользователя - if options.has_key('c'): + if 'c' in options: optUnix['c'] = options['c'] # Если нужно создаем новую Unix группу if flagCreateUnixGroup: @@ -4609,10 +4609,10 @@ mail user or group: %s")%foundReplUser) self.clVars.Set("ur_name", userName) #Полное имя пользователя fullNameUser = self.servUnixObj.fullNameUser - if options.has_key('c'): + if 'c' in options: fullNameUser = options['c'] else: - if resUnix and resUnix[0][0][1].has_key('cn'): + if resUnix and 'cn' in resUnix[0][0][1]: fullNameUser = resUnix[0][0][1]['cn'][0] self.clVars.Set("ur_fio",fullNameUser) if not userPwd: @@ -4627,7 +4627,7 @@ mail user or group: %s")%foundReplUser) ldifFile = self.ldifFileUser userRawLdif = self.createLdif(ldifFile) if not userRawLdif: - print self.getError() + print(self.getError()) if flagCreateUnixUser: self.servUnixObj.delUserUnixServer(userName, {}, False, False) return False @@ -4639,7 +4639,7 @@ mail user or group: %s")%foundReplUser) # не переделывать на else flagError = False if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) flagError = True if not flagError: if resUnix: @@ -4701,8 +4701,8 @@ for user %s in 'Replication/Mail' branch") %userName) self.clVars должен быть определен """ - print _("Enter the allowed ip addresses and network for %s service")\ - %"Mail" + " (" + _("comma or space delimited") + ")" + print(_("Enter the allowed ip addresses and network for %s service")\ + %"Mail" + " (" + _("comma or space delimited") + ")") strPrompt = _("allow networks: ") netAllow = self.clVars.Get("sr_mail_net_allow") strNetAllow = "" @@ -4734,10 +4734,10 @@ for user %s in 'Replication/Mail' branch") %userName) return False def printW(): - print _("Incorrect string hostname") - print _("Try again\n") + print(_("Incorrect string hostname")) + print(_("Try again\n")) - print _("Enter the hostname for %s service")%"Mail" + print(_("Enter the hostname for %s service")%"Mail") strPrompt = _("hostname: ") hostname = self.clVars.Get("sr_mail_host") hostname = self.raw_input(strPrompt, hostname) @@ -4779,7 +4779,7 @@ if you want to continue to run the program again")) """Начальная настройка Mail сервиса""" # Принудительная установка forceOptions = False - if options.has_key("f"): + if "f" in options: forceOptions = True # Создаем объект переменных и начальная проверка if not self.initialChecksSetup(): @@ -4811,13 +4811,13 @@ if you want to continue to run the program again")) _("input 'yes'") +", "+ _("if not 'no'") if not self.dialogYesNo(messDialog): return True - if options.has_key("a"): + if "a" in options: # Получаем от пользователя доверительные сети allowNet = self.getAllowNet() if not allowNet: return False else: - if options.has_key("a"): + if "a" in options: # Получаем от пользователя доверительные сети allowNet = self.getAllowNet() if not allowNet: @@ -4867,7 +4867,7 @@ if you want to continue to run the program again")) # Почтовый ност fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'), self.clVars.Get('os_net_domain')) - if options.has_key("host"): + if "host" in options: fullHostName = options['host'] if not "." in fullHostName: fullHostName = "%s.%s" %(fullHostName, @@ -4875,7 +4875,7 @@ if you want to continue to run the program again")) self.clVars.Set("sr_mail_host",fullHostName,True) history,history_domain,history_path = self.getMailHistoryData(options) mailType = "imap" - if options.has_key("t"): + if "t" in options: mailType = options['t'] if mailType: if not set(mailType.split(",")) <= set(["imap","pop3"]): @@ -4889,7 +4889,7 @@ if you want to continue to run the program again")) return False self.clVars.Set("sr_mail_type", mailType) mailCrypt = "tls" - if options.has_key("c"): + if "c" in options: mailCrypt = options['c'] if not mailCrypt in ["none", "tls"]: self.printERROR(_("Мail encryption not 'none' or 'tls'")) @@ -4933,7 +4933,7 @@ if you want to continue to run the program again")) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False # Записываем данные администратора сервиса Mail ldapParser = iniLdapParser() @@ -5092,7 +5092,7 @@ class servJabber(shareLdap): modAttrs = [] descr = groupSearch[0][0][1]["cn"][0] uid = userSearch[0][0][1]["uid"][0] - if userSearch[0][0][1].has_key('departmentNumber'): + if 'departmentNumber' in userSearch[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'departmentNumber', descr)) else: modAttrs.append((ldap.MOD_ADD, 'departmentNumber', descr)) @@ -5107,7 +5107,7 @@ class servJabber(shareLdap): str(userName)) return False modAttrs = [] - if searchUser[0][0][1].has_key('mail'): + if 'mail' in searchUser[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'mail', newJabberId)) else: modAttrs.append((ldap.MOD_ADD, 'mail', newJabberId)) @@ -5151,7 +5151,7 @@ in Jabber service")) flagFalse = True break if not replaceFlag and\ - userSearch[0][0][1].has_key('departmentNumber'): + 'departmentNumber' in userSearch[0][0][1]: self.printERROR(_("User %s is found in group")%\ str(userName) + " " + str(groupName)) flagFalse = True @@ -5176,7 +5176,7 @@ in Jabber service")) res = True for userName in users: userSearch = self.searchUserToNameOrId(userName) - if userSearch and userSearch[0][0][1].has_key('departmentNumber'): + if userSearch and 'departmentNumber' in userSearch[0][0][1]: if not userSearch[0][0][1]['departmentNumber'][0] == \ groupSearch[0][0][1]['cn'][0]: self.printERROR(_("User %s is not found in group")%\ @@ -5247,10 +5247,10 @@ in Jabber service")) # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя - if options.has_key('u'): + if 'u' in options: modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] # Выключаем пользователя - elif options.has_key('l'): + elif 'l' in options: modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] if not options: optPasswd = {"p":""} @@ -5258,7 +5258,7 @@ in Jabber service")) if userPwd == False: return False userPwdHash = userPwd - if resSearch[0][0][1].has_key('userPassword'): + if 'userPassword' in resSearch[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -5269,9 +5269,9 @@ in Jabber service")) DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False - if options.has_key('l'): + if 'l' in options: self.printSUCCESS(_("Locked Jabber user %s")% str(userName)) - if options.has_key('u'): + if 'u' in options: self.printSUCCESS(_("Unlocked Jabber user %s")%\ str(userName)) if not options: @@ -5294,7 +5294,7 @@ in Jabber service")) modAttrs = [] # Изменяем Jabber ID jabber_hosts = self.get_jabber_hosts() - if options.has_key('j'): + if 'j' in options: # Изменяем JID jabberId = options['j'] if not "@" in jabberId: @@ -5320,13 +5320,13 @@ in Jabber service")) self.printERROR(_("Failed set jabberID for user %s \ in Unix service") %str(jabberId)) return False - if res[0][0][1].has_key('mail'): + if 'mail' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'mail', jabberId)) else: modAttrs.append((ldap.MOD_ADD, 'mail', jabberId)) modAttrs.append((ldap.MOD_REPLACE,'cn',jabberId.partition("@")[0])) # Изменяет группу в которую входит пользователь - if options.has_key('g'): + if 'g' in options: userGroup = options['g'] if self.setUserGroup(userName, userGroup, res): self.printSUCCESS(_("Replaced user group")) @@ -5334,20 +5334,20 @@ in Unix service") %str(jabberId)) self.printERROR(_("Not replaced user group")) return False #загружаем картинку - if options.has_key('i'): + if 'i' in options: photoFile = options['i'] if not self.setJpegPhotoUser(userName, photoFile): self.printERROR(_("Can not add jpeg photo for user") + " " +\ str(userName)) return False # Включаем пользователя - if options.has_key('U'): + if 'U' in options: modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] # Выключаем пользователя - elif options.has_key('L'): + elif 'L' in options: modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] # Изменяем комментарий к пользователю - if options.has_key('c'): + if 'c' in options: comment = options['c'] modAttrs += [(ldap.MOD_REPLACE, 'sn', comment)] # Изменяем пароль пользователя @@ -5356,7 +5356,7 @@ in Unix service") %str(jabberId)) return False if userPwd: userPwdHash = userPwd - if res[0][0][1].has_key('userPassword'): + if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -5368,19 +5368,19 @@ in Unix service") %str(jabberId)) if not self.modAttrsDN(DN, modAttrs): return False if printSuccess: - if options.has_key('c'): + if 'c' in options: self.printSUCCESS(_("Modified comment (full name)")) - if options.has_key('L'): + if 'L' in options: self.printSUCCESS(_("Locked Jabber user %s")%str(userName)) - if options.has_key('U'): + if 'U' in options: self.printSUCCESS(_("Unlocked Jabber user %s")\ %str(userName)) - if options.has_key('P') or options.has_key('p'): + if 'P' in options or 'p' in options: self.printSUCCESS(_("Modified Jabber user password")) - if options.has_key('j'): + if 'j' in options: self.printSUCCESS(_("JID changed, a new JID is %s")\ %jabberId) - if printSuccess and options.has_key('i'): + if printSuccess and 'i' in options: self.printSUCCESS(_("Set image %s for Jabber user")%\ str(options['i']) + " " + str(userName)) return True @@ -5396,7 +5396,7 @@ in Unix service") %str(jabberId)) %str(groupName)) return False # Добавляем список пользователей в группу - if options.has_key('a'): + if 'a' in options: # добавляемые пользователи в группу users = options['a'].split(',') res = self.addUsersGroupJabber(users, groupName) @@ -5408,7 +5408,7 @@ in Unix service") %str(jabberId)) " " + str(groupName)) return False # Удаляем список пользователей из группы - if options.has_key('d'): + if 'd' in options: # удаляемые пользователи из группы users = options['d'].split(',') res = self.delUsersGroupJabber(users, groupName) @@ -5420,7 +5420,7 @@ in Unix service") %str(jabberId)) " " + str(groupName)) return False # Изменяем комментарий к группе - if options.has_key('c'): + if 'c' in options: gecos = options['c'] modAttrs = [(ldap.MOD_REPLACE, 'description', gecos)] groupDN = self.addDN("cn="+groupName, self.relGroupsDN) @@ -5431,7 +5431,7 @@ in Unix service") %str(jabberId)) " " + str(groupName)) return False # Изменяем имя группы - if options.has_key('n'): + if 'n' in options: newGroupName = options['n'] oldGroupName = searchGroup[0][0][1]["cn"][0] if self.renameGroup(oldGroupName, newGroupName): @@ -5517,18 +5517,18 @@ in Unix service") %str(jabberId)) self.clVars.Set("ur_group",groupName) # Комментарий к группе groupGecos = self.servUnixObj.groupGecos - if options.has_key('c'): + if 'c' in options: groupGecos = options['c'] self.clVars.Set("ur_group_comment",groupGecos) ldifFile = self.ldifFileGroup groupLdif = self.createLdif(ldifFile) if not groupLdif: - print self.getError() + print(self.getError()) return False if not self.ldapObj.getError(): self.ldapObj.ldapAdd(groupLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False self.printSUCCESS(_("Added group '%s' in Jabber service")\ %groupName) @@ -5544,7 +5544,7 @@ in Unix service") %str(jabberId)) searchUsers = self.searchAllUsers() flagError = False for fieldUser in searchUsers: - if fieldUser[0][1].has_key("mail"): + if "mail" in fieldUser[0][1]: userName = fieldUser[0][1]['uid'][0] jabberId = fieldUser[0][1]['mail'][0] cn = fieldUser[0][1]['cn'][0] @@ -5581,7 +5581,7 @@ in Unix service") %str(jabberId)) return False #jabber id jabberId = "%s@%s" %(userName,self.clVars.Get("sr_jabber_host")) - if options.has_key('j'): + if 'j' in options: # Изменяем JID jabberId = options['j'] if not "@" in jabberId: @@ -5617,7 +5617,7 @@ in Unix service") %str(jabberId)) self.clVars.Set("ur_name", userName) #Полное имя пользователя fullNameUser = self.servUnixObj.fullNameUser - if options.has_key('c'): + if 'c' in options: fullNameUser = options['c'] else: # Проверяем установку сервиса не печатая ошибку в случае @@ -5625,7 +5625,7 @@ in Unix service") %str(jabberId)) if self.isServiceSetup("unix",False): resUnix = self.servUnixObj.searchUnixUser(userName) # Берем комментарий для пользователя из Unix - if resUnix and resUnix[0][0][1].has_key('cn'): + if resUnix and 'cn' in resUnix[0][0][1]: fullNameUser = resUnix[0][0][1]['cn'][0] self.clVars.Set("ur_fio",fullNameUser) ldifFile = self.ldifFileUser @@ -5636,10 +5636,10 @@ in Unix service") %str(jabberId)) #ldapObj.ldapAdd(userLdif1) # не переделывать на else if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False # загружаем картинку - if options.has_key('i'): + if 'i' in options: photoFile = options['i'] if not self.setJpegPhotoUser(userName, photoFile): self.printERROR(_("Can not add jpeg photo for user") + " " +\ @@ -5653,7 +5653,7 @@ in Unix service") %str(jabberId)) """Начальная настройка Jabber сервиса""" # Принудительная установка forceOptions = False - if options.has_key("f"): + if "f" in options: forceOptions = True # Создаем объект переменных и начальная проверка if not self.initialChecksSetup(): @@ -5712,14 +5712,14 @@ in Unix service") %str(jabberId)) fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'), self.clVars.Get('os_net_domain')) jabberHosts = fullHostName - if options.has_key("host"): + if "host" in options: fullHostName = options['host'] if not "." in fullHostName: fullHostName = "%s.%s" %(fullHostName, self.clVars.Get('os_net_domain')) self.clVars.Set("sr_jabber_host",fullHostName,True) # Устанавливаем дополнительные хосты jabber cервиса - if options.has_key("hosts"): + if "hosts" in options: hosts = options['hosts'].split(",") jabberHostsList = [self.clVars.Get("sr_jabber_host")] for host in hosts: @@ -5768,12 +5768,12 @@ in Unix service") %str(jabberId)) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False # Администратор сервиса adminName = "admin" adminFullName = "%s@%s" %(adminName, self.clVars.Get("sr_jabber_host")) - print _("Enter the %s password") %adminFullName + print(_("Enter the %s password") %adminFullName) if not self.addUserJabberServer(adminName,{'p':""}, False): return False # Записываем данные администратора сервиса Jabber @@ -5850,7 +5850,7 @@ class servSamba(shareLdap): Если группы нет она будет добавлена в противном случае пропущена """ # Находим группы у которых есть аттрибут type - groupsSambaList = filter(lambda x: x[1].type, self.staticGroups.items()) + groupsSambaList = [x for x in self.staticGroups.items() if x[1].type] groupsSamba = {} groupsSamba.update(groupsSambaList) flagError = False @@ -5903,7 +5903,7 @@ class servSamba(shareLdap): warning += _("If all clients of this server are calculate-client \ of version > 2.1.10, then you can delete this file.") + "\n" if not self.createUserFile(fileReplRun,warning,0,0, - mode=0644): + mode=0o644): return False return True @@ -5934,7 +5934,7 @@ of version > 2.1.10, then you can delete this file.") + "\n" if not res : self.printERROR(_("group name is not found in Samba service")) return False - if not res[0][0][1].has_key("memberUid"): + if "memberUid" not in res[0][0][1]: if not getPrimaryUsers(): return False self.printERROR( @@ -6038,7 +6038,7 @@ of version > 2.1.10, then you can delete this file.") + "\n" userNetlogonDir =\ os.path.join(self.clVars.Get("sr_samba_winlogon_path"), userName) - if options.has_key('r'): + if 'r' in options: backup = False # Делаем сохранение данных удаляемого пользователя if backup: @@ -6110,7 +6110,7 @@ of version > 2.1.10, then you can delete this file.") + "\n" if checkSetup and not self.initialChecks("samba"): return False # Добавление машины samba - if options.has_key('w'): + if 'w' in options: if self.addMachineSambaServer(userName, options): return True else: @@ -6146,25 +6146,25 @@ of version > 2.1.10, then you can delete this file.") + "\n" # Добавим пользователя LDAP optUnix = {} # id пользователя - if options.has_key('u'): + if 'u' in options: optUnix['u'] = options['u'] # Группа пользователя - if options.has_key('g'): + if 'g' in options: optUnix['g'] = options['g'] # Группы в которые входит пользователь - if options.has_key('G'): + if 'G' in options: optUnix['G'] = options['G'] # Полное имя пользователя - if options.has_key('c'): + if 'c' in options: optUnix['c'] = options['c'] # shell - if options.has_key('s'): + if 's' in options: optUnix['s'] = options['s'] # Домашняя директория - if options.has_key('d'): + if 'd' in options: optUnix['d'] = options['d'] # Cделаем пользователя видимым - if optUnix.has_key('u'): + if 'u' in optUnix: try: int(optUnix['u']) except: @@ -6199,11 +6199,11 @@ of version > 2.1.10, then you can delete this file.") + "\n" if textLine != False: flagError = False - if options.has_key('G'): + if 'G' in options: # Изменяем Samba группы пользователя userGroups = options['G'].split(',') data = self.searchUnixAndSambaGroups(userGroups, True) - if data and type(data) == types.TupleType: + if data and type(data) == tuple: userGroupNamesUnix, userGroupNamesSamba = data else: flagError = True @@ -6294,12 +6294,13 @@ of version > 2.1.10, then you can delete this file.") + "\n" uid = int(resPasswd.split(":")[2]) gid = int(resPasswd.split(":")[3]) # Не удаляемые директории - notDeletedDirs = filter(lambda x:x and os.path.exists(x), - (createDirHome,createDirLogon, + notDeletedDirs = [x for x in (createDirHome, createDirLogon, createDirWin7Profile, - createDirWinProfile,createDirLinProfile)) + createDirWinProfile, createDirLinProfile) + if x and os.path.exists(x)] + if (resPasswd or resSearchUnix) and\ - (options.has_key('n') or int(uid) >=1000): + ('n' in options or int(uid) >=1000): # Cоздаем домашнюю директорию if createDirHome: if not self.createUserDir(uid, gid, createDirHome): @@ -6417,7 +6418,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) return False else: findUsers = [] - if res[0][0][1].has_key('memberUid'): + if 'memberUid' in res[0][0][1]: usersInGroup = res[0][0][1]['memberUid'] for userName in usersNames: if userName in usersInGroup: @@ -6574,7 +6575,7 @@ Samba and Unix services") %", ".join(exclGroup) return False # Если группа существует выходим без ошибки flagSearchGroups = True - if options.has_key('f'): + if 'f' in options: flagSearchGroups = False if flagSearchGroups and\ self.servUnixObj.searchGroupGroupName(groupName): @@ -6595,7 +6596,7 @@ Samba and Unix services") %", ".join(exclGroup) self.clVars.Set("ur_group",groupName) # номер группы gid = str(self.servUnixObj.getMaxGid()) - if options.has_key('g'): + if 'g' in options: gid = options['g'] try: int(gid) @@ -6613,7 +6614,7 @@ Samba and Unix services") %", ".join(exclGroup) return False groupSid = "" # Получаем sid - if options.has_key('s'): + if 's' in options: # Проверяем кoрректность sid sidRe = re.compile("^S-(?:\d+-)+\d+$") if not sidRe.search(options['s']): @@ -6626,7 +6627,7 @@ Samba and Unix services") %", ".join(exclGroup) return False # Получаем samba rid sambaRid = str(2*int(gid)+1001) - if options.has_key('r'): + if 'r' in options: try: int(options['r']) except: @@ -6640,7 +6641,7 @@ Samba and Unix services") %", ".join(exclGroup) return False # По умолчанию тип группы - доменная группа groupType = "2" - if options.has_key('t'): + if 't' in options: try: int(options['t']) except: @@ -6660,20 +6661,20 @@ Samba and Unix services") %", ".join(exclGroup) self.clVars.Set("ur_group_id", gid) # Комментарий к группе gecos = self.servUnixObj.groupGecos - if options.has_key('c'): + if 'c' in options: gecos = options['c'] self.clVars.Set("ur_group_comment",gecos) ldifFile = self.ldifFileGroup groupLdif = self.createLdif(ldifFile) if not groupLdif: - print self.getError() + print(self.getError()) return False if not self.ldapObj.getError(): self.ldapObj.ldapAdd(groupLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False - if options.has_key('p'): + if 'p' in options: sys.stdout.write(gid) else: if printSuccess: @@ -6750,7 +6751,7 @@ Samba and Unix services") %", ".join(exclGroup) self.printERROR(_("group name not found in Samba service")) return False # Добавляем список пользователей в группу - if options.has_key('a'): + if 'a' in options: # добавляемые пользователи в группу users = options['a'].split(',') res = self.addUsersGroupSamba(users, groupName) @@ -6762,7 +6763,7 @@ Samba and Unix services") %", ".join(exclGroup) " " + str(groupName)) return False # Удаляем список пользователей из группы - if options.has_key('d'): + if 'd' in options: # удаляемые пользователи из группы users = options['d'].split(',') res = self.delUsersGroupSamba(users, groupName) @@ -6775,7 +6776,7 @@ Samba and Unix services") %", ".join(exclGroup) return False modGroupName = groupName # Изменяем имя группы - if options.has_key('n'): + if 'n' in options: newGroupName = options['n'] if self.servUnixObj.searchUnixGroupName(newGroupName): self.printERROR( @@ -6799,7 +6800,7 @@ Samba and Unix services") %", ".join(exclGroup) return False modAttrs = [] # Изменяем тип группы - if options.has_key('t'): + if 't' in options: try: int(options['t']) except: @@ -6814,7 +6815,7 @@ Samba and Unix services") %", ".join(exclGroup) groupType = options['t'] modAttrs.append((ldap.MOD_REPLACE, 'sambaGroupType', groupType)) # Изменяем комментарий к группе - if options.has_key('c'): + if 'c' in options: gecos = options['c'] modAttrs.append((ldap.MOD_REPLACE, 'description', gecos)) modAttrs.append((ldap.MOD_REPLACE, 'displayName', gecos)) @@ -6822,15 +6823,15 @@ Samba and Unix services") %", ".join(exclGroup) groupDN = self.addDN("cn=" + modGroupName, self.relGroupsDN) res = self.modAttrsDN(groupDN, modAttrs) if res: - if options.has_key('c'): + if 'c' in options: self.printSUCCESS(_("Modified group comment")) - if options.has_key('t'): + if 't' in options: self.printSUCCESS(_("Modified group type")) return True else: - if options.has_key('c'): + if 'c' in options: self.printERROR(_("Can not modify group comment")) - if options.has_key('t'): + if 't' in options: self.printERROR(_("Can not modify group type")) return False return True @@ -6840,7 +6841,7 @@ Samba and Unix services") %", ".join(exclGroup) machineLogin = machineName.replace('$','') + "$" res = self.searchSambaMachine(machineLogin) if res: - if res[0][0][1].has_key('sambaSID'): + if 'sambaSID' in res[0][0][1]: self.printERROR(_("machine")+" "+machineLogin+" "+\ "is found in Samba service") return True @@ -6883,8 +6884,8 @@ Samba and Unix services") %", ".join(exclGroup) self.clVars должен быть определен """ - print _("Enter the allowed ip addresses and network for %s service")\ - %"Samba" + " (" + _("comma or space delimited") + ")" + print(_("Enter the allowed ip addresses and network for %s service")\ + %"Samba" + " (" + _("comma or space delimited") + ")") strPrompt = _("allow networks: ") netAllow = self.clVars.Get("sr_samba_net_allow") strNetAllow = "" @@ -6905,7 +6906,7 @@ Samba and Unix services") %", ".join(exclGroup) # Создаем объект переменных и начальная проверка if not self.initialChecksSetup(): return False - if options.has_key("f"): + if "f" in options: forceOptions = True if self.clVars.Get("sr_unix_set") != "on": self.printERROR(_("Unix service is not setuped")) @@ -6932,13 +6933,13 @@ Samba and Unix services") %", ".join(exclGroup) _("input 'yes'") +", "+ _("if not 'no'") if not self.dialogYesNo(messDialog): return True - if options.has_key("a"): + if "a" in options: # Получаем от пользователя доверительные сети allowNet = self.getAllowNet() if not allowNet: return False else: - if options.has_key("a"): + if "a" in options: # Получаем от пользователя доверительные сети allowNet = self.getAllowNet() if not allowNet: @@ -6974,7 +6975,7 @@ Samba and Unix services") %", ".join(exclGroup) # Устанавливаем доступные сети self.clVars.Set("sr_samba_net_allow",allowNet,True) # Задаем рабочую группу (домен) - if options.has_key("w"): + if "w" in options: workgroup = options['w'].strip() if len(workgroup)>15: self.printERROR(_("A very long name of the command line \ @@ -6982,10 +6983,10 @@ options '-w, --workgroup'")) return False self.clVars.Set("sr_samba_domain",workgroup) # Задаем netbios имя - if options.has_key("n"): + if "n" in options: netbios = options['n'].strip() # Проверка на неравенство workgroup и netbios - if options.has_key("w") and workgroup == netbios: + if "w" in options and workgroup == netbios: self.printERROR(_("Value of command line option \ '-w, --workgroup' equal to value of command line option '-n, --netbios'")) return False @@ -7059,7 +7060,7 @@ options '-w, --workgroup'")) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False self.printOK(_("Added ldif file") + " ...") for service_initd, service_name in [("samba", "Samba"), ("calculate-profile", "Calculate Profile")]: @@ -7133,12 +7134,12 @@ options '-w, --workgroup'")) # права и владелец /var/calculate/remote if os.path.exists(remotePath): os.chown(remotePath,0,int(cl.gid)) - os.chmod(remotePath,02755) + os.chmod(remotePath,0o2755) # изменяем владельца remote на client if not os.path.exists(remoteEnvFile): fd = os.open(remoteEnvFile, os.O_CREAT) os.close(fd) - os.chmod(remoteEnvFile, 0640) + os.chmod(remoteEnvFile, 0o640) if os.path.exists(remoteEnvFile): os.chown(remoteEnvFile,0,int(cl.gid)) if not self.setDaemonAutostart("slapd"): @@ -7187,7 +7188,7 @@ options '-w, --workgroup'")) _("Samba user %s is not found")%str(userName)) return False # отключаем samba account - if options.has_key('l'): + if 'l' in options: textLine = self.execProg("smbpasswd -d %s" %(userName)) if textLine == False: self.printERROR(_("Can not disable Samba user")+ " "+\ @@ -7196,7 +7197,7 @@ options '-w, --workgroup'")) else: self.printSUCCESS(_("Disabled Samba user %s")%str(userName)) # включаем Samba account - if options.has_key('u'): + if 'u' in options: textLine = self.execProg("smbpasswd -e %s" %(userName)) if textLine == False: self.printERROR(_("Can not enable Samba user")+ " "+\ @@ -7204,14 +7205,14 @@ options '-w, --workgroup'")) return False else: self.printSUCCESS(_("Enabled Samba user %s")%str(userName)) - if not options or options.has_key('s'): + if not options or 's' in options: optPasswd = {"p":""} userPwd = self.getUserPassword(optPasswd, "p", False) if userPwd == False: return False if userPwd: # Опция s пароль только для Samba - if not options.has_key('s'): + if 's' not in options: if not self.servUnixObj.modUserUnixPasswd(userName,{}, userPwd): return False @@ -7240,7 +7241,7 @@ options '-w, --workgroup'")) str(userName)) return False # отключаем Samba account - if options.has_key('L'): + if 'L' in options: textLine = self.execProg("smbpasswd -d %s" %(userName)) if textLine == False: self.printERROR(_("Can not disable Samba user")+ " "+\ @@ -7249,7 +7250,7 @@ options '-w, --workgroup'")) else: self.printSUCCESS(_("Disabled Samba user %s")%str(userName)) # включаем samba account - elif options.has_key('U'): + elif 'U' in options: textLine = self.execProg("smbpasswd -e %s" %(userName)) if textLine == False: self.printERROR(_("Can not enable Samba user")+ " "+\ @@ -7258,14 +7259,14 @@ options '-w, --workgroup'")) else: self.printSUCCESS(_("Enabled Samba user %s")%str(userName)) # модифицируем пароль - if options.has_key('P') or options.has_key('p'): + if 'P' in options or 'p' in options: pwDialog = [_("New SMB password"), _("Retype new SMB password")] userPwd = self.getUserPassword(options, "p", "P", pwDialog) if userPwd == False: return False # Опция s пароль только для Samba - if not options.has_key('s'): + if 's' not in options: if not self.servUnixObj.modUserUnixPasswd(userName,{}, userPwd): return False @@ -7276,17 +7277,17 @@ options '-w, --workgroup'")) return False self.printSUCCESS(_("Modified Samba user password")) - if options.has_key("g"): + if "g" in options: optUnix = {'g':options['g']} if not self.servUnixObj.modUserUnixServer(userName, optUnix, True, True): return False # изменяем Unix и Samba группы в которые включен пользователь - if options.has_key("G"): + if "G" in options: # Изменяем Samba группы пользователя userGroups = options['G'].split(',') data = self.searchUnixAndSambaGroups(userGroups, True) - if data and type(data) == types.TupleType: + if data and type(data) == tuple: userGroupNamesUnix, userGroupNamesSamba = data else: return False @@ -7309,9 +7310,9 @@ options '-w, --workgroup'")) if printSuccess: self.printSUCCESS(_("Replaced list of supplementary group")) # Изменяем комментарий к пользователю - if options.has_key('c'): + if 'c' in options: comment = options['c'] - if res[0][0][1].has_key('displayName'): + if 'displayName' in res[0][0][1]: modAttrs = [(ldap.MOD_REPLACE, 'displayName', comment)] else: modAttrs = [(ldap.MOD_ADD, 'displayName', comment)] @@ -7388,7 +7389,7 @@ class servLdap(shareLdap): try: FD = open (fileName, "w+") FD.close() - os.chmod(fileName,0600) + os.chmod(fileName,0o600) FD = open (fileName, "w+") FD.write(data) FD.close() @@ -7444,7 +7445,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) # В случае создания сервера репликации из файла backup c # другого компьютера replServices = [] - if options.has_key("repl"): + if "repl" in options: # Находим имена сервисов репликации для этого сервера # и инициализируем переменные replServices = self.getArchReplServices() @@ -7467,9 +7468,9 @@ outdated. If the backup is obsolete, use cl-backup-server.")) return False verbose = False opt = {} - if options.has_key("v"): + if "v" in options: opt['v'] = '' - if options.has_key("a"): + if "a" in options: opt['a'] = '' # Сервисы для которых не будет задаваться вопрос о доступных сетях # при включенной опции allow @@ -7497,7 +7498,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) self.printERROR(clProf.getError()) return False else: - if verbose and type(data) == types.TupleType: + if verbose and type(data) == tuple: dirs, files = data return files return True @@ -7552,7 +7553,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) # Настройка прокси if serviceUpdate in ["all","proxy"]: # Порт для прокси сервера - if options.has_key("p"): + if "p" in options: proxyPort = options['p'] try: numberProxyPort = int(proxyPort) @@ -7561,7 +7562,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) return False proxyPort = str(numberProxyPort) self.clVars.Set("sr_proxy_port", proxyPort, True) - if options.has_key("host"): + if "host" in options: fullHostName = options['host'] if not "." in fullHostName: fullHostName = "%s.%s" %(fullHostName, @@ -7574,7 +7575,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) return False history,history_domain,history_path = \ self.getMailHistoryData(options) - if options.has_key("t"): + if "t" in options: mailType = options['t'] if mailType: if not set(mailType.split(",")) <= set(["imap","pop3"]): @@ -7587,7 +7588,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) self.printERROR(_("Мail type incorrect")) return False self.clVars.Set("sr_mail_type", mailType) - if options.has_key("c"): + if "c" in options: mailCrypt = options['c'] if not mailCrypt in ["none", "tls"]: self.printERROR(_("Мail encryption not 'none' or 'tls'")) @@ -7602,7 +7603,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) # Устанавливаем основной хост jabber cервиса if not self.createJabberCertificate(): return False - if options.has_key("host"): + if "host" in options: newHostName = options['host'] if not "." in newHostName: newHostName = "%s.%s" %(newHostName, @@ -7618,7 +7619,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) jabberHosts = ",".join(unicHostsList) self.clVars.Set("sr_jabber_hosts",jabberHosts,True) # Устанавливаем дополнительные хосты jabber cервиса - if options.has_key("hosts"): + if "hosts" in options: hosts = options['hosts'].split(",") jabberHostsList = [self.clVars.Get("sr_jabber_host")] for host in hosts: @@ -7670,7 +7671,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) self.clVars.Set("ld_%s_pw"%servicePwd, adminPw, True) # Наложение профилей verbose = False - if options.has_key("v"): + if "v" in options: verbose = True # Cервисы которые рестартуют servicesRestart = [] @@ -7685,7 +7686,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) if service == "samba": # Получаем от пoльзователя доверительные сети # для сервиса Samba - if options.has_key("a") and\ + if "a" in options and\ not service in noInputAllowNetServices: self.servSambaObj.clVars = self.clVars if not self.servSambaObj.getAllowNet(): @@ -7732,7 +7733,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) if service == "mail": # Получаем от пользователя доверительные сети # для сервиса Mail - if options.has_key("a") and\ + if "a" in options and\ not service in noInputAllowNetServices: self.servMailObj.clVars = self.clVars if not self.servMailObj.getAllowNet(): @@ -7745,7 +7746,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) if service == "proxy": # Получаем от пользователя доверительные сети # для сервиса Proxy - if options.has_key("a") and\ + if "a" in options and\ not service in noInputAllowNetServices: self.servProxyObj.clVars = self.clVars if not self.servProxyObj.getAllowNet(): @@ -7767,7 +7768,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) if not files: flagError = True break - if verbose and type(files) == types.ListType: + if verbose and type(files) == list: self.printSUCCESS(_("Updating config from service %s")\ %self.printNameService(service)) for applyFile in files: @@ -7839,7 +7840,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) if not flagError and serviceUpdate in ["all","jabber"]: # Замена имени хоста для сервиса Jabber в LDAP - if options.has_key("host"): + if "host" in options: if self.clVars.Get("sr_jabber_host") != previousJabberHost: # Установка в LDAP ветке Jabber cервиса нового имени хоста if not self.servJabberObj.setHostName(newHostName, @@ -7961,7 +7962,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) foundFiles = clProf.scanProfiles(serviceName) if not foundFiles: return [] - foundFiles = filter(lambda x: os.path.exists(x), foundFiles) + foundFiles = [x for x in foundFiles if os.path.exists(x)] return foundFiles def backupNotLdap(self): @@ -8045,7 +8046,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) # если существуют удаляем файлы в /tmp self.removeTmpFiles() if os.path.exists(bFile): - os.chmod(bFile,0600) + os.chmod(bFile,0o600) self.printSUCCESS(_("Created archive file") + ": " +\ str(bFile)) return True @@ -8306,8 +8307,8 @@ service %s")%service replArchFilesUnix.append(additFile) replArchFilesUnix = self.unicList(replArchFilesUnix) # Удаляем начальный "/" - replArchFilesUnix = map(lambda x:\ - "/".join(filter(lambda y:y ,x.split("/"))),replArchFilesUnix) + replArchFilesUnix = ["/".join(y for y in x.split("/") if y) + for x in replArchFilesUnix] replArchFilesUnix.sort() if "samba" in replServices: # Дополнительные файлы добавляемые в архив @@ -8318,8 +8319,8 @@ service %s")%service replArchFilesSamba.append(additFile) replArchFilesSamba += replArchFilesUnix # Удаляем начальный "/" - replArchFilesSamba = map(lambda x:\ - "/".join(filter(lambda y:y ,x.split("/"))),replArchFilesSamba) + replArchFilesSamba = ["/".join(y for y in x.split("/") if y) + for x in replArchFilesSamba] replArchFilesSamba = self.unicList(replArchFilesSamba) replArchFilesSamba.sort() if "mail" in replServices: @@ -8335,9 +8336,8 @@ service %s")%service additFiles = list(set(additFilesMailUnix)|set(additFiles)) for additFile in additFilesMailUnix: replArchFilesMailUnix.append(additFile) - replArchFilesMailUnix = map(lambda x:\ - "/".join(filter(lambda y:y ,x.split("/"))),\ - replArchFilesMailUnix) + replArchFilesMailUnix = ["/".join(y for y in x.split("/") if y) + for x in replArchFilesMailUnix] replArchFilesMailUnix = self.unicList(replArchFilesMailUnix) replArchFilesMailUnix.sort() if "samba" in replServices: @@ -8346,14 +8346,13 @@ service %s")%service additFiles = list(set(additFilesMailSamba)|set(additFiles)) for additFile in additFilesMailSamba: replArchFilesMailSamba.append(additFile) - replArchFilesMailSamba = map(lambda x:\ - "/".join(filter(lambda y:y ,x.split("/"))),\ - replArchFilesMailSamba) + replArchFilesMailSamba = ["/".join(y for y in x.split("/") if y) + for x in replArchFilesMailSamba] replArchFilesMailSamba=self.unicList(replArchFilesMailSamba) replArchFilesMailSamba.sort() # Удаляем начальный "/" - replArchFilesMail = map(lambda x:\ - "/".join(filter(lambda y:y ,x.split("/"))),replArchFilesMail) + replArchFilesMail = ["/".join(y for y in x.split("/") if y) + for x in replArchFilesMail] replArchFilesMail = self.unicList(replArchFilesMail) replArchFilesMail.sort() for additFile in additFiles: @@ -8424,15 +8423,14 @@ service %s")%service return False # Удаляем dovecot, procmailrc из списка файлов # а также ненужные алиасы - replArchFilesMail = map(lambda x:"/".join(x),\ - filter(lambda x:\ - not 'dovecot' in x and\ - not 'procmailrc' == x[-1] and\ - not 'ldap-aliases-gr.cf' == x[-1] and\ - not 'ldap-aliases.cf' == x[-1] and\ - not 'ldap-recipient-gr.cf' == x[-1] and\ - not 'ldap-recipient.cf' == x[-1],\ - map(lambda x:x.split("/"),replArchFilesMail))) + replArchFilesMail = ["/".join(x) + for x in (y.split("/") for y in replArchFilesMail) + if not 'dovecot' in x and + not 'procmailrc' == x[-1] and + not 'ldap-aliases-gr.cf' == x[-1] and + not 'ldap-aliases.cf' == x[-1] and + not 'ldap-recipient-gr.cf' == x[-1] and + not 'ldap-recipient.cf' == x[-1]] if not self.savePrivateFile (self.replListFileMail, "\n".join(replArchFilesMail)): self.printERROR(_("Can not create list archive files")+\ @@ -8483,7 +8481,7 @@ service %s")%service # если существуют удаляем файлы в /tmp self.removeTmpFiles() if os.path.exists(bFile): - os.chmod(bFile,0600) + os.chmod(bFile,0o600) self.printSUCCESS(_("Created archive file") + ": " +\ str(bFile)) return True @@ -8493,7 +8491,7 @@ service %s")%service return False def backupLdapServer(self, options): - if not options or (options and options.has_key("b")): + if not options or (options and "b" in options): # Создаем объект переменных clVars self.createClVars(self.clVars) # находим установленные сервисы @@ -8508,7 +8506,7 @@ service %s")%service return self.backupServer() else: return self.backupNotLdap() - if options.has_key("r"): + if "r" in options: return self.restoreServer() def startAllSetupServices(self): @@ -8522,7 +8520,7 @@ service %s")%service # заменяем mail на mail_relay if set(["mail","ldap"]) == set(servInstalled) and\ self.clVars.Get("sr_mail_relay_set") == "on": - servInstalled = filter(lambda x: x!="mail",servInstalled) +\ + servInstalled = [x for x in servInstalled if x != "mail"] +\ ["mail_relay"] return self.startServices(servInstalled) @@ -8565,7 +8563,7 @@ service %s")%service self.printERROR(_('Can not execute "%s"')%strCmd) return False # удаляем из элементов переводы строк - archFiles = map(lambda x: "".join(x.split('\n')),textListFiles) + archFiles = ("".join(x.split('\n')) for x in textListFiles) if self.archLdifFile[1:] in archFiles: return True return False @@ -8582,7 +8580,7 @@ service %s")%service self.printERROR(_('Can not execute "%s"')%strCmd) return False # удаляем из элементов переводы строк - archFiles = map(lambda x: "".join(x.split('\n')),textListFiles) + archFiles = ["".join(x.split('\n')) for x in textListFiles] flagError = False # Находим в списке файлов файлы списки для сервисов listReplFiles = list(set([self.replListFileSamba[1:], @@ -8747,8 +8745,8 @@ for running replication")%bFile) allArchFiles = [self.replArchLdifFileMail, self.replListFileMail] # Удаляем начальный '/' - allArchFiles = map(lambda x:\ - "/".join(filter(lambda y:y ,x.split("/"))),allArchFiles) + allArchFiles = ["/".join(y for y in x.split("/") if y) + for x in allArchFiles] # Удаляем временные файлы self.removeTmpFiles() # Сохраняем файл - список извлекаемых файлов (файл ldif) @@ -8785,7 +8783,7 @@ for running replication")%bFile) # Добавляем в базу из ldif self.ldapObj.ldapAdd(ldif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False # Останавливаем LDAP сервер if not self.stopLdapServer(): @@ -8941,7 +8939,7 @@ for running replication")%bFile) while ldapObj.getError(): try: # Задержка - wait.next() + next(wait) except StopIteration: break # Очистка ошибки @@ -8966,7 +8964,7 @@ for running replication")%bFile) # Принудительная установка forceOptions = False self.createClVars() - if options.has_key("f"): + if "f" in options: forceOptions = True if self.clVars.Get("sr_ldap_set") == "on" and\ not forceOptions: @@ -9052,7 +9050,7 @@ for running replication")%bFile) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False self.printOK(_("Added ldif file") + " ...") # Второй проход, @@ -11464,7 +11462,7 @@ service") catDir = os.path.join(pkgDir,category) package = "%s-"%package if not (os.path.exists(catDir) and - filter(lambda x:x.startswith(package),os.listdir(catDir))): + [x for x in os.listdir(catDir) if x.startswith(package)]): self.printERROR(_("Package '%s' is not installed")%pkg) return False return True @@ -11488,7 +11486,7 @@ service") # если установки параметрв не произошло if not datavars.flFromCmdParam(options['s']): # вывод - print _("Bad enviroment parameters") + print(_("Bad enviroment parameters")) return False # если опция отображения параметров if 'e' in options: @@ -11538,9 +11536,9 @@ service") """Записывает в аттрибут self.allServ названия всех сервисов""" sServ = re.compile("\s*([^\s]+)\s*") for par in self.data: - if par.has_key('helpChapter') and\ + if 'helpChapter' in par and\ par['helpChapter'] == _("Services") and\ - par.has_key('help') and self.access(par): + 'help' in par and self.access(par): res = sServ.search(par['help']) if res: self.allServ.append(res.group(1)) @@ -11572,7 +11570,7 @@ class servFtp(shareLdap): """Начальная настройка FTP сервиса""" # Принудительная установка forceOptions = False - if options.has_key("f"): + if "f" in options: forceOptions = True # Создаем объект переменных и начальная проверка if not self.initialChecksSetup(): @@ -11668,7 +11666,7 @@ class servFtp(shareLdap): if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False # Записываем данные администратора сервиса FTP ldapParser = iniLdapParser() @@ -11708,12 +11706,12 @@ class servFtp(shareLdap): ftpTmpPath = os.path.join(ftpPath,"tmp") if not os.path.exists(ftpTmpPath): os.makedirs(ftpTmpPath) - os.chmod(ftpTmpPath,0777) + os.chmod(ftpTmpPath,0o777) #cоздаем директорию pub ftpPubPath = os.path.join(ftpPath,"pub") if not os.path.exists(ftpPubPath): os.makedirs(ftpPubPath) - os.chmod(ftpPubPath,0755) + os.chmod(ftpPubPath,0o755) #запишем переменные для клиента clientVars = ["cl_remote_ftp"] if not self.saveVarsClient(clientVars): @@ -11754,7 +11752,7 @@ class servFtp(shareLdap): # Изменяемые аттрибуты пользователя modAttrs = [] # Изменяем комментарий к пользователю - if options.has_key('c'): + if 'c' in options: comment = options['c'] modAttrs += [(ldap.MOD_REPLACE, 'sn', comment), (ldap.MOD_REPLACE, 'cn', comment)] @@ -11766,7 +11764,7 @@ class servFtp(shareLdap): userPwdHash = self.getHashPasswd(userPwd, self.userCrypt) if not userPwdHash: return False - if resSearch[0][0][1].has_key('userPassword'): + if 'userPassword' in resSearch[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -11777,9 +11775,9 @@ class servFtp(shareLdap): DN = self.addDN("uid="+uid, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False - if options.has_key('c'): + if 'c' in options: self.printSUCCESS(_("Modified comment (full name)")) - if options.has_key('P') or options.has_key('p'): + if 'P' in options or 'p' in options: self.printSUCCESS(_("Modified FTP user password")) return True @@ -11803,7 +11801,7 @@ class servFtp(shareLdap): userPwdHash = self.getHashPasswd(userPwd, self.userCrypt) if not userPwdHash: return False - if resSearch[0][0][1].has_key('userPassword'): + if 'userPassword' in resSearch[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -11873,7 +11871,7 @@ class servFtp(shareLdap): # Флаг создания группы по умолчанию flagCreateUnixGroup = False # Группа пользователя - if options.has_key('g'): + if 'g' in options: optUnix['g'] = options['g'] else: optUnix['g'] = self.defaultUnixGroup["name"] @@ -11889,7 +11887,7 @@ class servFtp(shareLdap): if not self.servUnixObj.searchUnixGroupName(optUnix['g']): flagCreateUnixGroup = True # Полное имя пользователя - if options.has_key('c'): + if 'c' in options: optUnix['c'] = options['c'] # Если нужно создаем новую Unix группу if flagCreateUnixGroup: @@ -11910,10 +11908,10 @@ class servFtp(shareLdap): self.clVars.Set("ur_name", userName) #Полное имя пользователя fullNameUser = self.servUnixObj.fullNameUser - if options.has_key('c'): + if 'c' in options: fullNameUser = options['c'] else: - if resUnix and resUnix[0][0][1].has_key('cn'): + if resUnix and 'cn' in resUnix[0][0][1]: fullNameUser = resUnix[0][0][1]['cn'][0] self.clVars.Set("ur_fio",fullNameUser) if not userPwd: @@ -11940,7 +11938,7 @@ class servFtp(shareLdap): # Корневая FTP директория ftpDir = self.clVars.Get("sr_ftp_path") # FTP директория пользователя - if options.has_key('d') and options.has_key('m'): + if 'd' in options and 'm' in options: ftpUserDir = options['d'] if ftpUserDir[0] == "/": ftpUserDir = ftpUserDir[1:] @@ -11955,14 +11953,14 @@ class servFtp(shareLdap): self.ldapObj.ldapAdd(userLdif) # не переделывать на else if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False flagError = False # FTP директория пользователя - if not options.has_key('d'): + if 'd' not in options: ftpUserDir = os.path.join(ftpDir,"pub/users",userName) # Создаем FTP директорию пользователя - if options.has_key('m'): + if 'm' in options: if not self.createUserDir(uid, gid, ftpUserDir): flagError = True if flagError: @@ -12055,7 +12053,7 @@ class servRepl(shareLdap): clVars.flServer() calculate_ini = self.clVars.Get("cl_env_path") remoteIni = "" - if calculate_ini and type(calculate_ini) == types.ListType: + if calculate_ini and type(calculate_ini) == list: remoteIni = calculate_ini[0] if remoteIni: # проверить сущестование ini файла @@ -12171,8 +12169,8 @@ class servRepl(shareLdap): self.restoreLocalVar) # Получаем от пользователя доверительные сети для сервиса Samba # Переназначаем объект переменных - print _("Replications servers for Samba: %s")\ - % " ".join(replSambaServers) + print(_("Replications servers for Samba: %s")\ + % " ".join(replSambaServers)) self.servSambaObj.clVars = self.clVars if not self.servSambaObj.getAllowNet(): return False @@ -12199,8 +12197,8 @@ class servRepl(shareLdap): self.restoreRemoteClientVar = [] # Получаем от пользователя доверительные сети для сервиса Mail # Переназначаем объект переменных - print _("Replications servers for Mail: %s")\ - % " ".join(replMailServers) + print(_("Replications servers for Mail: %s")\ + % " ".join(replMailServers)) self.servMailObj.clVars = self.clVars if not self.servMailObj.getAllowNet(): return False @@ -12230,8 +12228,8 @@ class servRepl(shareLdap): self.restoreRemoteClientVar = [] # Получаем от пользователя доверительные сети для сервиса Mail # Переназначаем объект переменных - print _("Replications servers for Mail: %s")\ - % " ".join(replMailServers) + print(_("Replications servers for Mail: %s")\ + % " ".join(replMailServers)) self.servMailObj.clVars = self.clVars if not self.servMailObj.getAllowNet(): return False @@ -12247,15 +12245,15 @@ class servRepl(shareLdap): self.restoreLocalVar) # Получаем от пользователя доверительные сети для сервиса Samba # Переназначаем объект переменных - print _("Replications servers for Samba: %s")\ - % " ".join(replSambaServers) + print(_("Replications servers for Samba: %s")\ + % " ".join(replSambaServers)) self.servSambaObj.clVars = self.clVars if not self.servSambaObj.getAllowNet(): return False # Получаем от пользователя доверительные сети для сервиса Mail # Переназначаем объект переменных - print _("Replications servers for Mail: %s")\ - % " ".join(replMailServers) + print(_("Replications servers for Mail: %s")\ + % " ".join(replMailServers)) self.servMailObj.clVars = self.clVars if not self.servMailObj.getAllowNet(): return False @@ -12303,12 +12301,12 @@ class servRepl(shareLdap): # права и владелец /var/calculate/remote if os.path.exists(remotePath): os.chown(remotePath,0,int(cl.gid)) - os.chmod(remotePath,02755) + os.chmod(remotePath,0o2755) # изменяем владельца remote на client if not os.path.exists(remoteEnvFile): fd = os.open(remoteEnvFile, os.O_CREAT) os.close(fd) - os.chmod(remoteEnvFile, 0640) + os.chmod(remoteEnvFile, 0o640) if os.path.exists(remoteEnvFile): os.chown(remoteEnvFile,0,int(cl.gid)) return True @@ -12337,11 +12335,11 @@ class servRepl(shareLdap): os.path.exists(os.path.join(x, self.logOutFile)) or \ os.path.exists(os.path.join(x, self.srvFile)) or\ os.path.exists(os.path.join(x, self.deskFile)) - return filter(filterFunc, - [profileDir] + map(lambda x: os.path.join(profileDir, x),\ - filter(lambda x:\ - os.path.isdir(os.path.join(profileDir, x)) ,\ - os.listdir(profileDir)))) + return [x for x + in [profileDir] + [os.path.join(profileDir, y) + for y in os.listdir(profileDir) + if os.path.isdir(os.path.join(profileDir, y))] + if filterFunc(x)] @adminConnectLdap def deleteLogoutFile(self, userName, logoutFile): @@ -12380,7 +12378,7 @@ class servRepl(shareLdap): uid = int(resPasswd.split(":")[2]) gid = int(resPasswd.split(":")[3]) if uid == None or gid == None: - print _("User %s not found in Unix service") + print(_("User %s not found in Unix service")) return False winProfDir =\ os.path.join(self.clVars.Get("sr_samba_winprof_path"), @@ -12495,7 +12493,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False return True @@ -12525,7 +12523,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False # Если ветка Replication/Mail не существует - добавляем ее if not self.isReplMailDNExists(): @@ -12535,7 +12533,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) try: self.conLdap.add_s(self.clVars.Get("ld_repl_mail_dn"), entry) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR(_("LDAP Error") + ": " + e[0]['desc'].strip()) self.printERROR(errorMessage) return False @@ -12550,7 +12548,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) try: self.conLdap.add_s(self.clVars.Get("ld_repl_worked_dn"), entry) - except ldap.LDAPError, e: + except ldap.LDAPError as e: self.printERROR(_("LDAP Error") + ": " + e[0]['desc'].strip()) self.printERROR(errorMessage) return False @@ -12613,7 +12611,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) if fullDel: foundUsers = self.searchWorkedUser(userName+"@*") if foundUsers: - deleteUserNames = map(lambda x: x[0][1]["uid"][0], foundUsers) + deleteUserNames = (x[0][1]["uid"][0] for x in foundUsers) for delUser in deleteUserNames: delDN = self.addDN("uid=" + delUser, relWorkedDN) if not self.delDN(delDN): @@ -12683,7 +12681,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) rez = self.searchMailAlias(aliasName) if not rez: return True - if rez[0][0][1].has_key('filtersender'): + if 'filtersender' in rez[0][0][1]: attrDelete = [] relMailDN = self.getRelMailDN() aliasDN = self.addDN("cn=%s"%aliasName, relMailDN) @@ -12709,26 +12707,23 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) self.clVars.Set('sr_mail_host',fullHostName,True) mailHost = fullHostName # Получаем почтовые алиасы (почтовые адреса на других серверах) - userMails = filter(lambda x:\ - len(x.split("@"))==2 and x.split('@')[1] != mailHost,\ - filter(lambda x: "@" in x, srcMails)) + userMails = [x for x in (y for y in srcMails if "@" in y) + if len(x.split("@")) == 2 and x.split('@')[1] != mailHost] if userMails: # Внешний почтовый адрес пользователя (первый в списке) userMail = userMails[0] # Убирает первый адрес из списка - userMails = list(set(filter(lambda x: x != userMail, - userMails))) + userMails = list(set(x for x in userMails if x != userMail)) attrAppend = [] attrDelete = [] attrReplace = [] if filterHosts: domain = self.clVars.Get('os_net_domain') # Если необходимо добавляем домен к именам хостов - fHosts = map(lambda x: (not '.' in x and x+"."+domain) or x, - filterHosts) + fHosts = [(not '.' in x and x + "." + domain) or x for x in filterHosts] for host in fHosts: attrAppend.append((ldap.MOD_ADD, 'filtersender', host)) - if rez[0][0][1].has_key('filtersender'): + if 'filtersender' in rez[0][0][1]: attrDelete.append((ldap.MOD_DELETE, 'filtersender', None)) email = rez[0][0][1]["mail"][0] altEmails = rez[0][0][1]["mailAlternateAddress"] @@ -12776,21 +12771,19 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) self.clVars.Set('sr_mail_host',fullHostName,True) mailHost = fullHostName # Получаем почтовые алиасы (почтовые адреса на других серверах) - userMails = filter(lambda x:\ - len(x.split("@"))==2 and x.split('@')[1] != mailHost,\ - filter(lambda x: "@" in x, srcMails)) + userMails = [x for x in (y for y in srcMails if "@" in y) + if len(x.split("@")) == 2 and x.split('@')[1] != mailHost] if userMails: # Внешний почтовый адрес пользователя (первый в списке) userMail = userMails[0] # Убираем первый адрес из списка - userMails = list(set(filter(lambda x: x != userMail, - userMails))) + userMails = list(set(x for x in userMail if x != userMail)) self.clVars.Set("ur_mail", userMail) baseLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": "+self.ldapObj.getError().strip() + print(_("LDAP Error") + ": "+self.ldapObj.getError().strip()) return False modAttrs = [] relMailDN = self.getRelMailDN() @@ -12801,8 +12794,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) if filterHosts: domain = self.clVars.Get('os_net_domain') # Если необходимо добавляем домен к именам хостов - fHosts = map(lambda x: (not '.' in x and x+"."+domain) or x, - filterHosts) + fHosts = [(not '.' in x and x + "." + domain) or x for x in filterHosts] for host in fHosts: modAttrs.append((ldap.MOD_ADD, 'filtersender', host)) @@ -12825,12 +12817,12 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False rez = self.searchWorkedUser(userName) replHost = self.clVars.Get("ld_repl_host") if not replHost: - print _("Variable Error: not set a variable ld_repl_host") + print(_("Variable Error: not set a variable ld_repl_host")) return False if rez: host = rez[0][0][1]['host'][0] @@ -12842,7 +12834,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) if not self.modAttrsDN(DN, modAttrs): return False else: - print _("Can not add user %s in branch 'Replication'")%userName + print(_("Can not add user %s in branch 'Replication'")%userName) return False return True @@ -12916,7 +12908,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) uid = int(resPasswd.split(":")[2]) gid = int(resPasswd.split(":")[3]) if uid == None or gid == None: - print _("User %s not found in Unix service") + print(_("User %s not found in Unix service")) return False linProfDir =\ os.path.join(self.clVars.Get("sr_samba_linprof_path"), @@ -13156,7 +13148,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) if supportSections: sections = list(set(sections)-set(["command"])) sections = set(sections)-set(supportSections) - delSections = map(lambda x: x.split(","), sections) + delSections = (x.split(",") for x in sections) for delSect in delSections: txtConfig.delArea(delSect) # Если включена репликация и нет команды на упаковку @@ -13212,16 +13204,16 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) errMessages = [] # Опция выключает вывод cообщений на экран verboseMode = True - if options.has_key('s'): + if 's' in options: verboseMode = False login = "" logout = "" makeDir = "" - isLogin = options.has_key('login') - isLogout = options.has_key('logout') - isMakeDir = options.has_key('makedir') + isLogin = 'login' in options + isLogout = 'logout' in options + isMakeDir = 'makedir' in options dictOpt = {"login":isLogin, "logout":isLogout, "makedir":isMakeDir} - firstOpt = filter(lambda x: x[1] ,dictOpt.items()) + firstOpt = [x for x in dictOpt.items() if x[1]] lenOpt = len(firstOpt) if lenOpt == 1: if isLogin: @@ -13332,14 +13324,14 @@ incompatible")) errMessages = [] # Опция выключает вывод cообщений на экран verboseMode = True - if options.has_key('s'): + if 's' in options: verboseMode = False logout = "" makeDir = "" - isLogout = options.has_key('logout') - isMakeDir = options.has_key('makedir') + isLogout = 'logout' in options + isMakeDir = 'makedir' in options dictOpt = {"logout":isLogout, "makedir":isMakeDir} - firstOpt = filter(lambda x: x[1] ,dictOpt.items()) + firstOpt = [x for x in dictOpt.items() if x[1]] lenOpt = len(firstOpt) if lenOpt == 1: if isLogout: @@ -13519,7 +13511,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) if supportSections: sections = list(set(sections)-set(["command"])) sections = set(sections)-set(supportSections) - delSections = map(lambda x: x.split(","), sections) + delSections = (x.split(",") for x in sections) for delSect in delSections: txtConfig.delArea(delSect) # Если включена репликация и нет команды на упаковку @@ -13589,7 +13581,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) _("Samba user %s is not found")%str(userName)) return False # Проверка правильности предыдущего пароля - if resSamba[0][0][1].has_key('sambaNTPassword'): + if 'sambaNTPassword' in resSamba[0][0][1]: if userOldNTHash !=resSamba[0][0][1]['sambaNTPassword'][0]: self.printERROR( _("Invalid previous password for the user %s")\ @@ -13603,7 +13595,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) # Изменение пароля пользователя Unix # Изменяемые аттрибуты пользователя modAttrs = [] - if resUnix[0][0][1].has_key('userPassword'): + if 'userPassword' in resUnix[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -13626,7 +13618,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) ("sambaNTPassword",userNTHash)] resSambaAttr = resSamba[0][0][1] for attr, value in data: - if resSambaAttr.has_key(attr): + if attr in resSambaAttr: modAttrs.append((ldap.MOD_REPLACE, attr, value)) else: if attr!="sambaLMPassword": @@ -13701,7 +13693,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) if os.path.isdir(path): os.chdir(path) users = os.listdir(".") - users = filter(lambda x: os.path.isdir(x), users) + users = [x for x in users if os.path.isdir(x)] for dirName in users: # имя пользователя (исключая суффикс V2) userName = \ @@ -13790,7 +13782,7 @@ calculate-server") return False return True if not self.createUserFile(cronWeeklyFile, replCronFileContent, - 0, 0, 0744): + 0, 0, 0o744): return False return True @@ -13821,9 +13813,9 @@ calculate-server") self.printERROR(_('Can not execute "%s"')%strCmd) return False # Удаляем из элементов переводы строк - listCronLinesSrc = map(lambda x: x.split('\n')[0],listCronLines) + listCronLinesSrc = [x.split('\n')[0] for x in listCronLines] # Удаляем из элементов все начиная с # - listCronLines = map(lambda x: x.split("#")[0].strip(), listCronLinesSrc) + listCronLines = [x.split("#")[0].strip() for x in listCronLinesSrc] listCronLinesOut = [] i = 0 for textCron in listCronLines: @@ -13905,7 +13897,7 @@ use the new version. (openldap > 2.4)")%openLdapVesion) return False listGroupMail = [] for i in resSearch: - if i[0][1].has_key('filtersender'): + if 'filtersender' in i[0][1]: listGroupMail.append((i[0][1]["cn"][0], i[0][1]["mailAlternateAddress"], i[0][1]["filtersender"])) @@ -13921,7 +13913,7 @@ use the new version. (openldap > 2.4)")%openLdapVesion) # Определяем поддерживает ли openldap репликацию if not self.supportReplOpenldap(self.clVars): return False - if options.has_key('off'): + if 'off' in options: if self.clVars.Get("ld_repl_set") == "off": self.printWARNING(_("Replication off for all services")) return True @@ -13993,19 +13985,19 @@ file %s")%bFile) self.clVars.Write("ld_repl_set", "off") # Включаем репликацию self.clVars.Set("ld_repl_set", "on") - if not options.has_key('off') and\ - (not options.has_key('r') or not options['r']): + if 'off' not in options and\ + ('r' not in options or not options['r']): self.printERROR(\ _("Not specified replication servers \ (command line option '-r')")) return False - if options.has_key('off') and options.has_key('r'): + if 'off' in options and 'r' in options: self.printERROR(\ _("You can not use the option to '--off', \ together with option '-r'")) return False replServers = [] - if options.has_key('r'): + if 'r' in options: replServers = options['r'].split(',') # Преобразуем короткие имена в длинные hostName = self.clVars.Get('os_net_hostname') @@ -14032,29 +14024,28 @@ together with option '-r'")) self.printERROR(\ _("Set Replication error, Unix service not setuped")) return False - if options.has_key('r'): + if 'r' in options: replSambaServers = self.clVars.Get("ld_repl_samba_servers") replMailServers = self.clVars.Get("ld_repl_mail_servers") dictServers = {"samba":replSambaServers, "mail":replMailServers, "unix":",".join(replServers)} - listServersRepl = map(lambda x: (x[0],set(x[1].split(","))), - filter(lambda x: x[1], - dictServers.items())) + listServersRepl = [(x[0],set(x[1].split(","))) for x + in dictServers.items() if x[1]] # Все серверы репликации - replAllServers = list(reduce(lambda x,y: ('',x[1]|y[1]), - listServersRepl,("",set()))[1]) + replAllServers = list(reduce(lambda x, y: ('', x[1] | y[1]), + listServersRepl, ("", set()))[1]) # Серверы репликации для ветки Unix - replUnixServers = list(reduce(lambda x,y: ('',x[1]|y[1]), - filter(lambda x: x[0] in ['samba','unix'], - listServersRepl),("",set()))[1]) + replUnixServers = list(reduce(lambda x, y: ('', x[1] | y[1]), + [z for z in listServersRepl if z[0] in ['samba','unix']], + ("", set()))[1]) # Устанавливаем переменную серверы репл. для Unix сервиса self.clVars.Set("ld_repl_unix_servers", ",".join(replUnixServers),True) # Устанавливаем переменную серверы репл. для всех сервисов self.clVars.Set("ld_repl_servers", ",".join(replAllServers),True) - elif options.has_key('off'): + elif 'off' in options: # Выключаем репликацию для сервисов Samba и Mail if self.clVars.Get("ld_repl_mail_set") == "on" and\ self.clVars.Get("ld_repl_mail_servers"): @@ -14079,7 +14070,7 @@ together with option '-r'")) replUnixServers = self.clVars.Get("ld_repl_unix_servers") if replUnixServers: replUnixServers = replUnixServers.split(",") - if options.has_key('off'): + if 'off' in options: # Очищаем cерверы репликации Samba self.clVars.Set("ld_repl_samba_servers", "", True) self.clVars.Delete("ld_repl_samba_servers","local","server") @@ -14093,19 +14084,18 @@ together with option '-r'")) dictServers = {"samba":",".join(replServers), "mail":replMailServers, "unix":",".join(diffReplServers)} - listServersRepl = map(lambda x: (x[0],set(x[1].split(","))), - filter(lambda x: x[1], dictServers.items())) + listServersRepl = [(x[0], set(x[1].split(","))) for x in dictServers.items() if x[1]] # Все серверы репликации replAllServers = list(reduce(lambda x,y: ('',x[1]|y[1]), listServersRepl,("",set()))[1]) # Серверы репликации для ветки Unix - replUnixServers = list(reduce(lambda x,y: ('',x[1]|y[1]), - filter(lambda x: x[0] in ['samba','unix'], - listServersRepl),("",set()))[1]) + replUnixServers = list(reduce(lambda x, y: ('', x[1] | y[1]), + [z for z in listServersRepl if z[0] in ['samba','unix']], + ("", set()))[1]) # Серверы репликации для ветки Samba - replSambaServers = list(reduce(lambda x,y: ('',x[1]|y[1]), - filter(lambda x: x[0] in ['samba'], - listServersRepl),("",set()))[1]) + replSambaServers = list(reduce(lambda x, y: ('', x[1] | y[1]), + [z for z in listServersRepl if z[0] in ['samba']], + ("", set()))[1]) # Устанавливаем переменную серверы репл. для Samba сервиса self.clVars.Set("ld_repl_samba_servers", ",".join(replSambaServers),True) @@ -14124,7 +14114,7 @@ together with option '-r'")) _("Set Replication error, Mail service not setuped")) return False replUnixServers = self.clVars.Get("ld_repl_unix_servers") - if options.has_key('off'): + if 'off' in options: # Очищаем cерверы репликации Mail self.clVars.Set("ld_repl_mail_servers", "", True) self.clVars.Delete("ld_repl_mail_servers","local","server") @@ -14133,15 +14123,15 @@ together with option '-r'")) dictServers = {"samba":replSambaServers, "mail":",".join(replServers), "unix":replUnixServers} - listServersRepl = map(lambda x: (x[0],set(x[1].split(","))), - filter(lambda x: x[1], dictServers.items())) + listServersRepl = [(x[0], set(x[1].split(","))) + for x in dictServers.items() if x[1]] # Все серверы репликации - replAllServers = list(reduce(lambda x,y: ('',x[1]|y[1]), - listServersRepl,("",set()))[1]) + replAllServers = list(reduce(lambda x,y: ('', x[1] | y[1]), + listServersRepl, ("", set()))[1]) # Серверы репликации для ветки Mail - replMailServers = list(reduce(lambda x,y: ('',x[1]|y[1]), - filter(lambda x: x[0] in ['mail'], - listServersRepl),("",set()))[1]) + replMailServers = list(reduce(lambda x,y: ('', x[1] | y[1]), + [z for z in listServersRepl if z[0] in ['mail']], + ("", set()))[1]) # Устанавливаем переменную серверы репл. для Mail сервиса self.clVars.Set("ld_repl_mail_servers", ",".join(replMailServers),True) @@ -14163,7 +14153,7 @@ together with option '-r'")) #Cоединение с Ldap (администратор) if not shareLdap.getLdapObjInFile(self): return False - if options.has_key('r'): + if 'r' in options: # Проверяем существует ли id текущего сервера if not self.clVars.Get("ld_repl_id"): self.printERROR(_("Not found 'serverID' this server")) @@ -14172,7 +14162,7 @@ together with option '-r'")) # Делаем update cервиса Samba в случае опции off и не показываем # реплицируемые серверы if service == "unix" and self.clVars.Get("sr_samba_set") == "on" and\ - options.has_key('off'): + 'off' in options: if not self.servLdapObj.updateServer({},"samba",self.clVars, [],False): return False @@ -14210,9 +14200,8 @@ together with option '-r'")) # Получаем почтовые группы groupsMail = self.getGroupsMail() # объединяет usersMail и groupsMail - usersAndGroupsMail = map(lambda x: (len(x)==2 and\ - (x[0],x[1],[])) or x, reduce(lambda x, y: x+y,\ - map(lambda x: x or [], [usersMail,groupsMail]),[])) + usersAndGroupsMail = [(len(x) == 2 and (x[0], x[1], [])) or x + for x in reduce(lambda x, y: x + y, [z or [] for z in [usersMail,groupsMail]],[])] if usersAndGroupsMail: flagError = False for name, mails, hosts in usersAndGroupsMail: @@ -14258,15 +14247,15 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): strService = self.printNameService(service) # Информация сервиса DHCP # Информация о всех сетях DHCP - if service == "dhcp" and options.has_key("n"): + if service == "dhcp" and "n" in options: dhcpObj = dncpTxt() dataNets = dhcpObj.getDataInAllSubnet() dataList = [] for net, data in dataNets: dataTmp = [] - if data.has_key('net'): + if 'net' in data: dataTmp.append(data['net'][0]) - if data.has_key('mask'): + if 'mask' in data: dataTmp.append(data['mask'][0]) if len(dataTmp) == 2: dataList.append(["%s/%s"%(dataTmp[0],\ @@ -14279,7 +14268,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): repObj.printReport() return True # Информация о сети DHCP - if service == "dhcp" and options.has_key("N"): + if service == "dhcp" and "N" in options: # ip сети и сетевая маска /24 net = options["N"] # cоздаем объект DHCP @@ -14339,7 +14328,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): return True # Информация о статическом носте DHCP - if service == "dhcp" and options.has_key("H"): + if service == "dhcp" and "H" in options: hostname = options["H"] # Проверка правильности названия хоста if '.' in hostname: @@ -14379,13 +14368,13 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): return True # Информация о всех статических хостах DHCP - if service == "dhcp" and options.has_key("hosts"): + if service == "dhcp" and "hosts" in options: dhcpObj = dncpTxt() dataHosts = dhcpObj.getDataInAllHost() dataList = [] for hostname, data in dataHosts: ip = "" - if data.has_key("fixed-address"): + if "fixed-address" in data: if data["fixed-address"]: ip = data["fixed-address"][0] dataList.append([hostname,ip]) @@ -14398,8 +14387,8 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): return True # Информация о DNS - if service == "dns" and options.has_key("z") or options.has_key("Z") or\ - options.has_key("r"): + if service == "dns" and "z" in options or "Z" in options or\ + "r" in options: # cоздаем объект DNS servDnsObj = servDns() # Проверим установлен ли сервис dns @@ -14407,9 +14396,9 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): return False objTxtZone = dnsTxt() # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) # Информация о всех DNS зонах - if service == "dns" and options.has_key("z"): + if service == "dns" and "z" in options: # Зоны в файле namesZonesFile = objTxtZone.getAllNamesZones() if namesZonesFile == False: @@ -14417,15 +14406,13 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): # Зоны в LDAP namesZonesLDAP = servDnsObj.searchAllZonesInLDAP() # Подчиненные зоны - slaveZones = list(set(namesZonesFile)-set(namesZonesLDAP)) + slaveZones = list(set(namesZonesFile) - set(namesZonesLDAP)) # Обратные зоны if namesZonesLDAP: namesZonesLDAP.sort() - reverseZones = filter(lambda x: '.in-addr.arpa' in x,\ - namesZonesLDAP) + reverseZones = [x for x in namesZonesLDAP if '.in-addr.arpa' in x] # Прямые зоны - forwardZones = filter(lambda x: not '.in-addr.arpa' in x,\ - namesZonesLDAP) + forwardZones = [x for x in namesZonesLDAP if '.in-addr.arpa' not in x] # Формирование строки для отчета title=_("Information about the master DNS zones in LDAP") headerList = [_("DNS zone"), @@ -14434,12 +14421,10 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): # Получение домена getDomain = lambda x: not '.in-addr.arpa' in x and x or "" # Получение сети - getNet = lambda x: ".".join(map(lambda x:x,\ - reversed('.in-addr.arpa' in x and ["0/24"] +\ - x.rpartition(".in-addr.arpa")[0].split(".") or []))) - dataList = map(lambda x:\ - [x, getDomain(x), getNet(x)],\ - forwardZones + reverseZones) + getNet = lambda x: ".".join(x for x + in reversed('.in-addr.arpa' in x and ["0/24"] +\ + x.rpartition(".in-addr.arpa")[0].split(".") or [])) + dataList = [[x, getDomain(x), getNet(x)] for x in forwardZones + reverseZones] repObj = report(title, headerList, dataList) repObj.printReport() if slaveZones: @@ -14454,30 +14439,26 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): if xmlNodes: masterIPNode = xmlNodes[0] xmlNodes = xpath.Evaluate( "child::value", masterIPNode) - ips = map(lambda x: x.firstChild.nodeValue.strip(),\ - xmlNodes) + ips = (x.firstChild.nodeValue.strip() for x in xmlNodes) flagAddIPs = True slaveIPs.append(",".join(ips)) if not flagAddIPs: slaveIPs.append("") - reverseZones = filter(lambda x: '.in-addr.arpa' in x,\ - slaveZones) + reverseZones = [x for x in slaveZones if '.in-addr.arpa' in x] # Прямые зоны - forwardZones = filter(lambda x: not '.in-addr.arpa' in x,\ - slaveZones) + forwardZones = [x for x in slaveZones if '.in-addr.arpa' not in x] # Формирование строки для отчета title=_("Information about the slave DNS zones in \ /etc/bind/named.conf") headerList = [_("DNS zone"),_("IP master DNS servers")] - dataList = map(lambda x: [x], forwardZones + reverseZones) - dataList = map(lambda x: dataList[x]+[slaveIPs[x]],\ - range(len(dataList))) + dataList = ([x] for x in forwardZones + reverseZones) + dataList = [dataList[x] + [slaveIPs[x]] for x in range(len(dataList))] repObj = report(title, headerList, dataList) - print "" + print("") repObj.printReport() return True # Информация о DNS зоне - if service == "dns" and options.has_key("Z"): + if service == "dns" and "Z" in options: zoneName = options["Z"] if not zoneName: self.printERROR(_('Incorrect zone name')) @@ -14523,9 +14504,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): if xmlNodes: masterIPNode = xmlNodes[0] xmlNodes = xpath.Evaluate( "child::value", masterIPNode) - ipMasterServers = map(lambda x:\ - x.firstChild.nodeValue.strip(),\ - xmlNodes) + ipMasterServers = [x.firstChild.nodeValue.strip() for x in xmlNodes] if not ipMasterServers: self.printERROR(_("The program does not support information \ for %s DNS zone")%zoneName) @@ -14554,12 +14533,12 @@ for %s DNS zone")%zoneName) # Все авторитативные сервера зоны nSRecords = zoneData[0][0][1]['nSRecord'] mXRecords = [] - if zoneData[0][0][1].has_key('mXRecord'): + if 'mXRecord' in zoneData[0][0][1]: mXRecords = zoneData[0][0][1]['mXRecord'] aRecords = [] - if zoneData[0][0][1].has_key('aRecord'): + if 'aRecord' in zoneData[0][0][1]: aRecords = zoneData[0][0][1]['aRecord'] - soaData = map(lambda x: delDot(x), soaRecord.split(" ")) + soaData = [delDot(x) for x in soaRecord.split(" ")] if len(soaData)!=7: self.printERROR(_("Incorrect SOA-record in DNS zone %s")\ %zoneName) @@ -14591,13 +14570,13 @@ for %s DNS zone")%zoneName) [_("Expiry"), expiry], [_("Minimum"), minimum]] if mXRecords: - map(lambda x:dataList.insert(2,["",x]) ,reversed(mXRecords[1:])) + [dataList.insert(2, ["", x]) for x in reversed(mXRecords[1:])] dataList.insert(2,[_("MX-record"), mXRecords[0]]) if aRecords: - map(lambda x:dataList.insert(2,["",x]) ,reversed(aRecords[1:])) + [dataList.insert(2, ["", x]) for x in reversed(aRecords[1:])] dataList.insert(2,[_("A-record"), aRecords[0]]) if nSRecords: - map(lambda x:dataList.insert(2,["",x]), reversed(nSRecords[1:])) + [dataList.insert(2, ["", x]) for x in reversed(nSRecords[1:])] dataList.insert(2,[_("NS-record"), nSRecords[0]]) repObj = report(title, headerList, dataList) repObj.printReport() @@ -14612,10 +14591,10 @@ for %s DNS zone")%zoneName) domainName = "%s.%s"\ %(record[0][1]["relativeDomainName"][0],\ zoneName) - if record[0][1].has_key("aRecord"): + if "aRecord" in record[0][1]: dataAList.append([domainName, record[0][1]["aRecord"][0]]) - if record[0][1].has_key("mXRecord"): + if "mXRecord" in record[0][1]: flagFirst = True flagError = False for mxData in record[0][1]["mXRecord"]: @@ -14638,7 +14617,7 @@ for %s DNS zone")%zoneName) _("Incorrect MX-records in A-record %s")\ %domainName) return False - elif record[0][1].has_key("cNAMERecord"): + elif "cNAMERecord" in record[0][1]: dataCNList.append([domainName, delDot(record[0][1]["cNAMERecord"][0])]) allDataList = [dataAList, dataCNList,dataMXList] @@ -14655,21 +14634,21 @@ for %s DNS zone")%zoneName) headerList = allHeaderList[i] dataList = allDataList[i] repObj = report(title, headerList, dataList) - print "" + print("") repObj.printReport() # Если обратная зона else: dataPTRList = [] # Получение из названия зоны cтроки из 3-х частей IP - getThreeOctetsIP = lambda x: ".".join(map(lambda x:x,\ - reversed('.in-addr.arpa' in x and\ - x.rpartition(".in-addr.arpa")[0].split(".") or []))) + getThreeOctetsIP = lambda x: ".".join(x + for x in reversed('.in-addr.arpa' in x and\ + x.rpartition(".in-addr.arpa")[0].split(".") or [])) threeOctetsIP = getThreeOctetsIP(zoneName) if not threeOctetsIP: - self.printERROR(_("Incorrect zone name %s")%zoneName) + self.printERROR(_("Incorrect zone name %s") % zoneName) return False for record in recordsSearch: - if record[0][1].has_key("pTRRecord"): + if "pTRRecord" in record[0][1]: IP = "%s.%s"%(threeOctetsIP,\ record[0][1]["relativeDomainName"][0]) domainName = delDot(record[0][1]["pTRRecord"][0]) @@ -14681,11 +14660,11 @@ for %s DNS zone")%zoneName) headerList = ("ip", _("Domain")) dataList = dataPTRList repObj = report(title, headerList, dataList) - print "" + print("") repObj.printReport() return True # Информация о DNS записи - if service == "dns" and options.has_key("r"): + if service == "dns" and "r" in options: hostOrIP = options["r"] # Флаг True - hostOrIP является хостом hostInForwardZone = servDnsObj.isForwardName(hostOrIP) @@ -14696,7 +14675,7 @@ for %s DNS zone")%zoneName) headerList = [_("Field"), _("Value")] dataList = [] # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) # hostOrIP является именем хоста if hostInForwardZone: domainName = delDot(hostOrIP.lower()) @@ -14713,10 +14692,10 @@ for %s DNS zone")%zoneName) flagF = True for record in dataRecords: dataList.append([_("Domain name"), domainName]) - if record[0][1].has_key("aRecord"): + if "aRecord" in record[0][1]: dataList.append([_("A-record"),\ record[0][1]["aRecord"][0]]) - if record[0][1].has_key("mXRecord"): + if "mXRecord" in record[0][1]: flagFirst = True flagError = False for mxData in record[0][1]["mXRecord"]: @@ -14735,7 +14714,7 @@ for %s DNS zone")%zoneName) %domainName) return False typeRecord = "A" - elif record[0][1].has_key("cNAMERecord"): + elif "cNAMERecord" in record[0][1]: dataList.append([_("CNAME-record"),\ record[0][1]["cNAMERecord"][0]]) typeRecord = "CNAME" @@ -14746,7 +14725,7 @@ for %s DNS zone")%zoneName) if flagF: flagF = False else: - print "" + print("") repObj.printReport() # hostOrIP является ip else: @@ -14769,7 +14748,7 @@ for %s DNS zone")%zoneName) typeRecord = "Unknown" for record in dataRecords: dataList.append(["ip", ip]) - if record[0][1].has_key("pTRRecord"): + if "pTRRecord" in record[0][1]: domainNameDot = record[0][1]["pTRRecord"][0] dataList.append([_("PTR-record"), domainNameDot]) typeRecord = "PTR" @@ -14780,11 +14759,11 @@ for %s DNS zone")%zoneName) if flagF: flagF = False else: - print "" + print("") repObj.printReport() return True # Информация о компьютере - if options.has_key("M"): + if "M" in options: machineName = options["M"] data = self.getMachine(machineName, service) if not data: @@ -14793,7 +14772,7 @@ for %s DNS zone")%zoneName) title=_("Information about machine %s") %machineName + " " +\ _("for service %s") %strService # Информация о пользователе - elif options.has_key("U"): + elif "U" in options: userName = options["U"] data = self.getUser(userName, service) if not data: @@ -14802,7 +14781,7 @@ for %s DNS zone")%zoneName) title=_("Information about user %s") %userName + " " +\ _("for service %s") %strService # Информация о группе - elif options.has_key("G"): + elif "G" in options: groupName = options["G"] data = self.getGroup(groupName, service) if not data: @@ -14812,9 +14791,9 @@ for %s DNS zone")%zoneName) _("for service %s") %strService # Информация о компьютерах - elif options.has_key("m"): + elif "m" in options: fields = "short" - if options.has_key("full"): + if "full" in options: fields = "full" data = self.getAllMachines(fields, service) if not data: @@ -14822,9 +14801,9 @@ for %s DNS zone")%zoneName) headerList, dataList = data title=_("All machines in LDAP for service %s")%strService # Информация о пользователях - elif options.has_key("u"): + elif "u" in options: fields = "short" - if options.has_key("full"): + if "full" in options: fields = "full" data = self.getAllUsers(fields, service) if not data: @@ -14832,9 +14811,9 @@ for %s DNS zone")%zoneName) headerList, dataList = data title=_("All users in LDAP for service %s")%strService # Информация о группах - elif options.has_key("g"): + elif "g" in options: fields = "short" - if options.has_key("full"): + if "full" in options: fields = "full" data = self.getAllGroups(fields, service) if not data: @@ -14842,14 +14821,14 @@ for %s DNS zone")%zoneName) headerList, dataList = data title=_("All groups in LDAP for service %s")%strService - if options.has_key("M") or options.has_key("m") or\ - options.has_key("U") or options.has_key("G") or\ - options.has_key("u") or options.has_key("g"): + if "M" in options or "m" in options or\ + "U" in options or "G" in options or\ + "u" in options or "g" in options: repObj = report(title, headerList, dataList) repObj.printReport() return True - if len(options) == 1 and options.has_key("full"): + if len(options) == 1 and "full" in options: self.printERROR(_("Can not use a single command line option \ 'full'.")) @@ -14865,7 +14844,7 @@ with another option.")) branchData = {'users':'relUsersDN', 'groups':'relGroupsDN', 'computers':'relComputersDN'} - if not branchData.has_key(branch): + if branch not in branchData: self.printERROR("getQueryLDAP service=%s"%service) self.printERROR(_("ERROR: getQueryLDAP incorrect branch=%s")%branch) return False @@ -14879,7 +14858,8 @@ with another option.")) # Если сервис не установлен то ошибка if not servObj.isServiceSetup(service): return False - if not servObj.__dict__.has_key(relAttr): + #TODO debug this: + if relAttr not in servObj.__dict__: self.printERROR("getQueryLDAP service=%s"%service) self.printERROR(_("ERROR: getQueryLDAP incorrect branch=%s")%branch) return False @@ -14903,8 +14883,8 @@ with another option.")) %self.printNameService(service)) return False headers = [_("Field"),_("Value")] - attributes = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + attributes = [x[0] for x in data] + retrAttrs = [x[1] for x in data] retClVars=False searchRes = self.getQueryLDAP(service, "computers", searchAttr, searchStr, retrAttrs) @@ -14958,8 +14938,8 @@ with another option.")) %self.printNameService(service)) return False headers = [_("Field"),_("Value")] - attributes = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + attributes = [x[0] for x in data] + retrAttrs = [x[1] for x in data] retClVars=False searchRes = self.getQueryLDAP(service, "groups", searchAttr, searchStr, retrAttrs) @@ -14970,7 +14950,7 @@ with another option.")) if service == "proxy": for i in searchRes: memberList = i[0][1]['member'] - i[0][1]['member']=map(lambda x: x.partition("=")[2],memberList) + i[0][1]['member'] = [x.partition("=")[2] for x in memberList] if service == "jabber": servObj = servJabber() resMemberSearch = servObj.searchUsersToGroup(groupName) @@ -14981,14 +14961,14 @@ with another option.")) for i in searchRes: i[0][1]['memberUid'] = memberUid data.append((_("Member UID"),"memberUid")) - attributes = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + attributes = [x[0] for x in data] + retrAttrs = [x[1] for x in data] data = [] lenRetrAttrs = len(retrAttrs) # Добавляем первичные группы if service in ("unix", "samba"): memberUid = [] - if searchRes[0][0][1].has_key('memberUid'): + if 'memberUid' in searchRes[0][0][1]: memberUid = searchRes[0][0][1]['memberUid'] groupId = searchRes[0][0][1]['gidNumber'][0] primaryUids = self.getUnixUidPrimGroup(groupId) @@ -15032,8 +15012,8 @@ with another option.")) %self.printNameService(service)) return False headers = [_("Field"), _("Value")] - attributes = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + attributes = [x[0] for x in data] + retrAttrs = [x[1] for x in data] retClVars=False if service in ["mail", "samba"]: retClVars=True @@ -15051,7 +15031,7 @@ with another option.")) if service == "mail": for i in searchRes: i[0][1]['homeDirectory'] = [os.path.join(\ - clVars.Get("sr_mail_path"),i[0][1]['uid'][0])] + clVars.Get("sr_mail_path"), i[0][1]['uid'][0])] data.append((_("Home directory"),"homeDirectory")) # Добавляем директории пользователя для сервиса samba # а так же первичную и дополнительные группы @@ -15099,8 +15079,8 @@ with another option.")) if os.path.exists(winLogonPath): i[0][1]['winLogonPath'] = [winLogonPath] data.append((_("Windows logon"),"winLogonPath")) - attributes = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + attributes = [x[0] for x in data] + retrAttrs = [x[1] for x in data] data = [] lenRetrAttrs = len(retrAttrs) @@ -15166,9 +15146,9 @@ with another option.")) %self.printNameService(service)) return False if fields == "short": - data = filter(lambda x: not x[0] in delData, data) - headers = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + data = [x for x in data if x[0] not in delData] + headers = [x[0] for x in data] + retrAttrs = [x[1] for x in data] machines = [] searchRes = self.getQueryLDAP(service, "computers", searchAttr, searchStr, retrAttrs) @@ -15203,9 +15183,9 @@ with another option.")) %self.printNameService(service)) return False if fields == "short": - data = filter(lambda x: not x[0] in delData, data) - headers = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + data = [x for x in data if x[0] not in delData] + headers = [x[0] for x in data] + retrAttrs = [x[1] for x in data] groups = [] searchRes = self.getQueryLDAP(service, "groups", searchAttr, searchStr, retrAttrs) @@ -15215,15 +15195,14 @@ with another option.")) return (headers , []) for info in searchRes: if service in ("proxy",): - if info[0][1].has_key('member'): + if 'member' in info[0][1]: memberList = info[0][1]['member'] - info[0][1]['member'] = map(lambda x: x.partition("=")[2],\ - memberList) + info[0][1]['member'] = [x.partition("=")[2] for x in memberList] listAttr = [] # Добавляем первичные группы if service in ("unix", "samba"): memberUid = [] - if info[0][1].has_key('memberUid'): + if 'memberUid' in info[0][1]: memberUid = info[0][1]['memberUid'] groupId = info[0][1]['gidNumber'][0] primaryUids = self.getUnixUidPrimGroup(groupId) @@ -15382,9 +15361,9 @@ with another option.")) %self.printNameService(service)) return False if fields == "short": - data = filter(lambda x: not x[0] in delData, data) - headers = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + data = [x for x in data if x[0] not in delData] + headers = [x[0] for x in data] + retrAttrs = [x[1] for x in data] loginsUsers = [] retClVars=False @@ -15407,9 +15386,9 @@ with another option.")) data.append((_("Home directory"),"homeDirectory")) delData.append(_("Home directory")) if fields == "short": - data = filter(lambda x: not x[0] in delData, data) - headers = map(lambda x: x[0], data) - retrAttrs = map(lambda x: x[1], data) + data = [x for x in data if x[0] not in delData] + headers = [x[0] for x in data] + retrAttrs = [x[1] for x in data] for info in searchRes: listAttr = [] for attr in retrAttrs: @@ -15510,11 +15489,12 @@ with another option.")) """Конвертирует количество дней или секунд с 1970, в строку даты""" if dataDays: if len(str(dataDays)) <= 6: - value = long(dataDays)*86400 + value = long(dataDays) * 86400 elif len(str(dataDays)) > 6: value = long(dataDays) - return reduce(lambda x,y: y+"."+x,map(lambda x: (len(str(x))==1 and\ - "0"+str(x)) or str(x), time.localtime(value)[:3])) + return reduce(lambda x,y: y + "." + x, [(len(str(x)) == 1 + and "0" + str(x)) or str(x) + for x in time.localtime(value)[:3]]) return "" def _getUserGroupName(self, userGid, service): @@ -15662,20 +15642,20 @@ class servProxy(shareLdap): def filterProxyServer(self, options): """Фильтр Proxy групп для доступа пользователя""" optPwd = ["p","P"] - listOptPwd = filter(lambda x: x in optPwd, options.keys()) + listOptPwd = [x for x in options.keys() if x in optPwd] if len(listOptPwd) > 1: self.printERROR(_("Command line options '-p' and '-P' are \ incompatible, use one of the options")) return False - if not (options.has_key("s") and options.has_key("b") and\ - (options.has_key("p") or options.has_key("P"))): + if not ("s" in options and "b" in options and\ + ("p" in options or "P" in options)): self.printERROR(_("Not found the options '-s' and '-b' and ('-p' \ or '-P')")) return False adminDn = options['s'] - if options.has_key("p"): + if "p" in options: adminPw = options['p'] - elif options.has_key("P"): + elif "P" in options: pathPasswd = options['P'] if os.path.exists(pathPasswd): try: @@ -15696,7 +15676,7 @@ or '-P')")) try: strInput = sys.stdin.readline() strInput = strInput[:-1] - params = map(lambda x: x, strInput.split(" ")) + params = strInput.split(" ") if params == ['']: sys.stdout.write("ERR\n") sys.stdout.flush() @@ -15724,7 +15704,7 @@ or '-P')")) def searchProxyGroups(self, groupNames): """Ищет группы. Находит все группы - True иначе - False""" - notFindGroup=filter(lambda x: not self.searchGroupToName(x), groupNames) + notFindGroup = [x for x in groupNames if not self.searchGroupToName(x)] if notFindGroup: self.printERROR(_("Groups %s is not found in Proxy service")\ %", ".join(notFindGroup)) @@ -15752,13 +15732,13 @@ or '-P')")) self.clVars.Set("ur_group",groupName) # Комментарий к группе groupGecos = self.servUnixObj.groupGecos - if options.has_key('c'): + if 'c' in options: groupGecos = options['c'] self.clVars.Set("ur_group_comment",groupGecos) # Тип группы groupType = "port" accessPorts = "" - if options.has_key('p'): + if 'p' in options: accessPorts = options['p'] reFalseString = re.compile("[^\d,\-]|^,|^-|,-|-,|,$|-$") if reFalseString.search(accessPorts): @@ -15773,12 +15753,12 @@ is not valid ") %accessPorts) ldifFile = self.ldifFileGroup groupLdif = self.createLdif(ldifFile) if not groupLdif: - print self.getError() + print(self.getError()) return False if not self.ldapObj.getError(): self.ldapObj.ldapAdd(groupLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False self.printSUCCESS(_("Added group '%s' in Proxy service")\ %groupName) @@ -15852,7 +15832,7 @@ is not valid ") %accessPorts) self.clVars.Set("ur_name", userName) #Полное имя пользователя (комментарий) fullNameUser = self.servUnixObj.fullNameUser - if options.has_key('c'): + if 'c' in options: fullNameUser = options['c'] else: # Проверяем установку сервиса не печатая ошибку в случае @@ -15860,7 +15840,7 @@ is not valid ") %accessPorts) if self.isServiceSetup("unix",False): resUnix = self.servUnixObj.searchUnixUser(userName) # Берем комментарий для пользователя из Unix - if resUnix and resUnix[0][0][1].has_key('cn'): + if resUnix and 'cn' in resUnix[0][0][1]: fullNameUser = resUnix[0][0][1]['cn'][0] self.clVars.Set("ur_fio",fullNameUser) ldifFile = self.ldifFileUser @@ -15871,7 +15851,7 @@ is not valid ") %accessPorts) #ldapObj.ldapAdd(userLdif1) # не переделывать на else if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False self.printSUCCESS(_("Added user in Proxy service")) return True @@ -15896,13 +15876,12 @@ is not valid ") %accessPorts) # Группа не пуста flagEmptyGroup = False # Если есть пустой member аттрибут (пустая группа) - if filter(lambda x: not x.strip(), searchGroup[0][0][1]['member']): + if [x for x in searchGroup[0][0][1]['member'] if not x.strip()]: flagEmptyGroup = True addUsers = users else: - memberUsers = map(lambda x:x.rpartition("=")[2],\ - searchGroup[0][0][1]["member"]) - addUsers = filter(lambda x: not x in memberUsers, users) + memberUsers = [x.rpartition("=")[2] for x in searchGroup[0][0][1]["member"]] + addUsers = [x for x in users if x not in memberUsers] for userName in addUsers: if flagEmptyGroup: modAttrs.append((ldap.MOD_REPLACE, 'member', "uid="+userName)) @@ -15945,12 +15924,11 @@ is not valid ") %accessPorts) %str(groupName)) return False # Если группа пуста - if filter(lambda x: not x.strip(), searchGroup[0][0][1]['member']): + if [x for x in searchGroup[0][0][1]['member'] if not x.strip()]: self.printERROR( _("Member list of group %s is empty")%str(groupName)) - return False - memberUsers = map(lambda x:x.rpartition("=")[2],\ - searchGroup[0][0][1]["member"]) + memberUsers = [x.rpartition("=")[2] for x + in searchGroup[0][0][1]["member"]] flagError = False for user in users: if not user in memberUsers: @@ -15986,10 +15964,10 @@ is not valid ") %accessPorts) # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя - if options.has_key('u'): + if 'u' in options: modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] # Выключаем пользователя - elif options.has_key('l'): + elif 'l' in options: modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] if not options: optPasswd = {"p":""} @@ -15999,7 +15977,7 @@ is not valid ") %accessPorts) userPwdHash = self.getHashPasswd(userPwd, self.userCrypt) if not userPwdHash: return False - if res[0][0][1].has_key('userPassword'): + if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -16009,10 +15987,10 @@ is not valid ") %accessPorts) DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False - if options.has_key('l'): + if 'l' in options: self.printSUCCESS(_("Locked user") + " " + str(userName) +\ " " +_("of Proxy service")) - if options.has_key('u'): + if 'u' in options: self.printSUCCESS(_("Unlocked user") + " " + str(userName) +\ " " +_("of Proxy service")) if not options: @@ -16031,7 +16009,7 @@ is not valid ") %accessPorts) _("User %s is not found in Proxy service")%str(userName)) return False # Новые группы в которые входит пользователь - if options.has_key('G'): + if 'G' in options: userGroups = options['G'].split(',') if not self.searchProxyGroups(userGroups): return False @@ -16047,7 +16025,7 @@ is not valid ") %accessPorts) return False self.printSUCCESS(_("Replaced list of supplementary group")) # Добавляем группы в которые входит пользователь - elif options.has_key('a'): + elif 'a' in options: userGroups = options['a'].split(',') if not self.searchProxyGroups(userGroups): return False @@ -16062,13 +16040,13 @@ is not valid ") %accessPorts) # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя - if options.has_key('U'): + if 'U' in options: modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] # Выключаем пользователя - elif options.has_key('L'): + elif 'L' in options: modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] # Изменяем комментарий к пользователю - if options.has_key('c'): + if 'c' in options: comment = options['c'] modAttrs += [(ldap.MOD_REPLACE, 'sn', comment), (ldap.MOD_REPLACE, 'cn', comment)] @@ -16080,7 +16058,7 @@ is not valid ") %accessPorts) userPwdHash = self.getHashPasswd(userPwd, self.userCrypt) if not userPwdHash: return False - if res[0][0][1].has_key('userPassword'): + if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: @@ -16090,13 +16068,13 @@ is not valid ") %accessPorts) DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False - if options.has_key('P') or options.has_key('p'): + if 'P' in options or 'p' in options: self.printSUCCESS(_("Modified user password")) - if options.has_key('c'): + if 'c' in options: self.printSUCCESS(_("Modified comment")) - if options.has_key('U'): + if 'U' in options: self.printSUCCESS(_("Unlocked user %s")% str(userName)) - if options.has_key('L'): + if 'L' in options: self.printSUCCESS(_("Locked user %s")% str(userName)) return True @@ -16111,7 +16089,7 @@ is not valid ") %accessPorts) %str(groupName)) return False # Добавляем список пользователей в группу - if options.has_key('a'): + if 'a' in options: # добавляемые пользователи в группу users = options['a'].split(',') res = self.addUsersGroupProxy(users, groupName) @@ -16123,7 +16101,7 @@ is not valid ") %accessPorts) " " + str(groupName)) return False # Удаляем список пользователей из группы - if options.has_key('d'): + if 'd' in options: # удаляемые пользователи из группы users = options['d'].split(',') res = self.delUsersGroupProxy(users, groupName) @@ -16135,7 +16113,7 @@ is not valid ") %accessPorts) " " + str(groupName)) return False # Изменяем комментарий к группе - if options.has_key('c'): + if 'c' in options: gecos = options['c'] modAttrs = [(ldap.MOD_REPLACE, 'description', gecos)] groupDN = self.addDN("cn="+groupName, self.relGroupsDN) @@ -16146,7 +16124,7 @@ is not valid ") %accessPorts) " " + str(groupName)) return False # Изменяем имя группы - if options.has_key('n'): + if 'n' in options: newGroupName = options['n'] newFirstDn = "cn=" + newGroupName oldDN = self.addDN("cn=" + groupName, self.relGroupsDN) @@ -16167,8 +16145,8 @@ is not valid ") %accessPorts) self.clVars должен быть определен """ - print _("Enter the allowed ip addresses and network for %s service")\ - %"Proxy" + " (" + _("comma or space delimited") + ")" + print(_("Enter the allowed ip addresses and network for %s service")\ + %"Proxy" + " (" + _("comma or space delimited") + ")") strPrompt = _("allow networks: ") netAllow = self.clVars.Get("sr_proxy_net_allow") strNetAllow = "" @@ -16187,7 +16165,7 @@ is not valid ") %accessPorts) """Начальная настройка Proxy сервиса""" # Принудительная установка forceOptions = False - if options.has_key("f"): + if "f" in options: forceOptions = True # Создаем объект переменных и начальная проверка if not self.initialChecksSetup(): @@ -16204,7 +16182,7 @@ is not valid ") %accessPorts) _("Proxy server is configured")+ ".") return True # Порт для прокси сервера - if options.has_key("p"): + if "p" in options: proxyPort = options['p'] try: numberProxyPort = int(proxyPort) @@ -16227,13 +16205,13 @@ is not valid ") %accessPorts) _("input 'yes'") +", "+ _("if not 'no'") if not self.dialogYesNo(messDialog): return True - if options.has_key("a"): + if "a" in options: # Получаем от пользователя доверительные сети allowNet = self.getAllowNet() if not allowNet: return False else: - if options.has_key("a"): + if "a" in options: # Получаем от пользователя доверительные сети allowNet = self.getAllowNet() if not allowNet: @@ -16253,7 +16231,7 @@ is not valid ") %accessPorts) self.createClVars() # Устанавливаем доступные сети self.clVars.Set("sr_proxy_net_allow", allowNet, True) - if options.has_key("p"): + if "p" in options: self.clVars.Set("sr_proxy_port",proxyPort, True) # Удаляем из автозапуска демона if not self.delDaemonAutostart("squid"): @@ -16268,7 +16246,7 @@ is not valid ") %accessPorts) fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'), self.clVars.Get('os_net_domain')) jabberHosts = fullHostName - if options.has_key("host"): + if "host" in options: fullHostName = options['host'] if not "." in fullHostName: fullHostName = "%s.%s" %(fullHostName, @@ -16307,7 +16285,7 @@ is not valid ") %accessPorts) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False # Записываем данные администратора сервиса Proxy ldapParser = iniLdapParser() @@ -16431,7 +16409,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): (ip, '\tfixed-address %s;'%ip), (mac,'\thardware ethernet %s;'%mac), (True, '}')] - templateList = map(lambda x: x[1], filter(lambda x: x[0], templateList)) + templateList = [x[1] for x in templateList if x[0]] template = "".join(templateList) return template @@ -16462,7 +16440,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): %(delChar,domainNameServers)), (iprange, '\t%srange %s;'%(delChar, iprange)), (True, '}')] - templateList = map(lambda x: x[1], filter(lambda x: x[0], templateList)) + templateList = [x[1] for x in templateList if x[0]] template = "".join(templateList) return template @@ -16475,9 +16453,10 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): "child::area/child::caption/child::name", xmlNodeBody) if not namesArea: return [] - return filter(lambda x: x.firstChild and x.firstChild.nodeValue and\ - len(x.firstChild.nodeValue) > 4 and\ - 'host' in x.firstChild.nodeValue[:4], namesArea) + return [x for x in namesArea + if x.firstChild and x.firstChild.nodeValue and\ + len(x.firstChild.nodeValue) > 4 and\ + 'host' in x.firstChild.nodeValue[:4]] def getAllXMLSubnet(self): """Получаем все XML ноды подсетей""" @@ -16488,23 +16467,24 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): "child::area/child::caption/child::name", xmlNodeBody) if not namesArea: return [] - return filter(lambda x: x.firstChild and x.firstChild.nodeValue and\ - len(x.firstChild.nodeValue) > 6 and\ - 'subnet' in x.firstChild.nodeValue[:6], namesArea) + return [x for x in namesArea + if x.firstChild and x.firstChild.nodeValue and\ + len(x.firstChild.nodeValue) > 6 and\ + 'subnet' in x.firstChild.nodeValue[:6]] def getDataInAllHost(self): """Получить информацию о статических хостах""" if self.getError(): return False allXmlNames = self._getAllXMLStaticHosts() - allXmlAreas = map(lambda x: x.parentNode.parentNode, allXmlNames) + allXmlAreas = [x.parentNode.parentNode for x in allXmlNames] # Информация dataHost = [] iterXmlNames = iter(allXmlNames) for xmlArea in allXmlAreas: #print xmlArea.toprettyxml() # Ност - xmlNodeName = iterXmlNames.next() + xmlNodeName = next(iterXmlNames) strNameNode = xmlNodeName.firstChild.nodeValue # название хоста hostname = strNameNode.partition("host")[2].strip().encode("UTF-8") @@ -16521,13 +16501,13 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if self.getError(): return False allXmlNames = self.getAllXMLSubnet() - allXmlAreas = map(lambda x: x.parentNode.parentNode, allXmlNames) + allXmlAreas = [x.parentNode.parentNode for x in allXmlNames] # Информация dataNet = [] iterXmlNames = iter(allXmlNames) for xmlArea in allXmlAreas: # Сеть - xmlNodeName = iterXmlNames.next() + xmlNodeName = next(iterXmlNames) # Название области strNameNode = xmlNodeName.firstChild.nodeValue # ip сети @@ -16565,10 +16545,10 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): return binList[::-1] listOctMask = ipNetMask.split('.') - if filter(lambda x: not isNumber(x), listOctMask): + if [x for x in listOctMask if not isNumber(x)]: return "" - countOne = lambda z: filter(lambda x:x==1, strToBinList(z)) - numberMask = sum(map(lambda x: sum(countOne(x)), listOctMask)) + countOne = lambda z: [x for x in strToBinList(z) if x == 1] + numberMask = sum(sum(countOne(x)) for x in listOctMask) return str(numberMask) @@ -16584,10 +16564,8 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): nodesXml = xpath.Evaluate("child::value", node) for nodeFind in nodesXml: if nodeFind.firstChild: - listOpt = map(lambda x: x.encode("UTF-8"),\ - filter(lambda x: x,\ - nodeFind.firstChild.nodeValue.replace("\t",\ - " ").split(" "))) + listOpt = [x.encode("UTF-8") for x + in nodeFind.firstChild.nodeValue.replace("\t"," ").split(" ") if x] dataPars[opt] = listOpt return dataPars @@ -16601,8 +16579,8 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if not xmlStaticHosts: return [] slpHostName = 'host%s' %hostName.lower() - return map(lambda x: x.parentNode.parentNode, filter(lambda x:\ - slpHostName == x.firstChild.nodeValue.lower(), xmlStaticHosts)) + return [x.parentNode.parentNode for x in xmlStaticHosts + if slpHostName == x.firstChild.nodeValue.lower()] def getXMLNet(self, net): """Получить XML ноду подсети по ip""" @@ -16614,10 +16592,9 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): return [] slpNetName = 'subnet%s' %net.lower() lenSlpNetName = len(slpNetName) - return map(lambda x: x.parentNode.parentNode, filter(lambda x:\ - len(x.firstChild.nodeValue)>lenSlpNetName and\ - slpNetName==x.firstChild.nodeValue[:lenSlpNetName].lower(),\ - xmlSubnets)) + return [x.parentNode.parentNode for x in xmlSubnets + if len(x.firstChild.nodeValue) > lenSlpNetName and + slpNetName == x.firstChild.nodeValue[:lenSlpNetName].lower()] def createStaticHost(self, hostname, ip, mac): """Создает статический хост в файле конфигурации dhcp""" @@ -16648,7 +16625,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): netIPList = splNameNewNode.partition("subnet")[2].partition("netmask") netIP = netIPList[0].strip().encode("UTF-8") netMask = netIPList[2].partition("{")[0].strip().encode("UTF-8") - if not filter(lambda x: x, (routers, domainName, dnsIPs, iprange)): + if not any((routers, domainName, dnsIPs, iprange)): self.setError(_("empty modify options")) return False textNet = self.getTextSubnet(netIP, "", routers, domainName, @@ -16668,7 +16645,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): namesArea = xpath.Evaluate("child::caption/child::name", xmlNode) splNameNewNode = namesArea[0].firstChild.nodeValue hostname = splNameNewNode.partition("host")[2].strip().encode("UTF-8") - if not filter(lambda x: x, (ip, mac)): + if not any((ip, mac)): self.setError(_("empty modify options")) return False textHost = self.getTextStaticIP(hostname, ip, mac) @@ -16713,18 +16690,20 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): def deleteAllNetAndHosts(self): """Удаляет все сети и статические хосты из конфигурационного файла""" # IP всех сетей - delNamesNets = map(lambda x:\ -x.firstChild.nodeValue.partition("subnet")[2].partition("netmask")[0].\ -encode("UTF-8"), filter(lambda x: x.firstChild, self.getAllXMLSubnet())) + delNamesNets = [x.firstChild.nodeValue.partition("subnet")[2].\ + partition("netmask")[0].encode("UTF-8") + for x in self.getAllXMLSubnet() + if x.firstChild] # Имена всех статических хостов - delNamesHosts = map(lambda x:\ - x.firstChild.nodeValue.partition("host")[2].strip().encode("UTF-8"),\ - filter(lambda x: x.firstChild, self._getAllXMLStaticHosts())) + delNamesHosts = [x.firstChild.nodeValue.partition("host")[2].\ + strip().encode("UTF-8") + for x in self._getAllXMLStaticHosts() + if x.firstChild] # Удаление - for term in map(lambda x: self.deleteNet(x), delNamesNets): + for term in (self.deleteNet(x) for x in delNamesNets): if not term: return False - for term in map(lambda x: self.deleteStaticHost(x), delNamesHosts): + for term in (self.deleteStaticHost(x) for x in delNamesHosts): if not term: return False return True @@ -16772,10 +16751,10 @@ encode("UTF-8"), filter(lambda x: x.firstChild, self.getAllXMLSubnet())) delNodesNext.pop() delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк - map(lambda x: xmlNodeBody.removeChild(x), delNodes) + [xmlNodeBody.removeChild(x) for x in delNodes] #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области - for term in map(lambda x: xmlNodeBody.removeChild(x), deletesNodes): + for term in (xmlNodeBody.removeChild(x) for x in deletesNodes): if not term: self.setError(_('Can not remove static host "%s"')%hostname+\ " " + _("in config file %s")%self.nameConfigFile) @@ -16827,10 +16806,10 @@ encode("UTF-8"), filter(lambda x: x.firstChild, self.getAllXMLSubnet())) delNodesNext.pop() delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк - map(lambda x: xmlNodeBody.removeChild(x), delNodes) + [xmlNodeBody.removeChild(x) for x in delNodes] #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области - for term in map(lambda x: xmlNodeBody.removeChild(x), deletesNodes): + for term in (xmlNodeBody.removeChild(x) for x in deletesNodes): if not term: self.setError(_('Can not remove subnet "%s"')%net+\ " " + _("in config file %s")%self.nameConfigFile) @@ -16897,8 +16876,9 @@ class dnsTxt(cl_profile.bind,shareTxt): "child::area/child::caption/child::name", xmlNodeBody) if not namesArea: return [] - return filter(lambda x: x.firstChild and x.firstChild.nodeValue and\ - 'zone"' in x.firstChild.nodeValue, namesArea) + return [x for x in namesArea + if x.firstChild and x.firstChild.nodeValue and\ + 'zone"' in x.firstChild.nodeValue] def getXMLZoneToName(self, nameZone): """Получить XML ноду DNS зоны по ее имени""" @@ -16911,10 +16891,10 @@ class dnsTxt(cl_profile.bind,shareTxt): if not xmlZonesNames: return [] nameZoneL = nameZone.lower() - return map(lambda x: x.parentNode.parentNode, filter(lambda x:\ - nameZoneL == \ - x.firstChild.nodeValue.lower().partition('"')[2].partition('"')[0],\ - xmlZonesNames)) + return [x.parentNode.parentNode + for x in xmlZonesNames + if nameZoneL == \ + x.firstChild.nodeValue.lower().partition('"')[2].partition('"')[0]] def getAllNamesZones(self): """Получить все имена нод областей (кроме служебных)""" @@ -16934,8 +16914,8 @@ class dnsTxt(cl_profile.bind,shareTxt): continue retNodesNames.append(\ nodeZone.firstChild.nodeValue.rpartition('"')[0].partition('"')[2]) - retNodesNames = filter(lambda x: x, retNodesNames) - return map(lambda x: x.encode("UTF-8"), retNodesNames) + retNodesNames = [x for x in retNodesNames if x] + return [x.encode("UTF-8") for x in retNodesNames] def deleteZone(self, zoneName): """Удаляет зону из конфигурационного файла bind""" @@ -16980,10 +16960,10 @@ class dnsTxt(cl_profile.bind,shareTxt): delNodesNext.pop() delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк - map(lambda x: xmlNodeBody.removeChild(x), delNodes) + [xmlNodeBody.removeChild(x) for x in delNodes] #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области - for term in map(lambda x: xmlNodeBody.removeChild(x), deletesNodes): + for term in [xmlNodeBody.removeChild(x) for x in deletesNodes]: if not term: self.setError(_('Can not remove DNS zone "%s"')%zoneName+\ " " + _("in config file %s")%self.nameConfigFile) @@ -17057,7 +17037,7 @@ class dnsTxt(cl_profile.bind,shareTxt): if not delNode in delNodes: delNodes.append(delNode) # Удаляем переводы строк - map(lambda x: xmlNodeBody.removeChild(x), delNodes) + [xmlNodeBody.removeChild(x) for x in delNodes] #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области for delNode, zoneName in deletesNodes: @@ -17241,12 +17221,11 @@ class servDns(shareLdap): Кроме SOA записи (имя домена @) """ relZonesDN = self.getRelZonesDN(zoneName) - relZoneDN = self.addDN("zoneName=%s"%zoneName,relZonesDN) + relZoneDN = self.addDN("zoneName=%s" % zoneName, relZonesDN) resSearch = self.searchLdapDN("*", relZoneDN,"relativeDomainName") if resSearch: - resSearch = filter(lambda x:\ - not x[0][1]["relativeDomainName"][0]=="@",\ - resSearch) + resSearch = [x for x in resSearch + if not x[0][1]["relativeDomainName"][0] == "@"] return resSearch def searchAllDomainNamesInLDAP(self, domainName): @@ -17268,8 +17247,8 @@ class servDns(shareLdap): """ resSearch = self.searchAllDomainNamesInLDAP(domainName) if resSearch: - resSearch=filter(lambda x: not x[0][1].has_key("cNAMERecord"),\ - resSearch) + resSearch = [x for x in resSearch + if "cNAMERecord" not in x[0][1]] return resSearch def searchCNameInLDAP(self, domainName): @@ -17279,8 +17258,8 @@ class servDns(shareLdap): """ resSearch = self.searchAllDomainNamesInLDAP(domainName) if resSearch: - resSearch=filter(lambda x: x[0][1].has_key("cNAMERecord"),\ - resSearch) + resSearch = [x for x in resSearch + if "cNAMERecord" in x[0][1]] return resSearch def searchIPinForward(self, ip): @@ -17290,9 +17269,8 @@ class servDns(shareLdap): """ resSearch = self._searchLdapDNSub(ip, self.relForwardDN, "aRecord") if resSearch: - resSearch = filter(lambda x:\ - not x[0][1]["relativeDomainName"][0]=="@",\ - resSearch) + resSearch = [x for x in resSearch + if not x[0][1]["relativeDomainName"][0] == "@"] return resSearch def searchHostsForIPinForward(self, ip): @@ -17303,7 +17281,7 @@ class servDns(shareLdap): for aRecord in foundNames: relDomainNames = aRecord[0][1]['relativeDomainName'] zoneName = aRecord[0][1]['zoneName'][0] - domainNames = map(lambda x:"%s.%s"%(x,zoneName),relDomainNames) + domainNames = ["%s.%s" % (x, zoneName) for x in relDomainNames] hostNames += domainNames return hostNames @@ -17312,12 +17290,11 @@ class servDns(shareLdap): Ищет в LDAP """ - hostDot = "%s."%host + hostDot = "%s." % host resSearch = self._searchLdapDNSub(hostDot,self.relReverseDN,"pTRRecord") if resSearch: - resSearch = filter(lambda x:\ - not x[0][1]["relativeDomainName"][0]=="@",\ - resSearch) + resSearch = [x for x in resSearch + if not x[0][1]["relativeDomainName"][0] == "@"] return resSearch def searchIPForHostInReverse(self, host): @@ -17328,7 +17305,7 @@ class servDns(shareLdap): for ptrRecord in foundIPs: lastOctIPs = ptrRecord[0][1]['relativeDomainName'] zoneName = ptrRecord[0][1]['zoneName'][0] - domainNames = map(lambda x:"%s.%s"%(x,zoneName),lastOctIPs) + domainNames = ["%s.%s" % (x, zoneName) for x in lastOctIPs] for name in domainNames: listOctRev = name.rpartition(".in-addr.arpa")[0].split(".") listOctRev.reverse() @@ -17503,15 +17480,15 @@ class servDns(shareLdap): regTime = re.compile("^\d+[smhdwSMHDW]?$") sOATimeParams = [refresh,updateRetry,expiry,minimum] # Проверка корректности значений интервалов времени - incorrectTimeValues = filter(lambda x: not regTime.search(x),\ - sOATimeParams) + incorrectTimeValues = [x for x in sOATimeParams + if not regTime.search(x)] if incorrectTimeValues: self.printERROR(_("Values %s incorrect in SOA-record")\ %", ".join(incorrectTimeValues)) return False # Добавление точки если необходимо в каждое имя DNS сервера # Имена авторитативных DNS серверов для зоны - namesServersDot = map(lambda x: addDot(x), namesServers) + namesServersDot = [addDot(x) for x in namesServers] # Получение текста sOA записи sOARecord = " ".join([nameServerDot,emailAddrDot,serialNumber] +\ sOATimeParams) @@ -17553,9 +17530,9 @@ class servDns(shareLdap): if ip: zoneDomainEntry += [('aRecord',ip)] if mxList: - mxListDot = map(lambda x: addDot(x), mxList) - mxValues = map(lambda x: "%s %s" %(x*10+10, mxListDot[x]),\ - range(len(mxListDot))) + mxListDot = [addDot(x) for x in mxList] + mxValues = ["%s %s" % (x * 10 + 10, mxListDot[x]) + for x in range(len(mxListDot))] zoneDomainEntry += [('mXRecord', mxValues)] if not self.addEntry(zoneDomainDN, zoneDomainEntry, zoneDomainErrorMessage): @@ -17588,14 +17565,14 @@ incompatible with option "--ip" (PTR-record)')) return False # Флаг MX - записи flagDeleteMX = False - if options.has_key('mx'): + if 'mx' in options: flagDeleteMX = True # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) domainName = "" ip = "" typeRec = "" - if options.has_key('host'): + if 'host' in options: # Доменное имя (имя включающее домен) typeRec = "a" domainName = delDot(options['host'].lower()) @@ -17604,7 +17581,7 @@ incompatible with option "--ip" (PTR-record)')) if not zoneName: self.printERROR(_("Domain name %s incorrectly")%domainName) return False - elif options.has_key('ip'): + elif 'ip' in options: if flagDeleteMX: self.printERROR(_('Command line option "--mx" (MX-record) \ incompatible with option "--ip" (PTR-record)')) @@ -17631,7 +17608,7 @@ incompatible with option "--ip" (PTR-record)')) if flagDeleteMX: # Удаляем MX запись из A записи if foundDomain: - if not foundDomain[0][0][1].has_key('mXRecord'): + if 'mXRecord' not in foundDomain[0][0][1]: self.printERROR(\ _("Can not found MX-records in A-record %s"%domainName)) return False @@ -17718,10 +17695,10 @@ incompatible with option "--ip" (PTR-record)')) if not self.isServiceSetup("dns"): return False # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) # Имя зоны zoneName = "" - if options.has_key('n'): + if 'n' in options: zoneName = delDot(options["n"].lower()) if not zoneName: self.printERROR(_('Incorrect zone name')) @@ -17748,7 +17725,7 @@ incompatible with option "--ip" (PTR-record)')) if not zoneName: self.printERROR(_("Not enough command line option %s")%"-n") return False - if options.has_key('ip') or options.has_key('mx'): + if 'ip' in options or 'mx' in options: # Получение данных зоны из LDAP zoneData = self.searchAllDomainNamesInLDAP("@.%s"%zoneName) if not zoneData: @@ -17756,13 +17733,13 @@ incompatible with option "--ip" (PTR-record)')) %zoneName) return False # Удаление A записи - if options.has_key('ip'): - if not zoneData[0][0][1].has_key('aRecord'): + if 'ip' in options: + if 'aRecord' not in zoneData[0][0][1]: self.printERROR(_("Can not found A-records in zone %s")\ %zoneName) return False - if options.has_key('mx'): - if not zoneData[0][0][1].has_key('mXRecord'): + if 'mx' in options: + if 'mXRecord' not in zoneData[0][0][1]: self.printERROR(\ _("Can not found MX-records in zone %s")\ %zoneName) @@ -17778,8 +17755,8 @@ incompatible with option "--ip" (PTR-record)')) self.printSUCCESS(_("Deleted A-records for zone %s")%zoneName) ret = True # Удаление MX записей - if options.has_key('mx'): - if not zoneData[0][0][1].has_key('mXRecord'): + if 'mx' in options: + if 'mXRecord' not in zoneData[0][0][1]: self.printERROR(_("Can not found MX-records in zone %s")\ %zoneName) return False @@ -17822,19 +17799,18 @@ incompatible with option "--ip" (PTR-record)')) %", ".join(["master","slave"])) return False - if not set(minKeys)<=set(optKeys): + if not set(minKeys) <= set(optKeys): notFoundKeys = list(set(minKeys)-set(optKeys)) - notFoundKeys = map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x,\ - notFoundKeys) + notFoundKeys (len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys) self.printERROR(_("Not enough command line options: %s")\ %", ".join(notFoundKeys)) return False # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) # Имя зоны zoneName = "" forwardZone = True - if options.has_key('n'): + if 'n' in options: zoneName = delDot(options["n"].lower()) if not zoneName: self.printERROR(_('Incorrect zone name')) @@ -17851,12 +17827,12 @@ incompatible with option "--ip" (PTR-record)')) else: # Проверка на недопустимые ключи для обратной зоны # ip зоны для обратной зоны недопустим - if options.has_key('ip'): + if 'ip' in options: self.printERROR(_('Command line option "--ip" \ incompatible with reverse DNS zone %s')%zoneName) return False # MX записи для обратной зоны недопустимы - if options.has_key('mx'): + if 'mx' in options: self.printERROR(_('Command line option "--mx" \ incompatible with reverse DNS zone %s')%zoneName) return False @@ -17887,7 +17863,7 @@ incompatible with reverse DNS zone %s')%zoneName) return False # ip зоны zoneIP = "" - if options.has_key('ip'): + if 'ip' in options: zoneIP = options["ip"] if "," in zoneIP or \ not self.isCorrectStringNet(zoneIP, False): @@ -17895,16 +17871,16 @@ incompatible with reverse DNS zone %s')%zoneName) return False # Почтовые серверы для зоны zoneListMX = [] - if options.has_key('mx'): - zoneListMX = map(lambda x: delDot(x.lower()),\ - options['mx'].split(",")) + if 'mx' in options: + zoneListMX = [delDot(x.lower()) for x + in options['mx'].split(",")] zoneListMX = self.unicList(zoneListMX) if not self.checkMXDomains(zoneListMX): return False # Все авторитативные сервера зоны, в случае slаve зоны # ip авторитативных серверов хранения зоны namesServers = [] - if options.has_key('servers'): + if 'servers' in options: namesServers = options['servers'].split(",") # Проверка на ip if not flagZoneMaster: @@ -17935,7 +17911,7 @@ incompatible with reverse DNS zone %s')%zoneName) warningsMX = [] # Авторитативный сервер nameServer = "" - if options.has_key('server'): + if 'server' in options: nameServer = delDot(options["server"].lower()) if self.isCorrectStringNet(nameServer, False): self.printERROR(_('Incorrect autoritative server')) @@ -17959,7 +17935,7 @@ incompatible with reverse DNS zone %s')%zoneName) if nameServer == zoneName or nsZoneName == zoneName or\ (self.searchZoneInLDAP(nsZoneName) and\ not self.searchDomainNameInLDAP(nameServer)): - if not options.has_key('ipserver'): + if 'ipserver' not in options: self.printERROR(_('Not found A-record for "%s" \ (master server DNS)')%nameServer) self.printERROR(_('Not enough command line option \ @@ -17977,7 +17953,7 @@ the primary authoritative server for the zone")) self.printERROR(_("IP address %s incorrectly")%ipserver) return False else: - if options.has_key('ipserver'): + if 'ipserver' in options: if self.searchZoneInLDAP(nsZoneName) and\ self.searchDomainNameInLDAP(nameServer): self.printERROR(_('Command line option "--ipserver" \ @@ -17990,7 +17966,7 @@ this DNS server')%nameServer) # Почтовый адрес администратора зоны # по умолчанию email = "%s@%s"%("root",zoneName) - if options.has_key('email'): + if 'email' in options: email = options['email'] # refresh - интервал времени для обновления зоны # update - интервал времени после неудачного обновления зоны @@ -18003,7 +17979,7 @@ this DNS server')%nameServer) for nameOpt in zoneTimeIntervals.keys(): valueOpt = zoneTimeIntervals[nameOpt] locals()[nameOpt] = valueOpt - if options.has_key(nameOpt): + if nameOpt in options: valueOpt = options[nameOpt] locals()[nameOpt] = valueOpt.upper() if not self.checkTimeValue(locals()[nameOpt]): @@ -18074,8 +18050,7 @@ this DNS server')%nameServer) foundReverseDomain[0][0][1]['relativeDomainName'][0] pTRRecord = foundReverseDomain[0][0][1]['pTRRecord'][0] # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x,\ - y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) reverseHost = delDot(pTRRecord) listOctRev = \ zoneName.rpartition(".in-addr.arpa")[0].split(".") @@ -18099,8 +18074,7 @@ this DNS server')%nameServer) notCmdKey = list(set(optKeys) - set(minKeys)) if notCmdKey: # Добавляем кавычки и -- - addQ = lambda y: map(lambda x:\ - len(x)>1 and '"--%s"'%x or '"-%s"'%x, y) + addQ = lambda y: [len(x) > 1 and '"--%s"' % x or '"-%s"' % x, y] self.printERROR(_("Incorrect command line options %s")\ %", ".join(addQ(notCmdKey))) return False @@ -18269,10 +18243,10 @@ this DNS server')%nameServer) if not self.isServiceSetup("dns"): return False # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) # Имя зоны zoneName = "" - if options.has_key('n'): + if 'n' in options: zoneName = delDot(options["n"].lower()) if not zoneName: self.printERROR(_('Incorrect zone name')) @@ -18304,23 +18278,21 @@ this DNS server')%nameServer) self.printERROR(_("Can not found master zone %s in LDAP")%zoneName) return False # Проверка на mx совместно с mxmod - if options.has_key('mx') and options.has_key('mxmod'): + if 'mx' in options and 'mxmod' in options: self.printERROR('Command line option "-mx" is incompatible \ with option "--mxmod"') return False # MX серверы mxServers = [] - if options.has_key('mx'): - mxServers=map(lambda x: delDot(x.lower()), - options['mx'].split(",")) + if 'mx' in options: + mxServers = [delDot(x.lower()) for x in options['mx'].split(",")] mxServers = self.unicList(mxServers) # Переименование mx записи # modMxServers[0] - cтарая запись # modMxServers[1] - новая запись modMxServers = [] - if options.has_key('mxmod'): - modMxServers=map(lambda x: delDot(x.lower()),\ - options['mxmod'].split(",")) + if 'mxmod' in options: + modMxServers = [delDot(x.lower()) for x in options['mxmod'].split(",")] modMxServers = self.unicList(modMxServers) if len(modMxServers)!=2: self.printERROR(_('Incorrect command line option "--mxmod"')) @@ -18329,7 +18301,7 @@ with option "--mxmod"') return False # ip зоны zoneIP = "" - if options.has_key('ip'): + if 'ip' in options: zoneIP = options["ip"] if "," in zoneIP or \ not self.isCorrectStringNet(zoneIP, False): @@ -18342,19 +18314,19 @@ with option "--mxmod"') return False soaRecord = zoneData[0][0][1]['sOARecord'][0] nSRecords = zoneData[0][0][1]['nSRecord'] - soaData = map(lambda x: delDot(x), soaRecord.split(" ")) + soaData = [delDot(x) for x in soaRecord.split(" ")] if len(soaData)!=7: self.printERROR(_("Incorrect SOA-record in DNS zone %s")%zoneName) return False # Все авторитативные сервера зоны, в случае slаve зоны - namesServers = map(lambda x: delDot(x), nSRecords) - oldNamesServers = map(lambda x: delDot(x), nSRecords) + namesServers = [delDot(x) for x in nSRecords] + oldNamesServers = [delDot(x) for x in nSRecords] # Изменяем ip зоны if zoneIP: addDot = lambda x: (len(x)>0 and x[-1]!="." and "%s."%x) or x relZoneDN = self.getRelZoneDN(zoneName) modAttrs = [] - if zoneData[0][0][1].has_key('aRecord'): + if 'aRecord' in zoneData[0][0][1]: modAttrs =[(ldap.MOD_DELETE, 'aRecord', None)] modAttrs.append((ldap.MOD_ADD, 'aRecord', zoneIP)) DN = self.addDN("relativeDomainName=@", relZoneDN) @@ -18368,7 +18340,7 @@ with option "--mxmod"') # Изменяем MX записи if mxServers or modMxServers: flagFoundMX = False - if zoneData[0][0][1].has_key('mXRecord'): + if 'mXRecord' in zoneData[0][0][1]: flagFoundMX = True # Изменяем почтовый хост на другой почтовый хост if modMxServers: @@ -18377,9 +18349,8 @@ with option "--mxmod"') %zoneName) return False # Находим нужную запись - foundMxServers = map(lambda x: len(x.split(" "))==1\ - and delDot(x) or delDot(x.split(" ")[1]),\ - zoneData[0][0][1]['mXRecord']) + foundMxServer = [len(x.split(" ")) == 1 and delDot(x) or delDot(x.split(" ")[1]) + for x in zoneData[0][0][1]['mXRecord']] oldMxHost = modMxServers[0] newMxHost = modMxServers[1] if not oldMxHost in foundMxServers: @@ -18413,7 +18384,7 @@ with option "--mxmod"') if not self.modMXRecord("@", zoneName, zoneName, flagFoundMX, mxServers): return False - if options.has_key('servers'): + if 'servers' in options: namesServers = options['servers'].split(",") flagErrorNs = False for ns in namesServers: @@ -18428,7 +18399,7 @@ with option "--mxmod"') return False # Авторитативный сервер nameServer = soaData[0] - if options.has_key('server'): + if 'server' in options: nameServer = delDot(options["server"].lower()) if self.isCorrectStringNet(nameServer, False): self.printERROR(_('Incorrect autoritative server')) @@ -18460,7 +18431,7 @@ with option "--mxmod"') splEmail = soaData[1].partition(".") email = "%s@%s"%(splEmail[0], delDot(splEmail[2])) oldEmail = email - if options.has_key('email'): + if 'email' in options: email = options['email'] # Серийный номер зоны serialNumber = str(ctypes.c_uint32(int(soaData[2])).value + 1) @@ -18475,7 +18446,7 @@ with option "--mxmod"') for nameOpt in zoneTimeIntervals.keys(): valueOpt = zoneTimeIntervals[nameOpt] locals()[nameOpt] = valueOpt - if options.has_key(nameOpt): + if nameOpt in options: valueOpt = options[nameOpt] locals()[nameOpt] = valueOpt.upper() if not self.checkTimeValue(locals()[nameOpt]): @@ -18496,13 +18467,13 @@ with option "--mxmod"') sOARecord = " ".join(sOAList) relZoneDN = self.getRelZoneDN(zoneName) modAttrs = [(ldap.MOD_REPLACE, 'sOARecord', sOARecord)] - if options.has_key('server') or options.has_key('servers'): + if 'server' in options or 'servers' in options: # Добавляем мастер сервер в имена авторитативаных серверов if not nameServer in namesServers: namesServers.insert(0, nameServer) modAttrs.append((ldap.MOD_DELETE, 'nSRecord', None)) modAttrs.append((ldap.MOD_ADD, 'nSRecord',\ - map(lambda x: addDot(x), namesServers))) + [addDot(x) for x in namesServers])) DN = self.addDN("relativeDomainName=@", relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(_("Can not modify new SOA-record for zone %s \ @@ -18542,15 +18513,15 @@ in LDAP")%zoneName) if "f" in options.keys(): checkDHCPConfig = False # Проверка на имя хоста вместе с ip - if options.has_key('ip') and options.has_key('host'): + if 'ip' in options and 'host' in options: self.printERROR('Command line option "--host" is incompatible \ with option "--ip"') return False # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) # модификация другой записи A -> PTR, PTR -> A modOther = True - if options.has_key('automod'): + if 'automod' in options: autoMod = options['automod'] if autoMod == "on": modOther = True @@ -18562,7 +18533,7 @@ incorrect, use "--automod on" or "--automod off"')%autoMod) return False # По умолчанию прямой тип записи typeRec = "a" - if options.has_key('t'): + if 't' in options: # Тип модифицируемой записи typeRec = options['t'].lower() supportTypes = ("a","ptr","cname","mx") @@ -18572,12 +18543,12 @@ incorrect, use "--automod on" or "--automod off"')%autoMod) %", ".join(supportTypes)) return False # Проверка на mx совместно с mxmod - if options.has_key('mx') and options.has_key('mxmod'): + if 'mx' in options and 'mxmod' in options: self.printERROR('Command line option "-mx" is incompatible \ with option "--mxmod"') return False # Добавляем кавычки и -- - addQ = lambda y: map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x, y) + addQ = lambda y: [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in y] # Ключи опций optKeys = options.keys() # Обязательные опции @@ -18636,7 +18607,7 @@ with option "--mxmod"') %addQ([key])[0]) self.printWARNING(_('Valid values are the options %s')\ %addQ([key])[0] + " " + '(%s)'\ - % (" "+_("or")+" ").join(map(lambda x: '"%s"'%x, value))) + % (" "+_("or")+" ").join(('"%s"' % x for x in value))) return False # Проверка лишних опций unnecessaryOpt = list(set(optKeys)-set(requiredOpt+optionalOpt.keys())) @@ -18646,7 +18617,7 @@ with option "--mxmod"') return False mxServers = [] - if options.has_key('mx'): + if 'mx' in options: # Оключаем модификацию обратной зоны modOther = False # Почтовые серверы для доменного имени @@ -18658,14 +18629,13 @@ incompatible with PTR-record (option "-t")')) self.printERROR(_('Command line option "--mx" \ incompatible with CNAME-record (option "-t")')) return False - mxServers=map(lambda x: delDot(x.lower()), - options['mx'].split(",")) + mxServers = [delDot(x.lower()) for x in options['mx'].split(",")] mxServers = self.unicList(mxServers) # Переименование mx записи # modMxServers[0] - cтарая запись # modMxServers[1] - новая запись modMxServers = [] - if options.has_key('mxmod'): + if 'mxmod' in options: # Отключаем модификацию обратной зоны modOther = False # Почтовые cерверы для доменного имени @@ -18677,8 +18647,7 @@ incompatible with PTR-record (option "-t")')) self.printERROR(_('Command line option "--mxmod" \ incompatible with CNAME-record (option "-t")')) return False - modMxServers=map(lambda x: delDot(x.lower()),\ - options['mxmod'].split(",")) + modMxServers = [delDot(x.lower()) for x in options['mxmod'].split(",")] modMxServers = self.unicList(modMxServers) if len(modMxServers)!=2: self.printERROR(_('Incorrect command line option "--mxmod"')) @@ -18686,7 +18655,7 @@ incompatible with CNAME-record (option "-t")')) self.printWARNING("--mxmod old.mail.host,new.mail.host") return False cnameServer = "" - if options.has_key('cname'): + if 'cname' in options: # Оключаем модификацию обратной зоны modOther = False # Доменное имя (имя включающее домен) @@ -18701,7 +18670,7 @@ incompatible with CNAME-record (option "-t")')) newZoneName = "" # Новая запись является CNAME foundNewCnameRecord = False - if options.has_key('host'): + if 'host' in options: # Доменное имя (имя включающее домен) newDomainName = delDot(options['host'].lower()) # Имя хоста, имя зоны @@ -18768,7 +18737,7 @@ incompatible with CNAME-record (option "-t")')) newIP = "" newZoneNameIP = "" newHostNameIP = "" - if options.has_key('ip'): + if 'ip' in options: if typeRec == "cname": self.printERROR('Command line option "-t cname" \ is incompatible with option "--ip"') @@ -19070,7 +19039,7 @@ is incompatible with option "--ip"') %domainName) return False flagFoundMX = False - if foundMain[0][0][1].has_key('mXRecord'): + if 'mXRecord' in foundMain[0][0][1]: flagFoundMX = True # Изменяем почтовый хост на другой почтовый хост if modMxServers: @@ -19080,9 +19049,9 @@ is incompatible with option "--ip"') %domainName) return False # Находим нужную запись - foundMxServers = map(lambda x: len(x.split(" "))==1\ - and delDot(x) or delDot(x.split(" ")[1]),\ - foundMain[0][0][1]['mXRecord']) + foundMxServers = [len(x.split(" ")) == 1\ + and delDot(x) or delDot(x.split(" ")[1]) + for x in foundMain[0][0][1]['mXRecord']] oldMxHost = modMxServers[0] newMxHost = modMxServers[1] if not oldMxHost in foundMxServers: @@ -19343,7 +19312,7 @@ is incompatible with option "--ip"') %domainName) return False flagFoundMX = False - if foundMain[0][0][1].has_key('mXRecord'): + if 'mXRecord' in foundMain[0][0][1]: flagFoundMX = True # Изменяем почтовый хост на другой почтовый хост if modMxServers: @@ -19353,9 +19322,9 @@ is incompatible with option "--ip"') %domainName) return False # Находим нужную запись - foundMxServers = map(lambda x: len(x.split(" "))==1\ - and delDot(x) or delDot(x.split(" ")[1]),\ - foundMain[0][0][1]['mXRecord']) + foundMxServers = [len(x.split(" ")) == 1\ + and delDot(x) or delDot(x.split(" ")[1]) + for x in foundMain[0][0][1]['mXRecord']] oldMxHost = modMxServers[0] newMxHost = modMxServers[1] if not oldMxHost in foundMxServers: @@ -19485,7 +19454,7 @@ is incompatible with option "--ip"') checkDHCPConfig = False # По умолчанию прямой тип записи typeRec = "a" - if options.has_key('t'): + if 't' in options: # Тип добавлямой записи typeRec = options['t'].lower() supportTypes = ("a","ptr","cname") @@ -19500,14 +19469,13 @@ is incompatible with option "--ip"') minKeys = ["host","ip"] if not set(minKeys)<=set(optKeys): notFoundKeys = list(set(minKeys)-set(optKeys)) - notFoundKeys = map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x,\ - notFoundKeys) + notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ %", ".join(notFoundKeys)) return False # Флаг автоматического создания PTR записи createPtr = True - if options.has_key('autoptr'): + if 'autoptr' in options: if typeRec == "ptr": self.printERROR(_('Command line option "--autoptr" \ incompatible with type DNS record PTR (option "-t")')) @@ -19526,11 +19494,11 @@ incompatible with type DNS record CNAME (option "-t")')) incorrect, use "--autoptr on" or "--autoptr off"')%autoPtr) return False # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) domainName = "" hostName = "" zoneName = "" - if options.has_key('host'): + if 'host' in options: # Доменное имя (имя включающее домен) domainName = delDot(options['host'].lower()) # Имя хоста, имя зоны @@ -19541,12 +19509,12 @@ incorrect, use "--autoptr on" or "--autoptr off"')%autoPtr) cnDomainName = "" cnHostName = "" cnZoneName = "" - if options.has_key('cname'): - if options.has_key('ip'): + if 'cname' in options: + if 'ip' in options: self.printERROR(_('Command line option "--ip" incompatible \ with type DNS record CNAME (option "-t")')) return False - if options.has_key('mx'): + if 'mx' in options: self.printERROR(_('Command line option "--mx" incompatible \ with type DNS record CNAME (option "-t")')) return False @@ -19558,7 +19526,7 @@ with type DNS record CNAME (option "-t")')) self.printERROR(_("Domain name %s incorrectly")%cnDomainName) return False ip = "" - if options.has_key('ip'): + if 'ip' in options: # ip адрес ip = options['ip'] if "," in ip or not self.isCorrectStringNet(ip, False): @@ -19573,14 +19541,13 @@ with type DNS record CNAME (option "-t")')) if not servDhcpObj.isCorrectStaticIP(ip): return False mxServers = [] - if options.has_key('mx'): + if 'mx' in options: # Почтовые серверы для доменного имени if typeRec == "ptr": self.printERROR(_('Command line option "--mx" incompatible \ with type DNS record PTR (option "-t")')) return False - mxServers = map(lambda x: delDot(x.lower()),\ - options['mx'].split(",")) + mxServers = [delDot(x.lower()) for x in options['mx'].split(",")] mxServers = self.unicList(mxServers) ret = False # Флаг создания A записи @@ -19673,7 +19640,7 @@ with type DNS record PTR (option "-t")')) def checkTimeValue(self, timeValue): """Проверяет корректность переменной времени""" # разбиваем строку на символы - charList = map(lambda x: timeValue[x:x+1], range(len(timeValue))) + charList = [timeValue[x:x + 1] for x in range(len(timeValue))] if not charList: return False # Проверяем последний символ на число @@ -19699,12 +19666,10 @@ with type DNS record PTR (option "-t")')) (зона для доменного имени существует, доменного имени в ней нет) """ # Имена серверов которые могут находится в существующих зонах - serversInZones = filter(lambda x:\ - self.searchZoneInLDAP(x.partition(".")[2]),\ - namesServers) - notFoundServers = filter(lambda x:\ - not self.searchDomainNameInLDAP(x),\ - serversInZones) + serversInZones = [x for x in namesServers + if self.searchZoneInLDAP(x.partition(".")[2])] + notFoundServers = [x for x in serversInZones + if not self.searchDomainNameInLDAP(x)] return notFoundServers @@ -19743,14 +19708,14 @@ with type DNS record PTR (option "-t")')) # Проверка существования A записей для MX хостов if not self.checkMXDomains(namesMailServers): return False - namesMailServersDot = map(lambda x: addDot(x), namesMailServers) + namesMailServersDot = [addDot(x) for x in namesMailServers] domainEntry = [('objectclass', ['top','dNSZone']), ('relativeDomainName', [hostName]), ('dNSClass', ['IN']), ('zoneName',[zoneName]), ('aRecord',[ipAddrOrHost])] - mxValues=map(lambda x: "%s %s" %(x*10+10, namesMailServersDot[x]),\ - range(len(namesMailServersDot))) + mxValues= ["%s %s" % (x * 10 + 10, namesMailServersDot[x]) + for x in range(len(namesMailServersDot))] if mxValues: # Добавляем MX записи domainEntry.append(('mXRecord', mxValues)) @@ -19835,8 +19800,8 @@ in LDAP")%zoneName) self.clVars должен быть определен """ - print _("Enter the allowed ip addresses and network for %s service")\ - %"DNS" + " (" + _("comma or space delimited") + ")" + print(_("Enter the allowed ip addresses and network for %s service")\ + %"DNS" + " (" + _("comma or space delimited") + ")") strPrompt = _("allow networks: ") netAllow = self.clVars.Get("sr_dns_net_allow") strNetAllow = "" @@ -19854,12 +19819,11 @@ in LDAP")%zoneName) """Проверка ключа sdb-ldap bind""" pathBind = "/var/db/pkg/net-dns" if os.path.exists(pathBind): - subPathsBind = filter(lambda x: re.search("bind-\d",x),\ - os.listdir(pathBind)) + subPathsBind = [x for x in os.listdir(pathBind) if re.search("bind-\d", x)] if subPathsBind: - pathsUSE = (os.path.join(pathBind,subPathsBind[0],"IUSE"), - os.path.join(pathBind,subPathsBind[0],"USE")) - if filter(lambda x: not os.path.exists(x), pathsUSE): + pathsUSE = (os.path.join(pathBind, subPathsBind[0], "IUSE"), + os.path.join(pathBind, subPathsBind[0], "USE")) + if [x for x in pathsUSE if not os.path.exists(x)]: return False for pathUSE in pathsUSE: flagFound = False @@ -19886,7 +19850,7 @@ net-dns/bind version>=9.6.1')) return False # Принудительная установка forceOptions = False - if options.has_key("f"): + if "f" in options: forceOptions = True # Создаем объект переменных self.createClVars() @@ -19916,13 +19880,13 @@ net-dns/bind version>=9.6.1')) _("input 'yes'") +", "+ _("if not 'no'") if not self.dialogYesNo(messDialog): return True - if options.has_key("a"): + if "a" in options: # Получаем от пользователя доверительные сети allowNet = self.getAllowNet() if not allowNet: return False else: - if options.has_key("a"): + if "a" in options: # Получаем от пользователя доверительные сети allowNet = self.getAllowNet() if not allowNet: @@ -20004,7 +19968,7 @@ net-dns/bind version>=9.6.1')) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): - print _("LDAP Error") + ": " + self.ldapObj.getError().strip() + print(_("LDAP Error") + ": " + self.ldapObj.getError().strip()) return False # Записываем данные администратора сервиса Proxy ldapParser = iniLdapParser() @@ -20054,10 +20018,8 @@ class servDhcp(shareLdap, shareIP): # Проверка на наличие всех нужных опций if not set(minKeys)<=set(optKeys): notFoundKeys = list(set(minKeys)-set(optKeys)) - notFoundKeys = map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x,\ - notFoundKeys) - self.printERROR(_("Not enough command line options: %s")\ - %", ".join(notFoundKeys)) + notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] + self.printERROR(_("Not enough command line options: %s") % ", ".join(notFoundKeys)) return False # имя хоста hostname = options["host"] @@ -20127,25 +20089,25 @@ class servDhcp(shareLdap, shareIP): for net, data in dataNets: if netNoMask == net: notFoundOpts = [] - if data.has_key("range"): - ranges = filter(lambda x: x.strip(), data["range"]) + if "range" in data: + ranges = [x for x in data["range"] if x.strip()] if not ranges: notFoundOpts.append(("range", "--range ")) - if data.has_key("optiondomain-name-servers"): + if "optiondomain-name-servers" in data: dnsIPs = data["optiondomain-name-servers"][0].split(",") if not dnsIPs: notFoundOpts.append(("option domain-name-servers", "--dnsip ")) - if data.has_key("optiondomain-name"): - domainNames = map(lambda x: x.strip().replace('"',''),\ - data["optiondomain-name"]) + if "optiondomain-name" in data: + domainNames = [x.strip().replace('"', '') + for x in data["optiondomain-name"]] if not domainNames: notFoundOpts.append(("option domain-name", "--dnames ")) if notFoundOpts: - optionsPr = map(lambda x: "'%s'"%x[0], notFoundOpts) - optionsCmdPr = map(lambda x: x[1], notFoundOpts) + optionsPr = ["'%s'" % x[0] for x in notFoundOpts] + optionsCmdPr = [x[1] for x in notFoundOpts] self.printERROR(_("Can not create DNS zone %s") %net) self.printERROR(\ _('Can not found %s')%",".join(optionsPr) + " "+\ @@ -20190,9 +20152,9 @@ class servDhcp(shareLdap, shareIP): ipNumb = self.getNumberIP(ip) domainNames = [] if isRange(ipNumb, minNumber, maxNumber): - if data.has_key("optiondomain-name"): - domainNames = map(lambda x: x.strip().replace('"',''),\ - data["optiondomain-name"]) + if "optiondomain-name" in data: + domainNames = [x.strip().replace('"','') + for x in data["optiondomain-name"]] break else: self.printERROR(\ @@ -20236,11 +20198,10 @@ class servDhcp(shareLdap, shareIP): minNumber, maxNumber = self.getMinAndMaxIpNumb(net) osNets = self.clVars.Get("os_net_allow") serverNets = osNets.split(',') - dataMinMaxIP = map(lambda x: self.getMinAndMaxIpNumb(x), serverNets) + dataMinMaxIP = [self.getMinAndMaxIpNumb(x) for x in serverNets] # Проверка на попадание в диапазон сети isRange = lambda n, minN, maxN: minN<=n<=maxN - if filter(lambda x: isRange(minNumber,x[0],x[1]) and\ - isRange(maxNumber,x[0],x[1]), dataMinMaxIP): + if [x for x in dataMinMaxIP if isRange(minNumber, x[0], x[1]) and isRange(maxNumber, x[0], x[1])]: return True self.printERROR("Can not found network %s in network interfaces: \ eth0, eth1, ... etc."%net) @@ -20281,7 +20242,7 @@ eth0, eth1, ... etc."%net) _("in config file %s") %dhcpObj.nameConfigFile) return False ip = "" - if options.has_key("ip"): + if "ip" in options: # ip адрес хоста ip = options["ip"] # проверка правильности ip @@ -20302,7 +20263,7 @@ eth0, eth1, ... etc."%net) if not self.modifyDNSHostIP(fullHostName, ip): return False mac = "" - if options.has_key("mac"): + if "mac" in options: # mac адрес хоста mac = options["mac"] if mac: @@ -20351,7 +20312,7 @@ eth0, eth1, ... etc."%net) xmlNodesNet = dhcpObj.getXMLNet(network) # ip роутера router = "" - if options.has_key("router"): + if "router" in options: router = options["router"] # Проверка коректности ip роутера if "," in router or not self.isCorrectStringNet(router, False): @@ -20361,13 +20322,13 @@ eth0, eth1, ... etc."%net) self.printERROR(_("IP address %s incorrectly")%router) return False domainNames = [] - if options.has_key("dnames"): + if "dnames" in options: # доменные имена для поиска - domainNames = map(lambda x: x.lower(), options["dnames"].split(",")) + domainNames = [x.lower() for x in options["dnames"].split(",")] domainNames = self.unicList(domainNames) # проверка доменных имен на ip - incorrectDomains = filter(lambda x:\ - self.isCorrectStringNet(x, False), domainNames) + incorrectDomains = [x for x in domainNames + if self.isCorrectStringNet(x, False)] if incorrectDomains: self.printERROR(_('Incorrect command line option "--dnames"')) self.printWARNING(_("Example") + ":") @@ -20375,7 +20336,7 @@ eth0, eth1, ... etc."%net) return False dhcpObj = dncpTxt() ranges = [] - if options.has_key("range"): + if "range" in options: # Диапазон динамических ip ranges = self.isCorrectIPRangeListAndSort(net, options["range"].split(",")) @@ -20393,7 +20354,7 @@ eth0, eth1, ... etc."%net) return False dnsIP = "" # ip адреса dns серверов - if options.has_key("dnsip"): + if "dnsip" in options: dnsIP = options["dnsip"] # проверка правильности ip if not self.isCorrectStringNet(dnsIP, False) or\ @@ -20423,9 +20384,8 @@ eth0, eth1, ... etc."%net) hostname = self.servDnsObj.clVars.Get("os_net_hostname") if hostname: zone = oldDomainNames[0] - fullServerDNSName = "%s.%s"%(hostname,zone) - if not filter(lambda x: fullServerDNSName==x[0],\ - moveRecords): + fullServerDNSName = "%s.%s" % (hostname,zone) + if not [x for x in moveRecords if fullServerDNSName == x[0]]: foundServ = self.servDnsObj.searchDomainNameInLDAP(\ fullServerDNSName) if foundServ: @@ -20470,8 +20430,8 @@ eth0, eth1, ... etc."%net) # Проверка на наличие всех нужных опций if not set(minKeys)<=set(optKeys): notFoundKeys = list(set(minKeys)-set(optKeys)) - notFoundKeys = map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x,\ - notFoundKeys) + notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x + for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ %", ".join(notFoundKeys)) return False @@ -20490,7 +20450,7 @@ eth0, eth1, ... etc."%net) # Находим ip хоста dataHosts = dhcpObj.getDataInAllHost() for host, data in dataHosts: - if hostname == host and data.has_key("fixed-address"): + if hostname == host and "fixed-address" in data: if data["fixed-address"]: ip = data["fixed-address"][0] break @@ -20518,8 +20478,7 @@ eth0, eth1, ... etc."%net) self.printERROR(_("Can not found networks in config file %s")\ %dhcpObj.nameConfigFile) return False - getPar = lambda opt, data: map(lambda x: opt in x[1].keys() and\ - (x[0],x[1][opt]) or (), data) + getPar = lambda opt, data: [opt in x[1].keys() and (x[0], x[1][opt]) or () for x in data] nets = getPar('mask', dataNets) if not nets: self.printERROR(\ @@ -20554,8 +20513,7 @@ eth0, eth1, ... etc."%net) # Проверка на наличие всех нужных опций if not set(minKeys)<=set(optKeys): notFoundKeys = list(set(minKeys)-set(optKeys)) - notFoundKeys = map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x,\ - notFoundKeys) + notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ %", ".join(notFoundKeys)) return False @@ -20598,19 +20556,19 @@ eth0, eth1, ... etc."%net) FD = open(self.resolvFile) lines = FD.readlines() FD.close() - linesSearchDomains = filter(lambda x: "search " in x or\ - "search\t" in x, lines) + linesSearchDomains = [x for x in lines if "search " in x or\ + "search\t" in x] if linesSearchDomains: - searchDomains = filter(lambda x: x,\ - linesSearchDomains[0].partition("search")[2].replace("\t",\ - " ").split(" ")) - return map(lambda x: x.rstrip(), searchDomains) + searchDomains = [x for x in linesSearchDomains[0].\ + partition("search")[2].replace("\t",\ + " ").split(" ") if x] + return [x.rstrip() for x in searchDomains] def createResolvFile(self, searchDomains): """Создание и модификация /etc/resolv.conf""" dnsIP = "127.0.0.1" - mode = 0644 - domainNames = map(lambda x: x.lower(), searchDomains.split(",")) + mode = 0o644 + domainNames = [x.lower() for x in searchDomains.split(",")] domainNames = self.unicList(domainNames) searchDomains = " ".join(domainNames) if not os.path.exists(self.resolvFile): @@ -20633,7 +20591,7 @@ eth0, eth1, ... etc."%net) def createHostsFile(self, fullHostName): """Создание и модификация /etc/hosts""" dnsIP = "127.0.0.1" - mode = 0644 + mode = 0o644 hostname, spl, domainName = fullHostName.partition(".") if not domainName: domainName = "local" @@ -20674,8 +20632,7 @@ eth0, eth1, ... etc."%net) # Проверка на наличие всех нужных опций if not set(minKeys)<=set(optKeys): notFoundKeys = list(set(minKeys)-set(optKeys)) - notFoundKeys = map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x,\ - notFoundKeys) + notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ %", ".join(notFoundKeys)) return False @@ -20699,12 +20656,12 @@ eth0, eth1, ... etc."%net) return False # доменные имена для поиска domainNames = [] - if options.has_key("dnames"): - domainNames = map(lambda x: x.lower(), options["dnames"].split(",")) + if "dnames" in options: + domainNames = [x.lower() for x in options["dnames"].split(",")] domainNames = self.unicList(domainNames) # проверка доменных имен на ip - incorrectDomains = filter(lambda x:\ - self.isCorrectStringNet(x, False), domainNames) + incorrectDomains = [x for x in domainNames + if self.isCorrectStringNet(x, False)] if incorrectDomains: self.printERROR(_('Incorrect command line option "--dnames"')) self.printWARNING(_("Example") + ":") @@ -20720,7 +20677,7 @@ eth0, eth1, ... etc."%net) return False dnsIP = "" # ip адреса dns серверов - if options.has_key("dnsip"): + if "dnsip" in options: dnsIP = options["dnsip"] # проверка правильности ip if not self.isCorrectStringNet(dnsIP, False) or\ @@ -20754,7 +20711,7 @@ eth0, eth1, ... etc."%net) recData = self.servDnsObj.searchAllDomainNamesInLDAP(fullHostName) ip = "" if recData: - if recData[0][0][1].has_key('aRecord'): + if 'aRecord' in recData[0][0][1]: ip = recData[0][0][1]['aRecord'][0] # Удаляем A запись if not self.servDnsObj.delRecordDnsServer({"host":fullHostName}, @@ -20773,12 +20730,11 @@ eth0, eth1, ... etc."%net) deleteIP = self.servDnsObj.searchIPForHostInReverse(\ fullHostName) if recData: - if recData[0][0][1].has_key('pTRRecord'): + if 'pTRRecord' in recData[0][0][1]: hostList = recData[0][0][1]['pTRRecord'] # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x,\ - y.split("."))) - hostList = map(lambda x: delDot(x),hostList) + delDot = lambda y: ".".join(x for x in y.split(".") if x) + hostList = [delDot(x) for x in hostList] if not fullHostName in hostList: deleteIP.append(ip) deleteIP = list(set(deleteIP)) @@ -20806,7 +20762,7 @@ eth0, eth1, ... etc."%net) return False if recData: flagDelARecord = True - if recData[0][0][1].has_key('aRecord'): + if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] if ip in aRecords: flagCreateARecord = False @@ -20885,14 +20841,13 @@ eth0, eth1, ... etc."%net) # Флаг создания обратной записи flagCreatePTRRecord = True if recData: - if recData[0][0][1].has_key('pTRRecord'): + if 'pTRRecord' in recData[0][0][1]: hostList = recData[0][0][1]['pTRRecord'] # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x,\ - y.split("."))) - hostList = map(lambda x: delDot(x),hostList) + delDot = lambda y: ".".join(x for x in y.split(".") if x) + hostList = [delDot(x) for x in hostList] if fullHostName in hostList: - deleteIP = filter(lambda x: x!=ip, deleteIP) + deleteIP = [x for x in deleteIP if x != ip] flagCreatePTRRecord = False else: deleteIP.append(ip) @@ -20943,24 +20898,24 @@ eth0, eth1, ... etc."%net) optKeys = options.keys() minKeys = ["ip", "domain", "host", "s", "b"] # Проверка на наличие всех нужных опций - if not set(minKeys)<=set(optKeys): - notFoundKeys = list(set(minKeys)-set(optKeys)) - notFoundKeys = map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x,\ - notFoundKeys) + if not set(minKeys) <= set(optKeys): + notFoundKeys = list(set(minKeys) - set(optKeys)) + notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x + for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ %", ".join(notFoundKeys)) return False optPwd = ["p","P"] - listOptPwd = filter(lambda x: x in optPwd, options.keys()) + listOptPwd = [x for x in options.keys() if x in optPwd] if len(listOptPwd) > 1: self.printERROR(_("Command line options '-p' and '-P' are \ incompatible, use one of the options")) return False adminDn = options['s'] - if options.has_key("p"): + if "p" in options: adminPw = options['p'] - elif options.has_key("P"): + elif "P" in options: pathPasswd = options['P'] if os.path.exists(pathPasswd): try: @@ -20982,7 +20937,7 @@ incompatible, use one of the options")) self.printERROR(_("IP address %s incorrectly")%ip) return False domain = options['domain'] - listDomain = filter(lambda x: x.strip(), domain.split(" ")) + listDomain = [x for x in domain.split(" ") if x.strip()] if not listDomain: self.printERROR(_('Incorrect command line option "--domain"')) return False @@ -21029,7 +20984,7 @@ incompatible, use one of the options")) # Поиск статических DHCP хостов в DNS for hostname, data in dataHosts: ip = "" - if not data.has_key("fixed-address"): + if "fixed-address" not in data: self.printERROR(_("Can not found ip static host %s")\ %hostname+ " " + _("in config file %s")\ %dhcpObj.nameConfigFile) @@ -21052,7 +21007,7 @@ incompatible, use one of the options")) recData = self.servDnsObj.searchAllDomainNamesInLDAP(\ fullDomainName) if recData: - if recData[0][0][1].has_key('aRecord'): + if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] if ip in aRecords: retData[fullDomainName] = ip @@ -21100,7 +21055,7 @@ incompatible, use one of the options")) domainName = "%s.%s"\ %(record[0][1]["relativeDomainName"][0],\ zoneName) - if record[0][1].has_key("aRecord"): + if "aRecord" in record[0][1]: ip = record[0][1]["aRecord"][0] # ip в диапазоне динамических адресов if isRange(self.getNumberIP(ip), minIpRange, maxIpRange): @@ -21139,7 +21094,7 @@ incompatible, use one of the options")) def moveDNSRecords(self, newZoneName, moveRecords): """Перенос записей в новую зону""" # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x, y.split("."))) + delDot = lambda y: ".".join(x for x in y.split(".") if x) flagError = False for hostname, ip in moveRecords: newHostName = ".".join([hostname.partition(".")[0],newZoneName]) @@ -21169,7 +21124,7 @@ incompatible, use one of the options")) # Поиск в новой зоне A записи foundNewARec = self.servDnsObj.searchDomainNameInLDAP(newHostName) if foundNewARec: - if foundNewARec[0][0][1].has_key('aRecord'): + if 'aRecord' in foundNewARec[0][0][1]: if foundNewARec[0][0][1]['aRecord'][0] != otherIP: self.printERROR(_("Record %s exists in DNS service")\ %newHostName) @@ -21253,8 +21208,7 @@ incompatible, use one of the options")) dnsIP = ",".join(dnsIPs) if not self.servDnsObj.searchZoneInLDAP(zoneName): # Находим все ip DNS cервера - IPs = filter(None, - self.servDnsObj.clVars.Get("os_net_ip").split(",")) + IPs = [x for x in self.servDnsObj.clVars.Get("os_net_ip").split(",") if x] if not IPs: self.printERROR(_("Can not found ip in net interfaces")) return False @@ -21269,10 +21223,10 @@ incompatible, use one of the options")) if flagErrorRange: self.printERROR(\ _('Command line option "--range %s" incorrectly')\ - %",".join(ranges)) + % ",".join(ranges)) self.printERROR( _("Invalid range of network addresses for the network %s")\ - %net) + % net) return False flagFoundDnsIp = False for ipDns in dnsIPs: @@ -21285,7 +21239,7 @@ incompatible, use one of the options")) _('Command line option "--dnsip %s" incorrectly')\ %dnsIP) self.printERROR(_("Can not found ip address dns servers in \ -network %s")%net) +network %s") % net) return False ipserver = "" for ipIntr in IPs: @@ -21296,8 +21250,8 @@ network %s")%net) if not ipserver: self.printERROR(\ _("Ip addresses on the interfaces of the system (%s)")\ - %",".join(IPs)+" "+_("does not belong to the network %s")\ - %net) + % ",".join(IPs) + " " + _("does not belong to the network %s")\ + % net) return False # опции добавления DNS зоны optionsDns = {"n":zoneName, @@ -21308,8 +21262,7 @@ network %s")%net) return False # Ищем обратные зоны в DNS listNet24 = self.nets24ToIpAndMask(net) - listStrNet24 = map(lambda x: ".".join(map(lambda y: str(y), x)), - listNet24) + listStrNet24 = [".".join(str(y) for y in x) for x in listNet24] # Получаем имена обратных зон reverseZoneNames = [] for net24 in listStrNet24: @@ -21317,7 +21270,7 @@ network %s")%net) netSpl.pop() netSpl.reverse() # Имя обратной зоны - reverseZoneNames.append("%s.in-addr.arpa" %".".join(netSpl)) + reverseZoneNames.append("%s.in-addr.arpa" % ".".join(netSpl)) # Создаем обратные зоны в тексте конфигурационного файла objTxtZone = dnsTxt() if not objTxtZone.createExclZones(self.servDnsObj.clVars, @@ -21362,8 +21315,8 @@ network %s")%net) for net, data in dataNets: notFoundOpts = [] ranges = [] - if data.has_key("range"): - ranges = filter(lambda x: x.strip(), data["range"]) + if "range" in data: + ranges = [x for x in data["range"] if x.strip()] if not ranges: notFoundOpts.append(("range", "--range ")) @@ -21375,21 +21328,21 @@ network %s")%net) " " + _("in config file %s") %dhcpObj.nameConfigFile) return False dnsIPs = [] - if data.has_key("optiondomain-name-servers"): + if "optiondomain-name-servers" in data: dnsIPs = data["optiondomain-name-servers"][0].split(",") if not dnsIPs: notFoundOpts.append(("option domain-name-servers", "--dnsip ")) domainNames = [] - if data.has_key("optiondomain-name"): - domainNames = map(lambda x: x.strip().replace('"',''),\ - data["optiondomain-name"]) + if "optiondomain-name" in data: + domainNames = [x.strip().replace('"', '') + for x in data["optiondomain-name"]] if not domainNames: notFoundOpts.append(("option domain-name", "--dnames ")) if notFoundOpts: - optionsPr = map(lambda x: "'%s'"%x[0], notFoundOpts) - optionsCmdPr = map(lambda x: x[1], notFoundOpts) + optionsPr = ["'%s'" % x[0] for x in notFoundOpts] + optionsCmdPr = [x[1] for x in notFoundOpts] self.printERROR(_("Can not create DNS zone %s") %net) self.printERROR(\ _('Can not found %s')%",".join(optionsPr) + " "+\ @@ -21411,7 +21364,7 @@ network %s")%net) dataHosts = dhcpObj.getDataInAllHost() for hostname, data in dataHosts: ip = "" - if not data.has_key("fixed-address"): + if "fixed-address" not in data: self.printERROR(_("Can not create static host")) self.printERROR(_("Can not found ip static host %s")\ %hostname+ " " + _("in config file %s")\ @@ -21440,7 +21393,7 @@ network %s")%net) recData = self.servDnsObj.searchAllDomainNamesInLDAP(\ fullDomainName) if recData: - if recData[0][0][1].has_key('aRecord'): + if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] if not ip in aRecords: flagError = True @@ -21469,14 +21422,13 @@ network %s")%net) # Флаг создания обратной записи flagCreatePTR = True if recData: - if recData[0][0][1].has_key('pTRRecord'): + if 'pTRRecord' in recData[0][0][1]: hostList = recData[0][0][1]['pTRRecord'] # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x,\ - y.split("."))) - hostList = map(lambda x: delDot(x),hostList) + delDot = lambda y: ".".join(x for x in y.split(".") if x) + hostList = [delDot(x) for x in hostList] if hostname in hostList: - deleteIP = filter(lambda x: x!=ip, deleteIP) + deleteIP = [x for x in deleteIP if x != ip] flagCreatePTR = False else: deleteIP.append(ip) @@ -21545,8 +21497,8 @@ network %s")%net) if not dhcpObj: dhcpObj = dncpTxt() dataHosts = dhcpObj.getDataInAllHost() - getPar = lambda opt, data: map(lambda x: opt in x[1].keys() and\ - (x[0],x[1][opt]) or (), data) + getPar = lambda opt, data:\ + [opt in x[1].keys() and (x[0],x[1][opt]) or () for x in data] flagCorrect = True staticMACs = getPar('hardwareethernet', dataHosts) for data in staticMACs: @@ -21607,12 +21559,11 @@ network %s")%net) " " + _("for network %s")%net) return False netList = self.nets24ToMinIpAndMaxIp(minNumber, maxNumber) - strNetList = map(lambda x: ".".join(map(lambda y: str(y), x[0:3])), - netList) + strNetList = [".".join(str(y) for y in x[0:3]) for x in netList] # Проверка на статические хосты dataHosts = dhcpObj.getDataInAllHost() - getPar = lambda opt, data: map(lambda x: opt in x[1].keys() and\ - (x[0],x[1][opt]) or (), data) + getPar = lambda opt, data: [opt in x[1].keys() and\ + (x[0],x[1][opt]) or () for x in data] staticIPs = getPar('fixed-address', dataHosts) for data in staticIPs: if not data: @@ -21646,8 +21597,8 @@ network %s")%net) dhcpObj = dncpTxt() dataNets = dhcpObj.getDataInAllSubnet() dataHosts = dhcpObj.getDataInAllHost() - getPar = lambda opt, data: map(lambda x: opt in x[1].keys() and\ - (x[0],x[1][opt]) or (), data) + getPar = lambda opt, data: [opt in x[1].keys() and\ + (x[0], x[1][opt]) or () for x in data] ranges = getPar('range', dataNets) try: numbIp = self.getNumberIP(ip) @@ -21743,8 +21694,8 @@ network %s")%net) dhcpObj = dncpTxt() dataNets = dhcpObj.getDataInAllSubnet() dataHosts = dhcpObj.getDataInAllHost() - getPar = lambda opt, data: map(lambda x: opt in x[1].keys() and\ - (x[0],x[1][opt]) or (), data) + getPar = lambda opt, data: [opt in x[1].keys() and\ + (x[0], x[1][opt]) or () for x in data] ranges = getPar('range', dataNets) if not ranges: self.printERROR(_("Can not found 'range' in config file %s")\ @@ -21819,7 +21770,7 @@ network %s")%net) isNotRange(maxIpRanges, minNumber, maxNumber): return [] # Проверка на коректность сетевых адресов - if filter(lambda x: not self.isCorrectStringNet(x, False), (ipA, ipB)): + if [x for x in (ipA, ipB) if not self.isCorrectStringNet(x, False)]: return [] return [self.getIPinNumber(minIpRanges),self.getIPinNumber(maxIpRanges)] @@ -21838,9 +21789,9 @@ network %s")%net) # Создаем файловый объект fileObj = cl_profile._file() dMode, dUid, dGid = fileObj.getModeFile(cl_log.log.logDir) - if dMode != 0755: + if dMode != 0o755: try: - os.chmod(cl_log.log.logDir,0755) + os.chmod(cl_log.log.logDir,0o755) except: self.printERROR(_("Can not set mode 0755 for %s")\ %cl_log.log.logDir) @@ -21893,7 +21844,7 @@ network %s")%net) # Принудительная установка forceOptions = False minKeys = [] - if options.has_key("f"): + if "f" in options: forceOptions = True minKeys = ["f"] # Создаем объект переменных @@ -21923,8 +21874,7 @@ network %s")%net) # Проверка на наличие всех нужных опций if not set(minKeys)<=set(optKeys): notFoundKeys = list(set(minKeys)-set(optKeys)) - notFoundKeys = map(lambda x: len(x)>1 and '"--%s"'%x or '"-%s"'%x,\ - notFoundKeys) + notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ %", ".join(notFoundKeys)) return False @@ -21999,26 +21949,26 @@ network %s")%net) return False # Создаем текстовый блок в конфигурационном файле для новой сети netOptions = {} - if options.has_key("net"): + if "net" in options: netOptions["net"] = options["net"] - if options.has_key("router"): + if "router" in options: netOptions["router"] = options["router"] - if options.has_key("dnames"): + if "dnames" in options: netOptions["dnames"] = options["dnames"] - if options.has_key("dnsip"): + if "dnsip" in options: netOptions["dnsip"] = options["dnsip"] - if options.has_key("range"): + if "range" in options: netOptions["range"] = options["range"] if not self.createNetDhcpServer(netOptions, False): return False # Добавляем в статические хосты имя текущего хоста hostname = self.clVars.Get("os_net_hostname") if hostname: - domainNames = map(lambda x: x.lower(), options["dnames"].split(",")) + domainNames = [x.lower() for x in options["dnames"].split(",")] domainNames = self.unicList(domainNames) domain = domainNames[0] fullHostNameServer = "%s.%s"%(hostname,domain) - IPs = filter(None,self.clVars.Get("os_net_ip").split(",")) + IPs = [x for x in self.clVars.Get("os_net_ip").split(",") if x] if not any(IPs): self.printERROR(_("Can not found ip in net interfaces")) return False @@ -22039,7 +21989,7 @@ network %s")%net) # Ищем A запись в DNS recData = self.servDnsObj.searchDomainNameInLDAP(\ fullHostNameServer) - if recData and recData[0][0][1].has_key('aRecord'): + if recData and 'aRecord' in recData[0][0][1]: flagFoundARecord = True if ipServer in recData[0][0][1]['aRecord']: flagCreateDNSRecord = False @@ -22052,13 +22002,12 @@ network %s")%net) # Находим ptr запись в DNS recData = self.servDnsObj.searchAllDomainNamesInLDAP(\ PTRDomainName) - if recData and recData[0][0][1].has_key('pTRRecord'): + if recData and 'pTRRecord' in recData[0][0][1]: if not flagCreateDNSRecord: hostList = recData[0][0][1]['pTRRecord'] # Удаляет лишние точки в названии - delDot = lambda y: ".".join(filter(lambda x: x,\ - y.split("."))) - hostList = map(lambda x: delDot(x),hostList) + delDot = lambda y: ".".join(x for x in y.split(".") if x) + hostList = [delDot(x) for x in hostList] if not fullHostNameServer in hostList: flagCreateDNSRecord = True flagDeletePTRRecord = True @@ -22142,15 +22091,15 @@ class tsOpt(cl_base.opt): tuple(set(self.opt.keys()).intersection(helpObj.relOptions.keys())) #Если есть опции help if len(helpopt) > 0: - print helpObj.getHelp(helpObj.relOptions[helpopt[0]]) + print(helpObj.getHelp(helpObj.relOptions[helpopt[0]])) self.flagHelp = True #Если нет хвостов elif not self.params: if optService or lastOpt: - print helpObj.getHelp(helpObj.relOptions['h']) + print(helpObj.getHelp(helpObj.relOptions['h'])) self.flagHelp = True else: - if self.params.has_key('service'): + if 'service' in self.params: if lastOpt: pass elif not (self.params['service'] in helpObj.allServ): @@ -22163,13 +22112,13 @@ class tsOpt(cl_base.opt): self.handlerErrOpt() self.flagHelp = True # В случае отсутствия опций командной строки - if notOptError and not self.opt and self.params.has_key('service'): + if notOptError and not self.opt and 'service' in self.params: self.printErrorNotOpt() self.flagHelp = True def printErrorNotOpt(self): """Сообщение в случае отсутствия опций""" - print _("Options are absent.") + print(_("Options are absent.")) def handlerOpt(self,option,value): # Обработчик (опция значение) @@ -22184,9 +22133,9 @@ class tsOpt(cl_base.opt): # Обработчик ошибок self.errorOpt = True argv = " ".join(sys.argv[1:]) - print _("Unrecognized option") + ' "' + argv + '"\n' + \ + print(_("Unrecognized option") + ' "' + argv + '"\n' + \ _("Try") + ' "' + sys.argv[0].split("/")[-1] + ' --help" ' +\ -_("for more information.") +_("for more information.")) def handlerParam(self,param): # Обработчик хвостов (значение) diff --git a/setup.py b/setup.py index c32e2de..4491ba7 100755 --- a/setup.py +++ b/setup.py @@ -140,15 +140,18 @@ class cl_install_data(install_data): def run (self): install_data.run(self) data_file = \ - [("/etc/init.d/sortmilter.init","sortmilter",0755), + [("/etc/init.d/sortmilter.init","sortmilter",0o755), ("/etc/conf.d/sortmilter.conf","sortmilter",None)] data_find = \ dict( - map(lambda x:(os.path.basename(x[0]), - [list(reversed(filter(lambda y:y,x[0].split("/")))), - x[1], - x[2]]), - data_file)) + # map(lambda x:(os.path.basename(x[0]), + # [list(reversed(filter(lambda y:y,x[0].split("/")))), + # x[1], + # x[2]]), + # data_file)) + + # [(os.path.basename(x[0]), [list(reversed(filter(lambda y:y,x[0].split("/")))), x[1],x[2]]) for x in data_file]) + [(os.path.basename(x[0]), [list(reversed((y for y in x[0].split("/") if y))), x[1],x[2]]) for x in data_file]) for path in self.get_outputs(): nameFile = os.path.split(path)[1] From f941712dada71373e496e25032d68fab0bfa3fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Mon, 30 Aug 2021 10:26:06 +0300 Subject: [PATCH 02/24] py3 changes in scripts, added missing cmp func --- pym/cl_ldap.py | 3 +++ scripts/cl-dhcp-hostadd | 2 +- scripts/cl-dhcp-hostdel | 2 +- scripts/cl-dhcp-hostmod | 4 ++-- scripts/cl-dhcp-netadd | 2 +- scripts/cl-dhcp-netdel | 2 +- scripts/cl-dhcp-netmod | 4 ++-- scripts/cl-dns-recadd | 2 +- scripts/cl-dns-recdel | 2 +- scripts/cl-dns-recmod | 4 ++-- scripts/cl-dns-zoneadd | 2 +- scripts/cl-dns-zonedel | 2 +- scripts/cl-dns-zonemod | 2 +- scripts/cl-groupadd | 4 ++-- scripts/cl-groupdel | 4 ++-- scripts/cl-groupmod | 4 ++-- scripts/cl-info | 2 +- scripts/cl-passwd | 4 ++-- scripts/cl-replication | 2 +- scripts/cl-setup | 2 +- scripts/cl-update-server | 2 +- scripts/cl-useradd | 4 ++-- scripts/cl-userdel | 4 ++-- scripts/cl-usermod | 4 ++-- scripts/dhcp | 6 +++--- scripts/sortmilter | 7 ++++--- 26 files changed, 43 insertions(+), 39 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index fd29efa..a378261 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -54,6 +54,9 @@ tr.setLanguage(sys.modules[__name__]) pcs = cl_utils.prettyColumnStr +def cmp(a, b): + return (a > b) - (b < a) + class report: """Класс для выдачи данных в табличном виде""" def __init__(self, title, headerList, dataList): diff --git a/scripts/cl-dhcp-hostadd b/scripts/cl-dhcp-hostadd index 1807d2a..b23cacc 100644 --- a/scripts/cl-dhcp-hostadd +++ b/scripts/cl-dhcp-hostadd @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Добавление статического хоста в DHСP diff --git a/scripts/cl-dhcp-hostdel b/scripts/cl-dhcp-hostdel index cdded4e..c6928c1 100644 --- a/scripts/cl-dhcp-hostdel +++ b/scripts/cl-dhcp-hostdel @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Удаление статического хоста diff --git a/scripts/cl-dhcp-hostmod b/scripts/cl-dhcp-hostmod index 10caf46..f4542a9 100644 --- a/scripts/cl-dhcp-hostmod +++ b/scripts/cl-dhcp-hostmod @@ -29,8 +29,8 @@ if __name__ == "__main__": optObj = cl_ldap.tsOpt(ldapObj,[],False,False,True) flagError = False # Вывод помощи если нет параметров командной строки - if not optObj.opt and optObj.params.has_key('service'): - print ldapObj.getHelp(ldapObj.relOptions['h']) + if not optObj.opt and 'service' in optObj.params: + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Модификация сети diff --git a/scripts/cl-dhcp-netadd b/scripts/cl-dhcp-netadd index dc1981e..38f3f58 100644 --- a/scripts/cl-dhcp-netadd +++ b/scripts/cl-dhcp-netadd @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Добавление cети diff --git a/scripts/cl-dhcp-netdel b/scripts/cl-dhcp-netdel index 35b31e6..b1eb435 100644 --- a/scripts/cl-dhcp-netdel +++ b/scripts/cl-dhcp-netdel @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Удаление сети diff --git a/scripts/cl-dhcp-netmod b/scripts/cl-dhcp-netmod index 66243a0..c6c0ff2 100644 --- a/scripts/cl-dhcp-netmod +++ b/scripts/cl-dhcp-netmod @@ -30,8 +30,8 @@ if __name__ == "__main__": optObj = cl_ldap.tsOpt(ldapObj,[],False,False,True) flagError = False # Вывод помощи если нет параметров командной строки - if not optObj.opt and optObj.params.has_key('service'): - print ldapObj.getHelp(ldapObj.relOptions['h']) + if not optObj.opt and 'service' in optObj.params: + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Модификация сети diff --git a/scripts/cl-dns-recadd b/scripts/cl-dns-recadd index ea697d7..06fcfc3 100644 --- a/scripts/cl-dns-recadd +++ b/scripts/cl-dns-recadd @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Добавление записи в DNS diff --git a/scripts/cl-dns-recdel b/scripts/cl-dns-recdel index 20f3d6a..232f7d4 100644 --- a/scripts/cl-dns-recdel +++ b/scripts/cl-dns-recdel @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Добавление записи в DNS diff --git a/scripts/cl-dns-recmod b/scripts/cl-dns-recmod index 2d759fc..700ec2e 100644 --- a/scripts/cl-dns-recmod +++ b/scripts/cl-dns-recmod @@ -30,8 +30,8 @@ if __name__ == "__main__": optObj = cl_ldap.tsOpt(ldapObj,[],False,False,True) flagError = False # Вывод помощи если нет параметров командной строки - if not optObj.opt and optObj.params.has_key('service'): - print ldapObj.getHelp(ldapObj.relOptions['h']) + if not optObj.opt and 'service' in optObj.params: + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Добавление записи в DNS diff --git a/scripts/cl-dns-zoneadd b/scripts/cl-dns-zoneadd index 24f9290..b54913d 100644 --- a/scripts/cl-dns-zoneadd +++ b/scripts/cl-dns-zoneadd @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Добавление записи в DNS diff --git a/scripts/cl-dns-zonedel b/scripts/cl-dns-zonedel index a3fa8a5..d7d30e6 100644 --- a/scripts/cl-dns-zonedel +++ b/scripts/cl-dns-zonedel @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Добавление записи в DNS diff --git a/scripts/cl-dns-zonemod b/scripts/cl-dns-zonemod index e1c0a46..03abafc 100644 --- a/scripts/cl-dns-zonemod +++ b/scripts/cl-dns-zonemod @@ -31,7 +31,7 @@ if __name__ == "__main__": flagError = False # Вывод помощи если нет параметров командной строки if not optObj.opt: - print ldapObj.getHelp(ldapObj.relOptions['h']) + print(ldapObj.getHelp(ldapObj.relOptions['h'])) optObj.flagHelp = True if not optObj.flagHelp: # Добавление записи в DNS diff --git a/scripts/cl-groupadd b/scripts/cl-groupadd index eedf35d..561e15f 100644 --- a/scripts/cl-groupadd +++ b/scripts/cl-groupadd @@ -30,8 +30,8 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-groupadd") optObj = cl_ldap.tsOpt(ldapObj,['group']) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and \ - optObj.params.has_key('group'): + if not optObj.flagHelp and 'service' in optObj.params and \ + 'group' in optObj.params: flagError = True if optObj.params['service'] == "unix": obj = cl_ldap.servUnix() diff --git a/scripts/cl-groupdel b/scripts/cl-groupdel index 9fa2222..0e942d2 100644 --- a/scripts/cl-groupdel +++ b/scripts/cl-groupdel @@ -29,8 +29,8 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-groupdel") optObj = cl_ldap.tsOpt(ldapObj,['group']) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ - optObj.params.has_key('group'): + if not optObj.flagHelp and 'service' in optObj.params and\ + 'group' in optObj.params: flagError = True if optObj.params['service'] == "unix": obj = cl_ldap.servUnix() diff --git a/scripts/cl-groupmod b/scripts/cl-groupmod index 4627c11..362d90d 100644 --- a/scripts/cl-groupmod +++ b/scripts/cl-groupmod @@ -29,8 +29,8 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-groupmod") optObj = cl_ldap.tsOpt(ldapObj,['group'],True,True) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ - optObj.params.has_key('group'): + if not optObj.flagHelp and 'service' in optObj.params and\ + 'group' in optObj.params: if optObj.params['service'] == "unix": obj = cl_ldap.servUnix() # Модифицируем группу diff --git a/scripts/cl-info b/scripts/cl-info index 2ab346e..2536a47 100644 --- a/scripts/cl-info +++ b/scripts/cl-info @@ -29,7 +29,7 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-info") optObj = cl_ldap.tsOpt(ldapObj,[]) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ + if not optObj.flagHelp and 'service' in optObj.params and\ not optObj.errorOpt: # Информация о сервисах и пользователях flagError = True diff --git a/scripts/cl-passwd b/scripts/cl-passwd index 2648002..fe14b80 100644 --- a/scripts/cl-passwd +++ b/scripts/cl-passwd @@ -29,8 +29,8 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-passwd") optObj = cl_ldap.tsOpt(ldapObj,['user']) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ - optObj.params.has_key('user'): + if not optObj.flagHelp and 'service' in optObj.params and\ + 'user' in optObj.params: flagError = True if optObj.params['service'] == "unix": obj = cl_ldap.servUnix() diff --git a/scripts/cl-replication b/scripts/cl-replication index ad66d02..1c5c4e3 100644 --- a/scripts/cl-replication +++ b/scripts/cl-replication @@ -29,7 +29,7 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-replication") optObj = cl_ldap.tsOpt(ldapObj,[]) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ + if not optObj.flagHelp and 'service' in optObj.params and\ not optObj.errorOpt: # Настройка сервера LDAP flagError = True diff --git a/scripts/cl-setup b/scripts/cl-setup index da84b81..5765713 100644 --- a/scripts/cl-setup +++ b/scripts/cl-setup @@ -29,7 +29,7 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-setup") optObj = cl_ldap.tsOpt(ldapObj,[]) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service'): + if not optObj.flagHelp and 'service' in optObj.params: # Настройка сервера LDAP flagError = True if optObj.params['service'] == "ldap" and \ diff --git a/scripts/cl-update-server b/scripts/cl-update-server index e03fc4d..d47bc54 100644 --- a/scripts/cl-update-server +++ b/scripts/cl-update-server @@ -29,7 +29,7 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-update-server") optObj = cl_ldap.tsOpt(ldapObj,[]) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ + if not optObj.flagHelp and 'service' in optObj.params and\ not optObj.errorOpt: # Настройка сервера LDAP flagError = True diff --git a/scripts/cl-useradd b/scripts/cl-useradd index df9f7de..3455b0d 100644 --- a/scripts/cl-useradd +++ b/scripts/cl-useradd @@ -29,8 +29,8 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-useradd") optObj = cl_ldap.tsOpt(ldapObj,['user']) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ - optObj.params.has_key('user'): + if not optObj.flagHelp and 'service' in optObj.params and\ + 'user' in optObj.params: flagError = True if optObj.params['service'] == "unix": obj = cl_ldap.servUnix() diff --git a/scripts/cl-userdel b/scripts/cl-userdel index 87f757f..562f156 100644 --- a/scripts/cl-userdel +++ b/scripts/cl-userdel @@ -29,8 +29,8 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-userdel") optObj = cl_ldap.tsOpt(ldapObj,['user']) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ - optObj.params.has_key('user'): + if not optObj.flagHelp and 'service' in optObj.params and\ + 'user' in optObj.params: flagError = True if optObj.params['service'] == "unix": obj = cl_ldap.servUnix() diff --git a/scripts/cl-usermod b/scripts/cl-usermod index cac1cc0..5229b83 100644 --- a/scripts/cl-usermod +++ b/scripts/cl-usermod @@ -30,8 +30,8 @@ if __name__ == "__main__": ldapObj = cl_ldap.cl_ldap("cl-usermod") optObj = cl_ldap.tsOpt(ldapObj,['user'],True,True) flagError = False - if not optObj.flagHelp and optObj.params.has_key('service') and\ - optObj.params.has_key('user'): + if not optObj.flagHelp and 'service' in optObj.params and\ + 'user' in optObj.params: flagError = True if optObj.params['service'] == "unix": obj = cl_ldap.servUnix() diff --git a/scripts/dhcp b/scripts/dhcp index 07256ae..e091139 100644 --- a/scripts/dhcp +++ b/scripts/dhcp @@ -45,12 +45,12 @@ if __name__ == "__main__": os.setgid(gid) os.setuid(uid) except: - print _("ERROR: Can not set owner") + \ + print(_("ERROR: Can not set owner") + \ " (dhcp:dhcp uid=%s,gid=%s) "%(uid, gid) +\ - _("the this process") + _("the this process")) sys.exit(1) if os.getuid() != uid: - print _("ERROR: Owner this process not dhcp or root") + print(_("ERROR: Owner this process not dhcp or root")) sys.exit(1) if os.access(logFullFile, os.W_OK): logObj = cl_log.log(logFile) diff --git a/scripts/sortmilter b/scripts/sortmilter index abef8c0..eaed84e 100755 --- a/scripts/sortmilter +++ b/scripts/sortmilter @@ -24,6 +24,7 @@ from os.path import join as pathjoin, exists as pathexists from shutil import copy as copyfile, move as movefile from optparse import OptionParser from threading import Lock +from functools import reduce # fix ecre in email module email.header.ecre = re.compile(r''' @@ -63,7 +64,7 @@ class Logger: self.logfile.flush() except: sys.stderr.write(strftime("%Y%m%d%H%M%S ") + - "".join(apply(traceback.format_exception, sys.exc_info()))) + "".join(traceback.format_exception(*sys.exc_info()))) self.lock.release() def printDEBUG(self,s): @@ -96,7 +97,7 @@ class Logger: def dbg_except(): """Debug function, for try-except block""" Logger().printLOG(strftime("%Y%m%d%H%M%S ") + - "".join(apply(traceback.format_exception, sys.exc_info()))) + "".join(traceback.format_exception(*sys.exc_info()))) def strstime(format="%Y-%m-%d_%H:%M",seconds=0): return strftime(format, localtime(seconds)) @@ -186,7 +187,7 @@ class Letter: try: if charset and charset[0] and not charset[0].lower() in ['utf-8','utf8']: letter_text = letter_text.decode(charset[0]).encode('utf-8') - except Exception,e: + except Exception as e: Logger().printDEBUG("wrong decode from %s: %s" % (charset[0], e)) return letter_text From e70baedc10d720598654d192489b3ff22e99eed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Mon, 30 Aug 2021 14:44:39 +0300 Subject: [PATCH 03/24] added lib scripts to server, applied more py3 changes --- pym/cl_base.py | 1161 +++++++ pym/cl_fill.py | 311 ++ pym/cl_fill_server.py | 293 +- pym/cl_ldap.py | 55 +- pym/cl_log.py | 59 + pym/cl_profile.py | 7240 +++++++++++++++++++++++++++++++++++++++++ pym/cl_utils.py | 608 ++++ pym/cl_utils2.py | 563 ++++ pym/cl_vars.py | 92 + setup.py | 5 +- 10 files changed, 10355 insertions(+), 32 deletions(-) create mode 100644 pym/cl_base.py create mode 100644 pym/cl_fill.py create mode 100644 pym/cl_log.py create mode 100644 pym/cl_profile.py create mode 100644 pym/cl_utils.py create mode 100644 pym/cl_utils2.py create mode 100644 pym/cl_vars.py diff --git a/pym/cl_base.py b/pym/cl_base.py new file mode 100644 index 0000000..a827c8d --- /dev/null +++ b/pym/cl_base.py @@ -0,0 +1,1161 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Mir Calculate. 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 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 +from . import cl_utils +############################################################################## + +_expand_lang = gettext._expand_lang + +def exit(codeExit): + """Метод выхода из программы""" + sys.exit(codeExit) + +def __findFileMO(domain, localedir=None, languages=None, all=0): + # Модифицинрованный метод модуля gettext ищет файл перевода + if localedir is None: + localedir = gettext._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(metaclass=GlobalParam): + """Класс многоязыковой поддержки 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() - домен перевода. + """ + def __init__(self,l=''): + self.nameDomain = self.GP[0] + #self.nameDomain = '' + """ Название файла перевода (Домен) если используется 1 файл перевода + """ + self.__catalog = os.path.abspath('/usr/share/calculate-2.0/i18n') + """ Путь к каталогу переводов (в этом каталоге + ru_RU/LC_MESSAGES в котором файл перевода) + """ + env = os.environ + if l == "" and 'LANG' in env: + 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 namemodule in self.__modnames: + 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 + +############################################################################### +from . import cl_profile +class iniParser(cl_profile._error): + """Класс для работы с ini файлами + + """ + def __init__(self, iniFile): + # название ini файла + self.iniFile = iniFile + # права создаваемого ini-файла + self.mode = 0o640 + # Cоответствует ли формат файла нужному + self.checkIni = None + + def setMode(self, mode): + """установка прав создаваемого ini-файла""" + self.mode = mode + + def openIniFile(self): + if not os.access(self.iniFile, os.R_OK): + 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() + nameFomat = self.checkIniFile(textIni) + if not nameFomat: + return False + if type(strHeader) in (tuple, list): + # формат plasma + classObj = cl_profile.plasma + else: + if nameFomat == "plasma": + self.setError(_("In the file %s (format - 'plasma'), \ + write the variable in the format 'samba'")\ + %self.iniFile) + return False + # формат samba + classObj = cl_profile.samba + # создаем объект + # и записываем в него содержимое ini-файла + objIni = classObj(textIni) + # создаем текст из строки заголовка и + # словаря переменных области + txtConfig = objIni.createTxtConfig(strHeader, dictVar) + # создаем объект и записываем в него текст + objIniAdd = classObj(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 = "samba" + # В файле есть данные + textIni = re.sub(r"^#.*$",textIni,'',re.M) + if not self.isEmptyFile(textIni): + try: + objIni = cl_profile.plasma(textIni) + except: + self.setError(_("Incorrect format file") + ": " + \ + self.iniFile) + self.checkIni = False + return self.checkIni + allAreas = objIni.docObj.getAllAreas() + for xmlArea in allAreas: + parentNode = xmlArea.parentNode + if parentNode and parentNode.tagName == "area": + self.checkIni = "plasma" + break + if self.checkIni == "samba": + 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 файла""" + if type(strHeader) in (tuple, list): + # Формат plasma + delStrHeader = strHeader[:] + delStrHeader[-1] = "!%s"%delStrHeader[-1] + else: + # Формат samba + delStrHeader = "!%s" %(strHeader) + dictVar = {"del":"del"} + res = self.setVar(delStrHeader, dictVar) + return res + + def getVar(self, strHeader, nameVar): + """Получаем значение переменной из ini-файла""" + textIni = self.openIniFile() + nameFomat = self.checkIniFile(textIni) + if not nameFomat: + return False + formatPlasma = False + if type(strHeader) in (tuple, list): + # формат plasma + classObj = cl_profile.plasma + formatPlasma = True + else: + if nameFomat == "plasma": + self.setError(_("In the file %s (format - 'plasma'), \ + get the variable in the format 'samba'")\ + %self.iniFile) + return False + # формат samba + classObj = cl_profile.samba + # создаем объект и записываем в него содержимое ini-файла + objIni = classObj(textIni) + # получаем ноду body + xmlBody = objIni.docObj.getNodeBody() + flagFound, xmlBody = self.getLastNode(objIni, xmlBody, strHeader, + formatPlasma) + if flagFound and xmlBody: + if formatPlasma: + strHeader = strHeader[-1] + # находим в области переменную + res = objIni.docObj.getAreaFieldValues(strHeader, nameVar, xmlBody) + else: + res = False + if res is False: + return "" + else: + return res + + + def getLastNode(self, objIni, xmlBody, strHeader, formatPlasma): + """Ищет область в XML в которой область с переменными""" + flagFound = True + lenStrHeader = len(strHeader) + if formatPlasma and lenStrHeader>0: + xmlAreas = [xmlBody] + for i in range(lenStrHeader-1): + flagFound = False + for xmlArea in xmlAreas: + xmlAreas = objIni.docObj.getArea(strHeader[i], xmlArea) + if xmlAreas: + flagFound = True + break + if xmlAreas: + xmlBody = xmlAreas[0] + return flagFound,xmlBody + + def getAreaVars(self, strHeader): + """Получаем все переменнные области из ini-файла""" + textIni = self.openIniFile() + nameFomat = self.checkIniFile(textIni) + if not nameFomat: + return False + formatPlasma = False + if type(strHeader) in (tuple, list): + # формат plasma + classObj = cl_profile.plasma + formatPlasma = True + else: + if nameFomat == "plasma": + self.setError(_("In the file %s (format - 'plasma'), \ + get all variables in the format 'samba'")\ + %self.iniFile) + return False + # формат samba + classObj = cl_profile.samba + # создаем объект типа samba и записываем в него содержимое ini-файла + objIni = classObj(textIni) + # получаем ноду body + xmlBody = objIni.docObj.getNodeBody() + flagFound, xmlBody = self.getLastNode(objIni, xmlBody, strHeader, + formatPlasma) + if flagFound and xmlBody: + if formatPlasma: + strHeader = strHeader[-1] + # если находим область то выдаем словарем все переменные иначе False + res = objIni.docObj.getAreaFields(strHeader, xmlBody) + else: + res = False + if res is False: + return {} + else: + return res + + def getAllSectionNames(self): + """Получаем все имена секций определенных в ini файле + + Если формат ini файла plasma то имя секции - + имена нескольких секций через запятую + """ + textIni = self.openIniFile() + nameFomat = self.checkIniFile(textIni) + if not nameFomat: + return False + if nameFomat == "samba": + # создаем объект типа samba и записываем в него содержимое ini-файла + objIni = cl_profile.samba(textIni) + elif nameFomat == "plasma": + # создаем объект типа plasma и записываем в него содержимое + # ini-файла + objIni = cl_profile.plasma(textIni) + else: + return [] + xmlNodes = objIni.docObj.getAllAreas() + # Имена секций ini файла + namesSection = [] + if nameFomat == "plasma": + for xmlNode in xmlNodes: + nSect = objIni.docObj.getNameArea(xmlNode) + if nSect: + namesSect = [nSect] + parentNode = xmlNode.parentNode + while parentNode != objIni.docObj.body: + nameSect = objIni.docObj.getNameArea(parentNode) + if nameSect: + namesSect.append(nameSect) + parentNode = parentNode.parentNode + else: + return [] + namesSection.append(",".join(reversed(namesSect))) + elif nameFomat == "samba": + # получаем ноду body + for xmlNode in xmlNodes: + nSect = objIni.docObj.getNameArea(xmlNode) + if nSect: + namesSection.append(nSect) + return namesSection + +############################################################################## + +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(): + 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: + eval("import %s" % (modVar)) + except ImportError as e: + err1 = _("Error in import module %s")%modVar + err2 = _("error") + ": " +str(e) + raise self.DataVarsError("%s\n%s"%(err1,err2)) + flagFindFillModule = True + try: + eval("import %s" % (modFill)) + except ImportError as 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: + # Создаем объект с методами заполнения переменных + fillObj = eval("%s.fillVars()" % modFill) + # Подключаем методы получения и записи переменных + fillObj.Get = self.Get + fillObj.Set = self.Set + else: + fillObj = False + # Заполняем self._importList + eval("self._importList.insert(0,(section,%s,fillObj))"%(modVar)) + + def __findVarData(self, nameVar): + """Находит данные для создания объекта переменная в модулях и + + объектах + """ + # Ищем переменную в модуле + dataVar = False + e = False + for section, moduleVar, fillobj in self._importList: + try: + eval("dataVar=moduleVar.Data.%s"%nameVar) + except AttributeError as 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 hasattr(self, 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 hasattr(self, 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 hasattr(self, 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 name not in frames: + 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 hasattr(self, vname): + if getattr(self, vname).service == 'Global': + return 'calculate' + else: + return getattr(self, 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[3] + elif location == 'custom': + 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 as e: + print(e) + 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') + header раздел ini файла ('client', 'server', 'calculate') + + Возвращаемые значение: + True удалено успешно + False удаление не удалсь + ''' + # получаем все пути до ini файлов + calculate_ini = self.__getPathCalculateIni() + # получаем полный путь до файла ini + if location == 'default': + name_calculate_ini = calculate_ini[3] + elif location == 'custom': + 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) + if not header: + self.Get(vname) + header = self.__getSection(vname) + # Удаляем переменную + retDelVar = config.delVar(header, vname) + retDelArea = True + if not config.getAreaVars(header): + retDelArea = config.delArea(header) + if retDelArea and retDelVar: + return True + else: + return False + + def Write(self, vname, val, force=False, location='default',header=False): + '''Установить и записать значение переменной в ini файл + + Параметры: + vname имя переменной + val значение переменной + force "принудительный режим" + location расположение ini файла ('default', 'local', 'remote') + header раздел ini файла ('client', 'server', 'calculate') + ''' + if self.__Set(vname, val, force)!= False: + if not val.strip(): + self.__deleteVarValue(vname, location, header) + self.__writeVarValue(vname, val, location, header) + return True + return False + + def Delete(self, vname, location='default', header=False): + '''Удалить переменную в calculate.ini + + Параметры: + vname имя переменной + location расположение ini файла ('default', 'local', 'remote') + + Возвращаемые значение: + True удалено успешна + False удаление не удалсь + ''' + return self.__deleteVarValue(vname, location, header) + + def __getActiveSections(self): + """активные секции в ini файле""" + act_section = [] + for service,t,t in self._importList: + if service == "Global": + act_section.append('calculate') + else: + act_section.append(service.lower()) + return act_section + + def flIniFile(self): + '''Заместить значение переменных значениями из ини файлов + + Возвращаемые значения: + cловарь импортированных переменных - переменные считаны + False - файл не был обнаружен + ''' + #Cловарь переменных из ini файлов + importVars = {} + calculate_ini = self.__getPathCalculateIni() + # активные секции (секции из которых будут использованы переменные) + act_section = self.__getActiveSections() + set_act_section = set(act_section) + i = 0 + locations = ['remote','local','custom','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 < 4: + 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): + return True + + + + def exists(self, nameVar): + """ Определяет существует ли переменная с таким имененм + """ + if hasattr(self, nameVar): + return True + foundVar = False + # Ищем переменную в импортируемых модулях + for section, moduleVar, fillobj in self._importList: + if nameVar in moduleVar.Data.__dict__: + 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 ("official" in getattr(dataVar,nameVar) 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: + """Глобальные аттрибуты для методов заполнения переменных""" + + 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 diff --git a/pym/cl_fill.py b/pym/cl_fill.py new file mode 100644 index 0000000..45f5b11 --- /dev/null +++ b/pym/cl_fill.py @@ -0,0 +1,311 @@ +# #-*- coding: utf-8 -*- + +# # Copyright 2008-2010 Mir Calculate. 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 re +# import os +# import types +# import cl_utils +# import cl_base + +# class fillVars_(cl_base.glob_attr): + +# def get_os_net_domain(self): +# ''' Определим домен''' +# domain=self._runos("hostname -d 2>&1") +# if not domain: +# print _("Error:") + " " +_("Not found domain name") +# print _("Command 'hostname -d' returns an empty value") +# cl_base.exit(1) +# elif re.search("^hostname: ",domain): +# return "local" +# else: +# return domain + +# def get_os_linux_shortname(self): +# '''Получить переменную короткого названия системы''' +# path = '/etc/calculate/calculate.ini' +# 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]=="calculate" and\ +# x.split("=")[1].strip(), data)) +# if shortNameList: +# return shortNameList[0] +# gentooFile = "/etc/gentoo-release" +# shortName = "Linux" +# if os.path.exists(gentooFile): +# shortName = "Gentoo" +# return shortName + +# def get_os_linux_name(self): +# """полное название системы""" +# linuxShortName = self.Get("os_linux_shortname") +# if linuxShortName: +# dictLinuxName = {"CLD":"Calculate Linux Desktop", +# "CLDX":"Calculate Linux Desktop", +# "CLDG":"Calculate Linux Desktop", +# "CDS":"Calculate Directory Server", +# "Gentoo":"Gentoo"} +# if linuxShortName in dictLinuxName.keys(): +# return dictLinuxName[linuxShortName] +# else: +# return "Linux" +# else: +# return "Linux" + +# def get_os_linux_subname(self): +# """постфикс к названию системы""" +# linuxShortName = self.Get("os_linux_shortname") +# if linuxShortName: +# dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE", "CLDG":"GNOME"} +# if linuxShortName in dictLinuxSubName.keys(): +# return dictLinuxSubName[linuxShortName] +# else: +# return "" +# else: +# return "" + +# def get_os_linux_ver(self): +# '''Получить версию системы''' +# path = '/etc/calculate/calculate.ini' +# 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]=="linuxver" and\ +# x.split("=")[1].strip(), data)) +# if shortNameList: +# return shortNameList[0] +# gentooFile = "/etc/gentoo-release" +# systemVersion = "" +# flagGentoo = False +# if os.path.exists(gentooFile): +# gentooLink = "/etc/make.profile" +# if os.path.islink(gentooLink): +# systemVersion = os.readlink(gentooLink).rpartition("/")[2] +# flagGentoo = True +# if not flagGentoo: +# kernelVersion=self._runos("uname -r") +# if kernelVersion: +# systemVersion = kernelVersion.partition("-")[0] +# return systemVersion + +# def get_os_net_hostname(self): +# '''Считать имя компьютера net_host''' +# hostname=self._runos("hostname -s 2>&1") +# if not hostname: +# return "" +# if re.search("^hostname: ",hostname): +# hostname=self._runos("hostname 2>&1") +# if not hostname: +# return "" +# if re.search("^hostname: ",hostname): +# return self.Get('os_linux_shortname') +# else: +# if hostname=='livecd': +# return self.Get('os_linux_shortname') +# return hostname + +# # все ip +# def get_os_net_ip(self): +# """все ip компьютера, разделитель запятая""" +# return ",".join(map(cl_utils.getIp, +# cl_utils.getInterfaces())) + +# # Разрешенные сети (в данном случае все сети) +# def get_os_net_allow(self): +# """Разрешенные сети разделитель запятая""" +# networks=[] +# netInterfaces=cl_utils.getInterfaces() +# for i in netInterfaces: +# ipaddr, mask = cl_utils.getIp(i), \ +# cl_utils.cidrToMask(cl_utils.getMask(i)) +# if ipaddr and mask: +# networks.append(cl_utils.getIpNet(ipaddr, mask)) +# else: +# networks.append("") +# return ",".join(filter(lambda x:x,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): +# """названия используемых раскладок клавиатуры для X""" +# localeXkb = self.Get("os_locale_xkb") +# if localeXkb: +# return localeXkb.split("(")[0] +# return "" + +# def get_os_arch_machine(self): +# """архитектура процессора""" +# march = self._runos("uname -m") +# if not march: +# return "" +# return march + +# def get_os_root_dev(self): +# """корневой раздел файловой системы""" +# for record in open('/proc/cmdline','rb').readlines(): +# re_res=re.search('^root=(\/dev\/[a-z]+[0-9]).*',record.strip()) +# if re_res: +# return re_res.group(1) +# else: +# mountLunes = self._runos("mount") +# if not mountLunes: +# return "" +# if type(mountLunes) == types.ListType: +# root_dev = mountLunes[0].split("on / type")[0].strip() +# if root_dev: +# return root_dev +# return "" + +# def get_os_root_type(self): +# """тип носителя (ram, hdd, livecd)""" +# mountLunes = self._runos("mount") +# if not mountLunes: +# return "" +# rootType = "hdd" +# if type(mountLunes) == types.ListType: +# flagCD = False +# for line in mountLunes: +# if "/dev/loop0 on / type" in line: +# rootType = "ram" +# break +# elif "/dev/loop0 on /newroot/mnt/livecd type" in line: +# rootType = "ram" +# flagCD = True +# break +# if rootType == "ram": +# if os.path.exists("/mnt/livecd") or flagCD: +# rootType = "livecd" +# return rootType +# rootDev = self.Get("os_root_dev") +# if rootType != "ram" and rootDev: +# slpRootDev = rootDev.split("/dev/") +# if len(slpRootDev) == 2: +# rDev = slpRootDev[1] +# devLines = self._runos("ls -la /dev/disk/by-id/", None, +# {"LANG":"C"}) +# if not devLines: +# return "" +# if type(devLines) == types.ListType: +# for line in devLines: +# if rDev in line and "usb-" in line: +# rootType = "usb-hdd" +# break +# if rootType == "ram": +# rootType = "hdd" +# return rootType +# else: +# return "" + +# def get_hr_virtual(self): +# """Название виртуальной машины (virtualbox, vmware, qemu)""" +# pciLines = self._runos("/usr/sbin/lspci") +# if not pciLines: +# return False +# virtSysDict = {'VirtualBox':'virtualbox', +# 'VMware':'vmware', +# 'Qumranet':'qemu'} +# virtName = '' +# for vName in virtSysDict.keys(): +# if filter(lambda x: vName in x, pciLines): +# virtName = virtSysDict[vName] +# break +# return virtName diff --git a/pym/cl_fill_server.py b/pym/cl_fill_server.py index 5d897f6..7a46f47 100644 --- a/pym/cl_fill_server.py +++ b/pym/cl_fill_server.py @@ -13,13 +13,17 @@ # 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. -from __future__ import print_function + import os -import cl_base -import cl_utils +from . import cl_base +from . import cl_utils import hashlib +import re +import types + +# _ = lambda x: x -class fillVars(object, cl_base.glob_attr): +class fillVars(cl_base.glob_attr): def getHash(self, password, encrypt): """Получить хеш пароля @@ -602,3 +606,284 @@ class fillVars(object, cl_base.glob_attr): if netAllow: return getNetAllow(netAllow) return "listen-on { 127.0.0.1; };" + + def get_os_net_domain(self): + ''' Определим домен''' + domain=self._runos("hostname -d 2>&1") + if not domain: + print(_("Error:") + " " +_("Not found domain name")) + print(_("Command 'hostname -d' returns an empty value")) + cl_base.exit(1) + elif re.search("^hostname: ",domain): + return "local" + else: + return domain + + def get_os_linux_shortname(self): + '''Получить переменную короткого названия системы''' + path = '/etc/calculate/calculate.ini' + if os.path.exists(path): + FD = open(path) + data = FD.readlines() + FD.close() + shortNameList = [x for x in (len(y.split("=")) == 2 and\ + y.split("=")[0]=="calculate" and\ + y.split("=")[1].strip() for y in data) if x] + if shortNameList: + return shortNameList[0] + gentooFile = "/etc/gentoo-release" + shortName = "Linux" + if os.path.exists(gentooFile): + shortName = "Gentoo" + return shortName + + def get_os_linux_name(self): + """полное название системы""" + linuxShortName = self.Get("os_linux_shortname") + if linuxShortName: + dictLinuxName = {"CLD":"Calculate Linux Desktop", + "CLDX":"Calculate Linux Desktop", + "CLDG":"Calculate Linux Desktop", + "CDS":"Calculate Directory Server", + "Gentoo":"Gentoo"} + if linuxShortName in dictLinuxName.keys(): + return dictLinuxName[linuxShortName] + else: + return "Linux" + else: + return "Linux" + + def get_os_linux_subname(self): + """постфикс к названию системы""" + linuxShortName = self.Get("os_linux_shortname") + if linuxShortName: + dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE", "CLDG":"GNOME"} + if linuxShortName in dictLinuxSubName.keys(): + return dictLinuxSubName[linuxShortName] + else: + return "" + else: + return "" + + def get_os_linux_ver(self): + '''Получить версию системы''' + path = '/etc/calculate/calculate.ini' + if os.path.exists(path): + FD = open(path) + data = FD.readlines() + FD.close() + shortNameList = [x for x in ( len(y.split("="))==2 and\ + y.split("=")[0]=="linuxver" and\ + y.split("=")[1].strip() for y in data) if x] + if shortNameList: + return shortNameList[0] + gentooFile = "/etc/gentoo-release" + systemVersion = "" + flagGentoo = False + if os.path.exists(gentooFile): + gentooLink = "/etc/make.profile" + if os.path.islink(gentooLink): + systemVersion = os.readlink(gentooLink).rpartition("/")[2] + flagGentoo = True + if not flagGentoo: + kernelVersion=self._runos("uname -r") + if kernelVersion: + systemVersion = kernelVersion.partition("-")[0] + return systemVersion + + def get_os_net_hostname(self): + '''Считать имя компьютера net_host''' + hostname=self._runos("hostname -s 2>&1") + if not hostname: + return "" + if re.search("^hostname: ",hostname): + hostname=self._runos("hostname 2>&1") + if not hostname: + return "" + if re.search("^hostname: ",hostname): + return self.Get('os_linux_shortname') + else: + if hostname=='livecd': + return self.Get('os_linux_shortname') + return hostname + + # все ip + def get_os_net_ip(self): + """все ip компьютера, разделитель запятая""" + return ",".join(cl_utils.getIp(x) for x in cl_utils.getInterfaces()) + + # Разрешенные сети (в данном случае все сети) + def get_os_net_allow(self): + """Разрешенные сети разделитель запятая""" + networks=[] + netInterfaces=cl_utils.getInterfaces() + for i in netInterfaces: + ipaddr, mask = cl_utils.getIp(i), \ + cl_utils.cidrToMask(cl_utils.getMask(i)) + if ipaddr and mask: + networks.append(cl_utils.getIpNet(ipaddr, mask)) + else: + networks.append("") + return ",".join(x for x in networks if x) + + def get_os_locale_locale(self): + """локаль (прим: ru_RU.UTF-8)""" + if "LANG" in os.environ: + 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 = [x for x in (len(y.split("="))==2 and\ + y.split("=")[0]=="KEYMAP" and\ + y.split("=")[1].replace('"',"").strip() + for y in data) if x] + 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 lang in xkbDict: + return xkbDict[lang] + return "" + + def get_os_locale_xkbname(self): + """названия используемых раскладок клавиатуры для X""" + localeXkb = self.Get("os_locale_xkb") + if localeXkb: + return localeXkb.split("(")[0] + return "" + + def get_os_arch_machine(self): + """архитектура процессора""" + march = self._runos("uname -m") + if not march: + return "" + return march + + def get_os_root_dev(self): + """корневой раздел файловой системы""" + for record in open('/proc/cmdline','rb').readlines(): + re_res=re.search('^root=(\/dev\/[a-z]+[0-9]).*',record.strip()) + if re_res: + return re_res.group(1) + else: + mountLunes = self._runos("mount") + if not mountLunes: + return "" + if type(mountLunes) == list: + root_dev = mountLunes[0].split("on / type")[0].strip() + if root_dev: + return root_dev + return "" + + def get_os_root_type(self): + """тип носителя (ram, hdd, livecd)""" + mountLunes = self._runos("mount") + if not mountLunes: + return "" + rootType = "hdd" + if type(mountLunes) == list: + flagCD = False + for line in mountLunes: + if "/dev/loop0 on / type" in line: + rootType = "ram" + break + elif "/dev/loop0 on /newroot/mnt/livecd type" in line: + rootType = "ram" + flagCD = True + break + if rootType == "ram": + if os.path.exists("/mnt/livecd") or flagCD: + rootType = "livecd" + return rootType + rootDev = self.Get("os_root_dev") + if rootType != "ram" and rootDev: + slpRootDev = rootDev.split("/dev/") + if len(slpRootDev) == 2: + rDev = slpRootDev[1] + devLines = self._runos("ls -la /dev/disk/by-id/", None, + {"LANG":"C"}) + if not devLines: + return "" + if type(devLines) == list: + for line in devLines: + if rDev in line and "usb-" in line: + rootType = "usb-hdd" + break + if rootType == "ram": + rootType = "hdd" + return rootType + else: + return "" + + def get_hr_virtual(self): + """Название виртуальной машины (virtualbox, vmware, qemu)""" + pciLines = self._runos("/usr/sbin/lspci") + if not pciLines: + return False + virtSysDict = {'VirtualBox':'virtualbox', + 'VMware':'vmware', + 'Qumranet':'qemu'} + virtName = '' + for vName in virtSysDict.keys(): + if [x for x in pciLines if vName in x]: + virtName = virtSysDict[vName] + break + return virtName diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index a378261..947e7ea 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -14,17 +14,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import print_function import os import sys import re import ldap import cStringIO, StringIO from ldif import LDIFParser, LDIFWriter -import cl_base -import cl_profile -import cl_utils2 -import cl_utils +from . import cl_base +from . import cl_profile +from . import cl_utils2 +from . import cl_utils # Для подсчета символов import termios, fcntl, struct # Ввод pwd @@ -47,6 +46,9 @@ from xml import xpath import ctypes from functools import reduce +#TODO delete this +_ = lambda x: x + Version = "calculate-server 2.1.20" tr = cl_base.lang() @@ -56,7 +58,7 @@ pcs = cl_utils.prettyColumnStr def cmp(a, b): return (a > b) - (b < a) - + class report: """Класс для выдачи данных в табличном виде""" def __init__(self, title, headerList, dataList): @@ -1331,9 +1333,9 @@ in a sambaDomainName', strInput = "" if promptText: # Получаем текст введенный пользователем - strInput = raw_input(promptText) + strInput = input(promptText) else: - strInput = raw_input() + strInput = input() if inputText: # Сбрасываем строку ввода readline.set_pre_input_hook(None) @@ -2063,8 +2065,7 @@ class servUnix(shareLdap): # Алгоритм шифрования пароля для LDAP пользователя userCrypt = "ssha" # Используемые ldif файлы - ldifFileMachine =\ - "/usr/lib/calculate/calculate-server/ldif/samba_machine.ldif" + ldifFileMachine = "/usr/lib/calculate/calculate-server/ldif/samba_machine.ldif" ldifFileUser = "/usr/lib/calculate/calculate-server/ldif/unix_user.ldif" ldifFileGroup = "/usr/lib/calculate/calculate-server/ldif/unix_group.ldif" ldifFileBase = "/usr/lib/calculate/calculate-server/ldif/unix_base.ldif" @@ -3798,7 +3799,7 @@ for user %s in 'Replication/Mail' branch") %str(userName)) if not servReplObj.delReplMailAlias(groupName): self.printERROR (_("ERROR") + ": " +\ _("Cannot delete email alias \ -for group %s in 'Replication/Mail' branch") %str(userName)) +for group %s in 'Replication/Mail' branch") % str(groupName)) return False self.printSUCCESS( _("Mail group %s is deleted")%groupName) return True @@ -4294,7 +4295,7 @@ mail user or group: %s")%foundReplUser) altMails, fHostNames): self.printERROR(_("Failed set mail aliases \ -for user %s in 'Replication/Mail' branch") %str(primaryMail)) +for user %s in 'Replication/Mail' branch") %str(mail)) return False self.printSUCCESS(_("Added group '%s' in Mail service")\ %groupName) @@ -8908,7 +8909,9 @@ for running replication")%bFile) os.remove(rmFile) #удаляем ссылки for linkRemove in scanObjs[0].links: - rmLink = flinkRemove.split(backupDir)[1] + # is this a typo? + # rmLink = flinkRemove.split(backupDir)[1] + rmLink = linkRemove.split(backupDir)[1] if os.path.exists(rmLink): os.unlink(rmLink) return True @@ -13001,7 +13004,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) if os.path.exists(archPathProcess): os.rename(archPathProcess, archPathSuccess) if ret: - self.printERROR(_("Can not create %s")%archPath) + self.printERROR(_("Can not create %s") % archPathTmp) return False else: return True @@ -13939,7 +13942,7 @@ use the new version. (openldap > 2.4)")%openLdapVesion) 'cl-rebuild --repl'")) bFile = self.servLdapObj.getArchFile() if not bFile: - return Falses + return False archFileTime = time.localtime(os.stat(bFile)[stat.ST_MTIME]) timeFile = datetime.datetime(archFileTime[0],archFileTime[1], archFileTime[2],archFileTime[3], @@ -14853,7 +14856,7 @@ with another option.")) return False relAttr = branchData[branch] try: - exec ("servObj=serv%s()" %service.capitalize()) + servObj = eval("serv%s()" %service.capitalize()) except: self.printERROR(\ _("ERROR: getQueryLDAP incorrect service=%s")%service) @@ -15492,9 +15495,9 @@ with another option.")) """Конвертирует количество дней или секунд с 1970, в строку даты""" if dataDays: if len(str(dataDays)) <= 6: - value = long(dataDays) * 86400 + value = int(dataDays) * 86400 elif len(str(dataDays)) > 6: - value = long(dataDays) + value = int(dataDays) return reduce(lambda x,y: y + "." + x, [(len(str(x)) == 1 and "0" + str(x)) or str(x) for x in time.localtime(value)[:3]]) @@ -15503,7 +15506,7 @@ with another option.")) def _getUserGroupName(self, userGid, service): """Находит имя группы по ее номеру""" try: - exec ("servObj=serv%s()" %service.capitalize()) + servObj = eval("serv%s()" % service.capitalize()) except: self.printERROR(\ _("ERROR: _getUserGroupName incorrect service=%s")%service) @@ -15537,7 +15540,7 @@ with another option.")) def _getUserMemberGroups(self, userName, service): """Находит имена групп в которые входит пользователь""" try: - exec ("servObj=serv%s()" %service.capitalize()) + servObj = eval("serv%s()" % service.capitalize()) except: self.printERROR(\ _("ERROR: _getUserGroupsNames incorrect service=%s")%service) @@ -17214,8 +17217,7 @@ class servDns(shareLdap): ["zoneName"]) resSearchRev = self.searchLdapDN('*', self.relReverseDN, "zoneName", ["zoneName"]) - return map (lambda x: x[0][1]['zoneName'][0],\ - resSearchFwd + resSearchRev) + return [x[0][1]['zoneName'][0] for x in resSearchFwd + resSearchRev] def searchAllRecordInZone(self, zoneName): @@ -18077,7 +18079,7 @@ this DNS server')%nameServer) notCmdKey = list(set(optKeys) - set(minKeys)) if notCmdKey: # Добавляем кавычки и -- - addQ = lambda y: [len(x) > 1 and '"--%s"' % x or '"-%s"' % x, y] + addQ = lambda y: [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in y] self.printERROR(_("Incorrect command line options %s")\ %", ".join(addQ(notCmdKey))) return False @@ -18352,7 +18354,7 @@ with option "--mxmod"') %zoneName) return False # Находим нужную запись - foundMxServer = [len(x.split(" ")) == 1 and delDot(x) or delDot(x.split(" ")[1]) + foundMxServers = [len(x.split(" ")) == 1 and delDot(x) or delDot(x.split(" ")[1]) for x in zoneData[0][0][1]['mXRecord']] oldMxHost = modMxServers[0] newMxHost = modMxServers[1] @@ -20220,7 +20222,8 @@ eth0, eth1, ... etc."%net) flagOK = True for hexNumber in macNumbers: try: - exec("0x%s"%hexNumber) + # exec("0x%s"%hexNumber) + tmp = int(hexNumber, 16) except: flagOK = False break @@ -21779,7 +21782,7 @@ network %s") % net) def createLogFile(self): """Создание файла лога или если нужно изменение владельца файла лога""" - import cl_log + from . import cl_log # Полное имя файла лога (путь плюс имя файла) logFullFile = os.path.join(cl_log.log.logDir, self.errorLogFile) if not os.path.exists(cl_log.log.logDir): diff --git a/pym/cl_log.py b/pym/cl_log.py new file mode 100644 index 0000000..6256b3c --- /dev/null +++ b/pym/cl_log.py @@ -0,0 +1,59 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Mir Calculate. 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 time + +class log(): + """Класс для записи в лог""" + # Директория хранения логов + logDir = "/var/log/calculate" + def __init__(self,fileName, addDataTime=True): + self.logFile = os.path.join(self.logDir,fileName) + if not os.path.exists(self.logDir): + os.makedirs(self.logDir) + self.addDataTime = addDataTime + + def addLog(self, textLog): + """Добавляет текст в лог файл""" + if not os.path.exists(self.logFile): + try: + fd = os.open(self.logFile, os.O_CREAT,0o600) + os.close(fd) + except: + print("Error creating file %s"%self.logFile) + return False + textWrite = textLog + if not textLog[-1:] == "\n" : + textWrite = "%s\n"%textLog + if self.addDataTime: + textWrite = "%s %s"%(time.strftime("%d/%m/%Y %H:%M:%S",\ + time.localtime()),textWrite) + try: + FD = open (self.logFile, "a") + FD.write(textWrite) + FD.close() + except: + print("Error writing to file %s"%self.logFile) + return False + return True + + def writeError(self, textLog): + """Добавляет сообщение об ошибке в log""" + return self.addLog("ERROR: %s" %textLog) + + def writeSuccess(self, textLog): + """Добавляет сообщение об успехе в log""" + return self.addLog("SUCCESS: %s" %textLog) diff --git a/pym/cl_profile.py b/pym/cl_profile.py new file mode 100644 index 0000000..32c47cc --- /dev/null +++ b/pym/cl_profile.py @@ -0,0 +1,7240 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Mir Calculate. 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 +from . import cl_base +import stat +import re +import xml.dom.minidom +import xml +if hasattr(xml,"use_pyxml"): + xml.use_pyxml() +from xml import xpath +import subprocess +import types +import copy +import random +import string +import time + +tr = cl_base.lang() +tr.setLocalDomain('cl_lib') +tr.setLanguage(sys.modules[__name__]) + +def cmp(a, b): + return (a > b) - (b < a) + +#TODO remove this +_ = lambda x: x + +class _error: + # Здесь ошибки, если они есть + 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): + """Установка ошибки""" + self.error.append(error) + return True + + +class _terms(_error): + """Вычисление условий применяемых в профилях + + """ + # регулярное выражение для не версии + _re_not_Version = re.compile("[^0-9\.]|^$") + # регулярное выражение для функции + _reFunction = re.compile(\ + "([a-zA-Z0-9\_\-]+)\([a-zA-Z0-9_\-\+\,\*\/\.\'\"~]+\)") + # Регулярное выражение для названия переменной + _reDenyName = re.compile("[^a-zA-Z0-9\_\-]") + # Регулярное выражение для сравниваемого значения + _reDenyValue = re.compile("[^0-9a-zA-Z_\.-]") + + def _convertVers(self, verA, verB): + """Конвертирование номеров версий для корректного сравнения + """ + elemA = verA.split(".") + elemB = verB.split(".") + if len(elemA) > len(elemB): + maxElemB = len(elemB)-1 + for i in range(len(elemA)): + if i > maxElemB: + elemB.append("0") + else: + maxElemA = len(elemA)-1 + for i in range(len(elemB)): + if i > maxElemA: + elemA.append("0") + for i in range(len(elemB)): + lenA = len(elemA[i]) + lenB = len(elemB[i]) + if lenA == lenB: + pass + elif lenA > lenB: + res = lenA - lenB + for z in range(res): + elemB[i] = "0" + elemB[i] + elif lenB > lenA: + res = lenB - lenA + for z in range(res): + elemA[i] = "0" + elemA[i] + return (".".join(elemA), ".".join(elemB)) + + def _equalTerm(self, term, textError, function=False): + """Вычисление логических выражений для условий + + Для корректной работы в классе который наследует этот класс + должен быть объявлен аттрибут self.objVar + (объект для работы с переменными) + function - функция для для обработки функций в заголовке блока + """ + trm = {"&":" and ","||":" or "} + rule = ["==", "!=", ">=", "<=", ">", "<"] + listEqual = [] + for k in trm.keys(): + if k in term: + term = term.replace(k,trm[k]) + trs = term.split(" ") + for t in trs: + flagRule = False + for sepF in rule: + if sepF in t: + flagRule = True + vals = t.split(sepF) + break + + if not flagRule: + flagLog = False + for k in trm.values(): + if k.strip() == t: + flagLog = True + break + if not flagLog: + self.setError("'%s'"%term + " " + _("incorrect")) + self.setError (textError) + return False + else: + listEqual.append(k) + else: + #проверка на допустимость названия переменной + flagFunction = False + if self._reDenyName.search(vals[0]): + #проверка на допустимость функции + flagError = True + if function: + searchFunct = self._reFunction.search(vals[0]) + if searchFunct: + flagError = False + flagFunction = True + if flagError: + self.setError("'%s'"%term + " " + _("incorrect")) + self.setError(textError) + return False + #проверка на допустимость значения + if self._reDenyValue.search(vals[1]): + self.setError("'%s'"%term + " " + _("incorrect")) + self.setError(textError) + return False + flagIntTypeVar = None + if flagFunction: + valVars = function("#-%s-#"%vals[0]) + if valVars is False: + self.setError("'%s'"%term + " " + _("incorrect")) + self.setError(textError) + return False + if "load" == searchFunct.group(1): + if re.search("\(\s*num\s*,",vals[0]): + if valVars: + try: + valVars = int(valVars) + except: + self.setError("'%s'"%term + " " + \ + _("incorrect")) + self.setError (textError) + return False + flagIntTypeVar = True + else: + flagIntTypeVar = False + else: + if valVars == "" and\ + not self._re_not_Version.search(vals[1]): + valVars = "0" + elif vals[1] == "" and\ + not self._re_not_Version.search(valVars): + vals[1] = "0" + else: + try: + valVars = self.objVar.Get(vals[0]) + except self.objVar.DataVarsError as e: + print(textError) + print(e) + cl_base.exit(1) + # Номера версий для ini + flagNotIniFunct = True + # Два значения не пусты + flagNotEmptyVals = not (valVars == "" and vals[1] == "") + if flagFunction and flagNotEmptyVals and\ + searchFunct.group(1) == "ini": + # Проверка значения на версию + if not self._re_not_Version.search(valVars) and\ + not self._re_not_Version.search(vals[1]): + verFile, verVar = self._convertVers(vals[1],valVars) + res = eval("("+"'"+verVar+"'"+sepF+"'"+verFile+"'"+")") + if res: + listEqual.append("1") + else: + listEqual.append("0") + flagNotIniFunct = False + # Cравниваем номера версий + if flagNotIniFunct: + if flagNotEmptyVals and\ + ("_ver" in vals[0] or\ + (flagFunction and searchFunct.group(1) == "pkg") or\ + (flagFunction and searchFunct.group(1) == "load" and\ + re.search("\(\s*ver\s*,",vals[0]))): + # Проверка значения на версию + if self._re_not_Version.search(vals[1]): + self.setError("'%s'"%term + " " + _("incorrect")) + self.setError (_("Value is not version")) + return False + # Проверка значения функции на версию + if self._re_not_Version.search(valVars): + self.setError("'%s'"%term + " " + _("incorrect")) + self.setError (_("Value function is not version")) + return False + verFile, verVar = self._convertVers(vals[1],valVars) + res = eval("("+"'"+verVar+"'"+sepF+"'"+verFile+"'"+")") + if res: + listEqual.append("1") + else: + listEqual.append("0") + flagNotIniFunct = False + else: + if flagIntTypeVar == None: + flagIntTypeVar = True + try: + valVars = int(valVars) + except: + flagIntTypeVar = False + if flagIntTypeVar: + if not vals[1].strip(): + vals[1] = 0 + try: + valFile = int(vals[1]) + except: + self.setError("'%s'" % term +" " +_("incorrect")) + self.setError (textError) + return False + valVar = valVars + res = eval("(%d%s%d)" % (valVar,sepF,valFile)) + if res: + listEqual.append("1") + else: + listEqual.append("0") + else: + if sepF == "!=" or sepF == "==": + if not vals[1].strip(): + vals[1] = "" + valFile = vals[1] + valVar = valVars + res = eval("("+'"""'+valVar+'"""'+sepF+"'"+valFile+"'"+")") + if res: + listEqual.append("1") + else: + listEqual.append("0") + else: + if not flagNotEmptyVals: + listEqual.append("0") + else: + self.setError("'%s'"%term + " "\ + + _("incorrect")) + self.setError (textError) + return False + res = eval("(%s)"%("".join(listEqual))) + return res + +class fileHeader(_terms): + """Обработка заголовков профилей и конфигурационных файлов + + """ + # Допустимые параметры заголовка + allowParam = ["format", "format_conf", "comment", "append", "force", + "link", "mirror", "symbolic", "chmod", "chown", "name"] + # Корректность заголовка + headerCorrect = True + + # Тип профиля + fileType = "" + # Тип вставки профиля + typeAppend = "" + # Возможные типы вставки профилей + _fileAppend = "join", "before", "after", "replace", "remove" + # Интерпретатор (#!/bin/bash) (#!/usr/bin/python) + execStr = "" + # Символ комментария + comment = False + # Выражение для поиска строки интерпретатора + reExecStr = re.compile("^#!.+\s*",re.I) + # условные операторы + terms = ('>', '<', '==', '!=', '>=', '<=') + # параметры без значения + listParNotVal = ("symbolic", "force", "mirror") + # Результат вычисления условия в заголовке + headerTerm = True + # Сообщение о ошибке + errorMessage = "" + + def __init__(self, text, comment=False, fileType=False, objVar=False, + function=False): + self.body = text + # Объект с переменными + self.objVar=objVar + # Параметры описанные в заголовке файла профиля + self.params = {} + # некорректные параметры + incorrectParams = set([]) + # Удаление Заголовка Calculate + if comment: + # В случае текста XML + if type(comment) == tuple and len(comment) == 2: + _titleList = (_("Modified"), _("File of a profile")) + reCalcHeader =\ + re.compile(u"\s*%s\s+%s.+Calculate.+\s+%s.+\s+%s\s?"%(\ + comment[0], + _titleList[0].decode("UTF-8"), + _titleList[1].decode("UTF-8"), + comment[1], + ), + re.M|re.I|re.U) + textUnicode = text.decode("UTF-8") + reS = reCalcHeader.search(textUnicode) + if reS: + textBody = textUnicode[:reS.start()]+textUnicode[reS.end():] + if textBody: + self.body = textBody.encode("UTF-8") + else: + reCalcHeader =\ + re.compile("\s*%s\-+\s+%s.+Calculate.+\s+%s.+\s+%s\-+\s?"%(\ + comment, + comment, + comment, + comment, + ), + re.M|re.I) + reS = reCalcHeader.search(text) + if reS: + self.body = text[reS.end():] + + if fileType != False: + if fileType=="bin": + self.params["format"] = fileType + self.fileType = self._getType() + self.typeAppend = self._getAppend() + else: + textLines = text.splitlines() + if textLines: + textLine = textLines[0] + rePar = re.compile("\s*#\s*calculate\s+",re.I) + reP = rePar.search(textLine) + if reP: + reL = False + reLns = re.compile(r"\A([^\\\n]*\\\n)+[^\n]*\n*",re.M) + reLs = reLns.search(text) + if reLs: + reL = reLs + paramLine = text[reP.end():reLs.end()] + paramLine = paramLine.replace("\\"," ") + else: + reLn = re.compile("\n") + reL = reLn.search(text) + paramLine = textLine[reP.end():] + if reL: + self.body = text[reL.end():] + else: + self.body = "" + paramList = re.split("\s+",paramLine) + if paramList: + for i in paramList: + foundTerm = False + for term in self.terms: + if term in i: + foundTerm = True + if function: + rezTerm = self._equalTerm(i,\ + _("header profile not valid: ") + \ + i,function) + else: + rezTerm = self._equalTerm(i,\ + _("header profile not valid: ") + \ + i) + if not rezTerm: + self.headerTerm = False + break + if not foundTerm: + par = i.split("=") + if len(par) == 1: + if i in self.listParNotVal: + self.params[i] = "True" + else: + if i.strip(): + incorrectParams = set([i]) + elif len(par) == 2: + self.params[par[0]] = par[1] + + self.comment = self._getComment() + self.fileType = self._getType() + self.typeAppend = self._getAppend() + reExecRes = self.reExecStr.search(self.body) + if reExecRes: + self.execStr = self.body[reExecRes.start():reExecRes.end()] + self.body = self.body[reExecRes.end():] + if not incorrectParams: + incorrectParams = set(self.params.keys()) - set(self.allowParam) + if incorrectParams: + self.headerTerm = False + self.headerCorrect = False + self.errorMessage = _("incorrect header parameters - '%s'")\ + % " ".join(list(incorrectParams)) + + def _getType(self): + """Выдать тип файла""" + if "format" in self.params: + return self.params["format"] + else: + return "raw" + + def _getAppend(self): + """Выдать тип добавления файла""" + if "append" in self.params and self.params["append"] in\ + self._fileAppend: + return self.params["append"] + else: + if self.fileType != "raw" and self.fileType != "bin" and\ + self.fileType != "": + self.params["append"] = "join" + return "join" + self.params["append"] = "replace" + return "replace" + + def _getComment(self): + """Выдать символ комментария файла""" + if "comment" in self.params: + return self.params["comment"] + else: + return False + + +class dirHeader(_terms): + """Обработка заголовков профилей директорий + + """ + # Допустимые параметры заголовка + allowParam = ["append", "chmod", "chown", "name"] + # Корректность заголовка + headerCorrect = True + + # Тип вставки профиля + typeAppend = "" + # Возможные типы вставки профилей + _fileAppend = "join", "remove" + # условные операторы + terms = ('>', '<', '==', '!=', '>=', '<=') + # параметры без значения + listParNotVal = ("symbolic", "force") + # Результат вычисления условия в заголовке + headerTerm = True + # Сообщение о ошибке + errorMessage = "" + + def __init__(self, text, objVar=False, function=False): + self.body = text + # Объект с переменными + self.objVar=objVar + # Параметры описанные в заголовке файла профиля + self.params = {} + # некорректные параметры + incorrectParams = set([]) + + textLines = text.splitlines() + flagErrorBody = False + if textLines: + textLine = textLines[0] + rePar = re.compile("\s*#\s*calculate\s+",re.I) + reP = rePar.search(textLine) + if reP: + reL = False + reLns = re.compile(r"\A([^\\\n]*\\\n)+[^\n]*\n*",re.M) + reLs = reLns.search(text) + if reLs: + reL = reLs + paramLine = text[reP.end():reLs.end()] + paramLine = paramLine.replace("\\"," ") + else: + reLn = re.compile("\n") + reL = reLn.search(text) + paramLine = textLine[reP.end():] + if reL: + self.body = text[reL.end():] + else: + self.body = "" + if self.body.strip(): + self.headerTerm = False + self.headerCorrect = False + self.errorMessage = _("incorrect text in profile: '%s'")\ + %self.body + flagErrorBody = True + if not flagErrorBody: + paramList = re.split("\s+",paramLine) + if paramList: + for i in paramList: + foundTerm = False + for term in self.terms: + if term in i: + foundTerm = True + if function: + rezTerm = self._equalTerm(i,\ + _("header profile not valid: ") + \ + i,function) + else: + rezTerm = self._equalTerm(i,\ + _("header profile not valid: ") + \ + i) + if not rezTerm: + self.headerTerm = False + break + if not foundTerm: + par = i.split("=") + if len(par) == 1: + if i in self.listParNotVal: + self.params[i] = "True" + else: + if i.strip(): + incorrectParams = set([i]) + elif len(par) == 2: + self.params[par[0]] = par[1] + self.typeAppend = self._getAppend() + if not flagErrorBody: + if not incorrectParams: + incorrectParams = set(self.params.keys()) - set(self.allowParam) + if incorrectParams: + self.headerTerm = False + self.headerCorrect = False + self.errorMessage = _("incorrect header parameters - '%s'")\ + % " ".join(list(incorrectParams)) + + def _getAppend(self): + """Выдать тип добавления директории""" + if "append" in self.params and self.params["append"] in\ + self._fileAppend: + return self.params["append"] + else: + return "join" + +class objShare: + """Общий клас для объектов, наследуем + + """ + + def createFieldTerm(self, name, value, quote, docObj): + """Создание поля переменная - значение + + при создании поля проверяется первый символ названия переменной + и добавляется тег action + "!" - drop удаляет + "+" - join добавляет + "-" - replace заменяет + """ + fieldAction = False + if name: + if name[0] == "!" or name[0] == "-" or name[0] == "+": + qnt = self.removeSymbolTerm(quote) + fieldXML = docObj.createField("var",[qnt], + name[1:], [value], + False, False) + if name[0] == "!": + fieldAction = "drop" + elif name[0] == "+": + fieldXML.setAttribute("type", "seplist") + fieldAction = "join" + else: + fieldXML = docObj.createField("var", + [quote.replace("\n","")], + name, [value], + False, False) + else: + fieldXML = docObj.createField("var", + [quote.replace("\n","")], + name, [value], + False, False) + if fieldAction: + docObj.setActionField(fieldXML, fieldAction) + return fieldXML + + def removeSymbolTerm(self, text): + """Удаляет первый символ названия переменной в строке + + Если первый встречающийся символ с начала строки + '+', '-', '!' то он из этой строки будет удален, + если перед этим символом были пробельные символы, + то они будут сохранены, так-же если в строке есть символ + перевода строки он будет удален. + """ + reTerm = re.compile("^[ \t]*(\!|\+|\-)") + textNS = text.replace("\n","") + res = reTerm.search(textNS) + if res: + textNS = textNS[res.start():res.end()-1] + textNS[res.end():] + return textNS + + def getConfig(self): + """Выдает конфигурационный файл""" + listConfigTxt = [] + childNodes = self.docObj.getNodeBody().childNodes + for node in childNodes: + if node.nodeType == node.ELEMENT_NODE: + if node.tagName == "field": + listConfigTxt.append(self.docObj.getQuoteField(node)) + elif node.tagName == "area": + self.docObj.xmlToText([node], listConfigTxt) + return "".join(listConfigTxt) + + + def splitToFields(self, txtBloc): + """Разбиваем текст на поля (объекты) которые имеют следующие аттрибуты + + self.name - если переменная то имя переменной + self.value - если у переменной есть значение то значение переменной + self.comment - если комментарий то текст комментария + self.br - если перевод строки то текст перед переводом из пробелов + + Результат список объектов полей + """ + finBloc = "\n" + if txtBloc[-1] != "\n": + finBloc = "" + + linesBlocTmp = txtBloc.splitlines() + linesBloc = [] + brBloc = [] + z = 0 + lenLines = len(linesBlocTmp) + for i in linesBlocTmp: + + if self.reComment.split(i)[0]: + findCooment = self.reComment.search(i) + comment = False + par = i + if findCooment: + par = i[:findCooment.start()] + comment = i[findCooment.start():] + fields = self.reSepFields.split(par) + lenFields = len(fields) + + if lenFields>1: + for fi in range(lenFields-1): + linesBloc.append(fields[fi]+ self.sepFields) + if fi == lenFields-2: + if comment: + brBloc.append("") + else: + if (lenLines-1)== z: + brBloc.append(finBloc) + else: + brBloc.append("\n") + else: + brBloc.append("") + if comment: + linesBloc.append(comment) + if (lenLines-1)== z: + brBloc.append(finBloc) + else: + brBloc.append("\n") + else: + linesBloc.append(i) + if (lenLines-1)== z: + brBloc.append(finBloc) + else: + brBloc.append("\n") + else: + linesBloc.append(i) + if (lenLines-1)== z: + brBloc.append(finBloc) + else: + brBloc.append("\n") + z +=1 + fields = self.setDataField(linesBloc, brBloc) + return fields + +class xmlShare: + """Общий класс для объектов XML, наследуем + + """ + def _createElement(self, doc, tagName, text="", attributes={}): + """Создание нового XML элемента""" + element = doc.createElement(tagName) + if text: + txtNode = doc.createTextNode(self._toUNICODE(text)) + element.appendChild(txtNode) + for attr in attributes.keys(): + attribute = doc.createAttribute(attr) + attribute.nodeValue = attributes[attr] + element.setAttributeNode(attribute) + return element + + def _toUNICODE(self,val): + """перевод текста в юникод""" + if 'unicode' in "%s" %(type(val)): + return val + else: + return val.decode('UTF-8') + + +class xmlNode(xmlShare): + """Класс для создания нод без аттрибутов + + """ + def __init__(self): + self.node = False + + + def createNode(self, doc, tagName, text=""): + """Создает XML элемент без аттрибутов""" + self.node=self._createElement(doc, tagName, text) + return self.node + + def getNode(self): + return self.node + + +class xmlCaption: + """Класс XML заголовок + + """ + def __init__(self): + #Заголовок области XML нода + self.caption = False + + + def createCaption(self, doc, name, quotes, action=False): + """Создание заголовка области""" + tmpNode = xmlNode() + self.caption = tmpNode.createNode(doc, "caption") + nameNode = tmpNode.createNode(doc, "name",name) + self.caption.appendChild(nameNode) + if action: + actNode = tmpNode.createNode(doc, "action", action) + self.caption.appendChild(actNode) + for q in quotes: + quoteNode = tmpNode.createNode(doc, "quote", q) + self.caption.appendChild(quoteNode) + return self.caption + + def getCaption(self): + """Выдает XML ноду заголовка области""" + return self.caption + +class xmlField(xmlShare): + """Класс для работы с XML полем + + """ + def __init__(self): + # XML нода поле + self.field = False + + + def createField(self, doc, typeField, quotes, name="", + values=[],action=False): + """Cоздание XML ноды поле""" + self.field = self._createElement(doc, "field", "", {"type":typeField}) + if name: + nameNode = self._createElement(doc, "name", name) + self.field.appendChild(nameNode) + for v in values: + valueNode = self._createElement(doc, "value", v) + self.field.appendChild(valueNode) + if action: + actNode = self._createElement(doc, "action", action) + self.field.appendChild(actNode) + for q in quotes: + quoteNode = self._createElement(doc, "quote", q) + self.field.appendChild(quoteNode) + return self.field + + + +class xmlFields: + """Класс, в котором находится список ХМL нод field + + """ + def __init__(self): + self.fields = [] + + def appendField(self, field): + """Добавить XML ноду field""" + self.fields.append(field) + return self.fields + + def getFields(self): + """Выдать список XML нод""" + return self.fields + + +class xmlArea: + """Класс для работы с XML областью + + """ + def __init__(self): + # Область + self.area = False + + def createArea(self, doc, xmlCaption, xmlFields): + """Создание XML области""" + tmpNode = xmlNode() + self.area = tmpNode.createNode(doc, "area") + if xmlCaption and xmlCaption.getCaption(): + self.area.appendChild(xmlCaption.getCaption()) + if xmlFields: + fields = xmlFields.getFields() + for field in fields: + self.area.appendChild(field) + return self.area + +class xmlDoc: + """Класс для работы с XML документом + + """ + def __init__(self): + # документ + self.doc = False + # главная нода + self.root = False + # тело документа + self.body = False + # Заголовок области - временный (в реальности один объект заголовок) + self.tmpCaption = False + # Поля - временные (в реальности один объект поля) + self.tmpFields = False + # Разделитель областей - по умолчанию перевод строки "\n" + self.sepAreas = False + # Разделитель разделенных списков - по умолчанию перевод строки "\n" + #self.sepSplitFields = False + + + def createDoc(self, typeDoc, version): + """Создание нового документа новый документ""" + docTxt = '' + docTxt += '%s'% version + docTxt += '%s' % typeDoc + docTxt += '' + self.doc = xml.dom.minidom.parseString(docTxt) + self.root = self.doc.documentElement + self.body = xpath.Evaluate('child::body',self.root)[0] + # установка разделителя областей + self.sepAreas = self.createField("br",[],"",[],False,False) + # установка разделителя областей разделенных списков + #self.sepSplitFields = self.createField("br",[],"",[],False,False) + return self.doc + + def addField(self, field): + """Добавляет поле во временный список + + Из этого списка в дальнейшем формируется XML область + """ + if not self.tmpFields: + self.tmpFields = xmlFields() + self.tmpFields.appendField(field) + + def createCaption(self, name, quotes, action=False): + """Cоздает заголовок области + + Помещает заголовок в временный артибут + Используется при создании области + """ + self.tmpCaption = xmlCaption() + return self.tmpCaption.createCaption(self.doc, name, quotes, action) + + def createField(self, typeField, quotes=[], name="", + values=[] ,action=False,addTmpField=True): + """Cоздает поле + + Если установлена переменнная addTmpField + добавляет поле во временный список + """ + fieldObj = xmlField() + field = fieldObj.createField(self.doc, typeField, quotes, name, + values, action) + if addTmpField: + self.addField(field) + return field + + def clearTmpFields(self): + """Очищает временный список""" + self.tmpFields = False + + def createArea(self): + """Cоздает область + + Область создается на основании временного атрибута и временного списка + """ + areaObj = xmlArea() + area = areaObj.createArea(self.doc, self.tmpCaption, self.tmpFields) + self.clearTmpCaptionAndFields() + return area + + def clearTmpCaptionAndFields(self): + """Очищает временный аттрибут и временный список""" + self.tmpCaption = False + self.tmpFields = False + + def getNodeRoot(self): + """Выдает корневую ноду""" + return self.root + + def getNodeBody(self): + """Выдает ноду body""" + return self.body + + def setActionField(self, xmlField, actionTxt): + """Устанавливает свойство action для XML поля""" + xmlActions = xpath.Evaluate('child::action',xmlField) + if xmlActions and xmlActions[0].firstChild: + xmlActions[0].firstChild.nodeValue = actionTxt + else: + nodeObj = xmlNode() + newNode = nodeObj.createNode(self.doc, "action", actionTxt) + xmlField.appendChild(newNode) + + + def setActionArea(self, xmlArea, actionTxt): + """Устанавливает свойство action для XML области""" + xmlActions = xpath.Evaluate('child::caption/action',xmlArea) + xmlCaptions = xpath.Evaluate('child::caption',xmlArea) + if xmlActions and xmlActions[0].firstChild: + xmlActions[0].firstChild.nodeValue = actionTxt + else: + if xmlCaptions: + nodeObj = xmlNode() + newNode = nodeObj.createNode(self.doc, "action", actionTxt) + xmlCaptions[0].appendChild(newNode) + + def joinField(self, xmlArea, xmlNewField): + """Объединяет XML ноду область и XML ноду поле""" + newNameField = self.getNameField(xmlNewField) + if not newNameField or not newNameField.strip(): + return False + fieldsOldComp = xpath.Evaluate("child::field[child::name='%s']"\ + %(newNameField), xmlArea) + # Если поле не найдено добавляем его + typeNewField = self.getTypeField(xmlNewField) + if not fieldsOldComp and typeNewField != "seplist": + if self.getActionField(xmlNewField) != "drop": + self.setActionField(xmlNewField, "append") + xmlArea.appendChild(xmlNewField) + return True + newFieldsAction = self.getActionField(xmlNewField) + newValues = self.getFieldValues(xmlNewField) + flagCompare = True + + for nodeFieldOld in fieldsOldComp: + if newFieldsAction == "drop": + if nodeFieldOld.nextSibling and\ + self.getTypeField(nodeFieldOld.nextSibling) == "br": + xmlArea.removeChild(nodeFieldOld.nextSibling) + elif nodeFieldOld.previousSibling and\ + self.getTypeField(nodeFieldOld.previousSibling) == "br": + xmlArea.removeChild(nodeFieldOld.previousSibling) + xmlArea.removeChild(nodeFieldOld) + continue + oldValues = self.getFieldValues(nodeFieldOld) + # Сравнение значений переменной профиля и файла + if set(newValues) != set(oldValues): + flagCompare = False + if self.getActionField(xmlNewField) == "drop": + return True + appSplLst = [] + insSplLst = [] + if typeNewField == "seplist": + if fieldsOldComp: + xmlOldField = fieldsOldComp[-1] + else: + xmlOldField = False + seplistNewXML = self.getSepListToField(xmlNewField) + if seplistNewXML: + for nodeSeplist in seplistNewXML: + if self.getActionField(nodeSeplist) != "drop": + if newFieldsAction == "join": + flagCompareSeplist = False + newValues = self.getFieldValues(nodeSeplist) + for nodeFieldOld in fieldsOldComp: + oldValues = self.getFieldValues(nodeFieldOld) + for newValue in newValues: + if newValue in oldValues: + flagCompareSeplist = True + break + if not flagCompareSeplist: + nextNode = xmlOldField.nextSibling + newInsNode = nodeSeplist.cloneNode(True) + self.setActionField(newInsNode,"append") + + if nextNode: + appSplLst.append((newInsNode, + nextNode, + "insert")) + else: + appSplLst.append((newInsNode, + False, + "append")) + else: + newInsNode = nodeSeplist.cloneNode(True) + if self.getActionField(newInsNode) == "join": + self.setActionField(newInsNode,"append") + if xmlOldField: + insSplLst.append((newInsNode, + xmlOldField, + "insert")) + else: + insSplLst.append((newInsNode, + False, + "append")) + + #xmlArea.insertBefore(\ + #nodeSeplist.cloneNode(True), + #xmlOldField) + + parentNode = nodeSeplist.parentNode + parentNode.removeChild(nodeSeplist) + + insNodesRepl = [] + for newNode, nxtNode, app in insSplLst: + flagCompareSeplist = False + newValues = self.getFieldValues(newNode) + for nodeRepl, nxtNode, app in insNodesRepl: + oldValues = self.getFieldValues(nodeRepl) + for newValue in newValues: + if newValue in oldValues: + flagCompareSeplist = True + break + if not flagCompareSeplist: + if xmlOldField: + insNodesRepl.append((newNode, nxtNode, app)) + + for newNode, nxtNode, app in insNodesRepl: + if app == "insert": + xmlArea.insertBefore(newNode,nxtNode) + elif app == "append": + xmlArea.appendChild(newNode) + if xmlOldField: + parentNode = xmlOldField.parentNode + if parentNode and newFieldsAction != "join": + parentNode.removeChild(xmlOldField) + + for newNode, nxtNode, app in appSplLst: + if app == "insert": + xmlArea.insertBefore(newNode,nxtNode) + elif app == "append": + xmlArea.appendChild(newNode) + + if not flagCompare and typeNewField != "seplist": + # Устанавливаем action=replace + self.setActionField(xmlNewField, "replace") + # Если параметры поля не сходятся заменяем поле + xmlArea.replaceChild(xmlNewField.cloneNode(True), + fieldsOldComp[-1]) + + if newFieldsAction == "join": + fieldsOldRemove = [] + else: + fieldsOldRemove = fieldsOldComp[:-1] + + for nodeFieldOld in fieldsOldRemove: + actionOldNode = self.getActionField(nodeFieldOld) + if actionOldNode == "insert" or actionOldNode == "append": + pass + else: + if nodeFieldOld.nextSibling and\ + self.getTypeField(nodeFieldOld.nextSibling) == "br": + xmlArea.removeChild(nodeFieldOld.nextSibling) + xmlArea.removeChild(nodeFieldOld) + return True + + + def getSepListToField(self, xmlField): + """Выдает элементы распределенного массива + + Область предок поля, в этой области ищутся + элементы распределенного массива + """ + nameField = self.getNameField(xmlField) + if not nameField: + return [] + parentNode = xmlField.parentNode + #print parentNode.toprettyxml() + if parentNode: + fieldsVal = xpath.Evaluate(\ + "child::field[attribute::type='seplist'][child::name='%s'] "\ + %(nameField), parentNode) + #print nameField + return fieldsVal + else: + return [] + + def removeComment(self, xmlArea): + """Удаляет комментарии в XML области""" + fieldNodes = xpath.Evaluate('descendant::field',xmlArea) + for fieldNode in fieldNodes: + if fieldNode.hasAttribute("type"): + if fieldNode.getAttribute("type") == "comment" or\ + fieldNode.getAttribute("type") == "br": + parentNode = fieldNode.parentNode + parentNode.removeChild(fieldNode) + else: + if self.getActionField(fieldNode) == "drop": + pass + elif self.getActionField(fieldNode) == "join": + pass + else: + self.setActionField(fieldNode,"append") + + + def joinBody(self, baseBody, newBody): + """Объединяет две области Body""" + newFields = xpath.Evaluate('child::field',newBody) + xmlNewAreas = xpath.Evaluate('child::area',newBody) + for xmlNewArea in xmlNewAreas: + self.joinArea(baseBody,xmlNewArea) + joinNewFields = xpath.Evaluate("child::field[child::action='join']" + ,newBody) + self.addNewFielsOldArea(newFields, joinNewFields, baseBody) + + + def getRemoveNodeSepList(self, removeNodesDict, baseNode, xmNewlField): + """Находит элементы разделенного списка + + Параметры: + removeNodesDict - Cловарь удаляемых полей разделенного списка + формируется программой + baseNode - Нода в которой идет поиск + xmNewlField - Нода field которая проверяется на принадлежность + к разделенному списку + """ + flagNewNodeSeplist = False + if self.getTypeField(xmNewlField) == "seplist": + flagNewNodeSeplist = True + nameNewField = self.getNameField(xmNewlField) + if nameNewField: + if nameNewField in removeNodesDict: + return removeNodesDict[nameNewField] + else: + oldFields = xpath.Evaluate('child::field', baseNode) + removeNodes = [] + lenOldFields = len(oldFields) + for i in range(lenOldFields): + oldNode = oldFields[i] + flagSep = self.getTypeField(oldNode) == "seplist" + if flagNewNodeSeplist: + flagSep = True + if flagSep and\ + nameNewField == self.getNameField(oldNode): + removeNodes.append(oldNode) + if i+1 1: + for node in listNodes: + node.setAttribute("type", "seplist") + + def insertBRtoBody(self, xmlArea): + """Добавляет необходимые переводы строк + """ + # Потомки + childNodes = self.getFieldsArea(xmlArea) + # нода BR + fieldXMLBr = self.createField("br",[],"",[],False, False) + # разделитель поля + fieldSplit = False + # Предыдущая нода + lastNode = False + # Cледующая нода + nextNode = False + lenChildNodes = len(childNodes) + for i in range(lenChildNodes): + node = childNodes[i] + lastTmpNode = node + # Нода area + if node.tagName == "area": + if self.getActionArea(node) == "append" or\ + self.getActionArea(node) == "join": + self.delActionNodeArea(node) + if lastNode and lastNode.hasAttribute("type") and\ + lastNode.getAttribute("type") == "br" or\ + lastNode and lastNode.hasAttribute("type") and\ + lastNode.getAttribute("type") == "comment": + indNext = i + 1 + if indNext == lenChildNodes: + xmlArea.appendChild(fieldXMLBr.cloneNode(True)) + else: + nextNode = childNodes[indNext] + lastTmpNode = xmlArea.insertBefore(\ + fieldXMLBr.cloneNode(True), + nextNode) + else: + xmlArea.insertBefore(fieldXMLBr.cloneNode(True), + node) + self.insertBRtoBody(node) + # Нода field + else: + if self.getActionField(node) == "append" or\ + self.getActionField(node) == "join": + self.delActionNodeField(node) + if lastNode and lastNode.hasAttribute("type") and\ + lastNode.getAttribute("type") == "br" or\ + lastNode and lastNode.hasAttribute("type") and\ + lastNode.getAttribute("type") == "comment": + indNext = i + 1 + if indNext == lenChildNodes: + xmlArea.appendChild(fieldXMLBr.cloneNode(True)) + else: + nextNode = childNodes[indNext] + lastTmpNode = xmlArea.insertBefore(\ + fieldXMLBr.cloneNode(True), + nextNode) + else: + xmlArea.insertBefore(fieldXMLBr.cloneNode(True), + node) + lastNode = lastTmpNode + + + + def postParserList(self): + """Находит подходящие XML области и делаем из них поля-массивы""" + xmlAreas = xpath.Evaluate('descendant::area', self.body) + for xmlArea in xmlAreas: + flagListXml = True + fieldValues = [] + xmlFields = xpath.Evaluate('child::field',xmlArea) + if not xmlFields: + flagListXml = False + lenXmlFields = len(xmlFields) + lenBrArea = 0 + for xmlField in xmlFields: + xmlNames = xpath.Evaluate('child::name',xmlField) + xmlVals = xpath.Evaluate('child::value',xmlField) + if xmlField.hasAttribute("type") and\ + xmlField.getAttribute("type") == "br": + lenBrArea += 1 + continue + if not xmlNames and not xmlVals: + flagListXml = False + break + if xmlNames and xmlNames[0].firstChild and\ + xmlNames[0].firstChild.nodeValue: + flagListXml = False + break + if not (xmlVals and xmlVals[0].firstChild and\ + xmlVals[0].firstChild.nodeValue): + flagListXml = False + break + else: + fieldValues.append(xmlVals[0].firstChild.nodeValue) + + if lenXmlFields == lenBrArea: + flagListXml = False + if flagListXml: + nameNode = xpath.Evaluate('child::caption/name',xmlArea)[0] + fieldName = "" + if nameNode.firstChild: + fieldName = nameNode.firstChild.nodeValue + listArea = [] + self.xmlToText([xmlArea],listArea) + fieldQuote = "".join(listArea) + fieldXMLBr = False + if fieldQuote and fieldQuote[-1] == "\n": + fieldQuote = fieldQuote[:-1] + fieldXMLBr = self.createField("br",[],"",[],False, False) + fieldXML = self.createField("list", + [fieldQuote], + fieldName, fieldValues, + False, False) + areaAction = self.getActionArea(xmlArea) + if areaAction: + self.setActionField(fieldXML, areaAction) + parentNode = xmlArea.parentNode + parentNode.insertBefore(fieldXML,xmlArea) + if fieldXMLBr: + parentNode.insertBefore(fieldXMLBr,xmlArea) + parentNode.removeChild(xmlArea) + + +class blocText: + """Разбиваем текст на блоки""" + + def splitTxtToBloc(self, text ,openTxtBloc,closeTxtBloc, + commentTxtBloc, sepField): + """Делит текст на блоки (без заголовков) + + openTxtBloc - регулярное выражение для начала блока + closeTxtBloc - регулярное выражение для конца блока + commentTxtBloc - регулярное выражение - комментарий + возвращает блоки текста + """ + blocs = [] + level = 0 + # Нахождение нескольких блоков в строке + # разделители линий, разделителями могут быть ("","\n") + sepsLines = [] + # линии + txtLines = [] + # Исходные строки + txtLinesSrc = text.splitlines() + for line in txtLinesSrc: + lineBR = "" + lineTmpA = line + closeBl = False + txtLinesTmp = [] + commentSpl = commentTxtBloc.split(line) + flagCommentLine = False + if commentSpl[0].strip(): + closeBl = True + if len(commentSpl) > 1: + commentBl = commentTxtBloc.search(line) + textLine =commentSpl[0] + commentLine = line[commentBl.start(0):] + lineTmpA = textLine + flagCommentLine = True + + while (closeBl): + closeBl = sepField.search(lineTmpA) + if closeBl: + lineTmpB = lineTmpA[closeBl.end(0):] + txtLinesTmp.append(lineTmpA[:closeBl.end(0)]) + lineTmpA = lineTmpB + if lineTmpA.strip(): + txtLinesTmp.append(lineTmpA) + # Если есть значение и комментарий в строке + if flagCommentLine: + for l in txtLinesTmp: + txtLines.append(l) + sepsLines.append("") + if not txtLinesTmp: + txtLines.append(textLine) + sepsLines.append("") + txtLines.append(commentLine) + sepsLines.append("\n") + # Если есть несколько блоков в строке + elif len(txtLinesTmp)>1 and txtLinesTmp[1].strip(): + lenTmpLines = len(txtLinesTmp) + for l in range(lenTmpLines): + txtLines.append(txtLinesTmp[l]) + if l == lenTmpLines-1: + sepsLines.append("\n") + else: + sepsLines.append("") + # Cтрока не преобразована + else: + txtLines.append(line) + sepsLines.append("\n") + + # разбивание на блоки + z = 0 + bl = "" + for i in txtLines: + if commentTxtBloc.split(i)[0].strip() and openTxtBloc.search(i): + level += len(openTxtBloc.split(i)) - 1 + if commentTxtBloc.split(i)[0].strip() and closeTxtBloc.search(i): + level -= len(closeTxtBloc.split(i)) - 1 + bl += i + sepsLines[z] + if level == 0: + if bl: + blocs.append(bl) + bl = "" + z += 1 + # cоздание блоков с элементами не входящими в блоки + realBlocs = [] + z = 0 + bl = "" + for i in blocs: + txtLines = i.splitlines() + if len(txtLines) > 0: + line = txtLines[0] + else: + line = i + if commentTxtBloc.split(i)[0].strip() and openTxtBloc.search(line): + if bl: + realBlocs.append(bl) + bl = "" + realBlocs.append(i) + else: + bl += i + z += 1 + if bl: + realBlocs.append(bl) + bl = "" + if level == 0: + if text and text[-1] != "\n": + tmpBlocs = realBlocs.pop() + tmpBlocs = tmpBlocs[:-1] + realBlocs.append(tmpBlocs) + return realBlocs + else: + return [] + + def findArea(self, text, reTextHeader, reTextArea, numGroupArea=0): + """ Делит текст на области (с заголовками) + + reTextHeader - регулярное выражение для заголовка области + reTextArea - регулярное выражение для всей области + numGroupArea - номер групы результата поиска по регулярному выражению + по всей области + возвращает два списка: первый - заголовки, второй - тела областей без + заголоков + """ + # Заголовки областей + headersArea = [] + # Тексты областей без заголовков + textBodyArea = [] + r = reTextArea.search(text) + if not r: + headersArea.append("") + textBodyArea.append(text) + return (headersArea, textBodyArea) + + txtWr = text + while r: + textArea = r.group(numGroupArea) + txtSpl = txtWr.split(textArea) + area = txtSpl[0] + txtWr = txtSpl[1] + if area: + headersArea.append("") + textBodyArea.append(area) + res = reTextHeader.search(textArea) + header = textArea[:res.end()] + body = textArea[res.end():] + + headersArea.append(header) + textBodyArea.append(body) + + if txtWr: + r = reTextArea.search(txtWr) + else: + r = False + if txtWr: + headersArea.append("") + textBodyArea.append(txtWr) + return (headersArea, textBodyArea) + + + def findBloc(self, text, captionTxtBloc, bodyTxtBloc): + """ Делит текст на блоки (с заголовками) + + captionTxtBloc - регулярное выражение для заголовка блока + bodyTxtBloc - регулярное выражение для тела блока + возвращает два списка: первый - заголовки, второй - тела блоков + """ + # Заголовки блоков + headersTxt = [] + # Тексты блоков + blocsTxt = [] + r = captionTxtBloc.search(text) + if r: + headersTxt.append(r.group(0)) + txtSpl = text.split(r.group(0)) + blocTxt = txtSpl[0] + txtWr = txtSpl[1] + rb = bodyTxtBloc.search(blocTxt) + if not blocTxt: + blocsTxt.append(blocTxt) + if rb: + blocsTxt.append(rb.group(0)) + while (r): + r = captionTxtBloc.search(txtWr) + if r: + headersTxt.append(r.group(0)) + txtSpl = txtWr.split(r.group(0)) + blocTxt = txtSpl[0] + txtWr = txtSpl[1] + rb = bodyTxtBloc.search(blocTxt) + if rb: + blocsTxt.append(rb.group(0)) + else: + blocsTxt.append(txtWr) + if headersTxt and blocsTxt: + if len(headersTxt)>len(blocsTxt): + blocsTxt.insert(0,"") + elif len(headersTxt)= 4: + l = 4 + elif lenSymb >= 3: + l = 3 + elif lenSymb >= 2: + l = 2 + else: + if symbols[0] == '_ch_': + return (True,1) + else: + return (False,1) + result = False + for i in range(l): + if i == 0 and symbols[i] != '_fb_': + break + elif i > 0 and symbols[i] != '_nb_': + break + if lenTail>1 and lenTail != i: + return (False,1) + if i > 0: + result = True + return (result, i) + + + #TODO get rid of this abomination + def _intToChar(self, x): + he = hex(x)[2:] + # exec("ret = '\\x%s'" % he) + # return ret + return None + + def _hexToChar(self, he): + # exec("ret = '\\x%s'" % he) + # return ret + return None + + def encode(self, text): + """Кодирует смешанный формат в UTF-8""" + ind = 0 + l = 0 + utf = [] + lenUtf = [] + indErr = [] + i = 0 + for ch in text: + r, l = self._retUTF(ch) + utf.append(r) + lenUtf.append(l) + i+=1 + while 1: + if utf[ind] == '_fb_': + res, l = self._sumbUtf(utf[ind:],lenUtf[ind]) + if res is False: + indErr.append(ind) + if l>0: + ind +=l + if ind >= len(utf): + break + else: + if utf[ind] != '_ch_': + indErr.append(ind) + ind +=1 + if ind >= len(utf): + break + if indErr: + lenIndErr = len(indErr) + block = [] + blocks = [] + if lenIndErr > 1: + i = 1 + while 1: + if i == 1: + block.append(indErr[i-1]) + if indErr[i] - indErr[i-1] == 1: + block.append(indErr[i]) + else: + if block: + blocks.append(block) + block = [] + block.append(indErr[i]) + i +=1 + if i >= lenIndErr: + break + else: + block.append(indErr[0]) + if block: + blocks.append(block) + listErr = [] + for block in blocks: + string = "" + for elem in block: + string += hex(ord(text[elem]))[-2:] + listErr.append((block[0],"__hex__?%s?__hex__" %string,elem)) + textOut = text + deltaInd = 0 + for erEl in listErr: + startInd = erEl[0] + deltaInd + endInd = erEl[2] + 1 + deltaInd + textOut = textOut[:startInd] + erEl[1] + textOut[endInd:] + deltaInd += len(erEl[1])-(erEl[2]-erEl[0]+1) + #if i == 1: + #break + #i += 1 + return textOut + + def decode(self, text): + """Декодирует UTF-8 в смешанный формат""" + varStart = "__hex__\?" + varEnd = "\?__hex__" + # -1 Это экранирование '?' которое тоже считается + deltVarStart = len(varStart)-1 + deltVarEnd = len(varEnd)-1 + reVar = re.compile(("%s[a-f0-9]+%s")%(varStart,varEnd),re.M) + resS = reVar.search(text) + textProfileTmp = text + while resS: + mark = textProfileTmp[resS.start():resS.end()] + hexString = mark[deltVarStart:-deltVarEnd] + i = 0 + stringInsert = "" + hexCode = "" + for ch in hexString: + if i>=1: + hexCode += ch + stringInsert += self._hexToChar(hexCode) + hexCode = "" + i = 0 + else: + hexCode += ch + i += 1 + textProfileTmp = textProfileTmp.replace(mark, stringInsert) + resS = reVar.search(textProfileTmp) + return textProfileTmp + + def getUserDataInLDAP(self, userName): + """Получаем домашнюю директорию пользователя из LDAP""" + if not self.conLdap: + from . import cl_utils2 + data = self.getLDAPDataInConfig() + if not data: + return "" + serverName, usersDN, bindDN, bindPW = data + # Подключаемся к LDAP + ldapObj = cl_utils2.ldapFun(bindDN, bindPW, serverName) + if self.getError(): + return "" + self.conLdap = ldapObj.conLdap + searchScope = ldap.SCOPE_ONELEVEL + searchFilter = "uid=%s" %(userName) + retrieveAttributes = ["uidNumber", + "gidNumber" + "homeDirectory"] + resSearch = ldapObj.ldapSearch(usersDN, searchScope, + searchFilter, retrieveAttributes) + if resSearch: + if 'uidNumber' in resSearch[0][0][1] and\ + 'gidNumber' in resSearch[0][0][1] and\ + 'homeDirectory' in resSearch[0][0][1]: + uid = resSearch[0][0][1]['uidNumber'][0] + gid = resSearch[0][0][1]['gidNumber'][0] + # uid = searchUser[0][0][1]['uidNumber'][0] + # gid = searchUser[0][0][1]['gidNumber'][0] + homeDir = resSearch[0][0][1]['homeDirectory'][0] + return uid, gid, homeDir + return "" + + +class processingTemplates: + """Класс для обработки шаблонов""" + + def processingFile(self, path, prefix): + """Обработка в случае профиля файла""" + return True + + def processingDirectory(self, path, prefix): + """Обработка в случае директории если возвращаем None то пропуск дир.""" + return True + + def scanningTemplates(self, scanDir, skipFile=[], skipDir=[], + prefix=None, flagDir=False): + """Время последней модификации внутри директории scanDir""" + ret = True + if not prefix: + prefix = os.path.join(scanDir,"")[:-1] + if not flagDir: + # проверка корневой директории + retDir = self.processingDirectory(scanDir, scanDir) + if retDir is None: + return None + elif retDir is False: + return False + if flagDir or stat.S_ISDIR(os.lstat(scanDir)[stat.ST_MODE]): + for fileOrDir in sorted(os.listdir(scanDir)): + absPath = os.path.join(scanDir,fileOrDir) + relPath = absPath.split(prefix)[1] + stInfo = os.lstat(absPath) + statInfo = stInfo[stat.ST_MODE] + if stat.S_ISREG(statInfo): + # Обработка файла + if relPath in skipFile: + continue + if not self.processingFile(absPath, prefix): + ret = False + break + elif stat.S_ISDIR(statInfo): + # Обработка директории + if relPath in skipDir: + continue + retDir = self.processingDirectory(absPath, prefix) + if retDir is None: + continue + elif retDir is False: + ret = False + break + ret = self.scanningTemplates(absPath, skipFile, + skipDir, prefix, True) + if ret is False: + break + return ret + + +class profile(_file, _terms, xmlShare, processingTemplates): + """Класс для работы с профилями + + На вход 2 параметра: объект хранения переменных, имя сервиса - не + обязательный параметр + + """ + # Словарь установленных программ {"имя программы":[версии]} + installProg = {} + + # Cписок просканированных категорий установленных программ + installCategory = [] + + # Флаг сканирования всех установленных программ + flagAllPkgScan = False + + # Название файла профиля директории + profDirNameFile = ".calculate_directory" + + # стек глобальных переменных + stackGlobalVars = [] + + # директория установленных программ + basePkgDir = "/var/db/pkg" + + # регулярное выражение для поиска версии + reFindVer = re.compile("(?<=\-)\d+\.?\d*\.?\d*") + + def __init__(self, objVar, servDir=False, dirsFilter=[], filesFilter=[]): + # Необрабатываемые директории + self.dirsFilter = dirsFilter + # Необрабатываемые файлы + self.filesFilter = filesFilter + _file.__init__(self) + # Словарь для создания объектов новых классов по образцу + self.newObjProt = {'proftpd':(apache,),} + # Заголовок title + self.__titleHead = "--------------------------------------\ +----------------------------------------" + self._titleBody = "" + self._titleList = (_("Modified"), _("File of a profile")) + + # Метки + varStart = "#-" + varEnd = "-#" + self._reVar = re.compile(("%s[a-zA-Z0-9_-]+%s")%(varStart,varEnd),re.M) + self._reFunc = re.compile(("%s[a-zA-Z0-9_\-\+\(\)\, \*\/\.\'\"~]+%s")\ + %(varStart,varEnd),re.M) + self._deltVarStart = len(varStart) + self._deltVarEnd = len(varEnd) + # Условия + self._reTermBloc = re.compile("#\?(?P[a-zA-Z0-9\-_]+)\ +(?P\([a-zA-Z0-9_\-\+\,\*\/\.\'\"~]+\))?\ +(?P[\>\<\=\!\&\|]+\ +[a-zA-Z0-9\>\<\=\!\|\&\-\+\*\/_\.\,\(\)\'\"~]*)#\ +\n*(?P.+?)\n*#(?P=rTerm)#(?P[ ,\t]*\n?)",re.M|re.S) + # Объект с переменными + self.objVar = objVar + # Базовая директория переноса профилей "/mnt/calculate" или "/" и.т.д + baseDir = self.objVar.Get("cl_root_path") + #self._baseDir = os.path.split(baseDir)[0] + self._baseDir = baseDir + if self._baseDir == "/": + self._baseDir = "" + # Последняя часть директории профиля (имя сервиса: samba, mail) + self._servDir = servDir + if self._servDir: + if self._servDir[0] != "/": + self._servDir = "/" + self._servDir + if self._servDir[-1] != "/": + self._servDir += "/" + self._servDir = os.path.split(self._servDir)[0] + # Созданные директории + self.createdDirs = [] + # Примененные файлы + self.filesApply = [] + # номер обрабатываемого файла + self.numberProcessProf = 0 + # имя текущей программы + _nameProgram = self.objVar.Get("cl_name").capitalize() + # версия текущей программы + _versionProgram = self.objVar.Get("cl_ver") + # имя и версия текущей программы + self.programVersion = "%s %s"%(_nameProgram, _versionProgram) + # Словарь измененных директорий + self.changeDirs = {} + # Словарь директорий с количесвом файлов шаблонов + self.dictTemplates = {} + # Общее количество шаблонов + self.allTemplates = 0 + # Аттрибуты для функции шаблона ini() + # Первоначальный словарь переменных для ini() + self.prevDictIni = {} + # Текущий словарь переменных для ini() + self.currDictIni = {} + # Время модификации конфигурационного файла для ini() + self.timeIni = -1 + self.uid, self.gid, self.homeDir = self.getDataUser() + # Путь к конфигурационному файлу для ini() + self.pathConfigIni = os.path.join(self.homeDir, ".calculate") + self.fileConfigIni = os.path.join(self.pathConfigIni,"ini.env") + # Словарь времен модификации env файлов + self.timeConfigsIni = {} + + def getDataUser(self): + """Получить информацию о пользователе""" + userName = self.objVar.Get("ur_login") + if not userName: + userName = "root" + import pwd + try: + pwdObj = pwd.getpwnam(userName) + uid = pwdObj.pw_uid + gid = pwdObj.pw_gid + homeDir = pwdObj.pw_dir + except: + print(_("Can not found user %s")%str(userName)) + cl_base.exit(1) + return uid, gid, homeDir + + + # Преобразование восьмеричного в целое (ввод строка, вывод число) + def __octToInt(self, strOct): + if strOct: + try: + # exec("res =" + "0" + strOct) + res = int(strOct, 8) + except: + self.setError (_("Not valid oct value: ") + str(strOct)) + return False + return res + else: + self.setError (_("Empty oct value")) + return False + + def removeDir(self, rmDir): + """Рекурсивное удаление директории + + входной параметр директория + Обязательно должен быть определен метод self.printERROR + """ + if not os.path.exists(rmDir): + self.printERROR(_("Not found remove dir %s") %rmDir) + return False + fileObj = _file() + # Сканируем директорию + 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 rmDir: + os.rmdir(rmDir) + return True + + + def createDir(self, baseProfDir, profDir, baseDirMv, createDir): + """Создает директорию + + baseDirMv + результат вычитания из profDir baseProfDir + createDir - создаваемая директория + """ + if baseDirMv and not os.access(baseDirMv, os.F_OK): + os.makedirs(baseDirMv) + # Созданные директории + createDirs = [] + baseDir = baseProfDir + if baseProfDir[-1] == "/": + baseDir = baseProfDir[:-1] + # Директория в системе относительно baseDirMv без условий + if baseDirMv: + dirMvNoTerm = createDir.partition(baseDirMv)[2] + else: + dirMvNoTerm = createDir + # директория в системе + dirMv = profDir.partition(baseDir)[2] + if len(dirMv)>1 and dirMv[-1] == "/": + dirMv = dirMv[:-1] + ## директория в системе без условий + #dirMvNoTerm = "/".join(map(lambda x:x.split("?")[0],\ + #dirMv.split("/"))) + listDirMv = dirMv.split("/") + listDirMvNoTerm = dirMvNoTerm.split("/") + if len(listDirMv) != len(listDirMvNoTerm): + self.setError (_("Error in profile") + " :" + profDir) + return False + genIn = listDirMv.__iter__() + genOut = listDirMvNoTerm.__iter__() + inAndOutDirs = [[x,next(genOut)] for x in genIn] + createDirs = [] + createDir = [] + while (len(inAndOutDirs)>1): + tmpDirIn = baseDir + "/".join(x[0] for x in inAndOutDirs) + tmpDirOut = baseDirMv + "/".join(x[1] for x in inAndOutDirs) + if os.access(tmpDirOut, os.F_OK): + break + else: + createDir.append((tmpDirIn, tmpDirOut)) + inAndOutDirs.pop() + createDir.reverse() + for crDirIn,crDirOut in createDir: + try: + mode,uid,gid = self.getModeFile(crDirIn) + except OSError: + self.setError (_("not access dir:" ) + crDirIn) + return False + createDirs.append(crDirOut) + os.mkdir(crDirOut, mode) + os.chown(crDirOut, uid, gid) + return createDirs + + + def applyVarsProfile(self, textProfile, nameProfile): + """ Заменяет переменные на их значения + """ + resS = self._reVar.search(textProfile) + textProfileTmp = textProfile + while resS: + mark = textProfileTmp[resS.start():resS.end()] + varName = mark[self._deltVarStart:-self._deltVarEnd] + varValue = "" + try: + varValue = str(self.objVar.Get(varName)) + except self.objVar.DataVarsError as e: + print(_("error in profile %s")%nameProfile) + print(e) + cl_base.exit(1) + textProfileTmp = textProfileTmp.replace(mark, varValue) + resS = self._reVar.search(textProfileTmp) + return textProfileTmp + + + def applyFuncProfile(self, textProfile, nameProfile, nameSystemFile): + """ Применяет функции к тексту профиля + """ + def equalTerm(term, sNum, sMD, localVars): + """Локальная функция для вычисления выражения""" + terms = sNum.findall(term) + if terms: + strNumers = [] + for n in terms: + strNum = n.strip() + if "*" in strNum or "/" in strNum: + strNum = multAndDiv(strNum,sNum,sMD,localVars) + try: + num = int(strNum) + except: + minus = False + if strNum[:1] == "-": + minus = True + strNum = strNum[1:] + if strNum in localVars: + try: + num = int(localVars[strNum]) + except: + print(_("error in profile %s")%nameProfile) + print(_("error local var %s not int")\ + %str(strNum)) + cl_base.exit(1) + elif self.objVar.exists(strNum): + try: + num = int(self.objVar.Get(strNum)) + except: + print(_("error in profile %s")%nameProfile) + print(_("error var %s not int")%str(strNum)) + cl_base.exit(1) + else: + print(_("error in profile %s")%nameProfile) + print(_("error local var %s not defined")\ + %str(strNum)) + cl_base.exit(1) + if minus: + num =-num + strNumers.append(num) + return sum(strNumers) + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s, incorrect data")%str(term)) + cl_base.exit(1) + + def multAndDiv(term,sNum,sMD,localVars): + """локальная функция для умножения и деления""" + termTmp = term + varsLocal = sMD.findall(term) + for var in varsLocal: + flagVarTxt = True + try: + int(var) + except: + flagVarTxt = False + if flagVarTxt: + continue + varReplace = str(equalTerm(var,sNum,sMD,localVars)) + termTmp = termTmp.replace(var,varReplace) + ret = eval(termTmp) + return ret + + def funcSum(funTxt,resS,localVars,textProfileTmp): + """локальная функция вычисляет первую функцию sum() в профиле""" + terms = funTxt[4:-1].replace(" ","").split(",") + # Название локальной переменной + nameLocVar = terms[0] + if nameLocVar not in localVars: + localVars[nameLocVar] = 0 + if len(terms) == 2: + if terms[1].strip(): + localVars[nameLocVar] = equalTerm(terms[1],sNum,sMD, + localVars) + replace = str(localVars[nameLocVar]) + else: + replace = "" + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + elif len(terms) == 3: + if terms[1].strip(): + replaceInt = equalTerm(terms[1],sNum,sMD,localVars) + replace = str(replaceInt) + else: + replace = "" + localVars[nameLocVar] = equalTerm(terms[2], + sNum,sMD,localVars) + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + else: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + return textProfileTmp + + + def funcExists(funTxt,resS,textProfileTmp): + """если файл существует читает из файла локальную переменную + + если один параметр - выводит значение локальной переменной + """ + terms = funTxt[7:-1].replace(" ","").split(",") + if len(terms) !=1: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + fileName = terms[0].strip() + if fileName[0] == "~": + # Получаем директорию пользователя + fileName = os.path.join(self.homeDir, + fileName.partition("/")[2],"")[:-1] + elif fileName[0] != "/": + path = os.path.split(nameSystemFile)[0] + fileName=os.path.join(path,fileName) + replace = "" + if os.path.exists(fileName): + replace = "1" + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return textProfileTmp + + def funcLoad(funTxt,resS,textProfileTmp): + """если файл существует читает из файла локальную переменную + + если один параметр - выводит значение локальной переменной + """ + terms = funTxt[5:-1].replace(" ","").split(",") + if not terms[0].strip() or\ + (len(terms)==2 and not terms[1].strip()) or\ + len(terms)>2: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + if len(terms) == 2: + if not terms[0] in ["ver","num","char","key"]: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + print(_("first argument function is not 'ver' or 'num' or\ + 'char'")) + cl_base.exit(1) + if len(terms) == 1: + fileName = terms[0].strip() + # Если домашняя директория + if fileName[0] == "~": + # Получаем директорию пользователя + fileName = os.path.join(self.homeDir, + fileName.partition("/")[2],"")[:-1] + elif fileName[0] != "/": + path = os.path.split(nameSystemFile)[0] + fileName=os.path.join(path,fileName) + else: + fileName = terms[1].strip() + # Если домашняя директория + if fileName[0] == "~": + # Получаем директорию пользователя + fileName = os.path.join(self.homeDir, + fileName.partition("/")[2],"")[:-1] + elif fileName[1] != "/": + path = os.path.split(nameSystemFile)[0] + fileName=os.path.join(path,fileName) + replace = "" + if os.path.exists(fileName): + FD = open(fileName) + replace = FD.read().strip() + FD.close + if not replace and len(terms) == 2 and terms[0] in ["ver","num"]: + replace = "0" + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return textProfileTmp + + def getInstallPkgGentoo(): + """Выдает словарь инсталлированных программ и номеров версий""" + pkgs = [] + def getFilesDir(pkgs, dirname, names): + for nameFile in names: + absNameFile = os.path.join(dirname,nameFile) + if os.path.isdir(absNameFile): + tail = absNameFile.split(self.basePkgDir) + if len(tail)==2: + tail = tail[1].split('/') + if len(tail)==3 and tail[1]!='virtual': + pkgs.append(tail[2]) + return True + os.path.walk(self.basePkgDir,getFilesDir, pkgs) + return sharePkg(pkgs) + + def sharePkg(pkgs): + """Получение имен и номеров версий программ""" + pkgs.sort() + installProg = {} + for pkg in pkgs: + findVer = self.reFindVer.search(pkg) + if findVer: + version = findVer.group() + name = pkg.split(version)[0][:-1] + if name in installProg: + installProg[name].append(version) + else: + installProg[name] = [version] + return installProg + + def pkg(nameProg, installProg): + """Выдает установленные версии по имени программы""" + if nameProg in installProg: + return installProg[nameProg][-1] + else: + return "" + + def funcPkg(funTxt,resS,textProfileTmp): + """локальная функция выдает номер версии программы""" + terms = funTxt[4:-1].replace(" ","") + # Название программы + nameProg = terms + # Замена функции в тексте шаблона + replace = "" + if "/" in nameProg: + if nameProg in self.installProg: + replace = pkg(nameProg, self.installProg) + else: + category, spl, nProg = terms.partition("/") + if not category in self.installCategory: + self.installCategory.append(category) + pathCategory = os.path.join(self.basePkgDir, category) + if os.path.exists(pathCategory): + pkgs = os.listdir(pathCategory) + pkgs = [os.path.join(category, x) for x in pkgs] + installProg = sharePkg(pkgs) + replace = pkg(nameProg, installProg) + self.installProg.update(installProg) + else: + if not self.flagAllPkgScan: + installProg = getInstallPkgGentoo() + self.installProg.update(installProg) + profile.flagAllPkgScan = True + replace = pkg(nameProg, self.installProg) + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return textProfileTmp + + def funcRnd(funTxt,resS,textProfileTmp): + """локальная функция выдает строку случайных символов + + первый аргумент: + 'num' - числа, + 'pas' - цифры и буквы + второй аргумент: + количество символов + """ + terms = funTxt[4:-1].replace(" ","").split(",") + if not terms[0].strip() or\ + (len(terms)==2 and not terms[1].strip()) or\ + len(terms)!=2: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + fArgvNames = ['num','pas'] + if not terms[0] in fArgvNames: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + print(_("first argument function is not 'num' or 'pas'")) + cl_base.exit(1) + try: + lenStr = int(terms[1]) + except: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + print(_("two argument function is not number")) + cl_base.exit(1) + if terms[0] == fArgvNames[0]: + replace=''.join([random.choice(string.digits)\ + for i in range(lenStr)]) + elif terms[0] == fArgvNames[1]: + replace=''.join([random.choice(string.ascii_letters + \ + string.digits) for i in range(lenStr)]) + else: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return textProfileTmp + + def funcCase(funTxt,resS,textProfileTmp): + """локальная функция выдает переменную в определенном регистре + + первый аргумент: + 'upper' - верхний регистр, + 'lower' - нижний регистр, + 'capitalize' - первая буква в верхнем регистре + второй аргумент: + название переменной + """ + terms = funTxt[5:-1].replace(" ","").split(",") + if not terms[0].strip() or\ + (len(terms)==2 and not terms[1].strip()) or len(terms)!=2: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + fArgvNames = ['upper','lower','capitalize'] + if not terms[0] in fArgvNames: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + print(_("first argument function is not 'upper' or 'lower' or\ + 'capitalize'")) + cl_base.exit(1) + try: + strValue = str(self.objVar.Get(terms[1])) + except: + print(_("error in profile %s")%nameProfile) + print(_("error var %s not found")%str(terms[1])) + cl_base.exit(1) + replace = "" + strValue = self._toUNICODE(strValue) + if terms[0] == 'upper': + replace = strValue.upper() + elif terms[0] == 'lower': + replace = strValue.lower() + elif terms[0] == 'capitalize': + replace = strValue.capitalize() + if replace: + replace = replace.encode("UTF-8") + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return textProfileTmp + + def funcPush(funTxt,resS,localVars,textProfileTmp): + """локальная функция записывает значение переменной + + в стек глобальных переменных + """ + terms = funTxt[5:-1].replace(" ","").split(",") + # Название локальной переменной + nameLocVar = terms[0] + flagFoundVar = False + if nameLocVar in localVars.keys(): + flagFoundVar = True + value = localVars[nameLocVar] + else: + try: + value = self.objVar.Get(nameLocVar) + flagFoundVar = True + except: + pass + if flagFoundVar: + # Если переменная существует + if len(terms) == 1: + self.stackGlobalVars.append(str(value)) + else: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + print(_("error var %s exists")%str(nameLocVar)) + cl_base.exit(1) + else: + # Если переменная не существует + if len(terms) == 1: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + print(_("error var %s not exists")%str(nameLocVar)) + cl_base.exit(1) + elif len(terms) == 2: + value = terms[1].strip() + self.stackGlobalVars.append(str(value)) + localVars[nameLocVar] = value + else: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + replace = "" + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return textProfileTmp + + def funcPop(funTxt,resS,localVars,textProfileTmp): + """локальная функция получает значение + + из стека глобальных переменных и присвает локальной переменной + + """ + terms = funTxt[4:-1].replace(" ","").split(",") + # Название локальной переменной + nameLocVar = terms[0] + if len(terms) == 1: + if self.stackGlobalVars: + localVars[nameLocVar] = self.stackGlobalVars.pop() + else: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + print(_("error, gloval variables stack is empty")) + cl_base.exit(1) + else: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + replace = "" + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return textProfileTmp + + def loadVarsIni(iniFileName): + """ Читает файл fileName + создает и заполняет переменные на основе этого файла + Используеться совместно c funcIni + """ + localVarsIni = {} + # Выходим если есть предыдущие ошибки + if self.getError(): + return False + # получить объект ini файла + config = cl_base.iniParser(iniFileName) + # получаем все секции из конфигурационного файла + allsect = config.getAllSectionNames() + if not allsect: + if self.getError(): + # Очистка ошибки + _error.error = [] + return localVarsIni + # Заполняем переменные для funcIni + for sect in allsect: + sectVars = config.getAreaVars(sect) + for name in sectVars.keys(): + nameVar = "%s.%s"%(sect,name) + valueVar = sectVars[name] + localVarsIni[nameVar] = valueVar + return localVarsIni + + def getTimeFile(fileName): + # Получаем время модификации файла + if fileName in self.timeConfigsIni: + return self.timeConfigsIni[fileName] + return 0 + + def funcIni(funTxt, resS, textProfileTmp): + """локальная функция записывает и считывает значение переменной + + из ini файла ~./calculate/ini.env + """ + # Создаем директорию + if not os.path.exists(self.pathConfigIni): + os.makedirs(self.pathConfigIni) + os.chown(self.pathConfigIni, int(self.uid), int(self.gid)) + termsRaw = funTxt[4:-1].split(",") + flagFirst = True + terms = [] + for term in termsRaw: + if flagFirst: + terms.append(term.replace(" ","")) + flagFirst = False + else: + val = term.strip() + # Флаг (не найдены кавычки) + flagNotFoundQuote = True + for el in ('"',"'"): + if val.startswith(el) and val.endswith(el): + terms.append(val[1:-1]) + flagNotFoundQuote = False + break + if flagNotFoundQuote: + terms.append(val) + # Название локальной переменной + nameLocVar = terms[0] + namesVar = nameLocVar.split(".") + if len(namesVar) == 1: + nameLocVar = "main.%s"%nameLocVar + elif len(namesVar)>2: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + replace = "" + # Получаем время модификации конфигурационного файла + curTime = getTimeFile(self.fileConfigIni) + if len(terms) == 1: + if self.timeIni != curTime: + # читаем переменные из файла + self.prevDictIni = loadVarsIni(self.fileConfigIni) + self.currDictIni.update(self.prevDictIni) + self.timeIni = getTimeFile(self.fileConfigIni) + if nameLocVar in self.currDictIni.keys(): + replace = self.currDictIni[nameLocVar] + elif len(terms) == 2: + if self.timeIni != curTime: + # читаем переменные из файла + self.prevDictIni = loadVarsIni(self.fileConfigIni) + self.currDictIni.update(self.prevDictIni) + self.timeIni = getTimeFile(self.fileConfigIni) + # Значение локальной переменной + valueLocVar = terms[1] + self.currDictIni[nameLocVar] = valueLocVar + else: + print(_("error in profile %s")%nameProfile) + print(_("error profile term %s")%str(funTxt)) + cl_base.exit(1) + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return (textProfileTmp) + + # Локальные переменные + localVars = {} + # Регулярное выражние для сложения + sNum = re.compile("\-[^\-\+]+|[^\-\+]+") + # Регулярное выражение для умножениея и деления + sMD = re.compile("[^\-\+\*\/]+") + resS = self._reFunc.search(textProfile) + textProfileTmp = textProfile + flagIniFunc = False + while resS: + mark = textProfileTmp[resS.start():resS.end()] + funTxt = mark[self._deltVarStart:-self._deltVarEnd] + # Функция sum + if funTxt.startswith("sum("): + textProfileTmp = funcSum(funTxt,resS,localVars,textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + # Функция load + elif funTxt.startswith("load("): + textProfileTmp = funcLoad(funTxt,resS,textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + elif funTxt.startswith("pkg("): + textProfileTmp = funcPkg(funTxt,resS,textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + elif funTxt.startswith("rnd("): + textProfileTmp = funcRnd(funTxt,resS,textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + elif funTxt.startswith("case("): + textProfileTmp = funcCase(funTxt,resS,textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + elif funTxt.startswith("pop("): + textProfileTmp = funcPop(funTxt,resS,localVars,textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + elif funTxt.startswith("push("): + textProfileTmp = funcPush(funTxt,resS,localVars,textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + elif funTxt.startswith("ini("): + flagIniFunc = True + textProfileTmp = funcIni(funTxt, resS, textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + elif funTxt.startswith("exists("): + textProfileTmp = funcExists(funTxt, resS, textProfileTmp) + resS = self._reFunc.search(textProfileTmp) + else: + resS = False + if flagIniFunc: + # Очистка файла в случае его ошибочного чтения + if not self.prevDictIni and os.path.exists(self.fileConfigIni): + FD = open(self.fileConfigIni, "r+") + FD.truncate(0) + FD.seek(0) + FD.close() + # Если конф. файл модифицирован шаблоном + curTime = getTimeFile(self.fileConfigIni) + if curTime != self.timeIni: + # Считаем переменные из конф. файла + self.prevDictIni = loadVarsIni(self.fileConfigIni) + self.currDictIni.update(self.prevDictIni) + self.timeIni = curTime + # Если словари переменных не совпадают + if self.prevDictIni != self.currDictIni: + # Запишем переменные в конфигурационный файл + # Создание объекта парсера + config = cl_base.iniParser(self.fileConfigIni) + # секции будущего конфигурационного файла + sects = list(set(x.split(".")[0] for x in self.currDictIni.keys())) + # запись переменных в файл + for sect in sects: + dictVar = {} + for varName in self.currDictIni.keys(): + if varName.startswith("%s."%sect): + nameVar = varName.rpartition(".")[2] + valueVar = self.currDictIni[varName] + if valueVar: + dictVar[nameVar] = valueVar + if dictVar: + # Запись переменных в секцию + config.setVar(sect, dictVar) + # читаем переменные из файла + self.prevDictIni = loadVarsIni(self.fileConfigIni) + self.currDictIni.update(self.prevDictIni) + self.timeConfigsIni[self.fileConfigIni] = float(time.time()) + self.timeIni = getTimeFile(self.fileConfigIni) + # Меняем владельца в случае необходимости + if os.path.exists(self.fileConfigIni): + fd = os.open(self.fileConfigIni, os.O_RDONLY) + fst = os.fstat(fd) + uid = fst.st_uid + gid = fst.st_gid + os.close(fd) + if self.uid!=uid or self.gid!=gid: + os.chown(self.fileConfigIni, int(self.uid), int(self.gid)) + return textProfileTmp + + def applyTermsProfile(self, textProfile, nameProfile, nameSystemFile=False): + """ Применяет условия, к условным блокам текста + """ + textTerm = "" + resS = self._reTermBloc.search(textProfile) + textProfileTmp = textProfile + def function(text): + """Функция обработки функций в заголовке""" + return self.applyFuncProfile(text, nameProfile, nameSystemFile) + if nameSystemFile: + while resS: + mark = resS.group(0) + body = resS.group("body") + end = resS.group("end") + parent = resS.group("func") + if not parent: + parent = "" + term = resS.group("rTerm") + parent +\ + resS.group("lTerm") + if self._equalTerm(term, _("content profile not valid: ")+\ + nameProfile, function): + textProfileTmp = textProfileTmp.replace(mark, body+end) + else: + textProfileTmp = textProfileTmp.replace(mark, "") + resS = self._reTermBloc.search(textProfileTmp) + else: + while resS: + mark = resS.group(0) + body = resS.group("body") + end = resS.group("end") + term = resS.group("rTerm") + resS.group("lTerm") + if self._equalTerm(term, _("content profile not valid: ")+\ + nameProfile): + textProfileTmp = textProfileTmp.replace(mark, body+end) + else: + textProfileTmp = textProfileTmp.replace(mark, "") + resS = self._reTermBloc.search(textProfileTmp) + return textProfileTmp + + def getNeedProfile(self, fileProfile): + """Применяем правила к названию файла""" + dirP,fileP = os.path.split(fileProfile) + if fileP: + spFile = fileP.split("?") + realFileName = spFile[0] + if len(spFile)>1: + flagTrue = False + for term in spFile[1:]: + if self._equalTerm(term, _("name profile not valid: ")+\ + fileProfile): + flagTrue = True + break + if flagTrue: + return True + else: + return False + else: + return True + else: + self.setError (_("name profile not valid: ")+ str(fileProfile)) + return False + + def getTitle(self, comment, commentList): + """Выдает заголовок профиля ( версия и.т.д)""" + if comment: + commentFirst = comment + commentInsert = comment + commentLast = comment + flagList = False + # В случае открывающего и закрывающего комментария + if type(comment) == tuple and len(comment) == 2: + commentFirst = comment[0] + commentInsert = "" + commentLast = comment[1] + flagList = True + if flagList: + self._titleBody = commentFirst + "\n" + else: + self._titleBody = commentFirst + self.__titleHead + "\n" + z = 0 + lenCommentList = len(commentList) - 1 + for com in self._titleList: + if lenCommentList < z: + self._titleBody += commentInsert + " " + com + "\n" + else: + self._titleBody += commentInsert + " " + com +\ + " " + commentList[z] + "\n" + z += 1 + if flagList: + self._titleBody += commentLast +"\n" + else: + self._titleBody += commentLast + self.__titleHead + "\n" + return self._titleBody + else: + return "" + + def numberAllProfiles(self, number): + """Количество профилей + + Вызов происходит перед наложением профилей + в момент вызова в number находится количество обрабатываемых файлов + Наследуемая функция + Используется для отображения прогресса при наложениии профилей + """ + return True + + def numberProcessProfiles(self, number): + """Номер текущего обрабатываемого профиля + + Вызов происходит при наложении профиля + в момент вызова в number находится номер обрабатываемого профиля + Наследуемая функция + Используется для отображения прогресса при наложениии профилей + """ + return True + + + def scanDirs(self, profilesDirs, objVar=False): + """Измененный метод сканирования директорий""" + dirs = [] + class dirProf: + def __init__(self): + self.baseDir = False + self.dirs = [] + self.files = [] + self.links = [] + self.sockets = [] + flagError = False + blockDirs = [] + def getFilesDir(dirP, dirname, names): + for nameFile in names: + absNameFile = dirname + "/" + nameFile + findBlock = False + for blDir in blockDirs: + st,mid,end = absNameFile.partition(blDir) + if (not st) and mid and end: + findBlock = True + break + if not findBlock: + if os.path.islink(absNameFile): + dest = absNameFile + src = os.readlink(absNameFile) + dirP.links.append((src,dest)) + elif os.path.isfile(absNameFile): + # Добавляем файлы кроме описаний директорий + if self.profDirNameFile != nameFile: + dirP.files.append(absNameFile) + elif os.path.isdir(absNameFile): + # Обработка условий в названии директории + if self.getNeedProfile(absNameFile): + if self.getError(): + blockDirs.append(absNameFile) + flagError = True + break + dirP.dirs.append(absNameFile) + else: + if self.getError(): + blockDirs.append(absNameFile) + flagError = True + break + blockDirs.append(absNameFile) + elif stat.S_ISSOCK(os.stat(absNameFile)[stat.ST_MODE]): + dirP.sockets.append(absNameFile) + for profileDir in profilesDirs: + if profileDir: + # Обработка условий в названии директории + if self.getNeedProfile(profileDir): + if self.getError(): + flagError = True + break + dirP = dirProf() + dirP.baseDir = profileDir + dirs.append(dirP) + os.path.walk(profileDir, getFilesDir, dirP) + else: + if self.getError(): + flagError = True + break + if flagError: + return [] + return dirs + + + def applyProfiles(self): + """Применяет профили к конфигурационным файлам""" + + def createDictTemplates(path, prefix, dictTemplates): + """Создает словарь {"директория":"кол-во шаблонов" ...} + + и считает общее количество шаблонов + """ + # Количество шаблонов + self.allTemplates += 1 + dirTemplate = os.path.split(path)[0] + while(True): + if dirTemplate in dictTemplates.keys(): + dictTemplates[dirTemplate] += 1 + else: + dictTemplates[dirTemplate] = 1 + if dirTemplate == prefix: + break + dirTemplate = os.path.split(dirTemplate)[0] + return dictTemplates + + if not self.objVar.defined("cl_profile_path"): + self.setError (_("not defined Var: ") + "cl_profile_path") + return False + dirsProfiles = self.objVar.Get("cl_profile_path") + dirsProfiles.sort() + # Словарь измененных директорий + self.changeDirs = {} + # Созданные директории + self.createdDirs = [] + # Примененные файлы + self.filesApply = [] + # Номер применяемого шаблона + self.numberProcessProf = 0 + # Словарь директорий с количеством файлов шаблонов + self.dictTemplates = {} + # Количество шаблонов + self.allTemplates = 0 + # Время доступа к конфигурационному файлу функции шаблона ini() + self.timeIni = -1 + # Первоначальный словарь переменных для ini() + self.prevDictIni = {} + # Текущий словарь переменных для ini() + self.currDictIni = {} + # Словарь времен модификации env файлов + self.timeConfigsIni = {} + if self._servDir: + tmpDirsProfiles = [] + for dirP in dirsProfiles: + dirProf = dirP + self._servDir + if os.access(dirProf, os.F_OK): + # Если директория существует + tmpDirsProfiles.append(dirProf) + dirsProfiles = tmpDirsProfiles + scanObj = processingTemplates() + scanObj.processingFile = lambda x,y: createDictTemplates(x, y,\ + self.dictTemplates) + # Считаем количество шаблонов + for dirTemplate in dirsProfiles: + scanObj.scanningTemplates(dirTemplate, + skipFile=self.filesFilter, + skipDir=self.dirsFilter) + self.numberAllProfiles(self.allTemplates) + for dirTemplate in dirsProfiles: + if self.scanningTemplates(dirTemplate, + skipFile=self.filesFilter, + skipDir=self.dirsFilter) is False: + return False + return (self.createdDirs, self.filesApply) + + + def processingFile(self, path, prefix): + """Обработка в случае профиля файла""" + self.numberProcessProf += 1 + self.numberProcessProfiles(self.numberProcessProf) + # Пропуск шаблонов директорий + if self.profDirNameFile == os.path.split(path)[1]: + return True + if self.getNeedProfile(path): + if self.getError(): + return False + fileProfileChange = path + findChangeDir = False + listD = self.changeDirs.items() + listD.reverse() + for dirChangeIn, dirChangeOut in listD: + st,mid,end = path.partition(dirChangeIn) + if (not st) and mid and end: + findChangeDir = True + break + if findChangeDir: + oldFile = dirChangeOut + end + else: + oldFile = path.partition(prefix)[2] + # файл в системе без условий + oldFile = "/".join(x.split("?")[0] for x in oldFile.split("/")) + if not findChangeDir: + oldFile = self._baseDir + oldFile + # Фильтрация профилей по названию файла + if oldFile in self.filesFilter: + return True + listProfTitle = prefix.split("/")[-2:] + profTitle = '"' + "/".join(listProfTitle) + '"' + # Записываем в переменную обрабатываемый файл + self.objVar.Set("cl_pass_file",oldFile) + # Пишем время модификации *.env файлов + if oldFile.endswith(".env"): + self.timeConfigsIni[oldFile] = float(time.time()) + filesApl = self.join(path, oldFile, + (self.programVersion,profTitle)) + if filesApl: + self.filesApply += filesApl + else: + if self.getError(): + #print self.getError() + return False + return True + + def processingDirectory(self, path, prefix): + """Обработка в случае директории если возвращаем None то пропуск дир.""" + # Файл шаблона директории + dirInfoFile = os.path.join(path, self.profDirNameFile) + # Проверяем заголовок + ret = self.__isApplyHeadDir(dirInfoFile) + if not ret: + if self.getError(): + self.setError(_("Incorrect profile: " ) + dirInfoFile) + return False + # Добавление количества файлов в пропущенной директории + if path in self.dictTemplates.keys(): + self.numberProcessProf += self.dictTemplates[path] + return None + newDir = self._baseDir + path.partition(prefix)[2] + newDir = "/".join(x.split("?")[0] for x in newDir.split("/")) + # Применяем шаблон + pathDir, objHeadDir = self.__getApplyHeadDir(newDir, + dirInfoFile, + self.changeDirs) + # Фильтрация профилей по названию директории + if pathDir in self.dirsFilter: + # Добавление количества файлов в пропущенной директории + if path in self.dictTemplates.keys(): + self.numberProcessProf += self.dictTemplates[path] + return None + if objHeadDir: + if isinstance(objHeadDir, dirHeader): + if not objHeadDir.headerCorrect: + self.setError(_("Incorrect profile: " ) +\ + dirInfoFile) + self.setError(objHeadDir.errorMessage) + return False + if not objHeadDir.headerTerm: + if objHeadDir.getError(): + self.setError(_("Incorrect profile: " ) +\ + dirInfoFile) + return False + if "name" in objHeadDir.params: + self.changeDirs[path] = pathDir + crDirs = self.createDir(prefix, path, + self._baseDir, pathDir) + if crDirs is False: + return False + self.createdDirs += crDirs + else: + if self.getError(): + self.setError(_("Incorrect profile: " ) +\ + dirInfoFile) + return False + # Добавление количества файлов в пропущенной директории + if path in self.dictTemplates.keys(): + self.numberProcessProf += self.dictTemplates[path] + return None + return True + + def __getGenHeadDir(self, newDir, profileDirFile, changeDirs): + """Определяет название создаваемой директории""" + + def function(text): + """Функция обработки функций в заголовке""" + return self.applyFuncProfile(text, newDir, profileDirFile) + + newDirMv = newDir + findChangeDir = False + #Меняем путь к директории + listD = changeDirs.items() + listD.reverse() + for dirChangeIn, dirChangeOut in listD: + st,mid,end = profileDirFile.partition(dirChangeIn) + if (not st) and mid: + findChangeDir = True + break + if findChangeDir: + pathRel = dirChangeOut + lenPathRel = len(pathRel.split("/")) + lenNewDir = len(newDir.split("/")) + lenEndDir = lenNewDir - lenPathRel + tmpDir = newDir + namesDirs = [] + for i in range(lenEndDir): + namesDirs.append(os.path.split(tmpDir)[1]) + tmpDir = os.path.split(tmpDir)[0] + namesDirs.reverse() + nameDir = "/".join(namesDirs) + newDirMv = os.path.join(pathRel, nameDir) + applyDir = newDirMv + if not os.path.exists(profileDirFile): + return (applyDir, True) + try: + FD = open(profileDirFile) + textProfile = FD.read() + FD.close() + except: + self.setError(_("Error open profile: " ) +\ + profileDirFile) + return (applyDir, False) + objHead = dirHeader(textProfile, self.objVar,function) + if not objHead.headerCorrect: + self.setError(_("Incorrect profile: " ) +\ + profileDirFile) + self.setError(objHead.errorMessage) + return (applyDir, False) + if not objHead.headerTerm: + if objHead.getError(): + self.setError(_("Incorrect profile: " ) +\ + profileDirFile) + return (applyDir, False) + # Изменяем название директории + if "name" in objHead.params: + nameDir = objHead.params['name'] + if "/" in nameDir or nameDir == ".." or nameDir == ".": + self.setError (_("False value 'name' in profile: " ) +\ + profileDirFile) + return (applyDir, False) + if not findChangeDir: + pathRel = os.path.split(os.path.abspath(newDirMv))[0] + # Новый путь к оригинальному файлу + newDirMv = os.path.join(pathRel, nameDir) + applyDir = newDirMv + # При удаленнии директории + if objHead.typeAppend == "remove": + return (applyDir, False) + return (applyDir, objHead) + + def scanProfiles(self, serviceName=False, dirObjs=False): + """Сканирует директории профилей - выводит список файлов""" + if not self.objVar.defined("cl_profile_path"): + self.setError (_("not defined Var: ") + "cl_profile_path") + return False + if not dirObjs: + if serviceName : + self._servDir = serviceName + if self._servDir: + if self._servDir[0] != "/": + self._servDir = "/" + self._servDir + if self._servDir[-1] != "/": + self._servDir += "/" + self._servDir = os.path.split(self._servDir)[0] + dirsProfiles = self.objVar.Get("cl_profile_path") + if self._servDir: + tmpDirsProfiles = [] + for dirP in dirsProfiles: + dirProf = dirP + self._servDir + if os.access(dirProf, os.F_OK): + # Если директория существует + tmpDirsProfiles.append(dirProf) + else: + tmpDirsProfiles.append(False) + dirsProfiles = tmpDirsProfiles + dirObjs = self.scanDirs(dirsProfiles,self.objVar) + #файлы к которым были применены профили + filesApply = [] + # Словарь измененных директорий + changeDirs = {} + dirObjsApply = [] + for dirObj in dirObjs: + dirInfoFile = os.path.join(dirObj.baseDir, self.profDirNameFile) + ret = self.__isApplyHeadDir(dirInfoFile) + if ret: + dirObjsApply.append(dirObj) + else: + if self.getError(): + self.setError(_("Incorrect profile: " ) +\ + dirInfoFile) + return False + for dirObj in dirObjsApply: + # сортируем файлы по названию + if dirObj.files: + dirObj.files.sort() + # сортируем директории по названию + if dirObj.dirs: + dirObj.dirs.sort() + blockDirs = [] + for dirProfile in dirObj.dirs: + newDir = self._baseDir + dirProfile.partition(dirObj.baseDir)[2] + newDir = "/".join(x.split("?")[0] for x in newDir.split("/")) + # Проверяем условие на директорию + dirInfoFile = os.path.join(dirProfile, self.profDirNameFile) + pathDir, objHeadDir = self.__getGenHeadDir(newDir, + dirInfoFile, + changeDirs) + # Фильтрация профилей по названию директории + if pathDir in self.dirsFilter: + blockDirs.append(dirProfile) + continue + if objHeadDir: + if isinstance(objHeadDir, dirHeader): + if not objHeadDir.headerCorrect: + self.setError(_("Incorrect profile: " ) +\ + dirInfoFile) + self.setError(objHeadDir.errorMessage) + return False + if not objHeadDir.headerTerm: + if objHeadDir.getError(): + self.setError(_("Incorrect profile: " ) +\ + dirInfoFile) + return False + if "name" in objHeadDir.params: + changeDirs[dirProfile] = pathDir + else: + if self.getError(): + self.setError(_("Incorrect profile: " ) +\ + dirInfoFile) + return False + blockDirs.append(dirProfile) + for fileProfile in dirObj.files: + findBlock = False + for blDir in blockDirs: + st,mid,end = fileProfile.partition(blDir) + if (not st) and mid and end: + findBlock = True + break + if findBlock: + continue + if self.getNeedProfile(fileProfile): + if self.getError(): + #print self.getError() + return False + fileProfileChange = fileProfile + findChangeDir = False + listD = changeDirs.items() + listD.reverse() + for dirChangeIn, dirChangeOut in listD: + st,mid,end = fileProfile.partition(dirChangeIn) + if (not st) and mid and end: + findChangeDir = True + break + if findChangeDir: + oldFile = dirChangeOut + end + else: + oldFile = fileProfile.partition(dirObj.baseDir)[2] + # файл в системе без условий + oldFile = "/".join(x.split("?")[0] for x in oldFile.split("/")) + if not findChangeDir: + oldFile = self._baseDir + oldFile + # Фильтрация профилей по названию файла + if oldFile in self.filesFilter: + continue + filesApply.append(oldFile) + else: + if self.getError(): + return False + return filesApply + + def __isApplyHeadDir(self, profileDirFile): + """Будет ли применен профиль корневой директории + + Возвращает True, False + """ + + def function(text): + """Функция обработки функций в заголовке""" + return self.applyFuncProfile(text, "", profileDirFile) + + if not os.path.exists(profileDirFile): + return True + try: + FD = open(profileDirFile) + textProfile = FD.read() + FD.close() + except: + self.setError(_("Error open profile: " ) +\ + profileDirFile) + return False + # Заменяем переменные на их значения + textProfile = self.applyVarsProfile(textProfile, profileDirFile) + # Обработка заголовка + objHead = dirHeader(textProfile, self.objVar,function) + if not objHead.headerCorrect: + self.setError(_("Incorrect profile: " ) +\ + profileDirFile) + self.setError(objHead.errorMessage) + return False + if not objHead.headerTerm: + if objHead.getError(): + self.setError(_("Incorrect profile: " ) +\ + profileDirFile) + return False + + ## Изменяем название директории + #if objHead.params.has_key("name"): + #self.setError (_("Invalid name 'name' in profile: " ) +\ + #profileDirFile) + #return False + + ## Удаляем директорию + #if objHead.typeAppend == "remove": + #self.setError (_("Invalid name 'remove' in profile: " ) +\ + #profileDirFile) + #return False + + ## chmod - изменяем права + #if objHead.params.has_key("chmod"): + #self.setError (_("Invalid name 'chmod' in profile: " ) +\ + #profileDirFile) + #return False + + ## chown - изменяем владельца и группу + #if objHead.params.has_key("chown"): + #self.setError (_("Invalid name 'chown' in profile: " ) +\ + #profileDirFile) + #return False + return True + + def __getApplyHeadDir(self, newDir, profileDirFile, changeDirs): + """Применяет профиль к директории (права, владелец, и.т. д)""" + + def function(text): + """Функция обработки функций в заголовке""" + return self.applyFuncProfile(text, newDir, profileDirFile) + + newDirMv = newDir + findChangeDir = False + #Меняем путь к директории + listD = changeDirs.items() + listD.reverse() + for dirChangeIn, dirChangeOut in listD: + st,mid,end = profileDirFile.partition(dirChangeIn) + if (not st) and mid: + findChangeDir = True + break + if findChangeDir: + pathRel = dirChangeOut + lenPathRel = len(pathRel.split("/")) + lenNewDir = len(newDir.split("/")) + lenEndDir = lenNewDir - lenPathRel + tmpDir = newDir + namesDirs = [] + for i in range(lenEndDir): + namesDirs.append(os.path.split(tmpDir)[1]) + tmpDir = os.path.split(tmpDir)[0] + namesDirs.reverse() + nameDir = "/".join(namesDirs) + newDirMv = os.path.join(pathRel, nameDir) + applyDir = newDirMv + if not os.path.exists(profileDirFile): + return (applyDir, True) + try: + FD = open(profileDirFile) + textProfile = FD.read() + FD.close() + except: + self.setError(_("Error open profile: " ) +\ + profileDirFile) + return (applyDir, False) + # Заменяем переменные на их значения + textProfile = self.applyVarsProfile(textProfile, profileDirFile) + # Обработка заголовка + objHead = dirHeader(textProfile, self.objVar,function) + if not objHead.headerCorrect: + self.setError(_("Incorrect profile: " ) +\ + profileDirFile) + self.setError(objHead.errorMessage) + return (applyDir, False) + if not objHead.headerTerm: + if objHead.getError(): + self.setError(_("Incorrect profile: " ) +\ + profileDirFile) + return (applyDir, False) + + # Изменяем название директории + if "name" in objHead.params: + nameDir = objHead.params['name'] + if "/" in nameDir or nameDir == ".." or nameDir == ".": + self.setError (_("False value 'name' in profile: " ) +\ + profileDirFile) + return (applyDir, False) + if not findChangeDir: + pathRel = os.path.split(os.path.abspath(newDirMv))[0] + # Новый путь к оригинальному файлу + newDirMv = os.path.join(pathRel, nameDir) + applyDir = newDirMv + + # Удаляем директорию + if objHead.typeAppend == "remove": + if os.path.isdir(newDirMv): + # удаляем директорию + try: + self.removeDir(newDirMv) + except: + self.setError(_("Can not delete dir: " ) +\ + newDirMv) + return (applyDir, False) + + # chmod - изменяем права + if "chmod" in objHead.params: + mode = self.__octToInt(objHead.params['chmod']) + if mode: + if not os.path.exists(newDirMv): + os.mkdir(newDirMv, mode) + else: + os.chmod(newDirMv, mode) + else: + self.setError (_("False value 'chmod' in profile: " ) +\ + profileDirFile) + return (applyDir, False) + # chown - изменяем владельца и группу + if "chown" in objHead.params: + owner = objHead.params['chown'] + if owner: + if ":" in owner: + strUid, strGid = owner.split(":") + import pwd + try: + uid = pwd.getpwnam(strUid)[2] + except: + self.setError (_("Not user in this system: ") + strUid) + self.setError (_("False value 'chown' in profile: " )+\ + profileDirFile) + return (applyDir, False) + try: + import grp + gid = grp.getgrnam(strGid)[2] + except: + self.setError (_("Not group in this system: ")+strGid) + self.setError (_("False value 'chown' in profile: " )+\ + profileDirFile) + return (applyDir, False) + + if not os.path.exists(newDirMv): + dirProfile = os.path.split(profileDirFile)[0] + try: + mode,uidTmp,gidTmp = self.getModeFile(dirProfile) + except OSError: + self.setError (_("not access dir:" ) + newDirMv) + return (applyDir, False) + os.mkdir(newDirMv, mode) + os.chown(newDirMv, uid, gid) + else: + self.setError (_("False value 'chown' in profile: " ) +\ + profileDirFile) + return (applyDir, False) + else: + self.setError (_("False value 'chown' in profile: " ) +\ + profileDirFile) + return (applyDir, False) + return (applyDir, objHead) + + def __getApplyHeadProfile(self ,newFile, oldFile, copyFile): + """Применяет заголовок к профилю (права, владелец, и.т. д)""" + + def function(text): + """Функция обработки функций в заголовке""" + return self.applyFuncProfile(text, newFile, oldFile) + + self.closeFiles() + # Файлы в системе к которым были применены профили + applyFiles = [oldFile] + if copyFile: + self.nameFileNew = self.absFileName(newFile) + self.FN = self.openNewFile(self.nameFileNew) + self.newProfile = self.FN.read() + self.closeNewFile() + objHeadNew = fileHeader(self.newProfile, False, + self.getFileType(),objVar=self.objVar, + function=function) + if not objHeadNew.headerCorrect: + self.setError(_("Incorrect profile: " ) +\ + newFile) + self.setError(objHeadNew.errorMessage) + return (applyFiles, False) + if not objHeadNew.headerTerm: + if objHeadNew.getError(): + self.setError(_("Incorrect profile: " ) +\ + newFile) + return (applyFiles, False) + + pathProg = "" + # Путь к оригинальному файлу + pathOldFile = oldFile + # Изменяем путь к оригинальному файлу + if "name" in objHeadNew.params: + nameFile = objHeadNew.params['name'] + if "/" in nameFile or nameFile == ".." or nameFile == ".": + self.setError (_("False value 'name' in profile: " ) + newFile) + return False + pathRel = os.path.split(os.path.abspath(oldFile))[0] + # Новый путь к оригинальному файлу + pathOldFile = os.path.join(pathRel,nameFile) + + # В случае force + if "force" in objHeadNew.params: + if os.path.islink(pathOldFile): + # удаляем ссылку + try: + os.unlink(pathOldFile) + except: + self.setError(_("Can not delete link: " ) +\ + pathOldFile) + return (applyFiles, False) + if os.path.isfile(pathOldFile): + # удаляем файл + try: + os.remove(pathOldFile) + except: + self.setError(_("Can not delete file: " ) +\ + pathOldFile) + return (applyFiles, False) + + # Удаляем оригинальный файл + if objHeadNew.typeAppend == "remove": + if os.path.islink(pathOldFile): + # удаляем ссылку + try: + os.unlink(pathOldFile) + except: + self.setError(_("Can not delete link: " ) +\ + pathOldFile) + if os.path.isfile(pathOldFile): + # удаляем файл + try: + os.remove(pathOldFile) + except: + self.setError(_("Can not delete file: " ) +\ + pathOldFile) + return (applyFiles, False) + + flagSymlink = False + flagForce = False + # Если есть параметр mirror + if "mirror" in objHeadNew.params: + if "link" in objHeadNew.params: + profileFile = objHeadNew.params['link'] + if not os.path.exists(profileFile): + if os.path.exists(pathOldFile): + os.remove(pathOldFile) + return (applyFiles, False) + elif not os.path.exists(pathOldFile): + return (applyFiles, False) + # Если есть указатель на файл профиля (link) + if "link" in objHeadNew.params and\ + "symbolic" not in objHeadNew.params: + profileFile = objHeadNew.params['link'] + foundProfileFile = os.path.exists(profileFile) + if foundProfileFile: + FO = self.openNewFile(profileFile) + buff = FO.read() + FO.close() + if os.path.exists(pathOldFile): + os.remove(pathOldFile) + if foundProfileFile: + fd = os.open(pathOldFile, os.O_CREAT) + os.close(fd) + os.chmod(pathOldFile, self._mode) + os.chown(pathOldFile, self._uid, self._gid) + FON = open (pathOldFile, "r+") + FON.write(buff) + FON.close() + + # Если символическая ссылка + if "symbolic" in objHeadNew.params: + prevOldFile = pathOldFile + pathOldFile = objHeadNew.params['link'] + flagSymlink = True + if not "/" == pathOldFile[0]: + pathLink = os.path.split(os.path.abspath(prevOldFile))[0] + pathProg = os.getcwd() + os.chdir(pathLink) + + # chmod - изменяем права + if "chmod" in objHeadNew.params: + mode = self.__octToInt(objHeadNew.params['chmod']) + if mode: + if not os.path.exists(pathOldFile): + fd = os.open(pathOldFile, os.O_CREAT) + os.close(fd) + os.chmod(pathOldFile, mode) + else: + self.setError (_("False value 'chmod' in profile: " ) +\ + newFile) + return (applyFiles, False) + + # chown - изменяем владельца и группу + if "chown" in objHeadNew.params: + owner = objHeadNew.params['chown'] + if owner: + if ":" in owner: + strUid, strGid = owner.split(":") + import pwd + try: + uid = pwd.getpwnam(strUid)[2] + except: + self.setError (_("Not user in this system: ") + strUid) + self.setError (_("False value 'chown' in profile: " )+\ + newFile) + return (applyFiles, False) + try: + import grp + gid = grp.getgrnam(strGid)[2] + except: + self.setError (_("Not group in this system: ")+strGid) + self.setError (_("False value 'chown' in profile: " )+\ + newFile) + return (applyFiles, False) + + if not os.path.exists(pathOldFile): + FO = self.openNewFile(newFile) + FO.close() + fd = os.open(pathOldFile, os.O_CREAT) + os.close(fd) + os.chmod(pathOldFile, self._mode) + os.chown(pathOldFile, uid, gid) + else: + self.setError (_("False value 'chown' in profile: " ) +\ + newFile) + return (applyFiles, False) + else: + self.setError (_("False value 'chown' in profile: " ) +\ + newFile) + return (applyFiles, False) + + self.openFiles(newFile, pathOldFile) + if flagSymlink: + if os.path.exists(prevOldFile) or os.path.islink(prevOldFile): + if os.path.islink(prevOldFile): + # если ссылка то удаляем её + os.unlink(prevOldFile) + else: + # иначе удаляем файл + os.remove(prevOldFile) + if not "/" == pathOldFile[0]: + os.symlink(pathOldFile, prevOldFile) + applyFiles = [prevOldFile,os.path.join(pathLink,pathOldFile)] + else: + os.symlink(pathOldFile, prevOldFile) + applyFiles = [prevOldFile,pathOldFile] + if not objHeadNew.body.strip(): + return (applyFiles, False) + else: + applyFiles = [pathOldFile] + if pathProg: + os.chdir(pathProg) + # Если файлы заменяются не нужно их обрабатывать дальше + if objHeadNew.typeAppend == "replace" and\ + "symbolic" not in objHeadNew.params and\ + "link" in objHeadNew.params: + return (applyFiles, False) + return (applyFiles, objHeadNew) + + def createNewClass(self, name, bases, attrs={}): + """Создает объект нового класса + + createNewClass(self, name, bases, attrs) + name - имя класса - str, + bases - cписок наследуемых классов - (tuple), + attrs - аттрибуты класса - {dict} + """ + class newMethod: + #Объединяем конфигурации + def join(self, newObj): + if newObj.__class__.__name__ == self.__class__.__name__: + self.docObj.joinDoc(newObj.doc) + # Пост обработка + if 'postXML' in dir(self): + self.postXML() + attrsNew = {} + attrsNew["configName"] = name + if attrs: + for key in attrs.keys(): + attrsNew[key] = attrs[key] + newCl = type(name, bases + (newMethod, object,), attrsNew) + return newCl + + def fileIsUtf(self, fileName): + """Проверяет файл на кодировку UTF-8""" + if os.path.exists(fileName): + FD = open(self.absFileName(fileName)) + newProfile = FD.read() + FD.close() + try: + newProfile.decode("UTF-8") + except: + return False + return True + + def join(self, newFile, oldFile, ListOptTitle): + """Объединения профиля и конф. файла + + join(newFile, oldFile, ListOptTitle) + Объединение профиля newFile и конф. файла oldFile, + ListOptTitle - список строк которые добавятся в заголовок + """ + # Выполняем условия для блока текста а так-же заменяем переменные + self.nameFileNew = self.absFileName(newFile) + self.FN = self.openNewFile(self.nameFileNew) + self.newProfile = self.FN.read() + self.closeNewFile() + copyFile = True + if self.getFileType() != "bin": + # Вычисляем условные блоки + self.newProfile = self.applyTermsProfile(self.newProfile, + newFile, oldFile) + #print "|%s|" %(self.newProfile) + # Заменяем переменные на их значения + self.newProfile = self.applyVarsProfile(self.newProfile, + newFile) + # Вычисляем функции + self.newProfile = self.applyFuncProfile(self.newProfile, + newFile, oldFile) + copyFile = False + filesApply, objHeadNew = self.__getApplyHeadProfile(newFile, oldFile, + copyFile) + if not objHeadNew: + return filesApply + # Флаг - кодировка с бинарными примесями у файла профиля включаем при + # условии текстового файла и кодировки отличной от UTF-8 + flagNotUtf8New = False + # Флаг - кодировка с бинарными примесями у оригинального файла + flagNotUtf8Old = False + if not copyFile: + # проверяем кодировку профиля + if not self.fileIsUtf(newFile): + flagNotUtf8New = True + if not ("link" in objHeadNew.params and\ + "symbolic" in objHeadNew.params): + # проверяем кодировку оригинального файла + if not self.fileIsUtf(oldFile): + flagNotUtf8Old = True + self.newProfile = objHeadNew.body + #if objHeadNew.fileType != "bin": + #self.newProfile = self.applyTermsProfile(self.newProfile, + #newFile) + #self.newProfile = self.applyVarsProfile(self.newProfile) + + # Титл конфигурационного файла + title = "" + if ListOptTitle: + title = self.getTitle(objHeadNew.comment, + ListOptTitle) + title = title.encode("UTF-8") + + objHeadOld = False + if objHeadNew.comment: + objHeadOld = fileHeader(self.oldProfile, objHeadNew.comment) + # Тестирование + #print self.nameFileOld + #print objHeadNew.typeAppend + if objHeadNew.fileType: + # Создаем объект в случае параметра format в заголовке + if (objHeadNew.typeAppend == "replace" or\ + objHeadNew.typeAppend == "before" or\ + objHeadNew.typeAppend == "after") and\ + not (objHeadNew.fileType == "bin" or\ + objHeadNew.fileType == "raw"): + # Преобразовываем бинарные файлы + if flagNotUtf8New: + objTxtCoder = utfBin() + self.newProfile = objTxtCoder.encode(self.newProfile) + try: + objProfNew = eval("%s(self.newProfile)"%\ + (objHeadNew.fileType)) + except NameError: + #Создаем объект из self.newObjProt с помощью + # метаклассов + if objHeadNew.fileType in self.newObjProt: + objProfNewCl = self.createNewClass(\ + objHeadNew.fileType, + self.newObjProt[objHeadNew.fileType]) + objProfNew = objProfNewCl(self.newProfile) + else: + self.setError (\ + _("False join profile for type profile: ")\ + + objHeadNew.fileType + " : " +\ + newFile) + return False + + if "xml_" in objHeadNew.fileType: + if objProfNew.getError(): + self.setError (_("False profile: " ) + newFile) + return False + nameRootNode = oldFile.rpartition("/")[2].split(".")[0] + objProfNew.setNameBodyNode(nameRootNode) + # Объект Документ + docObj = objProfNew.docObj + # Удаление комментариев из документа + docObj.removeComment(docObj.getNodeBody()) + # Добавление необходимых переводов строк + docObj.insertBRtoBody(docObj.getNodeBody()) + # Добавление необходимых разделителей между областями + docObj.insertBeforeSepAreas(docObj.getNodeBody()) + # Пост обработка + if 'postXML' in dir(objProfNew): + objProfNew.postXML() + # Получение текстового файла из XML документа + self.newProfile = objProfNew.getConfig().encode("UTF-8") + # Если не UTF-8 производим преобразование + if flagNotUtf8New: + self.newProfile = objTxtCoder.decode(self.newProfile) + # Титл для объединения + if ListOptTitle: + title = self.getTitle(objProfNew._comment, + ListOptTitle) + title = title.encode("UTF-8") + # Замена + if objHeadNew.typeAppend == "replace": + if "xml_" in objHeadNew.fileType: + data = self.newProfile.split("\n") + data.insert(1,title) + self.oldProfile = "\n".join(data) + else: + if objHeadNew.execStr: + self.oldProfile = objHeadNew.execStr+title+\ + self.newProfile + else: + self.oldProfile = title + self.newProfile + self.saveOldFile() + return filesApply + # Впереди + elif objHeadNew.typeAppend == "before": + if "xml_" in objHeadNew.fileType: + self.setError (\ + _("False option append=before in profile %s") %newFile) + return False + if objHeadOld and objHeadOld.body: + self.oldProfile = objHeadOld.body + if self.newProfile[-1] == "\n": + tmpProfile = self.newProfile + self.oldProfile + else: + tmpProfile = self.newProfile + "\n" + self.oldProfile + if objHeadNew.execStr: + self.oldProfile = objHeadNew.execStr + title + tmpProfile + elif objHeadOld.execStr: + self.oldProfile = objHeadOld.execStr + title + tmpProfile + else: + self.oldProfile = title + tmpProfile + + #print self.oldProfile + self.saveOldFile() + return filesApply + # Cзади + elif objHeadNew.typeAppend == "after": + if "xml_" in objHeadNew.fileType: + self.setError (\ + _("False option append=after in profile %s") %newFile) + return False + if objHeadOld and objHeadOld.body: + self.oldProfile = objHeadOld.body + if self.newProfile[-1] == "\n": + tmpProfile = self.oldProfile + self.newProfile + else: + tmpProfile = self.oldProfile + "\n" + self.newProfile + if objHeadNew.execStr: + self.oldProfile = objHeadNew.execStr + title + tmpProfile + elif objHeadOld.execStr: + self.oldProfile = objHeadOld.execStr + title + tmpProfile + else: + self.oldProfile = title + tmpProfile + self.saveOldFile() + return filesApply + # Объединение + elif objHeadNew.typeAppend == "join": + if flagNotUtf8New: + objTxtCoder = utfBin() + self.newProfile = objTxtCoder.encode(self.newProfile) + try: + objProfNew = eval("%s(self.newProfile)"%\ + (objHeadNew.fileType)) + except NameError: + #Создаем объект из self.newObjProt с помощью + # метаклассов + if objHeadNew.fileType in self.newObjProt: + objProfNewCl = self.createNewClass(\ + objHeadNew.fileType, + self.newObjProt[objHeadNew.fileType]) + objProfNew = objProfNewCl(self.newProfile) + else: + self.setError (\ + _("False join profile for type profile: ")\ + + objHeadNew.fileType + " : " +\ + newFile) + return False + if "xml_" in objHeadNew.fileType: + if objProfNew.getError(): + self.setError (_("False profile: " ) + newFile) + return False + nameRootNode = oldFile.rpartition("/")[2].split(".")[0] + objProfNew.setNameBodyNode(nameRootNode) + # Титл для объединения + if ListOptTitle: + title = self.getTitle(objProfNew._comment, + ListOptTitle) + title = title.encode("UTF-8") + + # В случае пустого конфигурационного файла + reNoClean = re.compile("[^\s]",re.M) + if not self.oldProfile or\ + not reNoClean.search(self.oldProfile): + self.oldProfile = "" + #if objHeadNew.execStr: + #self.oldProfile = objHeadNew.execStr + \ + #title + objProfNew.getConfig().encode("UTF-8") + #else: + #self.oldProfile = title +\ + #objProfNew.getConfig().encode("UTF-8") + #self.saveOldFile() + #return True + + objHeadOld = fileHeader(self.oldProfile, objProfNew._comment) + if objHeadOld.body: + self.oldProfile = objHeadOld.body + else: + self.oldProfile = "" + if flagNotUtf8Old: + objTxtCoder = utfBin() + self.oldProfile = objTxtCoder.encode(self.oldProfile) + if objHeadNew.fileType in self.newObjProt: + objProfOldCl = self.createNewClass(\ + objHeadNew.fileType, + self.newObjProt[objHeadNew.fileType]) + objProfOld = objProfOldCl(self.oldProfile) + else: + objProfOld = eval("%s(self.oldProfile)"%\ + (objHeadNew.fileType)) + if "xml_" in objHeadNew.fileType: + if objProfOld.getError(): + self.setError (_("False profile: " ) + oldFile) + return False + nameRootNode = oldFile.rpartition("/")[2].split(".")[0] + objProfOld.setNameBodyNode(nameRootNode) + + #print "#%s#" %(objProfOld.docObj.body.toprettyxml()) + #print "#%s#" %(objProfNew.docObj.body.toprettyxml()) + objProfOld.join(objProfNew) + #print objProfOld.doc.toprettyxml() + #print objProfNew.doc.toprettyxml() + if "xml_" in objHeadNew.fileType: + if objProfOld.getError(): + self.setError (_("False profile: " ) + newFile) + return False + data = \ + objProfOld.getConfig().encode("UTF-8").split("\n") + data.insert(1,title) + self.oldProfile = "\n".join(data) + else: + if objHeadNew.execStr: + self.oldProfile = objHeadNew.execStr + title +\ + objProfOld.getConfig().encode("UTF-8") + elif objHeadOld.execStr: + self.oldProfile = objHeadOld.execStr + title +\ + objProfOld.getConfig().encode("UTF-8") + else: + self.oldProfile = title +\ + objProfOld.getConfig().encode("UTF-8") + # Декодируем если кодировка не UTF-8 + if flagNotUtf8New or flagNotUtf8Old: + self.newProfile = objTxtCoder.decode(self.newProfile) + self.oldProfile = objTxtCoder.decode(self.oldProfile) + self.saveOldFile() + return filesApply + else: + self.setError (_("False (type append) profile: " ) +\ + objHeadNew.typeAppend) + return False + else: + self.setError (_("Type profile not found: ") + newFile) + return False + return filesApply + +class samba(objShare): + """Класс для обработки конфигурационного файла типа samba + + """ + _comment = "#" + configName = "samba" + configVersion = "0.1" + reHeader = re.compile("^[\t ]*\[[^\[\]]+\].*\n",re.M) + reBody = re.compile(".+",re.M|re.S) + reComment = re.compile("\s*%s.*|\s*;.*"%(_comment)) + reSeparator = re.compile("\s*=\s*") + sepFields = "\n" + reSepFields = re.compile(sepFields) + + def __init__(self,text): + self.text = text + self.blocTextObj = blocText() + self._splitToFields = self.splitToFields + # Объект документ + self.docObj = self._textToXML() + # XML документ + self.doc = self.docObj.doc + + 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) + # Удаление лишних переводов строк + 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): + """Объединяем конфигурации""" + if isinstance(sambaObj, samba): + self.docObj.joinDoc(sambaObj.doc) + self.postXML() + + def setDataField(self, txtLines, endtxtLines): + """Создаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + z += 1 + findComment = self.reComment.search(textLine) + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + elif findComment: + field.comment = textLine + fields.append(field) + field = fieldData() + else: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len(nameValue) > 2: + valueList = nameValue[1:] + nameValue =[nameValue[0],"=".join(valueList)] + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + + + def splitCleanBloc(self, txtBloc): + """Делим блок на две части (переменные, пустые строки в конце)""" + txtLines = txtBloc.split("\n") + firstBloc = [] + nextBloc = [] + txtLines.reverse() + z = 0 + for txtLine in txtLines: + if not txtLine.strip(): + nextBloc.append(txtLine) + else: + break + z += 1 + txtLines.reverse() + firstBloc = txtLines[:-z] + nextBloc.reverse() + if nextBloc: + firstBloc.append("") + if nextBloc and "\n".join(nextBloc): + return ("\n".join(firstBloc), "\n".join(nextBloc)) + else: + return False + + def getFullAreas(self, blocs): + """Делит текст на области, (Заголовок, тело) + + Возвращает два списка: заголовки, тела + """ + headsAreas = [] + bodyAreas = [] + if not blocs: + return [] + lenBlocs = len(blocs[0]) + for i in range(lenBlocs): + txtBloc = blocs[1][i] + clean = self.splitCleanBloc(txtBloc) + if clean: + headsAreas.append(blocs[0][i]) + bodyAreas.append(clean[0]) + headsAreas.append("") + bodyAreas.append(clean[1]) + else: + headsAreas.append(blocs[0][i]) + bodyAreas.append(blocs[1][i]) + return (headsAreas, bodyAreas) + + def createTxtConfig(self, strHeader, dictVar): + """Cоздает область с заголовком + + создает текст конфигурационного файла в формате samba из + заголовка (строка) и словаря переменных + """ + if not strHeader: + return "" + outTxt = "[" + strHeader + "]\n" + for key in dictVar.keys(): + outTxt += "%s = %s\n" %(key,dictVar[key]) + return outTxt + + def _textToXML(self): + """Преобразует текст в XML""" + blTmp = self.blocTextObj.findBloc(self.text,self.reHeader,self.reBody) + blocs = self.getFullAreas(blTmp) + headers = [] + startHeaders = [] + finHeaders = [] + docObj = xmlDoc() + docObj.createDoc(self.configName, self.configVersion) + rootNode = docObj.getNodeBody() + # Если пустой текст то создаем пустой документ + if not blocs: + return docObj + + for h in blocs[0]: + listfinH = h.split("]") + finH = listfinH[0] + if "[" in finH: + startHeaders.append(finH + "]") + else: + startHeaders.append(finH) + if len(listfinH) == 2: + finHeaders.append(listfinH[1]) + else: + finHeaders.append("") + headers.append(finH.replace("[","").replace("]","").strip()) + bodys = blocs[1] + + z = 0 + for h in headers: + if not bodys[z]: + z += 1 + continue + areaAction = False + if h: + if h[0] == "!": + docObj.createCaption(h[1:], [startHeaders[z],""]) + areaAction = "drop" + elif h[0] == "-": + docObj.createCaption(h[1:], [startHeaders[z],""]) + areaAction = "replace" + else: + docObj.createCaption(h, [startHeaders[z],""]) + else: + docObj.createCaption(h, [startHeaders[z],""]) + + if "\n" in blocs[0][z]: + if self.reComment.search(finHeaders[z]): + docObj.createField('comment', [finHeaders[z]]) + elif not finHeaders[z].strip() and\ + finHeaders[z].replace("\n",""): + docObj.createField('br', + [finHeaders[z].replace("\n","")]) + else: + docObj.createField('br') + fields = self._splitToFields(bodys[z]) + for f in fields: + if f.name != False and f.value!=False and f.br!=False: + # Обработка условий для samba + if f.name[0] == "!" or f.name[0] == "-" or\ + f.name[0] == "+": + qns = self.removeSymbolTerm(f.br) + xmlField = docObj.createField("var", + [qns], + f.name[1:], [f.value]) + if f.name[0] == "!": + # Удаляемое в дальнейшем поле + docObj.setActionField(xmlField, "drop") + else: + docObj.createField("var",[f.br.replace("\n","")], + f.name, [f.value]) + docObj.createField('br') + elif f.comment != False: + docObj.createField('comment', [f.comment]) + elif f.br != False: + docObj.createField('br', [f.br.replace("\n","")]) + if h.strip(): + area = docObj.createArea() + if areaAction: + docObj.setActionArea(area, areaAction) + rootNode.appendChild(area) + else: + fieldsNodes = docObj.tmpFields.getFields() + for fieldNode in fieldsNodes: + rootNode.appendChild(fieldNode) + docObj.clearTmpFields() + z += 1 + #print docObj.doc.toprettyxml() + return docObj + +class compiz(samba): + """Класс для обработки конфигурационного файла типа compiz + + """ + _comment = "#" + configName = "compiz" + configVersion = "0.1" + reHeader = re.compile("^[\t ]*\[[^\[\]]+\].*\n",re.M) + reBody = re.compile(".+",re.M|re.S) + reComment = re.compile("\s*%s.*"%(_comment)) + reSeparator = re.compile("\s*=\s*") + sepFields = "\n" + reSepFields = re.compile(sepFields) + + def __init__(self,text): + samba.__init__(self,text) + + def join(self, compizObj): + """Объединяем конфигурации""" + if isinstance(compizObj, compiz): + self.docObj.joinDoc(compizObj.doc) + self.postXML() + +class bind(objShare): + """Класс для обработки конфигурационного файла типа bind + + """ + _comment = "//" + configName = "bind" + configVersion = "0.1" + __openArea = "{" + __closeArea = "[ \t]*\}[ \t]*;[ \t]*" + sepFields = ";" + reOpen = re.compile(__openArea) + reClose = re.compile(__closeArea) + reCloseArea = re.compile(__closeArea + "\s*\Z") + reComment = re.compile("[ \t]+%s|^%s|(?<=;)%s"%(_comment,_comment,_comment)) + reSepFields = re.compile(sepFields) + reSeparator = re.compile("[ \t]+") + + def __init__(self,text): + self.text = text + self.blocTextObj = blocText() + # Объект документ + self.docObj = self.textToXML() + # Создаем поля-массивы + self.docObj.postParserList() + # XML документ + self.doc = self.docObj.doc + + # Делим область на составные части + def findOpenClose(self, text, reOpen, reClose, reComment): + """Делит область на составные части + + начальный текстовый блок, + открывающий блок, + блок-тело, + закрывающий блок + """ + firstBloc = "" + startBloc = "" + bodyBloc = "" + endBloc = "" + textLines = text.splitlines() + findOpen = False + if textLines: + findOpen = reOpen.search(textLines[0]) + openBl = reOpen.search(text) + if findOpen and reComment.split(text)[0].strip(): + blocA = text[openBl.end():] + firstBloc = text[:openBl.start()] + startBloc = text[openBl.start():openBl.end()] + closeBl = reClose.search(blocA) + endBloc = blocA[closeBl.start():closeBl.end()] + bodyBloc = blocA[:closeBl.start()] + return (firstBloc, startBloc, bodyBloc, endBloc) + else: + return (firstBloc, startBloc, text, endBloc) + + + # Делим текст на области включая вложенные (areas массив областей) + def splitToAllArea(self, text, areas, reOpen, reClose, reCloseArea, + reComment, reSepFields): + """Делит текст на области включая вложенные + + возвращает список объектов областей (переменная areas) + """ + class area: + def __init__(self): + self.header = False + self.start = False + self.fields = [] + self.end = False + + blocs = self.blocTextObj.splitTxtToBloc(text,reOpen,reClose, + reComment,reSepFields) + for i in blocs: + areaA = area() + first,start,body,end = self.findOpenClose(i, reOpen, reCloseArea, + reComment) + areaA.header = first.replace(" ","").replace("\t","") + areaA.start = first + start + areaA.end = end + + if areaA.end: + blocsA = self.blocTextObj.splitTxtToBloc(body,reOpen,reClose, + reComment,reSepFields) + if blocsA and blocsA[0] == body: + areaA.fields.append(body) + areas.append(areaA) + else: + for ar in blocsA: + self.splitToAllArea(ar, areaA.fields, reOpen, + reClose, + reCloseArea, reComment, + reSepFields) + areas.append(areaA) + else: + areaA.fields.append(body) + areas.append(areaA) + return areas + + + def setDataField(self, txtLines, endtxtLines): + """Создаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + z += 1 + findComment = self.reComment.search(textLine) + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + elif findComment: + field.comment = textLine + fields.append(field) + field = fieldData() + else: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len (nameValue) == 1: + field.name = "" + field.value = textLine.replace(self.sepFields,"") + field.br = textLine + fields.append(field) + field = fieldData() + + if len(nameValue) > 2: + valueList = nameValue[1:] + nameValue =[nameValue[0]," ".join(valueList).replace(\ + self.sepFields,"")] + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + + def createCaptionTerm(self, header, start, end, docObj): + """Создание пустой области с заголовком + + при создании области проверяется первый символ заголовка + и добавляется тег action + "!" - drop + "-" - replace + """ + areaAction = False + if header: + if header[0] == "!": + docObj.createCaption(header[1:], [start, + end.replace("\n","")]) + areaAction = "drop" + elif header[0] == "-": + docObj.createCaption(header[1:], [start, + end.replace("\n","")]) + areaAction = "replace" + else: + docObj.createCaption(header, [start, + end.replace("\n","")]) + else: + docObj.createCaption(header, [start, + end.replace("\n","")]) + + areaXML = docObj.createArea() + if areaAction: + docObj.setActionArea(areaXML, areaAction) + return areaXML + + def createXML(self, areas, rootNode, docObj): + """Создаем из массивов областей XML""" + for i in areas: + if str(i.__class__.__name__) == "area": + if i.header and i.start: + areaXML = self.createCaptionTerm(i.header, i.start, + i.end.replace("\n",""), + docObj) + else: + areaXML = rootNode + for f in i.fields: + if str(f.__class__.__name__) == "area": + if f.header and f.start: + areaXMLChild = self.createCaptionTerm(f.header, + f.start, + f.end.replace("\n",""), + docObj) + + self.createXML(f.fields, areaXMLChild, docObj) + + areaXML.appendChild(areaXMLChild) + else: + self.createXML(f.fields, areaXML, docObj) + if "\n" in f.end: + fieldXMLBr = docObj.createField("br",[], + "",[], + False, False) + areaXML.appendChild(fieldXMLBr) + else: + if not f: + continue + fields = self.splitToFields(f) + for field in fields: + if field.name != False: + fieldXML = self.createFieldTerm(field.name, + field.value, + field.br, docObj) + areaXML.appendChild(fieldXML) + if field.br[-1] == "\n": + fieldXMLBr = docObj.createField("br",[], + "",[], + False, False) + areaXML.appendChild(fieldXMLBr) + elif field.comment != False: + fieldXML = docObj.createField("comment", + [field.comment], + "", [], + False, False) + areaXML.appendChild(fieldXML) + elif field.br != False: + brText = field.br.replace("\n","") + if brText: + fieldXML = docObj.createField('br', + [brText], + "", [], + False, False) + else: + fieldXML = docObj.createField('br', + [], + "", [], + False, False) + areaXML.appendChild(fieldXML) + + if i.header and i.start: + rootNode.appendChild(areaXML) + if "\n" in i.end: + fieldXMLBr = docObj.createField("br",[], + "",[], + False, False) + rootNode.appendChild(fieldXMLBr) + + else: + fields = self.splitToFields(i) + for field in fields: + if field.name != False: + fieldXML = self.createFieldTerm(field.name, + field.value, + field.br, docObj) + rootNode.appendChild(fieldXML) + if field.br[-1] == "\n": + fieldXMLBr = docObj.createField("br",[],"", [], + False, False) + rootNode.appendChild(fieldXMLBr) + elif field.comment != False: + fieldXML = docObj.createField("comment", + [field.comment], + "", [], + False, False) + rootNode.appendChild(fieldXML) + elif field.br != False: + brText = field.br.replace("\n","") + if brText: + fieldXML = docObj.createField('br', [brText],"",[], + False, False) + else: + fieldXML = docObj.createField('br', [], "", [], + False, False) + rootNode.appendChild(fieldXML) + #rootNode.appendChild(areaXML) + + def textToXML(self): + """Преобразуем текст в XML""" + areas = [] + if self.text.strip(): + self.splitToAllArea(self.text, areas, self.reOpen, self.reClose, + self.reCloseArea,self.reComment,self.reSepFields) + docObj = xmlDoc() + # Создание объекта документ c пустым разделителем между полями + docObj.createDoc(self.configName, self.configVersion) + if not areas: + return docObj + self.createXML(areas, docObj.getNodeBody(), docObj) + return docObj + + + def join(self, bindObj): + """Объединяем конфигурации""" + if isinstance(bindObj, bind): + self.docObj.joinDoc(bindObj.doc) + +class apache(bind): + """Класс для обработки конфигурационного файла типа apache + + """ + _comment = "#" + configName = "apache" + configVersion = "0.1" + __headerArea = "[^\<\> \t]+[ \t]+[^\<\> \t]+" + __openArea = "[ \t]*\<%s\>"%(__headerArea) + __closeArea = "[ \t]*\<\/[^\<\>]+\>" + sepFields = "\n" + reOpen = re.compile(__openArea) + reClose = re.compile(__closeArea) + reCloseArea = re.compile(__closeArea + "\s*\Z") + reComment = re.compile("[ \t]*%s"%(_comment)) + reSepFields = re.compile(sepFields) + reSeparator = re.compile("[ \t]+") + reHeader = re.compile(__headerArea) + + def __init__(self,text): + self.text = text + self.blocTextObj = blocText() + # Объект документ + self.docObj = self.textToXML() + # Создаем поля-массивы + self.docObj.postParserList() + # Создаем поля разделенные массивы + self.docObj.postParserListSeplist(self.docObj.body) + # XML документ + self.doc = self.docObj.doc + + def postXML(self): + """Последующая постобработка XML""" + # Для добавления перевода строки перед закрывающим тегом + # конфигурационного файла + xmlFields = xpath.Evaluate("child::fields", self.docObj.body) + if not (xmlFields and\ + self.docObj.getTypeField(xmlFields[-1]) == "br"): + self.docObj.body.appendChild(self.docObj.createField("br", + [],"",[], + False,False)) + xmlAreas = xpath.Evaluate("child::area", self.docObj.body) + for xmlArea in xmlAreas: + xmlFields = xpath.Evaluate("child::field", xmlArea) + if not (xmlFields and\ + self.docObj.getTypeField(xmlFields[-1]) == "br"): + xmlArea.appendChild(self.docObj.createField("br", + [],"",[], + False,False)) + + def join(self, apacheObj): + """Объединяем конфигурации""" + if isinstance(apacheObj, apache): + #print self.docObj.doc.toprettyxml() + self.docObj.joinDoc(apacheObj.doc) + self.postXML() + + # Делим область на составные части + def findOpenClose(self, text, reOpen, reClose, reComment, reHeader): + """Делит область на составные части + + начальный текстовый блок, + открывающий блок, + блок-тело, + закрывающий блок + """ + firstBloc = "" + startBloc = "" + bodyBloc = "" + endBloc = "" + textLines = text.splitlines() + findOpen = False + if textLines: + findOpen = reOpen.search(textLines[0]) + openBl = reOpen.search(text) + if findOpen and reComment.split(text)[0].strip(): + blocA = text[openBl.end():] + firstBloc = "" + startBloc = text[openBl.start():openBl.end()] + headBl = reHeader.search(startBloc) + if headBl: + firstBloc = headBl.group(0) + closeBl = reClose.search(blocA) + endBloc = blocA[closeBl.start():closeBl.end()] + bodyBloc = blocA[:closeBl.start()] + return (firstBloc, startBloc, bodyBloc, endBloc) + else: + return (firstBloc, startBloc, text, endBloc) + + # Делим текст на области включая вложенные (areas массив областей) + def splitToAllArea(self, text, areas, reOpen, reClose, reCloseArea, + reComment, reSepFields, reHeader): + """Делит текст на области включая вложенные + + возвращает список объектов областей (переменная areas) + """ + class area: + def __init__(self): + self.header = False + self.start = False + self.fields = [] + self.end = False + + blocs = self.blocTextObj.splitTxtToBloc(text,reOpen,reClose, + reComment,reSepFields) + for i in blocs: + areaA = area() + first,start,body,end = self.findOpenClose(i, reOpen, reCloseArea, + reComment, reHeader) + areaA.header = first.replace(" ","").replace("\t","") + areaA.start = start + areaA.end = end + + if areaA.end: + blocsA = self.blocTextObj.splitTxtToBloc(body,reOpen,reClose, + reComment,reSepFields) + if blocsA and blocsA[0] == body: + areaA.fields.append(body) + areas.append(areaA) + else: + for ar in blocsA: + self.splitToAllArea(ar, areaA.fields, reOpen, + reClose, + reCloseArea, reComment, + reSepFields, reHeader) + areas.append(areaA) + else: + areaA.fields.append(body) + areas.append(areaA) + + + def setDataField(self, txtLines, endtxtLines): + """Создаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + #print "#"+brBloc[z]+"#" + z += 1 + findComment = self.reComment.search(textLine) + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + elif findComment: + field.comment = textLine + fields.append(field) + field = fieldData() + else: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len (nameValue) == 1: + field.name = "" + field.value = textLine.replace(self.sepFields,"") + field.br = textLine + fields.append(field) + field = fieldData() + + if len(nameValue) == 3: + valueList = nameValue[2:] + nameValue =["".join(nameValue[:2])," ".join(valueList)] + + if len(nameValue) > 3: + valueList = nameValue[1:] + nameValue =[nameValue[0]," ".join(valueList).replace(\ + self.sepFields,"")] + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + + + def textToXML(self): + """Преобразуем тект в XML""" + areas = [] + self.splitToAllArea(self.text, areas, self.reOpen, self.reClose, + self.reCloseArea,self.reComment,self.reSepFields, + self.reHeader) + docObj = xmlDoc() + + # Создание объекта документ c пустым разделителем между полями + docObj.createDoc(self.configName, self.configVersion) + if not areas: + return docObj + self.createXML(areas, docObj.getNodeBody(), docObj) + return docObj + +class postfix(apache): + """Класс для обработки конфигурационного файла типа postfix + + """ + _comment = "#" + configName = "postfix" + configVersion = "0.1" + sepFields = "\n" + reComment = re.compile("[ \t]*%s"%(_comment)) + reSepFields = re.compile(sepFields) + # разделитель названия и значения переменной + reSeparator = re.compile("\s*=\s*") + def __init__(self,text): + self.text = text + # Объект документ + self.docObj = self.textToXML() + # Создаем поля разделенные массивы + self.docObj.postParserListSeplist(self.docObj.body) + # XML документ + self.doc = self.docObj.doc + + def join(self, postfixObj): + """Объединяем конфигурации""" + if isinstance(postfixObj, postfix): + self.docObj.joinDoc(postfixObj.doc) + + def textToXML(self): + """Преобразуем текст в XML""" + class area: + def __init__(self): + self.header = False + self.start = False + self.fields = [] + self.end = False + areas = [] + oneArea = area() + oneArea.header = "" + oneArea.start = "" + oneArea.fields = [self.text] + oneArea.end = "" + areas.append(oneArea) + docObj = xmlDoc() + # Создание объекта документ c пустым разделителем между полями + docObj.createDoc(self.configName, self.configVersion) + if not areas: + return docObj + self.createXML(areas, docObj.getNodeBody(), docObj) + return docObj + + + def setDataField(self, txtLines, endtxtLines): + """Cоздаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + #print "#"+brBloc[z]+"#" + z += 1 + findComment = self.reComment.search(textLine) + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + elif findComment: + field.comment = textLine + fields.append(field) + field = fieldData() + else: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len (nameValue) == 1: + field.name = "" + field.value = textLine.replace(self.sepFields,"") + field.br = textLine + fields.append(field) + field = fieldData() + + if len(nameValue) > 2: + valueList = nameValue[1:] + nameValue =[nameValue[0],"=".join(valueList).replace(\ + self.sepFields,"")] + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + +class ldap(samba): + """Класс для обработки конфигурационного файла типа ldap + + """ + _comment = "#" + configName = "ldap" + configVersion = "0.1" + # Регулярное выражение для заголовка области + reHeader = re.compile("^[\t ]*(access|syncrepl)[^\n]+\n?") + # Регулярное выражения для области + reArea = re.compile("([\t ]*(access|syncrepl)[^\n]+\ +\n([\t ]+[^\n]+\n?)+)",re.M|re.S) + reComment = re.compile("\s*%s.*"%(_comment)) + # разделитель между переменной и значением переменной + reSeparator = re.compile("\s+|\s*=\s*") + # разделитель полей + sepFields = "\n" + # регулярное выражение для разделителя полей + reSepFields = re.compile(sepFields) + + def __init__(self,text): + self.text = text + self.blocTextObj = blocText() + self._splitToFields = self.splitToFields + # Объект документ + self.docObj = self._textToXML() + # Создаем поля-массивы + self.docObj.postParserList() + # Создаем поля разделенные массивы + self.docObj.postParserListSeplist(self.docObj.body) + # XML документ + self.doc = self.docObj.doc + + def join(self, ldapObj): + """Объединяем конфигурации""" + if isinstance(ldapObj, ldap): + self.docObj.joinDoc(ldapObj.doc) + + def setDataField(self, txtLines, endtxtLines): + """Создаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + z += 1 + findComment = self.reComment.search(textLine) + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + elif findComment: + field.comment = textLine + fields.append(field) + field = fieldData() + else: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len(nameValue) > 2: + valueList = nameValue[2:] + nameValue =[nameValue[0]+nameValue[1]," ".join(valueList)] + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + + def _textToXML(self): + """Преобразует текст в XML""" + blTmp = self.blocTextObj.findArea(self.text,self.reHeader,self.reArea) + blocs = self.getFullAreas(blTmp) + headers = [] + startHeaders = [] + finHeaders = [] + docObj = xmlDoc() + docObj.createDoc(self.configName, self.configVersion) + rootNode = docObj.getNodeBody() + # Если пустой текст то создаем пустой документ + if not blocs: + return docObj + + for h in blocs[0]: + headers.append(h.rstrip()) + bodys = blocs[1] + + z = 0 + for h in headers: + if not bodys[z]: + z += 1 + continue + areaAction = False + if h: + if h[0] == "!": + header = self.removeSymbolTerm(h.strip()) + headerQuote = self.removeSymbolTerm(h) + docObj.createCaption(header,[headerQuote,""]) + areaAction = "drop" + elif h[0] == "-": + header = self.removeSymbolTerm(h.strip()) + headerQuote = self.removeSymbolTerm(h) + docObj.createCaption(header,[headerQuote,""]) + areaAction = "replace" + else: + docObj.createCaption(h.strip(), [h.rstrip(),""]) + else: + docObj.createCaption(h.strip(), [h.rstrip(),""]) + + if "\n" in blocs[0][z]: + resHead = self.reComment.search(h) + if resHead: + docObj.createField('comment', + blocs[0][z][resHead.start():]) + else: + docObj.createField('br') + + fields = self._splitToFields(bodys[z]) + for f in fields: + if f.name != False and f.value!=False and f.br!=False: + # Обработка условий для samba + if f.name[0] == "!" or f.name[0] == "-" or\ + f.name[0] == "+": + qns = self.removeSymbolTerm(f.br) + xmlField = docObj.createField("var", + [qns], + f.name[1:], [f.value]) + if f.name[0] == "!": + # Удаляемое в дальнейшем поле + docObj.setActionField(xmlField, "drop") + elif f.name[0] == "+": + # Добавляем уникальное поле + xmlField.setAttribute("type", "seplist") + docObj.setActionField(xmlField, "join") + else: + docObj.createField("var",[f.br.replace("\n","")], + f.name, [f.value]) + docObj.createField('br') + elif f.comment != False: + docObj.createField('comment', [f.comment]) + elif f.br != False: + docObj.createField('br', [f.br.replace("\n","")]) + if h.strip(): + area = docObj.createArea() + if areaAction: + docObj.setActionArea(area, areaAction) + rootNode.appendChild(area) + else: + fieldsNodes = docObj.tmpFields.getFields() + for fieldNode in fieldsNodes: + rootNode.appendChild(fieldNode) + docObj.clearTmpFields() + z += 1 + #print docObj.doc.toprettyxml() + return docObj + +class dovecot(bind): + """Класс для обработки конфигурационного файла типа dovecot + + """ + _comment = "#" + configName = "dovecot" + configVersion = "0.1" + __openArea = "{" + __closeArea = "[ \t]*\}[ \t]*" + sepFields = "\n" + reOpen = re.compile(__openArea) + reClose = re.compile(__closeArea) + reCloseArea = re.compile(__closeArea + "\s*\Z") + reComment = re.compile("[ \t]*%s" %(_comment)) + reSepFields = re.compile(sepFields) + # разделитель названия и значения переменной + reSeparator = re.compile("\s*=\s*") + + def __init__(self, text): + bind.__init__(self,text) + + def postXML(self, xmlArea=False): + """Последующая постобработка XML""" + # Добавляем перевод строки если его нет в конец области + if not xmlArea: + xmlArea = self.docObj.body + xmlFields = xpath.Evaluate("child::field", xmlArea) + if xmlFields and not (\ + self.docObj.getTypeField(xmlFields[-1]) == "br" or\ + self.docObj.getTypeField(xmlFields[-1]) == "comment"): + xmlArea.appendChild(self.docObj.createField("br", + [],"",[], + False,False)) + xmlAreas = xpath.Evaluate("child::area", xmlArea) + for area in xmlAreas: + self.postXML(area) + + def join(self, dovecotObj): + """Объединяем конфигурации""" + if isinstance(dovecotObj, dovecot): + #print self.docObj.doc.toprettyxml() + self.docObj.joinDoc(dovecotObj.doc) + # Для добавления перевода строки перед закрывающим тегом + # конфигурационного файла + self.postXML() + + def setDataField(self, txtLines, endtxtLines): + """Создаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + z += 1 + findComment = self.reComment.search(textLine) + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + elif findComment: + field.comment = textLine + fields.append(field) + field = fieldData() + else: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len (nameValue) == 1 and \ + ( nameValue[0].startswith("!include") or + nameValue[0][1:].startswith("!include")): + field.name = textLine.replace(self.sepFields,"") + field.value = "" + field.br = textLine + fields.append(field) + field = fieldData() + elif len (nameValue) == 1: + field.name = "" + field.value = textLine.replace(self.sepFields,"") + field.br = textLine + fields.append(field) + field = fieldData() + + elif len(nameValue) > 2: + valueList = nameValue[1:] + nameValue =[nameValue[0]," ".join(valueList).replace(\ + self.sepFields,"")] + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + + def createFieldTerm(self, name, value, quote, docObj): + """Создание поля переменная - значение + + при создании поля проверяется первый символ названия переменной + и добавляется тег action + "!" - drop удаляет + "+" - join добавляет + "-" - replace заменяет + """ + fieldAction = False + if name: + if name.startswith("!include") or name[1:].startswith("!include"): + prefix = "!" + name = re.sub(r"(include)\s*(\S)",r"\1 \2", name[1:]) + else: + prefix = "" + if name[0] == "!" or name[0] == "-" or name[0] == "+": + qnt = self.removeSymbolTerm(quote) + fieldXML = docObj.createField("var",[qnt], + prefix+name[1:], [value], + False, False) + if name[0] == "!": + fieldAction = "drop" + elif name[0] == "+": + fieldXML.setAttribute("type", "seplist") + fieldAction = "join" + else: + fieldXML = docObj.createField("var", + [quote.replace("\n","")], + prefix+name, [value], + False, False) + else: + fieldXML = docObj.createField("var", + [quote.replace("\n","")], + name, [value], + False, False) + if fieldAction: + docObj.setActionField(fieldXML, fieldAction) + return fieldXML + +class procmail(objShare): + """Класс для обработки конфигурационного файла типа procmail + + """ + _comment = "#" + configName = "procmail" + configVersion = "0.1" + sepFields = "\n" + reComment = re.compile("[ \t]*%s" %(_comment)) + reSepFields = re.compile(sepFields) + # разделитель названия и значения переменной + reSeparator = re.compile("=") + def __init__(self, text): + self.text = text + self.docObj = self.textToXML() + self.doc = self.docObj.doc + + def setDataField(self, txtLines, endtxtLines): + """Создаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + z += 1 + findComment = self.reComment.search(textLine) + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + elif findComment: + field.comment = textLine + fields.append(field) + field = fieldData() + else: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + + def textToXML(self): + docObj = xmlDoc() + docObj.createDoc(self.configName, self.configVersion) + if self.text: + nodeBody = docObj.getNodeBody() + fields = self.splitToFields(self.text) + for field in fields: + if field.name != False: + fieldXML = self.createFieldTerm(field.name, + field.value, + field.br, docObj) + nodeBody.appendChild(fieldXML) + if field.br[-1] == "\n": + fieldXMLBr = docObj.createField("br",[], + "",[], + False, False) + nodeBody.appendChild(fieldXMLBr) + elif field.comment != False: + fieldXML = docObj.createField("comment", + [field.comment], + "", [], + False, False) + nodeBody.appendChild(fieldXML) + elif field.br != False: + brText = field.br.replace("\n","") + if brText: + fieldXML = docObj.createField('br', + [brText], + "", [], + False, False) + else: + fieldXML = docObj.createField('br', + [], + "", [], + False, False) + nodeBody.appendChild(fieldXML) + return docObj + + def join(self, procmailObj): + """Объединяем конфигурации""" + if isinstance(procmailObj, procmail): + #print self.docObj.doc.toprettyxml() + self.docObj.joinDoc(procmailObj.doc) + +class kde(samba): + """Класс для обработки конфигурационного файла типа kde + + """ + _comment = "#" + configName = "kde" + configVersion = "0.1" + reHeader = re.compile("^[\t ]*\[[^\[\]]+\].*\n?",re.M) + reBody = re.compile(".+",re.M|re.S) + reComment = re.compile("^\s*%s.*"%(_comment)) + reSeparator = re.compile("=") + sepFields = "\n" + reSepFields = re.compile(sepFields) + + def __init__(self,text): + samba.__init__(self,text) + + + def _textToXML(self): + """Преобразует текст в XML""" + blTmp = self.blocTextObj.findBloc(self.text,self.reHeader,self.reBody) + blocs = self.getFullAreas(blTmp) + headers = [] + startHeaders = [] + finHeaders = [] + docObj = xmlDoc() + docObj.createDoc(self.configName, self.configVersion) + rootNode = docObj.getNodeBody() + # Если пустой текст то создаем пустой документ + if not blocs: + return docObj + + for h in blocs[0]: + reH = re.compile("]\s*$") + #listfinH = h.split("]") + listfinH = reH.split(h) + finH = listfinH[0] + if "[" in finH: + startHeaders.append(finH + "]") + else: + startHeaders.append(finH) + if len(listfinH) == 2: + finHeaders.append(listfinH[1]) + else: + finHeaders.append("") + head=finH.replace("][",".").replace("[","").replace("]","").strip() + headers.append(head) + bodys = blocs[1] + + z = 0 + for h in headers: + if not bodys[z]: + z += 1 + continue + areaAction = False + if h: + if h[0] == "!": + docObj.createCaption(h[1:], [startHeaders[z],""]) + areaAction = "drop" + elif h[0] == "-": + docObj.createCaption(h[1:], [startHeaders[z],""]) + areaAction = "replace" + else: + docObj.createCaption(h, [startHeaders[z],""]) + else: + docObj.createCaption(h, [startHeaders[z],""]) + + if "\n" in blocs[0][z]: + if self.reComment.search(finHeaders[z]): + docObj.createField('comment', [finHeaders[z]]) + elif not finHeaders[z].strip() and\ + finHeaders[z].replace("\n",""): + docObj.createField('br', + [finHeaders[z].replace("\n","")]) + else: + docObj.createField('br') + fields = self._splitToFields(bodys[z]) + for f in fields: + if f.name != False and f.value!=False and f.br!=False: + # Обработка условий для samba + if f.name[0] == "!" or f.name[0] == "-" or\ + f.name[0] == "+": + qns = self.removeSymbolTerm(f.br) + xmlField = docObj.createField("var", + [qns], + f.name[1:], [f.value]) + if f.name[0] == "!": + # Удаляемое в дальнейшем поле + docObj.setActionField(xmlField, "drop") + else: + docObj.createField("var",[f.br.replace("\n","")], + f.name, [f.value]) + docObj.createField('br') + elif f.comment != False: + docObj.createField('comment', [f.comment]) + elif f.br != False: + docObj.createField('br', [f.br.replace("\n","")]) + if h.strip(): + area = docObj.createArea() + if areaAction: + docObj.setActionArea(area, areaAction) + rootNode.appendChild(area) + else: + fieldsNodes = docObj.tmpFields.getFields() + for fieldNode in fieldsNodes: + rootNode.appendChild(fieldNode) + docObj.clearTmpFields() + z += 1 + #print docObj.doc.toprettyxml() + return docObj + + def join(self, kdeObj): + """Объединяем конфигурации""" + if isinstance(kdeObj, kde): + self.docObj.joinDoc(kdeObj.doc) + self.postXML() + + +class xmlDocPlasma: + """Класс для замены метода joinArea в xmlDoc для plasma""" + # заменяемый метод для xmlDoc + def joinArea(self, baseNode, xmlNewArea): + """Объединяет область c областью Body (xmlNewArea c baseNode)""" + def appendArea(baseNode, xmlNewArea): + fieldsRemove = xpath.Evaluate(\ + "descendant::field[child::action='drop']", xmlNewArea) + for rmNode in fieldsRemove: + parentNode = rmNode.parentNode + parentNode.removeChild(rmNode) + captionAreasRemove = xpath.Evaluate(\ + "descendant::area/child::caption[child::action='drop']", + xmlNewArea) + for rmNodeCapt in captionAreasRemove: + rmNode = rmNodeCapt.parentNode + parentNode = rmNode.parentNode + parentNode.removeChild(rmNode) + self.setActionArea(xmlNewArea, "append") + # Добавляем разделитель областей во вложенные области + areaNodes = xpath.Evaluate('descendant::area',xmlNewArea) + for areaNode in areaNodes: + self.setActionArea(areaNode,"append") + parentNode = areaNode.parentNode + parentNode.insertBefore(self.sepAreas.cloneNode(True), + areaNode) + baseNode.appendChild(xmlNewArea) + # Добавляем разделитель областей + baseNode.insertBefore(self.sepAreas.cloneNode(True), xmlNewArea) + + nodesNames = xpath.Evaluate('child::area/caption/name',baseNode) + nodesNewArea = xpath.Evaluate('child::caption/name',xmlNewArea) + if not nodesNames: + # Добавляем область + if nodesNewArea: + newAreaAction = self.getActionArea(xmlNewArea) + if not (newAreaAction == "drop"): + appendArea(baseNode, xmlNewArea) + return True + if not nodesNames or not nodesNewArea: + return False + nameArea = "" + if nodesNewArea[0].firstChild: + nameArea = nodesNewArea[0].firstChild.nodeValue.strip() + flagFindArea = False + baseNodes = [] + for oName in nodesNames: + newAreaAction = self.getActionArea(xmlNewArea) + oArea = oName.parentNode.parentNode + oNameTxt = "" + if oName.firstChild: + oNameTxt = oName.firstChild.nodeValue + if nameArea == oNameTxt: + flagFindArea = True + # При использовании удаления + if newAreaAction == "drop": + prevNode = oName.parentNode.parentNode.previousSibling + removePrevNodes = [] + while (prevNode) and self.getTypeField(prevNode) == "br": + removePrevNodes.append(prevNode) + prevNode = prevNode.previousSibling + for removeNode in removePrevNodes: + baseNode.removeChild(removeNode) + baseNode.removeChild(oName.parentNode.parentNode) + continue + elif newAreaAction == "replace": + oldAreaNode = oName.parentNode.parentNode + newAreaCaption = xpath.Evaluate('child::caption', + xmlNewArea)[0] + oldAreaCaption = xpath.Evaluate('child::caption', + oldAreaNode)[0] + if newAreaCaption and oldAreaCaption: + xmlNewArea.replaceChild(oldAreaCaption,newAreaCaption) + self.setActionArea(xmlNewArea,"replace") + baseNode.replaceChild(xmlNewArea, + oldAreaNode) + continue + baseNodes.append(oName.parentNode.parentNode) + + # Заменяем QUOTE + oldAreaNode = oName.parentNode.parentNode + oldAreaQuote = xpath.Evaluate('child::caption/quote', + oldAreaNode)[0] + if oldAreaQuote and\ + not oldAreaQuote.firstChild: + newAreaQuote = xpath.Evaluate('child::caption/quote', + xmlNewArea)[0] + oldAreaCaption = xpath.Evaluate('child::caption', + oldAreaNode)[0] + if newAreaQuote and oldAreaCaption: + oldAreaCaption.replaceChild(newAreaQuote, oldAreaQuote) + + newFields = xpath.Evaluate('child::field',xmlNewArea) + + joinNewFields = xpath.Evaluate(\ + "child::field[child::action='join']" + ,xmlNewArea) + self.addNewFielsOldArea(newFields, joinNewFields, oArea) + + + if not flagFindArea: + # Добавляем область + if not (newAreaAction == "drop"): + appendArea(baseNode, xmlNewArea) + else: + tmpXmlNewAreas = xpath.Evaluate('child::area',xmlNewArea) + for na in tmpXmlNewAreas: + for bn in baseNodes: + self.joinArea(bn, na) + return True + +class plasma(samba): + """Класс для обработки конфигурационного файла типа kde + + """ + _comment = "#" + configName = "plasma" + configVersion = "0.1" + reHeader = re.compile("^[\t ]*\[[^\[\]]+\].*\n?",re.M) + reBody = re.compile(".+",re.M|re.S) + reComment = re.compile("^\s*%s.*"%(_comment)) + reSeparator = re.compile("=") + sepFields = "\n" + reSepFields = re.compile(sepFields) + + def __init__(self,text): + samba.__init__(self,text) + + # Делим текст на области включая вложенные (areas массив областей) + def splitToAllArea(self, text, areas): + """Делит текст на области включая вложенные + + возвращает список объектов областей (переменная areas) + """ + class area: + def __init__(self): + self.header = False + self.start = False + self.fields = [] + self.end = False + + + def findPathArea(listPath, areaF): + """Ищет путь в области + + areaF - объект area + listPath - cписок названий областей + """ + ret = False + if not listPath: + return ret + flagList = False + if type(areaF) == list: + fields = areaF + flagList = True + else: + fields = areaF.fields + if areaF.header == listPath[0]: + ret = areaF + else: + return ret + for i in fields: + if str(i.__class__.__name__) == "area": + add = False + if not flagList: + add = listPath.pop(0) + if not listPath: + break + ret = False + if i.header == listPath[0]: + ret = findPathArea(listPath, i) + break + else: + if add: + listPath.insert(0,add) + if ret == areaF and len(listPath)>1: + ret = False + return ret + + + blTmp = self.blocTextObj.findBloc(self.text,self.reHeader,self.reBody) + blocs = self.getFullAreas(blTmp) + reH = re.compile("\[([^\[\]]+)\]") + # Список имен блоков + namesBlockList = [] + # Временные поля + fieldsTmp = [] + # Добавляем заголовки + z = 0 + for h in blocs[0]: + if not h: + if blocs[1][z] == "": + fieldsTmp.append("") + #fieldsTmp.append("\n") + else: + fieldsTmp.append(blocs[1][z]) + #print '"' + blocs[1][z] + '"' + z += 1 + continue + #print '"' + blocs[1][z] + '"' + z += 1 + slpNamesBlock = reH.split(h) + # Отступ слева для заголовка + indentionLeft = slpNamesBlock[0] + namesBlock = [x for x in slpNamesBlock if x.strip()] + #namesBlock = map(lambda x: self.removeSymbolTerm(x), namesBlock) + findArea = findPathArea(copy.copy(namesBlock), areas) + namesBlockList.append(namesBlock) + if findArea: + if len(namesBlock) > 1: + namesBlockView = [self.removeSymbolTerm(x) for x in namesBlock] + else: + namesBlockView = namesBlock + findArea.start = indentionLeft + "[" + \ + "][".join(namesBlockView) + "]" + else: + i = 0 + lenNamesBlock = len(namesBlock) + namesBlockTmp = [] + for nameB in namesBlock: + namesBlockTmp.append(nameB) + findArea = findPathArea(copy.copy(namesBlockTmp), areas) + i += 1 + if not findArea: + areaNew = area() + areaNew.header = nameB + if lenNamesBlock == i: + if len(namesBlock) > 1: + namesBlockView = [self.removeSymbolTerm(x) for x in namesBlock] + else: + namesBlockView = namesBlock + areaNew.start = indentionLeft + "[" + \ + "][".join(namesBlockView) + "]" + else: + areaNew.start = "" + areaNew.end = "" + if i == 1: + if lenNamesBlock == i: + areas += fieldsTmp + areas.append(areaNew) + findAreaPrev = areas[-1] + else: + if lenNamesBlock == i: + findAreaPrev.fields += fieldsTmp + findAreaPrev.fields.append(areaNew) + findAreaPrev = findAreaPrev.fields[-1] + else: + findAreaPrev = findArea + fieldsTmp = [] + i = 0 + delt = 0 + # Добавляем тела + for body in blocs[1]: + #print "#" + body + "#" + #print + if not blocs[0][i]: + i += 1 + delt +=1 + continue + ## В случае последнего комментария не добавляем перевод строки + #if self.reComment.search(body.splitlines()[-1]): + body = "\n" + body + + namesBlock = namesBlockList[i-delt] + findArea = findPathArea(copy.copy(namesBlock), areas) + if findArea: + #if findArea.fields: + #if type(findArea.fields[0]) == types.StringType: + #findArea.fields.pop(0) + findArea.fields.insert(0, body) + i += 1 + + #eee = 1 + #def prAreas(ar, eee): + #for a in ar: + #if type(a) == types.StringType: + #print 'field', a + #else: + #print "--------------------" + #print "HEADER =", a.header + #print "START =", a.start + #print "FIELDS =", a.fields + #print "LEVEL", eee + #if type(a) != types.StringType: + #if a.fields: + #eee += 1 + #prAreas(a.fields, eee) + + #prAreas(areas, eee) + return areas + + def createCaptionTerm(self, header, start, end, docObj): + """Создание пустой области с заголовком + + при создании области проверяется первый символ заголовка + и добавляется тег action + "!" - drop + "-" - replace + """ + areaAction = False + if header: + if header[0] == "!": + docObj.createCaption(header[1:], [start, + end.replace("\n","")]) + areaAction = "drop" + elif header[0] == "-": + docObj.createCaption(header[1:], [start, + end.replace("\n","")]) + areaAction = "replace" + else: + docObj.createCaption(header, [start, + end.replace("\n","")]) + else: + docObj.createCaption(header, [start, + end.replace("\n","")]) + + areaXML = docObj.createArea() + if areaAction: + docObj.setActionArea(areaXML, areaAction) + return areaXML + + def createXML(self, areas, rootNode, docObj): + """Создаем из массивов областей XML""" + for i in areas: + if str(i.__class__.__name__) == "area": + if i.header: + areaXML = self.createCaptionTerm(i.header, i.start, + i.end.replace("\n",""), + docObj) + for f in i.fields: + if str(f.__class__.__name__) == "area": + if f.header: + areaXMLChild = self.createCaptionTerm(f.header, + f.start, + f.end.replace("\n",""), + docObj) + + self.createXML(f.fields, areaXMLChild, docObj) + + areaXML.appendChild(areaXMLChild) + else: + self.createXML(f.fields, areaXML, docObj) + if "\n" in f.end: + fieldXMLBr = docObj.createField("br",[], + "",[], + False, False) + areaXML.appendChild(fieldXMLBr) + else: + if not f: + continue + fields = self.splitToFields(f) + for field in fields: + if field.name != False: + fieldXML = self.createFieldTerm(field.name, + field.value, + field.br, docObj) + areaXML.appendChild(fieldXML) + if field.br[-1] == "\n": + fieldXMLBr = docObj.createField("br",[], + "",[], + False, False) + areaXML.appendChild(fieldXMLBr) + elif field.comment != False: + fieldXML = docObj.createField("comment", + [field.comment], + "", [], + False, False) + areaXML.appendChild(fieldXML) + elif field.br != False: + brText = field.br.replace("\n","") + if brText: + fieldXML = docObj.createField('br', + [brText], + "", [], + False, False) + else: + fieldXML = docObj.createField('br', + [], + "", [], + False, False) + if areaXML: + areaXML.appendChild(fieldXML) + + if i.header: + rootNode.appendChild(areaXML) + if "\n" in i.end: + fieldXMLBr = docObj.createField("br",[], + "",[], + False, False) + rootNode.appendChild(fieldXMLBr) + + else: + if not i: + continue + fields = self.splitToFields(i) + for field in fields: + if field.name != False: + fieldXML = self.createFieldTerm(field.name, + field.value, + field.br, docObj) + rootNode.appendChild(fieldXML) + if field.br[-1] == "\n": + fieldXMLBr = docObj.createField("br",[],"", [], + False, False) + rootNode.appendChild(fieldXMLBr) + elif field.comment != False: + fieldXML = docObj.createField("comment", + [field.comment], + "", [], + False, False) + rootNode.appendChild(fieldXML) + elif field.br != False: + brText = field.br.replace("\n","") + if brText: + fieldXML = docObj.createField('br', [brText],"",[], + False, False) + else: + fieldXML = docObj.createField('br', [], "", [], + False, False) + rootNode.appendChild(fieldXML) + #rootNode.appendChild(areaXML) + + + def createTxtConfig(self, strHeader, dictVar): + """Cоздает область с заголовком + + создает текст конфигурационного файла в формате samba из + заголовка (строка) и словаря переменных + """ + if not strHeader: + return "" + if type(strHeader) in (tuple, list): + outTxt = "".join("["+x+"]" for x in 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): + """Преобразуем текст в XML""" + areas = [] + if self.text.strip(): + self.splitToAllArea(self.text, areas) + #docObj = xmlDoc() + # Создаем новый класс xmlDoc с измененным методом joinArea + newClass = type("newXmlDocPlalma",(xmlDocPlasma,xmlDoc,object),{}) + # Создаем экземпляр нового класса + docObj = newClass() + # Создание объекта документ c пустым разделителем между полями + docObj.createDoc(self.configName, self.configVersion) + if not areas: + return docObj + self.createXML(areas, docObj.getNodeBody(), docObj) + return docObj + + + def postXML(self): + """Последующая постобработка XML""" + # Для добавления перевода строки между областями если его нет + #print self.docObj.body.toprettyxml() + def getQuotesArea(xmlArea): + quotes = [] + xmlQuotes = xpath.Evaluate('child::caption/quote',xmlArea) + for node in xmlQuotes: + if node.firstChild: + quotes.append(node.firstChild.nodeValue) + if len(quotes) == 0: + quotes.append("") + quotes.append("") + elif len(quotes) == 1: + quotes.append("") + return quotes + + xmlAreas = xpath.Evaluate("descendant::area", self.docObj.body) + #print "-------------------------------------------------------" + #print xmlAreas + #if xmlAreas: + #prXmlArea = xmlAreas[0] + for xmlArea in xmlAreas: + # Перед пустой областью и после нее удаляем переводы строк + if getQuotesArea(xmlArea) == ["",""]: + #areaTXT = xpath.Evaluate("child::caption/name", xmlArea)[0] + #print "CL_AREA", areaTXT.firstChild + if xmlArea.previousSibling and\ + self.docObj.getTypeField(xmlArea.previousSibling) == "br": + parentNode = xmlArea.previousSibling.parentNode + if xmlArea.previousSibling.previousSibling and\ + self.docObj.getTypeField(xmlArea.previousSibling.previousSibling) == "br": + parentNode.removeChild(\ + xmlArea.previousSibling.previousSibling) + parentNode.removeChild(xmlArea.previousSibling) + if xmlArea.nextSibling and\ + self.docObj.getTypeField(xmlArea.nextSibling) == "br": + parentNode = xmlArea.nextSibling.parentNode + if xmlArea.nextSibling.nextSibling and\ + self.docObj.getTypeField(xmlArea.nextSibling.nextSibling) == "br": + parentNode.removeChild(xmlArea.nextSibling.nextSibling) + parentNode.removeChild(xmlArea.nextSibling) + continue + + # Собираем поля в кучку + xmlChildAreas = xpath.Evaluate("child::area", xmlArea) + if xmlChildAreas: + childNodes = self.docObj.getFieldsArea(xmlArea) + firstChildArea = xmlChildAreas[0] + if firstChildArea.previousSibling and\ + self.docObj.getTypeField(firstChildArea.previousSibling)=="br": + if firstChildArea.previousSibling.previousSibling: + if self.docObj.getTypeField(\ + firstChildArea.previousSibling.previousSibling)=="br": + firstChildArea = firstChildArea.previousSibling + flagFoundArea = False + it = 0 + lenChild = len(childNodes) + for node in childNodes: + it += 1 + if node.tagName == "area": + flagFoundArea = True + continue + if flagFoundArea and node.tagName == "field": + if self.docObj.getTypeField(node) == "var": + xmlArea.insertBefore(node, firstChildArea) + if it < lenChild: + if self.docObj.getTypeField(childNodes[it])==\ + "br": + xmlArea.insertBefore(childNodes[it], + 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 если его нет первым полем + xmlFields = xpath.Evaluate("child::field", xmlArea) + if not (xmlFields and\ + (self.docObj.getTypeField(xmlFields[0]) == "br" or\ + self.docObj.getTypeField(xmlFields[0]) == "comment")): + if xmlFields: + xmlArea.insertBefore(self.docObj.createField("br", + [],"",[], + False,False), + xmlFields[0]) + # Если последним полем BR, удаляем его + if xmlFields and self.docObj.getTypeField(xmlFields[-1]) == "br": + #print "DEL_BR", xmlFields[-1].nextSibling + #and\ + if not xmlFields[-1].nextSibling: + xmlArea.removeChild(xmlFields[-1]) + + # Если предыдущим полем не (BR или комментарий) - добавляем BR + if xmlArea.previousSibling and\ + not (self.docObj.getTypeField(xmlArea.previousSibling) == "br" or\ + self.docObj.getTypeField(xmlArea.previousSibling) == "comment"): + parentNode = xmlArea.parentNode + parentNode.insertBefore(self.docObj.createField("br", + [],"",[], + False,False), + xmlArea) + # Если есть предыдущее поле, и поле предыдущеее предыдущему + # не равно BR или комментарий то добавляем BR + if xmlArea.previousSibling: + prPrSibling = xmlArea.previousSibling.previousSibling + if prPrSibling and\ + not (self.docObj.getTypeField(prPrSibling) == "br" or\ + self.docObj.getTypeField(prPrSibling) == "comment"): + parentNode = xmlArea.parentNode + parentNode.insertBefore(self.docObj.createField("br", + [],"",[], + False,False), + xmlArea) + # Если после есть BR а за ним ничего нет, удаляем BR + if xmlArea.nextSibling and\ + self.docObj.getTypeField(xmlArea.nextSibling) == "br": + if not xmlArea.nextSibling.nextSibling: + parentNode = xmlArea.nextSibling.parentNode + parentNode.removeChild(xmlArea.nextSibling) + + + def join(self, kdeObj): + """Объединяем конфигурации""" + if isinstance(kdeObj, plasma): + self.docObj.joinDoc(kdeObj.doc) + self.postXML() + +class xml_xfce(_error): + """Класс для объединения xfce-xml файлов""" + # root нода + rootNode = False + # body нода + bodyNode = False + # Документ + doc = False + # Текст профиля + text = "" + # Комментарий + _comment = ("") + + def __init__(self, text): + self.text = text + # Создаем пустой объект + self.docObj = type("_empty_class", (object,), {})() + # Названия аттрибутов для пустого объекта + emptyMethods = ["getNodeBody","removeComment","insertBRtoBody", + "insertBeforeSepAreas"] + # Добавляем необходимые аттрибуты пустому объекту + for method in emptyMethods: + setattr(self.docObj, method, self.emptyMethod) + # Создаем XML документ + self.doc = self.textToXML() + + def emptyMethod(self, *arg , **argv): + """Пустой метод""" + return True + + def setNameBodyNode(self, name): + """Устанавливает название для корневой ноды документа""" + if not self.bodyNode: + return False + self.bodyNode.setAttribute("name", name) + return True + + def textToXML(self): + """Создание из текста XML документа + Храним xml в своем формате + """ + if not self.text.strip(): + self.text = ''' + +''' + try: + self.doc = xml.dom.minidom.parseString(self.text) + except: + self.setError(_("Can not text profile is XML")) + return False + self.rootNode = self.doc.documentElement + self.bodyNode = self.rootNode + return self.doc + + def join(self, xml_xfceObj): + """Объединяем конфигурации""" + if isinstance(xml_xfceObj, xml_xfce): + try: + self.joinDoc(xml_xfceObj.doc) + except: + self.setError(_("Can not join profile")) + return False + return True + + def _removeDropNodesAndAttrAction(self, xmlNode): + """Удаляет ноды с аттрибутом action='drop' + + Также удаляет аттрибут action у всех нод + """ + flagError = False + childNodes = xmlNode.childNodes + if xmlNode.nodeType ==xmlNode.ELEMENT_NODE: + if xmlNode.hasAttribute("action"): + nAction = xmlNode.getAttribute("action") + if not nAction in ("join","replace","drop"): + textError = _('''In the text, XML profile, look \ +for a reserved attribute 'action' with the incorrect value.\n\ +Valid values attribute 'action': \ +(action="join", action="replace", action="drop")''') + self.setError(textError) + return False + xmlNode.removeAttribute("action") + if nAction == "drop": + parentNode = xmlNode.parentNode + if parentNode: + parentNode.removeChild(xmlNode) + if childNodes: + for node in childNodes: + if not self._removeDropNodesAndAttrAction(node): + flagError = True + break + if flagError: + return False + return True + + def postXML(self): + """Последующая постобработка XML""" + # Удаляем теги action и удаляемые ноды + self._removeDropNodesAndAttrAction(self.bodyNode) + + def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True): + """Объединение корневой ноды профиля и корневой ноды файла""" + xmlNode = xmlNewNode + childNodes = xmlNode.childNodes + nextOldNode = xmlOldNode + flagError = False + if xmlNode.nodeType ==xmlNode.ELEMENT_NODE: + n = xmlNode + path = u'' + nName = u'' + nType = u'' + nValue = u'' + nAction = u'' + attrName = '' + attrType = '' + path = n.tagName + if n.hasAttribute("name"): + nName = n.getAttribute("name") + attrName = u"attribute::name='%s'"%nName + if n.hasAttribute("type"): + nType = n.getAttribute("type") + attrType = u"attribute::type='%s'"%nType + if n.hasAttribute("value"): + nValue = n.getAttribute("value") + if n.hasAttribute("action"): + nAction = n.getAttribute("action") + if not nAction in ("join","replace","drop"): + textError = _('''In the text, XML profile, look \ +for a reserved attribute 'action' with the incorrect value.\n\ +Valid values attribute 'action': \ +(action="join", action="replace", action="drop")''') + self.setError(textError) + return False + if xmlOldNode.parentNode: + strAttr = [attrName, attrType] + findAttr = [x for x in strAttr if x] + findAttrStr = '' + if findAttr: + strAttr = u' and '.join(findAttr) + findAttrStr = "[%s]"%strAttr + findPath = u"child::%s%s"%(path,findAttrStr) + # Рабочая нода + if flagRootNode: + workNode = xmlOldNode.parentNode + else: + workNode = xmlOldNode + oldNodes = xpath.Evaluate(findPath, workNode) + #print findPath + #print workNode + #print "----------------------------" + # Новая нода список + flagArray = False + if nType == "array": + flagArray = True + flagDrop = False + flagJoin = True + flagReplace = False + if nAction == "replace": + flagJoin = False + flagReplace = True + elif nAction == "drop": + flagJoin = False + flagDrop = True + if flagRootNode: + textError = _('Incorrect action="drop" in root node') + self.setError(textError) + return False + if oldNodes: + if len(oldNodes)>1: + textError = _("The uncertainty in this profile are \ +the same nodes at one level") + self.setError(textError) + return False + nextOldNode = oldNodes[0] + # Замещаем ноду в случае массива + if flagArray and not flagDrop: + replaceXmlNode = xmlNode.cloneNode(True) + if nAction: + replaceXmlNode.removeAttribute("action") + workNode.replaceChild(replaceXmlNode, + nextOldNode) + flagJoin = False + flagReplace = False + childNodes = False + # Объединение нод + if flagJoin: + if nextOldNode.hasAttribute("value"): + oValue = nextOldNode.getAttribute("value") + if nValue != oValue: + nextOldNode.setAttribute("value",nValue) + # Замещение ноды + elif flagReplace: + replaceXmlNode = xmlNode.cloneNode(True) + if not\ + self._removeDropNodesAndAttrAction(replaceXmlNode): + return False + workNode.replaceChild(replaceXmlNode, + nextOldNode) + childNodes = False + # Удаление ноды + elif flagDrop: + workNode.removeChild(nextOldNode) + childNodes = False + else: + # Добавление ноды + childNodes = False + if not flagDrop: + appendXmlNode = xmlNode.cloneNode(True) + if not\ + self._removeDropNodesAndAttrAction(appendXmlNode): + return False + workNode.appendChild(appendXmlNode) + if childNodes: + for node in childNodes: + if not self._join(node, nextOldNode, False): + flagError = True + break + if flagError: + return False + return True + + def joinDoc(self, doc): + """Объединение документа профиля и документа файла""" + if not self.doc: + self.setError(_("Can not text file is XML")) + return False + if not doc: + self.setError(_("Can not text profile is XML")) + return False + # Импортируем корневую ноду нового документа в текущий документ + #newImportBodyNode = self.doc.importNode(doc.documentElement, True) + # Объединение корневой ноды профиля и корневой ноды файла + if not self._join(doc.documentElement, self.bodyNode): + return False + return True + + def getConfig(self): + """Получение текстового файла из XML документа""" + data = self.doc.toprettyxml(encoding='UTF-8').split("\n") + data = [x for x in data if x.strip()] + return "\n".join(data).replace("\t"," ").decode("UTF-8") + +class squid(procmail): + """Класс для обработки конфигурационного файла типа squid + + """ + configName = "squid" + configVersion = "0.1" + # разделитель названия и значения переменной + reSeparator = re.compile(" ") + + def __init__(self, text): + procmail.__init__(self, text) + # Создаем поля-массивы + self.docObj.postParserList() + # Создаем поля разделенные массивы + self.docObj.postParserListSeplist(self.docObj.body) + + def setDataField(self, txtLines, endtxtLines): + """Создаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + z += 1 + findComment = self.reComment.search(textLine) + flagVariable = True + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + flagVariable = False + elif findComment: + if textLine[:findComment.start()].strip(): + field.comment = textLine[findComment.start():] + textLine = textLine[:findComment.start()] + else: + field.comment = textLine + flagVariable = False + fields.append(field) + field = fieldData() + if flagVariable: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len(nameValue) > 2: + valueList = nameValue[1:] + nameValue =[nameValue[0]," ".join(valueList)] + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + + def join(self, squidObj): + """Объединяем конфигурации""" + if isinstance(squidObj, squid): + #print squidObj.getConfig() + self.docObj.joinDoc(squidObj.doc) + +class xml_xfcepanel(xml_xfce): + """Класс для объединения xfce-panel файлов""" + def __init__(self, text): + xml_xfce.__init__(self, text) + self.panelNumbers = {} + + def textToXML(self): + """Создание из текста XML документа + Храним xml в своем формате + """ + if not self.text.strip(): + self.text = ''' + + +''' + try: + self.doc = xml.dom.minidom.parseString(self.text) + except: + self.setError(_("Can not text profile is XML")) + return False + self.rootNode = self.doc.documentElement + self.bodyNode = self.rootNode + return self.doc + + def setNameBodyNode(self, name): + """Пустой метод""" + return True + + def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0): + """Объединение корневой ноды профиля и корневой ноды файла""" + xmlNode = xmlNewNode + childNodes = xmlNode.childNodes + nextOldNode = xmlOldNode + flagError = False + if xmlNode.nodeType ==xmlNode.ELEMENT_NODE: + n = xmlNode + path = u'' + nName = u'' + flagArray = False + nValue = u'' + nAction = u'' + attrName = '' + attrType = '' + path = n.tagName + if path == "items": + flagArray = True + if not flagArray: + if n.hasAttribute("name"): + nName = n.getAttribute("name") + attrName = u"attribute::name='%s'"%nName + if n.hasAttribute("value"): + nValue = n.getAttribute("value") + if n.hasAttribute("action"): + nAction = n.getAttribute("action") + if not nAction in ("join","replace","drop"): + textError = _('''In the text, XML profile, look \ +for a reserved attribute 'action' with the incorrect value.\n\ +Valid values attribute 'action': \ +(action="join", action="replace", action="drop")''') + self.setError(textError) + return False + if xmlOldNode.parentNode: + findAttrStr = "" + if attrName: + findAttrStr = "[%s]"%attrName + findPath = u"child::%s%s"%(path,findAttrStr) + # Рабочая нода + if flagRootNode: + workNode = xmlOldNode.parentNode + else: + workNode = xmlOldNode + oldNodes = xpath.Evaluate(findPath, workNode) + flagDrop = False + flagJoin = True + flagReplace = False + flagAppend = False + if nAction == "replace": + flagJoin = False + flagReplace = True + elif nAction == "drop": + flagJoin = False + flagDrop = True + if flagRootNode: + textError = _('Incorrect action="drop" in root node') + self.setError(textError) + return False + if path == "panel": + flagJoin = False + if levelNumber in self.panelNumbers.keys(): + self.panelNumbers[levelNumber] += 1 + else: + self.panelNumbers[levelNumber] = 0 + if oldNodes: + if len(oldNodes)>1 and path != "panel": + textError = _("The uncertainty in this profile are \ +the same nodes at one level") + self.setError(textError) + return False + if path == "panel": + if len(oldNodes)<=self.panelNumbers[levelNumber]: + nextOldNode = oldNodes[-1] + # Добавляем ноду + if not flagDrop: + flagAppend = True + flagReplace = False + childNodes = False + else: + nextOldNode=oldNodes[self.panelNumbers[levelNumber]] + else: + nextOldNode = oldNodes[0] + # Замещаем ноду в случае массива + if flagArray and not flagDrop: + replaceXmlNode = xmlNode.cloneNode(True) + if nAction: + replaceXmlNode.removeAttribute("action") + workNode.replaceChild(replaceXmlNode, + nextOldNode) + flagJoin = False + flagReplace = False + childNodes = False + # Объединение нод + if flagJoin: + if nextOldNode.hasAttribute("value"): + oValue = nextOldNode.getAttribute("value") + if nValue != oValue: + nextOldNode.setAttribute("value",nValue) + # Замещение ноды + elif flagReplace: + replaceXmlNode = xmlNode.cloneNode(True) + if not\ + self._removeDropNodesAndAttrAction(replaceXmlNode): + return False + workNode.replaceChild(replaceXmlNode, + nextOldNode) + childNodes = False + # Удаление ноды + elif flagDrop: + workNode.removeChild(nextOldNode) + childNodes = False + else: + flagAppend = True + flagDrop = False + if flagAppend and not flagDrop: + # Добавление ноды + childNodes = False + if not flagDrop: + appendXmlNode = xmlNode.cloneNode(True) + if not\ + self._removeDropNodesAndAttrAction(appendXmlNode): + return False + workNode.appendChild(appendXmlNode) + if childNodes: + for node in childNodes: + levelNumber +=1 + if not self._join(node, nextOldNode, False, levelNumber): + flagError = True + break + levelNumber -= 1 + if flagError: + return False + return True + + def join(self, xml_xfceObj): + """Объединяем конфигурации""" + if isinstance(xml_xfceObj, xml_xfcepanel): + try: + self.joinDoc(xml_xfceObj.doc) + except: + self.setError(_("Can not join profile")) + return False + return True + + +class dhcp(bind): + """Класс для обработки конфигурационного файла типа dhcp + + """ + _comment = "#" + configName = "dhcp" + configVersion = "0.1" + __openArea = "{" + __closeArea = "[ \t]*\}[ \t]*" + sepFields = ";" + reOpen = re.compile(__openArea) + reClose = re.compile(__closeArea) + reCloseArea = re.compile(__closeArea + "\s*\Z") + reComment = re.compile("^[ \t]*%s"%(_comment)) + reSepFields = re.compile(sepFields) + reSeparator = re.compile("[ \t]+") + + def __init__(self,text): + bind.__init__(self,text) + + def setDataField(self, txtLines, endtxtLines): + """Создаем список объектов с переменными""" + class fieldData: + def __init__(self): + self.name = False + self.value = False + self.comment = False + self.br = False + fields = [] + field = fieldData() + z = 0 + for k in txtLines: + textLine = k + endtxtLines[z] + z += 1 + findComment = self.reComment.search(textLine) + if not textLine.strip(): + field.br = textLine + fields.append(field) + field = fieldData() + elif findComment: + field.comment = textLine + fields.append(field) + field = fieldData() + else: + pars = textLine.strip() + nameValue = self.reSeparator.split(pars) + if len (nameValue) == 1: + field.name = textLine.replace(self.sepFields,"").strip() + field.value = "" + field.br = textLine + fields.append(field) + field = fieldData() + + if len(nameValue) > 2: + nameCheck = nameValue[0] + if nameValue[0][:1] in ["+","-","!"]: + nameCheck = nameValue[0][1:] + if nameCheck == "option" or nameCheck == "hardware" or\ + nameCheck == "set": + valueList = nameValue[2:] + nameValue =[nameValue[0]+nameValue[1], + " ".join(valueList).replace(\ + self.sepFields,"")] + else: + valueList = nameValue[1:] + nameValue =[nameValue[0]," ".join(valueList).replace(\ + self.sepFields,"")] + if len(nameValue) == 2: + name = nameValue[0] + value = nameValue[1].replace(self.sepFields,"") + field.name = name.replace(" ","").replace("\t","") + field.value = value + field.br = textLine + fields.append(field) + field = fieldData() + return fields + + def join(self, dhcpObj): + """Объединяем конфигурации""" + if isinstance(dhcpObj, dhcp): + self.docObj.joinDoc(dhcpObj.doc) + + +class xml_gconf(xml_xfce): + """Класс для объединения gconf-xml файлов""" + # root нода + rootNode = False + # body нода + bodyNode = False + # Документ + doc = False + # Текст профиля + text = "" + # Текущее время в секундах + currentTime = "" + # Комментарий + _comment = ("") + # поддерживаемые аттрибуты тега entry. Пример + supportEntryTypes = ("int", "bool", "float", "string", "list", "pair") + reStartTabs = re.compile("^(\t+)(.*)$") + + def __init__(self, text): + self.text = text + # Создаем пустой объект + self.docObj = type("_empty_class", (object,), {})() + # Названия аттрибутов для пустого объекта + emptyMethods = ["getNodeBody","removeComment","insertBRtoBody", + "insertBeforeSepAreas"] + # Добавляем необходимые аттрибуты пустому объекту + for method in emptyMethods: + setattr(self.docObj, method, self.emptyMethod) + # Пустой метод (не нужно имя файла для корневой ноды) + setattr(self, "setNameBodyNode", self.emptyMethod) + # Создаем XML документ + self.doc = self.textToXML() + + def getCurrentTime(self): + """Получение текущего времени в секундах""" + return str(int(time.time())) + + def textToXML(self): + """Создание из текста XML документа + Храним xml в своем формате + """ + if not self.text.strip(): + self.text = '''''' + try: + self.doc = xml.dom.minidom.parseString(self.text) + except: + self.setError(_("Can not text profile is XML")) + return False + self.rootNode = self.doc.documentElement + self.bodyNode = self.rootNode + return self.doc + + def cmpListsNodesEntry(self, listXmlA, listXmlB): + """Сравнение содержимого двух списков XML нод""" + # getTextsNodes = lambda y: map(lambda x:\ + # x.toxml().replace(" ","").replace("\t","").replace("\n",""), + # map(lambda x: x.hasAttribute("mtime") and\ + # x.removeAttribute("mtime") or x, + # map(lambda x: x.cloneNode(True), + # filter(lambda x: x.nodeType==x.ELEMENT_NODE, y)))) + getTextsNodes = lambda y: [o.toxml().replace(" ","").replace("\t","").replace("\n","") + for o in (z.hasAttribute("mtime") and z.removeAttribute("mtime") or z + for z in (x.cloneNode(True) + for x in y + if x.nodeType==x.ELEMENT_NODE))] + if set(getTextsNodes(listXmlA))==set(getTextsNodes(listXmlB)): + return True + return False + + def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0): + """Объединение корневой ноды профиля и корневой ноды файла""" + if levelNumber>1: + return True + xmlNode = xmlNewNode + childNodes = xmlNode.childNodes + nextOldNode = xmlOldNode + flagError = False + if xmlNode.nodeType == xmlNode.ELEMENT_NODE: + n = xmlNode + tagName = n.tagName + nAction = u'' + nName = u'' + nType = u'' + nValue = u'' + nSchema = u'' + attrName = '' + if flagRootNode: + if not tagName == "gconf": + self.setError(_("The text is not a valid gconf-XML format \ +(not found '...')")) + return False + flagType = False + flagValue = False + flagSchema = False + else: + if not tagName == "entry": + self.setError(_("The text is not a valid gconf-XML format \ +(found '<%s>..'")%(tagName,tagName)) + return False + if not n.hasAttribute("name"): + self.setError(_('Not found arrtibute "name" in tag entry')) + return False + 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')) + return False + nName = n.getAttribute("name") + attrName = u"attribute::name='%s'"%nName + if flagType: + flagValue = n.hasAttribute("value") + nType = n.getAttribute("type") + # Проверка правильности аттрибута type + if not nType in self.supportEntryTypes: + self.setError(\ + _('Incorrect arrtibute "type" - ')\ + %nType) + return False + if flagValue: + nValue = n.getAttribute("value") + if n.hasAttribute("action"): + nAction = n.getAttribute("action") + if not nAction in ("join","replace","drop"): + textError = _('''In the text, XML profile, look \ +for a reserved attribute 'action' with the incorrect value.\n\ +Valid values attribute 'action': \ +(action="join", action="replace", action="drop")''') + self.setError(textError) + return False + if xmlOldNode.parentNode: + findAttrStr = "" + if attrName: + findAttrStr = "[%s]"%attrName + findPath = u"child::%s%s"%(tagName,findAttrStr) + # Рабочая нода + if flagRootNode: + workNode = xmlOldNode.parentNode + else: + workNode = xmlOldNode + oldNodes = xpath.Evaluate(findPath, workNode) + # По умолчанию - объединение + flagJoin = True + flagReplace = False + flagDrop = False + # Замещаем ноду + if nType=="string" or nAction=="replace": + flagJoin = False + flagReplace = True + # Замещаем ноду в случае массива + elif nType == "list" or nType == "pair": + flagJoin = False + flagReplace = True + # Удаляем ноду + elif nAction == "drop": + flagJoin = False + flagDrop = True + if flagRootNode: + textError = _('Incorrect action="drop" in root node') + self.setError(textError) + return False + if oldNodes: + if len(oldNodes)>1: + textError = _("The uncertainty in this profile are \ +the same nodes at one level") + self.setError(textError) + return False + nextOldNode = oldNodes[0] + # Объединение нод + if flagJoin: + if flagType and flagValue: + flagChange = False + foundValue = nextOldNode.hasAttribute("value") + if foundValue: + oValue = nextOldNode.getAttribute("value") + if nValue != oValue: + flagChange = True + else: + flagChange = True + if flagChange: + nextOldNode.setAttribute("mtime", + self.currentTime) + 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: + replaceXmlNode = xmlNode.cloneNode(True) + # Сравнение содержимого нод + if not self.cmpListsNodesEntry([replaceXmlNode], + [nextOldNode]): + replaceXmlNode.setAttribute("mtime", + self.currentTime) + if not\ + self._removeDropNodesAndAttrAction(\ + replaceXmlNode): + return False + workNode.replaceChild(replaceXmlNode, + nextOldNode) + childNodes = False + # Удаление ноды + elif flagDrop: + workNode.removeChild(nextOldNode) + childNodes = False + else: + # Добавление ноды + childNodes = False + if not flagDrop: + appendXmlNode = xmlNode.cloneNode(True) + appendXmlNode.setAttribute("mtime", self.currentTime) + if not\ + self._removeDropNodesAndAttrAction(appendXmlNode): + return False + workNode.appendChild(appendXmlNode) + if childNodes: + for node in childNodes: + levelNumber +=1 + if not self._join(node, nextOldNode, False, levelNumber): + flagError = True + break + levelNumber -= 1 + if flagError: + return False + return True + + def join(self, xml_gconfObj): + """Объединяем конфигурации""" + # Получаем текущее время + self.currentTime = self.getCurrentTime() + if isinstance(xml_gconfObj, xml_gconf): + try: + self.joinDoc(xml_gconfObj.doc) + except: + self.setError(_("Can not join profile")) + return False + return True + + def getConfig(self): + """Получение текстового файла из XML документа""" + def expandStartTabs(s): + if s.startswith("\t"): + res = self.reStartTabs.findall(s) + return "".join((res[0][0].replace("\t"," "),res[0][1])) + else: + return s + data = self.doc.toprettyxml().split("\n") + data = [expandStartTabs(x) for x + in data if x.strip()] + dataOut = [] + z = 0 + lenData = len(data) + lenM2 = lenData - 2 + for i in range(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) diff --git a/pym/cl_utils.py b/pym/cl_utils.py new file mode 100644 index 0000000..0d58dae --- /dev/null +++ b/pym/cl_utils.py @@ -0,0 +1,608 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Mir Calculate. 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 filecmp +import string +from random import choice +from re import search, compile, S +import os +import types +import subprocess +import socket +import struct +import fcntl +import math +import ctypes +from functools import reduce + +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 range(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 range(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 range(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].encode('utf8'), end=' ') + cols[q] = '' + else: + # вывести часть строки не больше указанной ширины колонки + print((cols[q][:cols[q+1]].ljust(cols[q+1])).encode('utf8'), end=' ') + # остальную часть строки оставить на следующую итерацию + 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, env_dict=None): + """Выполняет внешнюю программу + + Параметры: + cmd внешняя программа + inStr данные передаваемые программе на страндартный вход. + ret_first вернуть только первую строку + env_dict словарь переменных окружения + Возвращаемые параметры: + строка/строки которую выведет внешняя программа + Возвращает код возврата, stdout+stderr + """ + pipe = subprocess.Popen(cmd, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env_dict, + close_fds=True, + shell=True) + fout, fin, ferr = (pipe.stdout, pipe.stdin, pipe.stderr) + # если есть данные на вход, передать их + if inStr: + fin.write(inStr) + fin.close() + # Код возврата + retcode = pipe.wait() + res = fout.readlines() + fout.close() + if not ("dovecot start" in cmd or "dovecot restart" in cmd): + res += ferr.readlines() + ferr.close() + if res: + if len(res) == 1 or ret_first: + return retcode, res[0].strip() + else: + return retcode, res + return retcode, None + + +def genpassword(passlen=9): + '''Вернуть случайный пассворд указанной длины + + Параметры: + passlen длина пароля который нужно сгенерировать + + Возвращаемые параметры: + Сгенерированный пароль указанной длины + ''' + res=''.join([choice(string.ascii_letters+string.digits)\ + for i in range(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 'PATH' in env: + 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) + +#класс для работы с установленными пакетами +class pakages: + #путь к директории установленнх пакетов + pkgdir="/var/db/pkg/" + #список установленных пакетов + pkglist={} + #Объект содержащий параметры пакета + class pakage(): + #имя пакета с версией + 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 fpkg in instaledPkg: + 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 pinfo[0]+'/'+pinfo[1] not in self.pkglist: + 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 pinfo[0]+'/'+pinfo[1] not in self.pkglist: + 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) == list: + return list2str(val) + # если подан словарь + elif type(val) == dict: + 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) == str: + return val + else: + return str(val).decode('UTF-8') + +SYSFS_NET_PATH = "/sys/class/net" + +# From linux/sockios.h +SIOCGIFADDR = 0x8915 +SIOCGIFNETMASK = 0x891B +SIOCGIFHWADDR = 0x8927 + +def getInterfaces(): + """ + Get available interfaces (discard which hasn't device) + """ + try: + return [x for x in os.listdir(SYSFS_NET_PATH) if x!= "lo"] + except: + return [] + +def getIp(iface): + sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14) + try: + res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq) + except IOError: + return "" + finally: + sockfd.close() + ip = struct.unpack('16sH2x4s8x', res)[2] + return socket.inet_ntoa(ip) + +def getMask(iface): + """ + Get mask for interface + """ + sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14) + try: + res = fcntl.ioctl(sockfd, SIOCGIFNETMASK, ifreq) + except IOError: + return 0 + finally: + sockfd.close() + netmask = socket.ntohl(struct.unpack('16sH2xI8x', res)[2]) + return 32 - int(math.log(ctypes.c_uint32(~netmask).value + 1, 2)) + +def getMac(iface): + """ + Get mac for interface + """ + sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + ifreq = struct.pack('16sH14s', iface, socket.AF_UNIX, '\x00'*14) + res = fcntl.ioctl(sockfd, SIOCGIFHWADDR, ifreq) + address = struct.unpack('16sH14s', res)[2] + mac = struct.unpack('6B8x', address) + sockfd.close() + return ":".join(['%02X' % i for i in mac]) + +def intIpToStrIp(addr): + """Convert ip specified by integer to string""" + return "{0}.{1}.{2}.{3}".format( + addr>>24,(addr>>16)&0xff,(addr>>8)&0xff,addr&0xff) + +def maskToCidr(mask): + """Convert mask specified by str to net""" + mask = strIpToIntIp(mask) + return 32-int(math.log(((~mask) & 0xffffffff)+1,2)) + +def cidrToMask(cidr): + """Convert net to mask specified by str""" + return intIpToStrIp((2**cidr-1)<<(32-cidr)) + +def strIpToIntIp(addr): + """Convert ip specified by string to integer""" + addr = addr.split('.') + return ((int(addr[0])<<24)| + (int(addr[1])<<16)| + (int(addr[2])<<8)| + (int(addr[3]))) + return reduce(lambda x,y:x+(int(y[1])<<(y[0]*8)), + enumerate(reversed(addr.split("."))),0) + +def getIpNet(ip,mask=None,cidr=None): + """Get net (xx.xx.xx.xx/xx) by ip address and mask""" + ip = strIpToIntIp(ip) + if not mask is None: + net = maskToCidr(mask) + else: + net = int(cidr) + mask = cidrToMask(net) + mask = strIpToIntIp(mask) + return "{ip}/{net}".format(ip=intIpToStrIp(ip&mask), + net=net) diff --git a/pym/cl_utils2.py b/pym/cl_utils2.py new file mode 100644 index 0000000..fe3c30d --- /dev/null +++ b/pym/cl_utils2.py @@ -0,0 +1,563 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Mir Calculate. 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 struct +import termios +import fcntl +from . import cl_utils + +from . 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 as 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 "shortOption" in par: + sp[par["shortOption"]+":"+par["helpChapter"]] = i + # есть только длинная опция + elif "longOption" in par: + 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 = next(iterChapterBloc) + # если тип раздела опциональный + 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 "shortOption" in par and self.access(par): + if "optVal" in par: + 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 "longOption" in par and self.access(par): + if "optVal" in par: + 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 "shortOption" in par and self.access(par): + if ("longOption" in par and\ + par["longOption"] == option) or \ + par["shortOption"] == option: + return par["shortOption"] + break + return "" + +class cl_smartcon(): + + 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, offsetL=0, printBR=True): + """Печатает справа и слева консоли цветные сообщения""" + #Допустимые цвета + 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 color in colorDict: + # печатаем и считаем смещение + colorDict[color](leftString) + else: + colorDict[''](leftString) + # cмещение от правого края консоли + offsetR = 0 + for color,rightString in argR: + offsetR += self.lenString(rightString) + # Добавляем пробелы + if offsetR: + self.printRight(offsetL, offsetR) + for color,rightString in argR: + if color in colorDict: + # печатаем и считаем смещение + colorDict[color](rightString) + else: + colorDict[''](rightString) + if printBR: + print("") + + def printNotOK(self, string, offsetL=0, printBR=True): + """Вывод на печать в случае сбоя""" + self.printLine((('greenBr',' * '), + ('',string), + ), + (('blueBr','['), + ('redBr',' !! '), + ('blueBr',']'), + ), offsetL, printBR) + + def printOnlyNotOK(self, string, offsetL=0, printBR=True): + """Вывод на печать в случае сбоя""" + self.printLine((('', string),), + (('blueBr','['), + ('redBr',' !! '), + ('blueBr',']'), + ), offsetL, printBR) + + def printOK(self, string, offsetL=0, printBR=True): + """Вывод на печать в случае успеха""" + self.printLine((('greenBr',' * '), + ('',string), + ), + (('blueBr','['), + ('greenBr',' ok '), + ('blueBr',']'), + ), offsetL, printBR) + + def printOnlyOK(self, string, offsetL=0, printBR=True): + """Вывод на печать в случае успеха""" + self.printLine((('',string),), + (('blueBr','['), + ('greenBr',' ok '), + ('blueBr',']'), + ), offsetL, printBR) + + def printWARNING(self, string, offsetL=0, printBR=True): + """Вывод на печать предупреждения""" + self.printLine((('yellowBr',' * '), + ('',string), + ), + (('',''), + ), offsetL, printBR) + + def printERROR(self, string, offsetL=0, printBR=True): + """Вывод на печать предупреждения""" + self.printLine((('redBr',' * '), + ('',string), + ), + (('',''), + ), offsetL, printBR) + + def printSUCCESS(self, string, offsetL=0, printBR=True): + """Вывод на печать в случае успеха без [ok] справа""" + self.printLine((('greenBr',' * '), + ('',string), + ), + (('',''), + ), offsetL, printBR) diff --git a/pym/cl_vars.py b/pym/cl_vars.py new file mode 100644 index 0000000..6f857ea --- /dev/null +++ b/pym/cl_vars.py @@ -0,0 +1,92 @@ +#-*- coding: utf-8 -*- + +# Copyright 2008-2010 Mir Calculate. 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. + +#Допустимые ключи значений +# mode - режим переменной r-не переназначается из командной строки, +# w-переназначается из командной строки +# type - тип переменной состоит из двух элементов(что это и для чего +# это) +# value - значение переменной + +class Data: + + # имя компьютера + os_net_hostname = {'mode':"w"} + # разрешенные сети + os_net_allow ={} + # ip на всех интерфейсах + os_net_ip ={} + + #короткое название системы (CLD) + os_linux_shortname={} + + #домен + os_net_domain = {'mode':"w"} + + # Пути к ini файлам + cl_env_path = {'value':['/var/calculate/remote/calculate.env', + '/var/calculate/calculate.env', + '/etc/calculate/calculate.env', + '/var/lib/calculate/calculate.env']} + + # локаль (прим: ru_RU.UTF-8) + os_locale_locale = {} + # язык (прим: ru_RU) + os_locale_lang = {} + # язык (прим: ru) + os_locale_language = {} + + # раскладка клавиатуры для X + os_locale_xkb = {} + + # названия используемых раскладок клавиатуры для X + os_locale_xkbname = {} + + # архитектура компьютера (i686,x86_64) + os_arch_machine = {} + + #проход при наложении профилей 1,2,3,4,5 и.т д + cl_pass_step = {'mode':"w"} + + # обрабатываемый файл профиля + cl_pass_file = {'mode':"w"} + + # корневой раздел файловой системы + os_root_dev = {} + + # тип носителя (ram, hdd, usb-hdd, livecd) + os_root_type = {} + + # полное название системы + os_linux_name = {} + + # постфикс к названию системы + os_linux_subname = {} + + # название виртуальной машины (virtualbox, vmware, qemu) + hr_virtual = {} + + # версия системы + os_linux_ver = {} + + # Тип профиля + cl_pass_type = {'mode':"w"} + + # Действие программы + cl_pass_run = {'mode':"w"} + + #Логин пользователя + ur_login = {'mode':"w"} diff --git a/setup.py b/setup.py index 4491ba7..c914aca 100755 --- a/setup.py +++ b/setup.py @@ -24,7 +24,8 @@ from distutils.core import setup from distutils.command.build_scripts import build_scripts from distutils.command.install_scripts import install_scripts from distutils.command.install_data import install_data - +def cmp(a, b): + return (a > b) - (b < a) data_files = [] var_data_files = [("/var/calculate/server-profile",[]), @@ -115,7 +116,7 @@ class cl_build_scripts(build_scripts): './scripts/execserv', './scripts/execsamba'] backup_build_dir = self.build_dir - backup_scripts = filter(lambda x: not x in scripts, self.scripts) + backup_scripts = [x for x in self.scripts if x not in scripts] self.scripts = scripts self.build_dir = self.build_dir + "-bin" build_scripts.run(self) From 0642ae894b0fecfafdbe1b4923f70cac2bf079d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Tue, 31 Aug 2021 15:13:30 +0300 Subject: [PATCH 04/24] lxml changes --- pym/cl_base.py | 24 +- pym/cl_ldap.py | 181 ++++--- pym/cl_profile.py | 919 ++++++++++++++++++------------------ pym/cl_vars_server.py | 20 +- pym/cl_xml.py | 1045 +++++++++++++++++++++++++++++++++++++++++ setup.py | 13 +- 6 files changed, 1615 insertions(+), 587 deletions(-) create mode 100644 pym/cl_xml.py diff --git a/pym/cl_base.py b/pym/cl_base.py index a827c8d..1995d36 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -25,13 +25,14 @@ import types import string #import os import filecmp -import ConfigParser +# import ConfigParser import time import socket #import sys import random import string from . import cl_utils +from .cl_xml import firstChild ############################################################################## _expand_lang = gettext._expand_lang @@ -389,14 +390,14 @@ class iniParser(cl_profile._error): return self.checkIni allAreas = objIni.docObj.getAllAreas() for xmlArea in allAreas: - parentNode = xmlArea.parentNode - if parentNode and parentNode.tagName == "area": + parentNode = xmlArea.getparent() + if parentNode is not None and parentNode.tagName == "area": self.checkIni = "plasma" break if self.checkIni == "samba": objIni = cl_profile.samba(textIni) xmlBody = objIni.docObj.getNodeBody() - if not xmlBody.firstChild: + if firstChild(xmlBody) is None: self.checkIni = False return self.checkIni @@ -539,12 +540,12 @@ class iniParser(cl_profile._error): nSect = objIni.docObj.getNameArea(xmlNode) if nSect: namesSect = [nSect] - parentNode = xmlNode.parentNode + parentNode = xmlNode.getparent() while parentNode != objIni.docObj.body: nameSect = objIni.docObj.getNameArea(parentNode) - if nameSect: + if nameSect is not None: namesSect.append(nameSect) - parentNode = parentNode.parentNode + parentNode = parentNode.getparent() else: return [] namesSection.append(",".join(reversed(namesSect))) @@ -1103,9 +1104,9 @@ class DataVars(): def printVars(self,type_names=None): var=None var=self.getVars(type_names) - mlen_name=0; - mlen_type=0; - mlen_mode=0; + mlen_name=0 + mlen_type=0 + mlen_mode=0 for i,j in var.items(): if len(i)>mlen_name: mlen_name=len(i) @@ -1145,6 +1146,9 @@ class DataVars(): #mlen_type, p_val) print(br) + + + ############################################################################## class glob_attr: """Глобальные аттрибуты для методов заполнения переменных""" diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 947e7ea..8487df4 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -1,5 +1,3 @@ -#-*- coding: utf-8 -*- - # Copyright 2008-2010 Mir Calculate. http://www.calculate-linux.org # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +16,8 @@ import os import sys import re import ldap -import cStringIO, StringIO +# import cStringIO, StringIO +from io import StringIO, BytesIO from ldif import LDIFParser, LDIFWriter from . import cl_base from . import cl_profile @@ -41,14 +40,12 @@ import tempfile # Вывод в строку ввода import readline # Пути в XML документе -from xml import xpath +# from xml import xpath +from .cl_xml import xpath, firstChild # Для 32 битного целого (генерация серийного номера DNS зоны) import ctypes from functools import reduce -#TODO delete this -_ = lambda x: x - Version = "calculate-server 2.1.20" tr = cl_base.lang() @@ -136,7 +133,7 @@ class report: for i in range(lenLines): char = " | " if i == 0 or i == 2 or i == lenLines-1: - char ="-+-" + char = "-+-" convLines.append(self._insertStrChar(lines[i], lenCols, char)) print("\n".join(convLines)) print("(%s %s)"%(len(self.dataList), _("rows"))) @@ -200,7 +197,7 @@ class iniLdapParser(cl_base.iniParser): class addLdif(LDIFParser): """Класс необходимый для добавления записей в LDAP""" def __init__(self, strInput,ldapCon): - FD = cStringIO.StringIO(strInput) + FD = StringIO(strInput) LDIFParser.__init__(self, FD) self.ldapCon = ldapCon @@ -677,17 +674,17 @@ in a sambaDomainName', %delBackDir) return True - def stringIsJpeg(self, string): - """Определяет является ли строка jpeg изображением""" - if len(string)<8: + def dataIsJpeg(self, bytes): + """Определяет является ли набор байтов jpeg изображением""" + if len(bytes)<8: return False - FD = cStringIO.StringIO(string) + FD = BytesIO(bytes) isJpeg = False FD.seek(0, 0) (firstByte, secondByte) = FD.read(2) - if (ord(firstByte) == 0xff and ord(secondByte) == 0xd8): + if (firstByte == 0xff and secondByte == 0xd8): (firstByte, secondByte) = FD.read(2) - if (ord(firstByte) == 0xff and ord(secondByte) == 0xe0): + if (firstByte == 0xff and secondByte == 0xe0): isJpeg = True return isJpeg @@ -1122,7 +1119,7 @@ in a sambaDomainName', """Добавляем jpeg фотографию пользователя в LDAP""" import subprocess try: - FD = open(photoPath) + FD = open(photoPath, "rb") photoData = FD.read() FD.close() except: @@ -1134,7 +1131,7 @@ in a sambaDomainName', _("not found")) return False modAttrs = [] - if not self.stringIsJpeg(photoData): + if not self.dataIsJpeg(photoData): if self.execProg("which convert") is False: self.printERROR(_("Can not found package imagemagick")) return False @@ -1155,7 +1152,7 @@ in a sambaDomainName', fErr.close() if not flagError: photoData = fOut.read() - if not self.stringIsJpeg(photoData): + if not self.dataIsJpeg(photoData): self.printERROR(\ _("Can not convert file '%s' in jpeg format") %photoPath) flagError = True @@ -14445,7 +14442,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): if xmlNodes: masterIPNode = xmlNodes[0] xmlNodes = xpath.Evaluate( "child::value", masterIPNode) - ips = (x.firstChild.nodeValue.strip() for x in xmlNodes) + ips = (firstChild(x).nodeValue.strip() for x in xmlNodes) flagAddIPs = True slaveIPs.append(",".join(ips)) if not flagAddIPs: @@ -14510,7 +14507,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): if xmlNodes: masterIPNode = xmlNodes[0] xmlNodes = xpath.Evaluate( "child::value", masterIPNode) - ipMasterServers = [x.firstChild.nodeValue.strip() for x in xmlNodes] + ipMasterServers = [firstChild(x).nodeValue.strip() for x in xmlNodes] if not ipMasterServers: self.printERROR(_("The program does not support information \ for %s DNS zone")%zoneName) @@ -16460,9 +16457,9 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if not namesArea: return [] return [x for x in namesArea - if x.firstChild and x.firstChild.nodeValue and\ - len(x.firstChild.nodeValue) > 4 and\ - 'host' in x.firstChild.nodeValue[:4]] + if firstChild(x) is not None and firstChild(x).nodeValue and\ + len(firstChild(x).nodeValue) > 4 and\ + 'host' in firstChild(x).nodeValue[:4]] def getAllXMLSubnet(self): """Получаем все XML ноды подсетей""" @@ -16474,16 +16471,16 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if not namesArea: return [] return [x for x in namesArea - if x.firstChild and x.firstChild.nodeValue and\ - len(x.firstChild.nodeValue) > 6 and\ - 'subnet' in x.firstChild.nodeValue[:6]] + if firstChild(x) is not None and firstChild(x).nodeValue and\ + len(firstChild(x).nodeValue) > 6 and\ + 'subnet' in firstChild(x).nodeValue[:6]] def getDataInAllHost(self): """Получить информацию о статических хостах""" if self.getError(): return False allXmlNames = self._getAllXMLStaticHosts() - allXmlAreas = [x.parentNode.parentNode for x in allXmlNames] + allXmlAreas = [x.getparent().getparent() for x in allXmlNames] # Информация dataHost = [] iterXmlNames = iter(allXmlNames) @@ -16491,9 +16488,9 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): #print xmlArea.toprettyxml() # Ност xmlNodeName = next(iterXmlNames) - strNameNode = xmlNodeName.firstChild.nodeValue + strNameNode = firstChild(xmlNodeName).nodeValue # название хоста - hostname = strNameNode.partition("host")[2].strip().encode("UTF-8") + hostname = strNameNode.partition("host")[2].strip() # Параметры статического хоста dataPars = self.dataParsHost.copy() # Заполняем словарь dataPars реальными параметрами @@ -16507,7 +16504,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if self.getError(): return False allXmlNames = self.getAllXMLSubnet() - allXmlAreas = [x.parentNode.parentNode for x in allXmlNames] + allXmlAreas = [x.getparent().getparent() for x in allXmlNames] # Информация dataNet = [] iterXmlNames = iter(allXmlNames) @@ -16515,13 +16512,13 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): # Сеть xmlNodeName = next(iterXmlNames) # Название области - strNameNode = xmlNodeName.firstChild.nodeValue + strNameNode = firstChild(xmlNodeName).nodeValue # ip сети netIP = strNameNode.partition("subnet")[2].partition("netmask")[0] - netIP = netIP.encode("UTF-8") + # netIP = netIP.encode("UTF-8") # Маска сети netMask = strNameNode.partition("subnet")[2].partition("netmask")[2] - netMask = netMask.encode("UTF-8") + # netMask = netMask.encode("UTF-8") # Параметры сети dataPars = self.dataParsNet.copy() # Заполняем словарь dataPars реальными параметрами @@ -16569,9 +16566,9 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): for node in nodesFind: nodesXml = xpath.Evaluate("child::value", node) for nodeFind in nodesXml: - if nodeFind.firstChild: - listOpt = [x.encode("UTF-8") for x - in nodeFind.firstChild.nodeValue.replace("\t"," ").split(" ") if x] + if firstChild(nodeFind) is not None: + listOpt = [x for x + in firstChild(nodeFind).nodeValue.replace("\t"," ").split(" ") if x] dataPars[opt] = listOpt return dataPars @@ -16585,8 +16582,8 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if not xmlStaticHosts: return [] slpHostName = 'host%s' %hostName.lower() - return [x.parentNode.parentNode for x in xmlStaticHosts - if slpHostName == x.firstChild.nodeValue.lower()] + return [x.getparent().getparent() for x in xmlStaticHosts + if slpHostName == firstChild(x).nodeValue.lower()] def getXMLNet(self, net): """Получить XML ноду подсети по ip""" @@ -16598,9 +16595,9 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): return [] slpNetName = 'subnet%s' %net.lower() lenSlpNetName = len(slpNetName) - return [x.parentNode.parentNode for x in xmlSubnets - if len(x.firstChild.nodeValue) > lenSlpNetName and - slpNetName == x.firstChild.nodeValue[:lenSlpNetName].lower()] + return [x.getparent().getparent() for x in xmlSubnets + if len(firstChild(x).nodeValue) > lenSlpNetName and + slpNetName == firstChild(x).nodeValue[:lenSlpNetName].lower()] def createStaticHost(self, hostname, ip, mac): """Создает статический хост в файле конфигурации dhcp""" @@ -16611,7 +16608,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): xmlNodeBodyNewNet = dhcpObj.docObj.getNodeBody() namesAreaNew = xpath.Evaluate("child::area/child::caption/child::name", xmlNodeBodyNewNet) - splNameNewNode = namesAreaNew[0].firstChild.nodeValue + splNameNewNode = firstChild(namesAreaNew[0]).nodeValue hostnameNode = splNameNewNode.partition("host")[2].strip() if self.getXMLStaticHost(hostnameNode): self.setError(_('DHCP static host "%s" exists')%hostnameNode) @@ -16627,10 +16624,10 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if self.getError(): return False namesArea = xpath.Evaluate("child::caption/child::name", xmlNode) - splNameNewNode = namesArea[0].firstChild.nodeValue + splNameNewNode = firstChild(namesArea[0]).nodeValue netIPList = splNameNewNode.partition("subnet")[2].partition("netmask") - netIP = netIPList[0].strip().encode("UTF-8") - netMask = netIPList[2].partition("{")[0].strip().encode("UTF-8") + netIP = netIPList[0].strip() + netMask = netIPList[2].partition("{")[0].strip() if not any((routers, domainName, dnsIPs, iprange)): self.setError(_("empty modify options")) return False @@ -16641,7 +16638,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): # Объединение конфигураций self.join(dhcpObj) # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) def modHostOpts(self, xmlNode, ip, mac): @@ -16649,8 +16646,8 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if self.getError(): return False namesArea = xpath.Evaluate("child::caption/child::name", xmlNode) - splNameNewNode = namesArea[0].firstChild.nodeValue - hostname = splNameNewNode.partition("host")[2].strip().encode("UTF-8") + splNameNewNode = firstChild(namesArea[0]).nodeValue + hostname = splNameNewNode.partition("host")[2].strip() if not any((ip, mac)): self.setError(_("empty modify options")) return False @@ -16659,7 +16656,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): # Объединение конфигураций self.join(dhcpObj) # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) def createNet(self, net, routers, domainNames, dnsIPs, ipranges): @@ -16681,30 +16678,30 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): xmlNodeBodyNewNet = dhcpObj.docObj.getNodeBody() namesAreaNew = xpath.Evaluate("child::area/child::caption/child::name", xmlNodeBodyNewNet) - splNameNewNode = namesAreaNew[0].firstChild.nodeValue + splNameNewNode = firstChild(namesAreaNew[0]).nodeValue netIP = splNameNewNode.partition("subnet")[2].partition("netmask")[0] - netIP = netIP.encode("UTF-8") + # netIP = netIP.encode("UTF-8") if self.getXMLNet(netIP): self.setError(_('DHCP subnet "%s" exists')%netIP) return False # Объединение конфигураций self.join(dhcpObj) # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) def deleteAllNetAndHosts(self): """Удаляет все сети и статические хосты из конфигурационного файла""" # IP всех сетей - delNamesNets = [x.firstChild.nodeValue.partition("subnet")[2].\ - partition("netmask")[0].encode("UTF-8") + delNamesNets = [firstChild(x).nodeValue.partition("subnet")[2].\ + partition("netmask")[0] for x in self.getAllXMLSubnet() - if x.firstChild] + if firstChild(x) is not None] # Имена всех статических хостов - delNamesHosts = [x.firstChild.nodeValue.partition("host")[2].\ - strip().encode("UTF-8") + delNamesHosts = [firstChild(x).nodeValue.partition("host")[2].\ + strip() for x in self._getAllXMLStaticHosts() - if x.firstChild] + if firstChild(x) is not None] # Удаление for term in (self.deleteNet(x) for x in delNamesNets): if not term: @@ -16726,8 +16723,8 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): return False # Удаление областей xmlNodeBody = self.docObj.getNodeBody() - nextNode = lambda x: x.nextSibling - prevNode = lambda x: x.previousSibling + nextNode = lambda x: x.getnext() + prevNode = lambda x: x.getprevious() delNodesNext = [] delNodesPrev = [] for node in deletesNodes: @@ -16757,10 +16754,10 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): delNodesNext.pop() delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк - [xmlNodeBody.removeChild(x) for x in delNodes] + [xmlNodeBody.remove(x) for x in delNodes] #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области - for term in (xmlNodeBody.removeChild(x) for x in deletesNodes): + for term in (xmlNodeBody.remove(x) for x in deletesNodes): if not term: self.setError(_('Can not remove static host "%s"')%hostname+\ " " + _("in config file %s")%self.nameConfigFile) @@ -16781,8 +16778,8 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): return False # Удаление областей xmlNodeBody = self.docObj.getNodeBody() - nextNode = lambda x: x.nextSibling - prevNode = lambda x: x.previousSibling + nextNode = lambda x: x.getnext() + prevNode = lambda x: x.getprevious() delNodesNext = [] delNodesPrev = [] for node in deletesNodes: @@ -16812,16 +16809,16 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): delNodesNext.pop() delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк - [xmlNodeBody.removeChild(x) for x in delNodes] + [xmlNodeBody.remove(x) for x in delNodes] #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области - for term in (xmlNodeBody.removeChild(x) for x in deletesNodes): + for term in (xmlNodeBody.remove(x) for x in deletesNodes): if not term: self.setError(_('Can not remove subnet "%s"')%net+\ " " + _("in config file %s")%self.nameConfigFile) return False # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) class dnsTxt(cl_profile.bind,shareTxt): @@ -16883,8 +16880,8 @@ class dnsTxt(cl_profile.bind,shareTxt): if not namesArea: return [] return [x for x in namesArea - if x.firstChild and x.firstChild.nodeValue and\ - 'zone"' in x.firstChild.nodeValue] + if firstChild(x) is not None and firstChild(x).nodeValue and\ + 'zone"' in firstChild(x).nodeValue] def getXMLZoneToName(self, nameZone): """Получить XML ноду DNS зоны по ее имени""" @@ -16897,10 +16894,10 @@ class dnsTxt(cl_profile.bind,shareTxt): if not xmlZonesNames: return [] nameZoneL = nameZone.lower() - return [x.parentNode.parentNode + return [x.getparent().getparent() for x in xmlZonesNames if nameZoneL == \ - x.firstChild.nodeValue.lower().partition('"')[2].partition('"')[0]] + firstChild(x).nodeValue.lower().partition('"')[2].partition('"')[0]] def getAllNamesZones(self): """Получить все имена нод областей (кроме служебных)""" @@ -16912,16 +16909,16 @@ class dnsTxt(cl_profile.bind,shareTxt): if not xmlZonesNames: return retNodesNames for nodeZone in xmlZonesNames: - if '"."' in nodeZone.firstChild.nodeValue.lower(): + if '"."' in firstChild(nodeZone).nodeValue.lower(): continue - elif '"localhost"' in nodeZone.firstChild.nodeValue.lower(): + elif '"localhost"' in firstChild(nodeZone).nodeValue.lower(): continue - elif '"127.in-addr.arpa"' in nodeZone.firstChild.nodeValue.lower(): + elif '"127.in-addr.arpa"' in firstChild(nodeZone).nodeValue.lower(): continue retNodesNames.append(\ - nodeZone.firstChild.nodeValue.rpartition('"')[0].partition('"')[2]) + firstChild(nodeZone).nodeValue.rpartition('"')[0].partition('"')[2]) retNodesNames = [x for x in retNodesNames if x] - return [x.encode("UTF-8") for x in retNodesNames] + return retNodesNames def deleteZone(self, zoneName): """Удаляет зону из конфигурационного файла bind""" @@ -16935,8 +16932,8 @@ class dnsTxt(cl_profile.bind,shareTxt): return False # Удаление областей xmlNodeBody = self.docObj.getNodeBody() - nextNode = lambda x: x.nextSibling - prevNode = lambda x: x.previousSibling + nextNode = lambda x: x.getnext() + prevNode = lambda x: x.getprevious() delNodesNext = [] delNodesPrev = [] for node in deletesNodes: @@ -16966,16 +16963,16 @@ class dnsTxt(cl_profile.bind,shareTxt): delNodesNext.pop() delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк - [xmlNodeBody.removeChild(x) for x in delNodes] + [xmlNodeBody.remove(x) for x in delNodes] #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области - for term in [xmlNodeBody.removeChild(x) for x in deletesNodes]: + for term in [xmlNodeBody.remove(x) for x in deletesNodes]: if not term: self.setError(_('Can not remove DNS zone "%s"')%zoneName+\ " " + _("in config file %s")%self.nameConfigFile) return False # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) def deleteAllZones(self, functPrintSuccess=False): @@ -16995,7 +16992,7 @@ class dnsTxt(cl_profile.bind,shareTxt): if not xmlZonesNames: return True for nodeZone in xmlZonesNames: - nodeValue = nodeZone.firstChild.nodeValue.lower() + nodeValue = firstChild(nodeZone).nodeValue.lower() if '"."' in nodeValue: continue elif '"localhost"' in nodeValue: @@ -17003,14 +17000,14 @@ class dnsTxt(cl_profile.bind,shareTxt): elif '"127.in-addr.arpa"' in nodeValue: continue else: - nodeValue = nodeValue.encode("UTF-8") + # nodeValue = nodeValue.encode("UTF-8") # Название зоны nameZ = nodeValue.rpartition('"')[0].partition('"')[2] - deletesNodes.append((nodeZone.parentNode.parentNode,nameZ)) + deletesNodes.append((nodeZone.getparent().getparent(), nameZ)) # Удаление областей xmlNodeBody = self.docObj.getNodeBody() - nextNode = lambda x: x.nextSibling - prevNode = lambda x: x.previousSibling + nextNode = lambda x: x.getnext() + prevNode = lambda x: x.getprevious() delNodesNext = [] delNodesPrev = [] for node, zoneNameTmp in deletesNodes: @@ -17043,11 +17040,11 @@ class dnsTxt(cl_profile.bind,shareTxt): if not delNode in delNodes: delNodes.append(delNode) # Удаляем переводы строк - [xmlNodeBody.removeChild(x) for x in delNodes] + [xmlNodeBody.remove(x) for x in delNodes] #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области for delNode, zoneName in deletesNodes: - if xmlNodeBody.removeChild(delNode): + if xmlNodeBody.remove(delNode): # Печатаем сообщение о успешном удалении зоны if flagPrintSuccess: functPrintSuccess(zoneName) @@ -17056,7 +17053,7 @@ class dnsTxt(cl_profile.bind,shareTxt): " " + _("in config file %s")%self.nameConfigFile) return False # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) def createZone(self, clVars, zoneName, zoneType, zoneMasters=[]): @@ -17072,7 +17069,7 @@ class dnsTxt(cl_profile.bind,shareTxt): namesAreaNew = xpath.Evaluate(\ "child::area/child::caption/child::name", xmlNodeBodyNewZone) splNameNewNode =\ - namesAreaNew[0].firstChild.nodeValue.replace("{","").split('"') + firstChild(namesAreaNew[0]).nodeValue.replace("{","").split('"') splNameNewNode = splNameNewNode[1] if self.getXMLZoneToName(splNameNewNode): self.setError(_('DNS zone "%s" exists')%splNameNewNode) @@ -17080,7 +17077,7 @@ class dnsTxt(cl_profile.bind,shareTxt): # Объединение конфигураций self.join(bindObj) # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) def notFoundZones(self, zoneNames): @@ -20211,7 +20208,7 @@ class servDhcp(shareLdap, shareIP): self.printERROR("Can not found network %s in network interfaces: \ eth0, eth1, ... etc."%net) if osNets: - self.printWARNING(_("Existing nets: %s")%osNets) + self.printWARNING(_("Existing nets: %s") % osNets) return False def isCorrectMacAddress(self, mac): diff --git a/pym/cl_profile.py b/pym/cl_profile.py index 32c47cc..a1abf1c 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -19,17 +19,21 @@ import os from . import cl_base import stat import re -import xml.dom.minidom -import xml -if hasattr(xml,"use_pyxml"): - xml.use_pyxml() -from xml import xpath +# import xml.dom.minidom +# import xml + +# if hasattr(xml,"use_pyxml"): +# xml.use_pyxml() +# from xml import xpath +from . import cl_xml +from .cl_xml import xpath, firstChild, insertBefore, str_to_xml_doc import subprocess import types import copy import random import string import time +from copy import deepcopy tr = cl_base.lang() tr.setLocalDomain('cl_lib') @@ -38,9 +42,6 @@ tr.setLanguage(sys.modules[__name__]) def cmp(a, b): return (a > b) - (b < a) -#TODO remove this -_ = lambda x: x - class _error: # Здесь ошибки, если они есть error = [] @@ -116,7 +117,7 @@ class _terms(_error): listEqual = [] for k in trm.keys(): if k in term: - term = term.replace(k,trm[k]) + term = term.replace(k, trm[k]) trs = term.split(" ") for t in trs: flagRule = False @@ -133,7 +134,7 @@ class _terms(_error): flagLog = True break if not flagLog: - self.setError("'%s'"%term + " " + _("incorrect")) + self.setError("'%s'" % term + " " + _("incorrect")) self.setError (textError) return False else: @@ -612,13 +613,12 @@ class objShare: def getConfig(self): """Выдает конфигурационный файл""" listConfigTxt = [] - childNodes = self.docObj.getNodeBody().childNodes + childNodes = list(self.docObj.getNodeBody()) for node in childNodes: - if node.nodeType == node.ELEMENT_NODE: - if node.tagName == "field": - listConfigTxt.append(self.docObj.getQuoteField(node)) - elif node.tagName == "area": - self.docObj.xmlToText([node], listConfigTxt) + if node.tagName == "field": + listConfigTxt.append(self.docObj.getQuoteField(node)) + elif node.tagName == "area": + self.docObj.xmlToText([node], listConfigTxt) return "".join(listConfigTxt) @@ -697,7 +697,7 @@ class xmlShare: element = doc.createElement(tagName) if text: txtNode = doc.createTextNode(self._toUNICODE(text)) - element.appendChild(txtNode) + element.append(txtNode) for attr in attributes.keys(): attribute = doc.createAttribute(attr) attribute.nodeValue = attributes[attr] @@ -743,13 +743,13 @@ class xmlCaption: tmpNode = xmlNode() self.caption = tmpNode.createNode(doc, "caption") nameNode = tmpNode.createNode(doc, "name",name) - self.caption.appendChild(nameNode) + self.caption.append(nameNode) if action: actNode = tmpNode.createNode(doc, "action", action) - self.caption.appendChild(actNode) + self.caption.append(actNode) for q in quotes: quoteNode = tmpNode.createNode(doc, "quote", q) - self.caption.appendChild(quoteNode) + self.caption.append(quoteNode) return self.caption def getCaption(self): @@ -771,16 +771,16 @@ class xmlField(xmlShare): self.field = self._createElement(doc, "field", "", {"type":typeField}) if name: nameNode = self._createElement(doc, "name", name) - self.field.appendChild(nameNode) + self.field.append(nameNode) for v in values: valueNode = self._createElement(doc, "value", v) - self.field.appendChild(valueNode) + self.field.append(valueNode) if action: actNode = self._createElement(doc, "action", action) - self.field.appendChild(actNode) + self.field.append(actNode) for q in quotes: quoteNode = self._createElement(doc, "quote", q) - self.field.appendChild(quoteNode) + self.field.append(quoteNode) return self.field @@ -815,11 +815,11 @@ class xmlArea: tmpNode = xmlNode() self.area = tmpNode.createNode(doc, "area") if xmlCaption and xmlCaption.getCaption(): - self.area.appendChild(xmlCaption.getCaption()) + self.area.append(xmlCaption.getCaption()) if xmlFields: fields = xmlFields.getFields() for field in fields: - self.area.appendChild(field) + self.area.append(field) return self.area class xmlDoc: @@ -920,25 +920,25 @@ class xmlDoc: def setActionField(self, xmlField, actionTxt): """Устанавливает свойство action для XML поля""" xmlActions = xpath.Evaluate('child::action',xmlField) - if xmlActions and xmlActions[0].firstChild: - xmlActions[0].firstChild.nodeValue = actionTxt + if xmlActions is not None and firstChild(xmlActions[0]): + firstChild(xmlActions[0]).nodeValue = actionTxt else: nodeObj = xmlNode() newNode = nodeObj.createNode(self.doc, "action", actionTxt) - xmlField.appendChild(newNode) + xmlField.append(newNode) def setActionArea(self, xmlArea, actionTxt): """Устанавливает свойство action для XML области""" xmlActions = xpath.Evaluate('child::caption/action',xmlArea) xmlCaptions = xpath.Evaluate('child::caption',xmlArea) - if xmlActions and xmlActions[0].firstChild: - xmlActions[0].firstChild.nodeValue = actionTxt + if xmlActions is not None and firstChild(xmlActions[0]): + firstChild(xmlActions[0]).nodeValue = actionTxt else: if xmlCaptions: nodeObj = xmlNode() newNode = nodeObj.createNode(self.doc, "action", actionTxt) - xmlCaptions[0].appendChild(newNode) + xmlCaptions[0].append(newNode) def joinField(self, xmlArea, xmlNewField): """Объединяет XML ноду область и XML ноду поле""" @@ -952,7 +952,7 @@ class xmlDoc: if not fieldsOldComp and typeNewField != "seplist": if self.getActionField(xmlNewField) != "drop": self.setActionField(xmlNewField, "append") - xmlArea.appendChild(xmlNewField) + xmlArea.append(xmlNewField) return True newFieldsAction = self.getActionField(xmlNewField) newValues = self.getFieldValues(xmlNewField) @@ -960,13 +960,13 @@ class xmlDoc: for nodeFieldOld in fieldsOldComp: if newFieldsAction == "drop": - if nodeFieldOld.nextSibling and\ - self.getTypeField(nodeFieldOld.nextSibling) == "br": - xmlArea.removeChild(nodeFieldOld.nextSibling) - elif nodeFieldOld.previousSibling and\ - self.getTypeField(nodeFieldOld.previousSibling) == "br": - xmlArea.removeChild(nodeFieldOld.previousSibling) - xmlArea.removeChild(nodeFieldOld) + if nodeFieldOld.getnext() and\ + self.getTypeField(nodeFieldOld.getnext()) == "br": + xmlArea.remove(nodeFieldOld.getnext()) + elif nodeFieldOld.getprevious() and\ + self.getTypeField(nodeFieldOld.getprevious()) == "br": + xmlArea.remove(nodeFieldOld.getprevious()) + xmlArea.remove(nodeFieldOld) continue oldValues = self.getFieldValues(nodeFieldOld) # Сравнение значений переменной профиля и файла @@ -995,8 +995,8 @@ class xmlDoc: flagCompareSeplist = True break if not flagCompareSeplist: - nextNode = xmlOldField.nextSibling - newInsNode = nodeSeplist.cloneNode(True) + nextNode = xmlOldField.getnext() + newInsNode = deepcopy(nodeSeplist) self.setActionField(newInsNode,"append") if nextNode: @@ -1008,7 +1008,7 @@ class xmlDoc: False, "append")) else: - newInsNode = nodeSeplist.cloneNode(True) + newInsNode = deepcopy(nodeSeplist) if self.getActionField(newInsNode) == "join": self.setActionField(newInsNode,"append") if xmlOldField: @@ -1024,8 +1024,8 @@ class xmlDoc: #nodeSeplist.cloneNode(True), #xmlOldField) - parentNode = nodeSeplist.parentNode - parentNode.removeChild(nodeSeplist) + parentNode = nodeSeplist.getparent() + parentNode.remove(nodeSeplist) insNodesRepl = [] for newNode, nxtNode, app in insSplLst: @@ -1038,31 +1038,30 @@ class xmlDoc: flagCompareSeplist = True break if not flagCompareSeplist: - if xmlOldField: + if xmlOldField is not None: insNodesRepl.append((newNode, nxtNode, app)) for newNode, nxtNode, app in insNodesRepl: if app == "insert": - xmlArea.insertBefore(newNode,nxtNode) + insertBefore(xmlArea, newNode, nxtNode) elif app == "append": - xmlArea.appendChild(newNode) + xmlArea.append(newNode) if xmlOldField: - parentNode = xmlOldField.parentNode + parentNode = xmlOldField.getparent() if parentNode and newFieldsAction != "join": - parentNode.removeChild(xmlOldField) + parentNode.remove(xmlOldField) for newNode, nxtNode, app in appSplLst: if app == "insert": - xmlArea.insertBefore(newNode,nxtNode) + insertBefore(xmlArea, newNode, nxtNode) elif app == "append": - xmlArea.appendChild(newNode) + xmlArea.append(newNode) if not flagCompare and typeNewField != "seplist": # Устанавливаем action=replace self.setActionField(xmlNewField, "replace") # Если параметры поля не сходятся заменяем поле - xmlArea.replaceChild(xmlNewField.cloneNode(True), - fieldsOldComp[-1]) + xmlArea.replace(fieldsOldComp[-1], deepcopy(xmlNewField)) if newFieldsAction == "join": fieldsOldRemove = [] @@ -1074,10 +1073,10 @@ class xmlDoc: if actionOldNode == "insert" or actionOldNode == "append": pass else: - if nodeFieldOld.nextSibling and\ - self.getTypeField(nodeFieldOld.nextSibling) == "br": - xmlArea.removeChild(nodeFieldOld.nextSibling) - xmlArea.removeChild(nodeFieldOld) + if nodeFieldOld.getnext() and\ + self.getTypeField(nodeFieldOld.getnext()) == "br": + xmlArea.remove(nodeFieldOld.getnext()) + xmlArea.remove(nodeFieldOld) return True @@ -1090,9 +1089,9 @@ class xmlDoc: nameField = self.getNameField(xmlField) if not nameField: return [] - parentNode = xmlField.parentNode + parentNode = xmlField.getparent() #print parentNode.toprettyxml() - if parentNode: + if parentNode is not None: fieldsVal = xpath.Evaluate(\ "child::field[attribute::type='seplist'][child::name='%s'] "\ %(nameField), parentNode) @@ -1105,11 +1104,11 @@ class xmlDoc: """Удаляет комментарии в XML области""" fieldNodes = xpath.Evaluate('descendant::field',xmlArea) for fieldNode in fieldNodes: - if fieldNode.hasAttribute("type"): - if fieldNode.getAttribute("type") == "comment" or\ - fieldNode.getAttribute("type") == "br": - parentNode = fieldNode.parentNode - parentNode.removeChild(fieldNode) + if "type" in fieldNode.keys(): + if fieldNode.get("type") == "comment" or\ + fieldNode.get("type") == "br": + parentNode = fieldNode.getparent() + parentNode.remove(fieldNode) else: if self.getActionField(fieldNode) == "drop": pass @@ -1198,7 +1197,7 @@ class xmlDoc: removeNodes = removeNodes[:-2] for removeNode in removeNodes: - xmlOldArea.removeChild(removeNode) + xmlOldArea.remove(removeNode) for node in sepListField: node.setAttribute("type", "seplist") if not (self.getActionField(node) == "join" or\ @@ -1207,13 +1206,13 @@ class xmlDoc: self.joinField(xmlOldArea, node) #else: #self.setActionField(node, "append") - #baseBody.appendChild(node) + #baseBody.append(node) for node in notSepListField: if self.getTypeField(node) == "seplist": #if removeNodesDict.has_key(self.getNameField(node)): #print removeNodesDict[self.getNameField(node)] self.setActionField(node, "append") - xmlOldArea.appendChild(node) + xmlOldArea.append(node) else: self.joinField(xmlOldArea, node) @@ -1223,10 +1222,10 @@ class xmlDoc: return False areaNodes = xpath.Evaluate('descendant::area',xmlArea) for areaNode in areaNodes: - prevNode = areaNode.previousSibling + prevNode = areaNode.getprevious() if prevNode: - parentNode = areaNode.parentNode - parentNode.insertBefore(self.sepAreas.cloneNode(True), + parentNode = areaNode.getparent() + insertBefore(parentNode, deepcopy(self.sepAreas), areaNode) return True @@ -1242,15 +1241,15 @@ class xmlDoc: if not namesAreaComare: return False fields = xpath.Evaluate("child::field/child::name", - namesAreaComare[0].parentNode) + namesAreaComare[0].getparent()) dictVar = {} for fieldName in fields: - nodeField = fieldName.parentNode + nodeField = fieldName.getparent() fieldValue = xpath.Evaluate("child::value",nodeField) - name = fieldName.firstChild.nodeValue + name = firstChild(fieldName).nodeValue value = "" - if fieldValue and fieldValue[0].firstChild: - value = fieldValue[0].firstChild.nodeValue + if fieldValue is not None and firstChild(fieldValue[0]): + value = firstChild(fieldValue[0]).nodeValue dictVar[name] = value return dictVar @@ -1266,14 +1265,14 @@ class xmlDoc: for areaComp in namesAreaComare: fieldsVal = xpath.Evaluate(\ "child::field[child::name='%s'] "\ - %(nameField), areaComp.parentNode) + %(nameField), areaComp.getparent()) if fieldsVal: break if not fieldsVal: return False fieldValue = xpath.Evaluate("child::value", fieldsVal[0]) - return fieldValue[0].firstChild.nodeValue + return firstChild(fieldValue[0]).nodeValue def getAllAreas(self): """Выдает все области""" @@ -1284,7 +1283,7 @@ class xmlDoc: namesAreaComare = xpath.Evaluate(\ "child::area/child::caption[child::name='%s']" %(nameArea), xmlArea) - return [x.parentNode for x in namesAreaComare] + return [x.getparent() for x in namesAreaComare] def joinArea(self, baseNode, xmlNewArea): @@ -1293,26 +1292,26 @@ class xmlDoc: fieldsRemove = xpath.Evaluate(\ "descendant::field[child::action='drop']", xmlNewArea) for rmNode in fieldsRemove: - parentNode = rmNode.parentNode - parentNode.removeChild(rmNode) + parentNode = rmNode.getparent() + parentNode.remove(rmNode) captionAreasRemove = xpath.Evaluate(\ "descendant::area/child::caption[child::action='drop']", xmlNewArea) for rmNodeCapt in captionAreasRemove: - rmNode = rmNodeCapt.parentNode - parentNode = rmNode.parentNode - parentNode.removeChild(rmNode) + rmNode = rmNodeCapt.getparent() + parentNode = rmNode.getparent() + parentNode.remove(rmNode) self.setActionArea(xmlNewArea, "append") # Добавляем разделитель областей во вложенные области areaNodes = xpath.Evaluate('descendant::area',xmlNewArea) for areaNode in areaNodes: self.setActionArea(areaNode,"append") - parentNode = areaNode.parentNode - parentNode.insertBefore(self.sepAreas.cloneNode(True), + parentNode = areaNode.getparent() + insertBefore(parentNode, deepcopy(self.sepAreas), areaNode) - baseNode.appendChild(xmlNewArea) + baseNode.append(xmlNewArea) # Добавляем разделитель областей - baseNode.insertBefore(self.sepAreas.cloneNode(True), xmlNewArea) + insertBefore(baseNode, deepcopy(self.sepAreas), xmlNewArea) nodesNames = xpath.Evaluate('child::area/caption/name',baseNode) nodesNewArea = xpath.Evaluate('child::caption/name',xmlNewArea) @@ -1326,42 +1325,41 @@ class xmlDoc: if not nodesNames or not nodesNewArea: return False nameArea = "" - if nodesNewArea[0].firstChild: - nameArea = nodesNewArea[0].firstChild.nodeValue.strip() + if firstChild(nodesNewArea[0]): + nameArea = firstChild(nodesNewArea[0]).nodeValue.strip() flagFindArea = False baseNodes = [] for oName in nodesNames: newAreaAction = self.getActionArea(xmlNewArea) - oArea = oName.parentNode.parentNode + oArea = oName.getparent().getparent() oNameTxt = "" - if oName.firstChild: - oNameTxt = oName.firstChild.nodeValue + if firstChild(oName) is not None: + oNameTxt = firstChild(oName).nodeValue if nameArea == oNameTxt: flagFindArea = True # При использовании удаления if newAreaAction == "drop": - prevNode = oName.parentNode.parentNode.previousSibling + prevNode = oName.getparent().getparent().getprevious() removePrevNodes = [] while (prevNode) and self.getTypeField(prevNode) == "br": removePrevNodes.append(prevNode) - prevNode = prevNode.previousSibling + prevNode = prevNode.getprevious() for removeNode in removePrevNodes: - baseNode.removeChild(removeNode) - baseNode.removeChild(oName.parentNode.parentNode) + baseNode.remove(removeNode) + baseNode.remove(oName.getparent().getparent()) continue elif newAreaAction == "replace": - oldAreaNode = oName.parentNode.parentNode + oldAreaNode = oName.getparent().getparent() newAreaCaption = xpath.Evaluate('child::caption', xmlNewArea)[0] oldAreaCaption = xpath.Evaluate('child::caption', oldAreaNode)[0] if newAreaCaption and oldAreaCaption: - xmlNewArea.replaceChild(oldAreaCaption,newAreaCaption) + xmlNewArea.replace(newAreaCaption, oldAreaCaption) self.setActionArea(xmlNewArea,"replace") - baseNode.replaceChild(xmlNewArea, - oldAreaNode) + baseNode.replace(oldAreaNode, xmlNewArea) continue - baseNodes.append(oName.parentNode.parentNode) + baseNodes.append(oName.getparent().getparent()) newFields = xpath.Evaluate('child::field',xmlNewArea) joinNewFields = xpath.Evaluate(\ @@ -1399,45 +1397,44 @@ class xmlDoc: """Выдает текст из поля""" xmlQuotes = xpath.Evaluate('child::quote',xmlField) br = "" - if xmlField.hasAttribute("type") and\ - xmlField.getAttribute("type") == "br": + if "type" in xmlField.keys() and\ + xmlField.get("type") == "br": br = "\n" if xmlQuotes: field = xmlQuotes[0] - if field.firstChild: - return field.firstChild.nodeValue + br + if firstChild(field) is not None: + return firstChild(field).nodeValue + br return "" + br def getFieldsArea(self, xmlArea): """Выдает потомков XML области""" xmlFields = [] - childNodes = xmlArea.childNodes + childNodes = list(xmlArea) for node in childNodes: - if node.nodeType == node.ELEMENT_NODE: - if node.tagName == "area" or node.tagName == "field": - xmlFields.append(node) + if node.tagName == "area" or node.tagName == "field": + xmlFields.append(node) return xmlFields def getTypeField(self, xmlField): """Выдает тип поля""" - if xmlField.hasAttribute("type"): - return xmlField.getAttribute("type") + if "type" in xmlField.keys(): + return xmlField.get("type") else: return False def getNameField(self, xmlField): """Выдает имя поля""" xmlNameFields = xpath.Evaluate('child::name', xmlField) - if xmlNameFields and xmlNameFields[0].firstChild: - return xmlNameFields[0].firstChild.nodeValue + if xmlNameFields is not None and firstChild(xmlNameFields[0]): + return firstChild(xmlNameFields[0]).nodeValue else: return False def getNameArea(self, xmlArea): """Выдает имя области""" xmlNameAreas = xpath.Evaluate('child::caption/name', xmlArea) - if xmlNameAreas and xmlNameAreas[0].firstChild: - return xmlNameAreas[0].firstChild.nodeValue + if xmlNameAreas is not None and firstChild(xmlNameAreas[0]): + return firstChild(xmlNameAreas[0]).nodeValue else: return False @@ -1447,8 +1444,8 @@ class xmlDoc: quotes = [] xmlQuotes = xpath.Evaluate('child::caption/quote',xmlArea) for node in xmlQuotes: - if node.firstChild: - quotes.append(node.firstChild.nodeValue) + if firstChild(node) is not None: + quotes.append(firstChild(node).nodeValue) if len(quotes) == 0: quotes.append("") quotes.append("") @@ -1483,8 +1480,8 @@ class xmlDoc: def getActionField(self, xmlField): """Выдает свойство action XML поля""" xmlActions = xpath.Evaluate('child::action',xmlField) - if xmlActions and xmlActions[0].firstChild: - return xmlActions[0].firstChild.nodeValue + if xmlActions is not None and firstChild(xmlActions[0]): + return firstChild(xmlActions[0]).nodeValue else: return False @@ -1494,24 +1491,24 @@ class xmlDoc: xmlValues = xpath.Evaluate('child::value',xmlField) if xmlValues: for node in xmlValues: - if node.firstChild: - vals.append(node.firstChild.nodeValue) + if firstChild(node) is not None: + vals.append(firstChild(node).nodeValue) return vals def getActionArea(self, xmlArea): """Выдает свойство action XML области""" xmlActions = xpath.Evaluate('child::caption/action',xmlArea) - if xmlActions and xmlActions[0].firstChild: - return xmlActions[0].firstChild.nodeValue + if xmlActions is not None and firstChild(xmlActions[0]): + return firstChild(xmlActions[0]).nodeValue else: return False def delActionNodeArea(self, xmlArea): """Удаляет свойство action XML области""" xmlActions = xpath.Evaluate('child::caption/action',xmlArea) - if xmlActions and xmlActions[0].firstChild: - parentNode = xmlActions[0].parentNode - parentNode.removeChild(xmlActions[0]) + if xmlActions is not None and firstChild(xmlActions[0]): + parentNode = xmlActions[0].getparent() + parentNode.remove(xmlActions[0]) return True else: return False @@ -1519,9 +1516,9 @@ class xmlDoc: def delActionNodeField(self, xmlField): """Удаляет свойство action XML поля""" xmlActions = xpath.Evaluate('child::action',xmlField) - if xmlActions and xmlActions[0].firstChild: - parentNode = xmlActions[0].parentNode - parentNode.removeChild(xmlActions[0]) + if xmlActions is not None and firstChild(xmlActions[0]): + parentNode = xmlActions[0].getparent() + parentNode.remove(xmlActions[0]) return True else: return False @@ -1539,8 +1536,8 @@ class xmlDoc: else: fieldName = False xmlFieldNameNodes = xpath.Evaluate('child::name',node) - if xmlFieldNameNodes and xmlFieldNameNodes[0].firstChild: - fieldName = xmlFieldNameNodes[0].firstChild.nodeValue + if xmlFieldNameNodes is not None and firstChild(xmlFieldNameNodes[0]): + fieldName = firstChild(xmlFieldNameNodes[0]).nodeValue if fieldName: if fieldName in fieldsSeplist: fieldsSeplist[fieldName].append(node) @@ -1574,20 +1571,19 @@ class xmlDoc: if self.getActionArea(node) == "append" or\ self.getActionArea(node) == "join": self.delActionNodeArea(node) - if lastNode and lastNode.hasAttribute("type") and\ - lastNode.getAttribute("type") == "br" or\ - lastNode and lastNode.hasAttribute("type") and\ - lastNode.getAttribute("type") == "comment": + if lastNode and "type" in lastNode.keys() and\ + lastNode.get("type") == "br" or\ + lastNode and "type" in lastNode.keys() and\ + lastNode.get("type") == "comment": indNext = i + 1 if indNext == lenChildNodes: - xmlArea.appendChild(fieldXMLBr.cloneNode(True)) + xmlArea.append(deepcopy(fieldXMLBr)) else: nextNode = childNodes[indNext] - lastTmpNode = xmlArea.insertBefore(\ - fieldXMLBr.cloneNode(True), + lastTmpNode = insertBefore(xmlArea, deepcopy(fieldXMLBr), nextNode) else: - xmlArea.insertBefore(fieldXMLBr.cloneNode(True), + insertBefore(xmlArea, deepcopy(fieldXMLBr), node) self.insertBRtoBody(node) # Нода field @@ -1595,20 +1591,20 @@ class xmlDoc: if self.getActionField(node) == "append" or\ self.getActionField(node) == "join": self.delActionNodeField(node) - if lastNode and lastNode.hasAttribute("type") and\ - lastNode.getAttribute("type") == "br" or\ - lastNode and lastNode.hasAttribute("type") and\ - lastNode.getAttribute("type") == "comment": + if lastNode and "type" in lastNode.keys() and\ + lastNode.get("type") == "br" or\ + lastNode and "type" in lastNode.keys() and\ + lastNode.get("type") == "comment": indNext = i + 1 if indNext == lenChildNodes: - xmlArea.appendChild(fieldXMLBr.cloneNode(True)) + xmlArea.append(deepcopy(fieldXMLBr)) else: nextNode = childNodes[indNext] - lastTmpNode = xmlArea.insertBefore(\ - fieldXMLBr.cloneNode(True), + lastTmpNode = insertBefore(xmlArea, + deepcopy(fieldXMLBr), nextNode) else: - xmlArea.insertBefore(fieldXMLBr.cloneNode(True), + insertBefore(xmlArea, deepcopy(fieldXMLBr), node) lastNode = lastTmpNode @@ -1628,31 +1624,31 @@ class xmlDoc: for xmlField in xmlFields: xmlNames = xpath.Evaluate('child::name',xmlField) xmlVals = xpath.Evaluate('child::value',xmlField) - if xmlField.hasAttribute("type") and\ - xmlField.getAttribute("type") == "br": + if "type" in xmlField.keys() and\ + xmlField.get("type") == "br": lenBrArea += 1 continue if not xmlNames and not xmlVals: flagListXml = False break - if xmlNames and xmlNames[0].firstChild and\ - xmlNames[0].firstChild.nodeValue: + if xmlNames and firstChild(xmlNames[0]) is not None and\ + firstChild(xmlNames[0]).nodeValue: flagListXml = False break - if not (xmlVals and xmlVals[0].firstChild and\ - xmlVals[0].firstChild.nodeValue): + if not (xmlVals and firstChild(xmlVals[0]) is not None and\ + firstChild(xmlVals[0]).nodeValue): flagListXml = False break else: - fieldValues.append(xmlVals[0].firstChild.nodeValue) + fieldValues.append(firstChild(xmlVals[0]).nodeValue) if lenXmlFields == lenBrArea: flagListXml = False if flagListXml: nameNode = xpath.Evaluate('child::caption/name',xmlArea)[0] fieldName = "" - if nameNode.firstChild: - fieldName = nameNode.firstChild.nodeValue + if firstChild(nameNode) is not None: + fieldName = firstChild(nameNode).nodeValue listArea = [] self.xmlToText([xmlArea],listArea) fieldQuote = "".join(listArea) @@ -1667,11 +1663,11 @@ class xmlDoc: areaAction = self.getActionArea(xmlArea) if areaAction: self.setActionField(fieldXML, areaAction) - parentNode = xmlArea.parentNode - parentNode.insertBefore(fieldXML,xmlArea) + parentNode = xmlArea.getparent() + insertBefore(parentNode, fieldXML, xmlArea) if fieldXMLBr: - parentNode.insertBefore(fieldXMLBr,xmlArea) - parentNode.removeChild(xmlArea) + insertBefore(parentNode, fieldXMLBr, xmlArea) + parentNode.remove(xmlArea) class blocText: @@ -4440,18 +4436,18 @@ class samba(objShare): #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": + if xmlArea.getprevious() and\ + self.docObj.getTypeField(xmlArea.getprevious()) == "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", + if xmlArea.getnext(): + parentNode = xmlArea.getparent() + nextNode = xmlArea.getnext() + insertBefore(parentNode, self.docObj.createField("br", [],"",[], False,False), nextNode) @@ -4469,7 +4465,7 @@ class samba(objShare): lenBr = 0 # Удаление for rmNode in removeBrNodes: - self.docObj.body.removeChild(rmNode) + self.docObj.body.remove(rmNode) def join(self, sambaObj): @@ -4657,11 +4653,11 @@ class samba(objShare): area = docObj.createArea() if areaAction: docObj.setActionArea(area, areaAction) - rootNode.appendChild(area) + rootNode.append(area) else: fieldsNodes = docObj.tmpFields.getFields() for fieldNode in fieldsNodes: - rootNode.appendChild(fieldNode) + rootNode.append(fieldNode) docObj.clearTmpFields() z += 1 #print docObj.doc.toprettyxml() @@ -4887,14 +4883,14 @@ class bind(objShare): self.createXML(f.fields, areaXMLChild, docObj) - areaXML.appendChild(areaXMLChild) + areaXML.append(areaXMLChild) else: self.createXML(f.fields, areaXML, docObj) if "\n" in f.end: fieldXMLBr = docObj.createField("br",[], "",[], False, False) - areaXML.appendChild(fieldXMLBr) + areaXML.append(fieldXMLBr) else: if not f: continue @@ -4904,18 +4900,18 @@ class bind(objShare): fieldXML = self.createFieldTerm(field.name, field.value, field.br, docObj) - areaXML.appendChild(fieldXML) + areaXML.append(fieldXML) if field.br[-1] == "\n": fieldXMLBr = docObj.createField("br",[], "",[], False, False) - areaXML.appendChild(fieldXMLBr) + areaXML.append(fieldXMLBr) elif field.comment != False: fieldXML = docObj.createField("comment", [field.comment], "", [], False, False) - areaXML.appendChild(fieldXML) + areaXML.append(fieldXML) elif field.br != False: brText = field.br.replace("\n","") if brText: @@ -4928,15 +4924,15 @@ class bind(objShare): [], "", [], False, False) - areaXML.appendChild(fieldXML) + areaXML.append(fieldXML) if i.header and i.start: - rootNode.appendChild(areaXML) + rootNode.append(areaXML) if "\n" in i.end: fieldXMLBr = docObj.createField("br",[], "",[], False, False) - rootNode.appendChild(fieldXMLBr) + rootNode.append(fieldXMLBr) else: fields = self.splitToFields(i) @@ -4945,17 +4941,17 @@ class bind(objShare): fieldXML = self.createFieldTerm(field.name, field.value, field.br, docObj) - rootNode.appendChild(fieldXML) + rootNode.append(fieldXML) if field.br[-1] == "\n": fieldXMLBr = docObj.createField("br",[],"", [], False, False) - rootNode.appendChild(fieldXMLBr) + rootNode.append(fieldXMLBr) elif field.comment != False: fieldXML = docObj.createField("comment", [field.comment], "", [], False, False) - rootNode.appendChild(fieldXML) + rootNode.append(fieldXML) elif field.br != False: brText = field.br.replace("\n","") if brText: @@ -4964,8 +4960,8 @@ class bind(objShare): else: fieldXML = docObj.createField('br', [], "", [], False, False) - rootNode.appendChild(fieldXML) - #rootNode.appendChild(areaXML) + rootNode.append(fieldXML) + #rootNode.append(areaXML) def textToXML(self): """Преобразуем текст в XML""" @@ -5025,7 +5021,7 @@ class apache(bind): xmlFields = xpath.Evaluate("child::fields", self.docObj.body) if not (xmlFields and\ self.docObj.getTypeField(xmlFields[-1]) == "br"): - self.docObj.body.appendChild(self.docObj.createField("br", + self.docObj.body.append(self.docObj.createField("br", [],"",[], False,False)) xmlAreas = xpath.Evaluate("child::area", self.docObj.body) @@ -5033,7 +5029,7 @@ class apache(bind): xmlFields = xpath.Evaluate("child::field", xmlArea) if not (xmlFields and\ self.docObj.getTypeField(xmlFields[-1]) == "br"): - xmlArea.appendChild(self.docObj.createField("br", + xmlArea.append(self.docObj.createField("br", [],"",[], False,False)) @@ -5438,11 +5434,11 @@ class ldap(samba): area = docObj.createArea() if areaAction: docObj.setActionArea(area, areaAction) - rootNode.appendChild(area) + rootNode.append(area) else: fieldsNodes = docObj.tmpFields.getFields() for fieldNode in fieldsNodes: - rootNode.appendChild(fieldNode) + rootNode.append(fieldNode) docObj.clearTmpFields() z += 1 #print docObj.doc.toprettyxml() @@ -5478,7 +5474,7 @@ class dovecot(bind): if xmlFields and not (\ self.docObj.getTypeField(xmlFields[-1]) == "br" or\ self.docObj.getTypeField(xmlFields[-1]) == "comment"): - xmlArea.appendChild(self.docObj.createField("br", + xmlArea.append(self.docObj.createField("br", [],"",[], False,False)) xmlAreas = xpath.Evaluate("child::area", xmlArea) @@ -5653,18 +5649,18 @@ class procmail(objShare): fieldXML = self.createFieldTerm(field.name, field.value, field.br, docObj) - nodeBody.appendChild(fieldXML) + nodeBody.append(fieldXML) if field.br[-1] == "\n": fieldXMLBr = docObj.createField("br",[], "",[], False, False) - nodeBody.appendChild(fieldXMLBr) + nodeBody.append(fieldXMLBr) elif field.comment != False: fieldXML = docObj.createField("comment", [field.comment], "", [], False, False) - nodeBody.appendChild(fieldXML) + nodeBody.append(fieldXML) elif field.br != False: brText = field.br.replace("\n","") if brText: @@ -5677,7 +5673,7 @@ class procmail(objShare): [], "", [], False, False) - nodeBody.appendChild(fieldXML) + nodeBody.append(fieldXML) return docObj def join(self, procmailObj): @@ -5787,11 +5783,11 @@ class kde(samba): area = docObj.createArea() if areaAction: docObj.setActionArea(area, areaAction) - rootNode.appendChild(area) + rootNode.append(area) else: fieldsNodes = docObj.tmpFields.getFields() for fieldNode in fieldsNodes: - rootNode.appendChild(fieldNode) + rootNode.append(fieldNode) docObj.clearTmpFields() z += 1 #print docObj.doc.toprettyxml() @@ -5813,26 +5809,26 @@ class xmlDocPlasma: fieldsRemove = xpath.Evaluate(\ "descendant::field[child::action='drop']", xmlNewArea) for rmNode in fieldsRemove: - parentNode = rmNode.parentNode - parentNode.removeChild(rmNode) + parentNode = rmNode.getparent() + parentNode.remove(rmNode) captionAreasRemove = xpath.Evaluate(\ "descendant::area/child::caption[child::action='drop']", xmlNewArea) for rmNodeCapt in captionAreasRemove: - rmNode = rmNodeCapt.parentNode - parentNode = rmNode.parentNode - parentNode.removeChild(rmNode) + rmNode = rmNodeCapt.getparent() + parentNode = rmNode.getparent() + parentNode.remove(rmNode) self.setActionArea(xmlNewArea, "append") # Добавляем разделитель областей во вложенные области areaNodes = xpath.Evaluate('descendant::area',xmlNewArea) for areaNode in areaNodes: self.setActionArea(areaNode,"append") - parentNode = areaNode.parentNode - parentNode.insertBefore(self.sepAreas.cloneNode(True), + parentNode = areaNode.getparent() + insertBefore(parentNode, deepcopy(self.sepAreas), areaNode) - baseNode.appendChild(xmlNewArea) + baseNode.append(xmlNewArea) # Добавляем разделитель областей - baseNode.insertBefore(self.sepAreas.cloneNode(True), xmlNewArea) + insertBefore(baseNode, deepcopy(self.sepAreas), xmlNewArea) nodesNames = xpath.Evaluate('child::area/caption/name',baseNode) nodesNewArea = xpath.Evaluate('child::caption/name',xmlNewArea) @@ -5846,55 +5842,54 @@ class xmlDocPlasma: if not nodesNames or not nodesNewArea: return False nameArea = "" - if nodesNewArea[0].firstChild: - nameArea = nodesNewArea[0].firstChild.nodeValue.strip() + if firstChild(nodesNewArea[0]) is not None: + nameArea = firstChild(nodesNewArea[0]).nodeValue.strip() flagFindArea = False baseNodes = [] for oName in nodesNames: newAreaAction = self.getActionArea(xmlNewArea) - oArea = oName.parentNode.parentNode + oArea = oName.getparent().getparent() oNameTxt = "" - if oName.firstChild: - oNameTxt = oName.firstChild.nodeValue + if firstChild(oName) is not None: + oNameTxt = firstChild(oName).nodeValue if nameArea == oNameTxt: flagFindArea = True # При использовании удаления if newAreaAction == "drop": - prevNode = oName.parentNode.parentNode.previousSibling + prevNode = oName.getparent().getparent().getprevious() removePrevNodes = [] while (prevNode) and self.getTypeField(prevNode) == "br": removePrevNodes.append(prevNode) - prevNode = prevNode.previousSibling + prevNode = prevNode.getprevious() for removeNode in removePrevNodes: - baseNode.removeChild(removeNode) - baseNode.removeChild(oName.parentNode.parentNode) + baseNode.remove(removeNode) + baseNode.remove(oName.getparent().getparent()) continue elif newAreaAction == "replace": - oldAreaNode = oName.parentNode.parentNode + oldAreaNode = oName.getparent().getparent() newAreaCaption = xpath.Evaluate('child::caption', xmlNewArea)[0] oldAreaCaption = xpath.Evaluate('child::caption', oldAreaNode)[0] if newAreaCaption and oldAreaCaption: - xmlNewArea.replaceChild(oldAreaCaption,newAreaCaption) + xmlNewArea.replace(newAreaCaption, oldAreaCaption) self.setActionArea(xmlNewArea,"replace") - baseNode.replaceChild(xmlNewArea, - oldAreaNode) + baseNode.replace(oldAreaNode, xmlNewArea) continue - baseNodes.append(oName.parentNode.parentNode) + baseNodes.append(oName.getparent().getparent()) # Заменяем QUOTE - oldAreaNode = oName.parentNode.parentNode + oldAreaNode = oName.getparent().getparent() oldAreaQuote = xpath.Evaluate('child::caption/quote', oldAreaNode)[0] if oldAreaQuote and\ - not oldAreaQuote.firstChild: + firstChild(oldAreaQuote) is None: newAreaQuote = xpath.Evaluate('child::caption/quote', xmlNewArea)[0] oldAreaCaption = xpath.Evaluate('child::caption', oldAreaNode)[0] if newAreaQuote and oldAreaCaption: - oldAreaCaption.replaceChild(newAreaQuote, oldAreaQuote) + oldAreaCaption.replace(oldAreaQuote, newAreaQuote) newFields = xpath.Evaluate('child::field',xmlNewArea) @@ -6143,14 +6138,14 @@ class plasma(samba): self.createXML(f.fields, areaXMLChild, docObj) - areaXML.appendChild(areaXMLChild) + areaXML.append(areaXMLChild) else: self.createXML(f.fields, areaXML, docObj) if "\n" in f.end: fieldXMLBr = docObj.createField("br",[], "",[], False, False) - areaXML.appendChild(fieldXMLBr) + areaXML.append(fieldXMLBr) else: if not f: continue @@ -6160,18 +6155,18 @@ class plasma(samba): fieldXML = self.createFieldTerm(field.name, field.value, field.br, docObj) - areaXML.appendChild(fieldXML) + areaXML.append(fieldXML) if field.br[-1] == "\n": fieldXMLBr = docObj.createField("br",[], "",[], False, False) - areaXML.appendChild(fieldXMLBr) + areaXML.append(fieldXMLBr) elif field.comment != False: fieldXML = docObj.createField("comment", [field.comment], "", [], False, False) - areaXML.appendChild(fieldXML) + areaXML.append(fieldXML) elif field.br != False: brText = field.br.replace("\n","") if brText: @@ -6185,15 +6180,15 @@ class plasma(samba): "", [], False, False) if areaXML: - areaXML.appendChild(fieldXML) + areaXML.append(fieldXML) if i.header: - rootNode.appendChild(areaXML) + rootNode.append(areaXML) if "\n" in i.end: fieldXMLBr = docObj.createField("br",[], "",[], False, False) - rootNode.appendChild(fieldXMLBr) + rootNode.append(fieldXMLBr) else: if not i: @@ -6204,17 +6199,17 @@ class plasma(samba): fieldXML = self.createFieldTerm(field.name, field.value, field.br, docObj) - rootNode.appendChild(fieldXML) + rootNode.append(fieldXML) if field.br[-1] == "\n": fieldXMLBr = docObj.createField("br",[],"", [], False, False) - rootNode.appendChild(fieldXMLBr) + rootNode.append(fieldXMLBr) elif field.comment != False: fieldXML = docObj.createField("comment", [field.comment], "", [], False, False) - rootNode.appendChild(fieldXML) + rootNode.append(fieldXML) elif field.br != False: brText = field.br.replace("\n","") if brText: @@ -6223,8 +6218,8 @@ class plasma(samba): else: fieldXML = docObj.createField('br', [], "", [], False, False) - rootNode.appendChild(fieldXML) - #rootNode.appendChild(areaXML) + rootNode.append(fieldXML) + #rootNode.append(areaXML) def createTxtConfig(self, strHeader, dictVar): @@ -6272,8 +6267,8 @@ class plasma(samba): quotes = [] xmlQuotes = xpath.Evaluate('child::caption/quote',xmlArea) for node in xmlQuotes: - if node.firstChild: - quotes.append(node.firstChild.nodeValue) + if firstChild(node) is None: + quotes.append(firstChild(node).nodeValue) if len(quotes) == 0: quotes.append("") quotes.append("") @@ -6291,21 +6286,21 @@ class plasma(samba): if getQuotesArea(xmlArea) == ["",""]: #areaTXT = xpath.Evaluate("child::caption/name", xmlArea)[0] #print "CL_AREA", areaTXT.firstChild - if xmlArea.previousSibling and\ - self.docObj.getTypeField(xmlArea.previousSibling) == "br": - parentNode = xmlArea.previousSibling.parentNode - if xmlArea.previousSibling.previousSibling and\ - self.docObj.getTypeField(xmlArea.previousSibling.previousSibling) == "br": - parentNode.removeChild(\ - xmlArea.previousSibling.previousSibling) - parentNode.removeChild(xmlArea.previousSibling) - if xmlArea.nextSibling and\ - self.docObj.getTypeField(xmlArea.nextSibling) == "br": - parentNode = xmlArea.nextSibling.parentNode - if xmlArea.nextSibling.nextSibling and\ - self.docObj.getTypeField(xmlArea.nextSibling.nextSibling) == "br": - parentNode.removeChild(xmlArea.nextSibling.nextSibling) - parentNode.removeChild(xmlArea.nextSibling) + if xmlArea.getprevious() and\ + self.docObj.getTypeField(xmlArea.getprevious()) == "br": + parentNode = xmlArea.getprevious().getparent() + if xmlArea.getprevious().getprevious() and\ + self.docObj.getTypeField(xmlArea.getprevious().getprevious()) == "br": + parentNode.remove(\ + xmlArea.getprevious().getprevious()) + parentNode.remove(xmlArea.getprevious()) + if xmlArea.getnext() and\ + self.docObj.getTypeField(xmlArea.getnext()) == "br": + parentNode = xmlArea.getnext().getparent() + if xmlArea.getnext().getnext() and\ + self.docObj.getTypeField(xmlArea.getnext().getnext()) == "br": + parentNode.remove(xmlArea.getnext().getnext()) + parentNode.remove(xmlArea.getnext()) continue # Собираем поля в кучку @@ -6313,12 +6308,12 @@ class plasma(samba): if xmlChildAreas: childNodes = self.docObj.getFieldsArea(xmlArea) firstChildArea = xmlChildAreas[0] - if firstChildArea.previousSibling and\ - self.docObj.getTypeField(firstChildArea.previousSibling)=="br": - if firstChildArea.previousSibling.previousSibling: + if firstChildArea.getprevious() and\ + self.docObj.getTypeField(firstChildArea.getprevious())=="br": + if firstChildArea.getprevious().getprevious(): if self.docObj.getTypeField(\ - firstChildArea.previousSibling.previousSibling)=="br": - firstChildArea = firstChildArea.previousSibling + firstChildArea.getprevious().getprevious())=="br": + firstChildArea = firstChildArea.getprevious() flagFoundArea = False it = 0 lenChild = len(childNodes) @@ -6329,18 +6324,18 @@ class plasma(samba): continue if flagFoundArea and node.tagName == "field": if self.docObj.getTypeField(node) == "var": - xmlArea.insertBefore(node, firstChildArea) + insertBefore(xmlArea, node, firstChildArea) if it < lenChild: if self.docObj.getTypeField(childNodes[it])==\ "br": - xmlArea.insertBefore(childNodes[it], + insertBefore(xmlArea, childNodes[it], firstChildArea) # Добавление перевода строк в если его нет между полями if self.docObj.getTypeField(node) == "var" and\ - node.previousSibling and\ - not (self.docObj.getTypeField(node.previousSibling) in\ + node.getprevious() and\ + not (self.docObj.getTypeField(node.getprevious()) in\ ("br","comment")): - xmlArea.insertBefore(self.docObj.createField("br", + insertBefore(xmlArea, self.docObj.createField("br", [],"",[], False,False), node) @@ -6351,44 +6346,44 @@ class plasma(samba): (self.docObj.getTypeField(xmlFields[0]) == "br" or\ self.docObj.getTypeField(xmlFields[0]) == "comment")): if xmlFields: - xmlArea.insertBefore(self.docObj.createField("br", + insertBefore(xmlArea, self.docObj.createField("br", [],"",[], False,False), xmlFields[0]) # Если последним полем BR, удаляем его if xmlFields and self.docObj.getTypeField(xmlFields[-1]) == "br": - #print "DEL_BR", xmlFields[-1].nextSibling + #print "DEL_BR", xmlFields[-1].getnext() #and\ - if not xmlFields[-1].nextSibling: - xmlArea.removeChild(xmlFields[-1]) + if not xmlFields[-1].getnext(): + xmlArea.remove(xmlFields[-1]) # Если предыдущим полем не (BR или комментарий) - добавляем BR - if xmlArea.previousSibling and\ - not (self.docObj.getTypeField(xmlArea.previousSibling) == "br" or\ - self.docObj.getTypeField(xmlArea.previousSibling) == "comment"): - parentNode = xmlArea.parentNode - parentNode.insertBefore(self.docObj.createField("br", + if xmlArea.getprevious() and\ + not (self.docObj.getTypeField(xmlArea.getprevious()) == "br" or\ + self.docObj.getTypeField(xmlArea.getprevious()) == "comment"): + parentNode = xmlArea.getparent() + insertBefore(parentNode, self.docObj.createField("br", [],"",[], False,False), xmlArea) # Если есть предыдущее поле, и поле предыдущеее предыдущему # не равно BR или комментарий то добавляем BR - if xmlArea.previousSibling: - prPrSibling = xmlArea.previousSibling.previousSibling + if xmlArea.getprevious(): + prPrSibling = xmlArea.getprevious().getprevious() if prPrSibling and\ not (self.docObj.getTypeField(prPrSibling) == "br" or\ self.docObj.getTypeField(prPrSibling) == "comment"): - parentNode = xmlArea.parentNode - parentNode.insertBefore(self.docObj.createField("br", + parentNode = xmlArea.getparent() + insertBefore(parentNode, self.docObj.createField("br", [],"",[], False,False), xmlArea) # Если после есть BR а за ним ничего нет, удаляем BR - if xmlArea.nextSibling and\ - self.docObj.getTypeField(xmlArea.nextSibling) == "br": - if not xmlArea.nextSibling.nextSibling: - parentNode = xmlArea.nextSibling.parentNode - parentNode.removeChild(xmlArea.nextSibling) + if xmlArea.getnext() and\ + self.docObj.getTypeField(xmlArea.getnext()) == "br": + if not xmlArea.getnext().getnext(): + parentNode = xmlArea.getnext().getparent() + parentNode.remove(xmlArea.getnext()) def join(self, kdeObj): @@ -6467,27 +6462,28 @@ class xml_xfce(_error): Также удаляет аттрибут action у всех нод """ flagError = False - childNodes = xmlNode.childNodes - if xmlNode.nodeType ==xmlNode.ELEMENT_NODE: - if xmlNode.hasAttribute("action"): - nAction = xmlNode.getAttribute("action") - if not nAction in ("join","replace","drop"): - textError = _('''In the text, XML profile, look \ -for a reserved attribute 'action' with the incorrect value.\n\ -Valid values attribute 'action': \ -(action="join", action="replace", action="drop")''') - self.setError(textError) - return False - xmlNode.removeAttribute("action") - if nAction == "drop": - parentNode = xmlNode.parentNode - if parentNode: - parentNode.removeChild(xmlNode) - if childNodes: - for node in childNodes: - if not self._removeDropNodesAndAttrAction(node): - flagError = True - break + childNodes = list(xmlNode) + if "action" in xmlNode.keys(): + nAction = xmlNode.get("action") + if not nAction in ("join","replace","drop"): + textError = _("In the text of the XML template, " + "reserved attribute 'action' comes with an " + "incorrect value.\n" + "Valid values of the 'action' attribute are: " + '(action="join", action="replace",' + 'action="drop")') + self.setError(textError) + return False + xmlNode.removeAttribute("action") + if nAction == "drop": + parentNode = xmlNode.getparent() + if parentNode: + parentNode.remove(xmlNode) + if childNodes: + for node in childNodes: + if not self._removeDropNodesAndAttrAction(node): + flagError = True + break if flagError: return False return True @@ -6498,124 +6494,114 @@ Valid values attribute 'action': \ self._removeDropNodesAndAttrAction(self.bodyNode) def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True): - """Объединение корневой ноды профиля и корневой ноды файла""" + """Объединение корневой ноды шаблона и корневой ноды файла""" xmlNode = xmlNewNode - childNodes = xmlNode.childNodes + childNodes = list(xmlNode) nextOldNode = xmlOldNode - flagError = False - if xmlNode.nodeType ==xmlNode.ELEMENT_NODE: - n = xmlNode - path = u'' - nName = u'' - nType = u'' - nValue = u'' - nAction = u'' - attrName = '' - attrType = '' - path = n.tagName - if n.hasAttribute("name"): - nName = n.getAttribute("name") - attrName = u"attribute::name='%s'"%nName - if n.hasAttribute("type"): - nType = n.getAttribute("type") - attrType = u"attribute::type='%s'"%nType - if n.hasAttribute("value"): - nValue = n.getAttribute("value") - if n.hasAttribute("action"): - nAction = n.getAttribute("action") - if not nAction in ("join","replace","drop"): - textError = _('''In the text, XML profile, look \ -for a reserved attribute 'action' with the incorrect value.\n\ -Valid values attribute 'action': \ -(action="join", action="replace", action="drop")''') + # if xmlNode.nodeType == xmlNode.ELEMENT_NODE: + n = xmlNode + nType = '' + nValue = '' + nAction = '' + attrName = '' + attrType = '' + path = n.tag + if "name" in n.keys(): + nName = n.get("name") + attrName = "attribute::name='%s'" % nName + if "type" in n.keys(): + nType = n.get("type") + attrType = "attribute::type='%s'" % nType + if "value" in n.keys(): + nValue = n.get("value") + if "action" in n.keys(): + nAction = n.get("action") + if not nAction in ("join", "replace", "drop"): + textError = _( + "In the text of the XML template, " + "reserved attribute 'action' comes with an " + "incorrect value.\n" + "Valid values of the 'action' attribute are: " + '(action="join", action="replace", action="drop")') + self.setError(textError) + return False + if xmlNewNode.getparent() is not None: + strAttr = [attrName, attrType] + findAttr = [x for x in strAttr if x] + findAttrStr = '' + if findAttr: + strAttr = ' and '.join(findAttr) + findAttrStr = "[%s]" % strAttr + findPath = "child::%s%s" % (path, findAttrStr) + # Рабочая нода + if flagRootNode: + workNode = xmlOldNode.getparent() + else: + workNode = xmlOldNode + oldNodes = xpath.Evaluate(findPath, workNode) + # Новая нода список + flagArray = nType == "array" + flagDrop = False + flagJoin = True + flagReplace = False + if nAction == "replace": + flagJoin = False + flagReplace = True + elif nAction == "drop": + flagJoin = False + flagDrop = True + if flagRootNode: + textError = _('Incorrect action="drop" in ' + 'the root node') self.setError(textError) return False - if xmlOldNode.parentNode: - strAttr = [attrName, attrType] - findAttr = [x for x in strAttr if x] - findAttrStr = '' - if findAttr: - strAttr = u' and '.join(findAttr) - findAttrStr = "[%s]"%strAttr - findPath = u"child::%s%s"%(path,findAttrStr) - # Рабочая нода - if flagRootNode: - workNode = xmlOldNode.parentNode - else: - workNode = xmlOldNode - oldNodes = xpath.Evaluate(findPath, workNode) - #print findPath - #print workNode - #print "----------------------------" - # Новая нода список - flagArray = False - if nType == "array": - flagArray = True - flagDrop = False - flagJoin = True - flagReplace = False - if nAction == "replace": - flagJoin = False - flagReplace = True - elif nAction == "drop": + if oldNodes: + if len(oldNodes) > 1: + textError = _("Ambiguity in this template: " + "the same nodes are on a same level") + self.setError(textError) + return False + nextOldNode = oldNodes[0] + # Замещаем ноду в случае массива + if flagArray and not flagDrop: + replaceXmlNode = deepcopy(xmlNode) + if nAction: + del replaceXmlNode.attrib["action"] + workNode.replace(nextOldNode, replaceXmlNode) flagJoin = False - flagDrop = True - if flagRootNode: - textError = _('Incorrect action="drop" in root node') - self.setError(textError) - return False - if oldNodes: - if len(oldNodes)>1: - textError = _("The uncertainty in this profile are \ -the same nodes at one level") - self.setError(textError) + flagReplace = False + childNodes = False + # Объединение нод + if flagJoin: + if "value" in nextOldNode.keys(): + oValue = nextOldNode.get("value") + if nValue != oValue: + nextOldNode.setAttribute("value", nValue) + # Замещение ноды + elif flagReplace: + replaceXmlNode = deepcopy(xmlNode) + if not self._removeDropNodesAndAttrAction( + replaceXmlNode): return False - nextOldNode = oldNodes[0] - # Замещаем ноду в случае массива - if flagArray and not flagDrop: - replaceXmlNode = xmlNode.cloneNode(True) - if nAction: - replaceXmlNode.removeAttribute("action") - workNode.replaceChild(replaceXmlNode, - nextOldNode) - flagJoin = False - flagReplace = False - childNodes = False - # Объединение нод - if flagJoin: - if nextOldNode.hasAttribute("value"): - oValue = nextOldNode.getAttribute("value") - if nValue != oValue: - nextOldNode.setAttribute("value",nValue) - # Замещение ноды - elif flagReplace: - replaceXmlNode = xmlNode.cloneNode(True) - if not\ - self._removeDropNodesAndAttrAction(replaceXmlNode): - return False - workNode.replaceChild(replaceXmlNode, - nextOldNode) - childNodes = False - # Удаление ноды - elif flagDrop: - workNode.removeChild(nextOldNode) - childNodes = False - else: - # Добавление ноды + workNode.replace(nextOldNode, replaceXmlNode) childNodes = False - if not flagDrop: - appendXmlNode = xmlNode.cloneNode(True) - if not\ - self._removeDropNodesAndAttrAction(appendXmlNode): - return False - workNode.appendChild(appendXmlNode) - if childNodes: - for node in childNodes: - if not self._join(node, nextOldNode, False): - flagError = True - break - if flagError: - return False + # Удаление ноды + elif flagDrop: + workNode.remove(nextOldNode) + childNodes = False + else: + # Добавление ноды + childNodes = False + if not flagDrop: + appendXmlNode = deepcopy(xmlNode) + if not self._removeDropNodesAndAttrAction( + appendXmlNode): + return False + workNode.append(appendXmlNode) + if isinstance(childNodes, Iterable): + for node in childNodes: + if not self._join(node, nextOldNode, False): + return False return True def joinDoc(self, doc): @@ -6629,15 +6615,16 @@ the same nodes at one level") # Импортируем корневую ноду нового документа в текущий документ #newImportBodyNode = self.doc.importNode(doc.documentElement, True) # Объединение корневой ноды профиля и корневой ноды файла - if not self._join(doc.documentElement, self.bodyNode): + if not self._join(doc, self.bodyNode): return False return True - + def getConfig(self): """Получение текстового файла из XML документа""" - data = self.doc.toprettyxml(encoding='UTF-8').split("\n") + data = xml_to_str(self.doc).split("\n") data = [x for x in data if x.strip()] - return "\n".join(data).replace("\t"," ").decode("UTF-8") + data.insert(0, '\n') + return "\n".join(data).replace("\t", " ") class squid(procmail): """Класс для обработки конфигурационного файла типа squid @@ -6723,13 +6710,14 @@ class xml_xfcepanel(xml_xfce): ''' try: - self.doc = xml.dom.minidom.parseString(self.text) + self.doc = str_to_xml_doc(self.text) except: self.setError(_("Can not text profile is XML")) return False - self.rootNode = self.doc.documentElement + self.rootNode = self.doc.getroottree().getroot() self.bodyNode = self.rootNode return self.doc + def setNameBodyNode(self, name): """Пустой метод""" @@ -6738,10 +6726,11 @@ class xml_xfcepanel(xml_xfce): def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0): """Объединение корневой ноды профиля и корневой ноды файла""" xmlNode = xmlNewNode - childNodes = xmlNode.childNodes + childNodes = list(xmlNode) nextOldNode = xmlOldNode flagError = False - if xmlNode.nodeType ==xmlNode.ELEMENT_NODE: + # if xmlNode.nodeType ==xmlNode.ELEMENT_NODE: + if True: n = xmlNode path = u'' nName = u'' @@ -6754,13 +6743,13 @@ class xml_xfcepanel(xml_xfce): if path == "items": flagArray = True if not flagArray: - if n.hasAttribute("name"): - nName = n.getAttribute("name") + if "name" in n.keys(): + nName = n.get("name") attrName = u"attribute::name='%s'"%nName - if n.hasAttribute("value"): - nValue = n.getAttribute("value") - if n.hasAttribute("action"): - nAction = n.getAttribute("action") + if "value" in n.keys(): + nValue = n.get("value") + if "action" in n.keys(): + nAction = n.get("action") if not nAction in ("join","replace","drop"): textError = _('''In the text, XML profile, look \ for a reserved attribute 'action' with the incorrect value.\n\ @@ -6768,14 +6757,14 @@ Valid values attribute 'action': \ (action="join", action="replace", action="drop")''') self.setError(textError) return False - if xmlOldNode.parentNode: + if xmlOldNode.getparent(): findAttrStr = "" if attrName: findAttrStr = "[%s]"%attrName findPath = u"child::%s%s"%(path,findAttrStr) # Рабочая нода if flagRootNode: - workNode = xmlOldNode.parentNode + workNode = xmlOldNode.getparent() else: workNode = xmlOldNode oldNodes = xpath.Evaluate(findPath, workNode) @@ -6819,32 +6808,30 @@ the same nodes at one level") nextOldNode = oldNodes[0] # Замещаем ноду в случае массива if flagArray and not flagDrop: - replaceXmlNode = xmlNode.cloneNode(True) + replaceXmlNode = deepcopy(xmlNode) if nAction: replaceXmlNode.removeAttribute("action") - workNode.replaceChild(replaceXmlNode, - nextOldNode) + workNode.replace(nextOldNode, replaceXmlNode) flagJoin = False flagReplace = False childNodes = False # Объединение нод if flagJoin: - if nextOldNode.hasAttribute("value"): - oValue = nextOldNode.getAttribute("value") + if "value" in nextOldNode.keys(): + oValue = nextOldNode.get("value") if nValue != oValue: nextOldNode.setAttribute("value",nValue) # Замещение ноды elif flagReplace: - replaceXmlNode = xmlNode.cloneNode(True) + replaceXmlNode = deepcopy(xmlNode) if not\ self._removeDropNodesAndAttrAction(replaceXmlNode): return False - workNode.replaceChild(replaceXmlNode, - nextOldNode) + workNode.replace(nextOldNode, replaceXmlNode) childNodes = False # Удаление ноды elif flagDrop: - workNode.removeChild(nextOldNode) + workNode.remove(nextOldNode) childNodes = False else: flagAppend = True @@ -6853,11 +6840,11 @@ the same nodes at one level") # Добавление ноды childNodes = False if not flagDrop: - appendXmlNode = xmlNode.cloneNode(True) + appendXmlNode = deepcopy(xmlNode) if not\ self._removeDropNodesAndAttrAction(appendXmlNode): return False - workNode.appendChild(appendXmlNode) + workNode.append(appendXmlNode) if childNodes: for node in childNodes: levelNumber +=1 @@ -7019,15 +7006,15 @@ class xml_gconf(xml_xfce): """Сравнение содержимого двух списков XML нод""" # getTextsNodes = lambda y: map(lambda x:\ # x.toxml().replace(" ","").replace("\t","").replace("\n",""), - # map(lambda x: x.hasAttribute("mtime") and\ + # map(lambda x: "mtime" in x.keys() and\ # x.removeAttribute("mtime") or x, # map(lambda x: x.cloneNode(True), # filter(lambda x: x.nodeType==x.ELEMENT_NODE, y)))) getTextsNodes = lambda y: [o.toxml().replace(" ","").replace("\t","").replace("\n","") - for o in (z.hasAttribute("mtime") and z.removeAttribute("mtime") or z - for z in (x.cloneNode(True) - for x in y - if x.nodeType==x.ELEMENT_NODE))] + for o in ("mtime" in z.keys() and z.removeAttribute("mtime") or z + for z in (deepcopy(x) + for x in y))] + # if x.nodeType==x.ELEMENT_NODE))] if set(getTextsNodes(listXmlA))==set(getTextsNodes(listXmlB)): return True return False @@ -7037,10 +7024,11 @@ class xml_gconf(xml_xfce): if levelNumber>1: return True xmlNode = xmlNewNode - childNodes = xmlNode.childNodes + childNodes = list(xmlNode) nextOldNode = xmlOldNode flagError = False - if xmlNode.nodeType == xmlNode.ELEMENT_NODE: + # if xmlNode.nodeType == xmlNode.ELEMENT_NODE: + if True: n = xmlNode tagName = n.tagName nAction = u'' @@ -7062,22 +7050,22 @@ class xml_gconf(xml_xfce): self.setError(_("The text is not a valid gconf-XML format \ (found '<%s>..'")%(tagName,tagName)) return False - if not n.hasAttribute("name"): + if not "name" in n.keys(): self.setError(_('Not found arrtibute "name" in tag entry')) return False - flagType = n.hasAttribute("type") + flagType = "type" in n.keys() flagValue = False - flagSchema = n.hasAttribute("schema") + flagSchema = "schema" in n.keys() if flagSchema: - nSchema = n.getAttribute("schema") + nSchema = n.get("schema") if not flagType and not flagSchema: self.setError(_('Not found arrtibute "type" in tag entry')) return False - nName = n.getAttribute("name") + nName = n.get("name") attrName = u"attribute::name='%s'"%nName if flagType: - flagValue = n.hasAttribute("value") - nType = n.getAttribute("type") + flagValue = "value" in n.keys() + nType = n.get("type") # Проверка правильности аттрибута type if not nType in self.supportEntryTypes: self.setError(\ @@ -7085,9 +7073,9 @@ class xml_gconf(xml_xfce): %nType) return False if flagValue: - nValue = n.getAttribute("value") - if n.hasAttribute("action"): - nAction = n.getAttribute("action") + nValue = n.get("value") + if "action" in n.keys(): + nAction = n.get("action") if not nAction in ("join","replace","drop"): textError = _('''In the text, XML profile, look \ for a reserved attribute 'action' with the incorrect value.\n\ @@ -7095,14 +7083,14 @@ Valid values attribute 'action': \ (action="join", action="replace", action="drop")''') self.setError(textError) return False - if xmlOldNode.parentNode: + if xmlOldNode.getparent(): findAttrStr = "" if attrName: findAttrStr = "[%s]"%attrName findPath = u"child::%s%s"%(tagName,findAttrStr) # Рабочая нода if flagRootNode: - workNode = xmlOldNode.parentNode + workNode = xmlOldNode.getparent() else: workNode = xmlOldNode oldNodes = xpath.Evaluate(findPath, workNode) @@ -7137,9 +7125,9 @@ the same nodes at one level") if flagJoin: if flagType and flagValue: flagChange = False - foundValue = nextOldNode.hasAttribute("value") + foundValue = "value" in nextOldNode.keys() if foundValue: - oValue = nextOldNode.getAttribute("value") + oValue = nextOldNode.get("value") if nValue != oValue: flagChange = True else: @@ -7150,9 +7138,9 @@ the same nodes at one level") nextOldNode.setAttribute("value",nValue) elif flagSchema: flagChange = False - foundValue = nextOldNode.hasAttribute("schema") + foundValue = "schema" in nextOldNode.keys() if foundValue: - oSchema = nextOldNode.getAttribute("schema") + oSchema = nextOldNode.get("schema") if nSchema != oSchema: flagChange = True else: @@ -7163,7 +7151,7 @@ the same nodes at one level") nextOldNode.setAttribute("schema",nSchema) # Замещение ноды elif flagReplace: - replaceXmlNode = xmlNode.cloneNode(True) + replaceXmlNode = deepcopy(xmlNode) # Сравнение содержимого нод if not self.cmpListsNodesEntry([replaceXmlNode], [nextOldNode]): @@ -7173,23 +7161,22 @@ the same nodes at one level") self._removeDropNodesAndAttrAction(\ replaceXmlNode): return False - workNode.replaceChild(replaceXmlNode, - nextOldNode) + workNode.replace(nextOldNode, replaceXmlNode) childNodes = False # Удаление ноды elif flagDrop: - workNode.removeChild(nextOldNode) + workNode.remove(nextOldNode) childNodes = False else: # Добавление ноды childNodes = False if not flagDrop: - appendXmlNode = xmlNode.cloneNode(True) + appendXmlNode = deepcopy(xmlNode) appendXmlNode.setAttribute("mtime", self.currentTime) if not\ self._removeDropNodesAndAttrAction(appendXmlNode): return False - workNode.appendChild(appendXmlNode) + workNode.append(appendXmlNode) if childNodes: for node in childNodes: levelNumber +=1 diff --git a/pym/cl_vars_server.py b/pym/cl_vars_server.py index 2eeb339..053967a 100644 --- a/pym/cl_vars_server.py +++ b/pym/cl_vars_server.py @@ -253,24 +253,24 @@ class Data: ld_samba_hash = {} # Директория настроек пользователя windows - sr_samba_winprof_path = {\ - 'value':'/var/calculate/server-data/samba/profiles/win'} + sr_samba_winprof_path = \ + {'value':'/var/calculate/server-data/samba/profiles/win'} # Директория хранения настроек пользователя linux - sr_samba_linprof_path = {\ - 'value':'/var/calculate/server-data/samba/profiles/unix'} + sr_samba_linprof_path = \ + {'value':'/var/calculate/server-data/samba/profiles/unix'} # Домашняя директория - sr_samba_home_path = {\ - 'value':'/var/calculate/server-data/samba/home'} + sr_samba_home_path = \ + {'value':'/var/calculate/server-data/samba/home'} # Директория netlogon - sr_samba_winlogon_path = {\ - 'value':'/var/calculate/server-data/samba/netlogon'} + sr_samba_winlogon_path = \ + {'value':'/var/calculate/server-data/samba/netlogon'} # Директория share - sr_samba_share_path = {\ - 'value':'/var/calculate/server-data/samba/share'} + sr_samba_share_path = \ + {'value':'/var/calculate/server-data/samba/share'} # Настроен или нет сервис Samba sr_samba_set = {'mode':"w", diff --git a/pym/cl_xml.py b/pym/cl_xml.py new file mode 100644 index 0000000..38a5fcd --- /dev/null +++ b/pym/cl_xml.py @@ -0,0 +1,1045 @@ +# -*- coding: utf-8 -*- + +# 2015 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 lxml +from lxml import etree as ET +from copy import deepcopy + +# def append(*args, **kwargs): +# ET._Element.append(*args, **kwargs) + +def display_xml(xml): + print(xml_to_str(xml)) + +def xml_to_str(xml): + return str(ET.tostring(xml, pretty_print=True), encoding="UTF-8") + +def str_to_xml_doc(text): + return ET.XML(bytes(bytearray(text, encoding="UTF-8"))) + +#backwards compat +class xpath(): + @staticmethod + def Evaluate(xpath, xml): + f = ET.XPath(xpath) + return f(xml) + +#can't add methods to Cython lib. +#have to do this the ugly way +def firstChild(element): + if(element.text): + return element + if(len(element) == 0): + return None + return element[0] + +def insertBefore(elem, new_child, ref_child): + + child_parent = new_child.getparent() + if child_parent is not None: + child_parent.remove(new_child) + if(ref_child is None): + elem.append(new_child) + ref_child.addprevious(new_child) + return new_child + +class xmlShare(): + """Общий класс для объектов XML, наследуем + """ + + def _createElement(self, doc, tag, text="", attributes=None): + """Создание нового XML элемента""" + if not isinstance(attributes, dict): + attributes = {} + element = ET.Element(tag, attributes) + if text: + element.text = text + return element + + +class xmlNode(xmlShare): + """Класс для создания нод без аттрибутов + """ + + def __init__(self): + self.node = None + + def createNode(self, doc, tag, text=""): + """Создает XML элемент без аттрибутов""" + self.node = self._createElement(doc, tag, text) + return self.node + + def getNode(self): + return self.node + + def toxml(self, pretty_print=True): + if(self.node is not None): + return ET.tostring(self.node, encoding="UTF-8", pretty_print=pretty_print) + +class xmlCaption(): + """Класс XML заголовок + + """ + + def __init__(self): + # Заголовок области XML нода + self.caption = False + + def createCaption(self, doc, name, quotes, action=None): + """Создание заголовка области""" + tmpNode = xmlNode() + self.caption = tmpNode.createNode(doc, "caption") + nameNode = tmpNode.createNode(doc, "name", name) + self.caption.append(nameNode) + if action: + actNode = tmpNode.createNode(doc, "action", action) + self.caption.append(actNode) + for q in quotes: + quoteNode = tmpNode.createNode(doc, "quote", q) + self.caption.append(quoteNode) + return self.caption + + def getCaption(self): + """Выдает XML ноду заголовка области""" + return self.caption + + +class xmlField(xmlShare): + """Класс для работы с XML полем + + """ + + def __init__(self): + # XML нода поле + self.field = None + + def createField(self, doc, typeField, quotes, name="", + values=(), action=None): + """Cоздание XML ноды поле""" + self.field = self._createElement(doc, "field", "", {"type": typeField}) + if name: + nameNode = self._createElement(doc, "name", name) + self.field.append(nameNode) + for v in values: + valueNode = self._createElement(doc, "value", v) + self.field.append(valueNode) + if action: + actNode = self._createElement(doc, "action", action) + self.field.append(actNode) + for q in quotes: + quoteNode = self._createElement(doc, "quote", q) + self.field.append(quoteNode) + return self.field + + def toxml(self, pretty_print=True): + if(self.field is not None): + return ET.tostring(self.field, encoding="UTF-8", pretty_print=pretty_print) + + +class xmlFields(): + """Класс, в котором находится список ХМL нод field + + """ + + def __init__(self): + self.fields = [] + + def appendField(self, field): + """Добавить XML ноду field""" + self.fields.append(field) + return self.fields + + def getFields(self): + """Выдать список XML нод""" + return self.fields + + +class xmlArea(): + """Класс для работы с XML областью + + """ + + def __init__(self): + # Область + self.area = None + + def createArea(self, doc, xmlCaption, xmlFields): + """Создание XML области""" + tmpNode = xmlNode() + self.area = tmpNode.createNode(doc, "area") + if xmlCaption and xmlCaption.getCaption() is not None: + self.area.append(xmlCaption.getCaption()) + if xmlFields: + fields = xmlFields.getFields() + for field in fields: + self.area.append(field) + return self.area + + +class xmlDoc(): + """Класс для работы с XML документом + + """ + + def __init__(self): + # документ + self.doc = None + # главная нода + self.root = None + # тело документа + self.body = None + # Заголовок области - временный (в реальности один объект заголовок) + self.tmpCaption = None + # Поля - временные (в реальности один объект поля) + self.tmpFields = None + # Разделитель областей - по умолчанию перевод строки "\n" + self.sepAreas = None + # Разделитель разделенных списков - по умолчанию перевод строки "\n" + # self.sepSplitFields = False + + def toxml(self, pretty_print=True): + if(self.doc is not None): + return ET.tostring(self.doc, encoding="UTF-8", pretty_print=pretty_print) + + def createDoc(self, typeDoc, version): + """Создание нового документа новый документ""" + docTxt = ('' + '{version}' + '{type_doc}' + ''.format(version=version, + type_doc=typeDoc)) + # self.doc = minidom.parseString(docTxt) + # self.root = self.doc.documentElement + # self.body = xpath.Evaluate('child::body', self.root)[0] + + self.doc = str_to_xml_doc(docTxt) + self.root = self.doc + self.body = xpath.Evaluate('child::body', self.root)[0] + # установка разделителя областей + self.sepAreas = self.createField("br", [], "", [], False, False) + # установка разделителя областей разделенных списков + # self.sepSplitFields = self.createField("br",[],"",[],False,False) + return self.doc + + def addField(self, field): + """Добавляет поле во временный список + + Из этого списка в дальнейшем формируется XML область + """ + if not self.tmpFields: + self.tmpFields = xmlFields() + self.tmpFields.appendField(field) + + def createCaption(self, name, quotes, action=False): + """Cоздает заголовок области + + Помещает заголовок в временный артибут + Используется при создании области + """ + self.tmpCaption = xmlCaption() + return self.tmpCaption.createCaption(self.doc, name, quotes, action) + + def createField(self, typeField, quotes=(), name="", + values=(), action=False, addTmpField=True): + """Cоздает поле + + Если установлена переменнная addTmpField + добавляет поле во временный список + """ + fieldObj = xmlField() + field = fieldObj.createField(self.doc, typeField, quotes, name, + values, action) + if addTmpField: + self.addField(field) + return field + + def clearTmpFields(self): + """Очищает временный список""" + self.tmpFields = False + + def createArea(self): + """Cоздает область + + Область создается на основании временного атрибута и временного списка + """ + areaObj = xmlArea() + area = areaObj.createArea(self.doc, self.tmpCaption, self.tmpFields) + self.clearTmpCaptionAndFields() + return area + + def clearTmpCaptionAndFields(self): + """Очищает временный аттрибут и временный список""" + self.tmpCaption = False + self.tmpFields = False + + def getNodeRoot(self): + """Выдает корневую ноду""" + return self.root + + def getNodeBody(self): + """Выдает ноду body""" + return self.body + + def setActionField(self, xmlField, actionTxt): + """Устанавливает свойство action для XML поля""" + xmlActions = xpath.Evaluate('child::action', xmlField) + if xmlActions and firstChild(xmlActions[0]) is not None: + firstChild(xmlActions[0]).text = actionTxt + else: + nodeObj = xmlNode() + newNode = nodeObj.createNode(self.doc, "action", actionTxt) + xmlField.append(newNode) + + def setActionArea(self, xmlArea, actionTxt): + """Устанавливает свойство action для XML области""" + xmlActions = xpath.Evaluate('child::caption/action', xmlArea) + xmlCaptions = xpath.Evaluate('child::caption', xmlArea) + if xmlActions and firstChild(xmlActions[0]) is not None: + firstChild(xmlActions[0]).text = actionTxt + else: + if xmlCaptions: + nodeObj = xmlNode() + newNode = nodeObj.createNode(self.doc, "action", actionTxt) + xmlCaptions[0].append(newNode) + + def joinField(self, xmlArea, xmlNewField): + """Объединяет XML ноду область и XML ноду поле""" + newNameField = self.getNameField(xmlNewField) + if not newNameField or not newNameField.strip(): + return False + fieldsOldComp = xpath.Evaluate("child::field[child::name='%s']" \ + % newNameField, xmlArea) + # Если поле не найдено добавляем его + typeNewField = self.getTypeField(xmlNewField) + if not fieldsOldComp and typeNewField != "seplist": + if self.getActionField(xmlNewField) != "drop": + self.setActionField(xmlNewField, "append") + xmlArea.append(xmlNewField) + return True + newFieldsAction = self.getActionField(xmlNewField) + newValues = self.getFieldValues(xmlNewField) + flagCompare = True + + for nodeFieldOld in fieldsOldComp: + if newFieldsAction == "drop": + if nodeFieldOld.getnext() is not None and \ + self.getTypeField( + nodeFieldOld.getnext()) == "br": + xmlArea.remove(nodeFieldOld.getnext()) + elif nodeFieldOld.getprevious() is not None and \ + self.getTypeField( + nodeFieldOld.getprevious()) == "br": + xmlArea.remove(nodeFieldOld.getprevious()) + xmlArea.remove(nodeFieldOld) + continue + oldValues = self.getFieldValues(nodeFieldOld) + # Сравнение значений переменной шаблона и файла + if set(newValues) != set(oldValues): + flagCompare = False + if self.getActionField(xmlNewField) == "drop": + return True + appSplLst = [] + insSplLst = [] + if typeNewField == "seplist": + if fieldsOldComp: + xmlOldField = fieldsOldComp[-1] + else: + xmlOldField = None + seplistNewXML = self.getSepListToField(xmlNewField) + if seplistNewXML: + for nodeSeplist in seplistNewXML: + if self.getActionField(nodeSeplist) != "drop": + if newFieldsAction == "join": + flagCompareSeplist = False + newValues = self.getFieldValues(nodeSeplist) + for nodeFieldOld in fieldsOldComp: + oldValues = self.getFieldValues(nodeFieldOld) + for newValue in newValues: + if newValue in oldValues: + flagCompareSeplist = True + break + if not flagCompareSeplist: + nextNode = xmlOldField.getnext() + newInsNode = deepcopy(nodeSeplist) + self.setActionField(newInsNode, "append") + + if nextNode: + appSplLst.append((newInsNode, + nextNode, + "insert")) + else: + appSplLst.append((newInsNode, + False, + "append")) + else: + newInsNode = deepcopy(nodeSeplist) + if self.getActionField(newInsNode) == "join": + self.setActionField(newInsNode, "append") + if xmlOldField: + insSplLst.append((newInsNode, + xmlOldField, + "insert")) + else: + insSplLst.append((newInsNode, + False, + "append")) + + # xmlArea.insertBefore(\ + # nodeSeplist.cloneNode(True), + # xmlOldField) + + parentNode = nodeSeplist.getparent() + parentNode.remove(nodeSeplist) + + insNodesRepl = [] + for newNode, nxtNode, app in insSplLst: + flagCompareSeplist = False + newValues = self.getFieldValues(newNode) + for nodeRepl, nxtNode_, app_ in insNodesRepl: + nxtNode, app = nxtNode_, app_ + oldValues = self.getFieldValues(nodeRepl) + for newValue in newValues: + if newValue in oldValues: + flagCompareSeplist = True + break + if not flagCompareSeplist: + if xmlOldField: + insNodesRepl.append((newNode, nxtNode, app)) + + for newNode, nxtNode, app in insNodesRepl: + if app == "insert": + insertBefore(xmlArea, newNode, nxtNode) + elif app == "append": + xmlArea.append(newNode) + if xmlOldField: + parentNode = xmlOldField.getparent() + if parentNode and newFieldsAction != "join": + parentNode.remove(xmlOldField) + + for newNode, nxtNode, app in appSplLst: + if app == "insert": + insertBefore(xmlArea, newNode, nxtNode) + elif app == "append": + xmlArea.append(newNode) + + if not flagCompare and typeNewField != "seplist": + # Устанавливаем action=replace + self.setActionField(xmlNewField, "replace") + # Если параметры поля не сходятся заменяем поле + xmlArea.replace(fieldsOldComp[-1], deepcopy(xmlNewField)) + + if newFieldsAction == "join": + fieldsOldRemove = [] + else: + fieldsOldRemove = fieldsOldComp[:-1] + + for nodeFieldOld in fieldsOldRemove: + actionOldNode = self.getActionField(nodeFieldOld) + if actionOldNode == "insert" or actionOldNode == "append": + pass + else: + if nodeFieldOld.getnext() and \ + self.getTypeField( + nodeFieldOld.getnext()) == "br": + xmlArea.remove(nodeFieldOld.getnext()) + xmlArea.remove(nodeFieldOld) + return True + + def getSepListToField(self, xmlField): + """Выдает элементы распределенного массива + + Область предок поля, в этой области ищутся + элементы распределенного массива + """ + nameField = self.getNameField(xmlField) + if not nameField: + return [] + parentNode = xmlField.getparent() + if parentNode: + fieldsVal = xpath.Evaluate( + "child::field[attribute::type='seplist'][child::name='%s'] " \ + % nameField, parentNode) + return fieldsVal + else: + return [] + + def removeComment(self, xmlArea): + """Удаляет комментарии в XML области""" + fieldNodes = xpath.Evaluate('descendant::field', xmlArea) + for fieldNode in fieldNodes: + if "type" in fieldNode.keys(): + if fieldNode.get("type") == "comment" or \ + fieldNode.get("type") == "br": + parentNode = fieldNode.getparent() + parentNode.remove(fieldNode) + else: + if self.getActionField(fieldNode) == "drop": + pass + elif self.getActionField(fieldNode) == "join": + pass + else: + self.setActionField(fieldNode, "append") + + def joinBody(self, baseBody, newBody): + """Объединяет две области Body""" + newFields = xpath.Evaluate('child::field', newBody) + xmlNewAreas = xpath.Evaluate('child::area', newBody) + for i, xmlNewArea in enumerate(xmlNewAreas): + self.joinArea(baseBody, xmlNewArea) + joinNewFields = xpath.Evaluate("child::field[child::action='join']", + newBody) + self.addNewFielsOldArea(newFields, joinNewFields, baseBody) + + def getRemoveNodeSepList(self, removeNodesDict, baseNode, xmNewlField): + """Находит элементы разделенного списка + + Параметры: + removeNodesDict - Cловарь удаляемых полей разделенного списка + формируется программой + baseNode - Нода в которой идет поиск + xmNewlField - Нода field которая проверяется на принадлежность + к разделенному списку + """ + flagNewNodeSeplist = False + if self.getTypeField(xmNewlField) == "seplist": + flagNewNodeSeplist = True + nameNewField = self.getNameField(xmNewlField) + if nameNewField: + if nameNewField in removeNodesDict: + return removeNodesDict[nameNewField] + else: + oldFields = xpath.Evaluate('child::field', baseNode) + removeNodes = [] + lenOldFields = len(oldFields) + for i in range(lenOldFields): + oldNode = oldFields[i] + flagSep = self.getTypeField(oldNode) == "seplist" + if flagNewNodeSeplist: + flagSep = True + if flagSep and \ + nameNewField == self.getNameField(oldNode): + removeNodes.append(oldNode) + if i + 1 < lenOldFields: + nextNode = oldFields[i + 1] + if self.getTypeField(nextNode) == "br": + removeNodes.append(nextNode) + removeNodesDict[nameNewField] = removeNodes + return removeNodes + + def addNewFielsOldArea(self, newFields, joinNewFields, xmlOldArea): + """Добавляет новые XML поля в область шаблона""" + removeNodesDict = {} + notRemoveNodesDict = {} + for notRemNode in joinNewFields: + nameField = self.getNameField(notRemNode) + if nameField not in notRemoveNodesDict: + notRemoveNodesDict[nameField] = [] + notRemoveNodesDict[nameField].append(notRemNode) + else: + notRemoveNodesDict[nameField].append(notRemNode) + notSepListField = [] + sepListField = [] + for nField in newFields: + if self.getRemoveNodeSepList(removeNodesDict, xmlOldArea, + nField): + sepListField.append(nField) + else: + if self.getNameField(nField): + notSepListField.append(nField) + for name in notRemoveNodesDict: + if name in removeNodesDict: + removeNodesDict[name] = [] + for removeNodes in removeNodesDict.values(): + if removeNodes: + if self.getTypeField(removeNodes[-1]) == "seplist": + removeNodes = removeNodes[:-1] + else: + removeNodes = removeNodes[:-2] + + for removeNode in removeNodes: + xmlOldArea.remove(removeNode) + for node in sepListField: + node.set("type", "seplist") + if not (self.getActionField(node) == "join" or + self.getActionField(node) == "drop"): + self.setActionField(node, "insert") + self.joinField(xmlOldArea, node) + for node in notSepListField: + if self.getTypeField(node) == "seplist": + self.setActionField(node, "append") + xmlOldArea.append(node) + else: + self.joinField(xmlOldArea, node) + + def insertBeforeSepAreas(self, xmlArea): + """Добавляет разделитель областей перед каждой областью""" + if self.sepAreas is None: + return False + areaNodes = xpath.Evaluate('descendant::area', xmlArea) + for areaNode in areaNodes: + prevNode = areaNode.getprevious() + if prevNode is not None: + parentNode = areaNode.getparent() + insertBefore(parentNode, deepcopy(self.sepAreas), + areaNode) + return True + + def getAreaFields(self, nameArea, xmlArea, allVars=False): + """По имени области выводит названия и значения всех переменных + + поиск ведется только в 1-х потомках области xmlArea + на выход словарь переменных {имя:значение} + """ + namesAreaCompareAll = xpath.Evaluate( + "child::area/child::caption[child::name='%s']" % nameArea, + xmlArea) + if not namesAreaCompareAll: + return False + dictVar = {} + for namesAreaCompare in namesAreaCompareAll: + fields = xpath.Evaluate("child::field/child::name", + namesAreaCompare.getparent()) + for fieldName in fields: + nodeField = fieldName.getparent() + fieldValue = xpath.Evaluate("child::value", nodeField) + name = firstChild(fieldName).text + value = "" + if fieldValue and firstChild(fieldValue[0]) is not None: + value = firstChild(fieldValue[0]).text + dictVar[name] = value + if not allVars: + break + return dictVar + + def getAreaFieldValues(self, nameArea, nameField, xmlArea): + """По имени области и имени переменной выводит значениe переменной + + поиск ведется только в 1-х потомках области xmlArea + """ + namesAreaComare = xpath.Evaluate( + "child::area/child::caption[child::name='%s']" % nameArea, + xmlArea) + fieldsVal = False + for areaComp in namesAreaComare: + fieldsVal = xpath.Evaluate( + "child::field[child::name='%s'] " + % nameField, areaComp.getparent()) + if fieldsVal: + break + if not fieldsVal: + return False + fieldValue = xpath.Evaluate("child::value", + fieldsVal[0]) + if not fieldValue: + return False + if firstChild(fieldValue[0]) is not None: + return firstChild(fieldValue[0]).text + else: + return "" + + def getAllAreas(self): + """Выдает все области""" + return xpath.Evaluate('descendant::area', self.body) + + def getArea(self, nameArea, xmlArea): + """По имени области находит области (первый потомок xmlArea)""" + namesAreaComare = xpath.Evaluate( + "child::area/child::caption[child::name='%s']" % nameArea, + xmlArea) + return [x.getparent() for x in namesAreaComare] + + + def joinArea(self, baseNode, xmlNewArea): + """Объединяет область c областью Body (xmlNewArea c baseNode)""" + + def appendArea(baseNode, xmlNewArea): + fieldsRemove = xpath.Evaluate( + "descendant::field[child::action='drop']", xmlNewArea) + for rmNode in fieldsRemove: + parentNode = rmNode.getparent() + parentNode.remove(rmNode) + captionAreasRemove = xpath.Evaluate( + "descendant::area/child::caption[child::action='drop']", + xmlNewArea) + for rmNodeCapt in captionAreasRemove: + rmNode = rmNodeCapt.getparent() + parentNode = rmNode.getparent() + parentNode.remove(rmNode) + self.setActionArea(xmlNewArea, "append") + # Добавляем разделитель областей во вложенные области + areaNodes = xpath.Evaluate('descendant::area', xmlNewArea) + for areaNode in areaNodes: + self.setActionArea(areaNode, "append") + parentNode = areaNode.getparent() + insertBefore(parentNode, deepcopy(self.sepAreas), + areaNode) + baseNode.append(xmlNewArea) + # Добавляем разделитель областей + insertBefore(baseNode, deepcopy(self.sepAreas), xmlNewArea) + + nodesNames = xpath.Evaluate('child::area/caption/name', baseNode) + nodesNewArea = xpath.Evaluate('child::caption/name', xmlNewArea) + if not nodesNames: + # Добавляем область + if nodesNewArea: + newAreaAction = self.getActionArea(xmlNewArea) + if not (newAreaAction == "drop" or newAreaAction == "replace"): + appendArea(baseNode, xmlNewArea) + return True + if not nodesNames or not nodesNewArea: + return False + nameArea = "" + if firstChild(nodesNewArea[0]) is not None: + nameArea = firstChild(nodesNewArea[0]).text.strip() + flagFindArea = False + newAreaAction = None + baseNodes = [] + for oName in nodesNames: + newAreaAction = self.getActionArea(xmlNewArea) + oArea = oName.getparent().getparent() + oNameTxt = "" + + if firstChild(oName) is not None: + + oNameTxt = firstChild(oName).text + if nameArea == oNameTxt: + flagFindArea = True + # При использовании удаления + if newAreaAction == "drop": + prevNode = oName.getparent().getparent().getprevious() + removePrevNodes = [] + while prevNode and self.getTypeField(prevNode) == "br": + removePrevNodes.append(prevNode) + prevNode = prevNode.getprevious() + for removeNode in removePrevNodes: + baseNode.remove(removeNode) + baseNode.remove(oName.getparent().getparent()) + continue + elif newAreaAction == "replace": + oldAreaNode = oName.getparent().getparent() + newAreaCaption = xpath.Evaluate('child::caption', + xmlNewArea)[0] + oldAreaCaption = xpath.Evaluate('child::caption', + oldAreaNode)[0] + if newAreaCaption and oldAreaCaption: + #its was "replace(old, new)" in legacy code, even though + #the func takes (new, old). Mistake, or on purpose? + #xmlNewArea.replaceChild(oldAreaCaption, newAreaCaption) + + xmlNewArea.replace(newAreaCaption, oldAreaCaption) + self.setActionArea(xmlNewArea, "replace") + baseNode.replace(oldAreaNode, xmlNewArea) + continue + baseNodes.append(oName.getparent().getparent()) + newFields = xpath.Evaluate('child::field', xmlNewArea) + + joinNewFields = xpath.Evaluate( + "child::field[child::action='join']", + xmlNewArea) + self.addNewFielsOldArea(newFields, joinNewFields, oArea) + + if not flagFindArea: + # Добавляем область + if not (newAreaAction == "drop" or newAreaAction == "replace"): + appendArea(baseNode, xmlNewArea) + else: + tmpXmlNewAreas = xpath.Evaluate('child::area', xmlNewArea) + for na in tmpXmlNewAreas: + for bn in baseNodes: + self.joinArea(bn, na) + return True + + def joinDoc(self, xmlNewDoc): + """Объединяет два документа""" + newRootNode = xmlNewDoc.getroottree().getroot() + newBodyNode = xpath.Evaluate('child::body', newRootNode)[0] + # newImportBodyNode = self.doc.importNode(newBodyNode, True) + newImportBodyNode = deepcopy(newBodyNode) + # Перед объединение области с документом + # удаляем комментарии + + self.removeComment(newImportBodyNode) + self.joinBody(self.body, newImportBodyNode) + # расставляем BR + self.insertBRtoBody(self.body) + + def getQuoteField(self, xmlField): + """Выдает текст из поля""" + xmlQuotes = xpath.Evaluate('child::quote', xmlField) + br = "" + if (xmlField.get("type") == "br"): + br = "\n" + if xmlQuotes: + field = xmlQuotes[0] + if firstChild(field) is not None: + return firstChild(field).text + br + return "" + br + + def getFieldsArea(self, xmlArea): + """Выдает потомков XML области""" + xmlFields = [] + childNodes = list(xmlArea) + for node in childNodes: + # if node.nodeType == node.ELEMENT_NODE: + if node.tag == "area" or node.tag == "field": + xmlFields.append(node) + return xmlFields + + def getTypeField(self, xmlField): + """Выдает тип поля""" + return xmlField.get("type") + + def getNameField(self, xmlField): + """Выдает имя поля""" + xmlNameFields = xpath.Evaluate('child::name', xmlField) + if xmlNameFields and firstChild(xmlNameFields[0]) is not None: + return firstChild(xmlNameFields[0]).text + else: + return False + + def getNameArea(self, xmlArea): + """Выдает имя области""" + xmlNameAreas = xpath.Evaluate('child::caption/name', xmlArea) + if xmlNameAreas and firstChild(xmlNameAreas[0]): + return firstChild(xmlNameAreas[0]).text + else: + return False + + def xmlToText(self, xmlAreas, text): + """Преобразует список XML областей в текст""" + + def getQuotesArea(xmlArea): + quotes = [] + xmlQuotes = xpath.Evaluate('child::caption/quote', xmlArea) + for node in xmlQuotes: + if firstChild(node) is not None: + quotes.append(firstChild(node).text) + if len(quotes) == 0: + quotes.append("") + quotes.append("") + elif len(quotes) == 1: + quotes.append("") + return quotes + + for i in xmlAreas: + if i.tag == "area": + quotesI = getQuotesArea(i) + startAreaI = quotesI[0] + endAreaI = quotesI[1] + text.append(startAreaI) + xmlFieldsI = self.getFieldsArea(i) + for f in xmlFieldsI: + if f.tag == "area": + quotesF = getQuotesArea(f) + startAreaF = quotesF[0] + endAreaF = quotesF[1] + text.append(startAreaF) + xmlFieldsF = self.getFieldsArea(f) + self.xmlToText(xmlFieldsF, text) + text.append(endAreaF) + else: + fieldF = self.getQuoteField(f) + text.append(fieldF) + text.append(endAreaI) + else: + fieldI = self.getQuoteField(i) + text.append(fieldI) + + def getActionField(self, xmlField): + """Выдает свойство action XML поля""" + xmlActions = xpath.Evaluate('child::action', xmlField) + if xmlActions and firstChild(xmlActions[0]) is not None: + return firstChild(xmlActions[0]).text + else: + return False + + def getFieldValues(self, xmlField): + """Выдает значения XML поля в виде массива""" + vals = [] + xmlValues = xpath.Evaluate('child::value', xmlField) + if xmlValues: + for node in xmlValues: + if firstChild(node) is not None: + vals.append(firstChild(node).text) + return vals + + def getActionArea(self, xmlArea): + """Выдает свойство action XML области""" + xmlActions = xpath.Evaluate('child::caption/action', xmlArea) + if xmlActions and firstChild(xmlActions[0]) is not None: + return firstChild(xmlActions[0]).text + else: + return False + + def delActionNodeArea(self, xmlArea): + """Удаляет свойство action XML области""" + xmlActions = xpath.Evaluate('child::caption/action', xmlArea) + if xmlActions and firstChild(xmlActions[0]) is not None: + parentNode = xmlActions[0].getparent() + parentNode.remove(xmlActions[0]) + return True + else: + return False + + def delActionNodeField(self, xmlField): + """Удаляет свойство action XML поля""" + xmlActions = xpath.Evaluate('child::action', xmlField) + if xmlActions and firstChild(xmlActions[0]) is not None: + parentNode = xmlActions[0].getparent() + parentNode.remove(xmlActions[0]) + return True + else: + return False + + # Создает распределенные списки + def postParserListSeplist(self, xmlArea): + """Создает распределенные списки из элементов области""" + # Потомки + childNodes = self.getFieldsArea(xmlArea) + # содержит списки нод полей с одинаковыми именами в одной области + fieldsSeplist = {} + for node in childNodes: + if node.tag == "area": + self.postParserListSeplist(node) + else: + fieldName = False + xmlFieldNameNodes = xpath.Evaluate('child::name', node) + if xmlFieldNameNodes and firstChild(xmlFieldNameNodes[0]) is not None: + fieldName = firstChild(xmlFieldNameNodes[0]).text + if fieldName: + if fieldName in fieldsSeplist: + fieldsSeplist[fieldName].append(node) + else: + fieldsSeplist[fieldName] = [] + fieldsSeplist[fieldName].append(node) + for listNodes in fieldsSeplist.values(): + if len(listNodes) > 1: + for node in listNodes: + node.set("type", "seplist") + + def insertBRtoBody(self, xmlArea): + """Добавляет необходимые переводы строк + """ + # Потомки + childNodes = self.getFieldsArea(xmlArea) + # нода BR + fieldXMLBr = self.createField("br", [], "", [], False, False) + + # Предыдущая нода + lastNode = None + lenChildNodes = len(childNodes) + for i in range(lenChildNodes): + node = childNodes[i] + lastTmpNode = node + # Нода area + if node.tag == "area": + if self.getActionArea(node) == "append" or \ + self.getActionArea(node) == "join": + self.delActionNodeArea(node) + if lastNode is not None and lastNode.get("type") == "br" or \ + lastNode is not None and lastNode.get("type") == "comment": + indNext = i + 1 + if indNext == lenChildNodes: + xmlArea.append(deepcopy(fieldXMLBr)) + else: + nextNode = childNodes[indNext] + lastTmpNode = insertBefore(xmlArea, + deepcopy(fieldXMLBr), + nextNode) + else: + insertBefore(xmlArea, deepcopy(fieldXMLBr), + node) + self.insertBRtoBody(node) + # Нода field + else: + if self.getActionField(node) == "append" or \ + self.getActionField(node) == "join": + self.delActionNodeField(node) + if lastNode is not None and lastNode.get("type") == "br" or \ + lastNode is not None and lastNode.get("type") == "comment": + indNext = i + 1 + if indNext == lenChildNodes: + xmlArea.append(deepcopy(fieldXMLBr)) + else: + nextNode = childNodes[indNext] + lastTmpNode = insertBefore(xmlArea, + deepcopy(fieldXMLBr), + nextNode) + else: + insertBefore(xmlArea, deepcopy(fieldXMLBr), node) + lastNode = lastTmpNode + + def postParserList(self): + """Находит подходящие XML области и делаем из них поля-массивы""" + xmlAreas = xpath.Evaluate('descendant::area', self.body) + for xmlArea in xmlAreas: + flagListXml = True + fieldValues = [] + xmlFields = xpath.Evaluate('child::field', xmlArea) + if not xmlFields: + flagListXml = False + lenXmlFields = len(xmlFields) + lenBrArea = 0 + for xmlField in xmlFields: + xmlNames = xpath.Evaluate('child::name', xmlField) + xmlVals = xpath.Evaluate('child::value', xmlField) + # if "type" in xmlField.keys() and \ + # xmlField.get("type") == "br": + if xmlField.get("type") == "br": + lenBrArea += 1 + continue + if not xmlNames and not xmlVals: + flagListXml = False + break + if xmlNames and firstChild(xmlNames[0]) and \ + firstChild(xmlNames[0]).text: + flagListXml = False + break + if not (xmlVals and firstChild(xmlVals[0]) and + firstChild(xmlVals[0]).text): + flagListXml = False + break + else: + fieldValues.append(firstChild(xmlVals[0]).text) + + if lenXmlFields == lenBrArea: + flagListXml = False + if flagListXml: + nameNode = xpath.Evaluate('child::caption/name', xmlArea)[0] + fieldName = "" + if firstChild(nameNode) is not None: + fieldName = firstChild(nameNode).text + listArea = [] + self.xmlToText([xmlArea], listArea) + fieldQuote = "".join(listArea) + fieldXMLBr = False + if fieldQuote and fieldQuote[-1] == "\n": + fieldQuote = fieldQuote[:-1] + fieldXMLBr = self.createField("br", [], "", [], False, + False) + fieldXML = self.createField("list", + [fieldQuote], + fieldName, fieldValues, + False, False) + areaAction = self.getActionArea(xmlArea) + if areaAction: + self.setActionField(fieldXML, areaAction) + parentNode = xmlArea.getparent() + insertBefore(parentNode, fieldXML, xmlArea) + if fieldXMLBr: + insertBefore(parentNode, fieldXMLBr, xmlArea) + parentNode.remove(xmlArea) diff --git a/setup.py b/setup.py index c914aca..4250b4a 100755 --- a/setup.py +++ b/setup.py @@ -24,8 +24,10 @@ from distutils.core import setup from distutils.command.build_scripts import build_scripts from distutils.command.install_scripts import install_scripts from distutils.command.install_data import install_data + def cmp(a, b): return (a > b) - (b < a) + data_files = [] var_data_files = [("/var/calculate/server-profile",[]), @@ -104,8 +106,8 @@ def create_data_files (data_dirs, prefix=""): test1_files = test2_files + test1_files return test1_files -data_files += create_data_files (data_dirs_local) -data_files += create_data_files (data_dirs_share, share_calculate_dir) +data_files += create_data_files(data_dirs_local) +data_files += create_data_files(data_dirs_share, share_calculate_dir) data_files += [('/etc/conf.d', ['data/sortmilter.conf']), ('/etc/init.d', ['data/sortmilter.init'])] @@ -145,13 +147,6 @@ class cl_install_data(install_data): ("/etc/conf.d/sortmilter.conf","sortmilter",None)] data_find = \ dict( - # map(lambda x:(os.path.basename(x[0]), - # [list(reversed(filter(lambda y:y,x[0].split("/")))), - # x[1], - # x[2]]), - # data_file)) - - # [(os.path.basename(x[0]), [list(reversed(filter(lambda y:y,x[0].split("/")))), x[1],x[2]]) for x in data_file]) [(os.path.basename(x[0]), [list(reversed((y for y in x[0].split("/") if y))), x[1],x[2]]) for x in data_file]) for path in self.get_outputs(): From 02811f6775c5de7601812c7397cb5575971f530c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Tue, 31 Aug 2021 17:50:52 +0300 Subject: [PATCH 05/24] updated formats and xml --- pym/cl_base.py | 7 +- pym/cl_ldap.py | 86 +- pym/cl_profile.py | 2856 +++++++++++++++++++++++---------------------- 3 files changed, 1489 insertions(+), 1460 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index 1995d36..76fc1cc 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -358,7 +358,7 @@ class iniParser(cl_profile._error): # объединяем объекты для получения результирующего текста objIni.join(objIniAdd) # получаем текст - txtConfig = objIni.getConfig().encode("UTF-8") + txtConfig = objIni.getConfig() # записываем его в ini файл self.writeIniFile(txtConfig) return True @@ -391,7 +391,7 @@ class iniParser(cl_profile._error): allAreas = objIni.docObj.getAllAreas() for xmlArea in allAreas: parentNode = xmlArea.getparent() - if parentNode is not None and parentNode.tagName == "area": + if parentNode is not None and parentNode.tag == "area": self.checkIni = "plasma" break if self.checkIni == "samba": @@ -1030,8 +1030,7 @@ class DataVars(): # принудительно переписать все переменные окружения # полученные из ini for (k,v) in allvars.items(): - k = k.encode("UTF-8") - value = cl_utils.convertStrListDict(v.encode("UTF-8")) + value = cl_utils.convertStrListDict(v) self.Set(k, value, True) importFileVars[k] = value if i < 4: diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 8487df4..2c22487 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -144,7 +144,7 @@ class report: сначала строки будет вставлено char[1:] в конце строки char[:-1] """ - lineUnicode = cl_utils._toUNICODE(line) + # lineUnicode = cl_utils._toUNICODE(line) prevPos = 0 convLine = char[1:] lenLenCols = len(lenCols) @@ -156,7 +156,7 @@ class report: insertChar = char convLine += lineUnicode[prevPos:pos] + insertChar prevPos = pos + 1 - return convLine.encode("UTF-8") + return convLine def adminConnectLdap(fun): @@ -12079,8 +12079,8 @@ class servRepl(shareLdap): # принудительно переписать все переменные окружения # полученные из ini for (k,v) in allvars.items(): - k = k.encode("UTF-8") - v = v.encode("UTF-8") + # k = k.encode("UTF-8") + # v = v.encode("UTF-8") clVars.Set(k, cl_utils.convertStrListDict(v), True) return (True, clVars) @@ -13567,10 +13567,11 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) return False # Если нет всех ключей - выходим без ошибки return True - userPwdHash = varsDict["unix_hash"].encode("UTF-8") - userLMHash = varsDict["samba_lm_hash"].encode("UTF-8") - userNTHash = varsDict["samba_nt_hash"].encode("UTF-8") - userOldNTHash = varsDict["samba_nt_hash_old"].encode("UTF-8") + #TODO debug this + userPwdHash = varsDict["unix_hash"]#.encode("UTF-8") + userLMHash = varsDict["samba_lm_hash"]#.encode("UTF-8") + userNTHash = varsDict["samba_nt_hash"]#.encode("UTF-8") + userOldNTHash = varsDict["samba_nt_hash_old"]#.encode("UTF-8") # Поиск пользователя в Unix сервисе resUnix = self.servUnixObj.searchUnixUser(userName) # Поиск пользователя в Samba сервисе @@ -14442,7 +14443,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): if xmlNodes: masterIPNode = xmlNodes[0] xmlNodes = xpath.Evaluate( "child::value", masterIPNode) - ips = (firstChild(x).nodeValue.strip() for x in xmlNodes) + ips = (firstChild(x).text.strip() for x in xmlNodes) flagAddIPs = True slaveIPs.append(",".join(ips)) if not flagAddIPs: @@ -14507,7 +14508,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): if xmlNodes: masterIPNode = xmlNodes[0] xmlNodes = xpath.Evaluate( "child::value", masterIPNode) - ipMasterServers = [firstChild(x).nodeValue.strip() for x in xmlNodes] + ipMasterServers = [firstChild(x).text.strip() for x in xmlNodes] if not ipMasterServers: self.printERROR(_("The program does not support information \ for %s DNS zone")%zoneName) @@ -16457,9 +16458,9 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if not namesArea: return [] return [x for x in namesArea - if firstChild(x) is not None and firstChild(x).nodeValue and\ - len(firstChild(x).nodeValue) > 4 and\ - 'host' in firstChild(x).nodeValue[:4]] + if firstChild(x) is not None and firstChild(x).text and\ + len(firstChild(x).text) > 4 and\ + 'host' in firstChild(x).text[:4]] def getAllXMLSubnet(self): """Получаем все XML ноды подсетей""" @@ -16471,9 +16472,9 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if not namesArea: return [] return [x for x in namesArea - if firstChild(x) is not None and firstChild(x).nodeValue and\ - len(firstChild(x).nodeValue) > 6 and\ - 'subnet' in firstChild(x).nodeValue[:6]] + if firstChild(x) is not None and firstChild(x).text and\ + len(firstChild(x).text) > 6 and\ + 'subnet' in firstChild(x).text[:6]] def getDataInAllHost(self): """Получить информацию о статических хостах""" @@ -16488,7 +16489,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): #print xmlArea.toprettyxml() # Ност xmlNodeName = next(iterXmlNames) - strNameNode = firstChild(xmlNodeName).nodeValue + strNameNode = firstChild(xmlNodeName).text # название хоста hostname = strNameNode.partition("host")[2].strip() # Параметры статического хоста @@ -16512,7 +16513,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): # Сеть xmlNodeName = next(iterXmlNames) # Название области - strNameNode = firstChild(xmlNodeName).nodeValue + strNameNode = firstChild(xmlNodeName).text # ip сети netIP = strNameNode.partition("subnet")[2].partition("netmask")[0] # netIP = netIP.encode("UTF-8") @@ -16568,7 +16569,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): for nodeFind in nodesXml: if firstChild(nodeFind) is not None: listOpt = [x for x - in firstChild(nodeFind).nodeValue.replace("\t"," ").split(" ") if x] + in firstChild(nodeFind).text.replace("\t"," ").split(" ") if x] dataPars[opt] = listOpt return dataPars @@ -16583,7 +16584,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): return [] slpHostName = 'host%s' %hostName.lower() return [x.getparent().getparent() for x in xmlStaticHosts - if slpHostName == firstChild(x).nodeValue.lower()] + if slpHostName == firstChild(x).text.lower()] def getXMLNet(self, net): """Получить XML ноду подсети по ip""" @@ -16596,8 +16597,8 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): slpNetName = 'subnet%s' %net.lower() lenSlpNetName = len(slpNetName) return [x.getparent().getparent() for x in xmlSubnets - if len(firstChild(x).nodeValue) > lenSlpNetName and - slpNetName == firstChild(x).nodeValue[:lenSlpNetName].lower()] + if len(firstChild(x).text) > lenSlpNetName and + slpNetName == firstChild(x).text[:lenSlpNetName].lower()] def createStaticHost(self, hostname, ip, mac): """Создает статический хост в файле конфигурации dhcp""" @@ -16608,7 +16609,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): xmlNodeBodyNewNet = dhcpObj.docObj.getNodeBody() namesAreaNew = xpath.Evaluate("child::area/child::caption/child::name", xmlNodeBodyNewNet) - splNameNewNode = firstChild(namesAreaNew[0]).nodeValue + splNameNewNode = firstChild(namesAreaNew[0]).text hostnameNode = splNameNewNode.partition("host")[2].strip() if self.getXMLStaticHost(hostnameNode): self.setError(_('DHCP static host "%s" exists')%hostnameNode) @@ -16616,7 +16617,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): # Объединение конфигураций self.join(dhcpObj) # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) def modNetOpts(self,xmlNode,routers="",domainName="",dnsIPs="",iprange=""): @@ -16624,7 +16625,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if self.getError(): return False namesArea = xpath.Evaluate("child::caption/child::name", xmlNode) - splNameNewNode = firstChild(namesArea[0]).nodeValue + splNameNewNode = firstChild(namesArea[0]).text netIPList = splNameNewNode.partition("subnet")[2].partition("netmask") netIP = netIPList[0].strip() netMask = netIPList[2].partition("{")[0].strip() @@ -16646,7 +16647,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): if self.getError(): return False namesArea = xpath.Evaluate("child::caption/child::name", xmlNode) - splNameNewNode = firstChild(namesArea[0]).nodeValue + splNameNewNode = firstChild(namesArea[0]).text hostname = splNameNewNode.partition("host")[2].strip() if not any((ip, mac)): self.setError(_("empty modify options")) @@ -16678,7 +16679,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): xmlNodeBodyNewNet = dhcpObj.docObj.getNodeBody() namesAreaNew = xpath.Evaluate("child::area/child::caption/child::name", xmlNodeBodyNewNet) - splNameNewNode = firstChild(namesAreaNew[0]).nodeValue + splNameNewNode = firstChild(namesAreaNew[0]).text netIP = splNameNewNode.partition("subnet")[2].partition("netmask")[0] # netIP = netIP.encode("UTF-8") if self.getXMLNet(netIP): @@ -16693,12 +16694,12 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): def deleteAllNetAndHosts(self): """Удаляет все сети и статические хосты из конфигурационного файла""" # IP всех сетей - delNamesNets = [firstChild(x).nodeValue.partition("subnet")[2].\ + delNamesNets = [firstChild(x).text.partition("subnet")[2].\ partition("netmask")[0] for x in self.getAllXMLSubnet() if firstChild(x) is not None] # Имена всех статических хостов - delNamesHosts = [firstChild(x).nodeValue.partition("host")[2].\ + delNamesHosts = [firstChild(x).text.partition("host")[2].\ strip() for x in self._getAllXMLStaticHosts() if firstChild(x) is not None] @@ -16755,7 +16756,6 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк [xmlNodeBody.remove(x) for x in delNodes] - #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области for term in (xmlNodeBody.remove(x) for x in deletesNodes): if not term: @@ -16763,7 +16763,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): " " + _("in config file %s")%self.nameConfigFile) return False # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) def deleteNet(self, net): @@ -16810,7 +16810,6 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк [xmlNodeBody.remove(x) for x in delNodes] - #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области for term in (xmlNodeBody.remove(x) for x in deletesNodes): if not term: @@ -16880,8 +16879,8 @@ class dnsTxt(cl_profile.bind,shareTxt): if not namesArea: return [] return [x for x in namesArea - if firstChild(x) is not None and firstChild(x).nodeValue and\ - 'zone"' in firstChild(x).nodeValue] + if firstChild(x) is not None and firstChild(x).text and\ + 'zone"' in firstChild(x).text] def getXMLZoneToName(self, nameZone): """Получить XML ноду DNS зоны по ее имени""" @@ -16897,7 +16896,7 @@ class dnsTxt(cl_profile.bind,shareTxt): return [x.getparent().getparent() for x in xmlZonesNames if nameZoneL == \ - firstChild(x).nodeValue.lower().partition('"')[2].partition('"')[0]] + firstChild(x).text.lower().partition('"')[2].partition('"')[0]] def getAllNamesZones(self): """Получить все имена нод областей (кроме служебных)""" @@ -16909,14 +16908,14 @@ class dnsTxt(cl_profile.bind,shareTxt): if not xmlZonesNames: return retNodesNames for nodeZone in xmlZonesNames: - if '"."' in firstChild(nodeZone).nodeValue.lower(): + if '"."' in firstChild(nodeZone).text.lower(): continue - elif '"localhost"' in firstChild(nodeZone).nodeValue.lower(): + elif '"localhost"' in firstChild(nodeZone).text.lower(): continue - elif '"127.in-addr.arpa"' in firstChild(nodeZone).nodeValue.lower(): + elif '"127.in-addr.arpa"' in firstChild(nodeZone).text.lower(): continue retNodesNames.append(\ - firstChild(nodeZone).nodeValue.rpartition('"')[0].partition('"')[2]) + firstChild(nodeZone).text.rpartition('"')[0].partition('"')[2]) retNodesNames = [x for x in retNodesNames if x] return retNodesNames @@ -16964,7 +16963,6 @@ class dnsTxt(cl_profile.bind,shareTxt): delNodes = delNodesPrev + delNodesNext # Удаляем переводы строк [xmlNodeBody.remove(x) for x in delNodes] - #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области for term in [xmlNodeBody.remove(x) for x in deletesNodes]: if not term: @@ -16992,7 +16990,7 @@ class dnsTxt(cl_profile.bind,shareTxt): if not xmlZonesNames: return True for nodeZone in xmlZonesNames: - nodeValue = firstChild(nodeZone).nodeValue.lower() + nodeValue = firstChild(nodeZone).text.lower() if '"."' in nodeValue: continue elif '"localhost"' in nodeValue: @@ -17000,7 +16998,6 @@ class dnsTxt(cl_profile.bind,shareTxt): elif '"127.in-addr.arpa"' in nodeValue: continue else: - # nodeValue = nodeValue.encode("UTF-8") # Название зоны nameZ = nodeValue.rpartition('"')[0].partition('"')[2] deletesNodes.append((nodeZone.getparent().getparent(), nameZ)) @@ -17041,7 +17038,6 @@ class dnsTxt(cl_profile.bind,shareTxt): delNodes.append(delNode) # Удаляем переводы строк [xmlNodeBody.remove(x) for x in delNodes] - #print xmlNodeBody.toprettyxml().encode("UTF-8") # Удаляем области for delNode, zoneName in deletesNodes: if xmlNodeBody.remove(delNode): @@ -17069,7 +17065,7 @@ class dnsTxt(cl_profile.bind,shareTxt): namesAreaNew = xpath.Evaluate(\ "child::area/child::caption/child::name", xmlNodeBodyNewZone) splNameNewNode =\ - firstChild(namesAreaNew[0]).nodeValue.replace("{","").split('"') + firstChild(namesAreaNew[0]).text.replace("{","").split('"') splNameNewNode = splNameNewNode[1] if self.getXMLZoneToName(splNameNewNode): self.setError(_('DNS zone "%s" exists')%splNameNewNode) @@ -17113,7 +17109,7 @@ class dnsTxt(cl_profile.bind,shareTxt): # Объединение конфигураций self.join(bindObj) # Запись файла - text = self.getConfig().encode("UTF-8") + text = self.getConfig() return self.writeInConfig(text) class servDns(shareLdap): diff --git a/pym/cl_profile.py b/pym/cl_profile.py index a1abf1c..9ce364c 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -26,7 +26,9 @@ import re # xml.use_pyxml() # from xml import xpath from . import cl_xml -from .cl_xml import xpath, firstChild, insertBefore, str_to_xml_doc +from .cl_xml import xpath, firstChild,\ + insertBefore, str_to_xml_doc, xml_to_str, xmlShare,\ + xmlNode, xmlField, xmlFields, xmlArea, xmlDoc import subprocess import types import copy @@ -34,7 +36,7 @@ import random import string import time from copy import deepcopy - +from collections.abc import Iterable tr = cl_base.lang() tr.setLocalDomain('cl_lib') tr.setLanguage(sys.modules[__name__]) @@ -335,7 +337,7 @@ class fileHeader(_terms): if reS: textBody = textUnicode[:reS.start()]+textUnicode[reS.end():] if textBody: - self.body = textBody.encode("UTF-8") + self.body = textBody else: reCalcHeader =\ re.compile("\s*%s\-+\s+%s.+Calculate.+\s+%s.+\s+%s\-+\s?"%(\ @@ -578,7 +580,7 @@ class objShare: if name[0] == "!": fieldAction = "drop" elif name[0] == "+": - fieldXML.setAttribute("type", "seplist") + fieldXML.set("type", "seplist") fieldAction = "join" else: fieldXML = docObj.createField("var", @@ -615,13 +617,12 @@ class objShare: listConfigTxt = [] childNodes = list(self.docObj.getNodeBody()) for node in childNodes: - if node.tagName == "field": + if node.tag == "field": listConfigTxt.append(self.docObj.getQuoteField(node)) - elif node.tagName == "area": + elif node.tag == "area": self.docObj.xmlToText([node], listConfigTxt) return "".join(listConfigTxt) - def splitToFields(self, txtBloc): """Разбиваем текст на поля (объекты) которые имеют следующие аттрибуты @@ -642,7 +643,6 @@ class objShare: z = 0 lenLines = len(linesBlocTmp) for i in linesBlocTmp: - if self.reComment.split(i)[0]: findCooment = self.reComment.search(i) comment = False @@ -652,8 +652,7 @@ class objShare: comment = i[findCooment.start():] fields = self.reSepFields.split(par) lenFields = len(fields) - - if lenFields>1: + if lenFields > 1: for fi in range(lenFields-1): linesBloc.append(fields[fi]+ self.sepFields) if fi == lenFields-2: @@ -688,45 +687,45 @@ class objShare: fields = self.setDataField(linesBloc, brBloc) return fields -class xmlShare: - """Общий класс для объектов XML, наследуем +# class xmlShare: +# """Общий класс для объектов XML, наследуем - """ - def _createElement(self, doc, tagName, text="", attributes={}): - """Создание нового XML элемента""" - element = doc.createElement(tagName) - if text: - txtNode = doc.createTextNode(self._toUNICODE(text)) - element.append(txtNode) - for attr in attributes.keys(): - attribute = doc.createAttribute(attr) - attribute.nodeValue = attributes[attr] - element.setAttributeNode(attribute) - return element - - def _toUNICODE(self,val): - """перевод текста в юникод""" - if 'unicode' in "%s" %(type(val)): - return val - else: - return val.decode('UTF-8') +# """ +# def _createElement(self, doc, tag, text="", attributes={}): +# """Создание нового XML элемента""" +# element = doc.createElement(tag) +# if text: +# txtNode = doc.createTextNode(self._toUNICODE(text)) +# element.append(txtNode) +# for attr in attributes.keys(): +# attribute = doc.createAttribute(attr) +# attribute.text = attributes[attr] +# element.setNode(attribute) +# return element +# def _toUNICODE(self,val): +# """перевод текста в юникод""" +# if 'unicode' in "%s" %(type(val)): +# return val +# else: +# return val.decode('UTF-8') -class xmlNode(xmlShare): - """Класс для создания нод без аттрибутов - """ - def __init__(self): - self.node = False +# class xmlNode(xmlShare): +# """Класс для создания нод без аттрибутов +# """ +# def __init__(self): +# self.node = False - def createNode(self, doc, tagName, text=""): - """Создает XML элемент без аттрибутов""" - self.node=self._createElement(doc, tagName, text) - return self.node - def getNode(self): - return self.node +# def createNode(self, doc, tag, text=""): +# """Создает XML элемент без аттрибутов""" +# self.node=self._createElement(doc, tag, text) +# return self.node + +# def getNode(self): +# return self.node class xmlCaption: @@ -756,918 +755,918 @@ class xmlCaption: """Выдает XML ноду заголовка области""" return self.caption -class xmlField(xmlShare): - """Класс для работы с XML полем - - """ - def __init__(self): - # XML нода поле - self.field = False - - - def createField(self, doc, typeField, quotes, name="", - values=[],action=False): - """Cоздание XML ноды поле""" - self.field = self._createElement(doc, "field", "", {"type":typeField}) - if name: - nameNode = self._createElement(doc, "name", name) - self.field.append(nameNode) - for v in values: - valueNode = self._createElement(doc, "value", v) - self.field.append(valueNode) - if action: - actNode = self._createElement(doc, "action", action) - self.field.append(actNode) - for q in quotes: - quoteNode = self._createElement(doc, "quote", q) - self.field.append(quoteNode) - return self.field - - - -class xmlFields: - """Класс, в котором находится список ХМL нод field - - """ - def __init__(self): - self.fields = [] - - def appendField(self, field): - """Добавить XML ноду field""" - self.fields.append(field) - return self.fields - - def getFields(self): - """Выдать список XML нод""" - return self.fields - - -class xmlArea: - """Класс для работы с XML областью - - """ - def __init__(self): - # Область - self.area = False - - def createArea(self, doc, xmlCaption, xmlFields): - """Создание XML области""" - tmpNode = xmlNode() - self.area = tmpNode.createNode(doc, "area") - if xmlCaption and xmlCaption.getCaption(): - self.area.append(xmlCaption.getCaption()) - if xmlFields: - fields = xmlFields.getFields() - for field in fields: - self.area.append(field) - return self.area - -class xmlDoc: - """Класс для работы с XML документом - - """ - def __init__(self): - # документ - self.doc = False - # главная нода - self.root = False - # тело документа - self.body = False - # Заголовок области - временный (в реальности один объект заголовок) - self.tmpCaption = False - # Поля - временные (в реальности один объект поля) - self.tmpFields = False - # Разделитель областей - по умолчанию перевод строки "\n" - self.sepAreas = False - # Разделитель разделенных списков - по умолчанию перевод строки "\n" - #self.sepSplitFields = False - - - def createDoc(self, typeDoc, version): - """Создание нового документа новый документ""" - docTxt = '' - docTxt += '%s'% version - docTxt += '%s' % typeDoc - docTxt += '' - self.doc = xml.dom.minidom.parseString(docTxt) - self.root = self.doc.documentElement - self.body = xpath.Evaluate('child::body',self.root)[0] - # установка разделителя областей - self.sepAreas = self.createField("br",[],"",[],False,False) - # установка разделителя областей разделенных списков - #self.sepSplitFields = self.createField("br",[],"",[],False,False) - return self.doc - - def addField(self, field): - """Добавляет поле во временный список - - Из этого списка в дальнейшем формируется XML область - """ - if not self.tmpFields: - self.tmpFields = xmlFields() - self.tmpFields.appendField(field) - - def createCaption(self, name, quotes, action=False): - """Cоздает заголовок области - - Помещает заголовок в временный артибут - Используется при создании области - """ - self.tmpCaption = xmlCaption() - return self.tmpCaption.createCaption(self.doc, name, quotes, action) - - def createField(self, typeField, quotes=[], name="", - values=[] ,action=False,addTmpField=True): - """Cоздает поле - - Если установлена переменнная addTmpField - добавляет поле во временный список - """ - fieldObj = xmlField() - field = fieldObj.createField(self.doc, typeField, quotes, name, - values, action) - if addTmpField: - self.addField(field) - return field - - def clearTmpFields(self): - """Очищает временный список""" - self.tmpFields = False - - def createArea(self): - """Cоздает область - - Область создается на основании временного атрибута и временного списка - """ - areaObj = xmlArea() - area = areaObj.createArea(self.doc, self.tmpCaption, self.tmpFields) - self.clearTmpCaptionAndFields() - return area - - def clearTmpCaptionAndFields(self): - """Очищает временный аттрибут и временный список""" - self.tmpCaption = False - self.tmpFields = False - - def getNodeRoot(self): - """Выдает корневую ноду""" - return self.root - - def getNodeBody(self): - """Выдает ноду body""" - return self.body - - def setActionField(self, xmlField, actionTxt): - """Устанавливает свойство action для XML поля""" - xmlActions = xpath.Evaluate('child::action',xmlField) - if xmlActions is not None and firstChild(xmlActions[0]): - firstChild(xmlActions[0]).nodeValue = actionTxt - else: - nodeObj = xmlNode() - newNode = nodeObj.createNode(self.doc, "action", actionTxt) - xmlField.append(newNode) - - - def setActionArea(self, xmlArea, actionTxt): - """Устанавливает свойство action для XML области""" - xmlActions = xpath.Evaluate('child::caption/action',xmlArea) - xmlCaptions = xpath.Evaluate('child::caption',xmlArea) - if xmlActions is not None and firstChild(xmlActions[0]): - firstChild(xmlActions[0]).nodeValue = actionTxt - else: - if xmlCaptions: - nodeObj = xmlNode() - newNode = nodeObj.createNode(self.doc, "action", actionTxt) - xmlCaptions[0].append(newNode) - - def joinField(self, xmlArea, xmlNewField): - """Объединяет XML ноду область и XML ноду поле""" - newNameField = self.getNameField(xmlNewField) - if not newNameField or not newNameField.strip(): - return False - fieldsOldComp = xpath.Evaluate("child::field[child::name='%s']"\ - %(newNameField), xmlArea) - # Если поле не найдено добавляем его - typeNewField = self.getTypeField(xmlNewField) - if not fieldsOldComp and typeNewField != "seplist": - if self.getActionField(xmlNewField) != "drop": - self.setActionField(xmlNewField, "append") - xmlArea.append(xmlNewField) - return True - newFieldsAction = self.getActionField(xmlNewField) - newValues = self.getFieldValues(xmlNewField) - flagCompare = True - - for nodeFieldOld in fieldsOldComp: - if newFieldsAction == "drop": - if nodeFieldOld.getnext() and\ - self.getTypeField(nodeFieldOld.getnext()) == "br": - xmlArea.remove(nodeFieldOld.getnext()) - elif nodeFieldOld.getprevious() and\ - self.getTypeField(nodeFieldOld.getprevious()) == "br": - xmlArea.remove(nodeFieldOld.getprevious()) - xmlArea.remove(nodeFieldOld) - continue - oldValues = self.getFieldValues(nodeFieldOld) - # Сравнение значений переменной профиля и файла - if set(newValues) != set(oldValues): - flagCompare = False - if self.getActionField(xmlNewField) == "drop": - return True - appSplLst = [] - insSplLst = [] - if typeNewField == "seplist": - if fieldsOldComp: - xmlOldField = fieldsOldComp[-1] - else: - xmlOldField = False - seplistNewXML = self.getSepListToField(xmlNewField) - if seplistNewXML: - for nodeSeplist in seplistNewXML: - if self.getActionField(nodeSeplist) != "drop": - if newFieldsAction == "join": - flagCompareSeplist = False - newValues = self.getFieldValues(nodeSeplist) - for nodeFieldOld in fieldsOldComp: - oldValues = self.getFieldValues(nodeFieldOld) - for newValue in newValues: - if newValue in oldValues: - flagCompareSeplist = True - break - if not flagCompareSeplist: - nextNode = xmlOldField.getnext() - newInsNode = deepcopy(nodeSeplist) - self.setActionField(newInsNode,"append") - - if nextNode: - appSplLst.append((newInsNode, - nextNode, - "insert")) - else: - appSplLst.append((newInsNode, - False, - "append")) - else: - newInsNode = deepcopy(nodeSeplist) - if self.getActionField(newInsNode) == "join": - self.setActionField(newInsNode,"append") - if xmlOldField: - insSplLst.append((newInsNode, - xmlOldField, - "insert")) - else: - insSplLst.append((newInsNode, - False, - "append")) - - #xmlArea.insertBefore(\ - #nodeSeplist.cloneNode(True), - #xmlOldField) - - parentNode = nodeSeplist.getparent() - parentNode.remove(nodeSeplist) - - insNodesRepl = [] - for newNode, nxtNode, app in insSplLst: - flagCompareSeplist = False - newValues = self.getFieldValues(newNode) - for nodeRepl, nxtNode, app in insNodesRepl: - oldValues = self.getFieldValues(nodeRepl) - for newValue in newValues: - if newValue in oldValues: - flagCompareSeplist = True - break - if not flagCompareSeplist: - if xmlOldField is not None: - insNodesRepl.append((newNode, nxtNode, app)) - - for newNode, nxtNode, app in insNodesRepl: - if app == "insert": - insertBefore(xmlArea, newNode, nxtNode) - elif app == "append": - xmlArea.append(newNode) - if xmlOldField: - parentNode = xmlOldField.getparent() - if parentNode and newFieldsAction != "join": - parentNode.remove(xmlOldField) - - for newNode, nxtNode, app in appSplLst: - if app == "insert": - insertBefore(xmlArea, newNode, nxtNode) - elif app == "append": - xmlArea.append(newNode) - - if not flagCompare and typeNewField != "seplist": - # Устанавливаем action=replace - self.setActionField(xmlNewField, "replace") - # Если параметры поля не сходятся заменяем поле - xmlArea.replace(fieldsOldComp[-1], deepcopy(xmlNewField)) - - if newFieldsAction == "join": - fieldsOldRemove = [] - else: - fieldsOldRemove = fieldsOldComp[:-1] - - for nodeFieldOld in fieldsOldRemove: - actionOldNode = self.getActionField(nodeFieldOld) - if actionOldNode == "insert" or actionOldNode == "append": - pass - else: - if nodeFieldOld.getnext() and\ - self.getTypeField(nodeFieldOld.getnext()) == "br": - xmlArea.remove(nodeFieldOld.getnext()) - xmlArea.remove(nodeFieldOld) - return True - - - def getSepListToField(self, xmlField): - """Выдает элементы распределенного массива - - Область предок поля, в этой области ищутся - элементы распределенного массива - """ - nameField = self.getNameField(xmlField) - if not nameField: - return [] - parentNode = xmlField.getparent() - #print parentNode.toprettyxml() - if parentNode is not None: - fieldsVal = xpath.Evaluate(\ - "child::field[attribute::type='seplist'][child::name='%s'] "\ - %(nameField), parentNode) - #print nameField - return fieldsVal - else: - return [] - - def removeComment(self, xmlArea): - """Удаляет комментарии в XML области""" - fieldNodes = xpath.Evaluate('descendant::field',xmlArea) - for fieldNode in fieldNodes: - if "type" in fieldNode.keys(): - if fieldNode.get("type") == "comment" or\ - fieldNode.get("type") == "br": - parentNode = fieldNode.getparent() - parentNode.remove(fieldNode) - else: - if self.getActionField(fieldNode) == "drop": - pass - elif self.getActionField(fieldNode) == "join": - pass - else: - self.setActionField(fieldNode,"append") - - - def joinBody(self, baseBody, newBody): - """Объединяет две области Body""" - newFields = xpath.Evaluate('child::field',newBody) - xmlNewAreas = xpath.Evaluate('child::area',newBody) - for xmlNewArea in xmlNewAreas: - self.joinArea(baseBody,xmlNewArea) - joinNewFields = xpath.Evaluate("child::field[child::action='join']" - ,newBody) - self.addNewFielsOldArea(newFields, joinNewFields, baseBody) - - - def getRemoveNodeSepList(self, removeNodesDict, baseNode, xmNewlField): - """Находит элементы разделенного списка - - Параметры: - removeNodesDict - Cловарь удаляемых полей разделенного списка - формируется программой - baseNode - Нода в которой идет поиск - xmNewlField - Нода field которая проверяется на принадлежность - к разделенному списку - """ - flagNewNodeSeplist = False - if self.getTypeField(xmNewlField) == "seplist": - flagNewNodeSeplist = True - nameNewField = self.getNameField(xmNewlField) - if nameNewField: - if nameNewField in removeNodesDict: - return removeNodesDict[nameNewField] - else: - oldFields = xpath.Evaluate('child::field', baseNode) - removeNodes = [] - lenOldFields = len(oldFields) - for i in range(lenOldFields): - oldNode = oldFields[i] - flagSep = self.getTypeField(oldNode) == "seplist" - if flagNewNodeSeplist: - flagSep = True - if flagSep and\ - nameNewField == self.getNameField(oldNode): - removeNodes.append(oldNode) - if i+1 1: - for node in listNodes: - node.setAttribute("type", "seplist") - - def insertBRtoBody(self, xmlArea): - """Добавляет необходимые переводы строк - """ - # Потомки - childNodes = self.getFieldsArea(xmlArea) - # нода BR - fieldXMLBr = self.createField("br",[],"",[],False, False) - # разделитель поля - fieldSplit = False - # Предыдущая нода - lastNode = False - # Cледующая нода - nextNode = False - lenChildNodes = len(childNodes) - for i in range(lenChildNodes): - node = childNodes[i] - lastTmpNode = node - # Нода area - if node.tagName == "area": - if self.getActionArea(node) == "append" or\ - self.getActionArea(node) == "join": - self.delActionNodeArea(node) - if lastNode and "type" in lastNode.keys() and\ - lastNode.get("type") == "br" or\ - lastNode and "type" in lastNode.keys() and\ - lastNode.get("type") == "comment": - indNext = i + 1 - if indNext == lenChildNodes: - xmlArea.append(deepcopy(fieldXMLBr)) - else: - nextNode = childNodes[indNext] - lastTmpNode = insertBefore(xmlArea, deepcopy(fieldXMLBr), - nextNode) - else: - insertBefore(xmlArea, deepcopy(fieldXMLBr), - node) - self.insertBRtoBody(node) - # Нода field - else: - if self.getActionField(node) == "append" or\ - self.getActionField(node) == "join": - self.delActionNodeField(node) - if lastNode and "type" in lastNode.keys() and\ - lastNode.get("type") == "br" or\ - lastNode and "type" in lastNode.keys() and\ - lastNode.get("type") == "comment": - indNext = i + 1 - if indNext == lenChildNodes: - xmlArea.append(deepcopy(fieldXMLBr)) - else: - nextNode = childNodes[indNext] - lastTmpNode = insertBefore(xmlArea, - deepcopy(fieldXMLBr), - nextNode) - else: - insertBefore(xmlArea, deepcopy(fieldXMLBr), - node) - lastNode = lastTmpNode - - - - def postParserList(self): - """Находит подходящие XML области и делаем из них поля-массивы""" - xmlAreas = xpath.Evaluate('descendant::area', self.body) - for xmlArea in xmlAreas: - flagListXml = True - fieldValues = [] - xmlFields = xpath.Evaluate('child::field',xmlArea) - if not xmlFields: - flagListXml = False - lenXmlFields = len(xmlFields) - lenBrArea = 0 - for xmlField in xmlFields: - xmlNames = xpath.Evaluate('child::name',xmlField) - xmlVals = xpath.Evaluate('child::value',xmlField) - if "type" in xmlField.keys() and\ - xmlField.get("type") == "br": - lenBrArea += 1 - continue - if not xmlNames and not xmlVals: - flagListXml = False - break - if xmlNames and firstChild(xmlNames[0]) is not None and\ - firstChild(xmlNames[0]).nodeValue: - flagListXml = False - break - if not (xmlVals and firstChild(xmlVals[0]) is not None and\ - firstChild(xmlVals[0]).nodeValue): - flagListXml = False - break - else: - fieldValues.append(firstChild(xmlVals[0]).nodeValue) - - if lenXmlFields == lenBrArea: - flagListXml = False - if flagListXml: - nameNode = xpath.Evaluate('child::caption/name',xmlArea)[0] - fieldName = "" - if firstChild(nameNode) is not None: - fieldName = firstChild(nameNode).nodeValue - listArea = [] - self.xmlToText([xmlArea],listArea) - fieldQuote = "".join(listArea) - fieldXMLBr = False - if fieldQuote and fieldQuote[-1] == "\n": - fieldQuote = fieldQuote[:-1] - fieldXMLBr = self.createField("br",[],"",[],False, False) - fieldXML = self.createField("list", - [fieldQuote], - fieldName, fieldValues, - False, False) - areaAction = self.getActionArea(xmlArea) - if areaAction: - self.setActionField(fieldXML, areaAction) - parentNode = xmlArea.getparent() - insertBefore(parentNode, fieldXML, xmlArea) - if fieldXMLBr: - insertBefore(parentNode, fieldXMLBr, xmlArea) - parentNode.remove(xmlArea) +# class xmlField(xmlShare): +# """Класс для работы с XML полем + +# """ +# def __init__(self): +# # XML нода поле +# self.field = False + + +# def createField(self, doc, typeField, quotes, name="", +# values=[],action=False): +# """Cоздание XML ноды поле""" +# self.field = self._createElement(doc, "field", "", {"type":typeField}) +# if name: +# nameNode = self._createElement(doc, "name", name) +# self.field.append(nameNode) +# for v in values: +# valueNode = self._createElement(doc, "value", v) +# self.field.append(valueNode) +# if action: +# actNode = self._createElement(doc, "action", action) +# self.field.append(actNode) +# for q in quotes: +# quoteNode = self._createElement(doc, "quote", q) +# self.field.append(quoteNode) +# return self.field + + + +# class xmlFields: +# """Класс, в котором находится список ХМL нод field + +# """ +# def __init__(self): +# self.fields = [] + +# def appendField(self, field): +# """Добавить XML ноду field""" +# self.fields.append(field) +# return self.fields + +# def getFields(self): +# """Выдать список XML нод""" +# return self.fields + + +# class xmlArea: +# """Класс для работы с XML областью + +# """ +# def __init__(self): +# # Область +# self.area = False + +# def createArea(self, doc, xmlCaption, xmlFields): +# """Создание XML области""" +# tmpNode = xmlNode() +# self.area = tmpNode.createNode(doc, "area") +# if xmlCaption and xmlCaption.getCaption(): +# self.area.append(xmlCaption.getCaption()) +# if xmlFields: +# fields = xmlFields.getFields() +# for field in fields: +# self.area.append(field) +# return self.area + +# class xmlDoc: +# """Класс для работы с XML документом + +# """ +# def __init__(self): +# # документ +# self.doc = False +# # главная нода +# self.root = False +# # тело документа +# self.body = False +# # Заголовок области - временный (в реальности один объект заголовок) +# self.tmpCaption = False +# # Поля - временные (в реальности один объект поля) +# self.tmpFields = False +# # Разделитель областей - по умолчанию перевод строки "\n" +# self.sepAreas = False +# # Разделитель разделенных списков - по умолчанию перевод строки "\n" +# #self.sepSplitFields = False + + +# def createDoc(self, typeDoc, version): +# """Создание нового документа новый документ""" +# docTxt = '' +# docTxt += '%s'% version +# docTxt += '%s' % typeDoc +# docTxt += '' +# self.doc = xml.dom.minidom.parseString(docTxt) +# self.root = self.doc.documentElement +# self.body = xpath.Evaluate('child::body',self.root)[0] +# # установка разделителя областей +# self.sepAreas = self.createField("br",[],"",[],False,False) +# # установка разделителя областей разделенных списков +# #self.sepSplitFields = self.createField("br",[],"",[],False,False) +# return self.doc + +# def addField(self, field): +# """Добавляет поле во временный список + +# Из этого списка в дальнейшем формируется XML область +# """ +# if not self.tmpFields: +# self.tmpFields = xmlFields() +# self.tmpFields.appendField(field) + +# def createCaption(self, name, quotes, action=False): +# """Cоздает заголовок области + +# Помещает заголовок в временный артибут +# Используется при создании области +# """ +# self.tmpCaption = xmlCaption() +# return self.tmpCaption.createCaption(self.doc, name, quotes, action) + +# def createField(self, typeField, quotes=[], name="", +# values=[] ,action=False,addTmpField=True): +# """Cоздает поле + +# Если установлена переменнная addTmpField +# добавляет поле во временный список +# """ +# fieldObj = xmlField() +# field = fieldObj.createField(self.doc, typeField, quotes, name, +# values, action) +# if addTmpField: +# self.addField(field) +# return field + +# def clearTmpFields(self): +# """Очищает временный список""" +# self.tmpFields = False + +# def createArea(self): +# """Cоздает область + +# Область создается на основании временного атрибута и временного списка +# """ +# areaObj = xmlArea() +# area = areaObj.createArea(self.doc, self.tmpCaption, self.tmpFields) +# self.clearTmpCaptionAndFields() +# return area + +# def clearTmpCaptionAndFields(self): +# """Очищает временный аттрибут и временный список""" +# self.tmpCaption = False +# self.tmpFields = False + +# def getNodeRoot(self): +# """Выдает корневую ноду""" +# return self.root + +# def getNodeBody(self): +# """Выдает ноду body""" +# return self.body + +# def setActionField(self, xmlField, actionTxt): +# """Устанавливает свойство action для XML поля""" +# xmlActions = xpath.Evaluate('child::action',xmlField) +# if xmlActions is not None and firstChild(xmlActions[0]): +# firstChild(xmlActions[0]).text = actionTxt +# else: +# nodeObj = xmlNode() +# newNode = nodeObj.createNode(self.doc, "action", actionTxt) +# xmlField.append(newNode) + + +# def setActionArea(self, xmlArea, actionTxt): +# """Устанавливает свойство action для XML области""" +# xmlActions = xpath.Evaluate('child::caption/action',xmlArea) +# xmlCaptions = xpath.Evaluate('child::caption',xmlArea) +# if xmlActions is not None and firstChild(xmlActions[0]): +# firstChild(xmlActions[0]).text = actionTxt +# else: +# if xmlCaptions: +# nodeObj = xmlNode() +# newNode = nodeObj.createNode(self.doc, "action", actionTxt) +# xmlCaptions[0].append(newNode) + +# def joinField(self, xmlArea, xmlNewField): +# """Объединяет XML ноду область и XML ноду поле""" +# newNameField = self.getNameField(xmlNewField) +# if not newNameField or not newNameField.strip(): +# return False +# fieldsOldComp = xpath.Evaluate("child::field[child::name='%s']"\ +# %(newNameField), xmlArea) +# # Если поле не найдено добавляем его +# typeNewField = self.getTypeField(xmlNewField) +# if not fieldsOldComp and typeNewField != "seplist": +# if self.getActionField(xmlNewField) != "drop": +# self.setActionField(xmlNewField, "append") +# xmlArea.append(xmlNewField) +# return True +# newFieldsAction = self.getActionField(xmlNewField) +# newValues = self.getFieldValues(xmlNewField) +# flagCompare = True + +# for nodeFieldOld in fieldsOldComp: +# if newFieldsAction == "drop": +# if nodeFieldOld.getnext() and\ +# self.getTypeField(nodeFieldOld.getnext()) == "br": +# xmlArea.remove(nodeFieldOld.getnext()) +# elif nodeFieldOld.getprevious() and\ +# self.getTypeField(nodeFieldOld.getprevious()) == "br": +# xmlArea.remove(nodeFieldOld.getprevious()) +# xmlArea.remove(nodeFieldOld) +# continue +# oldValues = self.getFieldValues(nodeFieldOld) +# # Сравнение значений переменной профиля и файла +# if set(newValues) != set(oldValues): +# flagCompare = False +# if self.getActionField(xmlNewField) == "drop": +# return True +# appSplLst = [] +# insSplLst = [] +# if typeNewField == "seplist": +# if fieldsOldComp: +# xmlOldField = fieldsOldComp[-1] +# else: +# xmlOldField = False +# seplistNewXML = self.getSepListToField(xmlNewField) +# if seplistNewXML: +# for nodeSeplist in seplistNewXML: +# if self.getActionField(nodeSeplist) != "drop": +# if newFieldsAction == "join": +# flagCompareSeplist = False +# newValues = self.getFieldValues(nodeSeplist) +# for nodeFieldOld in fieldsOldComp: +# oldValues = self.getFieldValues(nodeFieldOld) +# for newValue in newValues: +# if newValue in oldValues: +# flagCompareSeplist = True +# break +# if not flagCompareSeplist: +# nextNode = xmlOldField.getnext() +# newInsNode = deepcopy(nodeSeplist) +# self.setActionField(newInsNode,"append") + +# if nextNode: +# appSplLst.append((newInsNode, +# nextNode, +# "insert")) +# else: +# appSplLst.append((newInsNode, +# False, +# "append")) +# else: +# newInsNode = deepcopy(nodeSeplist) +# if self.getActionField(newInsNode) == "join": +# self.setActionField(newInsNode,"append") +# if xmlOldField: +# insSplLst.append((newInsNode, +# xmlOldField, +# "insert")) +# else: +# insSplLst.append((newInsNode, +# False, +# "append")) + +# #xmlArea.insertBefore(\ +# #nodeSeplist.cloneNode(True), +# #xmlOldField) + +# parentNode = nodeSeplist.getparent() +# parentNode.remove(nodeSeplist) + +# insNodesRepl = [] +# for newNode, nxtNode, app in insSplLst: +# flagCompareSeplist = False +# newValues = self.getFieldValues(newNode) +# for nodeRepl, nxtNode, app in insNodesRepl: +# oldValues = self.getFieldValues(nodeRepl) +# for newValue in newValues: +# if newValue in oldValues: +# flagCompareSeplist = True +# break +# if not flagCompareSeplist: +# if xmlOldField is not None: +# insNodesRepl.append((newNode, nxtNode, app)) + +# for newNode, nxtNode, app in insNodesRepl: +# if app == "insert": +# insertBefore(xmlArea, newNode, nxtNode) +# elif app == "append": +# xmlArea.append(newNode) +# if xmlOldField: +# parentNode = xmlOldField.getparent() +# if parentNode and newFieldsAction != "join": +# parentNode.remove(xmlOldField) + +# for newNode, nxtNode, app in appSplLst: +# if app == "insert": +# insertBefore(xmlArea, newNode, nxtNode) +# elif app == "append": +# xmlArea.append(newNode) + +# if not flagCompare and typeNewField != "seplist": +# # Устанавливаем action=replace +# self.setActionField(xmlNewField, "replace") +# # Если параметры поля не сходятся заменяем поле +# xmlArea.replace(fieldsOldComp[-1], deepcopy(xmlNewField)) + +# if newFieldsAction == "join": +# fieldsOldRemove = [] +# else: +# fieldsOldRemove = fieldsOldComp[:-1] + +# for nodeFieldOld in fieldsOldRemove: +# actionOldNode = self.getActionField(nodeFieldOld) +# if actionOldNode == "insert" or actionOldNode == "append": +# pass +# else: +# if nodeFieldOld.getnext() and\ +# self.getTypeField(nodeFieldOld.getnext()) == "br": +# xmlArea.remove(nodeFieldOld.getnext()) +# xmlArea.remove(nodeFieldOld) +# return True + + +# def getSepListToField(self, xmlField): +# """Выдает элементы распределенного массива + +# Область предок поля, в этой области ищутся +# элементы распределенного массива +# """ +# nameField = self.getNameField(xmlField) +# if not nameField: +# return [] +# parentNode = xmlField.getparent() +# #print parentNode.toprettyxml() +# if parentNode is not None: +# fieldsVal = xpath.Evaluate(\ +# "child::field[attribute::type='seplist'][child::name='%s'] "\ +# %(nameField), parentNode) +# #print nameField +# return fieldsVal +# else: +# return [] + +# def removeComment(self, xmlArea): +# """Удаляет комментарии в XML области""" +# fieldNodes = xpath.Evaluate('descendant::field',xmlArea) +# for fieldNode in fieldNodes: +# if "type" in fieldNode.keys(): +# if fieldNode.get("type") == "comment" or\ +# fieldNode.get("type") == "br": +# parentNode = fieldNode.getparent() +# parentNode.remove(fieldNode) +# else: +# if self.getActionField(fieldNode) == "drop": +# pass +# elif self.getActionField(fieldNode) == "join": +# pass +# else: +# self.setActionField(fieldNode,"append") + + +# def joinBody(self, baseBody, newBody): +# """Объединяет две области Body""" +# newFields = xpath.Evaluate('child::field',newBody) +# xmlNewAreas = xpath.Evaluate('child::area',newBody) +# for xmlNewArea in xmlNewAreas: +# self.joinArea(baseBody,xmlNewArea) +# joinNewFields = xpath.Evaluate("child::field[child::action='join']" +# ,newBody) +# self.addNewFielsOldArea(newFields, joinNewFields, baseBody) + + +# def getRemoveNodeSepList(self, removeNodesDict, baseNode, xmNewlField): +# """Находит элементы разделенного списка + +# Параметры: +# removeNodesDict - Cловарь удаляемых полей разделенного списка +# формируется программой +# baseNode - Нода в которой идет поиск +# xmNewlField - Нода field которая проверяется на принадлежность +# к разделенному списку +# """ +# flagNewNodeSeplist = False +# if self.getTypeField(xmNewlField) == "seplist": +# flagNewNodeSeplist = True +# nameNewField = self.getNameField(xmNewlField) +# if nameNewField: +# if nameNewField in removeNodesDict: +# return removeNodesDict[nameNewField] +# else: +# oldFields = xpath.Evaluate('child::field', baseNode) +# removeNodes = [] +# lenOldFields = len(oldFields) +# for i in range(lenOldFields): +# oldNode = oldFields[i] +# flagSep = self.getTypeField(oldNode) == "seplist" +# if flagNewNodeSeplist: +# flagSep = True +# if flagSep and\ +# nameNewField == self.getNameField(oldNode): +# removeNodes.append(oldNode) +# if i+1 1: +# for node in listNodes: +# node.set("type", "seplist") + +# def insertBRtoBody(self, xmlArea): +# """Добавляет необходимые переводы строк +# """ +# # Потомки +# childNodes = self.getFieldsArea(xmlArea) +# # нода BR +# fieldXMLBr = self.createField("br",[],"",[],False, False) +# # разделитель поля +# fieldSplit = False +# # Предыдущая нода +# lastNode = False +# # Cледующая нода +# nextNode = False +# lenChildNodes = len(childNodes) +# for i in range(lenChildNodes): +# node = childNodes[i] +# lastTmpNode = node +# # Нода area +# if node.tag == "area": +# if self.getActionArea(node) == "append" or\ +# self.getActionArea(node) == "join": +# self.delActionNodeArea(node) +# if lastNode and "type" in lastNode.keys() and\ +# lastNode.get("type") == "br" or\ +# lastNode and "type" in lastNode.keys() and\ +# lastNode.get("type") == "comment": +# indNext = i + 1 +# if indNext == lenChildNodes: +# xmlArea.append(deepcopy(fieldXMLBr)) +# else: +# nextNode = childNodes[indNext] +# lastTmpNode = insertBefore(xmlArea, deepcopy(fieldXMLBr), +# nextNode) +# else: +# insertBefore(xmlArea, deepcopy(fieldXMLBr), +# node) +# self.insertBRtoBody(node) +# # Нода field +# else: +# if self.getActionField(node) == "append" or\ +# self.getActionField(node) == "join": +# self.delActionNodeField(node) +# if lastNode and "type" in lastNode.keys() and\ +# lastNode.get("type") == "br" or\ +# lastNode and "type" in lastNode.keys() and\ +# lastNode.get("type") == "comment": +# indNext = i + 1 +# if indNext == lenChildNodes: +# xmlArea.append(deepcopy(fieldXMLBr)) +# else: +# nextNode = childNodes[indNext] +# lastTmpNode = insertBefore(xmlArea, +# deepcopy(fieldXMLBr), +# nextNode) +# else: +# insertBefore(xmlArea, deepcopy(fieldXMLBr), +# node) +# lastNode = lastTmpNode + + + +# def postParserList(self): +# """Находит подходящие XML области и делаем из них поля-массивы""" +# xmlAreas = xpath.Evaluate('descendant::area', self.body) +# for xmlArea in xmlAreas: +# flagListXml = True +# fieldValues = [] +# xmlFields = xpath.Evaluate('child::field',xmlArea) +# if not xmlFields: +# flagListXml = False +# lenXmlFields = len(xmlFields) +# lenBrArea = 0 +# for xmlField in xmlFields: +# xmlNames = xpath.Evaluate('child::name',xmlField) +# xmlVals = xpath.Evaluate('child::value',xmlField) +# if "type" in xmlField.keys() and\ +# xmlField.get("type") == "br": +# lenBrArea += 1 +# continue +# if not xmlNames and not xmlVals: +# flagListXml = False +# break +# if xmlNames and firstChild(xmlNames[0]) is not None and\ +# firstChild(xmlNames[0]).text: +# flagListXml = False +# break +# if not (xmlVals and firstChild(xmlVals[0]) is not None and\ +# firstChild(xmlVals[0]).text): +# flagListXml = False +# break +# else: +# fieldValues.append(firstChild(xmlVals[0]).text) + +# if lenXmlFields == lenBrArea: +# flagListXml = False +# if flagListXml: +# nameNode = xpath.Evaluate('child::caption/name',xmlArea)[0] +# fieldName = "" +# if firstChild(nameNode) is not None: +# fieldName = firstChild(nameNode).text +# listArea = [] +# self.xmlToText([xmlArea],listArea) +# fieldQuote = "".join(listArea) +# fieldXMLBr = False +# if fieldQuote and fieldQuote[-1] == "\n": +# fieldQuote = fieldQuote[:-1] +# fieldXMLBr = self.createField("br",[],"",[],False, False) +# fieldXML = self.createField("list", +# [fieldQuote], +# fieldName, fieldValues, +# False, False) +# areaAction = self.getActionArea(xmlArea) +# if areaAction: +# self.setActionField(fieldXML, areaAction) +# parentNode = xmlArea.getparent() +# insertBefore(parentNode, fieldXML, xmlArea) +# if fieldXMLBr: +# insertBefore(parentNode, fieldXMLBr, xmlArea) +# parentNode.remove(xmlArea) class blocText: @@ -2117,18 +2116,12 @@ class utfBin: result = True return (result, i) - - #TODO get rid of this abomination def _intToChar(self, x): he = hex(x)[2:] - # exec("ret = '\\x%s'" % he) - # return ret - return None + return chr(int(he, 16)) def _hexToChar(self, he): - # exec("ret = '\\x%s'" % he) - # return ret - return None + return chr(int(he, 16)) def encode(self, text): """Кодирует смешанный формат в UTF-8""" @@ -2871,15 +2864,15 @@ class profile(_file, _terms, xmlShare, processingTemplates): print(_("error var %s not found")%str(terms[1])) cl_base.exit(1) replace = "" - strValue = self._toUNICODE(strValue) + # strValue = self._toUNICODE(strValue) if terms[0] == 'upper': replace = strValue.upper() elif terms[0] == 'lower': replace = strValue.lower() elif terms[0] == 'capitalize': replace = strValue.capitalize() - if replace: - replace = replace.encode("UTF-8") + # if replace: + # replace = replace.encode("UTF-8") textProfileTmp = textProfileTmp[:resS.start()] + replace +\ textProfileTmp[resS.end():] return textProfileTmp @@ -4178,7 +4171,6 @@ class profile(_file, _terms, xmlShare, processingTemplates): if ListOptTitle: title = self.getTitle(objHeadNew.comment, ListOptTitle) - title = title.encode("UTF-8") objHeadOld = False if objHeadNew.comment: @@ -4233,7 +4225,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): if 'postXML' in dir(objProfNew): objProfNew.postXML() # Получение текстового файла из XML документа - self.newProfile = objProfNew.getConfig().encode("UTF-8") + self.newProfile = objProfNew.getConfig() # Если не UTF-8 производим преобразование if flagNotUtf8New: self.newProfile = objTxtCoder.decode(self.newProfile) @@ -4241,7 +4233,6 @@ class profile(_file, _terms, xmlShare, processingTemplates): if ListOptTitle: title = self.getTitle(objProfNew._comment, ListOptTitle) - title = title.encode("UTF-8") # Замена if objHeadNew.typeAppend == "replace": if "xml_" in objHeadNew.fileType: @@ -4330,7 +4321,6 @@ class profile(_file, _terms, xmlShare, processingTemplates): if ListOptTitle: title = self.getTitle(objProfNew._comment, ListOptTitle) - title = title.encode("UTF-8") # В случае пустого конфигурационного файла reNoClean = re.compile("[^\s]",re.M) @@ -4379,19 +4369,19 @@ class profile(_file, _terms, xmlShare, processingTemplates): self.setError (_("False profile: " ) + newFile) return False data = \ - objProfOld.getConfig().encode("UTF-8").split("\n") + objProfOld.getConfig().split("\n") data.insert(1,title) self.oldProfile = "\n".join(data) else: if objHeadNew.execStr: self.oldProfile = objHeadNew.execStr + title +\ - objProfOld.getConfig().encode("UTF-8") + objProfOld.getConfig() elif objHeadOld.execStr: self.oldProfile = objHeadOld.execStr + title +\ - objProfOld.getConfig().encode("UTF-8") + objProfOld.getConfig() else: self.oldProfile = title +\ - objProfOld.getConfig().encode("UTF-8") + objProfOld.getConfig() # Декодируем если кодировка не UTF-8 if flagNotUtf8New or flagNotUtf8Old: self.newProfile = objTxtCoder.decode(self.newProfile) @@ -4432,32 +4422,48 @@ class samba(objShare): def postXML(self): """Последующая постобработка XML""" + # удаляем пустые области + xmlAreas = xpath.Evaluate("child::area", self.docObj.body) + removeList = [] + for xmlArea in xmlAreas: + xmlFields = xpath.Evaluate("child::field/name", xmlArea) + if not xmlFields: + removeList.append(xmlArea) + for xmlArea in removeList: + parentNode = xmlArea.getparent() + parentNode.remove(xmlArea) + # Для добавления перевода строки между областями если его нет - #print self.docObj.body.toprettyxml() xmlAreas = xpath.Evaluate("child::area", self.docObj.body) + xmlArea = None for xmlArea in xmlAreas: - if xmlArea.getprevious() and\ - self.docObj.getTypeField(xmlArea.getprevious()) == "br": - continue - firstArea = False xmlFields = xpath.Evaluate("child::field", xmlArea) - if not (xmlFields and\ - (self.docObj.getTypeField(xmlFields[-1]) == "br" or\ + if not (xmlFields and ( + self.docObj.getTypeField(xmlFields[-1]) == "br" or self.docObj.getTypeField(xmlFields[-1]) == "comment")): - if xmlArea.getnext(): + if xmlArea.getnext() is not None: parentNode = xmlArea.getparent() nextNode = xmlArea.getnext() - insertBefore(parentNode, self.docObj.createField("br", - [],"",[], - False,False), - nextNode) + insertBefore(parentNode, self.docObj.createField( + "br", [], "", [], False, False), nextNode) + # Добавление переводов строк между полями + if xmlFields: + for node in xmlFields: + # Добавление перевода строк в если его нет между полями + if (self.docObj.getTypeField(node) == "var" and + node.getprevious() is not None and + not (self.docObj.getTypeField( + node.getprevious()) in ("br", "comment"))): + insertBefore(xmlArea, self.docObj.createField( + "br", [], "", [], False, False), node) + # Удаление лишних переводов строк childNodes = self.docObj.getFieldsArea(self.docObj.body) lenBr = 0 removeBrNodes = [] for node in childNodes: - if node.tagName == "field" and\ - self.docObj.getTypeField(node) == "br": + if (node.tag == "field" and + self.docObj.getTypeField(node) == "br"): lenBr += 1 if lenBr > 2: removeBrNodes.append(node) @@ -4465,7 +4471,15 @@ class samba(objShare): lenBr = 0 # Удаление for rmNode in removeBrNodes: - self.docObj.body.remove(rmNode) + self.docObj.body.remove(rmNode) + + # Если после есть BR а за ним ничего нет, удаляем BR + if xmlArea is not None: + if (xmlArea.getnext() is not None and + self.docObj.getTypeField(xmlArea.getnext()) == "br"): + if xmlArea.getnext().getnext() is None: + parentNode = xmlArea.getnext().getparent() + parentNode.remove(xmlArea.getnext()) def join(self, sambaObj): @@ -4476,12 +4490,14 @@ class samba(objShare): def setDataField(self, txtLines, endtxtLines): """Создаем список объектов с переменными""" + class fieldData: def __init__(self): self.name = False self.value = False self.comment = False self.br = False + fields = [] field = fieldData() z = 0 @@ -4502,11 +4518,11 @@ class samba(objShare): nameValue = self.reSeparator.split(pars) if len(nameValue) > 2: valueList = nameValue[1:] - nameValue =[nameValue[0],"=".join(valueList)] + nameValue = [nameValue[0], "=".join(valueList)] if len(nameValue) == 2: name = nameValue[0] - value = nameValue[1].replace(self.sepFields,"") - field.name = name.replace(" ","").replace("\t","") + value = nameValue[1].replace(self.sepFields, "") + field.name = name.replace(" ", "").replace("\t", "") field.value = value field.br = textLine fields.append(field) @@ -5021,9 +5037,9 @@ class apache(bind): xmlFields = xpath.Evaluate("child::fields", self.docObj.body) if not (xmlFields and\ self.docObj.getTypeField(xmlFields[-1]) == "br"): - self.docObj.body.append(self.docObj.createField("br", - [],"",[], - False,False)) + self.docObj.body.append(self.docObj.createField("br", + [],"",[], + False,False)) xmlAreas = xpath.Evaluate("child::area", self.docObj.body) for xmlArea in xmlAreas: xmlFields = xpath.Evaluate("child::field", xmlArea) @@ -5420,7 +5436,7 @@ class ldap(samba): docObj.setActionField(xmlField, "drop") elif f.name[0] == "+": # Добавляем уникальное поле - xmlField.setAttribute("type", "seplist") + xmlField.set("type", "seplist") docObj.setActionField(xmlField, "join") else: docObj.createField("var",[f.br.replace("\n","")], @@ -5569,7 +5585,7 @@ class dovecot(bind): if name[0] == "!": fieldAction = "drop" elif name[0] == "+": - fieldXML.setAttribute("type", "seplist") + fieldXML.set("type", "seplist") fieldAction = "join" else: fieldXML = docObj.createField("var", @@ -5602,6 +5618,19 @@ class procmail(objShare): self.docObj = self.textToXML() self.doc = self.docObj.doc + def postXML(self): + """Последующая постобработка XML""" + xmlFields = xpath.Evaluate("child::field", self.docObj.body) + # Добавление переводов строк между полями + for node in xmlFields: + # Добавление перевода строк в если его нет между полями + if (self.docObj.getTypeField(node) == "var" and + node.getprevious() is not None and + (self.docObj.getTypeField(node.getprevious()) not in + ("br", "comment"))): + insertBefore(self.docObj.body, self.docObj.createField( + "br", [], "", [], False, False), node) + def setDataField(self, txtLines, endtxtLines): """Создаем список объектов с переменными""" class fieldData: @@ -5681,6 +5710,7 @@ class procmail(objShare): if isinstance(procmailObj, procmail): #print self.docObj.doc.toprettyxml() self.docObj.joinDoc(procmailObj.doc) + self.postXML() class kde(samba): """Класс для обработки конфигурационного файла типа kde @@ -5799,6 +5829,12 @@ class kde(samba): self.docObj.joinDoc(kdeObj.doc) self.postXML() +class PlasmaArea(): + def __init__(self): + self.header = False + self.start = False + self.fields = [] + self.end = "" class xmlDocPlasma: """Класс для замены метода joinArea в xmlDoc для plasma""" @@ -5843,22 +5879,24 @@ class xmlDocPlasma: return False nameArea = "" if firstChild(nodesNewArea[0]) is not None: - nameArea = firstChild(nodesNewArea[0]).nodeValue.strip() + nameArea = firstChild(nodesNewArea[0]).text.strip() flagFindArea = False baseNodes = [] + newAreaAction = None for oName in nodesNames: newAreaAction = self.getActionArea(xmlNewArea) oArea = oName.getparent().getparent() oNameTxt = "" if firstChild(oName) is not None: - oNameTxt = firstChild(oName).nodeValue + oNameTxt = firstChild(oName).text if nameArea == oNameTxt: flagFindArea = True # При использовании удаления if newAreaAction == "drop": prevNode = oName.getparent().getparent().getprevious() removePrevNodes = [] - while (prevNode) and self.getTypeField(prevNode) == "br": + while prevNode is not None\ + and self.getTypeField(prevNode) == "br": removePrevNodes.append(prevNode) prevNode = prevNode.getprevious() for removeNode in removePrevNodes: @@ -5929,16 +5967,11 @@ class plasma(samba): # Делим текст на области включая вложенные (areas массив областей) def splitToAllArea(self, text, areas): - """Делит текст на области включая вложенные - - возвращает список объектов областей (переменная areas) - """ - class area: - def __init__(self): - self.header = False - self.start = False - self.fields = [] - self.end = False + """Делит текст на области включая вложенные + + возвращает список объектов областей (переменная areas) + """ + area = PlasmaArea def findPathArea(listPath, areaF): @@ -5951,7 +5984,7 @@ class plasma(samba): if not listPath: return ret flagList = False - if type(areaF) == list: + if isinstance(areaF, list): fields = areaF flagList = True else: @@ -5961,7 +5994,7 @@ class plasma(samba): else: return ret for i in fields: - if str(i.__class__.__name__) == "area": + if isinstance(i, PlasmaArea): add = False if not flagList: add = listPath.pop(0) @@ -6041,7 +6074,8 @@ class plasma(samba): areas.append(areaNew) findAreaPrev = areas[-1] else: - if lenNamesBlock == i: + if (lenNamesBlock == i and + isinstance(findAreaPrev, area)): findAreaPrev.fields += fieldsTmp findAreaPrev.fields.append(areaNew) findAreaPrev = findAreaPrev.fields[-1] @@ -6064,7 +6098,7 @@ class plasma(samba): namesBlock = namesBlockList[i-delt] findArea = findPathArea(copy.copy(namesBlock), areas) - if findArea: + if isinstance(findArea, area): #if findArea.fields: #if type(findArea.fields[0]) == types.StringType: #findArea.fields.pop(0) @@ -6123,13 +6157,13 @@ class plasma(samba): def createXML(self, areas, rootNode, docObj): """Создаем из массивов областей XML""" for i in areas: - if str(i.__class__.__name__) == "area": + if isinstance(i, PlasmaArea): if i.header: areaXML = self.createCaptionTerm(i.header, i.start, i.end.replace("\n",""), docObj) for f in i.fields: - if str(f.__class__.__name__) == "area": + if isinstance(f, PlasmaArea): if f.header: areaXMLChild = self.createCaptionTerm(f.header, f.start, @@ -6246,11 +6280,10 @@ class plasma(samba): areas = [] if self.text.strip(): self.splitToAllArea(self.text, areas) - #docObj = xmlDoc() + # docObj = xmlDoc() # Создаем новый класс xmlDoc с измененным методом joinArea - newClass = type("newXmlDocPlalma",(xmlDocPlasma,xmlDoc,object),{}) # Создаем экземпляр нового класса - docObj = newClass() + docObj = xmlDocPlasma() # Создание объекта документ c пустым разделителем между полями docObj.createDoc(self.configName, self.configVersion) if not areas: @@ -6258,17 +6291,15 @@ class plasma(samba): self.createXML(areas, docObj.getNodeBody(), docObj) return docObj - def postXML(self): """Последующая постобработка XML""" # Для добавления перевода строки между областями если его нет - #print self.docObj.body.toprettyxml() def getQuotesArea(xmlArea): quotes = [] - xmlQuotes = xpath.Evaluate('child::caption/quote',xmlArea) + xmlQuotes = xpath.Evaluate('child::caption/quote', xmlArea) for node in xmlQuotes: - if firstChild(node) is None: - quotes.append(firstChild(node).nodeValue) + if firstChild(node) is not None: + quotes.append(firstChild(node).text) if len(quotes) == 0: quotes.append("") quotes.append("") @@ -6277,28 +6308,28 @@ class plasma(samba): return quotes xmlAreas = xpath.Evaluate("descendant::area", self.docObj.body) - #print "-------------------------------------------------------" - #print xmlAreas - #if xmlAreas: - #prXmlArea = xmlAreas[0] for xmlArea in xmlAreas: # Перед пустой областью и после нее удаляем переводы строк - if getQuotesArea(xmlArea) == ["",""]: - #areaTXT = xpath.Evaluate("child::caption/name", xmlArea)[0] - #print "CL_AREA", areaTXT.firstChild - if xmlArea.getprevious() and\ - self.docObj.getTypeField(xmlArea.getprevious()) == "br": + if getQuotesArea(xmlArea) == ["", ""]: + if (xmlArea.getprevious() is not None and + self.docObj.getTypeField( + xmlArea.getprevious()) == "br"): parentNode = xmlArea.getprevious().getparent() - if xmlArea.getprevious().getprevious() and\ - self.docObj.getTypeField(xmlArea.getprevious().getprevious()) == "br": - parentNode.remove(\ - xmlArea.getprevious().getprevious()) + prev_prev_sbl = xmlArea.getprevious().getprevious() + if (prev_prev_sbl and + self.docObj.getTypeField( + prev_prev_sbl) == "br"): + parentNode.remove( + xmlArea.getprevious().getprevious()) parentNode.remove(xmlArea.getprevious()) - if xmlArea.getnext() and\ - self.docObj.getTypeField(xmlArea.getnext()) == "br": + if (xmlArea.getnext() is not None and + self.docObj.getTypeField( + xmlArea.getnext()) == "br"): parentNode = xmlArea.getnext().getparent() - if xmlArea.getnext().getnext() and\ - self.docObj.getTypeField(xmlArea.getnext().getnext()) == "br": + next_next_sbl = xmlArea.getnext().getnext() + if (next_next_sbl is not None and + self.docObj.getTypeField( + next_next_sbl) == "br"): parentNode.remove(xmlArea.getnext().getnext()) parentNode.remove(xmlArea.getnext()) continue @@ -6308,82 +6339,96 @@ class plasma(samba): if xmlChildAreas: childNodes = self.docObj.getFieldsArea(xmlArea) firstChildArea = xmlChildAreas[0] - if firstChildArea.getprevious() and\ - self.docObj.getTypeField(firstChildArea.getprevious())=="br": - if firstChildArea.getprevious().getprevious(): - if self.docObj.getTypeField(\ - firstChildArea.getprevious().getprevious())=="br": + + if (firstChildArea.getprevious() and + self.docObj.getTypeField( + firstChildArea.getprevious()) == "br"): + prev_prev_sbl = ( + firstChildArea.getprevious().getprevious()) + if prev_prev_sbl: + if self.docObj.getTypeField(prev_prev_sbl) == "br": firstChildArea = firstChildArea.getprevious() flagFoundArea = False it = 0 lenChild = len(childNodes) for node in childNodes: it += 1 - if node.tagName == "area": + if node.tag == "area": flagFoundArea = True continue - if flagFoundArea and node.tagName == "field": + if flagFoundArea and node.tag == "field": if self.docObj.getTypeField(node) == "var": insertBefore(xmlArea, node, firstChildArea) if it < lenChild: - if self.docObj.getTypeField(childNodes[it])==\ - "br": + node_type = self.docObj.getTypeField( + childNodes[it]) + if node_type == "br": insertBefore(xmlArea, childNodes[it], - firstChildArea) + firstChildArea) # Добавление перевода строк в если его нет между полями - if self.docObj.getTypeField(node) == "var" and\ - node.getprevious() and\ - not (self.docObj.getTypeField(node.getprevious()) in\ - ("br","comment")): - insertBefore(xmlArea, self.docObj.createField("br", - [],"",[], - False,False), - node) + if (self.docObj.getTypeField(node) == "var" and + node.getprevious() and + not (self.docObj.getTypeField( + node.getprevious()) in ("br", "comment"))): + insertBefore(xmlArea, self.docObj.createField( + "br", [], "", [], False, False), node) # Добавляем BR если его нет первым полем - xmlFields = xpath.Evaluate("child::field", xmlArea) - if not (xmlFields and\ - (self.docObj.getTypeField(xmlFields[0]) == "br" or\ - self.docObj.getTypeField(xmlFields[0]) == "comment")): + xmlFields = xpath.Evaluate("child::field", xmlArea) + if not (xmlFields and + (self.docObj.getTypeField(xmlFields[0]) == "br" or + self.docObj.getTypeField( + xmlFields[0]) == "comment")): if xmlFields: insertBefore(xmlArea, self.docObj.createField("br", - [],"",[], - False,False), - xmlFields[0]) + [], "", [], + False, False), + xmlFields[0]) + # Добавление переводов строк между полями + if xmlFields: + for node in xmlFields: + # Добавление перевода строк в если его нет между полями + if (self.docObj.getTypeField(node) == "var" and + node.getprevious() is not None and + not (self.docObj.getTypeField( + node.getprevious()) in ("br", "comment"))): + insertBefore(xmlArea, self.docObj.createField("br", + [], "", [], + False, + False), + node) # Если последним полем BR, удаляем его if xmlFields and self.docObj.getTypeField(xmlFields[-1]) == "br": - #print "DEL_BR", xmlFields[-1].getnext() - #and\ - if not xmlFields[-1].getnext(): - xmlArea.remove(xmlFields[-1]) + if not xmlFields[-1].getnext(): + xmlArea.remove(xmlFields[-1]) # Если предыдущим полем не (BR или комментарий) - добавляем BR - if xmlArea.getprevious() and\ - not (self.docObj.getTypeField(xmlArea.getprevious()) == "br" or\ - self.docObj.getTypeField(xmlArea.getprevious()) == "comment"): + if (xmlArea.getprevious() is not None and + not (self.docObj.getTypeField( + xmlArea.getprevious()) == "br" or + self.docObj.getTypeField( + xmlArea.getprevious()) == "comment")): parentNode = xmlArea.getparent() - insertBefore(parentNode, self.docObj.createField("br", - [],"",[], - False,False), - xmlArea) + insertBefore(parentNode, self.docObj.createField( + "br", [], "", [], False, False), xmlArea) # Если есть предыдущее поле, и поле предыдущеее предыдущему # не равно BR или комментарий то добавляем BR - if xmlArea.getprevious(): + if xmlArea.getprevious() is not None: prPrSibling = xmlArea.getprevious().getprevious() - if prPrSibling and\ - not (self.docObj.getTypeField(prPrSibling) == "br" or\ - self.docObj.getTypeField(prPrSibling) == "comment"): + if (prPrSibling is not None and + not (self.docObj.getTypeField( + prPrSibling) == "br" or + self.docObj.getTypeField( + prPrSibling) == "comment")): parentNode = xmlArea.getparent() - insertBefore(parentNode, self.docObj.createField("br", - [],"",[], - False,False), - xmlArea) + insertBefore(parentNode, self.docObj.createField( + "br", [], "", [], False, False), xmlArea) # Если после есть BR а за ним ничего нет, удаляем BR - if xmlArea.getnext() and\ - self.docObj.getTypeField(xmlArea.getnext()) == "br": - if not xmlArea.getnext().getnext(): - parentNode = xmlArea.getnext().getparent() - parentNode.remove(xmlArea.getnext()) + if (xmlArea.getnext() is not None and + self.docObj.getTypeField(xmlArea.getnext()) == "br"): + if xmlArea.getnext().getnext() is None: + parentNode = xmlArea.getnext().getparent() + parentNode.remove(xmlArea.getnext()) def join(self, kdeObj): @@ -6426,7 +6471,7 @@ class xml_xfce(_error): """Устанавливает название для корневой ноды документа""" if not self.bodyNode: return False - self.bodyNode.setAttribute("name", name) + self.bodyNode.set("name", name) return True def textToXML(self): @@ -6438,11 +6483,12 @@ class xml_xfce(_error): ''' try: - self.doc = xml.dom.minidom.parseString(self.text) - except: - self.setError(_("Can not text profile is XML")) + self.doc = str_to_xml_doc(self.text) + except Exception as e: + print(e) + self.setError(_("The template content is not XML")) return False - self.rootNode = self.doc.documentElement + self.rootNode = self.doc.getroottree().getroot() self.bodyNode = self.rootNode return self.doc @@ -6461,11 +6507,10 @@ class xml_xfce(_error): Также удаляет аттрибут action у всех нод """ - flagError = False childNodes = list(xmlNode) if "action" in xmlNode.keys(): nAction = xmlNode.get("action") - if not nAction in ("join","replace","drop"): + if nAction not in ("join", "replace", "drop"): textError = _("In the text of the XML template, " "reserved attribute 'action' comes with an " "incorrect value.\n" @@ -6482,10 +6527,7 @@ class xml_xfce(_error): if childNodes: for node in childNodes: if not self._removeDropNodesAndAttrAction(node): - flagError = True - break - if flagError: - return False + return False return True def postXML(self): @@ -6574,7 +6616,7 @@ class xml_xfce(_error): # Объединение нод if flagJoin: if "value" in nextOldNode.keys(): - oValue = nextOldNode.get("value") + oValue = nextOldNode.getAttribute("value") if nValue != oValue: nextOldNode.setAttribute("value", nValue) # Замещение ноды @@ -6605,20 +6647,20 @@ class xml_xfce(_error): return True def joinDoc(self, doc): - """Объединение документа профиля и документа файла""" - if not self.doc: - self.setError(_("Can not text file is XML")) + """Объединение документа шаблона и документа файла""" + if self.doc is None: + self.setError(_("The text file is not XML")) return False - if not doc: - self.setError(_("Can not text profile is XML")) + if doc is None: + self.setError(_("The text file is not XML")) return False # Импортируем корневую ноду нового документа в текущий документ - #newImportBodyNode = self.doc.importNode(doc.documentElement, True) - # Объединение корневой ноды профиля и корневой ноды файла + # newImportBodyNode = self.doc.importNode(doc.documentElement, True) + # Объединение корневой ноды шаблона и корневой ноды файла if not self._join(doc, self.bodyNode): return False return True - + def getConfig(self): """Получение текстового файла из XML документа""" data = xml_to_str(self.doc).split("\n") @@ -6724,136 +6766,131 @@ class xml_xfcepanel(xml_xfce): return True def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0): - """Объединение корневой ноды профиля и корневой ноды файла""" + """Объединение корневой ноды шаблона и корневой ноды файла""" xmlNode = xmlNewNode childNodes = list(xmlNode) nextOldNode = xmlOldNode - flagError = False - # if xmlNode.nodeType ==xmlNode.ELEMENT_NODE: - if True: - n = xmlNode - path = u'' - nName = u'' - flagArray = False - nValue = u'' - nAction = u'' - attrName = '' - attrType = '' - path = n.tagName - if path == "items": - flagArray = True - if not flagArray: - if "name" in n.keys(): - nName = n.get("name") - attrName = u"attribute::name='%s'"%nName - if "value" in n.keys(): - nValue = n.get("value") - if "action" in n.keys(): - nAction = n.get("action") - if not nAction in ("join","replace","drop"): - textError = _('''In the text, XML profile, look \ -for a reserved attribute 'action' with the incorrect value.\n\ -Valid values attribute 'action': \ -(action="join", action="replace", action="drop")''') + n = xmlNode + flagArray = False + nValue = '' + nAction = '' + attrName = '' + path = n.tag + if path == "items": + flagArray = True + if not flagArray: + if "name" in n.keys(): + nName = n.get("name") + attrName = "attribute::name='%s'" % nName + if "value" in n.keys(): + nValue = n.get("value") + if "action" in n.keys(): + nAction = n.get("action") + if not nAction in ("join", "replace", "drop"): + textError = _("In the text of the XML template, " + "reserved attribute 'action' comes with an " + "incorrect value.\n" + "Valid values of the 'action' attribute are: " + '(action="join", action="replace", ' + 'action="drop")') + self.setError(textError) + return False + if xmlNewNode.getparent() is not None: + findAttrStr = "" + if attrName: + findAttrStr = "[%s]" % attrName + findPath = "child::%s%s" % (path, findAttrStr) + # Рабочая нода + if flagRootNode: + workNode = xmlOldNode.getparent() + else: + workNode = xmlOldNode + oldNodes = xpath.Evaluate(findPath, workNode) + flagDrop = False + flagJoin = True + flagReplace = False + flagAppend = False + if nAction == "replace": + flagJoin = False + flagReplace = True + elif nAction == "drop": + flagJoin = False + flagDrop = True + if flagRootNode: + textError = _('Incorrect action="drop" ' + 'in the root node') self.setError(textError) return False - if xmlOldNode.getparent(): - findAttrStr = "" - if attrName: - findAttrStr = "[%s]"%attrName - findPath = u"child::%s%s"%(path,findAttrStr) - # Рабочая нода - if flagRootNode: - workNode = xmlOldNode.getparent() + if path == "panel": + flagJoin = False + if levelNumber in self.panelNumbers.keys(): + self.panelNumbers[levelNumber] += 1 else: - workNode = xmlOldNode - oldNodes = xpath.Evaluate(findPath, workNode) - flagDrop = False - flagJoin = True - flagReplace = False - flagAppend = False - if nAction == "replace": - flagJoin = False - flagReplace = True - elif nAction == "drop": - flagJoin = False - flagDrop = True - if flagRootNode: - textError = _('Incorrect action="drop" in root node') - self.setError(textError) - return False + self.panelNumbers[levelNumber] = 0 + if oldNodes: + if len(oldNodes) > 1 and path != "panel": + textError = _("Ambiguity in this template: the " + "same nodes are on a same level") + self.setError(textError) + return False if path == "panel": - flagJoin = False - if levelNumber in self.panelNumbers.keys(): - self.panelNumbers[levelNumber] += 1 - else: - self.panelNumbers[levelNumber] = 0 - if oldNodes: - if len(oldNodes)>1 and path != "panel": - textError = _("The uncertainty in this profile are \ -the same nodes at one level") - self.setError(textError) - return False - if path == "panel": - if len(oldNodes)<=self.panelNumbers[levelNumber]: - nextOldNode = oldNodes[-1] - # Добавляем ноду - if not flagDrop: - flagAppend = True - flagReplace = False - childNodes = False - else: - nextOldNode=oldNodes[self.panelNumbers[levelNumber]] + if len(oldNodes) <= self.panelNumbers[levelNumber]: + nextOldNode = oldNodes[-1] + # Добавляем ноду + if not flagDrop: + flagAppend = True + flagReplace = False + childNodes = False else: - nextOldNode = oldNodes[0] - # Замещаем ноду в случае массива - if flagArray and not flagDrop: - replaceXmlNode = deepcopy(xmlNode) - if nAction: - replaceXmlNode.removeAttribute("action") - workNode.replace(nextOldNode, replaceXmlNode) - flagJoin = False - flagReplace = False - childNodes = False - # Объединение нод - if flagJoin: - if "value" in nextOldNode.keys(): - oValue = nextOldNode.get("value") - if nValue != oValue: - nextOldNode.setAttribute("value",nValue) - # Замещение ноды - elif flagReplace: - replaceXmlNode = deepcopy(xmlNode) - if not\ - self._removeDropNodesAndAttrAction(replaceXmlNode): - return False - workNode.replace(nextOldNode, replaceXmlNode) - childNodes = False - # Удаление ноды - elif flagDrop: - workNode.remove(nextOldNode) - childNodes = False + nextOldNode = oldNodes[ + self.panelNumbers[levelNumber]] else: - flagAppend = True - flagDrop = False - if flagAppend and not flagDrop: - # Добавление ноды + nextOldNode = oldNodes[0] + # Замещаем ноду в случае массива + if flagArray and not flagDrop: + replaceXmlNode = deepcopy(xmlNode) + if nAction: + del replaceXmlNode.attrib["action"] + workNode.replace(nextOldNode, replaceXmlNode) + flagJoin = False + flagReplace = False childNodes = False - if not flagDrop: - appendXmlNode = deepcopy(xmlNode) - if not\ - self._removeDropNodesAndAttrAction(appendXmlNode): - return False - workNode.append(appendXmlNode) - if childNodes: - for node in childNodes: - levelNumber +=1 - if not self._join(node, nextOldNode, False, levelNumber): - flagError = True - break - levelNumber -= 1 - if flagError: - return False + # Объединение нод + if flagJoin: + if "value" in nextOldNode.keys(): + oValue = nextOldNode.get("value") + if nValue != oValue: + nextOldNode.set("value", nValue) + # Замещение ноды + elif flagReplace: + replaceXmlNode = deepcopy(xmlNode) + if not self._removeDropNodesAndAttrAction( + replaceXmlNode): + return False + workNode.replace(nextOldNode, replaceXmlNode) + childNodes = False + # Удаление ноды + elif flagDrop: + workNode.remove(nextOldNode) + childNodes = False + else: + flagAppend = True + flagDrop = False + if flagAppend and not flagDrop: + # Добавление ноды + childNodes = False + if not flagDrop: + appendXmlNode = deepcopy(xmlNode) + if not self._removeDropNodesAndAttrAction( + appendXmlNode): + return False + workNode.append(appendXmlNode) + if isinstance(childNodes, Iterable): + for node in childNodes: + levelNumber += 1 + if not self._join(node, nextOldNode, False, levelNumber): + return False + levelNumber -= 1 return True def join(self, xml_xfceObj): @@ -6861,8 +6898,8 @@ the same nodes at one level") if isinstance(xml_xfceObj, xml_xfcepanel): try: self.joinDoc(xml_xfceObj.doc) - except: - self.setError(_("Can not join profile")) + except Exception: + self.setError(_("Failed to join the template")) return False return True @@ -6963,9 +7000,10 @@ class xml_gconf(xml_xfce): # Текущее время в секундах currentTime = "" # Комментарий - _comment = ("") + _comment = ("") # поддерживаемые аттрибуты тега entry. Пример supportEntryTypes = ("int", "bool", "float", "string", "list", "pair") + # регулярное выражения для поиска \t в начале строки (преобразование xml) reStartTabs = re.compile("^(\t+)(.*)$") def __init__(self, text): @@ -6973,7 +7011,7 @@ class xml_gconf(xml_xfce): # Создаем пустой объект self.docObj = type("_empty_class", (object,), {})() # Названия аттрибутов для пустого объекта - emptyMethods = ["getNodeBody","removeComment","insertBRtoBody", + emptyMethods = ["getNodeBody", "removeComment", "insertBRtoBody", "insertBeforeSepAreas"] # Добавляем необходимые аттрибуты пустому объекту for method in emptyMethods: @@ -6994,198 +7032,188 @@ class xml_gconf(xml_xfce): if not self.text.strip(): self.text = '''''' try: - self.doc = xml.dom.minidom.parseString(self.text) - except: + self.doc = str_to_xml_doc(self.text) + except Exception: self.setError(_("Can not text profile is XML")) return False - self.rootNode = self.doc.documentElement - self.bodyNode = self.rootNode + self.rootNode = self.doc.getroottree().getroot() + self.bodyNode = self.rootNode #? a mistake, maybe? return self.doc def cmpListsNodesEntry(self, listXmlA, listXmlB): """Сравнение содержимого двух списков XML нод""" - # getTextsNodes = lambda y: map(lambda x:\ - # x.toxml().replace(" ","").replace("\t","").replace("\n",""), - # map(lambda x: "mtime" in x.keys() and\ - # x.removeAttribute("mtime") or x, - # map(lambda x: x.cloneNode(True), - # filter(lambda x: x.nodeType==x.ELEMENT_NODE, y)))) - getTextsNodes = lambda y: [o.toxml().replace(" ","").replace("\t","").replace("\n","") - for o in ("mtime" in z.keys() and z.removeAttribute("mtime") or z - for z in (deepcopy(x) - for x in y))] - # if x.nodeType==x.ELEMENT_NODE))] - if set(getTextsNodes(listXmlA))==set(getTextsNodes(listXmlB)): + def getTextsNodes(listXml): + for node in (deepcopy(x) + for x in listXml):# if x.nodeType == x.ELEMENT_NODE): + if "mtime" in node.keys(): + # node.removeAttribute("mtime") + del node.attrib["mtime"] + text = node.toxml() + yield text.replace(" ", "").replace("\t", "").replace("\n", "") + if set(getTextsNodes(listXmlA)) == set(getTextsNodes(listXmlB)): return True return False def _join(self, xmlNewNode, xmlOldNode, flagRootNode=True, levelNumber=0): """Объединение корневой ноды профиля и корневой ноды файла""" - if levelNumber>1: + if levelNumber > 1: return True xmlNode = xmlNewNode childNodes = list(xmlNode) nextOldNode = xmlOldNode - flagError = False - # if xmlNode.nodeType == xmlNode.ELEMENT_NODE: - if True: - n = xmlNode - tagName = n.tagName - nAction = u'' - nName = u'' - nType = u'' - nValue = u'' - nSchema = u'' - attrName = '' - if flagRootNode: - if not tagName == "gconf": - self.setError(_("The text is not a valid gconf-XML format \ + # if xmlNode.nodeType == xmlNode.ELEMENT_NODE: + n = xmlNode + tagName = n.tag + nAction = '' + nType = '' + nValue = '' + nSchema = '' + attrName = '' + if flagRootNode: + if not tagName == "gconf": + self.setError(_("The text is not a valid gconf-XML format \ (not found '...')")) + return False + flagType = False + flagValue = False + flagSchema = False + else: + if not tagName == "entry": + self.setError(_("The text is not a valid gconf-XML format \ +(found '<%(tag)s>..')") % {'tag': tagName}) + return False + if "name" not in n.keys(): + self.setError( + _("Attribute \"name\" not found in the tag entry")) + return False + flagType = "type" in n.keys() + flagValue = False + flagSchema = "schema" in n.keys() + if flagSchema: + nSchema = n.get("schema") + if not flagType and not flagSchema: + self.setError( + _("Attribute \"type\" not found in the tag entry")) + return False + nName = n.get("name") + attrName = "attribute::name='%s'" % nName + if flagType: + flagValue = "value" in n.keys() + nType = n.get("type") + # Проверка правильности аттрибута type + if nType not in self.supportEntryTypes: + self.setError(_("Incorrect \"type\" attribute " + ": ") % nType) return False - flagType = False - flagValue = False - flagSchema = False + if flagValue: + nValue = n.get("value") + if "action" in n.keys(): + nAction = n.get("action") + if nAction not in ("join", "replace", "drop"): + textError = _("In the text of the XML template, " + "reserved attribute 'action' comes with an " + "incorrect value.\n" + "Valid values of the 'action' attribute are: " + '(action="join", action="replace",' + 'action="drop")') + self.setError(textError) + return False + if xmlNewNode.getparent(): + findAttrStr = "" + if attrName: + findAttrStr = "[%s]" % attrName + findPath = "child::%s%s" % (tagName, findAttrStr) + # Рабочая нода + if flagRootNode: + workNode = xmlOldNode.getparent() else: - if not tagName == "entry": - self.setError(_("The text is not a valid gconf-XML format \ -(found '<%s>..'")%(tagName,tagName)) - return False - if not "name" in n.keys(): - self.setError(_('Not found arrtibute "name" in tag entry')) - return False - flagType = "type" in n.keys() - flagValue = False - flagSchema = "schema" in n.keys() - if flagSchema: - nSchema = n.get("schema") - if not flagType and not flagSchema: - self.setError(_('Not found arrtibute "type" in tag entry')) + workNode = xmlOldNode + oldNodes = xpath.Evaluate(findPath, workNode) + # По умолчанию - объединение + flagJoin = True + flagReplace = False + flagDrop = False + # Замещаем ноду + if nType == "string" or nAction == "replace": + flagJoin = False + flagReplace = True + # Замещаем ноду в случае массива + elif nType == "list" or nType == "pair": + flagJoin = False + flagReplace = True + # Удаляем ноду + elif nAction == "drop": + flagJoin = False + flagDrop = True + if flagRootNode: + textError = _('Incorrect action="drop" in ' + 'the root node') + self.setError(textError) return False - nName = n.get("name") - attrName = u"attribute::name='%s'"%nName - if flagType: - flagValue = "value" in n.keys() - nType = n.get("type") - # Проверка правильности аттрибута type - if not nType in self.supportEntryTypes: - self.setError(\ - _('Incorrect arrtibute "type" - ')\ - %nType) - return False - if flagValue: - nValue = n.get("value") - if "action" in n.keys(): - nAction = n.get("action") - if not nAction in ("join","replace","drop"): - textError = _('''In the text, XML profile, look \ -for a reserved attribute 'action' with the incorrect value.\n\ -Valid values attribute 'action': \ -(action="join", action="replace", action="drop")''') + if oldNodes: + if len(oldNodes) > 1: + textError = _("Ambiguity in this template: the same " + "nodes are on a same level") self.setError(textError) return False - if xmlOldNode.getparent(): - findAttrStr = "" - if attrName: - findAttrStr = "[%s]"%attrName - findPath = u"child::%s%s"%(tagName,findAttrStr) - # Рабочая нода - if flagRootNode: - workNode = xmlOldNode.getparent() - else: - workNode = xmlOldNode - oldNodes = xpath.Evaluate(findPath, workNode) - # По умолчанию - объединение - flagJoin = True - flagReplace = False - flagDrop = False - # Замещаем ноду - if nType=="string" or nAction=="replace": - flagJoin = False - flagReplace = True - # Замещаем ноду в случае массива - elif nType == "list" or nType == "pair": - flagJoin = False - flagReplace = True - # Удаляем ноду - elif nAction == "drop": - flagJoin = False - flagDrop = True - if flagRootNode: - textError = _('Incorrect action="drop" in root node') - self.setError(textError) - return False - if oldNodes: - if len(oldNodes)>1: - textError = _("The uncertainty in this profile are \ -the same nodes at one level") - self.setError(textError) - return False - nextOldNode = oldNodes[0] - # Объединение нод - if flagJoin: - if flagType and flagValue: - flagChange = False - foundValue = "value" in nextOldNode.keys() - if foundValue: - oValue = nextOldNode.get("value") - if nValue != oValue: - flagChange = True - else: + nextOldNode = oldNodes[0] + # Объединение нод + if flagJoin: + if flagType and flagValue: + flagChange = False + if "value" in nextOldNode.keys(): + oValue = nextOldNode.get("value") + if nValue != oValue: flagChange = True - if flagChange: - nextOldNode.setAttribute("mtime", - self.currentTime) - nextOldNode.setAttribute("value",nValue) - elif flagSchema: - flagChange = False - foundValue = "schema" in nextOldNode.keys() - if foundValue: - oSchema = nextOldNode.get("schema") - if nSchema != oSchema: - flagChange = True - else: + else: + flagChange = True + if flagChange: + nextOldNode.set("mtime", self.currentTime) + nextOldNode.set("value", nValue) + elif flagSchema: + flagChange = False + if "schema" in nextOldNode.keys(): + oSchema = nextOldNode.get("schema") + if nSchema != oSchema: flagChange = True - if flagChange: - nextOldNode.setAttribute("mtime", - self.currentTime) - nextOldNode.setAttribute("schema",nSchema) - # Замещение ноды - elif flagReplace: - replaceXmlNode = deepcopy(xmlNode) - # Сравнение содержимого нод - if not self.cmpListsNodesEntry([replaceXmlNode], - [nextOldNode]): - replaceXmlNode.setAttribute("mtime", - self.currentTime) - if not\ - self._removeDropNodesAndAttrAction(\ - replaceXmlNode): - return False - workNode.replace(nextOldNode, replaceXmlNode) - childNodes = False - # Удаление ноды - elif flagDrop: - workNode.remove(nextOldNode) - childNodes = False - else: - # Добавление ноды + else: + flagChange = True + if flagChange: + nextOldNode.set("mtime", self.currentTime) + nextOldNode.set("schema", nSchema) + # Замещение ноды + elif flagReplace: + replaceXmlNode = deepcopy(xmlNode) + # Сравнение содержимого нод + if not self.cmpListsNodesEntry([replaceXmlNode], + [nextOldNode]): + replaceXmlNode.set("mtime", + self.currentTime) + if not self._removeDropNodesAndAttrAction( + replaceXmlNode): + return False + workNode.replace(nextOldNode, replaceXmlNode) childNodes = False - if not flagDrop: - appendXmlNode = deepcopy(xmlNode) - appendXmlNode.setAttribute("mtime", self.currentTime) - if not\ - self._removeDropNodesAndAttrAction(appendXmlNode): - return False - workNode.append(appendXmlNode) - if childNodes: - for node in childNodes: - levelNumber +=1 - if not self._join(node, nextOldNode, False, levelNumber): - flagError = True - break - levelNumber -= 1 - if flagError: - return False + # Удаление ноды + elif flagDrop: + workNode.remove(nextOldNode) + childNodes = False + else: + # Добавление ноды + childNodes = False + if not flagDrop: + appendXmlNode = deepcopy(xmlNode) + appendXmlNode.set("mtime", self.currentTime) + if not self._removeDropNodesAndAttrAction( + appendXmlNode): + return False + workNode.append(appendXmlNode) + if isinstance(childNodes, Iterable): + for node in childNodes: + levelNumber += 1 + if not self._join(node, nextOldNode, False, levelNumber): + return False + levelNumber -= 1 return True def join(self, xml_gconfObj): @@ -7195,33 +7223,39 @@ the same nodes at one level") if isinstance(xml_gconfObj, xml_gconf): try: self.joinDoc(xml_gconfObj.doc) - except: + except Exception: self.setError(_("Can not join profile")) return False return True def getConfig(self): """Получение текстового файла из XML документа""" + def expandStartTabs(s): if s.startswith("\t"): - res = self.reStartTabs.findall(s) - return "".join((res[0][0].replace("\t"," "),res[0][1])) + res = self.reStartTabs.search(s) + if res: + return str(res.group(1)).replace("\t", " ") + res.group(2) + return s else: return s - data = self.doc.toprettyxml().split("\n") - data = [expandStartTabs(x) for x - in data if x.strip()] + + data = xml_to_str(self.doc).split("\n") + data = [expandStartTabs(x) for x in data if x.strip()] dataOut = [] z = 0 lenData = len(data) lenM2 = lenData - 2 for i in range(lenData): - if z>0: + 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()) + 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) + #TODO test this + dataOut.insert(0, '\n') + return "\n".join(dataOut) \ No newline at end of file From 8f18d742f144fb99bd1ce45e987f052ad790ab05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Wed, 1 Sep 2021 11:58:29 +0300 Subject: [PATCH 06/24] modernized setup, changed os.path.walk to os.walk --- pym/cl_profile.py | 116 ++++++++++++++++++++++----------------------- scripts/sortmilter | 2 +- setup.py | 31 ++++++------ 3 files changed, 74 insertions(+), 75 deletions(-) diff --git a/pym/cl_profile.py b/pym/cl_profile.py index 9ce364c..9a8e84d 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -1941,27 +1941,26 @@ class _file(_error): self.links = [] self.sockets = [] self.fifo = [] - def getFilesDir(dirP, dirname,names): - for nameFile in names: - absNameFile = dirname + "/" + nameFile - if os.path.islink(absNameFile): - dest = absNameFile - src = os.readlink(absNameFile) - dirP.links.append((src,dest)) - elif os.path.isfile(absNameFile): - dirP.files.append(absNameFile) - elif os.path.isdir(absNameFile): - dirP.dirs.append(absNameFile) - elif stat.S_ISSOCK(os.stat(absNameFile)[stat.ST_MODE]): - dirP.sockets.append(absNameFile) - elif stat.S_ISFIFO(os.stat(absNameFile)[stat.ST_MODE]): - dirP.fifo.append(absNameFile) for profileDir in profilesDirs: if profileDir: dirP = dirProf() dirP.baseDir = profileDir + for dirname, dirs, files in os.walk(profileDir): + for nameFile in dirs + files: + absNameFile = dirname + "/" + nameFile + if os.path.islink(absNameFile): + dest = absNameFile + src = os.readlink(absNameFile) + dirP.links.append((src,dest)) + elif os.path.isfile(absNameFile): + dirP.files.append(absNameFile) + elif os.path.isdir(absNameFile): + dirP.dirs.append(absNameFile) + elif stat.S_ISSOCK(os.stat(absNameFile)[stat.ST_MODE]): + dirP.sockets.append(absNameFile) + elif stat.S_ISFIFO(os.stat(absNameFile)[stat.ST_MODE]): + dirP.fifo.append(absNameFile) dirs.append(dirP) - os.path.walk(profileDir,getFilesDir, dirP) return dirs def __absFileName(self, nameFile): @@ -2725,17 +2724,16 @@ class profile(_file, _terms, xmlShare, processingTemplates): def getInstallPkgGentoo(): """Выдает словарь инсталлированных программ и номеров версий""" pkgs = [] - def getFilesDir(pkgs, dirname, names): - for nameFile in names: - absNameFile = os.path.join(dirname,nameFile) + for dirname, dirs, files in os.walk(self.basePkgDir): + for nameFile in dirs + files: + absNameFile = os.path.join(dirname, nameFile) if os.path.isdir(absNameFile): tail = absNameFile.split(self.basePkgDir) - if len(tail)==2: + if len(tail) == 2: tail = tail[1].split('/') - if len(tail)==3 and tail[1]!='virtual': + if len(tail) == 3 and tail[1] != 'virtual': pkgs.append(tail[2]) - return True - os.path.walk(self.basePkgDir,getFilesDir, pkgs) + return sharePkg(pkgs) def sharePkg(pkgs): @@ -3256,7 +3254,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): """ return True - + #TODO rewrite with os.walk def scanDirs(self, profilesDirs, objVar=False): """Измененный метод сканирования директорий""" dirs = [] @@ -3269,40 +3267,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): self.sockets = [] flagError = False blockDirs = [] - def getFilesDir(dirP, dirname, names): - for nameFile in names: - absNameFile = dirname + "/" + nameFile - findBlock = False - for blDir in blockDirs: - st,mid,end = absNameFile.partition(blDir) - if (not st) and mid and end: - findBlock = True - break - if not findBlock: - if os.path.islink(absNameFile): - dest = absNameFile - src = os.readlink(absNameFile) - dirP.links.append((src,dest)) - elif os.path.isfile(absNameFile): - # Добавляем файлы кроме описаний директорий - if self.profDirNameFile != nameFile: - dirP.files.append(absNameFile) - elif os.path.isdir(absNameFile): - # Обработка условий в названии директории - if self.getNeedProfile(absNameFile): - if self.getError(): - blockDirs.append(absNameFile) - flagError = True - break - dirP.dirs.append(absNameFile) - else: - if self.getError(): - blockDirs.append(absNameFile) - flagError = True - break - blockDirs.append(absNameFile) - elif stat.S_ISSOCK(os.stat(absNameFile)[stat.ST_MODE]): - dirP.sockets.append(absNameFile) + for profileDir in profilesDirs: if profileDir: # Обработка условий в названии директории @@ -3312,8 +3277,41 @@ class profile(_file, _terms, xmlShare, processingTemplates): break dirP = dirProf() dirP.baseDir = profileDir + for dirname, dirs, files in os.walk(profileDir): + for nameFile in dirs + files: + absNameFile = dirname + "/" + nameFile + findBlock = False + for blDir in blockDirs: + st,mid,end = absNameFile.partition(blDir) + if (not st) and mid and end: + findBlock = True + break + if not findBlock: + if os.path.islink(absNameFile): + dest = absNameFile + src = os.readlink(absNameFile) + dirP.links.append((src,dest)) + elif os.path.isfile(absNameFile): + # Добавляем файлы кроме описаний директорий + if self.profDirNameFile != nameFile: + dirP.files.append(absNameFile) + elif os.path.isdir(absNameFile): + # Обработка условий в названии директории + if self.getNeedProfile(absNameFile): + if self.getError(): + blockDirs.append(absNameFile) + flagError = True + break + dirP.dirs.append(absNameFile) + else: + if self.getError(): + blockDirs.append(absNameFile) + flagError = True + break + blockDirs.append(absNameFile) + elif stat.S_ISSOCK(os.stat(absNameFile)[stat.ST_MODE]): + dirP.sockets.append(absNameFile) dirs.append(dirP) - os.path.walk(profileDir, getFilesDir, dirP) else: if self.getError(): flagError = True diff --git a/scripts/sortmilter b/scripts/sortmilter index eaed84e..e0a5bc5 100755 --- a/scripts/sortmilter +++ b/scripts/sortmilter @@ -542,7 +542,7 @@ class SortMilter(Milter.Milter): def close(self): """Execute after end of connect (include error disconnect)""" return Milter.CONTINUE - +#TODO rewrite with os.walk def getMailFromFolder(dir): # find all files in specified directory and generate list of Letter for root, dirs, files in os.walk(dir): diff --git a/setup.py b/setup.py index 4250b4a..50c7ca2 100755 --- a/setup.py +++ b/setup.py @@ -47,24 +47,24 @@ def scanDirs(profilesDirs): self.baseDir = False self.dirs = [] self.files = [] - def getFilesDir(dirP, dirname,names): - if '/.svn' in dirname: - return False - for nameFile in names: - absNameFile = dirname + "/" + nameFile - if '/.svn' in absNameFile: - continue - if os.path.isfile(absNameFile): - dirP.files.append(absNameFile) - elif os.path.isdir(absNameFile): - dirP.dirs.append(absNameFile) - return True for profileDir in profilesDirs: if profileDir: dirP = dirProf() dirP.baseDir = profileDir + for dirname, dirs, files in os.walk(profileDir): + if '/.svn' in dirname: + return False + for nameFile in files: + absNameFile = dirname + "/" + nameFile + if '/.svn' in absNameFile: + continue + dirP.files.append(absNameFile) + for nameDir in dirs: + absNameDir = dirname + "/" + nameDir + if '/.svn' in absNameDir: + continue + dirP.dirs.append(absNameDir) dirs.append(dirP) - os.path.walk(profileDir,getFilesDir, dirP) return dirs def create_data_files (data_dirs, prefix=""): @@ -85,7 +85,8 @@ def create_data_files (data_dirs, prefix=""): break for files_obj_dir in files_obj_dirs: obj.dirs.remove(files_obj_dir) - files_obj_dirs.sort(lambda x, y: cmp(len(y), len(x))) + # files_obj_dirs.sort(lambda x, y: cmp(len(y), len(x))) + files_obj_dirs.sort(key=len) for dir_name in files_obj_dirs: wr_sp = (prefix+dir_name,[]) file_dirs = [] @@ -147,7 +148,7 @@ class cl_install_data(install_data): ("/etc/conf.d/sortmilter.conf","sortmilter",None)] data_find = \ dict( - [(os.path.basename(x[0]), [list(reversed((y for y in x[0].split("/") if y))), x[1],x[2]]) for x in data_file]) + [(os.path.basename(x[0]), [list(reversed([y for y in x[0].split("/") if y])), x[1],x[2]]) for x in data_file]) for path in self.get_outputs(): nameFile = os.path.split(path)[1] From 17a38b0cfbe3318439e15d7c93d5d021e3d80278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Wed, 1 Sep 2021 12:23:59 +0300 Subject: [PATCH 07/24] fixed imports --- pym/cl_base.py | 9 ++++++--- pym/cl_fill_server.py | 6 ++++-- pym/cl_ldap.py | 18 ++++++++++++------ pym/cl_profile.py | 12 ++++++++---- pym/cl_utils2.py | 9 +++++---- scripts/sortmilter | 2 +- 6 files changed, 36 insertions(+), 20 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index 76fc1cc..cba0688 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -31,8 +31,10 @@ import socket #import sys import random import string -from . import cl_utils -from .cl_xml import firstChild +# from . import cl_utils +import cl_utils +# from .cl_xml import firstChild +from cl_xml import firstChild ############################################################################## _expand_lang = gettext._expand_lang @@ -286,7 +288,8 @@ class opt: pass ############################################################################### -from . import cl_profile +import cl_profile +# from . import cl_profile class iniParser(cl_profile._error): """Класс для работы с ini файлами diff --git a/pym/cl_fill_server.py b/pym/cl_fill_server.py index 7a46f47..a211121 100644 --- a/pym/cl_fill_server.py +++ b/pym/cl_fill_server.py @@ -15,8 +15,10 @@ # limitations under the License. import os -from . import cl_base -from . import cl_utils +# from . import cl_base +# from . import cl_utils +import cl_base +import cl_utils import hashlib import re import types diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 2c22487..870c26d 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -19,10 +19,14 @@ import ldap # import cStringIO, StringIO from io import StringIO, BytesIO from ldif import LDIFParser, LDIFWriter -from . import cl_base -from . import cl_profile -from . import cl_utils2 -from . import cl_utils +# from . import cl_base +# from . import cl_profile +# from . import cl_utils2 +# from . import cl_utils +import cl_base +import cl_profile +import cl_utils2 +import cl_utils # Для подсчета символов import termios, fcntl, struct # Ввод pwd @@ -41,7 +45,8 @@ import tempfile import readline # Пути в XML документе # from xml import xpath -from .cl_xml import xpath, firstChild +# from .cl_xml import xpath, firstChild +from cl_xml import xpath, firstChild # Для 32 битного целого (генерация серийного номера DNS зоны) import ctypes from functools import reduce @@ -21775,7 +21780,8 @@ network %s") % net) def createLogFile(self): """Создание файла лога или если нужно изменение владельца файла лога""" - from . import cl_log + # from . import cl_log + import cl_log # Полное имя файла лога (путь плюс имя файла) logFullFile = os.path.join(cl_log.log.logDir, self.errorLogFile) if not os.path.exists(cl_log.log.logDir): diff --git a/pym/cl_profile.py b/pym/cl_profile.py index 9a8e84d..802d436 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -16,7 +16,8 @@ import sys import os -from . import cl_base +import cl_base +# from . import cl_base import stat import re # import xml.dom.minidom @@ -25,8 +26,10 @@ import re # if hasattr(xml,"use_pyxml"): # xml.use_pyxml() # from xml import xpath -from . import cl_xml -from .cl_xml import xpath, firstChild,\ +import cl_xml +# from . import cl_xml +# from .cl_xml import xpath, firstChild,\ +from cl_xml import xpath, firstChild,\ insertBefore, str_to_xml_doc, xml_to_str, xmlShare,\ xmlNode, xmlField, xmlFields, xmlArea, xmlDoc import subprocess @@ -2223,7 +2226,8 @@ class utfBin: def getUserDataInLDAP(self, userName): """Получаем домашнюю директорию пользователя из LDAP""" if not self.conLdap: - from . import cl_utils2 + # from . import cl_utils2 + import cl_utils2 data = self.getLDAPDataInConfig() if not data: return "" diff --git a/pym/cl_utils2.py b/pym/cl_utils2.py index fe3c30d..5bca1c7 100644 --- a/pym/cl_utils2.py +++ b/pym/cl_utils2.py @@ -18,9 +18,10 @@ import sys import struct import termios import fcntl -from . import cl_utils - -from . import cl_profile +# from . import cl_utils +# from . import cl_profile +import cl_utils +import cl_profile import ldap class ldapFun(cl_profile._error): '''Объект для работы с LDAP сервером @@ -136,7 +137,7 @@ class cl_help: для по ним справку. """ # сформировать нужное количество блоков раздела - self.chapterBloc = [""]*len(self.chapter) + self.chapterBloc = [""] * len(self.chapter) # sp = {} i = 0 diff --git a/scripts/sortmilter b/scripts/sortmilter index e0a5bc5..2d707df 100755 --- a/scripts/sortmilter +++ b/scripts/sortmilter @@ -542,7 +542,7 @@ class SortMilter(Milter.Milter): def close(self): """Execute after end of connect (include error disconnect)""" return Milter.CONTINUE -#TODO rewrite with os.walk + def getMailFromFolder(dir): # find all files in specified directory and generate list of Letter for root, dirs, files in os.walk(dir): From 15f84dd3aae4f01e867d1df5e418ef79e1164c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Wed, 1 Sep 2021 15:54:24 +0300 Subject: [PATCH 08/24] fixed some encoding bugs --- pym/cl_base.py | 36 +-- pym/cl_fill.py | 575 +++++++++++++++++++++--------------------- pym/cl_fill_server.py | 281 +-------------------- pym/cl_ldap.py | 27 +- pym/cl_utils.py | 18 +- pym/cl_xml.py | 2 +- 6 files changed, 329 insertions(+), 610 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index cba0688..7c1b6eb 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -35,6 +35,7 @@ import string import cl_utils # from .cl_xml import firstChild from cl_xml import firstChild +import importlib ############################################################################## _expand_lang = gettext._expand_lang @@ -449,7 +450,7 @@ class iniParser(cl_profile._error): xmlBody = objIni.docObj.getNodeBody() flagFound, xmlBody = self.getLastNode(objIni, xmlBody, strHeader, formatPlasma) - if flagFound and xmlBody: + if flagFound and xmlBody is not None: if formatPlasma: strHeader = strHeader[-1] # находим в области переменную @@ -504,7 +505,7 @@ class iniParser(cl_profile._error): xmlBody = objIni.docObj.getNodeBody() flagFound, xmlBody = self.getLastNode(objIni, xmlBody, strHeader, formatPlasma) - if flagFound and xmlBody: + if flagFound and xmlBody is not None: if formatPlasma: strHeader = strHeader[-1] # если находим область то выдаем словарем все переменные иначе False @@ -656,10 +657,10 @@ class DataVars(): # Импортируемые модули - (раздел: модуль переменных, модуль заполнения #переменных) __modlist={ - # 'Global':('cl_vars','cl_fill'), + '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'), + 'Builder':('cl_vars_builder','cl_fill_builder'), + 'Client':('cl_vars_client','cl_fill_client'), } def __init__(self): #self.t1 = fillVars() @@ -685,14 +686,16 @@ class DataVars(): modFill = self.__modlist[section][1] # Импортируем класс описания переменных и класс заполнения try: - eval("import %s" % (modVar)) + # eval("import %s" % (modVar)) + modVar_imported = importlib.import_module(modVar) except ImportError as e: err1 = _("Error in import module %s")%modVar err2 = _("error") + ": " +str(e) raise self.DataVarsError("%s\n%s"%(err1,err2)) flagFindFillModule = True try: - eval("import %s" % (modFill)) + # eval("import %s" % (modFill)) + modFill_imported = importlib.import_module(modFill) except ImportError as e: if "No module named" in str(e): flagFindFillModule = False @@ -702,14 +705,16 @@ class DataVars(): raise self.DataVarsError("%s\n%s"%(err1,err2)) if flagFindFillModule: # Создаем объект с методами заполнения переменных - fillObj = eval("%s.fillVars()" % modFill) + fillObj = modFill_imported.fillVars() + importlib.import_module(modFill) # Подключаем методы получения и записи переменных fillObj.Get = self.Get fillObj.Set = self.Set else: fillObj = False # Заполняем self._importList - eval("self._importList.insert(0,(section,%s,fillObj))"%(modVar)) + self._importList.insert(0,(section, modVar_imported, fillObj)) + def __findVarData(self, nameVar): """Находит данные для создания объекта переменная в модулях и @@ -718,20 +723,21 @@ class DataVars(): """ # Ищем переменную в модуле dataVar = False - e = False + err = False for section, moduleVar, fillobj in self._importList: try: - eval("dataVar=moduleVar.Data.%s"%nameVar) + # dataVar = moduleVar.Data.nameVar + dataVar = getattr(moduleVar.Data, nameVar) except AttributeError as e: - pass + err = e 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)) + if err: + err2 = _("error") + ": " +str(err) + raise self.DataVarsError("%s\n%s"%(err1, err2)) dataVar['service'] = section # Ищем метод в объекте методов заполнения nameMethod = "get_" + nameVar diff --git a/pym/cl_fill.py b/pym/cl_fill.py index 45f5b11..66ef39b 100644 --- a/pym/cl_fill.py +++ b/pym/cl_fill.py @@ -1,311 +1,304 @@ -# #-*- coding: utf-8 -*- +#-*- coding: utf-8 -*- -# # Copyright 2008-2010 Mir Calculate. 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. +# Copyright 2008-2010 Mir Calculate. 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 re -# import os -# import types -# import cl_utils -# import cl_base +import re +import os +import types +import cl_utils +import cl_base -# class fillVars_(cl_base.glob_attr): +class fillVars(cl_base.glob_attr): -# def get_os_net_domain(self): -# ''' Определим домен''' -# domain=self._runos("hostname -d 2>&1") -# if not domain: -# print _("Error:") + " " +_("Not found domain name") -# print _("Command 'hostname -d' returns an empty value") -# cl_base.exit(1) -# elif re.search("^hostname: ",domain): -# return "local" -# else: -# return domain + def get_os_net_domain(self): + ''' Определим домен''' + domain=self._runos("hostname -d 2>&1") + if not domain: + print(_("Error:") + " " +_("Not found domain name")) + print(_("Command 'hostname -d' returns an empty value")) + cl_base.exit(1) + elif re.search("^hostname: ",domain): + return "local" + else: + return domain -# def get_os_linux_shortname(self): -# '''Получить переменную короткого названия системы''' -# path = '/etc/calculate/calculate.ini' -# 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]=="calculate" and\ -# x.split("=")[1].strip(), data)) -# if shortNameList: -# return shortNameList[0] -# gentooFile = "/etc/gentoo-release" -# shortName = "Linux" -# if os.path.exists(gentooFile): -# shortName = "Gentoo" -# return shortName + def get_os_linux_shortname(self): + '''Получить переменную короткого названия системы''' + path = '/etc/calculate/calculate.ini' + if os.path.exists(path): + FD = open(path) + data = FD.readlines() + FD.close() + shortNameList = [x for x in (len(y.split("=")) == 2 and\ + y.split("=")[0]=="calculate" and\ + y.split("=")[1].strip() for y in data) if x] + if shortNameList: + return shortNameList[0] + gentooFile = "/etc/gentoo-release" + shortName = "Linux" + if os.path.exists(gentooFile): + shortName = "Gentoo" + return shortName -# def get_os_linux_name(self): -# """полное название системы""" -# linuxShortName = self.Get("os_linux_shortname") -# if linuxShortName: -# dictLinuxName = {"CLD":"Calculate Linux Desktop", -# "CLDX":"Calculate Linux Desktop", -# "CLDG":"Calculate Linux Desktop", -# "CDS":"Calculate Directory Server", -# "Gentoo":"Gentoo"} -# if linuxShortName in dictLinuxName.keys(): -# return dictLinuxName[linuxShortName] -# else: -# return "Linux" -# else: -# return "Linux" + def get_os_linux_name(self): + """полное название системы""" + linuxShortName = self.Get("os_linux_shortname") + if linuxShortName: + dictLinuxName = {"CLD":"Calculate Linux Desktop", + "CLDX":"Calculate Linux Desktop", + "CLDG":"Calculate Linux Desktop", + "CDS":"Calculate Directory Server", + "Gentoo":"Gentoo"} + if linuxShortName in dictLinuxName.keys(): + return dictLinuxName[linuxShortName] + else: + return "Linux" + else: + return "Linux" -# def get_os_linux_subname(self): -# """постфикс к названию системы""" -# linuxShortName = self.Get("os_linux_shortname") -# if linuxShortName: -# dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE", "CLDG":"GNOME"} -# if linuxShortName in dictLinuxSubName.keys(): -# return dictLinuxSubName[linuxShortName] -# else: -# return "" -# else: -# return "" + def get_os_linux_subname(self): + """постфикс к названию системы""" + linuxShortName = self.Get("os_linux_shortname") + if linuxShortName: + dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE", "CLDG":"GNOME"} + if linuxShortName in dictLinuxSubName.keys(): + return dictLinuxSubName[linuxShortName] + else: + return "" + else: + return "" -# def get_os_linux_ver(self): -# '''Получить версию системы''' -# path = '/etc/calculate/calculate.ini' -# 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]=="linuxver" and\ -# x.split("=")[1].strip(), data)) -# if shortNameList: -# return shortNameList[0] -# gentooFile = "/etc/gentoo-release" -# systemVersion = "" -# flagGentoo = False -# if os.path.exists(gentooFile): -# gentooLink = "/etc/make.profile" -# if os.path.islink(gentooLink): -# systemVersion = os.readlink(gentooLink).rpartition("/")[2] -# flagGentoo = True -# if not flagGentoo: -# kernelVersion=self._runos("uname -r") -# if kernelVersion: -# systemVersion = kernelVersion.partition("-")[0] -# return systemVersion + def get_os_linux_ver(self): + '''Получить версию системы''' + path = '/etc/calculate/calculate.ini' + if os.path.exists(path): + FD = open(path) + data = FD.readlines() + FD.close() + shortNameList = [x for x in ( len(y.split("="))==2 and\ + y.split("=")[0]=="linuxver" and\ + y.split("=")[1].strip() for y in data) if x] + if shortNameList: + return shortNameList[0] + gentooFile = "/etc/gentoo-release" + systemVersion = "" + flagGentoo = False + if os.path.exists(gentooFile): + gentooLink = "/etc/make.profile" + if os.path.islink(gentooLink): + systemVersion = os.readlink(gentooLink).rpartition("/")[2] + flagGentoo = True + if not flagGentoo: + kernelVersion=self._runos("uname -r") + if kernelVersion: + systemVersion = kernelVersion.partition("-")[0] + return systemVersion -# def get_os_net_hostname(self): -# '''Считать имя компьютера net_host''' -# hostname=self._runos("hostname -s 2>&1") -# if not hostname: -# return "" -# if re.search("^hostname: ",hostname): -# hostname=self._runos("hostname 2>&1") -# if not hostname: -# return "" -# 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_hostname(self): + '''Считать имя компьютера net_host''' + hostname=self._runos("hostname -s 2>&1") + if not hostname: + return "" + if re.search("^hostname: ",hostname): + hostname=self._runos("hostname 2>&1") + if not hostname: + return "" + if re.search("^hostname: ",hostname): + return self.Get('os_linux_shortname') + else: + if hostname=='livecd': + return self.Get('os_linux_shortname') + return hostname -# # все ip -# def get_os_net_ip(self): -# """все ip компьютера, разделитель запятая""" -# return ",".join(map(cl_utils.getIp, -# cl_utils.getInterfaces())) + # все ip + def get_os_net_ip(self): + """все ip компьютера, разделитель запятая""" + return ",".join(cl_utils.getIp(x) for x in cl_utils.getInterfaces()) -# # Разрешенные сети (в данном случае все сети) -# def get_os_net_allow(self): -# """Разрешенные сети разделитель запятая""" -# networks=[] -# netInterfaces=cl_utils.getInterfaces() -# for i in netInterfaces: -# ipaddr, mask = cl_utils.getIp(i), \ -# cl_utils.cidrToMask(cl_utils.getMask(i)) -# if ipaddr and mask: -# networks.append(cl_utils.getIpNet(ipaddr, mask)) -# else: -# networks.append("") -# return ",".join(filter(lambda x:x,networks)) + # Разрешенные сети (в данном случае все сети) + def get_os_net_allow(self): + """Разрешенные сети разделитель запятая""" + networks=[] + netInterfaces=cl_utils.getInterfaces() + for i in netInterfaces: + ipaddr, mask = cl_utils.getIp(i), \ + cl_utils.cidrToMask(cl_utils.getMask(i)) + if ipaddr and mask: + networks.append(cl_utils.getIpNet(ipaddr, mask)) + else: + networks.append("") + return ",".join(x for x in networks if x) -# 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_locale(self): + """локаль (прим: ru_RU.UTF-8)""" + if "LANG" in os.environ: + 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_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_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_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 = [x for x in (len(y.split("="))==2 and\ + y.split("=")[0]=="KEYMAP" and\ + y.split("=")[1].replace('"',"").strip() + for y in data) if x] + 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 lang in xkbDict: + return xkbDict[lang] + return "" -# def get_os_locale_xkbname(self): -# """названия используемых раскладок клавиатуры для X""" -# localeXkb = self.Get("os_locale_xkb") -# if localeXkb: -# return localeXkb.split("(")[0] -# return "" + def get_os_locale_xkbname(self): + """названия используемых раскладок клавиатуры для X""" + localeXkb = self.Get("os_locale_xkb") + if localeXkb: + return localeXkb.split("(")[0] + return "" -# def get_os_arch_machine(self): -# """архитектура процессора""" -# march = self._runos("uname -m") -# if not march: -# return "" -# return march + def get_os_arch_machine(self): + """архитектура процессора""" + march = self._runos("uname -m") + if not march: + return "" + return march -# def get_os_root_dev(self): -# """корневой раздел файловой системы""" -# for record in open('/proc/cmdline','rb').readlines(): -# re_res=re.search('^root=(\/dev\/[a-z]+[0-9]).*',record.strip()) -# if re_res: -# return re_res.group(1) -# else: -# mountLunes = self._runos("mount") -# if not mountLunes: -# return "" -# if type(mountLunes) == types.ListType: -# root_dev = mountLunes[0].split("on / type")[0].strip() -# if root_dev: -# return root_dev -# return "" + def get_os_root_dev(self): + """корневой раздел файловой системы""" + for record in open('/proc/cmdline','rb').readlines(): + re_res=re.search('^root=(\/dev\/[a-z]+[0-9]).*',record.strip()) + if re_res: + return re_res.group(1) + else: + mountLunes = self._runos("mount") + if not mountLunes: + return "" + if type(mountLunes) == list: + root_dev = mountLunes[0].split("on / type")[0].strip() + if root_dev: + return root_dev + return "" -# def get_os_root_type(self): -# """тип носителя (ram, hdd, livecd)""" -# mountLunes = self._runos("mount") -# if not mountLunes: -# return "" -# rootType = "hdd" -# if type(mountLunes) == types.ListType: -# flagCD = False -# for line in mountLunes: -# if "/dev/loop0 on / type" in line: -# rootType = "ram" -# break -# elif "/dev/loop0 on /newroot/mnt/livecd type" in line: -# rootType = "ram" -# flagCD = True -# break -# if rootType == "ram": -# if os.path.exists("/mnt/livecd") or flagCD: -# rootType = "livecd" -# return rootType -# rootDev = self.Get("os_root_dev") -# if rootType != "ram" and rootDev: -# slpRootDev = rootDev.split("/dev/") -# if len(slpRootDev) == 2: -# rDev = slpRootDev[1] -# devLines = self._runos("ls -la /dev/disk/by-id/", None, -# {"LANG":"C"}) -# if not devLines: -# return "" -# if type(devLines) == types.ListType: -# for line in devLines: -# if rDev in line and "usb-" in line: -# rootType = "usb-hdd" -# break -# if rootType == "ram": -# rootType = "hdd" -# return rootType -# else: -# return "" + def get_os_root_type(self): + """тип носителя (ram, hdd, livecd)""" + mountLunes = self._runos("mount") + if not mountLunes: + return "" + rootType = "hdd" + if type(mountLunes) == list: + flagCD = False + for line in mountLunes: + if "/dev/loop0 on / type" in line: + rootType = "ram" + break + elif "/dev/loop0 on /newroot/mnt/livecd type" in line: + rootType = "ram" + flagCD = True + break + if rootType == "ram": + if os.path.exists("/mnt/livecd") or flagCD: + rootType = "livecd" + return rootType + rootDev = self.Get("os_root_dev") + if rootType != "ram" and rootDev: + slpRootDev = rootDev.split("/dev/") + if len(slpRootDev) == 2: + rDev = slpRootDev[1] + devLines = self._runos("ls -la /dev/disk/by-id/", None, + {"LANG":"C"}) + if not devLines: + return "" + if type(devLines) == list: + for line in devLines: + if rDev in line and "usb-" in line: + rootType = "usb-hdd" + break + if rootType == "ram": + rootType = "hdd" + return rootType + else: + return "" -# def get_hr_virtual(self): -# """Название виртуальной машины (virtualbox, vmware, qemu)""" -# pciLines = self._runos("/usr/sbin/lspci") -# if not pciLines: -# return False -# virtSysDict = {'VirtualBox':'virtualbox', -# 'VMware':'vmware', -# 'Qumranet':'qemu'} -# virtName = '' -# for vName in virtSysDict.keys(): -# if filter(lambda x: vName in x, pciLines): -# virtName = virtSysDict[vName] -# break -# return virtName + def get_hr_virtual(self): + """Название виртуальной машины (virtualbox, vmware, qemu)""" + pciLines = self._runos("/usr/sbin/lspci") + if not pciLines: + return False + virtSysDict = {'VirtualBox':'virtualbox', + 'VMware':'vmware', + 'Qumranet':'qemu'} + virtName = '' + for vName in virtSysDict.keys(): + if [x for x in pciLines if vName in x]: + virtName = virtSysDict[vName] + break + return virtName diff --git a/pym/cl_fill_server.py b/pym/cl_fill_server.py index a211121..ca15a07 100644 --- a/pym/cl_fill_server.py +++ b/pym/cl_fill_server.py @@ -609,283 +609,4 @@ class fillVars(cl_base.glob_attr): return getNetAllow(netAllow) return "listen-on { 127.0.0.1; };" - def get_os_net_domain(self): - ''' Определим домен''' - domain=self._runos("hostname -d 2>&1") - if not domain: - print(_("Error:") + " " +_("Not found domain name")) - print(_("Command 'hostname -d' returns an empty value")) - cl_base.exit(1) - elif re.search("^hostname: ",domain): - return "local" - else: - return domain - - def get_os_linux_shortname(self): - '''Получить переменную короткого названия системы''' - path = '/etc/calculate/calculate.ini' - if os.path.exists(path): - FD = open(path) - data = FD.readlines() - FD.close() - shortNameList = [x for x in (len(y.split("=")) == 2 and\ - y.split("=")[0]=="calculate" and\ - y.split("=")[1].strip() for y in data) if x] - if shortNameList: - return shortNameList[0] - gentooFile = "/etc/gentoo-release" - shortName = "Linux" - if os.path.exists(gentooFile): - shortName = "Gentoo" - return shortName - - def get_os_linux_name(self): - """полное название системы""" - linuxShortName = self.Get("os_linux_shortname") - if linuxShortName: - dictLinuxName = {"CLD":"Calculate Linux Desktop", - "CLDX":"Calculate Linux Desktop", - "CLDG":"Calculate Linux Desktop", - "CDS":"Calculate Directory Server", - "Gentoo":"Gentoo"} - if linuxShortName in dictLinuxName.keys(): - return dictLinuxName[linuxShortName] - else: - return "Linux" - else: - return "Linux" - - def get_os_linux_subname(self): - """постфикс к названию системы""" - linuxShortName = self.Get("os_linux_shortname") - if linuxShortName: - dictLinuxSubName = {"CLD":"KDE", "CLDX":"XFCE", "CLDG":"GNOME"} - if linuxShortName in dictLinuxSubName.keys(): - return dictLinuxSubName[linuxShortName] - else: - return "" - else: - return "" - - def get_os_linux_ver(self): - '''Получить версию системы''' - path = '/etc/calculate/calculate.ini' - if os.path.exists(path): - FD = open(path) - data = FD.readlines() - FD.close() - shortNameList = [x for x in ( len(y.split("="))==2 and\ - y.split("=")[0]=="linuxver" and\ - y.split("=")[1].strip() for y in data) if x] - if shortNameList: - return shortNameList[0] - gentooFile = "/etc/gentoo-release" - systemVersion = "" - flagGentoo = False - if os.path.exists(gentooFile): - gentooLink = "/etc/make.profile" - if os.path.islink(gentooLink): - systemVersion = os.readlink(gentooLink).rpartition("/")[2] - flagGentoo = True - if not flagGentoo: - kernelVersion=self._runos("uname -r") - if kernelVersion: - systemVersion = kernelVersion.partition("-")[0] - return systemVersion - - def get_os_net_hostname(self): - '''Считать имя компьютера net_host''' - hostname=self._runos("hostname -s 2>&1") - if not hostname: - return "" - if re.search("^hostname: ",hostname): - hostname=self._runos("hostname 2>&1") - if not hostname: - return "" - if re.search("^hostname: ",hostname): - return self.Get('os_linux_shortname') - else: - if hostname=='livecd': - return self.Get('os_linux_shortname') - return hostname - - # все ip - def get_os_net_ip(self): - """все ip компьютера, разделитель запятая""" - return ",".join(cl_utils.getIp(x) for x in cl_utils.getInterfaces()) - - # Разрешенные сети (в данном случае все сети) - def get_os_net_allow(self): - """Разрешенные сети разделитель запятая""" - networks=[] - netInterfaces=cl_utils.getInterfaces() - for i in netInterfaces: - ipaddr, mask = cl_utils.getIp(i), \ - cl_utils.cidrToMask(cl_utils.getMask(i)) - if ipaddr and mask: - networks.append(cl_utils.getIpNet(ipaddr, mask)) - else: - networks.append("") - return ",".join(x for x in networks if x) - - def get_os_locale_locale(self): - """локаль (прим: ru_RU.UTF-8)""" - if "LANG" in os.environ: - 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 = [x for x in (len(y.split("="))==2 and\ - y.split("=")[0]=="KEYMAP" and\ - y.split("=")[1].replace('"',"").strip() - for y in data) if x] - 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 lang in xkbDict: - return xkbDict[lang] - return "" - - def get_os_locale_xkbname(self): - """названия используемых раскладок клавиатуры для X""" - localeXkb = self.Get("os_locale_xkb") - if localeXkb: - return localeXkb.split("(")[0] - return "" - - def get_os_arch_machine(self): - """архитектура процессора""" - march = self._runos("uname -m") - if not march: - return "" - return march - - def get_os_root_dev(self): - """корневой раздел файловой системы""" - for record in open('/proc/cmdline','rb').readlines(): - re_res=re.search('^root=(\/dev\/[a-z]+[0-9]).*',record.strip()) - if re_res: - return re_res.group(1) - else: - mountLunes = self._runos("mount") - if not mountLunes: - return "" - if type(mountLunes) == list: - root_dev = mountLunes[0].split("on / type")[0].strip() - if root_dev: - return root_dev - return "" - - def get_os_root_type(self): - """тип носителя (ram, hdd, livecd)""" - mountLunes = self._runos("mount") - if not mountLunes: - return "" - rootType = "hdd" - if type(mountLunes) == list: - flagCD = False - for line in mountLunes: - if "/dev/loop0 on / type" in line: - rootType = "ram" - break - elif "/dev/loop0 on /newroot/mnt/livecd type" in line: - rootType = "ram" - flagCD = True - break - if rootType == "ram": - if os.path.exists("/mnt/livecd") or flagCD: - rootType = "livecd" - return rootType - rootDev = self.Get("os_root_dev") - if rootType != "ram" and rootDev: - slpRootDev = rootDev.split("/dev/") - if len(slpRootDev) == 2: - rDev = slpRootDev[1] - devLines = self._runos("ls -la /dev/disk/by-id/", None, - {"LANG":"C"}) - if not devLines: - return "" - if type(devLines) == list: - for line in devLines: - if rDev in line and "usb-" in line: - rootType = "usb-hdd" - break - if rootType == "ram": - rootType = "hdd" - return rootType - else: - return "" - - def get_hr_virtual(self): - """Название виртуальной машины (virtualbox, vmware, qemu)""" - pciLines = self._runos("/usr/sbin/lspci") - if not pciLines: - return False - virtSysDict = {'VirtualBox':'virtualbox', - 'VMware':'vmware', - 'Qumranet':'qemu'} - virtName = '' - for vName in virtSysDict.keys(): - if [x for x in pciLines if vName in x]: - virtName = virtSysDict[vName] - break - return virtName + \ No newline at end of file diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 870c26d..81d2779 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -149,7 +149,7 @@ class report: сначала строки будет вставлено char[1:] в конце строки char[:-1] """ - # lineUnicode = cl_utils._toUNICODE(line) + lineUnicode = cl_utils._toUNICODE(line) prevPos = 0 convLine = char[1:] lenLenCols = len(lenCols) @@ -14867,7 +14867,6 @@ with another option.")) # Если сервис не установлен то ошибка if not servObj.isServiceSetup(service): return False - #TODO debug this: if relAttr not in servObj.__dict__: self.printERROR("getQueryLDAP service=%s"%service) self.printERROR(_("ERROR: getQueryLDAP incorrect branch=%s")%branch) @@ -15040,7 +15039,7 @@ with another option.")) if service == "mail": for i in searchRes: i[0][1]['homeDirectory'] = [os.path.join(\ - clVars.Get("sr_mail_path"), i[0][1]['uid'][0])] + clVars.Get("sr_mail_path"), i[0][1]['uid'][0].decode("UTF-8"))] data.append((_("Home directory"),"homeDirectory")) # Добавляем директории пользователя для сервиса samba # а так же первичную и дополнительные группы @@ -15062,7 +15061,7 @@ with another option.")) data.append((_("Primary group"),"gidNumber")) homePath = os.path.join(\ clVars.Get("sr_samba_home_path"), - i[0][1]['uid'][0]) + i[0][1]['uid'][0].decode("UTF-8")) if os.path.exists(homePath): i[0][1]['homePath'] = [homePath] data.append((_("Home directory"),"homePath")) @@ -15072,19 +15071,19 @@ with another option.")) data.append((_("Share directory"),"sharePath")) linProfPath = os.path.join(\ clVars.Get("sr_samba_linprof_path"), - i[0][1]['uid'][0]) + i[0][1]['uid'][0].decode("UTF-8")) if os.path.exists(linProfPath): i[0][1]['linProfPath'] = [linProfPath] data.append((_("Linux profile"),"linProfPath")) winProfPath = os.path.join(\ clVars.Get("sr_samba_winprof_path"), - i[0][1]['uid'][0]) + i[0][1]['uid'][0].decode("UTF-8")) if os.path.exists(winProfPath): i[0][1]['winProfPath'] = [winProfPath] data.append((_("Windows profile"),"winProfPath")) winLogonPath = os.path.join(\ clVars.Get("sr_samba_winlogon_path"), - i[0][1]['uid'][0]) + i[0][1]['uid'][0].decode("UTF-8")) if os.path.exists(winLogonPath): i[0][1]['winLogonPath'] = [winLogonPath] data.append((_("Windows logon"),"winLogonPath")) @@ -15450,15 +15449,15 @@ with another option.")) def modUserAttr(self, attr, value, service): """Модифицирует аттрибуты пользователя для вывода на печать""" # Конвертируем время в текстовый формат - retValue = value + retValue = value.decode("UTF-8") if isinstance(value, bytes) else value if attr == "shadowLastChange" or\ attr == "sambaPwdLastSet": retValue = self._convDatatoStr(value) # Находим имя группы elif attr == "gidNumber" and service in ("unix", "ftp"): - retValue = self._getUserGroupName(value, "unix") + retValue = self._getUserGroupName(retValue, "unix") elif attr == "gidNumber" and service in ("samba",): - retValue = self._getUserGroupName(value, service) + retValue = self._getUserGroupName(retValue, service) # Ставим Y в случае выставленного флага elif attr == "initials": if value == "No": @@ -15476,7 +15475,7 @@ with another option.")) else: retValue = _("No") elif attr == "sambaAcctFlags": - if "D" in value: + if "D" in retValue: retValue = _("Yes") else: retValue = _("No") @@ -15492,7 +15491,7 @@ with another option.")) retValue = _("No") elif attr == "sambaNTPassword": retValue = _("Yes") - return retValue + return retValue.decode("UTF-8") if isinstance(retValue, bytes) else retValue def _convDatatoStr(self, dataDays): """Конвертирует количество дней или секунд с 1970, в строку даты""" @@ -15517,7 +15516,7 @@ with another option.")) if service == "unix": retCondUnix, userGidNamesLdap, errMessUnix =\ servObj.searchGroupsUnix([userGid], False) - userGidNamesLdap = userGidNamesLdap.keys() + userGidNamesLdap = list(userGidNamesLdap.keys()) userGidNamesPasswd = servObj.searchGroupsGroups([userGid], False) if userGidNamesPasswd: #Имя группы пользователя @@ -15531,7 +15530,7 @@ with another option.")) if service == "samba": retCondSamba, userGidNamesLdap, errMessUnix =\ servObj.searchGroupsSamba([userGid], False) - userGidNamesLdap = userGidNamesLdap.keys() + userGidNamesLdap = list(userGidNamesLdap.keys()) if userGidNamesLdap: #Имя группы пользователя groupName = userGidNamesLdap[0] diff --git a/pym/cl_utils.py b/pym/cl_utils.py index 0d58dae..61a6f1d 100644 --- a/pym/cl_utils.py +++ b/pym/cl_utils.py @@ -142,7 +142,7 @@ def prettyColumnStr(*cols): q += 2 # колонки отображены retstr += "\n" - return retstr.encode('utf8') + return retstr def columnStr(*cols): '''Вывод данных по колонкам, причем, если данные не вмещаются в указнаную @@ -162,7 +162,7 @@ def columnStr(*cols): cols = list(cols) # перевести текст в юникод, заодно перевести числа в строку for i in range(0,len(cols),2): - cols[i] = (str(cols[i])).decode('utf8') + cols[i] = (str(cols[i])) # флаг "есть еще текст для вывода" repeat = True @@ -179,7 +179,7 @@ def columnStr(*cols): cols[q] = '' else: # вывести часть строки не больше указанной ширины колонки - retstr+=(cols[q][:cols[q+1]].ljust(cols[q+1])).encode('utf8') \ + retstr+=(cols[q][:cols[q+1]].ljust(cols[q+1])) \ + " " # остальную часть строки оставить на следующую итерацию cols[q] = cols[q][cols[q+1]:] @@ -207,7 +207,7 @@ def columnWrite(*cols): cols = list(cols) # перевести текст в юникод, заодно перевести числа в строку for i in range(0,len(cols),2): - cols[i] = (str(cols[i])).decode('utf8') + cols[i] = (str(cols[i])) # флаг "есть еще текст для вывода" repeat = True @@ -220,11 +220,11 @@ def columnWrite(*cols): # если это последний параметр, и для него не указана ширина if q == len(cols)-1: # выводим его полностью не смотря на ширину окна - print(cols[q].encode('utf8'), end=' ') + print(cols[q], end=' ') cols[q] = '' else: # вывести часть строки не больше указанной ширины колонки - print((cols[q][:cols[q+1]].ljust(cols[q+1])).encode('utf8'), end=' ') + print((cols[q][:cols[q+1]].ljust(cols[q+1])), end=' ') # остальную часть строки оставить на следующую итерацию cols[q] = cols[q][cols[q+1]:] # если от строки что то осаталось @@ -252,7 +252,7 @@ def justify(s,width): pos = 0 # переводим в юникод для правильного вычисления длины try: - s = s.decode( 'utf-8' ) + s = s # пропуск если это не utf-8 except UnicodeEncodeError: pass @@ -268,7 +268,7 @@ def justify(s,width): # оставить удвоенный пробел pos += 3 # вернуть строку в utf8 если она пришла в utf8 - return s.encode('utf-8') + return s def runOsCommand(cmd, inStr=None, ret_first=None, env_dict=None): """Выполняет внешнюю программу @@ -514,7 +514,7 @@ def _toUNICODE(val): if type(val) == str: return val else: - return str(val).decode('UTF-8') + return str(val) SYSFS_NET_PATH = "/sys/class/net" diff --git a/pym/cl_xml.py b/pym/cl_xml.py index 38a5fcd..770e586 100644 --- a/pym/cl_xml.py +++ b/pym/cl_xml.py @@ -814,7 +814,7 @@ class xmlDoc(): def getNameArea(self, xmlArea): """Выдает имя области""" xmlNameAreas = xpath.Evaluate('child::caption/name', xmlArea) - if xmlNameAreas and firstChild(xmlNameAreas[0]): + if xmlNameAreas and firstChild(xmlNameAreas[0]) is not None: return firstChild(xmlNameAreas[0]).text else: return False From 19be01624bf55a44f074483ec284d4ea8284cce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Wed, 1 Sep 2021 17:59:39 +0300 Subject: [PATCH 09/24] added more encoding fixes, switched ldap to unicode mode --- pym/cl_ldap.py | 33 +++++++++++++++++---------------- pym/cl_profile.py | 14 ++++++-------- pym/cl_utils2.py | 2 +- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 81d2779..f444070 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -207,7 +207,7 @@ class addLdif(LDIFParser): self.ldapCon = ldapCon def handle(self, dn, entry): - self.ldapCon.add_s(dn, entry.items()) + self.ldapCon.add_s(dn, list(entry.items())) class ldapFunction(cl_utils2.ldapFun): '''Объект для работы с LDAP сервером''' @@ -2958,7 +2958,7 @@ service")) homeDir = False if 'homeDirectory' in resLdap[0][0][1]: #Домашняя директория пользователя - homeDir = resLdap[0][0][1]['homeDirectory'][0] + homeDir = resLdap[0][0][1]['homeDirectory'][0].decode("UTF-8") if backup and os.path.exists(homeDir) and\ os.path.isdir(homeDir) and os.listdir(homeDir): # Делаем сохранение домашней директории @@ -2973,7 +2973,7 @@ service")) if not self.delUserInGroup(userName): return False if 'gidNumber' in resLdap[0][0][1]: - gid = resLdap[0][0][1]['gidNumber'][0] + gid = resLdap[0][0][1]['gidNumber'][0].decode("UTF-8") else: resPasswd = self.searchPasswdUser(userName) if resPasswd: @@ -3573,8 +3573,8 @@ service")) """Изменим последнюю дату измениня пароля на текущую""" # число дней от 1970 года date = int(time.time()/86400) - modAttrs = [(ldap.MOD_REPLACE, 'shadowLastChange', str(date))] - userDN = self.addDN('uid='+userName,self.relUsersDN) + modAttrs = [(ldap.MOD_REPLACE, 'shadowLastChange', str(date).encode("UTF-8"))] + userDN = self.addDN('uid=' + userName,self.relUsersDN) if not self.modAttrsDN(userDN, modAttrs): self.printERROR(_("Can not modify shadowLastChange attribute")) return False @@ -15427,7 +15427,7 @@ with another option.")) def modGroupAttr(self, attr, value, service): """Модифицирует аттрибуты группы для вывода на печать""" - retValue = value + retValue = value.decode("UTF-8") if isinstance(value, bytes) else value # Заменяем mail на имя пользователя if service == "mail" and attr == "rfc822member": servObj = servMail() @@ -15444,7 +15444,7 @@ with another option.")) retValue = _("local group") if value == "5": retValue = _("builtin group") - return retValue + return retValue.decode("UTF-8") if isinstance(retValue, bytes) else retValue def modUserAttr(self, attr, value, service): """Модифицирует аттрибуты пользователя для вывода на печать""" @@ -15849,7 +15849,7 @@ is not valid ") %accessPorts) resUnix = self.servUnixObj.searchUnixUser(userName) # Берем комментарий для пользователя из Unix if resUnix and 'cn' in resUnix[0][0][1]: - fullNameUser = resUnix[0][0][1]['cn'][0] + fullNameUser = resUnix[0][0][1]['cn'][0].decode("UTF-8") self.clVars.Set("ur_fio",fullNameUser) ldifFile = self.ldifFileUser userLdif = self.createLdif(ldifFile) @@ -15888,7 +15888,7 @@ is not valid ") %accessPorts) flagEmptyGroup = True addUsers = users else: - memberUsers = [x.rpartition("=")[2] for x in searchGroup[0][0][1]["member"]] + memberUsers = [x.decode("UTF-8").rpartition("=")[2] for x in searchGroup[0][0][1]["member"]] addUsers = [x for x in users if x not in memberUsers] for userName in addUsers: if flagEmptyGroup: @@ -16483,7 +16483,7 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): def getDataInAllHost(self): """Получить информацию о статических хостах""" if self.getError(): - return False + return [] allXmlNames = self._getAllXMLStaticHosts() allXmlAreas = [x.getparent().getparent() for x in allXmlNames] # Информация @@ -17602,9 +17602,9 @@ incompatible with option "--ip" (PTR-record)')) self.printERROR(_("Record %s not exists in LDAP")%domainName) return False if foundDomain: - foundIP = foundDomain[0][0][1]['aRecord'][0] + foundIP = foundDomain[0][0][1]['aRecord'][0].decode("UTF-8") elif foundDomainCName: - foundCName = foundDomainCName[0][0][1]['cNAMERecord'][0] + foundCName = foundDomainCName[0][0][1]['cNAMERecord'][0].decode("UTF-8") typeRec = "cname" # Если MX запись if flagDeleteMX: @@ -17638,7 +17638,7 @@ incompatible with option "--ip" (PTR-record)')) if not foundDomain: self.printERROR(_("PTR-record %s not exists in LDAP")%domainName) return False - foundDomainName = foundDomain[0][0][1]['pTRRecord'][0] + foundDomainName = foundDomain[0][0][1]['pTRRecord'][0].decode("UTF-8") # Удаляем PTR запись ret = self.deleteDNSRecord(domainNamePTR) if not ret: @@ -18047,10 +18047,10 @@ this DNS server')%nameServer) return False foundReverseDomain =self.searchDomainNameInLDAP(domainNamePTR) if foundReverseDomain: - zoneName = foundReverseDomain[0][0][1]['zoneName'][0] + zoneName = foundReverseDomain[0][0][1]['zoneName'][0].decode("UTF-8") relativeDomainName = \ - foundReverseDomain[0][0][1]['relativeDomainName'][0] - pTRRecord = foundReverseDomain[0][0][1]['pTRRecord'][0] + foundReverseDomain[0][0][1]['relativeDomainName'][0].decode("UTF-8") + pTRRecord = foundReverseDomain[0][0][1]['pTRRecord'][0].decode("UTF-8") # Удаляет лишние точки в названии delDot = lambda y: ".".join(x for x in y.split(".") if x) reverseHost = delDot(pTRRecord) @@ -18314,6 +18314,7 @@ with option "--mxmod"') if not zoneData: self.printERROR(_("Can not found SOA-record in zone %s")%zoneName) return False + #these return lists soaRecord = zoneData[0][0][1]['sOARecord'][0] nSRecords = zoneData[0][0][1]['nSRecord'] soaData = [delDot(x) for x in soaRecord.split(" ")] diff --git a/pym/cl_profile.py b/pym/cl_profile.py index 802d436..c86f2f0 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -328,14 +328,14 @@ class fileHeader(_terms): if type(comment) == tuple and len(comment) == 2: _titleList = (_("Modified"), _("File of a profile")) reCalcHeader =\ - re.compile(u"\s*%s\s+%s.+Calculate.+\s+%s.+\s+%s\s?"%(\ + re.compile("\s*%s\s+%s.+Calculate.+\s+%s.+\s+%s\s?" % (\ comment[0], - _titleList[0].decode("UTF-8"), - _titleList[1].decode("UTF-8"), + _titleList[0], + _titleList[1], comment[1], ), re.M|re.I|re.U) - textUnicode = text.decode("UTF-8") + textUnicode = text reS = reCalcHeader.search(textUnicode) if reS: textBody = textUnicode[:reS.start()]+textUnicode[reS.end():] @@ -4110,11 +4110,9 @@ class profile(_file, _terms, xmlShare, processingTemplates): def fileIsUtf(self, fileName): """Проверяет файл на кодировку UTF-8""" if os.path.exists(fileName): - FD = open(self.absFileName(fileName)) - newProfile = FD.read() - FD.close() try: - newProfile.decode("UTF-8") + with open(fileName, encoding="utf-8", errors="strict") as FD: + newProfile = FD.read() except: return False return True diff --git a/pym/cl_utils2.py b/pym/cl_utils2.py index 5bca1c7..4120f69 100644 --- a/pym/cl_utils2.py +++ b/pym/cl_utils2.py @@ -38,7 +38,7 @@ class ldapFun(cl_profile._error): def __ldapConnect(self, dnUser, password, host): """Соединение с LDAP сервером""" - conLdap = ldap.initialize('ldap://%s'%host) + conLdap = ldap.initialize('ldap://%s'%host, bytes_mode=False) conLdap.simple_bind_s(dnUser, password) return conLdap From ad6bddbae4bc0275714762fa1fc3718616fb78c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Thu, 2 Sep 2021 12:39:51 +0300 Subject: [PATCH 10/24] added decoding to most values returned by LDAP --- pym/cl_base.py | 7 +- pym/cl_ldap.py | 241 +++++++++++++++++++++++++------------------- pym/cl_profile.py | 10 +- pym/cl_utils.py | 2 +- scripts/cl-groupdel | 2 +- setup.py | 1 - 6 files changed, 148 insertions(+), 115 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index 7c1b6eb..e9de8d0 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -796,7 +796,12 @@ class DataVars(): return ret def Get(self, nameVar): - return self.__Get(nameVar) + tmp = self.__Get(nameVar) + #DEBUG + isBytes = isinstance(tmp, bytes) + if isBytes: + print(f"DEBUG: var {nameVar} returned bytes value: {tmp}") + return tmp.decode("UTF-8") if isBytes else tmp def __Set(self, nameVar, value, force=False): diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index f444070..8b7a74e 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -598,7 +598,7 @@ in a sambaDomainName', # id пользователя strUid = "" if searchUnixUser: - strUid = searchUnixUser[0][0][1]['uidNumber'][0] + strUid = searchUnixUser[0][0][1]['uidNumber'][0].decode("UTF-8") else: resPasswd = servUnixObj.searchPasswdUser(userName) if resPasswd: @@ -641,7 +641,7 @@ in a sambaDomainName', # id пользователя strUid = "" if searchUnixUser: - strUid = searchUnixUser[0][0][1]['uidNumber'][0] + strUid = searchUnixUser[0][0][1]['uidNumber'][0].decode("UTF-8") if strUid: delBackDir =\ os.path.join(self.clVars.Get("sr_deleted_path"), @@ -1090,7 +1090,7 @@ in a sambaDomainName', pwd = re.sub("(\W)", r"\\\1", password) pwdHash = self.execProg("slappasswd -s %s -h %s" %(pwd,cryptStr)) if pwdHash and len(pwdHash)>lenCryptStr and\ - pwdHash[:lenCryptStr] == cryptStr: + pwdHash[:lenCryptStr] == cryptStr.encode("UTF-8"): return pwdHash self.printERROR(_("ERROR") + " getHashPasswd: " +\ _("create crypto password")) @@ -1193,7 +1193,7 @@ in a sambaDomainName', for linkRm in scanObjs[0].links: # Удаляем ссылки os.unlink(linkRm[1]) - scanObjs[0].dirs.sort(lambda x, y: cmp(len(y), len(x))) + scanObjs[0].dirs.sort(key=len) for dirRm in scanObjs[0].dirs: # Удаляем директории os.rmdir(dirRm) @@ -1686,7 +1686,8 @@ This command is not allowed.")) return False for dn, f in dnList: delListDN.append(dn) - delListDN.sort(lambda x, y: cmp(len(y), len(x))) + delListDN.sort(key=len) + for dn in delListDN: try: self.conLdap.delete_s(dn) @@ -1704,9 +1705,13 @@ This command is not allowed.")) Возвращаемые параметры: строка которую выведет внешняя программа или False в случае ошибки """ - env_path = {"PATH":cl_utils.getpathenv()} + env_path = {"PATH" : cl_utils.getpathenv()} env = {} - env.update(os.environ.items() + env_path.items() + envProg.items()) + env.update(dict(os.environ)) + env.update(env_path) + env.update(envProg) + + inStr = inStr.encode("UTF-8") if isinstance(inStr, str) else inStr retCode,programOut = cl_utils.runOsCommand(cmdStrProg,inStr,retFull,env) if not retCode: return programOut @@ -2226,7 +2231,7 @@ class servUnix(shareLdap): flagError = True continue userGroupNames[res[0][0][1]['cn'][0]]=\ - res[0][0][1]['gidNumber'][0] + res[0][0][1]['gidNumber'][0].decode("UTF-8") continue gidNumber = gid res = self.searchUnixGid(gidNumber) @@ -2234,7 +2239,8 @@ class servUnix(shareLdap): gidErrors.append(gidNumber) flagError = True continue - userGroupNames[res[0][0][1]['cn'][0]] = res[0][0][1]['gidNumber'][0] + userGroupNames[res[0][0][1]['cn'][0]] =\ + res[0][0][1]['gidNumber'][0].decode("UTF-8") if flagError: errorMessage = "" if groupErrors: @@ -2309,6 +2315,7 @@ class servUnix(shareLdap): findUsers = [] if 'memberUid' in res[0][0][1]: usersInGroup = res[0][0][1]['memberUid'] + #TODO maybe we'll need to decode each username for userName in usersNames: if userName in usersInGroup: findUsers.append(userName) @@ -2420,7 +2427,7 @@ class servUnix(shareLdap): return False resSearch = self.servSambaObj.searchSambaGroupName(groupName) if resSearch: - groupId = resSearch[0][0][1]['gidNumber'][0] + groupId = resSearch[0][0][1]['gidNumber'][0].decode("UTF-8") else: gr = self.staticGroups["Domain Computers"] groupId = gr.gid @@ -2609,7 +2616,7 @@ class servUnix(shareLdap): if resGroup: userGid = resGroup.split(":")[2] if resLdap: - userGid = resLdap[0][0][1]['gidNumber'][0] + userGid = resLdap[0][0][1]['gidNumber'][0].decode("UTF-8") else: flagAddGroup = self.addGroupUnixServer(userName,{},False) flagAdd['group'] = flagAddGroup @@ -2707,7 +2714,7 @@ Unix service")) %str(userName)) return False if 'registeredAddress' in searchUser[0][0][1]: - return searchUser[0][0][1]['registeredAddress'][0] + return searchUser[0][0][1]['registeredAddress'][0].decode("UTF-8") else: return "" @@ -2748,7 +2755,7 @@ in Unix service")) %str(userName)) return False if 'mail' in searchUser[0][0][1]: - return searchUser[0][0][1]['mail'][0] + return searchUser[0][0][1]['mail'][0].decode("UTF-8") else: return "" @@ -2989,7 +2996,7 @@ service")) # В случае отсутствия других пользователей удаляем # основную группу в Samba сервисе if 'memberUid' not in resGroupSamba[0][0][1]: - groupName = resGroupSamba[0][0][1]['cn'][0] + groupName = resGroupSamba[0][0][1]['cn'][0].decode("UTF-8") # Находим группы у которых есть аттрибут type groupsSambaList = [x for x in self.staticGroups.items() if x[1].type] groupsSamba = {} @@ -3006,7 +3013,7 @@ service")) # В случае отсутствия других пользователей # удаляем основную группу в Unix сервисе if 'memberUid' not in resGroup[0][0][1]: - groupName = resGroup[0][0][1]['cn'][0] + groupName = resGroup[0][0][1]['cn'][0].decode("UTF-8") if not self.delGroupUnixServer(groupName, {}, False): return False # Удаляем пользователя из ветки Worked в случае репликации @@ -3038,7 +3045,7 @@ service")) _("Group %s is not found in Unix service")%groupName) return False if checkPrimaryGroup: - groupId = res[0][0][1]['gidNumber'][0] + groupId = res[0][0][1]['gidNumber'][0].decode("UTF-8") if self.searchUnixUserPrimGroup(groupId): self.printWARNING(_("cannot remove user's primary group") + ".") return True @@ -3141,15 +3148,15 @@ service")) if resGroup: userGid = resGroup.split(":")[2] if resLdap: - userGid = resLdap[0][0][1]['gidNumber'][0] + userGid = resLdap[0][0][1]['gidNumber'][0].decode("UTF-8") modAttrs += [(ldap.MOD_REPLACE, 'gidNumber', userGid)] visible = False # пользователя видно if 'V' in options: - visible = '1' + visible = b'1' # пользователя не видно if 'I' in options: - visible = '0' + visible = b'0' if visible: modAttrs += [(ldap.MOD_REPLACE, 'shadowFlag', visible)] # Изменяем домашнюю директорию @@ -3158,10 +3165,10 @@ service")) modAttrs += [(ldap.MOD_REPLACE, 'homeDirectory', homeDir)] # Включаем пользователя if 'U' in options: - modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "-1")] + modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', b"-1")] # Выключаем пользователя if 'L' in options: - modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "1")] + modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', b"1")] # Изменяем комментарий к пользователю if 'c' in options: comment = options['c'] @@ -3194,7 +3201,7 @@ service")) return False # Переносим домашнюю директорию пользователя if 'd' in options and 'm' in options: - homeDirOld = res[0][0][1]['homeDirectory'][0] + homeDirOld = res[0][0][1]['homeDirectory'][0].decode("UTF-8") homeDirNew = homeDir textLine = self.execProg("mv %s %s" %(homeDirOld, homeDirNew)) if textLine == False: @@ -3436,6 +3443,7 @@ service")) return False memberUsers = res[0][0][1]["memberUid"] flagError =False + #TODO decode each member? for user in users: if not user in memberUsers: flagError = True @@ -3628,7 +3636,7 @@ class servMail(shareLdap): if not searchEmailGroup: flagError = True break - userGroupNames.append(searchEmailGroup[0][0][1]['cn'][0]) + userGroupNames.append(searchEmailGroup[0][0][1]['cn'][0].decode("UTF-8")) else: searchNameGroup = self.searchMailGroupToName(userGroup) if not searchNameGroup: @@ -3722,7 +3730,7 @@ for user %s in 'Replication/Mail' branch") %str(userName)) _("Mail user or email %s are not found in Mail service")%\ str(nameOrMail)) return False - userMail = resSearchUser[0][0][1]['mail'][0] + userMail = resSearchUser[0][0][1]['mail'][0].decode("UTF-8") resSearchGroup = self.searchLdapDN(userMail, self.relGroupsDN, "rfc822member") return (userMail, resSearchGroup) @@ -3757,7 +3765,7 @@ for user %s in 'Replication/Mail' branch") %str(userName)) self.printERROR(\ _("Member list of group %s is empty")%str(groupName)) return False - memberMailUsers = res[0][0][1]["rfc822member"] + memberMailUsers = res[0][0][1]["rfc822member"].decode("UTF-8") flagError = False memberUsers = {} for mailUser in memberMailUsers: @@ -3864,9 +3872,10 @@ are incompatible, use one of the options")) attrDeleteFirst.append((ldap.MOD_DELETE, 'filtersender', None)) if 'e' in options: altMails = options['e'].split(",") - email = searchGroup[0][0][1]["mail"][0] + email = searchGroup[0][0][1]["mail"][0].decode("UTF-8") altEmails = searchGroup[0][0][1]["mailAlternateAddress"] # Удаляем альтернативные адреса, кроме первого + #TODO decode each email for altEmail in altEmails: if email != altEmail: attrDeleteFirst.append( @@ -3900,6 +3909,7 @@ option '-e'")) if servReplObj: if not altMails and filterHosts: altMails = searchGroup[0][0][1]["mailAlternateAddress"] + #TODO decode each if altMails: for mail in altMails: if "@" in altMail: @@ -3911,6 +3921,7 @@ option '-e'")) if foundReplAlias: flagError = False foundReplUsers = foundReplAlias[0][0][1]['cn'] + #TODO decode each for foundReplUser in foundReplUsers: if foundReplUser!=groupName: flagError = True @@ -3969,6 +3980,7 @@ mail user or group: %s")%foundReplUser) return False # изменяем адрес и альтернативный адрес altEmails = searchGroup[0][0][1]["mailAlternateAddress"] + #todo decode each for altEmail in altEmails: splAltEmail = altEmail.split("@") grName = splAltEmail[0] @@ -3984,7 +3996,7 @@ mail user or group: %s")%foundReplUser) (ldap.MOD_ADD, 'mailAlternateAddress', newAltEmail)) break - email = searchGroup[0][0][1]["mail"][0] + email = searchGroup[0][0][1]["mail"][0].decode("UTF-8") splEmail = email.split("@") emailDomen = "" if len(splEmail)==2: @@ -4125,6 +4137,7 @@ in 'Replication/Mail' branch") %groupName) if 'e' in options: altEmails = res[0][0][1]["mailAlternateAddress"] altMails = options['e'].split(",") + #TODO decode each for altMail in altMails: if "@" in altMail: if len(altMail.split("@")) != 2: @@ -4168,8 +4181,9 @@ in Unix service") %str(primaryMail)) if foundReplAlias: flagError = False foundReplUsers = foundReplAlias[0][0][1]['cn'] + #TODO decode each for foundReplUser in foundReplUsers: - if foundReplUser!=userName: + if foundReplUser != userName: flagError = True break if flagError: @@ -4236,7 +4250,7 @@ option '-e'")) if servReplObj: foundReplAlias = servReplObj.searchMailAddress(mail) if foundReplAlias: - foundReplUser = foundReplAlias[0][0][1]['cn'][0] + foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ 'Replication/Mail' branch")%mail) self.printERROR(_("The address belongs to \ @@ -4267,7 +4281,7 @@ mail user or group: %s")%foundReplUser) if servReplObj: foundReplAlias = servReplObj.searchMailAddress(mail) if foundReplAlias: - foundReplUser = foundReplAlias[0][0][1]['cn'][0] + foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ 'Replication/Mail' branch")%mail) self.printERROR(_("The address belongs to \ @@ -4363,6 +4377,7 @@ for user %s in 'Replication/Mail' branch") %str(mail)) findUsers = [] if 'rfc822member' in res[0][0][1]: usersInGroup = res[0][0][1]['rfc822member'] + #TODO decode each for userName in usersNames: userMail = "%s@%s" %(userName, self.clVars.Get("sr_mail_host")) @@ -4526,7 +4541,7 @@ for user %s in 'Replication/Mail' branch") %str(mail)) if servReplObj: foundReplAlias = servReplObj.searchMailAddress(mail) if foundReplAlias: - foundReplUser = foundReplAlias[0][0][1]['cn'][0] + foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ 'Replication/Mail' branch")%mail) self.printERROR(_("The address belongs to \ @@ -4552,7 +4567,7 @@ mail user or group: %s")%foundReplUser) if servReplObj: foundReplAlias = servReplObj.searchMailAddress(mail) if foundReplAlias: - foundReplUser = foundReplAlias[0][0][1]['cn'][0] + foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ 'Replication/Mail' branch")%mail) self.printERROR(_("The address belongs to \ @@ -4619,7 +4634,7 @@ mail user or group: %s")%foundReplUser) fullNameUser = options['c'] else: if resUnix and 'cn' in resUnix[0][0][1]: - fullNameUser = resUnix[0][0][1]['cn'][0] + fullNameUser = resUnix[0][0][1]['cn'][0].decode("UTF-8") self.clVars.Set("ur_fio",fullNameUser) if not userPwd: userPwdHash = "crypt{xxx}" @@ -5096,8 +5111,8 @@ class servJabber(shareLdap): str(userName)) return False modAttrs = [] - descr = groupSearch[0][0][1]["cn"][0] - uid = userSearch[0][0][1]["uid"][0] + descr = groupSearch[0][0][1]["cn"][0].decode("UTF-8") + uid = userSearch[0][0][1]["uid"][0].decode("UTF-8") if 'departmentNumber' in userSearch[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'departmentNumber', descr)) else: @@ -5184,7 +5199,7 @@ in Jabber service")) userSearch = self.searchUserToNameOrId(userName) if userSearch and 'departmentNumber' in userSearch[0][0][1]: if not userSearch[0][0][1]['departmentNumber'][0] == \ - groupSearch[0][0][1]['cn'][0]: + groupSearch[0][0][1]['cn'][0].decode("UTF-8"): self.printERROR(_("User %s is not found in group")%\ str(userName) + " " + str(groupName)) res = False @@ -5198,9 +5213,9 @@ in Jabber service")) return False for userName in users: userSearch = self.searchUserToNameOrId(userName) - uid = userSearch[0][0][1]['uid'][0] + uid = userSearch[0][0][1]['uid'][0].decode("UTF-8") modAttrs = [(ldap.MOD_DELETE, 'departmentNumber', None)] - userDN = self.addDN("uid="+uid, self.relUsersDN) + userDN = self.addDN("uid=" + uid, self.relUsersDN) res = self.modAttrsDN(userDN, modAttrs) if not res: break @@ -5271,7 +5286,7 @@ in Jabber service")) modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: - uid = resSearch[0][0][1]['uid'][0] + uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False @@ -5315,7 +5330,7 @@ in Jabber service")) return False searchUser = self.searchUserToId(jabberId) if searchUser: - foundUserName = searchUser[0][0][1]['uid'][0] + foundUserName = searchUser[0][0][1]['uid'][0].decode("UTF-8") if foundUserName != userName: self.printERROR(_("User %s") %str(foundUserName) + " " +\ _("has a JID %s") %jabberId) @@ -5369,7 +5384,7 @@ in Unix service") %str(jabberId)) modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: - uid = res[0][0][1]['uid'][0] + uid = res[0][0][1]['uid'][0].decode("UTF-8") DN = self.addDN("uid="+uid, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False @@ -5439,7 +5454,7 @@ in Unix service") %str(jabberId)) # Изменяем имя группы if 'n' in options: newGroupName = options['n'] - oldGroupName = searchGroup[0][0][1]["cn"][0] + oldGroupName = searchGroup[0][0][1]["cn"][0].decode("UTF-8") if self.renameGroup(oldGroupName, newGroupName): self.printSUCCESS(_("Group renamed to %s")\ %newGroupName) @@ -5460,7 +5475,7 @@ in Unix service") %str(jabberId)) self.printERROR (_("ERROR") + ": " +\ _("User %s is not found in Jabber service") % str(userName)) return False - uid = resSearch[0][0][1]['uid'][0] + uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") # Удаляем jabberID из Unix сервиса # удаляем jabberID из Unix if self.isServiceSetup("unix",False) and\ @@ -5632,7 +5647,7 @@ in Unix service") %str(jabberId)) resUnix = self.servUnixObj.searchUnixUser(userName) # Берем комментарий для пользователя из Unix if resUnix and 'cn' in resUnix[0][0][1]: - fullNameUser = resUnix[0][0][1]['cn'][0] + fullNameUser = resUnix[0][0][1]['cn'][0].decode("UTF-8") self.clVars.Set("ur_fio",fullNameUser) ldifFile = self.ldifFileUser userLdif = self.createLdif(ldifFile) @@ -5922,11 +5937,12 @@ of version > 2.1.10, then you can delete this file.") + "\n" """Удаление пользователей из списка из группы Samba""" def getPrimaryUsers(): - gidNumber = res[0][0][1]["gidNumber"][0] + gidNumber = res[0][0][1]["gidNumber"][0].decode("UTF-8") searchUsers = self.servUnixObj.searchUnixUserPrimGroup(gidNumber) foundUserNames = [] if searchUsers: for data in searchUsers: + #TODO check encoding foundUserNames.append(data[0][1]["uid"][0]) if foundUserNames: primaryUsers = list(set(foundUserNames)&set(users)) @@ -5947,6 +5963,7 @@ of version > 2.1.10, then you can delete this file.") + "\n" _("Member list of group %s is empty")%str(groupName)) return False memberUsers = res[0][0][1]["memberUid"] + #TODO decode each flagError =False for user in users: if not user in memberUsers: @@ -5993,7 +6010,7 @@ of version > 2.1.10, then you can delete this file.") + "\n" _("Group %s is not found in Samba service")%groupName) return False if checkPrimaryGroup: - groupId = res[0][0][1]['gidNumber'][0] + groupId = res[0][0][1]['gidNumber'][0].decode("UTF-8") if self.servUnixObj.searchUnixUserPrimGroup(groupId): self.printWARNING(_("cannot remove user's primary group") + ".") return True @@ -6125,7 +6142,7 @@ of version > 2.1.10, then you can delete this file.") + "\n" uidUnixUser = False resSearch = self.servUnixObj.searchUnixUser(userName) if resSearch: - uidUnixUser = resSearch[0][0][1]['uidNumber'][0] + uidUnixUser = resSearch[0][0][1]['uidNumber'][0].decode("UTF-8") ## создание пользователя Unix опция f #if not resSearch and not options.has_key('f'): #self.printERROR( @@ -6426,6 +6443,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) findUsers = [] if 'memberUid' in res[0][0][1]: usersInGroup = res[0][0][1]['memberUid'] + #TODO decode each for userName in usersNames: if userName in usersInGroup: findUsers.append(userName) @@ -6513,7 +6531,7 @@ Samba and Unix services") %", ".join(exclGroup) flagError = True continue userGroupNames[res[0][0][1]['cn'][0]]=\ - res[0][0][1]['gidNumber'][0] + res[0][0][1]['gidNumber'][0].decode("UTF-8") continue gidNumber = gid res = self.searchSambaGid(gidNumber) @@ -6521,7 +6539,8 @@ Samba and Unix services") %", ".join(exclGroup) gidErrors.append(gidNumber) flagError = True continue - userGroupNames[res[0][0][1]['cn'][0]] = res[0][0][1]['gidNumber'][0] + userGroupNames[res[0][0][1]['cn'][0]] =\ + res[0][0][1]['gidNumber'][0].decode("UTF-8") if flagError: errorMessage = "" if groupErrors: @@ -6726,13 +6745,14 @@ Samba and Unix services") %", ".join(exclGroup) machineGroupName = self.clVars.Get('sr_samba_machine_group') resSearch = self.searchSambaGroupName(machineGroupName) if resSearch: - machineGid = resSearch[0][0][1]['gidNumber'][0] + machineGid = resSearch[0][0][1]['gidNumber'][0].decode("UTF-8") else: mGr = self.staticGroups["Domain Computers"] machineGid = mGr.gid searchAllMachines = self.searchAllSambaMachines() if searchAllMachines: for data in searchAllMachines: + #TODO check encoding machineName = data[0][1]['uid'][0] machineDN = self.addDN("uid=" + machineName, self.relComputersDN) @@ -6878,7 +6898,7 @@ Samba and Unix services") %", ".join(exclGroup) resSearch = self.searchLdapDN("*", self.relDN, "sambaDomainName", ["sambaSID"]) if resSearch: - return resSearch[0][0][1]['sambaSID'][0] + return resSearch[0][0][1]['sambaSID'][0].decode("UTF-8") self.printERROR(_("Not found sambaSID in LDAP")) return False @@ -11779,7 +11799,7 @@ class servFtp(shareLdap): modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: - uid = resSearch[0][0][1]['uid'][0] + uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") DN = self.addDN("uid="+uid, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False @@ -11816,7 +11836,7 @@ class servFtp(shareLdap): modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: - uid = resSearch[0][0][1]['uid'][0] + uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False @@ -11838,7 +11858,7 @@ class servFtp(shareLdap): self.printERROR(_("User not exists in FTP service")) return False # FTP директория пользователя - ftpUserDir = resFtp[0][0][1]['homeDirectory'][0] + ftpUserDir = resFtp[0][0][1]['homeDirectory'][0].decode("UTF-8") ftpPath = self.clVars.Get("sr_ftp_path") if ftpUserDir == ftpPath: ftpUserDir = os.path.join(ftpPath,"pub/users",userName) @@ -11920,7 +11940,7 @@ class servFtp(shareLdap): fullNameUser = options['c'] else: if resUnix and 'cn' in resUnix[0][0][1]: - fullNameUser = resUnix[0][0][1]['cn'][0] + fullNameUser = resUnix[0][0][1]['cn'][0].decode("UTF-8") self.clVars.Set("ur_fio",fullNameUser) if not userPwd: userPwdHash = "crypt{xxx}" @@ -12664,7 +12684,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) rez = self.searchMailAlias(oldName) if not rez: return True - email = rez[0][0][1]["rfc822member"][0] + email = rez[0][0][1]["rfc822member"][0].decode("UTF-8") splEmail = email.split("@") attrAppend = [] relMailDN = self.getRelMailDN() @@ -12733,9 +12753,10 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) attrAppend.append((ldap.MOD_ADD, 'filtersender', host)) if 'filtersender' in rez[0][0][1]: attrDelete.append((ldap.MOD_DELETE, 'filtersender', None)) - email = rez[0][0][1]["mail"][0] + email = rez[0][0][1]["mail"][0].decode("UTF-8") altEmails = rez[0][0][1]["mailAlternateAddress"] # Удаляем альтернативные адреса, кроме первого + #TODO decode each for altEmail in altEmails: if email != altEmail: attrDelete.append( @@ -12833,12 +12854,12 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) print(_("Variable Error: not set a variable ld_repl_host")) return False if rez: - host = rez[0][0][1]['host'][0] + host = rez[0][0][1]['host'][0].decode("UTF-8") if host != replHost: # Изменяемые аттрибуты modAttrs = [(ldap.MOD_REPLACE, 'host', replHost)] relWorkedDN = self.getRelWorkedDN() - DN = self.addDN("uid="+userName, relWorkedDN) + DN = self.addDN("uid=" + userName, relWorkedDN) if not self.modAttrsDN(DN, modAttrs): return False else: @@ -13591,7 +13612,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) return False # Проверка правильности предыдущего пароля if 'sambaNTPassword' in resSamba[0][0][1]: - if userOldNTHash !=resSamba[0][0][1]['sambaNTPassword'][0]: + if userOldNTHash != resSamba[0][0][1]['sambaNTPassword'][0].decode("UTF-8"): self.printERROR( _("Invalid previous password for the user %s")\ %str(userName)) @@ -14538,7 +14559,7 @@ for %s DNS zone")%zoneName) self.printERROR(_("Can not found SOA-record in zone %s")\ %zoneName) return False - soaRecord = zoneData[0][0][1]['sOARecord'][0] + soaRecord = zoneData[0][0][1]['sOARecord'][0].decode("UTF-8") # Все авторитативные сервера зоны nSRecords = zoneData[0][0][1]['nSRecord'] mXRecords = [] @@ -14977,8 +14998,9 @@ with another option.")) if service in ("unix", "samba"): memberUid = [] if 'memberUid' in searchRes[0][0][1]: + #TODO check encoding memberUid = searchRes[0][0][1]['memberUid'] - groupId = searchRes[0][0][1]['gidNumber'][0] + groupId = searchRes[0][0][1]['gidNumber'][0].decode("UTF-8") primaryUids = self.getUnixUidPrimGroup(groupId) memberUid = primaryUids + memberUid uniqueUid = [] @@ -15054,7 +15076,7 @@ with another option.")) #i[0][1]['uidNumber'] = [uidNumber] #data.insert(0,(_("ID"),"uidNumber")) - gidNumber = searchResUnix[0][0][1]['gidNumber'][0] + gidNumber = searchResUnix[0][0][1]['gidNumber'][0].decode("UTF-8") #sambaGroup = servObj.searchSambaGid(gidNumber) #if sambaGroup: i[0][1]['gidNumber'] = [gidNumber] @@ -15433,7 +15455,7 @@ with another option.")) servObj = servMail() searchUser = servObj.searchUserToMail(value) if searchUser: - retValue = searchUser[0][0][1]['uid'][0] + retValue = searchUser[0][0][1]['uid'][0].decode("UTF-8") else: retValue = "Not found" # Заменяем тип группы названием типа @@ -15444,7 +15466,7 @@ with another option.")) retValue = _("local group") if value == "5": retValue = _("builtin group") - return retValue.decode("UTF-8") if isinstance(retValue, bytes) else retValue + return retValue def modUserAttr(self, attr, value, service): """Модифицирует аттрибуты пользователя для вывода на печать""" @@ -15932,10 +15954,10 @@ is not valid ") %accessPorts) %str(groupName)) return False # Если группа пуста - if [x for x in searchGroup[0][0][1]['member'] if not x.strip()]: + if [x.decode("UTF-8") for x in searchGroup[0][0][1]['member'] if not x.strip()]: self.printERROR( _("Member list of group %s is empty")%str(groupName)) - memberUsers = [x.rpartition("=")[2] for x + memberUsers = [x.decode("UTF-8").rpartition("=")[2] for x in searchGroup[0][0][1]["member"]] flagError = False for user in users: @@ -17306,8 +17328,8 @@ class servDns(shareLdap): if foundIPs: for ptrRecord in foundIPs: lastOctIPs = ptrRecord[0][1]['relativeDomainName'] - zoneName = ptrRecord[0][1]['zoneName'][0] - domainNames = ["%s.%s" % (x, zoneName) for x in lastOctIPs] + zoneName = ptrRecord[0][1]['zoneName'][0].decode("UTF-8") + domainNames = ["%s.%s" % (x.decode("UTF-8"), zoneName) for x in lastOctIPs] for name in domainNames: listOctRev = name.rpartition(".in-addr.arpa")[0].split(".") listOctRev.reverse() @@ -18315,7 +18337,7 @@ with option "--mxmod"') self.printERROR(_("Can not found SOA-record in zone %s")%zoneName) return False #these return lists - soaRecord = zoneData[0][0][1]['sOARecord'][0] + soaRecord = zoneData[0][0][1]['sOARecord'][0].decode("UTF-8") nSRecords = zoneData[0][0][1]['nSRecord'] soaData = [delDot(x) for x in soaRecord.split(" ")] if len(soaData)!=7: @@ -18352,7 +18374,9 @@ with option "--mxmod"') %zoneName) return False # Находим нужную запись - foundMxServers = [len(x.split(" ")) == 1 and delDot(x) or delDot(x.split(" ")[1]) + foundMxServers = [len(x.decode("UTF-8").split(" ")) == 1 + and delDot(x.decode("UTF-8")) + or delDot(x.decode("UTF-8").split(" ")[1]) for x in zoneData[0][0][1]['mXRecord']] oldMxHost = modMxServers[0] newMxHost = modMxServers[1] @@ -18692,12 +18716,12 @@ incompatible with CNAME-record (option "-t")')) self.printERROR(_("CNAME-record %s exists in LDAP")\ %newDomainName) self.printERROR("%s --> %s"%(newDomainName,\ - delDot(foundNewDomain[0][0][1]['cNAMERecord'][0]))) + delDot(foundNewDomain[0][0][1]['cNAMERecord'][0].decode("UTF-8")))) else: self.printERROR(_("A-record %s exists in LDAP")\ %newDomainName) self.printERROR("%s --> %s"\ - %(newDomainName, foundNewDomain[0][0][1]['aRecord'][0])) + %(newDomainName, foundNewDomain[0][0][1]['aRecord'][0].decode("UTF-8"))) self.printERROR("") return False # Проверка существования обратной записи @@ -18729,12 +18753,12 @@ incompatible with CNAME-record (option "-t")')) self.printERROR(_("CNAME-record %s exists in LDAP")\ %newDomainName) self.printERROR("%s --> %s"%(newDomainName,\ - delDot(foundNewDomain[0][0][1]['cNAMERecord'][0]))) + delDot(foundNewDomain[0][0][1]['cNAMERecord'][0].decode("UTF-8")))) else: self.printERROR(_("A-record %s exists in LDAP")\ %newDomainName) self.printERROR("%s --> %s"\ - %(newDomainName, foundNewDomain[0][0][1]['aRecord'][0])) + %(newDomainName, foundNewDomain[0][0][1]['aRecord'][0].decode("UTF-8"))) self.printERROR("") return False newIP = "" @@ -18769,7 +18793,7 @@ is incompatible with option "--ip"') if foundNewIp: self.printERROR(_("IP address %s exists in LDAP")%newIP) self.printERROR("%s --> %s"%(newIP,\ - delDot(foundNewIp[0][0][1]['pTRRecord'][0]))) + delDot(foundNewIp[0][0][1]['pTRRecord'][0].decode("UTF-8")))) self.printERROR("") return False # Проверка существования обратной записи @@ -18800,7 +18824,7 @@ is incompatible with option "--ip"') if foundNewIp: self.printERROR(_("IP address %s exists in LDAP")%newIP) self.printERROR("%s --> %s"%(newIP,\ - delDot(foundNewIp[0][0][1]['pTRRecord'][0]))) + delDot(foundNewIp[0][0][1]['pTRRecord'][0].decode("UTF-8")))) self.printERROR("") return False # Имена изменяемых зон @@ -18836,7 +18860,7 @@ is incompatible with option "--ip"') self.printERROR(_("Record %s not exists in LDAP")\ %domainName) return False - otherIP = delDot(foundMain[0][0][1]['aRecord'][0]) + otherIP = delDot(foundMain[0][0][1]['aRecord'][0].decode("UTF-8")) # Поиcк в обратной зоне в случае необходимости if modOther: dataIP = self.getDomainAndZoneFromIP(otherIP) @@ -18850,11 +18874,11 @@ is incompatible with option "--ip"') %otherDomain) return False # Проверка на соответствие имени хоста - if domainName!=delDot(foundOther[0][0][1]['pTRRecord'][0]): + if domainName!=delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")): self.printERROR(_("Found PTR-record %s in LDAP")\ %otherDomain) self.printERROR("%s --> %s"%(otherIP,\ - delDot(foundOther[0][0][1]['pTRRecord'][0]))) + delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")))) self.printERROR("") return False # Изменяем в двух зонах @@ -18944,18 +18968,18 @@ is incompatible with option "--ip"') return False # Поиcк в обратной зоне в случае необходимости if modOther: - otherDomain = delDot(foundMain[0][0][1]['pTRRecord'][0]) + otherDomain = delDot(foundMain[0][0][1]['pTRRecord'][0].decode("UTF-8")) foundOther = self.searchAllDomainNamesInLDAP(otherDomain) if not foundOther: self.printERROR(_("A-record %s not exists in LDAP")\ %otherDomain) return False # Проверка на соответствие ip хоста - if ip != foundOther[0][0][1]['aRecord'][0]: + if ip != foundOther[0][0][1]['aRecord'][0].decode("UTF-8"): self.printERROR(_("Found A-record %s in LDAP")\ %otherDomain) self.printERROR("%s --> %s"\ - %(otherDomain, foundOther[0][0][1]['aRecord'][0])) + %(otherDomain, foundOther[0][0][1]['aRecord'][0].decode("UTF-8"))) self.printERROR("") return False # Модифицируем PTR запись @@ -19026,7 +19050,7 @@ is incompatible with option "--ip"') namesZones.append(zoneName) # CNAME запись (изменяем имя домена) if newDomainName: - oldCname = delDot(foundMain[0][0][1]['cNAMERecord'][0]) + oldCname = delDot(foundMain[0][0][1]['cNAMERecord'][0].decode("UTF-8")) if not self.moveCNAMERecord(oldCname,domainName, newDomainName): return False @@ -19052,8 +19076,9 @@ is incompatible with option "--ip"') %domainName) return False # Находим нужную запись - foundMxServers = [len(x.split(" ")) == 1\ - and delDot(x) or delDot(x.split(" ")[1]) + foundMxServers = [len(x.decode("UTF-8").split(" ")) == 1\ + and delDot(x.decode("UTF-8")) + or delDot(x.decode("UTF-8").split(" ")[1]) for x in foundMain[0][0][1]['mXRecord']] oldMxHost = modMxServers[0] newMxHost = modMxServers[1] @@ -19127,7 +19152,7 @@ is incompatible with option "--ip"') self.printERROR(_("PTR-record %s not exists in LDAP")\ %domainNamePTR) return False - otherDomain = delDot(foundMain[0][0][1]['pTRRecord'][0]) + otherDomain = delDot(foundMain[0][0][1]['pTRRecord'][0].decode("UTF-8")) # Модификация domainName = otherDomain # Модификация @@ -19140,11 +19165,11 @@ is incompatible with option "--ip"') %otherDomain) return False # Проверка на соответствие ip хоста - if ip != foundOther[0][0][1]['aRecord'][0]: + if ip != foundOther[0][0][1]['aRecord'][0].decode("UTF-8"): self.printERROR(_("Found A-record %s in LDAP")\ %otherDomain) self.printERROR("%s --> %s"\ - %(otherDomain, foundOther[0][0][1]['aRecord'][0])) + %(otherDomain, foundOther[0][0][1]['aRecord'][0].decode("UTF-8"))) self.printERROR("") return False # Модифицируем PTR запись @@ -19226,7 +19251,7 @@ is incompatible with option "--ip"') return False # Поиcк в обратной зоне в случае необходимости if modOther: - otherIP = delDot(foundMain[0][0][1]['aRecord'][0]) + otherIP = delDot(foundMain[0][0][1]['aRecord'][0].decode("UTF-8")) dataIP = self.getDomainAndZoneFromIP(otherIP) if not dataIP: self.printERROR(_("IP address %s incorrectly")%otherIP) @@ -19238,11 +19263,11 @@ is incompatible with option "--ip"') %otherDomain) return False # Проверка на соответствие имени хоста - if domainName!=delDot(foundOther[0][0][1]['pTRRecord'][0]): + if domainName != delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")): self.printERROR(_("Found PTR-record %s in LDAP")\ %otherDomain) self.printERROR("%s --> %s"%(otherIP,\ - delDot(foundOther[0][0][1]['pTRRecord'][0]))) + delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")))) self.printERROR("") return False # Изменяем в двух зонах @@ -19325,8 +19350,9 @@ is incompatible with option "--ip"') %domainName) return False # Находим нужную запись - foundMxServers = [len(x.split(" ")) == 1\ - and delDot(x) or delDot(x.split(" ")[1]) + foundMxServers = [len(x.decode("UTF-8").split(" ")) == 1\ + and delDot(x.decode("UTF-8")) + or delDot(x.decode("UTF-8").split(" ")[1]) for x in foundMain[0][0][1]['mXRecord']] oldMxHost = modMxServers[0] newMxHost = modMxServers[1] @@ -19616,6 +19642,7 @@ with type DNS record PTR (option "-t")')) self.printERROR(_("CNAME-record %s exists in LDAP")\ %domainName) cnameHosts = findCName[0][0][1]['cNAMERecord'] + #TODO check encodings for cnameHost in cnameHosts: self.printERROR("%s --> %s"%(domainName,cnameHost)) self.printERROR("") @@ -19773,7 +19800,7 @@ with type DNS record PTR (option "-t")')) self.printERROR(_("Can not found SOA-record in DNS zone %s")\ %zoneName) return False - sOARecord = foundNames[0][0][1]['sOARecord'][0] + sOARecord = foundNames[0][0][1]['sOARecord'][0].decode("UTF-8") sOAList = sOARecord.split(" ") if len(sOAList)!=7: self.printERROR(_("Incorrect SOA-record in DNS zone %s")%zoneName) @@ -20388,12 +20415,12 @@ eth0, eth1, ... etc."%net) hostname = self.servDnsObj.clVars.Get("os_net_hostname") if hostname: zone = oldDomainNames[0] - fullServerDNSName = "%s.%s" % (hostname,zone) + fullServerDNSName = "%s.%s" % (hostname, zone) if not [x for x in moveRecords if fullServerDNSName == x[0]]: foundServ = self.servDnsObj.searchDomainNameInLDAP(\ fullServerDNSName) if foundServ: - serverIP = foundServ[0][0][1]['aRecord'][0] + serverIP = foundServ[0][0][1]['aRecord'][0].decode("UTF-8") moveRecords.append((fullServerDNSName,serverIP)) data = [oldDnsIPs, oldRanges, net] if not self.modifyDNSZoneName(oldDomainNames[0], domainNames[0], @@ -20716,7 +20743,7 @@ eth0, eth1, ... etc."%net) ip = "" if recData: if 'aRecord' in recData[0][0][1]: - ip = recData[0][0][1]['aRecord'][0] + ip = recData[0][0][1]['aRecord'][0].decode("UTF-8") # Удаляем A запись if not self.servDnsObj.delRecordDnsServer({"host":fullHostName}, False): @@ -20738,7 +20765,7 @@ eth0, eth1, ... etc."%net) hostList = recData[0][0][1]['pTRRecord'] # Удаляет лишние точки в названии delDot = lambda y: ".".join(x for x in y.split(".") if x) - hostList = [delDot(x) for x in hostList] + hostList = [delDot(x.decode("UTF-8")) for x in hostList] if not fullHostName in hostList: deleteIP.append(ip) deleteIP = list(set(deleteIP)) @@ -20768,6 +20795,7 @@ eth0, eth1, ... etc."%net) flagDelARecord = True if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] + #TODO decode each if ip in aRecords: flagCreateARecord = False flagDelARecord = False @@ -20849,7 +20877,7 @@ eth0, eth1, ... etc."%net) hostList = recData[0][0][1]['pTRRecord'] # Удаляет лишние точки в названии delDot = lambda y: ".".join(x for x in y.split(".") if x) - hostList = [delDot(x) for x in hostList] + hostList = [delDot(x.decode("UTF-8")) for x in hostList] if fullHostName in hostList: deleteIP = [x for x in deleteIP if x != ip] flagCreatePTRRecord = False @@ -21013,6 +21041,7 @@ incompatible, use one of the options")) if recData: if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] + #TODO decode each if ip in aRecords: retData[fullDomainName] = ip else: @@ -21107,7 +21136,7 @@ incompatible, use one of the options")) foundMain = self.servDnsObj.searchDomainNameInLDAP(hostname) if not foundMain: continue - otherIP = foundMain[0][0][1]['aRecord'][0] + otherIP = foundMain[0][0][1]['aRecord'][0].decode("UTF-8") # Поиcк в обратной зоне dataIP = self.servDnsObj.getDomainAndZoneFromIP(otherIP) otherHostName, otherDomain, otherZoneName = dataIP @@ -21129,11 +21158,11 @@ incompatible, use one of the options")) foundNewARec = self.servDnsObj.searchDomainNameInLDAP(newHostName) if foundNewARec: if 'aRecord' in foundNewARec[0][0][1]: - if foundNewARec[0][0][1]['aRecord'][0] != otherIP: + if foundNewARec[0][0][1]['aRecord'][0].decode("UTF-8") != otherIP: self.printERROR(_("Record %s exists in DNS service")\ %newHostName) self.printERROR("%s --> %s"%(newHostName,\ - foundNewARec[0][0][1]['aRecord'][0])) + foundNewARec[0][0][1]['aRecord'][0].decode("UTF-8"))) self.printERROR("") flagError = True break @@ -21399,6 +21428,7 @@ network %s") % net) if recData: if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] + #TODO check encoding if not ip in aRecords: flagError = True else: @@ -21430,7 +21460,7 @@ network %s") % net) hostList = recData[0][0][1]['pTRRecord'] # Удаляет лишние точки в названии delDot = lambda y: ".".join(x for x in y.split(".") if x) - hostList = [delDot(x) for x in hostList] + hostList = [delDot(x.decode("UTF-8")) for x in hostList] if hostname in hostList: deleteIP = [x for x in deleteIP if x != ip] flagCreatePTR = False @@ -21996,6 +22026,7 @@ network %s") % net) fullHostNameServer) if recData and 'aRecord' in recData[0][0][1]: flagFoundARecord = True + #TODO check encoding if ipServer in recData[0][0][1]['aRecord']: flagCreateDNSRecord = False else: @@ -22012,7 +22043,7 @@ network %s") % net) hostList = recData[0][0][1]['pTRRecord'] # Удаляет лишние точки в названии delDot = lambda y: ".".join(x for x in y.split(".") if x) - hostList = [delDot(x) for x in hostList] + hostList = [delDot(x.decode("UTF-8")) for x in hostList] if not fullHostNameServer in hostList: flagCreateDNSRecord = True flagDeletePTRRecord = True diff --git a/pym/cl_profile.py b/pym/cl_profile.py index c86f2f0..eb1241b 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -2248,11 +2248,11 @@ class utfBin: if 'uidNumber' in resSearch[0][0][1] and\ 'gidNumber' in resSearch[0][0][1] and\ 'homeDirectory' in resSearch[0][0][1]: - uid = resSearch[0][0][1]['uidNumber'][0] - gid = resSearch[0][0][1]['gidNumber'][0] + uid = resSearch[0][0][1]['uidNumber'][0].decode("UTF-8") + gid = resSearch[0][0][1]['gidNumber'][0].decode("UTF-8") # uid = searchUser[0][0][1]['uidNumber'][0] # gid = searchUser[0][0][1]['gidNumber'][0] - homeDir = resSearch[0][0][1]['homeDirectory'][0] + homeDir = resSearch[0][0][1]['homeDirectory'][0].decode("UTF-8") return uid, gid, homeDir return "" @@ -2468,7 +2468,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): for fileRm in scanObjs[0].files: # Удаляем файлы os.remove(fileRm) - scanObjs[0].dirs.sort(lambda x, y: cmp(len(y), len(x))) + scanObjs[0].dirs.sort(key=len) for dirRm in scanObjs[0].dirs: # Удаляем директории os.rmdir(dirRm) @@ -3258,7 +3258,6 @@ class profile(_file, _terms, xmlShare, processingTemplates): """ return True - #TODO rewrite with os.walk def scanDirs(self, profilesDirs, objVar=False): """Измененный метод сканирования директорий""" dirs = [] @@ -7256,6 +7255,5 @@ class xml_gconf(xml_xfce): z = 2 continue dataOut.append(data[i]) - #TODO test this dataOut.insert(0, '\n') return "\n".join(dataOut) \ No newline at end of file diff --git a/pym/cl_utils.py b/pym/cl_utils.py index 61a6f1d..12577ef 100644 --- a/pym/cl_utils.py +++ b/pym/cl_utils.py @@ -236,7 +236,7 @@ def columnWrite(*cols): # колонки отображены print() -def justify(s,width): +def justify(s, width): '''Выровнить текст по ширине Параметры: diff --git a/scripts/cl-groupdel b/scripts/cl-groupdel index 0e942d2..c9ffe6d 100644 --- a/scripts/cl-groupdel +++ b/scripts/cl-groupdel @@ -38,7 +38,7 @@ if __name__ == "__main__": if obj.delGroupUnixServer(optObj.params['group'], optObj.opt): flagError = False - elif optObj.params['service'] == "samba": + elif optObj.params['service'] == "samba": obj = cl_ldap.servSamba() # Удаляем группу if obj.delGroupSambaServer(optObj.params['group'], diff --git a/setup.py b/setup.py index 50c7ca2..b707169 100755 --- a/setup.py +++ b/setup.py @@ -85,7 +85,6 @@ def create_data_files (data_dirs, prefix=""): break for files_obj_dir in files_obj_dirs: obj.dirs.remove(files_obj_dir) - # files_obj_dirs.sort(lambda x, y: cmp(len(y), len(x))) files_obj_dirs.sort(key=len) for dir_name in files_obj_dirs: wr_sp = (prefix+dir_name,[]) From b625a7afa000f3816184d6d986088a7be43e1553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Thu, 2 Sep 2021 15:48:23 +0300 Subject: [PATCH 11/24] removed mutables from default args, fixed some encoding errors --- pym/cl_base.py | 12 ++++---- pym/cl_ldap.py | 64 ++++++++++++++++++++++++++++++------------ pym/cl_profile.py | 69 ++++++++++++---------------------------------- pym/cl_utils.py | 19 +++++++------ pym/cl_xml.py | 6 ++-- scripts/sortmilter | 12 ++++---- 6 files changed, 88 insertions(+), 94 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index e9de8d0..7c28b3b 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -235,7 +235,7 @@ tr.setLanguage(sys.modules[__name__]) ############################################################################## class opt: - def __init__(self,shortOpt,longOpt = []): + def __init__(self, shortOpt, longOpt=None): """ Длинные и короткие опции командной строки допустимые в программе a - короткая опция >program -a @@ -257,6 +257,8 @@ class opt: >program -a две опции help - без значения, test - со значением """ + if longOpt is None: + longOpt = [] self.shortOpt = shortOpt self.longOpt = longOpt self.sysArgv = sys.argv[1:] @@ -1166,12 +1168,12 @@ class DataVars(): class glob_attr: """Глобальные аттрибуты для методов заполнения переменных""" - def _runos(self,cmd, ret_first=None, env={}): + def _runos(self,cmd, ret_first=None, env=None): """Вернуть результат выполнения команды ОС""" if not env: - envDict = {} - env.update(os.environ.items() + [("PATH",cl_utils.getpathenv())] +\ - env.items()) + env = {} + env.update(dict(os.environ)) + env.update([("PATH",cl_utils.getpathenv())]) retCode, programOut = cl_utils.runOsCommand(cmd, None, ret_first, env) if not retCode: return programOut diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 8b7a74e..f096f14 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -1696,7 +1696,7 @@ This command is not allowed.")) return False return True - def execProg(self, cmdStrProg, inStr=False, retFull=True, envProg={}): + def execProg(self, cmdStrProg, inStr=False, retFull=True, envProg=None): """Выполняет внешнюю программу Параметры: @@ -1705,13 +1705,15 @@ This command is not allowed.")) Возвращаемые параметры: строка которую выведет внешняя программа или False в случае ошибки """ + if not envProg: + envProg = {} env_path = {"PATH" : cl_utils.getpathenv()} env = {} env.update(dict(os.environ)) env.update(env_path) env.update(envProg) + - inStr = inStr.encode("UTF-8") if isinstance(inStr, str) else inStr retCode,programOut = cl_utils.runOsCommand(cmdStrProg,inStr,retFull,env) if not retCode: return programOut @@ -6024,10 +6026,12 @@ of version > 2.1.10, then you can delete this file.") + "\n" self.printERROR(_("Can not delete group") + " " + groupName) return False - def delUserSambaServer(self,userName,options,printSuccess=True, - backup=True, notDeletedDirs=[]): + def delUserSambaServer(self, userName, options, printSuccess=True, + backup=True, notDeletedDirs=None): """Удаляем Samba пользователя""" # Проверим установлен ли сервис samba + if not notDeletedDirs: + notDeletedDirs = [] if not self.initialChecks("samba"): return False if "$" in userName: @@ -7512,9 +7516,13 @@ outdated. If the backup is obsolete, use cl-backup-server.")) """Перегенерирует конфигурационные файлы, и базу данных LDAP""" return self.rebuildServer(options) - def applyProfilesFromService(self, service, verbose=False, dirsFilter = [], - filesFilter = []): + def applyProfilesFromService(self, service, verbose=False, dirsFilter=None, + filesFilter=None): """Применяем профили для данного сервиса""" + if dirsFilter is None: + dirsFilter = [] + if filesFilter is None: + filesFilter = [] # Cоздаем объект профиль устанавливая директорию # service для файлов профилей clProf = cl_profile.profile(self.clVars,service,dirsFilter,filesFilter) @@ -7541,12 +7549,14 @@ outdated. If the backup is obsolete, use cl-backup-server.")) return True def updateServer(self, options, serviceUpdate, clVars=False, - noInputAllowNetServices=[], printReplServ=True): + noInputAllowNetServices=None, printReplServ=True): """Перегенерируем конфигурационные файлы определенного или всех сервисов """ # Создаем переменные + if not noInputAllowNetServices: + noInputAllowNetServices = [] if clVars: self.clVars = clVars else: @@ -12719,10 +12729,12 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) return True @adminConnectLdap - def modReplMailAlias(self, userName, srcMails, filterHosts=[]): + def modReplMailAlias(self, userName, srcMails, filterHosts=None): """Изменяем запись в Replication/Mail (имя пользователя, список почтовых адресов пользователя""" + if filterHosts is None: + filterHosts = [] rez = self.searchMailAlias(userName) if not rez: # Если алиас не найден создаем его @@ -12784,10 +12796,12 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) return True @adminConnectLdap - def addReplMailAlias(self, userName, srcMails , filterHosts=[]): + def addReplMailAlias(self, userName, srcMails, filterHosts=None): """Добавляем запись в Replication/Mail (имя пользователя, список почтовых адресов пользователя""" + if filterHosts is None: + filterHosts = [] rez = self.searchMailAlias(userName) if not rez: ldifFile = self.ldifFileMailUser @@ -12867,13 +12881,15 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) return False return True - def maxDateAndListInDir(self, scanDir, listFiles, skipPathTime=[], + def maxDateAndListInDir(self, scanDir, listFiles, skipPathTime=None, checkTime=True, prefix=None, maxTime=None, flagDir=False): """Время последней модификации внутри директории scanDir Генерация списка файлов и директорий """ + if skipPathTime is None: + skipPathTime = [] startCheckTime = checkTime if not prefix: prefix = os.path.join(scanDir,"") @@ -16861,8 +16877,10 @@ class dnsTxt(cl_profile.bind,shareTxt): if not self.getError(): cl_profile.bind.__init__(self, text) - def getTextZone(self, clVars, zoneName, zoneType, zoneMasters=[]): + def getTextZone(self, clVars, zoneName, zoneType, zoneMasters=None): """Создание текста DNS зоны""" + if zoneMasters is None: + zoneMasters = [] if zoneType == "master": dnsBaseDN = clVars.Get("ld_dns_dn") dnsCommaSplDN = dnsBaseDN.replace(",","%2c") @@ -17078,8 +17096,10 @@ class dnsTxt(cl_profile.bind,shareTxt): text = self.getConfig() return self.writeInConfig(text) - def createZone(self, clVars, zoneName, zoneType, zoneMasters=[]): + def createZone(self, clVars, zoneName, zoneType, zoneMasters=None): """Создает зону в файле конфигурации bind""" + if zoneMasters is None: + zoneMasters = [] if self.getError(): return False textZone = self.getTextZone(clVars, zoneName, zoneType, @@ -17107,13 +17127,15 @@ class dnsTxt(cl_profile.bind,shareTxt): existsZones = self.getAllNamesZones() return sorted(list(set(zoneNames)-set(existsZones))) - def createExclZones(self, clVars, zoneNames, zoneType, zoneMasters=[]): + def createExclZones(self, clVars, zoneNames, zoneType, zoneMasters=None): """Создает зоны в файле конфигурации bind Будут созданы зоны которых нет в конфигурационном файле zoneNames - зоны которые будут созданы Не проверяется наличие зон в конфигурационном файле """ + if zoneMasters is None: + zoneMasters = [] if self.getError(): return False # Находим зоны отсутствующие в конфигурационном файле @@ -17365,13 +17387,13 @@ class servDns(shareLdap): def createMasterZone(self, zoneName, nameServer="", emailAddr="", - namesServers = [], + namesServers=None, serialNumber="1", refresh=zoneRefresh, updateRetry=zoneUpdateRetry, expiry=zoneExpiry, minimum=zoneMinimum, - ip="", mxList=[]): + ip="", mxList=None): """Создание первичной DNS зоны в конфигурационном файле и в LDAP Параметры: nameServer - имя первичного мастер сервера DNS зоны @@ -17393,6 +17415,10 @@ class servDns(shareLdap): mx - MX записи для зоны """ # Добавление зоны в конфигурационный файл + if namesServers is None: + namesServers = [] + if mxList is None: + mxList = [] ldapParser = iniLdapParser() part = "dns" self.clVars.Set("ld_dns_dn",ldapParser.getVar(part,"DN"),True) @@ -19715,8 +19741,10 @@ with type DNS record PTR (option "-t")')) return False return True - def addDNSRecord(self, domainName, ipAddrOrHost, namesMailServers=[]): + def addDNSRecord(self, domainName, ipAddrOrHost, namesMailServers=None): """Добавляем DNS запись в LDAP прямую или обратную""" + if namesMailServers is None: + namesMailServers = [] hostName, spl, zoneName = domainName.partition(".") # При поиске зоны создается объект переменных и соединение LDAP if not self.searchZoneInLDAP(zoneName): @@ -21073,7 +21101,7 @@ incompatible, use one of the options")) retData.update(dynamicHosts) if flagError: return False - return retData.items() + return list(retData.items()) def foundDynamicDNSRecords(self, zoneName, minIpRange, maxIpRange): """Находит имена динамических хостов @@ -21093,7 +21121,7 @@ incompatible, use one of the options")) # ip в диапазоне динамических адресов if isRange(self.getNumberIP(ip), minIpRange, maxIpRange): retData[domainName] = ip - return retData.items() + return list(retData.items()) def removeDynamicDNSRecords(self, netAndMask): """Удаляет динамические адреса для сети""" diff --git a/pym/cl_profile.py b/pym/cl_profile.py index eb1241b..f6c9a19 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -690,47 +690,6 @@ class objShare: fields = self.setDataField(linesBloc, brBloc) return fields -# class xmlShare: -# """Общий класс для объектов XML, наследуем - -# """ -# def _createElement(self, doc, tag, text="", attributes={}): -# """Создание нового XML элемента""" -# element = doc.createElement(tag) -# if text: -# txtNode = doc.createTextNode(self._toUNICODE(text)) -# element.append(txtNode) -# for attr in attributes.keys(): -# attribute = doc.createAttribute(attr) -# attribute.text = attributes[attr] -# element.setNode(attribute) -# return element - -# def _toUNICODE(self,val): -# """перевод текста в юникод""" -# if 'unicode' in "%s" %(type(val)): -# return val -# else: -# return val.decode('UTF-8') - - -# class xmlNode(xmlShare): -# """Класс для создания нод без аттрибутов - -# """ -# def __init__(self): -# self.node = False - - -# def createNode(self, doc, tag, text=""): -# """Создает XML элемент без аттрибутов""" -# self.node=self._createElement(doc, tag, text) -# return self.node - -# def getNode(self): -# return self.node - - class xmlCaption: """Класс XML заголовок @@ -1921,7 +1880,7 @@ class _file(_error): fout.close() retText = "" if textLine: - listTextLine = textLine.split(":") + listTextLine = textLine.decode("UTF-8").split(":") if len(listTextLine) == 2: textFormats = ["text", "XML"] retText = "bin" @@ -2268,11 +2227,15 @@ class processingTemplates: """Обработка в случае директории если возвращаем None то пропуск дир.""" return True - def scanningTemplates(self, scanDir, skipFile=[], skipDir=[], + def scanningTemplates(self, scanDir, skipFile=None, skipDir=None, prefix=None, flagDir=False): """Время последней модификации внутри директории scanDir""" + if skipFile is None: + skipFile = [] + if skipDir is None: + skipDir = [] ret = True - if not prefix: + if prefix is None: prefix = os.path.join(scanDir,"")[:-1] if not flagDir: # проверка корневой директории @@ -2339,11 +2302,11 @@ class profile(_file, _terms, xmlShare, processingTemplates): # регулярное выражение для поиска версии reFindVer = re.compile("(?<=\-)\d+\.?\d*\.?\d*") - def __init__(self, objVar, servDir=False, dirsFilter=[], filesFilter=[]): + def __init__(self, objVar, servDir=False, dirsFilter=None, filesFilter=None): # Необрабатываемые директории - self.dirsFilter = dirsFilter + self.dirsFilter = dirsFilter if dirsFilter is not None else [] # Необрабатываемые файлы - self.filesFilter = filesFilter + self.filesFilter = filesFilter if filesFilter is not None else [] _file.__init__(self) # Словарь для создания объектов новых классов по образцу self.newObjProt = {'proftpd':(apache,),} @@ -3407,7 +3370,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): return False fileProfileChange = path findChangeDir = False - listD = self.changeDirs.items() + listD = list(self.changeDirs.items()) listD.reverse() for dirChangeIn, dirChangeOut in listD: st,mid,end = path.partition(dirChangeIn) @@ -3508,7 +3471,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): newDirMv = newDir findChangeDir = False #Меняем путь к директории - listD = changeDirs.items() + listD = list(changeDirs.items()) listD.reverse() for dirChangeIn, dirChangeOut in listD: st,mid,end = profileDirFile.partition(dirChangeIn) @@ -3663,7 +3626,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): return False fileProfileChange = fileProfile findChangeDir = False - listD = changeDirs.items() + listD = list(changeDirs.items()) listD.reverse() for dirChangeIn, dirChangeOut in listD: st,mid,end = fileProfile.partition(dirChangeIn) @@ -3757,7 +3720,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): newDirMv = newDir findChangeDir = False #Меняем путь к директории - listD = changeDirs.items() + listD = list(changeDirs.items()) listD.reverse() for dirChangeIn, dirChangeOut in listD: st,mid,end = profileDirFile.partition(dirChangeIn) @@ -4082,7 +4045,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): return (applyFiles, False) return (applyFiles, objHeadNew) - def createNewClass(self, name, bases, attrs={}): + def createNewClass(self, name, bases, attrs=None): """Создает объект нового класса createNewClass(self, name, bases, attrs) @@ -4090,6 +4053,8 @@ class profile(_file, _terms, xmlShare, processingTemplates): bases - cписок наследуемых классов - (tuple), attrs - аттрибуты класса - {dict} """ + if attrs is None: + attrs = {} class newMethod: #Объединяем конфигурации def join(self, newObj): diff --git a/pym/cl_utils.py b/pym/cl_utils.py index 12577ef..7d75aa1 100644 --- a/pym/cl_utils.py +++ b/pym/cl_utils.py @@ -291,6 +291,7 @@ def runOsCommand(cmd, inStr=None, ret_first=None, env_dict=None): fout, fin, ferr = (pipe.stdout, pipe.stdin, pipe.stderr) # если есть данные на вход, передать их if inStr: + inStr = inStr.encode("UTF-8") if isinstance(inStr, str) else inStr fin.write(inStr) fin.close() # Код возврата @@ -302,9 +303,9 @@ def runOsCommand(cmd, inStr=None, ret_first=None, env_dict=None): ferr.close() if res: if len(res) == 1 or ret_first: - return retcode, res[0].strip() + return retcode, res[0].decode("UTF-8").strip() else: - return retcode, res + return retcode, [x.decode("UTF-8") for x in res] return retcode, None @@ -331,7 +332,7 @@ def getpathenv(): env=os.environ if env and 'PATH' in env: lpath=env['PATH'].split(":") - npath=[] + npath = [] for dirname in bindir: if os.path.exists(dirname) and dirname not in lpath: npath.append(dirname) @@ -343,7 +344,7 @@ class pakages: #путь к директории установленнх пакетов pkgdir="/var/db/pkg/" #список установленных пакетов - pkglist={} + pkglist = {} #Объект содержащий параметры пакета class pakage(): #имя пакета с версией @@ -355,7 +356,7 @@ class pakages: #тип пакета в портежах portdir="" def __init__(self, **args): - for atname,atvalue in args.items(): + for atname, atvalue in args.items(): setattr(self,atname, atvalue) def __init__(self): @@ -371,8 +372,8 @@ class pakages: #собрать установленные в системе пакеты def __getpkglist(self): - portageDirs=[] - instaledPkg={} + portageDirs = [] + instaledPkg = {} #проверим на существование директории с установленными пакетами if os.path.exists(self.pkgdir): #получим список типов пакетов @@ -436,12 +437,12 @@ class pakages: def getinstpkg(self, pkgname): pinfo=self.__partname(pkgname) if pinfo: - ret=[] + ret = [] if pinfo[0] and pinfo[1] and pinfo[2]: if pinfo[0]+'/'+pinfo[1] not in self.pkglist: return [] fpkg=self.pkglist[pinfo[0]+'/'+pinfo[1]] - ret=[] + ret = [] for i in fpkg: if i.ver==pinfo[2]: ret.append(i) diff --git a/pym/cl_xml.py b/pym/cl_xml.py index 770e586..146849b 100644 --- a/pym/cl_xml.py +++ b/pym/cl_xml.py @@ -19,8 +19,6 @@ from lxml import etree as ET from copy import deepcopy -# def append(*args, **kwargs): -# ET._Element.append(*args, **kwargs) def display_xml(xml): print(xml_to_str(xml)) @@ -1005,11 +1003,11 @@ class xmlDoc(): if not xmlNames and not xmlVals: flagListXml = False break - if xmlNames and firstChild(xmlNames[0]) and \ + if xmlNames and firstChild(xmlNames[0]) is not None and \ firstChild(xmlNames[0]).text: flagListXml = False break - if not (xmlVals and firstChild(xmlVals[0]) and + if not (xmlVals and firstChild(xmlVals[0]) is not None and firstChild(xmlVals[0]).text): flagListXml = False break diff --git a/scripts/sortmilter b/scripts/sortmilter index 2d707df..9525648 100755 --- a/scripts/sortmilter +++ b/scripts/sortmilter @@ -385,7 +385,7 @@ class MailBox: class MailKeeper: """Object which keep mailboxes (mailboxes union)""" - def __init__(self,storagedir=None,domains=[],errordir=None): + def __init__(self,storagedir=None, domains=None, errordir=None): # root directory for mail keeper self.root = storagedir # root directory for mail keeper @@ -397,7 +397,7 @@ class MailKeeper: # create directory for error letters mkdir_force(self.errordir) #self.initMailBoxes() - self.domains = domains + self.domains = domains if domains is not None else [] self.reInDomain = re.compile(r"@([^@]+)?(%s)$"%"|".join(self.domains),re.S) self.iNum = 2 if "unknown" not in self.mailboxes: @@ -581,24 +581,24 @@ def main(argv): help="Directory for letters with error"), parser.add_option("--domain", action="append", - default=[], + default= [], dest="domains", metavar="DOMAIN", help="Owner mail domain"), parser.add_option("--letters-dir", action="append", - default = [], + default=[], dest="letters_dir", metavar="DIR", help="Directory which contains letter for performing"), parser.add_option("--remove-success", action="store_true", - default = False, + default=False, dest="remove_success", help="Remove letters from directory if processed success"), parser.add_option("--letter-file", action="append", - default = [], + default=[], dest="letter_file", metavar="FILE", help="Letter file for performing"), From 20d9fdefb8ba0d00a1ee66853fd4d81504142368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Fri, 3 Sep 2021 09:37:01 +0300 Subject: [PATCH 12/24] fixed order in sorts, fixed ldap error messages --- pym/cl_ldap.py | 28 ++++++++++++++-------------- pym/cl_profile.py | 14 +++++++++++++- pym/cl_utils2.py | 2 +- pym/cl_vars.py | 6 +++--- setup.py | 2 +- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index f096f14..108b661 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -225,7 +225,7 @@ class ldapFunction(cl_utils2.ldapFun): parser = addLdif(strLdif,self.conLdap) parser.parse() except ldap.LDAPError as e: - self.setError(e[0]['desc']) + self.setError(str(e)) return False except: self.setError("Error in ldif file") @@ -1193,7 +1193,7 @@ in a sambaDomainName', for linkRm in scanObjs[0].links: # Удаляем ссылки os.unlink(linkRm[1]) - scanObjs[0].dirs.sort(key=len) + scanObjs[0].dirs.sort(key=len, reverse=True) for dirRm in scanObjs[0].dirs: # Удаляем директории os.rmdir(dirRm) @@ -1487,7 +1487,7 @@ if you want to continue to run the program again")) try: self.conLdap.add_s(DN, entry) except ldap.LDAPError as e: - self.printERROR(_("LDAP Error") + ": " + e[0]['desc'].strip()) + self.printERROR(_("LDAP Error") + ": " + str(e).strip()) self.printERROR(errorMessage) return False return True @@ -1552,7 +1552,7 @@ This command is not allowed.")) try: self.conLdap.modify_s(DN, modAttrs) except ldap.LDAPError as e: - self.printERROR(e[0]['desc']) + self.printERROR(str(e)) return False return True @@ -1563,7 +1563,7 @@ This command is not allowed.")) try: self.conLdap.modrdn_s(DN, newFirstDn) except ldap.LDAPError as e: - self.printERROR(e[0]['desc']) + self.printERROR(str(e)) return False return True @@ -1574,7 +1574,7 @@ This command is not allowed.")) try: self.conLdap.delete_s(DN) except ldap.LDAPError as e: - self.printERROR(e[0]['desc']) + self.printERROR(str(e)) return False return True @@ -1603,7 +1603,7 @@ This command is not allowed.")) ldap.SCOPE_SUBTREE, ldapFilter,None) except ldap.LDAPError as e: - self.printERROR("fullElementDN: "+e[0]['desc']) + self.printERROR("fullElementDN: " + str(e)) return False FDOUT = StringIO.StringIO("") writer = LDIFWriter(FDOUT) @@ -1682,17 +1682,17 @@ This command is not allowed.")) '(objectclass=*)', ['']) except ldap.LDAPError as e: - self.printERROR("deleteDN: "+e[0]['desc']) + self.printERROR("deleteDN: "+ str(e)) return False for dn, f in dnList: delListDN.append(dn) - delListDN.sort(key=len) + delListDN.sort(key=len, reverse=True) for dn in delListDN: try: self.conLdap.delete_s(dn) except ldap.LDAPError as e: - self.printERROR("deleteDN: "+e[0]['desc']) + self.printERROR("deleteDN: " + str(e)) return False return True @@ -2698,9 +2698,9 @@ class servUnix(shareLdap): return True modAttrs = [] if 'registeredAddress' in searchUser[0][0][1]: - modAttrs.append((ldap.MOD_REPLACE, 'registeredAddress', jabberID)) + modAttrs.append((ldap.MOD_REPLACE, 'registeredAddress', jabberID.encode("UTF-8"))) else: - modAttrs.append((ldap.MOD_ADD, 'registeredAddress', jabberID)) + modAttrs.append((ldap.MOD_ADD, 'registeredAddress', jabberID.encode("UTF-8"))) userDN = self.addDN('uid='+userName,self.relUsersDN) if not self.modAttrsDN(userDN, modAttrs): self.printERROR(_("Can not modify registeredAddress attribute in \ @@ -12572,7 +12572,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) self.conLdap.add_s(self.clVars.Get("ld_repl_mail_dn"), entry) except ldap.LDAPError as e: - self.printERROR(_("LDAP Error") + ": " + e[0]['desc'].strip()) + self.printERROR(_("LDAP Error") + ": " + str(e).strip()) self.printERROR(errorMessage) return False except: @@ -12587,7 +12587,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) self.conLdap.add_s(self.clVars.Get("ld_repl_worked_dn"), entry) except ldap.LDAPError as e: - self.printERROR(_("LDAP Error") + ": " + e[0]['desc'].strip()) + self.printERROR(_("LDAP Error") + ": " + str(e).strip()) self.printERROR(errorMessage) return False except: diff --git a/pym/cl_profile.py b/pym/cl_profile.py index f6c9a19..b85fa60 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -2431,7 +2431,7 @@ class profile(_file, _terms, xmlShare, processingTemplates): for fileRm in scanObjs[0].files: # Удаляем файлы os.remove(fileRm) - scanObjs[0].dirs.sort(key=len) + scanObjs[0].dirs.sort(key=len, reverse=True) for dirRm in scanObjs[0].dirs: # Удаляем директории os.rmdir(dirRm) @@ -5423,6 +5423,18 @@ class ldap(samba): z += 1 #print docObj.doc.toprettyxml() return docObj + + def getConfig(self): + """Выдает конфигурационный файл""" + listConfigTxt = [] + childNodes = list(self.docObj.getNodeBody()) + for node in childNodes: + if node.tag == "field": + listConfigTxt.append(self.docObj.getQuoteField(node)) + elif node.tag == "area": + self.docObj.xmlToText([node], listConfigTxt) + tmp = "".join(listConfigTxt) + return "\n".join(x for x in tmp.split("\n") if x.strip()) class dovecot(bind): """Класс для обработки конфигурационного файла типа dovecot diff --git a/pym/cl_utils2.py b/pym/cl_utils2.py index 4120f69..f0e6dc8 100644 --- a/pym/cl_utils2.py +++ b/pym/cl_utils2.py @@ -34,7 +34,7 @@ class ldapFun(cl_profile._error): try: self.conLdap = self.__ldapConnect(dnUser, password, host) except ldap.LDAPError as e: - self.setError(e[0]['desc']) + self.setError(str(e)) def __ldapConnect(self, dnUser, password, host): """Соединение с LDAP сервером""" diff --git a/pym/cl_vars.py b/pym/cl_vars.py index 6f857ea..2c3dd2a 100644 --- a/pym/cl_vars.py +++ b/pym/cl_vars.py @@ -26,12 +26,12 @@ class Data: # имя компьютера os_net_hostname = {'mode':"w"} # разрешенные сети - os_net_allow ={} + os_net_allow = {} # ip на всех интерфейсах - os_net_ip ={} + os_net_ip = {} #короткое название системы (CLD) - os_linux_shortname={} + os_linux_shortname = {} #домен os_net_domain = {'mode':"w"} diff --git a/setup.py b/setup.py index b707169..083075a 100755 --- a/setup.py +++ b/setup.py @@ -85,7 +85,7 @@ def create_data_files (data_dirs, prefix=""): break for files_obj_dir in files_obj_dirs: obj.dirs.remove(files_obj_dir) - files_obj_dirs.sort(key=len) + files_obj_dirs.sort(key=len, reverse=True) for dir_name in files_obj_dirs: wr_sp = (prefix+dir_name,[]) file_dirs = [] From b5fdbd082ff95e459aa9d842e51c7670f7666330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Fri, 3 Sep 2021 15:52:19 +0300 Subject: [PATCH 13/24] changed encodings in mail service --- pym/cl_base.py | 28 ++-- pym/cl_fill.py | 2 +- pym/cl_ldap.py | 334 +++++++++++++++++++++++---------------------- pym/cl_profile.py | 1 + scripts/sortmilter | 3 +- 5 files changed, 189 insertions(+), 179 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index 7c28b3b..6f4cb90 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -37,7 +37,7 @@ import cl_utils from cl_xml import firstChild import importlib ############################################################################## - +_ = lambda x : x _expand_lang = gettext._expand_lang def exit(codeExit): @@ -1096,7 +1096,7 @@ class DataVars(): def getVars(self, type_names=None): ret = {} for section, moduleVar, fillobj in self._importList: - dataVar=moduleVar.Data + dataVar = moduleVar.Data dictVars = dir(dataVar) for nameVar in dictVars: if not "__" in nameVar: @@ -1117,14 +1117,14 @@ class DataVars(): #распечатать список переменных с значениями def printVars(self,type_names=None): - var=None - var=self.getVars(type_names) - mlen_name=0 - mlen_type=0 - mlen_mode=0 + 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(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] @@ -1133,10 +1133,10 @@ class DataVars(): 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() + var[i].mode = mode + if len(mode) > mlen_mode: + mlen_mode = len(mode) + plist = list(var.keys()) plist.sort() br = cl_utils.fillstr("-",mlen_name) + " " +\ cl_utils.fillstr("-",mlen_mode) + " " + cl_utils.fillstr("-",10) @@ -1152,7 +1152,7 @@ class DataVars(): for i in plist: #if var[i].value is None: #continue - p_val=var[i].value + p_val = var[i].value if var[i].official: continue cl_utils.columnWrite( i, mlen_name, var[i].mode.lower(), diff --git a/pym/cl_fill.py b/pym/cl_fill.py index 66ef39b..3b81bf4 100644 --- a/pym/cl_fill.py +++ b/pym/cl_fill.py @@ -13,7 +13,7 @@ # 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. - +_ = lambda x : x import re import os import types diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 108b661..7027597 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -52,7 +52,7 @@ import ctypes from functools import reduce Version = "calculate-server 2.1.20" - +_ = lambda x : x tr = cl_base.lang() tr.setLanguage(sys.modules[__name__]) @@ -1089,8 +1089,8 @@ in a sambaDomainName', lenCryptStr = len(cryptStr) pwd = re.sub("(\W)", r"\\\1", password) pwdHash = self.execProg("slappasswd -s %s -h %s" %(pwd,cryptStr)) - if pwdHash and len(pwdHash)>lenCryptStr and\ - pwdHash[:lenCryptStr] == cryptStr.encode("UTF-8"): + if pwdHash and len(pwdHash) > lenCryptStr and\ + pwdHash[:lenCryptStr] == cryptStr: return pwdHash self.printERROR(_("ERROR") + " getHashPasswd: " +\ _("create crypto password")) @@ -1421,7 +1421,7 @@ in a sambaDomainName', if i == 3 and not self.isCorrectStringNet(strNet): printW() self.printERROR(_("You used four attempts, \ -if you want to continue to run the program again")) + if you want to continue to run the program again")) return False return self.isCorrectStringNet(strNet) @@ -2232,7 +2232,7 @@ class servUnix(shareLdap): groupErrors.append(groupName) flagError = True continue - userGroupNames[res[0][0][1]['cn'][0]]=\ + userGroupNames[res[0][0][1]['cn'][0].decode("UTF-8")]=\ res[0][0][1]['gidNumber'][0].decode("UTF-8") continue gidNumber = gid @@ -2241,7 +2241,7 @@ class servUnix(shareLdap): gidErrors.append(gidNumber) flagError = True continue - userGroupNames[res[0][0][1]['cn'][0]] =\ + userGroupNames[res[0][0][1]['cn'][0].decode("UTF-8")] =\ res[0][0][1]['gidNumber'][0].decode("UTF-8") if flagError: errorMessage = "" @@ -2317,9 +2317,9 @@ class servUnix(shareLdap): findUsers = [] if 'memberUid' in res[0][0][1]: usersInGroup = res[0][0][1]['memberUid'] - #TODO maybe we'll need to decode each username for userName in usersNames: - if userName in usersInGroup: + userName_encoded = userName.encode("UTF-8") + if userName_encoded in usersInGroup: findUsers.append(userName) return findUsers @@ -2542,13 +2542,13 @@ class servUnix(shareLdap): userGid = options['g'] retCondUnix, userGidNamesUnix, errMessUnix =\ self.searchGroupsUnix([userGid], False) - userGidNamesUnix = userGidNamesUnix.keys() + userGidNamesUnix = list(userGidNamesUnix.keys()) userGidNamesSamba = False # В случае вызова из Samba объекта if callSamba: retCondSamba, userGidNamesSamba, errMessSamba =\ self.servSambaObj.searchGroupsSamba([userGid], False) - userGidNamesSamba = userGidNamesSamba.keys() + userGidNamesSamba = list(userGidNamesSamba.keys()) userGidNamesPasswd = self.searchGroupsGroups([userGid], False) if userGidNamesUnix: #Имя группы пользователя @@ -2802,6 +2802,7 @@ service")) addUsers.append(user) modAttrs = [] for userName in addUsers: + #TODO check userName encoding modAttrs.append((ldap.MOD_ADD, 'memberUid', userName)) if modAttrs: groupDN = self.addDN("cn="+groupName, self.relGroupsDN) @@ -2830,7 +2831,7 @@ service")) if maxGid == 0: return self.minGid else: - return maxGid+1 + return maxGid + 1 def getMaxGidGroupSystem(self): """Получаем максимальный добавленный gid из /etc/group @@ -3121,12 +3122,12 @@ service")) if callSamba: retCondUnix, userGroupNames, errMessUnix =\ self.searchGroupsUnix([newFirstGroup],False) - userGroupNames = userGroupNames.keys() + userGroupNames = list(userGroupNames.keys()) if not userGroupNames: retCondSamba ,userGroupNames, errMessSamba =\ self.servSambaObj.searchGroupsSamba([newFirstGroup], False) - userGroupNames = userGroupNames.keys() + userGroupNames = list(userGroupNames.keys()) if not userGroupNames: self.printERROR(\ _("Group %s is not found in Unix and Samba services")%\ @@ -3135,7 +3136,7 @@ service")) else: retCondUnix, userGroupNames, errMessUnix =\ self.searchGroupsUnix([newFirstGroup]) - userGroupNames = userGroupNames.keys() + userGroupNames = list(userGroupNames.keys()) if not retCondUnix: return False groupName = userGroupNames[0] @@ -3273,10 +3274,10 @@ service")) str(userName)) # Включаем пользователя if 'u' in options: - modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "-1")] + modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', b"-1")] # Выключаем пользователя elif 'l' in options: - modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "1")] + modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', b"1")] if not options: optPasswd = {"p":""} if pwd: @@ -3290,10 +3291,10 @@ service")) return False if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: DN = self.addDN("uid="+userName, self.relUsersDN) @@ -3419,7 +3420,7 @@ service")) """Удаление пользователей из списка из группы Unix""" def getPrimaryUsers(): - gidNumber = res[0][0][1]["gidNumber"][0] + gidNumber = res[0][0][1]["gidNumber"][0].decode("UTF-8") searchUsers = self.searchUnixUserPrimGroup(gidNumber) foundUserNames = [] if searchUsers: @@ -3445,9 +3446,9 @@ service")) return False memberUsers = res[0][0][1]["memberUid"] flagError =False - #TODO decode each member? for user in users: - if not user in memberUsers: + user_encoded = user.encode("UTF-8") + if not user_encoded in memberUsers: flagError = True break if flagError: @@ -3658,7 +3659,7 @@ class servMail(shareLdap): return False return userGroupNames - def delUserMailServer(self,userName,options,printSuccess=True,backup=True): + def delUserMailServer(self, userName, options, printSuccess=True, backup=True): """Удаляем Mail пользователя""" # Проверим установлен ли сервис Mail if not self.initialChecks("mail"): @@ -3688,8 +3689,8 @@ class servMail(shareLdap): servReplObj = servRepl() if not servReplObj.delReplMailAlias(userName): self.printERROR (_("ERROR") + ": " +\ - _("Cannot delete email alias \ -for user %s in 'Replication/Mail' branch") %str(userName)) + _("Cannot delete email alias \ + for user %s in 'Replication/Mail' branch") %str(userName)) return False # Удаляем пользователя из групп if not self.delUserInGroup(userName): @@ -3744,10 +3745,10 @@ for user %s in 'Replication/Mail' branch") %str(userName)) return False userMail = resSearch[0] userInGroups = resSearch[1] - modAttrs = [(ldap.MOD_DELETE, 'rfc822member', userMail)] + modAttrs = [(ldap.MOD_DELETE, 'rfc822member', userMail.encode("UTF-8"))] flagError = False for group in userInGroups: - groupName = group[0][1]['cn'][0] + groupName = group[0][1]['cn'][0].decode("UTF-8") groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) if not self.modAttrsDN(groupDN, modAttrs): flagError = True @@ -3767,11 +3768,11 @@ for user %s in 'Replication/Mail' branch") %str(userName)) self.printERROR(\ _("Member list of group %s is empty")%str(groupName)) return False - memberMailUsers = res[0][0][1]["rfc822member"].decode("UTF-8") + memberMailUsers = res[0][0][1]["rfc822member"] flagError = False memberUsers = {} for mailUser in memberMailUsers: - userName = mailUser.split("@")[0] + userName = mailUser.decode("UTF-8").split("@")[0] memberUsers[userName] = mailUser for user in users: if not user in memberUsers.keys(): @@ -3779,14 +3780,14 @@ for user %s in 'Replication/Mail' branch") %str(userName)) break if flagError: self.printERROR(\ - _("User %s is not found in group")%str(user)+" "+\ + _("User %s is not found in group") % str(user) + " " +\ str(groupName)) return False modAttrs = [] for user in users: mailUser = memberUsers[user] modAttrs.append((ldap.MOD_DELETE, 'rfc822member', mailUser)) - groupDN = self.addDN("cn="+groupName, self.relGroupsDN) + groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) def delGroupMailServer(self, groupName, options): @@ -3799,7 +3800,7 @@ for user %s in 'Replication/Mail' branch") %str(userName)) self.printERROR( _("Group %s is not found in Mail service")%groupName) return False - delDN = self.addDN("cn="+groupName, self.relGroupsDN) + delDN = self.addDN("cn=" + groupName, self.relGroupsDN) res = self.delDN(delDN) if res: # В случае почтовой репликации удаляем алиас в ветке @@ -3811,7 +3812,8 @@ for user %s in 'Replication/Mail' branch") %str(userName)) if not servReplObj.delReplMailAlias(groupName): self.printERROR (_("ERROR") + ": " +\ _("Cannot delete email alias \ -for group %s in 'Replication/Mail' branch") % str(groupName)) + for group %s in 'Replication/Mail' branch") \ + % str(groupName)) return False self.printSUCCESS( _("Mail group %s is deleted")%groupName) return True @@ -3844,11 +3846,11 @@ for group %s in 'Replication/Mail' branch") % str(groupName)) return False if 'n' in options and 'e' in options: self.printERROR(_("Command Line Options '-n' and '-e' are \ -incompatible, use one of the options")) + incompatible, use one of the options")) return False if 'hide' in options and 'hide-off' in options: self.printERROR(_("Command Line Options '--hide' and '--hide-off' \ -are incompatible, use one of the options")) + are incompatible, use one of the options")) return False attrDelete = [] attrDeleteFirst = [] @@ -3868,16 +3870,16 @@ are incompatible, use one of the options")) # Если необходимо добавляем домен к именам хостов fHosts = [(not '.' in x and x + "." + domain) or x for x in filterHosts] for host in fHosts: - attrAppend.append((ldap.MOD_ADD, 'filtersender', host)) + attrAppend.append((ldap.MOD_ADD, 'filtersender', host.encode("UTF-8"))) if 'hide-off' in options: if 'filtersender' in searchGroup[0][0][1]: attrDeleteFirst.append((ldap.MOD_DELETE, 'filtersender', None)) if 'e' in options: altMails = options['e'].split(",") - email = searchGroup[0][0][1]["mail"][0].decode("UTF-8") + # в этот раз не трогаем кодировку + email = searchGroup[0][0][1]["mail"][0] altEmails = searchGroup[0][0][1]["mailAlternateAddress"] # Удаляем альтернативные адреса, кроме первого - #TODO decode each email for altEmail in altEmails: if email != altEmail: attrDeleteFirst.append( @@ -3888,7 +3890,7 @@ are incompatible, use one of the options")) if "@" in altMail: if len(altMail.split("@")) != 2: self.printERROR(_("Incorrect alternate adresses \ -option '-e'")) + option '-e'")) return False mail = altMail else: @@ -3898,22 +3900,23 @@ option '-e'")) (not (mail in altEmails) and len(searchGroupMail) == 1 or\ len(searchGroupMail) != 1)): self.printERROR( - _("Alternate email address %s is found in Mail service")%\ - str(mail)) + _("Alternate email address %s is found in Mail service")%\ + str(mail)) return False if i == 0: attrAppend.append((ldap.MOD_REPLACE, 'mailAlternateAddress', - mail)) + mail.encode("UTF-8"))) else: attrAppend.append((ldap.MOD_ADD, 'mailAlternateAddress', - mail)) + mail.encode("UTF-8"))) i += 1 if servReplObj: if not altMails and filterHosts: - altMails = searchGroup[0][0][1]["mailAlternateAddress"] - #TODO decode each + altMails = [x.decode("UTF-8") for x in searchGroup[0][0][1]["mailAlternateAddress"]] if altMails: - for mail in altMails: + #NOTE: there used to be a typo: + # for mail in altMails: + for altMail in altMails: if "@" in altMail: mail = altMail else: @@ -3923,28 +3926,29 @@ option '-e'")) if foundReplAlias: flagError = False foundReplUsers = foundReplAlias[0][0][1]['cn'] - #TODO decode each for foundReplUser in foundReplUsers: - if foundReplUser!=groupName: + foundReplUser_decoded = foundReplUser.decode("UTF-8") + if foundReplUser_decoded != groupName: flagError = True break if flagError: self.printERROR(_("Mail address %s is found in \ -'Replication/Mail' branch")%mail) + 'Replication/Mail' branch") % mail) self.printERROR(_("The address belongs to \ -mail user or group: %s")%foundReplUser) + mail user or group: %s") % foundReplUser_decoded) return False - if not servReplObj.modReplMailAlias(groupName, altMails, + if not servReplObj.modReplMailAlias(groupName, + altMails, filterHosts): errorMsg = _("Can not set replication mail alias,") +\ - " " + _("for name %s")%groupName + " " +\ - "(%s)"%", ".join(altMails) + " " + _("for name %s") % groupName + " " +\ + "(%s)" % ", ".join(altMails) self.printERROR(errorMsg) return False if 'hide-off' in options: if not servReplObj.deleteHideHosts(groupName): errorMsg = _("Can not delete hide host in mail alias,") +\ - " " + _("for name %s")%groupName + " " + _("for name %s") % groupName self.printERROR(errorMsg) return False # Добавляем список пользователей в группу @@ -3984,13 +3988,13 @@ mail user or group: %s")%foundReplUser) altEmails = searchGroup[0][0][1]["mailAlternateAddress"] #todo decode each for altEmail in altEmails: - splAltEmail = altEmail.split("@") - grName = splAltEmail[0] + splAltEmail = altEmail.split(b"@") + grName = splAltEmail[0].decode("UTF-8") if groupName == grName: - altEmailDomen = "" + altEmailDomen = b"" if len(splAltEmail)==2: altEmailDomen = splAltEmail[1] - newAltEmail = "%s@%s" %(newGroupName,altEmailDomen) + newAltEmail = b"%s@%s" %(newGroupName.encode("UTF-8"), altEmailDomen) attrDelete.append( (ldap.MOD_DELETE, 'mailAlternateAddress', altEmail)) @@ -3998,15 +4002,17 @@ mail user or group: %s")%foundReplUser) (ldap.MOD_ADD, 'mailAlternateAddress', newAltEmail)) break - email = searchGroup[0][0][1]["mail"][0].decode("UTF-8") - splEmail = email.split("@") - emailDomen = "" + #no decoding on purpose + email = searchGroup[0][0][1]["mail"][0] + splEmail = email.split(b"@") + emailDomen = b"" if len(splEmail)==2: emailDomen = splEmail[1] - newEmail = "%s@%s" %(newGroupName,emailDomen) + newGroupName_encoded = newGroupName.encode("UTF-8") + newEmail = b"%s@%s" %(newGroupName_encoded, emailDomen) attrAppend.append((ldap.MOD_REPLACE, 'mail', newEmail)) attrAppend.append((ldap.MOD_REPLACE, 'mailMessageStore', - newGroupName + "/")) + newGroupName_encoded + b"/")) newFirstDn = "cn=" + newGroupName oldDN = self.addDN("cn=" + groupName, self.relGroupsDN) @@ -4015,7 +4021,7 @@ mail user or group: %s")%foundReplUser) if servReplObj: if not servReplObj.renameReplMailAlias(groupName, newGroupName): self.printERROR(_("Failed modify name '%s' mail alias \ -in 'Replication/Mail' branch") %groupName) + in 'Replication/Mail' branch") %groupName) return False if res: self.printSUCCESS(_("Group renamed to %s")\ @@ -4028,7 +4034,7 @@ in 'Replication/Mail' branch") %groupName) # Изменяем комментарий к группе if 'c' in options: gecos = options['c'] - modAttrs.append((ldap.MOD_REPLACE, 'description', gecos)) + modAttrs.append((ldap.MOD_REPLACE, 'description', gecos.encode("UTF-8"))) if not modAttrs: if 'hide-off' in options: self.printWARNING(\ @@ -4108,14 +4114,14 @@ in 'Replication/Mail' branch") %groupName) modAttrs = [] # Включаем пользователя if 'U' in options: - modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "active")] + modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', b"active")] # Выключаем пользователя elif 'L' in options: - modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "passive")] + modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', b"passive")] # Изменяем комментарий к пользователю if 'c' in options: - comment = options['c'] + comment = options['c'].encode("UTF-8") modAttrs += [(ldap.MOD_REPLACE, 'sn', comment), (ldap.MOD_REPLACE, 'cn', comment)] # Изменяем пароль пользователя @@ -4128,10 +4134,10 @@ in 'Replication/Mail' branch") %groupName) return False if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) # Заменяем альтернативные почтовые адреса # Первичный почтовый адрес primaryMail = "" @@ -4144,70 +4150,72 @@ in 'Replication/Mail' branch") %groupName) if "@" in altMail: if len(altMail.split("@")) != 2: self.printERROR(_("Incorrect alternate adresses \ -option '-e'")) + option '-e'")) return False mail = altMail else: - mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host")) + mail = "%s@%s" %(altMail, self.clVars.Get("sr_mail_host")) if not primaryMail: primaryMail = mail searchUserMail = self.searchUserToMail(mail) if self.searchGroupToMail(mail) or (searchUserMail and\ - (not (mail in altEmails) and len(searchUserMail) == 1 or\ + (not (mail.encode("UTF-8") in altEmails) and len(searchUserMail) == 1 or\ len(searchUserMail) != 1)): self.printERROR( _("Alternate email address %s is found in Mail service")%\ str(mail)) return False - modAttrs.append((ldap.MOD_ADD, 'mailAlternateAddress', mail)) + modAttrs.append((ldap.MOD_ADD, 'mailAlternateAddress', mail.encode("UTF-8"))) # Удаляем предыдущие адреса self.delAlternateAddress(userName) # Изменяем основной почтовый адрес if primaryMail: if not self.servUnixObj.setUserMail(userName, primaryMail): self.printERROR(_("Failed set primary email for user %s \ -in Unix service") %str(primaryMail)) + in Unix service") % str(primaryMail)) return False # Если включена репликация почты if self.clVars.Get("ld_repl_mail_set") == "on": # Объект сервис репликации servReplObj = servRepl() if altMails: - for mail in altMails: - if "@" in altMail: - mail = altMail + #NOTE: there used to be a typo + # for mail in altMails: + for altMail in altMails: + if b"@" in altMail: + mail = altMail.decode("UTF-8") else: - mail = "%s@%s" %(altMail,\ + mail = "%s@%s" %(altMail.decode("UTF-8"),\ self.clVars.Get("sr_mail_host")) foundReplAlias = servReplObj.searchMailAddress(mail) if foundReplAlias: flagError = False foundReplUsers = foundReplAlias[0][0][1]['cn'] - #TODO decode each for foundReplUser in foundReplUsers: - if foundReplUser != userName: + foundReplUser_decoded = foundReplUser.decode("UTF-8") + if foundReplUser_decoded != userName: flagError = True break if flagError: self.printERROR(_("Mail address %s is found in \ -'Replication/Mail' branch")%mail) + 'Replication/Mail' branch") % mail) self.printERROR(_("The address belongs to \ -mail user or group: %s")%foundReplUser) + mail user or group: %s") % foundReplUser_decoded) return False if not servReplObj.modReplMailAlias(userName, altMails): self.printERROR(_("Failed modify mail aliases \ -for user %s in 'Replication/Mail' branch") %userName) + for user %s in 'Replication/Mail' branch") % userName) return False if modAttrs: - DN = self.addDN("uid="+userName, self.relUsersDN) + DN = self.addDN("uid=" + userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if 'c' in options: self.printSUCCESS(_("Modified comment")) if 'L' in options: - self.printSUCCESS(_("Locked Mail user %s")%str(userName)) + self.printSUCCESS(_("Locked Mail user %s") % str(userName)) if 'U' in options: - self.printSUCCESS(_("Unlocked Mail user %s")%str(userName)) + self.printSUCCESS(_("Unlocked Mail user %s") % str(userName)) if 'e' in options: self.printSUCCESS(_("Modified Mail alternate addresses")) if 'P' in options or 'p' in options: @@ -4227,7 +4235,7 @@ for user %s in 'Replication/Mail' branch") %userName) servReplObj = servRepl() if servReplObj.searchMailAlias(groupName): self.printERROR(_("Mail group %s is found in \ -'Replication/Mail' branch")%groupName) + 'Replication/Mail' branch") % groupName) return False #Проверяем альтернативные почтовые адреса modAttrs = [] @@ -4238,46 +4246,46 @@ for user %s in 'Replication/Mail' branch") %userName) if "@" in altMail: if len(altMail.split("@")) != 2: self.printERROR(_("Incorrect alternate adresses \ -option '-e'")) + option '-e'")) return False mail = altMail else: - mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host")) + mail = "%s@%s" % (altMail, self.clVars.Get("sr_mail_host")) if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR( - _("Alternate email address %s is found in Mail service")%\ - str(mail)) + _("Alternate email address %s is found in Mail service")%\ + str(mail)) return False if servReplObj: foundReplAlias = servReplObj.searchMailAddress(mail) if foundReplAlias: foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ -'Replication/Mail' branch")%mail) + 'Replication/Mail' branch") % mail) self.printERROR(_("The address belongs to \ -mail user or group: %s")%foundReplUser) + mail user or group: %s") % foundReplUser) return False - modAttrs.append('mailAlternateAddress: %s' %mail) + modAttrs.append('mailAlternateAddress: %s' % mail) # Фильтр почты (hostname) fHostNames = [] if 'hide' in options: fHostNames = options['hide'].split(",") for fHostName in fHostNames: if not "." in fHostName: - fHostName = "%s.%s" %(fHostName, - self.clVars.Get('os_net_domain')) - modAttrs.append('filtersender: %s' %fHostName) + fHostName = "%s.%s" % (fHostName, + self.clVars.Get('os_net_domain')) + modAttrs.append('filtersender: %s' % fHostName) if self.searchMailGroupToName(groupName): self.printERROR( - _("group name %s is found in Mail service")%\ + _("group name %s is found in Mail service")%\ str(groupName)) return False - mail = "%s@%s" %(groupName,self.clVars.Get("sr_mail_host")) + mail = "%s@%s" %(groupName, self.clVars.Get("sr_mail_host")) if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR( - _("Email address %s is found in Mail service")%\ + _("Email address %s is found in Mail service")%\ str(mail)) return False if servReplObj: @@ -4285,16 +4293,16 @@ mail user or group: %s")%foundReplUser) if foundReplAlias: foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ -'Replication/Mail' branch")%mail) + 'Replication/Mail' branch") % mail) self.printERROR(_("The address belongs to \ -mail user or group: %s")%foundReplUser) + mail user or group: %s") % foundReplUser) return False self.clVars.Set("ur_group", groupName) # Комментарий к группе groupGecos = self.servUnixObj.groupGecos if 'c' in options: groupGecos = options['c'] - self.clVars.Set("ur_group_comment",groupGecos) + self.clVars.Set("ur_group_comment", groupGecos) ldifFile = self.ldifFileGroup groupRawLdif = self.createLdif(ldifFile) if not groupRawLdif: @@ -4334,10 +4342,10 @@ for user %s in 'Replication/Mail' branch") %str(mail)) modAttrs = [] # Включаем пользователя if 'u' in options: - modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "active")] + modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', b"active")] # Выключаем пользователя elif 'l' in options: - modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "passive")] + modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', b"passive")] if not options: optPasswd = {"p":""} userPwd = self.getUserPassword(optPasswd, "p", False) @@ -4348,18 +4356,18 @@ for user %s in 'Replication/Mail' branch") %str(mail)) return False if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: - DN = self.addDN("uid="+userName, self.relUsersDN) + DN = self.addDN("uid=" + userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if 'l' in options: - self.printSUCCESS(_("Locked Mail user %s")% str(userName)) + self.printSUCCESS(_("Locked Mail user %s") % str(userName)) if 'u' in options: - self.printSUCCESS(_("Unlocked Mail user %s")% str(userName)) + self.printSUCCESS(_("Unlocked Mail user %s") % str(userName)) if not options: self.printSUCCESS(_("Changed Mail user password")) return True @@ -4383,7 +4391,7 @@ for user %s in 'Replication/Mail' branch") %str(mail)) for userName in usersNames: userMail = "%s@%s" %(userName, self.clVars.Get("sr_mail_host")) - if userMail in usersInGroup: + if userMail.encode("UTF-8") in usersInGroup: findUsers.append(userName) return findUsers @@ -4466,7 +4474,7 @@ for user %s in 'Replication/Mail' branch") %str(mail)) for userName in users: if not self.searchMailUserToName(userName): self.printERROR( - _("User %s is not found in Mail service")%\ + _("User %s is not found in Mail service")%\ str(userName)) flagFalse = True break @@ -4483,9 +4491,9 @@ for user %s in 'Replication/Mail' branch") %str(mail)) modAttrs = [] for userName in addUsers: userMail = "%s@%s" % (userName, self.clVars.Get("sr_mail_host")) - modAttrs.append((ldap.MOD_ADD, 'rfc822member', userMail)) + modAttrs.append((ldap.MOD_ADD, 'rfc822member', userMail.encode("UTF-8"))) if modAttrs: - groupDN = self.addDN("cn="+groupName, self.relGroupsDN) + groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) return True @@ -4515,7 +4523,7 @@ for user %s in 'Replication/Mail' branch") %str(mail)) servReplObj = servRepl() if servReplObj.searchMailAlias(userName): self.printERROR(_("Mail user %s is found in \ -'Replication/Mail' branch")%userName) + 'Replication/Mail' branch") % userName) return False #Проверяем альтернативные почтовые адреса modAttrs = [] @@ -4527,53 +4535,53 @@ for user %s in 'Replication/Mail' branch") %str(mail)) if "@" in altMail: if len(altMail.split("@")) != 2: self.printERROR(_("Incorrect alternate adresses option \ -'-e'")) + '-e'")) return False mail = altMail else: - mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host")) + mail = "%s@%s" %(altMail, self.clVars.Get("sr_mail_host")) if not primaryMail: primaryMail = mail if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR(\ - _("Alternate email address %s is found in Mail service")%\ - str(mail)) + _("Alternate email address %s is found in Mail service")%\ + str(mail)) return False if servReplObj: foundReplAlias = servReplObj.searchMailAddress(mail) if foundReplAlias: foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ -'Replication/Mail' branch")%mail) + 'Replication/Mail' branch")%mail) self.printERROR(_("The address belongs to \ -mail user or group: %s")%foundReplUser) + mail user or group: %s")%foundReplUser) return False - modAttrs.append("mailAlternateAddress: %s" %mail) + modAttrs.append("mailAlternateAddress: %s" % mail) else: self.printERROR(\ - _("Must be added one or more alternative addresses")) + _("Must be added one or more alternative addresses")) self.printWARNING("cl-useradd -e gst@calculate.org guest mail") return False if self.searchMailUserToName(userName): self.printERROR(_("User exists in Mail service")) return False else: - mail = "%s@%s" %(userName,self.clVars.Get("sr_mail_host")) + mail = "%s@%s" %(userName, self.clVars.Get("sr_mail_host")) if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR( - _("Email address %s is found in Mail service")%\ - str(mail)) + _("Email address %s is found in Mail service")%\ + str(mail)) return False if servReplObj: foundReplAlias = servReplObj.searchMailAddress(mail) if foundReplAlias: foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ -'Replication/Mail' branch")%mail) + 'Replication/Mail' branch") % mail) self.printERROR(_("The address belongs to \ -mail user or group: %s")%foundReplUser) + mail user or group: %s") % foundReplUser) return False # Почтовая директория пользователя mailDir = os.path.join(self.clVars.Get("sr_mail_path"), userName) @@ -4637,7 +4645,7 @@ mail user or group: %s")%foundReplUser) else: if resUnix and 'cn' in resUnix[0][0][1]: fullNameUser = resUnix[0][0][1]['cn'][0].decode("UTF-8") - self.clVars.Set("ur_fio",fullNameUser) + self.clVars.Set("ur_fio", fullNameUser) if not userPwd: userPwdHash = "crypt{xxx}" else: @@ -4646,7 +4654,7 @@ mail user or group: %s")%foundReplUser) if flagCreateUnixUser: self.servUnixObj.delUserUnixServer(userName, {}, False, False) return False - self.clVars.Set("ur_hash",userPwdHash) + self.clVars.Set("ur_hash", userPwdHash) ldifFile = self.ldifFileUser userRawLdif = self.createLdif(ldifFile) if not userRawLdif: @@ -4677,7 +4685,7 @@ mail user or group: %s")%foundReplUser) if not flagError: # Востановим удаленного пользователя message = _("Do you want to restore deleted user %s data?")\ - %userName + "\n" + "'yes', 'no'" + % userName + "\n" + "'yes', 'no'" resMailDir = self.restorePathDelUser(userName, mailDir, "mail", message) removeMailDirBack = False @@ -4695,14 +4703,14 @@ mail user or group: %s")%foundReplUser) # Записываем основной почтовый адрес в ветку Unix if not self.servUnixObj.setUserMail(userName, primaryMail): self.printERROR(_("Failed set primary email for user %s in \ -Unix service") %str(primaryMail)) + Unix service") %str(primaryMail)) flagError = True # Записываем почтовые алиасы в ветку # репликации Replication/Mail if not flagError and servReplObj: if not servReplObj.addReplMailAlias(userName, altMails): self.printERROR(_("Failed set mail aliases \ -for user %s in 'Replication/Mail' branch") %userName) + for user %s in 'Replication/Mail' branch") %userName) flagError = True if not flagError and removeMailDirBack\ and os.path.exists(removeMailDirBack): @@ -4772,7 +4780,7 @@ for user %s in 'Replication/Mail' branch") %userName) if i == 3 and not correctHostname(hostname): printW() self.printERROR(_("You used four attempts, \ -if you want to continue to run the program again")) + if you want to continue to run the program again")) return False # Установка имени хоста fullHostName = correctHostname(hostname) @@ -6459,7 +6467,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) rezultUnix, groupNamesUnix, errMessUnix =\ self.servUnixObj.searchGroupsUnix(userGroups, False) grUnix = groupNamesUnix - groupNamesUnix = groupNamesUnix.keys() + groupNamesUnix = list(groupNamesUnix.keys()) # Если установлен сервис Samba groupNamesSamba = [] gidNotFound = [] @@ -6467,7 +6475,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) rezultSamba, groupNamesSamba, errMessSamba =\ self.searchGroupsSamba(userGroups, False) grSamba = groupNamesSamba - groupNamesSamba = groupNamesSamba.keys() + groupNamesSamba = list(groupNamesSamba.keys()) userGroupNames = [] for userGr in userGroups: try: @@ -6513,7 +6521,6 @@ Samba and Unix services") %", ".join(exclGroup) resSearch = self.searchLdapDN(groupName, self.relGroupsDN, "cn") return resSearch - def searchGroupsSamba(self, userGroups, printError=True): """Ищет список групп из списка userGroups в LDAP @@ -6528,13 +6535,13 @@ Samba and Unix services") %", ".join(exclGroup) try: int(gid) except: - groupName = gid + groupName = gid.strip('\"').strip("\'") res = self.searchSambaGroupName(groupName) if not res: groupErrors.append(groupName) flagError = True continue - userGroupNames[res[0][0][1]['cn'][0]]=\ + userGroupNames[res[0][0][1]['cn'][0].decode("UTF-8")]=\ res[0][0][1]['gidNumber'][0].decode("UTF-8") continue gidNumber = gid @@ -6543,7 +6550,7 @@ Samba and Unix services") %", ".join(exclGroup) gidErrors.append(gidNumber) flagError = True continue - userGroupNames[res[0][0][1]['cn'][0]] =\ + userGroupNames[res[0][0][1]['cn'][0].decode("UTF-8")] =\ res[0][0][1]['gidNumber'][0].decode("UTF-8") if flagError: errorMessage = "" @@ -6562,6 +6569,7 @@ Samba and Unix services") %", ".join(exclGroup) return (False, userGroupNames, errorMessage) return (True, userGroupNames, "") + def searchSambaGid(self, groupId): """Находит группу сервиса Samba по ёе id""" resSearch = self.searchLdapDN(str(groupId), self.relGroupsDN, @@ -13599,12 +13607,12 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) """ varsData = ("unix_hash", "samba_lm_hash", "samba_nt_hash", "samba_nt_hash_old") - if not set(varsData)<=set(varsDict.keys()): + if not set(varsData) <= set(varsDict.keys()): notFoundVars = set(varsData) - set(varsDict.keys()) - if len(notFoundVars)1: sOARecord = " ".join(sOAList) relZoneDN = self.getRelZoneDN(zoneName) @@ -18603,7 +18611,7 @@ with option "--mxmod"') # Добавляем кавычки и -- addQ = lambda y: [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in y] # Ключи опций - optKeys = options.keys() + optKeys = list(options.keys()) # Обязательные опции requiredOpt = [] # Необязательные опции @@ -18640,8 +18648,8 @@ with option "--mxmod"') return False # Проверка обязательных опций - if not set(requiredOpt)<=set(optKeys): - notFoundReqOpt = list(set(requiredOpt)-set(optKeys)) + if not set(requiredOpt) <= set(optKeys): + notFoundReqOpt = list(set(requiredOpt) - set(optKeys)) self.printERROR(_('Can not found required command line options %s')\ %", ".join(addQ(notFoundReqOpt))) return False @@ -18663,7 +18671,7 @@ with option "--mxmod"') % (" "+_("or")+" ").join(('"%s"' % x for x in value))) return False # Проверка лишних опций - unnecessaryOpt = list(set(optKeys)-set(requiredOpt+optionalOpt.keys())) + unnecessaryOpt = list(set(optKeys) - set(requiredOpt + list(optionalOpt.keys()))) if unnecessaryOpt: self.printERROR(_("Exists unnecessary command line options %s")\ %",".join(addQ(unnecessaryOpt))) @@ -19503,7 +19511,7 @@ is incompatible with option "--ip"') # Проверим установлен ли сервис dns if not self.isServiceSetup("dns"): return False - optKeys = options.keys() + optKeys = list(options.keys()) # Опция force if "f" in optKeys: checkDHCPConfig = False @@ -20071,11 +20079,11 @@ class servDhcp(shareLdap, shareIP): # Проверим установлен ли сервис dhcp if checkSetup and not self.isServiceSetup("dhcp"): return False - optKeys = options.keys() + optKeys = list(options.keys()) minKeys = ["host", "ip", "mac"] # Проверка на наличие всех нужных опций - if not set(minKeys)<=set(optKeys): - notFoundKeys = list(set(minKeys)-set(optKeys)) + if not set(minKeys) <= set(optKeys): + notFoundKeys = list(set(minKeys) - set(optKeys)) notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s") % ", ".join(notFoundKeys)) return False @@ -20484,11 +20492,11 @@ eth0, eth1, ... etc."%net) # Проверим установлен ли сервис dhcp if not self.isServiceSetup("dhcp"): return False - optKeys = options.keys() + optKeys = list(options.keys()) minKeys = ["host"] # Проверка на наличие всех нужных опций - if not set(minKeys)<=set(optKeys): - notFoundKeys = list(set(minKeys)-set(optKeys)) + if not set(minKeys) <= set(optKeys): + notFoundKeys = list(set(minKeys) - set(optKeys)) notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ @@ -20567,7 +20575,7 @@ eth0, eth1, ... etc."%net) # Проверим установлен ли сервис dhcp if not self.isServiceSetup("dhcp"): return False - optKeys = options.keys() + optKeys = list(options.keys()) minKeys = ["net"] # Проверка на наличие всех нужных опций if not set(minKeys)<=set(optKeys): @@ -20686,7 +20694,7 @@ eth0, eth1, ... etc."%net) # Проверим установлен ли сервис dhcp if checkSetup and not self.isServiceSetup("dhcp"): return False - optKeys = options.keys() + optKeys = list(options.keys()) minKeys = ["net", "router", "range", "dnames", "dnsip"] # Проверка на наличие всех нужных опций if not set(minKeys)<=set(optKeys): @@ -20955,7 +20963,7 @@ eth0, eth1, ... etc."%net) self.printERROR = printERROR self.servDnsObj.printERROR = printERROR - optKeys = options.keys() + optKeys = list(options.keys()) minKeys = ["ip", "domain", "host", "s", "b"] # Проверка на наличие всех нужных опций if not set(minKeys) <= set(optKeys): @@ -21932,11 +21940,11 @@ network %s") % net) set(bakupObj.notLdapServices)) if listServicesLDAP: flagLdap = True - optKeys = options.keys() + optKeys = list(options.keys()) minKeys += ["net", "router", "range", "dnames", "dnsip"] # Проверка на наличие всех нужных опций - if not set(minKeys)<=set(optKeys): - notFoundKeys = list(set(minKeys)-set(optKeys)) + if not set(minKeys) <= set(optKeys): + notFoundKeys = list(set(minKeys) - set(optKeys)) notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ %", ".join(notFoundKeys)) diff --git a/pym/cl_profile.py b/pym/cl_profile.py index b85fa60..9346cb5 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -40,6 +40,7 @@ import string import time from copy import deepcopy from collections.abc import Iterable +_ = lambda x : x tr = cl_base.lang() tr.setLocalDomain('cl_lib') tr.setLanguage(sys.modules[__name__]) diff --git a/scripts/sortmilter b/scripts/sortmilter index 9525648..96df376 100755 --- a/scripts/sortmilter +++ b/scripts/sortmilter @@ -159,7 +159,8 @@ class Letter: resent_to = self.getResentTo() delivered_to = self.getDeliveredTo() if resent_to and delivered_to: - order_field = self.mail.keys() + order_field = list(self.mail.keys()) + #TODO probably will be bugged in py3: order of keys in dict changed if order_field.index("Delivered-To") < order_field.index("Resent-To"): receiver_emails = delivered_to else: From 125bb3b77601b087c94da3b90c2d2ac0c4f667e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Fri, 3 Sep 2021 17:51:32 +0300 Subject: [PATCH 14/24] More encoding fixes --- pym/cl_ldap.py | 264 ++++++++++++++++++++++++------------------------- 1 file changed, 129 insertions(+), 135 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 7027597..c3fa969 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -3152,7 +3152,7 @@ service")) userGid = resGroup.split(":")[2] if resLdap: userGid = resLdap[0][0][1]['gidNumber'][0].decode("UTF-8") - modAttrs += [(ldap.MOD_REPLACE, 'gidNumber', userGid)] + modAttrs += [(ldap.MOD_REPLACE, 'gidNumber', userGid.encode("UTF-8"))] visible = False # пользователя видно if 'V' in options: @@ -3210,7 +3210,7 @@ service")) if textLine == False: self.printERROR(_("Can not move home directory")) modAttrs = [(ldap.MOD_REPLACE, 'homeDirectory', - homeDirOld)] + homeDirOld.encode("UTF-8"))] self.modAttrsDN(DN, modAttrs) return False else: @@ -3986,7 +3986,6 @@ class servMail(shareLdap): return False # изменяем адрес и альтернативный адрес altEmails = searchGroup[0][0][1]["mailAlternateAddress"] - #todo decode each for altEmail in altEmails: splAltEmail = altEmail.split(b"@") grName = splAltEmail[0].decode("UTF-8") @@ -4145,7 +4144,6 @@ class servMail(shareLdap): if 'e' in options: altEmails = res[0][0][1]["mailAlternateAddress"] altMails = options['e'].split(",") - #TODO decode each for altMail in altMails: if "@" in altMail: if len(altMail.split("@")) != 2: @@ -4159,8 +4157,8 @@ class servMail(shareLdap): primaryMail = mail searchUserMail = self.searchUserToMail(mail) if self.searchGroupToMail(mail) or (searchUserMail and\ - (not (mail.encode("UTF-8") in altEmails) and len(searchUserMail) == 1 or\ - len(searchUserMail) != 1)): + (mail.encode("UTF-8" not in altEmails) and len(searchUserMail) == 1 or\ + len(searchUserMail) != 1)): self.printERROR( _("Alternate email address %s is found in Mail service")%\ str(mail)) @@ -4387,7 +4385,6 @@ for user %s in 'Replication/Mail' branch") %str(mail)) findUsers = [] if 'rfc822member' in res[0][0][1]: usersInGroup = res[0][0][1]['rfc822member'] - #TODO decode each for userName in usersNames: userMail = "%s@%s" %(userName, self.clVars.Get("sr_mail_host")) @@ -4553,9 +4550,9 @@ for user %s in 'Replication/Mail' branch") %str(mail)) if foundReplAlias: foundReplUser = foundReplAlias[0][0][1]['cn'][0].decode("UTF-8") self.printERROR(_("Mail address %s is found in \ - 'Replication/Mail' branch")%mail) + 'Replication/Mail' branch") % mail) self.printERROR(_("The address belongs to \ - mail user or group: %s")%foundReplUser) + mail user or group: %s") % foundReplUser) return False modAttrs.append("mailAlternateAddress: %s" % mail) else: @@ -5124,10 +5121,10 @@ class servJabber(shareLdap): descr = groupSearch[0][0][1]["cn"][0].decode("UTF-8") uid = userSearch[0][0][1]["uid"][0].decode("UTF-8") if 'departmentNumber' in userSearch[0][0][1]: - modAttrs.append((ldap.MOD_REPLACE, 'departmentNumber', descr)) + modAttrs.append((ldap.MOD_REPLACE, 'departmentNumber', descr.encode("UTF-8"))) else: - modAttrs.append((ldap.MOD_ADD, 'departmentNumber', descr)) - userDN = self.addDN("uid="+uid, self.relUsersDN) + modAttrs.append((ldap.MOD_ADD, 'departmentNumber', descr.encode("UTF-8"))) + userDN = self.addDN("uid=" + uid, self.relUsersDN) return self.modAttrsDN(userDN, modAttrs) def renameJabberId(self, userName, newJabberId): @@ -5139,10 +5136,10 @@ class servJabber(shareLdap): return False modAttrs = [] if 'mail' in searchUser[0][0][1]: - modAttrs.append((ldap.MOD_REPLACE, 'mail', newJabberId)) + modAttrs.append((ldap.MOD_REPLACE, 'mail', newJabberId.encode("UTF-8"))) else: - modAttrs.append((ldap.MOD_ADD, 'mail', newJabberId)) - userDN = self.addDN("uid="+userName, self.relUsersDN) + modAttrs.append((ldap.MOD_ADD, 'mail', newJabberId.encode("UTF-8"))) + userDN = self.addDN("uid=" + userName, self.relUsersDN) return self.modAttrsDN(userDN, modAttrs) @adminConnectLdap @@ -5209,7 +5206,7 @@ in Jabber service")) userSearch = self.searchUserToNameOrId(userName) if userSearch and 'departmentNumber' in userSearch[0][0][1]: if not userSearch[0][0][1]['departmentNumber'][0] == \ - groupSearch[0][0][1]['cn'][0].decode("UTF-8"): + groupSearch[0][0][1]['cn'][0]: self.printERROR(_("User %s is not found in group")%\ str(userName) + " " + str(groupName)) res = False @@ -5297,7 +5294,8 @@ in Jabber service")) userPwdHash)) if modAttrs: uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") - DN = self.addDN("uid="+userName, self.relUsersDN) + #NOTE: userName used instead of uid? bug? + DN = self.addDN("uid=" + userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if 'l' in options: @@ -5352,10 +5350,10 @@ in Jabber service")) in Unix service") %str(jabberId)) return False if 'mail' in res[0][0][1]: - modAttrs.append((ldap.MOD_REPLACE, 'mail', jabberId)) + modAttrs.append((ldap.MOD_REPLACE, 'mail', jabberId.encode("UTF-8"))) else: - modAttrs.append((ldap.MOD_ADD, 'mail', jabberId)) - modAttrs.append((ldap.MOD_REPLACE,'cn',jabberId.partition("@")[0])) + modAttrs.append((ldap.MOD_ADD, 'mail', jabberId.encode("UTF-8"))) + modAttrs.append((ldap.MOD_REPLACE,'cn', jabberId.partition("@")[0].encode("UTF-8"))) # Изменяет группу в которую входит пользователь if 'g' in options: userGroup = options['g'] @@ -5395,7 +5393,7 @@ in Unix service") %str(jabberId)) userPwdHash)) if modAttrs: uid = res[0][0][1]['uid'][0].decode("UTF-8") - DN = self.addDN("uid="+uid, self.relUsersDN) + DN = self.addDN("uid=" + uid, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if printSuccess: @@ -5658,7 +5656,7 @@ in Unix service") %str(jabberId)) # Берем комментарий для пользователя из Unix if resUnix and 'cn' in resUnix[0][0][1]: fullNameUser = resUnix[0][0][1]['cn'][0].decode("UTF-8") - self.clVars.Set("ur_fio",fullNameUser) + self.clVars.Set("ur_fio", fullNameUser) ldifFile = self.ldifFileUser userLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): @@ -5970,32 +5968,31 @@ of version > 2.1.10, then you can delete this file.") + "\n" if not getPrimaryUsers(): return False self.printERROR( - _("Member list of group %s is empty")%str(groupName)) + _("Member list of group %s is empty") % str(groupName)) return False memberUsers = res[0][0][1]["memberUid"] - #TODO decode each - flagError =False + flagError = False for user in users: - if not user in memberUsers: + if user.encode("UTF-8") not in memberUsers: flagError = True break if flagError: if not getPrimaryUsers(): return False self.printERROR( - _("User %s is not found in group")%str(user)+" "+\ + _("User %s is not found in group") % str(user)+ " " +\ str(groupName)) return False modAttrs = [] for userName in users: - modAttrs.append((ldap.MOD_DELETE, 'memberUid', userName)) - groupDN = self.addDN("cn="+groupName, self.relGroupsDN) + modAttrs.append((ldap.MOD_DELETE, 'memberUid', userName.encode("UTF-8"))) + groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) def delUserInGroup(self, userName): """Удаление из групп в которые входит пользователь""" userInGroups = self.searchSambaMemberGid(userName) - modAttrs = [(ldap.MOD_DELETE, 'memberUid', userName)] + modAttrs = [(ldap.MOD_DELETE, 'memberUid', userName.encode("UTF-8"))] flagError = False for group in userInGroups: groupName = group[0][1]['cn'][0] @@ -6024,7 +6021,7 @@ of version > 2.1.10, then you can delete this file.") + "\n" if self.servUnixObj.searchUnixUserPrimGroup(groupId): self.printWARNING(_("cannot remove user's primary group") + ".") return True - delDN = self.addDN("cn="+groupName, self.relGroupsDN) + delDN = self.addDN("cn=" + groupName, self.relGroupsDN) res = self.delDN(delDN) if res: if printSuccess: @@ -6455,9 +6452,8 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) findUsers = [] if 'memberUid' in res[0][0][1]: usersInGroup = res[0][0][1]['memberUid'] - #TODO decode each for userName in usersNames: - if userName in usersInGroup: + if userName.encode("UTF-8") in usersInGroup: findUsers.append(userName) return findUsers @@ -6757,22 +6753,21 @@ Samba and Unix services") %", ".join(exclGroup) machineGroupName = self.clVars.Get('sr_samba_machine_group') resSearch = self.searchSambaGroupName(machineGroupName) if resSearch: - machineGid = resSearch[0][0][1]['gidNumber'][0].decode("UTF-8") + machineGid = resSearch[0][0][1]['gidNumber'][0] else: mGr = self.staticGroups["Domain Computers"] - machineGid = mGr.gid + machineGid = mGr.gid.encode("UTF-8") searchAllMachines = self.searchAllSambaMachines() if searchAllMachines: for data in searchAllMachines: - #TODO check encoding - machineName = data[0][1]['uid'][0] + machineName = data[0][1]['uid'][0].decode("UTF-8") machineDN = self.addDN("uid=" + machineName, self.relComputersDN) res = self.modAttrsDN(machineDN, [(ldap.MOD_REPLACE, 'gidNumber', machineGid)]) if not res: self.printERROR(_("Can not replace machine %s \ -'gidNumber'")%machineName) + 'gidNumber'")%machineName) flagError = True break if flagError: @@ -11818,7 +11813,7 @@ class servFtp(shareLdap): userPwdHash)) if modAttrs: uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") - DN = self.addDN("uid="+uid, self.relUsersDN) + DN = self.addDN("uid=" + uid, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if 'c' in options: @@ -11959,7 +11954,7 @@ class servFtp(shareLdap): else: if resUnix and 'cn' in resUnix[0][0][1]: fullNameUser = resUnix[0][0][1]['cn'][0].decode("UTF-8") - self.clVars.Set("ur_fio",fullNameUser) + self.clVars.Set("ur_fio", fullNameUser) if not userPwd: userPwdHash = "crypt{xxx}" else: @@ -12710,9 +12705,9 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) if len(splEmail)==2: emailDomen = splEmail[1] newEmail = "%s@%s" %(newName,emailDomen) - attrAppend.append((ldap.MOD_REPLACE, 'rfc822member', newEmail)) + attrAppend.append((ldap.MOD_REPLACE, 'rfc822member', newEmail.encode("UTF-8"))) attrAppend.append((ldap.MOD_REPLACE, 'mailMessageStore', - newName + "/")) + (newName + "/").encode("UTF-8"))) if not self.modAttrsDN(oldDN, attrAppend): return False newFirstDn = "cn=" + newName @@ -12770,34 +12765,34 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) # Если необходимо добавляем домен к именам хостов fHosts = [(not '.' in x and x + "." + domain) or x for x in filterHosts] for host in fHosts: - attrAppend.append((ldap.MOD_ADD, 'filtersender', host)) + attrAppend.append((ldap.MOD_ADD, 'filtersender', host.encode("UTF-8"))) if 'filtersender' in rez[0][0][1]: attrDelete.append((ldap.MOD_DELETE, 'filtersender', None)) - email = rez[0][0][1]["mail"][0].decode("UTF-8") + email = rez[0][0][1]["mail"][0] altEmails = rez[0][0][1]["mailAlternateAddress"] # Удаляем альтернативные адреса, кроме первого - #TODO decode each for altEmail in altEmails: if email != altEmail: attrDelete.append( (ldap.MOD_DELETE, 'mailAlternateAddress', altEmail)) # Заменяем первый адрес - attrReplace.append((ldap.MOD_REPLACE, 'mail',userMail)) + attrReplace.append((ldap.MOD_REPLACE, 'mail', + userMail.encode("UTF-8"))) attrReplace.append((ldap.MOD_REPLACE, 'mailAlternateAddress', - userMail)) + userMail.encode("UTF-8"))) relMailDN = self.getRelMailDN() - aliasDN = self.addDN("cn=%s"%userName,relMailDN) + aliasDN = self.addDN("cn=%s" % userName, relMailDN) # Добавляем альтернативные адреса for mail in userMails: attrAppend.append((ldap.MOD_ADD, 'mailAlternateAddress', - mail)) + mail.encode("UTF-8"))) modAttrs = attrDelete + attrReplace + attrAppend if not self.modAttrsDN(aliasDN, modAttrs): return False else: relMailDN = self.getRelMailDN() - aliasDN = self.addDN("cn=%s"%userName,relMailDN) + aliasDN = self.addDN("cn=%s" % userName, relMailDN) # Удаляем почтовый алиас if not self.delDN(aliasDN): return False @@ -12879,7 +12874,7 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) host = rez[0][0][1]['host'][0].decode("UTF-8") if host != replHost: # Изменяемые аттрибуты - modAttrs = [(ldap.MOD_REPLACE, 'host', replHost)] + modAttrs = [(ldap.MOD_REPLACE, 'host', replHost.encode("UTF-8"))] relWorkedDN = self.getRelWorkedDN() DN = self.addDN("uid=" + userName, relWorkedDN) if not self.modAttrsDN(DN, modAttrs): @@ -13605,6 +13600,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) .calculate.env в домашней директории пользователя """ + #TODO debug this varsData = ("unix_hash", "samba_lm_hash", "samba_nt_hash", "samba_nt_hash_old") if not set(varsData) <= set(varsDict.keys()): @@ -14561,10 +14557,10 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): ipMasterServers = [firstChild(x).text.strip() for x in xmlNodes] if not ipMasterServers: self.printERROR(_("The program does not support information \ -for %s DNS zone")%zoneName) + for %s DNS zone")%zoneName) return False title=_("Information about slave DNS zone %s in \ -/etc/bind/named.conf") %zoneName + /etc/bind/named.conf") %zoneName headerList = [_("Field"), _("Value")] flagF = True dataList = [] @@ -14624,14 +14620,14 @@ for %s DNS zone")%zoneName) [_("Expiry"), expiry], [_("Minimum"), minimum]] if mXRecords: - [dataList.insert(2, ["", x]) for x in reversed(mXRecords[1:])] - dataList.insert(2,[_("MX-record"), mXRecords[0]]) + [dataList.insert(2, ["", x.decode("UTF-8")]) for x in reversed(mXRecords[1:])] + dataList.insert(2,[_("MX-record"), mXRecords[0].decode("UTF-8")]) if aRecords: - [dataList.insert(2, ["", x]) for x in reversed(aRecords[1:])] - dataList.insert(2,[_("A-record"), aRecords[0]]) + [dataList.insert(2, ["", x.decode("UTF-8")]) for x in reversed(aRecords[1:])] + dataList.insert(2,[_("A-record"), aRecords[0].decode("UTF-8")]) if nSRecords: - [dataList.insert(2, ["", x]) for x in reversed(nSRecords[1:])] - dataList.insert(2,[_("NS-record"), nSRecords[0]]) + [dataList.insert(2, ["", x.decode("UTF-8")]) for x in reversed(nSRecords[1:])] + dataList.insert(2,[_("NS-record"), nSRecords[0].decode("UTF-8")]) repObj = report(title, headerList, dataList) repObj.printReport() recordsSearch = servDnsObj.searchAllRecordInZone(zoneName) @@ -14643,16 +14639,16 @@ for %s DNS zone")%zoneName) dataMXList = [] for record in recordsSearch: domainName = "%s.%s"\ - %(record[0][1]["relativeDomainName"][0],\ + %(record[0][1]["relativeDomainName"][0].decode("UTF-8"),\ zoneName) if "aRecord" in record[0][1]: dataAList.append([domainName, - record[0][1]["aRecord"][0]]) + record[0][1]["aRecord"][0].decode("UTF-8")]) if "mXRecord" in record[0][1]: flagFirst = True flagError = False for mxData in record[0][1]["mXRecord"]: - mxDataSpl = mxData.split(" ") + mxDataSpl = mxData.decode("UTF-8").split(" ") if len(mxDataSpl) != 2: flagError = True break @@ -14673,8 +14669,8 @@ for %s DNS zone")%zoneName) return False elif "cNAMERecord" in record[0][1]: dataCNList.append([domainName, - delDot(record[0][1]["cNAMERecord"][0])]) - allDataList = [dataAList, dataCNList,dataMXList] + delDot(record[0][1]["cNAMERecord"][0].decode("UTF-8"))]) + allDataList = [dataAList, dataCNList, dataMXList] allRecordList = ["A","CNAME","MX"] allHeaderList = [(_("Domain"), "ip"), (_("Domain"), _("CNAME Domain")), @@ -14683,8 +14679,8 @@ for %s DNS zone")%zoneName) for i in range(len(allRecordList)): if allDataList[i]: title=_("Information about %s-records")\ - %allRecordList[i] + " " +\ - _("in master DNS zone %s")%zoneName + % allRecordList[i] + " " +\ + _("in master DNS zone %s") % zoneName headerList = allHeaderList[i] dataList = allDataList[i] repObj = report(title, headerList, dataList) @@ -14704,8 +14700,8 @@ for %s DNS zone")%zoneName) for record in recordsSearch: if "pTRRecord" in record[0][1]: IP = "%s.%s"%(threeOctetsIP,\ - record[0][1]["relativeDomainName"][0]) - domainName = delDot(record[0][1]["pTRRecord"][0]) + record[0][1]["relativeDomainName"][0].decode("UTF-8")) + domainName = delDot(record[0][1]["pTRRecord"][0].decode("UTF-8")) dataPTRList.append([IP, domainName]) if dataPTRList: title=_("Information about %s-records")\ @@ -14748,7 +14744,7 @@ for %s DNS zone")%zoneName) dataList.append([_("Domain name"), domainName]) if "aRecord" in record[0][1]: dataList.append([_("A-record"),\ - record[0][1]["aRecord"][0]]) + record[0][1]["aRecord"][0].decode("UTF-8")]) if "mXRecord" in record[0][1]: flagFirst = True flagError = False @@ -14758,23 +14754,23 @@ for %s DNS zone")%zoneName) flagError = True break if flagFirst: - dataList.append([_("MX-record") ,mxData]) + dataList.append([_("MX-record"), mxData.decode("UTF-8")]) flagFirst = False else: - dataList.append(["", mxData]) + dataList.append(["", mxData.decode("UTF-8")]) if flagError: self.printERROR(\ _("Incorrect MX-records in A-record %s")\ - %domainName) + % domainName) return False typeRecord = "A" elif "cNAMERecord" in record[0][1]: dataList.append([_("CNAME-record"),\ - record[0][1]["cNAMERecord"][0]]) + record[0][1]["cNAMERecord"][0].decode("UTF-8")]) typeRecord = "CNAME" title=_("Information about %s-record")\ %typeRecord + " " +\ - _("in master DNS zone %s")%zoneName + _("in master DNS zone %s") % zoneName repObj = report(title, headerList, dataList) if flagF: flagF = False @@ -14803,7 +14799,7 @@ for %s DNS zone")%zoneName) for record in dataRecords: dataList.append(["ip", ip]) if "pTRRecord" in record[0][1]: - domainNameDot = record[0][1]["pTRRecord"][0] + domainNameDot = record[0][1]["pTRRecord"][0].decode("UTF-8") dataList.append([_("PTR-record"), domainNameDot]) typeRecord = "PTR" title=_("Information about %s-record")\ @@ -14823,8 +14819,8 @@ for %s DNS zone")%zoneName) if not data: return False headerList, dataList = data - title=_("Information about machine %s") %machineName + " " +\ - _("for service %s") %strService + title=_("Information about machine %s") % machineName + " " +\ + _("for service %s") % strService # Информация о пользователе elif "U" in options: userName = options["U"] @@ -14832,8 +14828,8 @@ for %s DNS zone")%zoneName) if not data: return False headerList, dataList = data - title=_("Information about user %s") %userName + " " +\ - _("for service %s") %strService + title=_("Information about user %s") % userName + " " +\ + _("for service %s") % strService # Информация о группе elif "G" in options: groupName = options["G"] @@ -14841,8 +14837,8 @@ for %s DNS zone")%zoneName) if not data: return False headerList, dataList = data - title=_("Information about group %s") %groupName + " " +\ - _("for service %s") %strService + title=_("Information about group %s") % groupName + " " +\ + _("for service %s") % strService # Информация о компьютерах elif "m" in options: @@ -14853,7 +14849,7 @@ for %s DNS zone")%zoneName) if not data: return False headerList, dataList = data - title=_("All machines in LDAP for service %s")%strService + title=_("All machines in LDAP for service %s") % strService # Информация о пользователях elif "u" in options: fields = "short" @@ -14863,7 +14859,7 @@ for %s DNS zone")%zoneName) if not data: return False headerList, dataList = data - title=_("All users in LDAP for service %s")%strService + title=_("All users in LDAP for service %s") % strService # Информация о группах elif "g" in options: fields = "short" @@ -14873,7 +14869,7 @@ for %s DNS zone")%zoneName) if not data: return False headerList, dataList = data - title=_("All groups in LDAP for service %s")%strService + title=_("All groups in LDAP for service %s") % strService if "M" in options or "m" in options or\ "U" in options or "G" in options or\ @@ -14883,7 +14879,6 @@ for %s DNS zone")%zoneName) return True if len(options) == 1 and "full" in options: - self.printERROR(_("Can not use a single command line option \ 'full'.")) self.printERROR(_("This option should be used in conjunction \ @@ -14899,22 +14894,22 @@ with another option.")) 'groups':'relGroupsDN', 'computers':'relComputersDN'} if branch not in branchData: - self.printERROR("getQueryLDAP service=%s"%service) - self.printERROR(_("ERROR: getQueryLDAP incorrect branch=%s")%branch) + self.printERROR("getQueryLDAP service=%s" % service) + self.printERROR(_("ERROR: getQueryLDAP incorrect branch=%s") % branch) return False relAttr = branchData[branch] try: servObj = eval("serv%s()" %service.capitalize()) except: self.printERROR(\ - _("ERROR: getQueryLDAP incorrect service=%s")%service) + _("ERROR: getQueryLDAP incorrect service=%s") % service) return False # Если сервис не установлен то ошибка if not servObj.isServiceSetup(service): return False if relAttr not in servObj.__dict__: - self.printERROR("getQueryLDAP service=%s"%service) - self.printERROR(_("ERROR: getQueryLDAP incorrect branch=%s")%branch) + self.printERROR("getQueryLDAP service=%s" % service) + self.printERROR(_("ERROR: getQueryLDAP incorrect branch=%s") % branch) return False searchRes = servObj.searchLdapDN(searchStr, getattr(servObj, relAttr), searchAttr, retrAttrs) @@ -14939,6 +14934,7 @@ with another option.")) attributes = [x[0] for x in data] retrAttrs = [x[1] for x in data] retClVars=False + #TODO check encoding searchRes = self.getQueryLDAP(service, "computers", searchAttr, searchStr, retrAttrs) if searchRes == False: @@ -14954,22 +14950,23 @@ with another option.")) if attr in info[0][1]: ldapValue = info[0][1][attr] # Изменяем значения аттрибутов для вывода на печать + #modUserAttr already decodes ldapValue[0] = self.modUserAttr(attr, ldapValue[0], service) flagFirst = False for value in ldapValue: if not flagFirst: - data.append((attrName, value)) + data.append((attrName, value.decode("UTF-8"))) flagFirst = True else: - data.append(("", value)) + data.append(("", value.decode("UTF-8"))) if service == "samba" and attr == "gidNumber": memberGroups = self._getUserMemberGroups(machName, service) attrApp = _("Supplementary groups") if service == "samba": if value: - memberGroups.insert(0,value) + memberGroups.insert(0, value.decode("UTF-8")) flagFirst = False for value in memberGroups: if not flagFirst: @@ -15003,7 +15000,7 @@ with another option.")) if service == "proxy": for i in searchRes: memberList = i[0][1]['member'] - i[0][1]['member'] = [x.partition("=")[2] for x in memberList] + i[0][1]['member'] = [x.partition(b"=")[2] for x in memberList] if service == "jabber": servObj = servJabber() resMemberSearch = servObj.searchUsersToGroup(groupName) @@ -15013,7 +15010,7 @@ with another option.")) memberUid.append(dataGroup[0][1]['uid'][0]) for i in searchRes: i[0][1]['memberUid'] = memberUid - data.append((_("Member UID"),"memberUid")) + data.append((_("Member UID"), "memberUid")) attributes = [x[0] for x in data] retrAttrs = [x[1] for x in data] data = [] @@ -15022,15 +15019,14 @@ with another option.")) if service in ("unix", "samba"): memberUid = [] if 'memberUid' in searchRes[0][0][1]: - #TODO check encoding memberUid = searchRes[0][0][1]['memberUid'] groupId = searchRes[0][0][1]['gidNumber'][0].decode("UTF-8") primaryUids = self.getUnixUidPrimGroup(groupId) - memberUid = primaryUids + memberUid + memberUid = [x.encode("UTF-8") for x in primaryUids] + memberUid uniqueUid = [] # Удаляем одинаковые элементы for uid in memberUid: - if not uid in uniqueUid: + if uid not in uniqueUid: uniqueUid.append(uid) if uniqueUid: searchRes[0][0][1]['memberUid'] = uniqueUid @@ -15042,6 +15038,7 @@ with another option.")) ldapValue = info[0][1][attr] # Изменяем значения аттрибутов для вывода на печать for i in range(len(ldapValue)): + #modGroupAttr already decodes ldapValue[i] = self.modGroupAttr(attr, ldapValue[i], service) flagFirst = False @@ -15068,9 +15065,9 @@ with another option.")) headers = [_("Field"), _("Value")] attributes = [x[0] for x in data] retrAttrs = [x[1] for x in data] - retClVars=False + retClVars = False if service in ["mail", "samba"]: - retClVars=True + retClVars = True searchRes = self.getQueryLDAP(service, "users", searchAttr, searchStr, retrAttrs, retClVars) if searchRes == False: @@ -15084,6 +15081,7 @@ with another option.")) # Добавляем директорию хранения писем для сервиса mail if service == "mail": for i in searchRes: + #TODO maybe will have to remove decoding i[0][1]['homeDirectory'] = [os.path.join(\ clVars.Get("sr_mail_path"), i[0][1]['uid'][0].decode("UTF-8"))] data.append((_("Home directory"),"homeDirectory")) @@ -15468,7 +15466,7 @@ with another option.")) users = [] if searchUsers: for dataUser in searchUsers: - users.append(dataUser[0][1]['uid'][0]) + users.append(dataUser[0][1]['uid'][0].decode("UTF-8")) return users def modGroupAttr(self, attr, value, service): @@ -15597,15 +15595,15 @@ with another option.")) if service == "unix": userInGroups = servObj.searchUnixMemberGid(userName) for group in userInGroups: - memberGroups.append(group[0][1]['cn'][0]) + memberGroups.append(group[0][1]['cn'][0].decode("UTF-8")) if service == "samba": userInGroups = servObj.searchSambaMemberGid(userName) for group in userInGroups: - memberGroups.append(group[0][1]['cn'][0]) + memberGroups.append(group[0][1]['cn'][0].decode("UTF-8")) if service == "proxy": userInGroups = servObj.searchMemberGroups(userName) for group in userInGroups: - memberGroups.append(group[0][1]['cn'][0]) + memberGroups.append(group[0][1]['cn'][0].decode("UTF-8")) if service == "mail": resSearch = servObj.searchMailMember(userName) if not resSearch: @@ -15616,8 +15614,9 @@ with another option.")) altMailGroup = group[0][1]['mailAlternateAddress'] listMail = mailGroup + altMailGroup for mail in listMail: - if not mail in memberGroups: - memberGroups.append(mail) + mail_decoded = mail.decode("UTF-8") + if mail_decoded not in memberGroups: + memberGroups.append(mail_decoded) return memberGroups class servProxy(shareLdap): @@ -15938,12 +15937,12 @@ is not valid ") %accessPorts) addUsers = [x for x in users if x not in memberUsers] for userName in addUsers: if flagEmptyGroup: - modAttrs.append((ldap.MOD_REPLACE, 'member', "uid="+userName)) + modAttrs.append((ldap.MOD_REPLACE, 'member', b"uid=" + userName.encode("UTF-8"))) flagEmptyGroup = False else: - modAttrs.append((ldap.MOD_ADD, 'member', "uid="+userName)) + modAttrs.append((ldap.MOD_ADD, 'member', b"uid=" + userName.encode("UTF-8"))) if modAttrs: - groupDN = self.addDN("cn="+groupName, self.relGroupsDN) + groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) return True @@ -16001,8 +16000,8 @@ is not valid ") %accessPorts) if i >= lenMemberUsers: modAttrs.append((ldap.MOD_REPLACE, 'member', "")) else: - modAttrs.append((ldap.MOD_DELETE, 'member', "uid="+userName)) - groupDN = self.addDN("cn="+groupName, self.relGroupsDN) + modAttrs.append((ldap.MOD_DELETE, 'member', b"uid=" + userName.encode("UTF-8"))) + groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) def modUserProxyPasswd(self, userName, options): @@ -18378,23 +18377,23 @@ with option "--mxmod"') self.printERROR(_("Incorrect SOA-record in DNS zone %s")%zoneName) return False # Все авторитативные сервера зоны, в случае slаve зоны - namesServers = [delDot(x) for x in nSRecords] - oldNamesServers = [delDot(x) for x in nSRecords] + namesServers = [delDot(x.decode("UTF-8")) for x in nSRecords] + oldNamesServers = [delDot(x.decode("UTF-8")) for x in nSRecords] # Изменяем ip зоны if zoneIP: - addDot = lambda x: (len(x)>0 and x[-1]!="." and "%s."%x) or x + addDot = lambda x: (len(x) > 0 and x[-1] != "." and "%s." % x) or x relZoneDN = self.getRelZoneDN(zoneName) modAttrs = [] if 'aRecord' in zoneData[0][0][1]: modAttrs =[(ldap.MOD_DELETE, 'aRecord', None)] - modAttrs.append((ldap.MOD_ADD, 'aRecord', zoneIP)) + modAttrs.append((ldap.MOD_ADD, 'aRecord', zoneIP.encode("UTF-8"))) DN = self.addDN("relativeDomainName=@", relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(_("Can not modify A-record in zone %s")\ - %zoneName) + % zoneName) return False - self.printSUCCESS(_("Modified A-record in zone %s")%zoneName) - self.printSUCCESS("%s --> %s"%(zoneName, zoneIP)) + self.printSUCCESS(_("Modified A-record in zone %s") % zoneName) + self.printSUCCESS("%s --> %s" % (zoneName, zoneIP)) self.printSUCCESS("") # Изменяем MX записи if mxServers or modMxServers: @@ -18405,7 +18404,7 @@ with option "--mxmod"') if modMxServers: if not flagFoundMX: self.printERROR(_("Can not found MX-record in zone %s")\ - %zoneName) + % zoneName) return False # Находим нужную запись foundMxServers = [len(x.decode("UTF-8").split(" ")) == 1 @@ -18416,12 +18415,12 @@ with option "--mxmod"') newMxHost = modMxServers[1] if not oldMxHost in foundMxServers: self.printERROR(_("Can not found MX host %s")\ - %oldMxHost +" " + _("in zone %s")%zoneName) + %oldMxHost +" " + _("in zone %s") % zoneName) return False # Проверка наличия новой MX записи в A записи if newMxHost in foundMxServers: self.printERROR(_("MX host %s exists")\ - %newMxHost +" " + _("in zone %s")%zoneName) + % newMxHost +" " + _("in zone %s") % zoneName) return False # Проверка существования A записи для MX хоста if not self.checkMXDomains([newMxHost]): @@ -18465,14 +18464,14 @@ with option "--mxmod"') if self.isCorrectStringNet(nameServer, False): self.printERROR(_('Incorrect autoritative server')) self.printERROR(_('Error in command line option \ -"--server"')) + "--server"')) self.printWARNING(_('Example:')) self.printWARNING('--server ns.domain.com') return False if not nameServer: self.printERROR(_('Incorrect autoritative server name')) self.printERROR(_('Error in command line option \ -"--server"')) + "--server"')) return False # Добавляем мастер сервер в имена авторитативаных серверов if not nameServer in namesServers: @@ -18486,11 +18485,11 @@ with option "--mxmod"') %nameServer) self.printWARNING(\ _("Add A-record %s (autoritative DNS server) in LDAP")\ - %nameServer) + % nameServer) return False # Почтовый адрес администратора зоны splEmail = soaData[1].partition(".") - email = "%s@%s"%(splEmail[0], delDot(splEmail[2])) + email = "%s@%s" % (splEmail[0], delDot(splEmail[2])) oldEmail = email if 'email' in options: email = options['email'] @@ -18538,7 +18537,7 @@ with option "--mxmod"') DN = self.addDN("relativeDomainName=@", relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(_("Can not modify new SOA-record for zone %s \ -in LDAP")%zoneName) +in LDAP") % zoneName) return False # Результат исполнения для пользователя # Изменен ли главный сервер авторизации @@ -19676,9 +19675,8 @@ with type DNS record PTR (option "-t")')) self.printERROR(_("CNAME-record %s exists in LDAP")\ %domainName) cnameHosts = findCName[0][0][1]['cNAMERecord'] - #TODO check encodings for cnameHost in cnameHosts: - self.printERROR("%s --> %s"%(domainName,cnameHost)) + self.printERROR("%s --> %s"%(domainName,cnameHost.decode("UTF-8"))) self.printERROR("") return False # Метод добавляющий в конце текста точку если ее нет @@ -20457,7 +20455,7 @@ eth0, eth1, ... etc."%net) fullServerDNSName) if foundServ: serverIP = foundServ[0][0][1]['aRecord'][0].decode("UTF-8") - moveRecords.append((fullServerDNSName,serverIP)) + moveRecords.append((fullServerDNSName, serverIP)) data = [oldDnsIPs, oldRanges, net] if not self.modifyDNSZoneName(oldDomainNames[0], domainNames[0], moveRecords, data): @@ -20831,7 +20829,6 @@ eth0, eth1, ... etc."%net) flagDelARecord = True if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] - #TODO decode each if ip in aRecords: flagCreateARecord = False flagDelARecord = False @@ -20842,7 +20839,7 @@ eth0, eth1, ... etc."%net) # Проверка на диапазон адресов flagCorrect, flagError =\ self.isCorrectDynamicIP(\ - fullHostName.partition(".")[0], ipAdr, dhcpObj, + fullHostName.partition(".")[0], ipAdr.decode("UTF-8"), dhcpObj, False) if flagError: return False @@ -21077,14 +21074,13 @@ incompatible, use one of the options")) if recData: if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] - #TODO decode each if ip in aRecords: retData[fullDomainName] = ip else: self.printERROR(_("DHCP static host %s")%hostname) self.printERROR(_("DHCP ip %s")%ip) self.printERROR(_("DNS host %s")%fullDomainName) - self.printERROR(_("DNS ip %s")%",".join(aRecords)) + self.printERROR(_("DNS ip %s")%",".join(x.decode("UTF_8" for x in aRecords))) self.printERROR(_("IP addresses do not match")) flagError = True break @@ -21464,7 +21460,6 @@ network %s") % net) if recData: if 'aRecord' in recData[0][0][1]: aRecords = recData[0][0][1]['aRecord'] - #TODO check encoding if not ip in aRecords: flagError = True else: @@ -22062,7 +22057,6 @@ network %s") % net) fullHostNameServer) if recData and 'aRecord' in recData[0][0][1]: flagFoundARecord = True - #TODO check encoding if ipServer in recData[0][0][1]['aRecord']: flagCreateDNSRecord = False else: From f7eae8233bfb6cde2059518a7753674177e7cc41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Mon, 6 Sep 2021 16:01:04 +0300 Subject: [PATCH 15/24] more encoding fixes; minor code clean-up --- pym/cl_base.py | 1 + pym/cl_ldap.py | 173 ++++++++++++++++++++++++---------------------- pym/cl_profile.py | 2 +- pym/cl_utils.py | 8 +-- 4 files changed, 95 insertions(+), 89 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index 6f4cb90..ef77ec7 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -799,6 +799,7 @@ class DataVars(): def Get(self, nameVar): tmp = self.__Get(nameVar) + #TODO remove this #DEBUG isBytes = isinstance(tmp, bytes) if isBytes: diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index c3fa969..4e56826 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -141,7 +141,7 @@ class report: char = "-+-" convLines.append(self._insertStrChar(lines[i], lenCols, char)) print("\n".join(convLines)) - print("(%s %s)"%(len(self.dataList), _("rows"))) + print("(%s %s)" % (len(self.dataList), _("rows"))) return True def _insertStrChar(self, line, lenCols, char): @@ -927,10 +927,10 @@ in a sambaDomainName', if "erlang" in process: killPid.append(process.split(" ")[0]) if killPid and " ".join(killPid).strip(): - textLine=self.execProg("kill %s" %" ".join(killPid)) + textLine=self.execProg("kill %s" % " ".join(killPid)) if textLine == False: self.printERROR(_("Can not 'kill %s'")\ - %" ".join(killPid)) + % " ".join(killPid)) flagError = True break elif daemon == "squid" and self.getRunDaemons(["squid"]): @@ -957,11 +957,12 @@ in a sambaDomainName', tic = 0 if errStopProxy: self.printOnlyNotOK(" ",\ - self.lenString(message)+\ - offset+3) + self.lenString(message)+\ + offset + 3) else: - self.printOnlyOK(" ",self.lenString(message)+\ - offset+3) + self.printOnlyOK(" ", + self.lenString(message)+\ + offset + 3) else: sys.stdout.flush() if os.system("/etc/init.d/squid stop &>/dev/null"): @@ -1066,7 +1067,7 @@ in a sambaDomainName', else: pidDir = os.path.join(baseDir,addDirDict[daemon][0]) if os.access(pidDir, os.F_OK) and os.listdir(pidDir) and\ - os.path.exists(os.path.join(pidDir,addDirDict[daemon][1])): + os.path.exists(os.path.join(pidDir, addDirDict[daemon][1])): runDaemons[daemon] = True else: runDaemons[daemon] = False @@ -1085,10 +1086,10 @@ in a sambaDomainName', self.printERROR(_("ERROR") + " getHashPasswd: " +\ _("crypto algoritm empty")) return False - cryptStr = "{%s}"%crypt.upper() + cryptStr = "{%s}" % crypt.upper() lenCryptStr = len(cryptStr) pwd = re.sub("(\W)", r"\\\1", password) - pwdHash = self.execProg("slappasswd -s %s -h %s" %(pwd,cryptStr)) + pwdHash = self.execProg("slappasswd -s %s -h %s" % (pwd, cryptStr)) if pwdHash and len(pwdHash) > lenCryptStr and\ pwdHash[:lenCryptStr] == cryptStr: return pwdHash @@ -1100,7 +1101,7 @@ in a sambaDomainName', """Проверка, запущен ли сервис с данным именем""" flagError = False if not nameService in self.servicesDaemons.keys(): - self.printERROR(_("Can1 not supported service '%s'")%nameService) + self.printERROR(_("Can1 not supported service '%s'") % nameService) self.printERROR(_("Can not check run service")) return False # Названия демонов для сервиса @@ -1120,6 +1121,7 @@ in a sambaDomainName', [not x in retList and retList.append(x) for x in listEl] return retList + #TODO debug jpeg encoding def setJpegPhotoUser(self, userName, photoPath, attr="uid"): """Добавляем jpeg фотографию пользователя в LDAP""" import subprocess @@ -1351,10 +1353,10 @@ in a sambaDomainName', splNet = strNetworks.replace(","," ").split(" ") if checkNet: checkIP = False - res=re.compile("^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?\/\d\d?$") + res = re.compile("^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?\/\d\d?$") else: checkIP = True - res=re.compile("^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?$") + res = re.compile("^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?$") flagError = False networks = [] for i in splNet: @@ -1376,13 +1378,13 @@ in a sambaDomainName', break if checkNet: netList = r.split("/") - if len(netList)==2: + if len(netList) == 2: try: netMaskInt = int(netList[1]) except: flagError = True break - if netMaskInt>31 or netMaskInt<4: + if netMaskInt > 31 or netMaskInt<4: flagError = True break else: @@ -1547,7 +1549,7 @@ This command is not allowed.")) @adminConnectLdap def modAttrsDN(self, relDN, modAttrs): """Модифицирует аттрибуты DN""" - DN = self.addDN(relDN,self.baseDN) + DN = self.addDN(relDN, self.baseDN) if modAttrs: try: self.conLdap.modify_s(DN, modAttrs) @@ -1559,7 +1561,7 @@ This command is not allowed.")) @adminConnectLdap def modifyElemDN(self, relDN, newFirstDn): """Изменяет основной элемент DN (uid, cn и др.)""" - DN = self.addDN(relDN,self.baseDN) + DN = self.addDN(relDN, self.baseDN) try: self.conLdap.modrdn_s(DN, newFirstDn) except ldap.LDAPError as e: @@ -1605,7 +1607,7 @@ This command is not allowed.")) except ldap.LDAPError as e: self.printERROR("fullElementDN: " + str(e)) return False - FDOUT = StringIO.StringIO("") + FDOUT = StringIO("") writer = LDIFWriter(FDOUT) for dn, f in dnList: writer.unparse(dn, f) @@ -2740,9 +2742,9 @@ in Unix service")) return False modAttrs = [] if 'mail' in searchUser[0][0][1]: - modAttrs.append((ldap.MOD_REPLACE, 'mail', mail)) + modAttrs.append((ldap.MOD_REPLACE, 'mail', mail.encode("UTF-8"))) else: - modAttrs.append((ldap.MOD_ADD, 'mail', mail)) + modAttrs.append((ldap.MOD_ADD, 'mail', mail.encode("UTF-8"))) userDN = self.addDN('uid='+userName,self.relUsersDN) if not self.modAttrsDN(userDN, modAttrs): self.printERROR(_("Can not modify mail attribute in Unix service")) @@ -2803,9 +2805,9 @@ service")) modAttrs = [] for userName in addUsers: #TODO check userName encoding - modAttrs.append((ldap.MOD_ADD, 'memberUid', userName)) + modAttrs.append((ldap.MOD_ADD, 'memberUid', userName.encode("UTF-8"))) if modAttrs: - groupDN = self.addDN("cn="+groupName, self.relGroupsDN) + groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) return True @@ -3165,7 +3167,7 @@ service")) # Изменяем домашнюю директорию if 'd' in options: homeDir = options['d'] - modAttrs += [(ldap.MOD_REPLACE, 'homeDirectory', homeDir)] + modAttrs += [(ldap.MOD_REPLACE, 'homeDirectory', homeDir.encode("UTF-8"))] # Включаем пользователя if 'U' in options: modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', b"-1")] @@ -3176,14 +3178,14 @@ service")) if 'c' in options: comment = options['c'] if 'displayName' in res[0][0][1]: - modAttrs += [(ldap.MOD_REPLACE, 'displayName', comment), - (ldap.MOD_REPLACE, 'cn', comment)] + modAttrs += [(ldap.MOD_REPLACE, 'displayName', comment.encode("UTF-8")), + (ldap.MOD_REPLACE, 'cn', comment.encode("UTF-8"))] else: - modAttrs += [(ldap.MOD_REPLACE, 'cn', comment)] + modAttrs += [(ldap.MOD_REPLACE, 'cn', comment.encode("UTF-8"))] # Изменяем оболочку пользователя if 's' in options: shell = options['s'] - modAttrs.append((ldap.MOD_REPLACE, 'loginShell', shell)) + modAttrs.append((ldap.MOD_REPLACE, 'loginShell', shell.encode("UTF-8"))) # Изменяем пароль пользователя userPwd = self.getUserPassword(options, "p", "P") if userPwd == False: @@ -3194,10 +3196,10 @@ service")) return False if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): @@ -3402,7 +3404,7 @@ service")) def delUserInGroup(self, userName): """Удаление из групп в которые входит пользователь""" userInGroups = self.searchUnixMemberGid(userName) - modAttrs = [(ldap.MOD_DELETE, 'memberUid', userName)] + modAttrs = [(ldap.MOD_DELETE, 'memberUid', userName.encode("UTF-8"))] flagError = False for group in userInGroups: groupName = group[0][1]['cn'][0] @@ -3460,8 +3462,8 @@ service")) return False modAttrs = [] for userName in users: - modAttrs.append((ldap.MOD_DELETE, 'memberUid', userName)) - groupDN = self.addDN("cn="+groupName, self.relGroupsDN) + modAttrs.append((ldap.MOD_DELETE, 'memberUid', userName.encode("UTF-8"))) + groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) @@ -3786,6 +3788,7 @@ class servMail(shareLdap): modAttrs = [] for user in users: mailUser = memberUsers[user] + #mailUser - bytes modAttrs.append((ldap.MOD_DELETE, 'rfc822member', mailUser)) groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) @@ -5247,6 +5250,7 @@ in Jabber service")) for data in searchUsers: uid = data[0][1]['uid'][0] userDN = self.addDN("uid="+uid, self.relUsersDN) + # newName is a number? modAttrs = [(ldap.MOD_REPLACE, 'departmentNumber', newName)] @@ -5276,10 +5280,10 @@ in Jabber service")) modAttrs = [] # Включаем пользователя if 'u' in options: - modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] + modAttrs += [(ldap.MOD_REPLACE, 'initials', b"Yes")] # Выключаем пользователя elif 'l' in options: - modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] + modAttrs += [(ldap.MOD_REPLACE, 'initials', b"No")] if not options: optPasswd = {"p":""} userPwd = self.getUserPassword(optPasswd, "p", False) @@ -5288,10 +5292,10 @@ in Jabber service")) userPwdHash = userPwd if 'userPassword' in resSearch[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") #NOTE: userName used instead of uid? bug? @@ -5371,14 +5375,14 @@ in Unix service") %str(jabberId)) return False # Включаем пользователя if 'U' in options: - modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] + modAttrs += [(ldap.MOD_REPLACE, 'initials', b"Yes")] # Выключаем пользователя elif 'L' in options: - modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] + modAttrs += [(ldap.MOD_REPLACE, 'initials', b"No")] # Изменяем комментарий к пользователю if 'c' in options: comment = options['c'] - modAttrs += [(ldap.MOD_REPLACE, 'sn', comment)] + modAttrs += [(ldap.MOD_REPLACE, 'sn', comment.encode("UTF-8"))] # Изменяем пароль пользователя userPwd = self.getUserPassword(options, "p", "P") if userPwd == False: @@ -5387,10 +5391,10 @@ in Unix service") %str(jabberId)) userPwdHash = userPwd if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: uid = res[0][0][1]['uid'][0].decode("UTF-8") DN = self.addDN("uid=" + uid, self.relUsersDN) @@ -5451,7 +5455,7 @@ in Unix service") %str(jabberId)) # Изменяем комментарий к группе if 'c' in options: gecos = options['c'] - modAttrs = [(ldap.MOD_REPLACE, 'description', gecos)] + modAttrs = [(ldap.MOD_REPLACE, 'description', gecos.encode("UTF-8"))] groupDN = self.addDN("cn="+groupName, self.relGroupsDN) if self.modAttrsDN(groupDN, modAttrs): self.printSUCCESS(_("Modified group comment")) @@ -6593,7 +6597,7 @@ Samba and Unix services") %", ".join(exclGroup) addUsers.append(user) modAttrs = [] for userName in addUsers: - modAttrs.append((ldap.MOD_ADD, 'memberUid', userName)) + modAttrs.append((ldap.MOD_ADD, 'memberUid', userName.encode("UTF-8"))) if modAttrs: groupDN = self.addDN("cn="+groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) @@ -6846,12 +6850,12 @@ Samba and Unix services") %", ".join(exclGroup) 5 (builtin group).")) return False groupType = options['t'] - modAttrs.append((ldap.MOD_REPLACE, 'sambaGroupType', groupType)) + modAttrs.append((ldap.MOD_REPLACE, 'sambaGroupType', groupType.encode("UTF-8"))) # Изменяем комментарий к группе if 'c' in options: gecos = options['c'] - modAttrs.append((ldap.MOD_REPLACE, 'description', gecos)) - modAttrs.append((ldap.MOD_REPLACE, 'displayName', gecos)) + modAttrs.append((ldap.MOD_REPLACE, 'description', gecos.encode("UTF-8"))) + modAttrs.append((ldap.MOD_REPLACE, 'displayName', gecos.encode("UTF-8"))) if modAttrs: groupDN = self.addDN("cn=" + modGroupName, self.relGroupsDN) res = self.modAttrsDN(groupDN, modAttrs) @@ -7346,9 +7350,9 @@ options '-w, --workgroup'")) if 'c' in options: comment = options['c'] if 'displayName' in res[0][0][1]: - modAttrs = [(ldap.MOD_REPLACE, 'displayName', comment)] + modAttrs = [(ldap.MOD_REPLACE, 'displayName', comment.encode("UTF-8"))] else: - modAttrs = [(ldap.MOD_ADD, 'displayName', comment)] + modAttrs = [(ldap.MOD_ADD, 'displayName', comment.encode("UTF-8"))] DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False @@ -9664,12 +9668,12 @@ to this group") #'helpChapter':_("Samba service options"), #'help':_("create unix user account and Samba user account") #}, - #{'progAccess':(3,), - #'shortOption':"f", - #'longOption':"force", - #'helpChapter':_("Mail service options"), - #'help':_("create unix user account and mail user account") - #}, + {'progAccess':(3,6,), + 'shortOption':"f", + 'longOption':"force", + 'helpChapter':_("Mail service options"), + 'help':_("create unix user account and mail user account") + }, {'progAccess':(3,), 'shortOption':"n", 'longOption':"create-profile", @@ -11794,7 +11798,7 @@ class servFtp(shareLdap): modAttrs = [] # Изменяем комментарий к пользователю if 'c' in options: - comment = options['c'] + comment = options['c'].encode("UTF-8") modAttrs += [(ldap.MOD_REPLACE, 'sn', comment), (ldap.MOD_REPLACE, 'cn', comment)] # Изменяем пароль пользователя @@ -11807,10 +11811,10 @@ class servFtp(shareLdap): return False if 'userPassword' in resSearch[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") DN = self.addDN("uid=" + uid, self.relUsersDN) @@ -11844,10 +11848,10 @@ class servFtp(shareLdap): return False if 'userPassword' in resSearch[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: uid = resSearch[0][0][1]['uid'][0].decode("UTF-8") DN = self.addDN("uid="+userName, self.relUsersDN) @@ -12836,14 +12840,14 @@ if %%errorlevel%%==0 NET USE T: \\\\%s\\ftp' %(netbios,netbios,netbios) aliasDN = self.addDN("cn=%s"%userName,relMailDN) for mail in userMails: modAttrs.append((ldap.MOD_ADD, 'mailAlternateAddress', - mail)) + mail.encode("UTF-8"))) if filterHosts: domain = self.clVars.Get('os_net_domain') # Если необходимо добавляем домен к именам хостов fHosts = [(not '.' in x and x + "." + domain) or x for x in filterHosts] for host in fHosts: modAttrs.append((ldap.MOD_ADD, 'filtersender', - host)) + host.encode("UTF-8"))) res = self.modAttrsDN(aliasDN, modAttrs) # Если ошибка то удаляем почтовый алиас if not res: @@ -13647,10 +13651,10 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) modAttrs = [] if 'userPassword' in resUnix[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) DN = self.servUnixObj.addDN("uid="+userName, self.servUnixObj.relUsersDN) if not self.servUnixObj.modAttrsDN(DN, modAttrs): @@ -13667,6 +13671,7 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) ("sambaLMPassword",userLMHash), ("sambaNTPassword",userNTHash)] resSambaAttr = resSamba[0][0][1] + #TODO debug for attr, value in data: if attr in resSambaAttr: modAttrs.append((ldap.MOD_REPLACE, attr, value)) @@ -15434,8 +15439,8 @@ with another option.")) # Добавляем директорию хранения писем для сервиса mail for i in searchRes: i[0][1]['homeDirectory'] = [os.path.join(\ - clVars.Get("sr_mail_path"),i[0][1]['uid'][0])] - data.append((_("Home directory"),"homeDirectory")) + clVars.Get("sr_mail_path"), i[0][1]['uid'][0].decode("UTF-8"))] + data.append((_("Home directory"), "homeDirectory")) delData.append(_("Home directory")) if fields == "short": data = [x for x in data if x[0] not in delData] @@ -15831,9 +15836,9 @@ is not valid ") %accessPorts) groupName = group[0][1]['cn'][0] lenMember = len(group[0][1]['member']) if lenMember == 1: - modAttrs = [(ldap.MOD_REPLACE, 'member', "")] + modAttrs = [(ldap.MOD_REPLACE, 'member', b"")] else: - modAttrs = [(ldap.MOD_DELETE, 'member', "uid="+userName)] + modAttrs = [(ldap.MOD_DELETE, 'member', b"uid=" + userName.encode("UTF-8"))] groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) if not self.modAttrsDN(groupDN, modAttrs): flagError = True @@ -16018,10 +16023,10 @@ is not valid ") %accessPorts) modAttrs = [] # Включаем пользователя if 'u' in options: - modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] + modAttrs += [(ldap.MOD_REPLACE, 'initials', b"Yes")] # Выключаем пользователя elif 'l' in options: - modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] + modAttrs += [(ldap.MOD_REPLACE, 'initials', b"No")] if not options: optPasswd = {"p":""} userPwd = self.getUserPassword(optPasswd, "p", False) @@ -16032,10 +16037,10 @@ is not valid ") %accessPorts) return False if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): @@ -16094,13 +16099,13 @@ is not valid ") %accessPorts) modAttrs = [] # Включаем пользователя if 'U' in options: - modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] + modAttrs += [(ldap.MOD_REPLACE, 'initials', b"Yes")] # Выключаем пользователя elif 'L' in options: - modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] + modAttrs += [(ldap.MOD_REPLACE, 'initials', b"No")] # Изменяем комментарий к пользователю if 'c' in options: - comment = options['c'] + comment = options['c'].encode("UTF-8") modAttrs += [(ldap.MOD_REPLACE, 'sn', comment), (ldap.MOD_REPLACE, 'cn', comment)] # Изменяем пароль пользователя @@ -16113,10 +16118,10 @@ is not valid ") %accessPorts) return False if 'userPassword' in res[0][0][1]: modAttrs.append((ldap.MOD_REPLACE, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', - userPwdHash)) + userPwdHash.encode("UTF-8"))) if modAttrs: DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): @@ -16168,7 +16173,7 @@ is not valid ") %accessPorts) # Изменяем комментарий к группе if 'c' in options: gecos = options['c'] - modAttrs = [(ldap.MOD_REPLACE, 'description', gecos)] + modAttrs = [(ldap.MOD_REPLACE, 'description', gecos.encode("UTF-8"))] groupDN = self.addDN("cn="+groupName, self.relGroupsDN) if self.modAttrsDN(groupDN, modAttrs): self.printSUCCESS(_("Modified group comment")) @@ -18142,7 +18147,7 @@ this DNS server')%nameServer) def modARecord(self, hostName, domainName, zoneName, otherIP, newIP): """Изменение IP A записи (прямая зона)""" relZoneDN = self.getRelZoneDN(zoneName) - modAttrs = [(ldap.MOD_REPLACE, 'aRecord', newIP)] + modAttrs = [(ldap.MOD_REPLACE, 'aRecord', newIP.encode("UTF-8"))] DN = self.addDN("relativeDomainName=%s"\ %hostName, relZoneDN) if not self.modAttrsDN(DN, modAttrs): @@ -18167,7 +18172,7 @@ this DNS server')%nameServer) for mxServer in mxServers: i += 10 mxString = "%s %s" %(i, addDot(mxServer)) - modAttrs.append((ldap.MOD_ADD, 'mXRecord', mxString)) + modAttrs.append((ldap.MOD_ADD, 'mXRecord', mxString.encode("UTF-8"))) DN = self.addDN("relativeDomainName=%s"%hostName, relZoneDN) if not self.modAttrsDN(DN, modAttrs): if hostName == "@": @@ -18216,7 +18221,7 @@ this DNS server')%nameServer) addDot = lambda x: (len(x)>0 and x[-1]!="." and "%s."%x) or x relZoneDN = self.getRelZoneDN(PTRZoneName) modAttrs = [(ldap.MOD_REPLACE, 'pTRRecord',\ - addDot(newDomainName))] + addDot(newDomainName).encode("UTF-8"))] DN = self.addDN("relativeDomainName=%s"\ %PTRHostName, relZoneDN) if not self.modAttrsDN(DN, modAttrs): @@ -18236,7 +18241,7 @@ this DNS server')%nameServer) addDot = lambda x: (len(x)>0 and x[-1]!="." and "%s."%x) or x relZoneDN = self.getRelZoneDN(zoneName) modAttrs = [(ldap.MOD_REPLACE, 'cNAMERecord',\ - addDot(newCname))] + addDot(newCname).encode("UTF-8"))] DN = self.addDN("relativeDomainName=%s" %hostName, relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(\ @@ -18526,14 +18531,14 @@ with option "--mxmod"') if len(optKeys)>1: sOARecord = " ".join(sOAList) relZoneDN = self.getRelZoneDN(zoneName) - modAttrs = [(ldap.MOD_REPLACE, 'sOARecord', sOARecord)] + modAttrs = [(ldap.MOD_REPLACE, 'sOARecord', sOARecord.encode("UTF-8"))] if 'server' in options or 'servers' in options: # Добавляем мастер сервер в имена авторитативаных серверов if not nameServer in namesServers: namesServers.insert(0, nameServer) modAttrs.append((ldap.MOD_DELETE, 'nSRecord', None)) modAttrs.append((ldap.MOD_ADD, 'nSRecord',\ - [addDot(x) for x in namesServers])) + [addDot(x).encode("UTF-8") for x in namesServers])) DN = self.addDN("relativeDomainName=@", relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(_("Can not modify new SOA-record for zone %s \ @@ -19849,7 +19854,7 @@ with type DNS record PTR (option "-t")')) sOAList[2] = serialNumber sOARecord = " ".join(sOAList) relZoneDN = self.getRelZoneDN(zoneName) - modAttrs = [(ldap.MOD_REPLACE, 'sOARecord', sOARecord)] + modAttrs = [(ldap.MOD_REPLACE, 'sOARecord', sOARecord.encode("UTF-8"))] DN = self.addDN("relativeDomainName=@", relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(_("Can not write new serial number for zone %s \ diff --git a/pym/cl_profile.py b/pym/cl_profile.py index 9346cb5..0631240 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -5461,7 +5461,7 @@ class dovecot(bind): def postXML(self, xmlArea=False): """Последующая постобработка XML""" # Добавляем перевод строки если его нет в конец области - if not xmlArea: + if xmlArea is None: xmlArea = self.docObj.body xmlFields = xpath.Evaluate("child::field", xmlArea) if xmlFields and not (\ diff --git a/pym/cl_utils.py b/pym/cl_utils.py index 7d75aa1..4087fda 100644 --- a/pym/cl_utils.py +++ b/pym/cl_utils.py @@ -535,7 +535,7 @@ def getInterfaces(): def getIp(iface): sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14) + ifreq = struct.pack('16sH14s', iface.encode("UTF-8"), socket.AF_INET, b'\x00'*14) try: res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq) except IOError: @@ -550,7 +550,7 @@ def getMask(iface): Get mask for interface """ sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14) + ifreq = struct.pack('16sH14s', iface.encode("UTF-8"), socket.AF_INET, b'\x00'*14) try: res = fcntl.ioctl(sockfd, SIOCGIFNETMASK, ifreq) except IOError: @@ -565,7 +565,7 @@ def getMac(iface): Get mac for interface """ sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - ifreq = struct.pack('16sH14s', iface, socket.AF_UNIX, '\x00'*14) + ifreq = struct.pack('16sH14s', iface.encode("UTF-8"), socket.AF_UNIX, b'\x00'*14) res = fcntl.ioctl(sockfd, SIOCGIFHWADDR, ifreq) address = struct.unpack('16sH14s', res)[2] mac = struct.unpack('6B8x', address) @@ -599,7 +599,7 @@ def strIpToIntIp(addr): def getIpNet(ip,mask=None,cidr=None): """Get net (xx.xx.xx.xx/xx) by ip address and mask""" ip = strIpToIntIp(ip) - if not mask is None: + if mask is not None: net = maskToCidr(mask) else: net = int(cidr) From 6155c90053bae003fb9d2de64d7b3c7ac8d73d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Tue, 7 Sep 2021 16:06:36 +0300 Subject: [PATCH 16/24] fixed xml in DNS related methods; minor clean-up --- pym/cl_base.py | 4 - pym/cl_fill_server.py | 2 - pym/cl_ldap.py | 207 +++++----- pym/cl_profile.py | 923 ------------------------------------------ pym/cl_xml.py | 1 - 5 files changed, 103 insertions(+), 1034 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index ef77ec7..a99f440 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -23,17 +23,13 @@ import re import copy import types import string -#import os import filecmp # import ConfigParser import time import socket -#import sys import random import string -# from . import cl_utils import cl_utils -# from .cl_xml import firstChild from cl_xml import firstChild import importlib ############################################################################## diff --git a/pym/cl_fill_server.py b/pym/cl_fill_server.py index ca15a07..fb2c35b 100644 --- a/pym/cl_fill_server.py +++ b/pym/cl_fill_server.py @@ -15,8 +15,6 @@ # limitations under the License. import os -# from . import cl_base -# from . import cl_utils import cl_base import cl_utils import hashlib diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 4e56826..22d29a2 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -16,13 +16,8 @@ import os import sys import re import ldap -# import cStringIO, StringIO from io import StringIO, BytesIO from ldif import LDIFParser, LDIFWriter -# from . import cl_base -# from . import cl_profile -# from . import cl_utils2 -# from . import cl_utils import cl_base import cl_profile import cl_utils2 @@ -44,9 +39,7 @@ import tempfile # Вывод в строку ввода import readline # Пути в XML документе -# from xml import xpath -# from .cl_xml import xpath, firstChild -from cl_xml import xpath, firstChild +from cl_xml import xpath, firstChild, xml_to_str # Для 32 битного целого (генерация серийного номера DNS зоны) import ctypes from functools import reduce @@ -645,8 +638,8 @@ in a sambaDomainName', if strUid: delBackDir =\ os.path.join(self.clVars.Get("sr_deleted_path"), - "%s-%s"%(userName,strUid), - service) + "%s-%s"%(userName,strUid), + service) if os.path.exists(delBackDir) and os.listdir(delBackDir): self.printERROR(_("Found deleted user data dir %s")\ %delBackDir) @@ -656,15 +649,15 @@ in a sambaDomainName', else: delBackDir =\ os.path.join(self.clVars.Get("sr_deleted_path"), - "%s"%(userName), - service) + "%s"%(userName), + service) i = 0 while os.path.exists(delBackDir): i += 1 delBackDir =\ os.path.join(self.clVars.Get("sr_deleted_path"), - "%s_%s"%(userName,i), - service) + "%s_%s"%(userName, i), + service) # Cоздаем директорию хранения удаленных пользователей if not os.path.exists(self.clVars.Get("sr_deleted_path")): os.makedirs(self.clVars.Get("sr_deleted_path")) @@ -673,10 +666,10 @@ in a sambaDomainName', self.copyDir(delBackDir,srcDir) except: self.printERROR(_("Can not copy deleted user data in dir %s")\ - %delBackDir) + % delBackDir) return False self.printSUCCESS(_("Created deleted user data dir %s")\ - %delBackDir) + % delBackDir) return True def dataIsJpeg(self, bytes): @@ -813,7 +806,7 @@ in a sambaDomainName', if not service in self.servicesDaemons.keys(): self.printERROR(_("Not supported service '%s'")%service) self.printERROR(\ - _("Can not deleted service from default runlevel")) + _("Can not deleted service from default runlevel")) flagError = True break for daemon in self.servicesDaemons[service]: @@ -842,12 +835,12 @@ in a sambaDomainName', prnService = self.printNameService(service) if flagError: self.printNotOK(_("Starting") + " " + prnService + " " +\ - _("service") + " ...") + _("service") + " ...") return False else: if printSuccess: self.printOK(_("Starting") + " " + prnService + " "+\ - _("service") + " ...") + _("service") + " ...") return True def startServices(self, servInstalled, printSuccess=True): @@ -912,7 +905,7 @@ in a sambaDomainName', ret = self.execProg("/etc/init.d/%s stop"%daemon) if ret == False: self.printERROR(servicePrn + " " +\ - _("service is not stopped")) + _("service is not stopped")) flagError = True break # Удаляем процессы ejabberd @@ -1042,11 +1035,11 @@ in a sambaDomainName', runDaemons['postfix'] = False continue addDirDict = {"slapd":("openldap","slapd.pid"), - "dovecot":("dovecot","master.pid"), - "proftpd":("","proftpd.pid"), - "squid":("","squid.pid"), - "calculate-profile":("","calculate-profile.pid"), - "sortmilter":("","sortmilter.pid")} + "dovecot":("dovecot","master.pid"), + "proftpd":("","proftpd.pid"), + "squid":("","squid.pid"), + "calculate-profile":("","calculate-profile.pid"), + "sortmilter":("","sortmilter.pid")} baselayoutDir = "/var/lib/init.d/daemons" if not flagBaselayoutDir: if os.path.exists(baselayoutDir): @@ -1084,7 +1077,7 @@ in a sambaDomainName', """Хеш пароля используя slappasswd""" if not crypt: self.printERROR(_("ERROR") + " getHashPasswd: " +\ - _("crypto algoritm empty")) + _("crypto algoritm empty")) return False cryptStr = "{%s}" % crypt.upper() lenCryptStr = len(cryptStr) @@ -1094,7 +1087,7 @@ in a sambaDomainName', pwdHash[:lenCryptStr] == cryptStr: return pwdHash self.printERROR(_("ERROR") + " getHashPasswd: " +\ - _("create crypto password")) + _("create crypto password")) return False def getRunService(self, nameService, printError=False): @@ -1111,7 +1104,7 @@ in a sambaDomainName', if flagError: if printError: self.printERROR(self.printNameService(nameService) + " " +\ - _("service is not started")) + _("service is not started")) return False return True @@ -1144,10 +1137,10 @@ in a sambaDomainName', return False flagError = False pipe = subprocess.Popen("convert '%s' jpg:-" %photoPath, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, close_fds=True, - shell=True) + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, close_fds=True, + shell=True) fOut, fIn, fErr = (pipe.stdout, pipe.stdin, pipe.stderr) fIn.close() # Код возврата @@ -11505,10 +11498,10 @@ service") for pkg in pkgs: category,package = pkg.split('/') catDir = os.path.join(pkgDir,category) - package = "%s-"%package + package = "%s-" % package if not (os.path.exists(catDir) and [x for x in os.listdir(catDir) if x.startswith(package)]): - self.printERROR(_("Package '%s' is not installed")%pkg) + self.printERROR(_("Package '%s' is not installed") % pkg) return False return True @@ -13604,7 +13597,6 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) .calculate.env в домашней директории пользователя """ - #TODO debug this varsData = ("unix_hash", "samba_lm_hash", "samba_nt_hash", "samba_nt_hash_old") if not set(varsData) <= set(varsDict.keys()): @@ -13671,7 +13663,6 @@ remove user %s in the LDAP branch 'Worked'")%str(userName)) ("sambaLMPassword",userLMHash), ("sambaNTPassword",userNTHash)] resSambaAttr = resSamba[0][0][1] - #TODO debug for attr, value in data: if attr in resSambaAttr: modAttrs.append((ldap.MOD_REPLACE, attr, value)) @@ -15086,9 +15077,8 @@ with another option.")) # Добавляем директорию хранения писем для сервиса mail if service == "mail": for i in searchRes: - #TODO maybe will have to remove decoding i[0][1]['homeDirectory'] = [os.path.join(\ - clVars.Get("sr_mail_path"), i[0][1]['uid'][0].decode("UTF-8"))] + clVars.Get("sr_mail_path").encode("UTF-8"), i[0][1]['uid'][0])] data.append((_("Home directory"),"homeDirectory")) # Добавляем директории пользователя для сервиса samba # а так же первичную и дополнительные группы @@ -16808,14 +16798,16 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): elif delNodesNext and len(delNodesNext)==1: delNodesNext.pop() delNodes = delNodesPrev + delNodesNext - # Удаляем переводы строк - [xmlNodeBody.remove(x) for x in delNodes] - # Удаляем области - for term in (xmlNodeBody.remove(x) for x in deletesNodes): - if not term: - self.setError(_('Can not remove static host "%s"')%hostname+\ - " " + _("in config file %s")%self.nameConfigFile) - return False + try: + # Удаляем переводы строк + [xmlNodeBody.remove(x) for x in delNodes] + # Удаляем области + [xmlNodeBody.remove(x) for x in deletesNodes] + except Exception as e: + self.setError(_('Can not remove static host "%s"') % hostname +\ + " " + _("in config file %s") % self.nameConfigFile+\ + f"\n{str(e)}") + return False # Запись файла text = self.getConfig() return self.writeInConfig(text) @@ -16862,14 +16854,16 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): elif delNodesNext and len(delNodesNext)==1: delNodesNext.pop() delNodes = delNodesPrev + delNodesNext - # Удаляем переводы строк - [xmlNodeBody.remove(x) for x in delNodes] - # Удаляем области - for term in (xmlNodeBody.remove(x) for x in deletesNodes): - if not term: - self.setError(_('Can not remove subnet "%s"')%net+\ - " " + _("in config file %s")%self.nameConfigFile) - return False + try: + # Удаляем переводы строк + [xmlNodeBody.remove(x) for x in delNodes] + # Удаляем области + [xmlNodeBody.remove(x) for x in deletesNodes] + except Exception as e: + self.setError(_('Can not remove subnet "%s"')%net +\ + " " + _("in config file %s")%self.nameConfigFile +\ + f"\n{str(e)}") + return False # Запись файла text = self.getConfig() return self.writeInConfig(text) @@ -16994,37 +16988,40 @@ class dnsTxt(cl_profile.bind,shareTxt): for node in deletesNodes: nNode = node nNode = nextNode(nNode) - while nNode and self.docObj.getTypeField(nNode)=="br": + while nNode is not None and self.docObj.getTypeField(nNode) == "br": delNodesNext.append(nNode) nNode = nextNode(nNode) pNode = node pNode = prevNode(pNode) - while pNode and self.docObj.getTypeField(pNode)=="br": + while pNode is not None and self.docObj.getTypeField(pNode) == "br": delNodesPrev.append(pNode) pNode = prevNode(pNode) # Оставляем два перевода строки сверху - if delNodesPrev and len(delNodesPrev)>=2: + if delNodesPrev and len(delNodesPrev) >= 2: delNodesPrev.pop() delNodesPrev.pop() - elif delNodesNext and len(delNodesNext)>=2: + elif delNodesNext and len(delNodesNext) >= 2: delNodesNext.pop() delNodesNext.pop() - elif delNodesPrev and len(delNodesPrev)==1: + elif delNodesPrev and len(delNodesPrev) == 1: delNodesPrev.pop() - if delNodesNext and len(delNodesNext)==1: + if delNodesNext and len(delNodesNext) == 1: delNodesNext.pop() - elif delNodesNext and len(delNodesNext)==1: + elif delNodesNext and len(delNodesNext) == 1: delNodesNext.pop() delNodes = delNodesPrev + delNodesNext - # Удаляем переводы строк - [xmlNodeBody.remove(x) for x in delNodes] - # Удаляем области - for term in [xmlNodeBody.remove(x) for x in deletesNodes]: - if not term: - self.setError(_('Can not remove DNS zone "%s"')%zoneName+\ - " " + _("in config file %s")%self.nameConfigFile) - return False + try: + + # Удаляем переводы строк + [xmlNodeBody.remove(x) for x in delNodes] + # Удаляем области + [xmlNodeBody.remove(x) for x in deletesNodes] + except Exception as e: + self.setError(_('Can not remove DNS zone "%s"')%zoneName+\ + " " + _("in config file %s")%self.nameConfigFile+\ + f"\n{str(e)}") + return False # Запись файла text = self.getConfig() return self.writeInConfig(text) @@ -17096,13 +17093,15 @@ class dnsTxt(cl_profile.bind,shareTxt): [xmlNodeBody.remove(x) for x in delNodes] # Удаляем области for delNode, zoneName in deletesNodes: - if xmlNodeBody.remove(delNode): + try: + xmlNodeBody.remove(delNode) # Печатаем сообщение о успешном удалении зоны if flagPrintSuccess: functPrintSuccess(zoneName) - else: + except Exception as e: self.setError(_('Can not remove DNS zone "%s"')%zoneName+\ - " " + _("in config file %s")%self.nameConfigFile) + " " + _("in config file %s")%self.nameConfigFile +\ + f"\n{str(e)}") return False # Запись файла text = self.getConfig() @@ -17550,7 +17549,7 @@ class servDns(shareLdap): return False # Добавление точки если необходимо в каждое имя DNS сервера # Имена авторитативных DNS серверов для зоны - namesServersDot = [addDot(x) for x in namesServers] + namesServersDot = [addDot(x).encode("UTF-8") for x in namesServers] # Получение текста sOA записи sOARecord = " ".join([nameServerDot,emailAddrDot,serialNumber] +\ sOATimeParams) @@ -17576,24 +17575,24 @@ class servDns(shareLdap): # прямая зона zoneBaseDN = "zoneName=%s,%s,%s" %(zoneName, self.relFwdDN, baseDN) - zoneBaseEntry = [('objectclass', ['top','dNSZone']), - ('relativeDomainName', [zoneName]), - ('zoneName',[zoneName])] + zoneBaseEntry = [('objectclass', [b'top', b'dNSZone']), + ('relativeDomainName', [zoneName.encode("UTF-8")]), + ('zoneName',[zoneName.encode("UTF-8")])] zoneBaseErrorMessage = _("Can not add in LDAP DNS zone %s") %zoneName if not self.addEntry(zoneBaseDN, zoneBaseEntry, zoneBaseErrorMessage): return False zoneDomainDN = self.addDN("relativeDomainName=@",zoneBaseDN) zoneDomainErrorMessage = _("Can not add SOA-record in zone %s")%zoneName - zoneDomainEntry = [('objectclass', ['top','dNSZone']), - ('relativeDomainName', ["@"]), - ('zoneName',[zoneName]), - ('sOARecord',[sOARecord]), - ('nSRecord',namesServersDot)] + zoneDomainEntry = [('objectclass', [b'top', b'dNSZone']), + ('relativeDomainName', [b"@"]), + ('zoneName', [zoneName.encode("UTF-8")]), + ('sOARecord', [sOARecord.encode("UTF-8")]), + ('nSRecord', namesServersDot)] if ip: - zoneDomainEntry += [('aRecord',ip)] + zoneDomainEntry += [('aRecord', ip.encode("UTF-8"))] if mxList: - mxListDot = [addDot(x) for x in mxList] - mxValues = ["%s %s" % (x * 10 + 10, mxListDot[x]) + mxListDot = [addDot(x).encode("UTF-8") for x in mxList] + mxValues = [b"%s %s" % (x * 10 + 10, mxListDot[x]) for x in range(len(mxListDot))] zoneDomainEntry += [('mXRecord', mxValues)] if not self.addEntry(zoneDomainDN, zoneDomainEntry, @@ -19481,7 +19480,7 @@ is incompatible with option "--ip"') data = foundOld[0][0][1] data["zoneName"] = [newZoneName] data["relativeDomainName"] = [newHostName] - domainEntry = data.items() + domainEntry = [x.encode("UTF-8") for x in data.items()] # Добавляем новую запись baseDN = self.clVars.Get("ld_dns_dn") ouZonesDN = self.getOUZonesDN(newZoneName) @@ -19672,7 +19671,7 @@ with type DNS record PTR (option "-t")')) return False # Поиск зоны if not self.searchZoneInLDAP(zoneName): - self.printERROR(_("Can not found DNS zone %s in LDAP")%zoneName) + self.printERROR(_("Can not found DNS zone %s in LDAP") % zoneName) return False # Поиск CNAME записи findCName = self.searchCNameInLDAP(domainName) @@ -19686,18 +19685,18 @@ with type DNS record PTR (option "-t")')) return False # Метод добавляющий в конце текста точку если ее нет addDot = lambda x: (len(x)>0 and x[-1]!="." and "%s."%x) or x - domainEntry = [('objectclass', ['top','dNSZone']), - ('relativeDomainName', [hostName]), - ('dNSClass', ['IN']), - ('zoneName',[zoneName]), - ('cNAMERecord',[addDot(cnDomainName)])] + domainEntry = [('objectclass', [b'top', b'dNSZone']), + ('relativeDomainName', [hostName.encode("UTF-8")]), + ('dNSClass', [b'IN']), + ('zoneName', [zoneName.encode("UTF-8")]), + ('cNAMERecord', [addDot(cnDomainName).encode("UTF-8")])] baseDN = self.clVars.Get("ld_dns_dn") ouZonesDN = self.getOUZonesDN(zoneName) zoneBaseDN = "zoneName=%s,%s,%s" %(zoneName, ouZonesDN, baseDN) domainDN = self.addDN("relativeDomainName=%s"%hostName,zoneBaseDN) errorMessage = _("Can not add CNAME-record in LDAP") # Добавляем запись для хоста - if not self.addEntry(domainDN, domainEntry,errorMessage): + if not self.addEntry(domainDN, domainEntry, errorMessage): return False # Увеличиваем на 1 серийный номер зоны if not self.incrementSerialNumberZone(zoneName): @@ -19777,22 +19776,22 @@ with type DNS record PTR (option "-t")')) # Проверка существования A записей для MX хостов if not self.checkMXDomains(namesMailServers): return False - namesMailServersDot = [addDot(x) for x in namesMailServers] - domainEntry = [('objectclass', ['top','dNSZone']), - ('relativeDomainName', [hostName]), - ('dNSClass', ['IN']), - ('zoneName',[zoneName]), - ('aRecord',[ipAddrOrHost])] - mxValues= ["%s %s" % (x * 10 + 10, namesMailServersDot[x]) + namesMailServersDot = [addDot(x).encode("UTF-8") for x in namesMailServers] + domainEntry = [('objectclass', [b'top', b'dNSZone']), + ('relativeDomainName', [hostName.encode("UTF-8")]), + ('dNSClass', [b'IN']), + ('zoneName',[zoneName.encode("UTF-8")]), + ('aRecord',[ipAddrOrHost.encode("UTF-8")])] + mxValues = [b"%s %s" % (x * 10 + 10, namesMailServersDot[x]) for x in range(len(namesMailServersDot))] if mxValues: # Добавляем MX записи domainEntry.append(('mXRecord', mxValues)) else: - domainEntry = [('objectclass', ['top','dNSZone']), - ('relativeDomainName', [hostName]), - ('zoneName',[zoneName]), - ('pTRRecord',[addDot(ipAddrOrHost)])] + domainEntry = [('objectclass', [b'top', b'dNSZone']), + ('relativeDomainName', [hostName.encode("UTF-8")]), + ('zoneName',[zoneName.encode("UTF-8")]), + ('pTRRecord',[addDot(ipAddrOrHost).encode("UTF-8")])] baseDN = self.clVars.Get("ld_dns_dn") ouZonesDN = self.getOUZonesDN(zoneName) zoneBaseDN = "zoneName=%s,%s,%s" %(zoneName, ouZonesDN, baseDN) @@ -19802,7 +19801,7 @@ with type DNS record PTR (option "-t")')) else: errorMessage = _("Can not add PTR-record in LDAP") # Добавляем запись для хоста - if not self.addEntry(domainDN, domainEntry,errorMessage): + if not self.addEntry(domainDN, domainEntry, errorMessage): return False # Увеличиваем на 1 серийный номер зоны if not self.incrementSerialNumberZone(zoneName): diff --git a/pym/cl_profile.py b/pym/cl_profile.py index 0631240..7985f78 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -17,18 +17,9 @@ import sys import os import cl_base -# from . import cl_base import stat import re -# import xml.dom.minidom -# import xml - -# if hasattr(xml,"use_pyxml"): -# xml.use_pyxml() -# from xml import xpath import cl_xml -# from . import cl_xml -# from .cl_xml import xpath, firstChild,\ from cl_xml import xpath, firstChild,\ insertBefore, str_to_xml_doc, xml_to_str, xmlShare,\ xmlNode, xmlField, xmlFields, xmlArea, xmlDoc @@ -718,920 +709,6 @@ class xmlCaption: """Выдает XML ноду заголовка области""" return self.caption -# class xmlField(xmlShare): -# """Класс для работы с XML полем - -# """ -# def __init__(self): -# # XML нода поле -# self.field = False - - -# def createField(self, doc, typeField, quotes, name="", -# values=[],action=False): -# """Cоздание XML ноды поле""" -# self.field = self._createElement(doc, "field", "", {"type":typeField}) -# if name: -# nameNode = self._createElement(doc, "name", name) -# self.field.append(nameNode) -# for v in values: -# valueNode = self._createElement(doc, "value", v) -# self.field.append(valueNode) -# if action: -# actNode = self._createElement(doc, "action", action) -# self.field.append(actNode) -# for q in quotes: -# quoteNode = self._createElement(doc, "quote", q) -# self.field.append(quoteNode) -# return self.field - - - -# class xmlFields: -# """Класс, в котором находится список ХМL нод field - -# """ -# def __init__(self): -# self.fields = [] - -# def appendField(self, field): -# """Добавить XML ноду field""" -# self.fields.append(field) -# return self.fields - -# def getFields(self): -# """Выдать список XML нод""" -# return self.fields - - -# class xmlArea: -# """Класс для работы с XML областью - -# """ -# def __init__(self): -# # Область -# self.area = False - -# def createArea(self, doc, xmlCaption, xmlFields): -# """Создание XML области""" -# tmpNode = xmlNode() -# self.area = tmpNode.createNode(doc, "area") -# if xmlCaption and xmlCaption.getCaption(): -# self.area.append(xmlCaption.getCaption()) -# if xmlFields: -# fields = xmlFields.getFields() -# for field in fields: -# self.area.append(field) -# return self.area - -# class xmlDoc: -# """Класс для работы с XML документом - -# """ -# def __init__(self): -# # документ -# self.doc = False -# # главная нода -# self.root = False -# # тело документа -# self.body = False -# # Заголовок области - временный (в реальности один объект заголовок) -# self.tmpCaption = False -# # Поля - временные (в реальности один объект поля) -# self.tmpFields = False -# # Разделитель областей - по умолчанию перевод строки "\n" -# self.sepAreas = False -# # Разделитель разделенных списков - по умолчанию перевод строки "\n" -# #self.sepSplitFields = False - - -# def createDoc(self, typeDoc, version): -# """Создание нового документа новый документ""" -# docTxt = '' -# docTxt += '%s'% version -# docTxt += '%s' % typeDoc -# docTxt += '' -# self.doc = xml.dom.minidom.parseString(docTxt) -# self.root = self.doc.documentElement -# self.body = xpath.Evaluate('child::body',self.root)[0] -# # установка разделителя областей -# self.sepAreas = self.createField("br",[],"",[],False,False) -# # установка разделителя областей разделенных списков -# #self.sepSplitFields = self.createField("br",[],"",[],False,False) -# return self.doc - -# def addField(self, field): -# """Добавляет поле во временный список - -# Из этого списка в дальнейшем формируется XML область -# """ -# if not self.tmpFields: -# self.tmpFields = xmlFields() -# self.tmpFields.appendField(field) - -# def createCaption(self, name, quotes, action=False): -# """Cоздает заголовок области - -# Помещает заголовок в временный артибут -# Используется при создании области -# """ -# self.tmpCaption = xmlCaption() -# return self.tmpCaption.createCaption(self.doc, name, quotes, action) - -# def createField(self, typeField, quotes=[], name="", -# values=[] ,action=False,addTmpField=True): -# """Cоздает поле - -# Если установлена переменнная addTmpField -# добавляет поле во временный список -# """ -# fieldObj = xmlField() -# field = fieldObj.createField(self.doc, typeField, quotes, name, -# values, action) -# if addTmpField: -# self.addField(field) -# return field - -# def clearTmpFields(self): -# """Очищает временный список""" -# self.tmpFields = False - -# def createArea(self): -# """Cоздает область - -# Область создается на основании временного атрибута и временного списка -# """ -# areaObj = xmlArea() -# area = areaObj.createArea(self.doc, self.tmpCaption, self.tmpFields) -# self.clearTmpCaptionAndFields() -# return area - -# def clearTmpCaptionAndFields(self): -# """Очищает временный аттрибут и временный список""" -# self.tmpCaption = False -# self.tmpFields = False - -# def getNodeRoot(self): -# """Выдает корневую ноду""" -# return self.root - -# def getNodeBody(self): -# """Выдает ноду body""" -# return self.body - -# def setActionField(self, xmlField, actionTxt): -# """Устанавливает свойство action для XML поля""" -# xmlActions = xpath.Evaluate('child::action',xmlField) -# if xmlActions is not None and firstChild(xmlActions[0]): -# firstChild(xmlActions[0]).text = actionTxt -# else: -# nodeObj = xmlNode() -# newNode = nodeObj.createNode(self.doc, "action", actionTxt) -# xmlField.append(newNode) - - -# def setActionArea(self, xmlArea, actionTxt): -# """Устанавливает свойство action для XML области""" -# xmlActions = xpath.Evaluate('child::caption/action',xmlArea) -# xmlCaptions = xpath.Evaluate('child::caption',xmlArea) -# if xmlActions is not None and firstChild(xmlActions[0]): -# firstChild(xmlActions[0]).text = actionTxt -# else: -# if xmlCaptions: -# nodeObj = xmlNode() -# newNode = nodeObj.createNode(self.doc, "action", actionTxt) -# xmlCaptions[0].append(newNode) - -# def joinField(self, xmlArea, xmlNewField): -# """Объединяет XML ноду область и XML ноду поле""" -# newNameField = self.getNameField(xmlNewField) -# if not newNameField or not newNameField.strip(): -# return False -# fieldsOldComp = xpath.Evaluate("child::field[child::name='%s']"\ -# %(newNameField), xmlArea) -# # Если поле не найдено добавляем его -# typeNewField = self.getTypeField(xmlNewField) -# if not fieldsOldComp and typeNewField != "seplist": -# if self.getActionField(xmlNewField) != "drop": -# self.setActionField(xmlNewField, "append") -# xmlArea.append(xmlNewField) -# return True -# newFieldsAction = self.getActionField(xmlNewField) -# newValues = self.getFieldValues(xmlNewField) -# flagCompare = True - -# for nodeFieldOld in fieldsOldComp: -# if newFieldsAction == "drop": -# if nodeFieldOld.getnext() and\ -# self.getTypeField(nodeFieldOld.getnext()) == "br": -# xmlArea.remove(nodeFieldOld.getnext()) -# elif nodeFieldOld.getprevious() and\ -# self.getTypeField(nodeFieldOld.getprevious()) == "br": -# xmlArea.remove(nodeFieldOld.getprevious()) -# xmlArea.remove(nodeFieldOld) -# continue -# oldValues = self.getFieldValues(nodeFieldOld) -# # Сравнение значений переменной профиля и файла -# if set(newValues) != set(oldValues): -# flagCompare = False -# if self.getActionField(xmlNewField) == "drop": -# return True -# appSplLst = [] -# insSplLst = [] -# if typeNewField == "seplist": -# if fieldsOldComp: -# xmlOldField = fieldsOldComp[-1] -# else: -# xmlOldField = False -# seplistNewXML = self.getSepListToField(xmlNewField) -# if seplistNewXML: -# for nodeSeplist in seplistNewXML: -# if self.getActionField(nodeSeplist) != "drop": -# if newFieldsAction == "join": -# flagCompareSeplist = False -# newValues = self.getFieldValues(nodeSeplist) -# for nodeFieldOld in fieldsOldComp: -# oldValues = self.getFieldValues(nodeFieldOld) -# for newValue in newValues: -# if newValue in oldValues: -# flagCompareSeplist = True -# break -# if not flagCompareSeplist: -# nextNode = xmlOldField.getnext() -# newInsNode = deepcopy(nodeSeplist) -# self.setActionField(newInsNode,"append") - -# if nextNode: -# appSplLst.append((newInsNode, -# nextNode, -# "insert")) -# else: -# appSplLst.append((newInsNode, -# False, -# "append")) -# else: -# newInsNode = deepcopy(nodeSeplist) -# if self.getActionField(newInsNode) == "join": -# self.setActionField(newInsNode,"append") -# if xmlOldField: -# insSplLst.append((newInsNode, -# xmlOldField, -# "insert")) -# else: -# insSplLst.append((newInsNode, -# False, -# "append")) - -# #xmlArea.insertBefore(\ -# #nodeSeplist.cloneNode(True), -# #xmlOldField) - -# parentNode = nodeSeplist.getparent() -# parentNode.remove(nodeSeplist) - -# insNodesRepl = [] -# for newNode, nxtNode, app in insSplLst: -# flagCompareSeplist = False -# newValues = self.getFieldValues(newNode) -# for nodeRepl, nxtNode, app in insNodesRepl: -# oldValues = self.getFieldValues(nodeRepl) -# for newValue in newValues: -# if newValue in oldValues: -# flagCompareSeplist = True -# break -# if not flagCompareSeplist: -# if xmlOldField is not None: -# insNodesRepl.append((newNode, nxtNode, app)) - -# for newNode, nxtNode, app in insNodesRepl: -# if app == "insert": -# insertBefore(xmlArea, newNode, nxtNode) -# elif app == "append": -# xmlArea.append(newNode) -# if xmlOldField: -# parentNode = xmlOldField.getparent() -# if parentNode and newFieldsAction != "join": -# parentNode.remove(xmlOldField) - -# for newNode, nxtNode, app in appSplLst: -# if app == "insert": -# insertBefore(xmlArea, newNode, nxtNode) -# elif app == "append": -# xmlArea.append(newNode) - -# if not flagCompare and typeNewField != "seplist": -# # Устанавливаем action=replace -# self.setActionField(xmlNewField, "replace") -# # Если параметры поля не сходятся заменяем поле -# xmlArea.replace(fieldsOldComp[-1], deepcopy(xmlNewField)) - -# if newFieldsAction == "join": -# fieldsOldRemove = [] -# else: -# fieldsOldRemove = fieldsOldComp[:-1] - -# for nodeFieldOld in fieldsOldRemove: -# actionOldNode = self.getActionField(nodeFieldOld) -# if actionOldNode == "insert" or actionOldNode == "append": -# pass -# else: -# if nodeFieldOld.getnext() and\ -# self.getTypeField(nodeFieldOld.getnext()) == "br": -# xmlArea.remove(nodeFieldOld.getnext()) -# xmlArea.remove(nodeFieldOld) -# return True - - -# def getSepListToField(self, xmlField): -# """Выдает элементы распределенного массива - -# Область предок поля, в этой области ищутся -# элементы распределенного массива -# """ -# nameField = self.getNameField(xmlField) -# if not nameField: -# return [] -# parentNode = xmlField.getparent() -# #print parentNode.toprettyxml() -# if parentNode is not None: -# fieldsVal = xpath.Evaluate(\ -# "child::field[attribute::type='seplist'][child::name='%s'] "\ -# %(nameField), parentNode) -# #print nameField -# return fieldsVal -# else: -# return [] - -# def removeComment(self, xmlArea): -# """Удаляет комментарии в XML области""" -# fieldNodes = xpath.Evaluate('descendant::field',xmlArea) -# for fieldNode in fieldNodes: -# if "type" in fieldNode.keys(): -# if fieldNode.get("type") == "comment" or\ -# fieldNode.get("type") == "br": -# parentNode = fieldNode.getparent() -# parentNode.remove(fieldNode) -# else: -# if self.getActionField(fieldNode) == "drop": -# pass -# elif self.getActionField(fieldNode) == "join": -# pass -# else: -# self.setActionField(fieldNode,"append") - - -# def joinBody(self, baseBody, newBody): -# """Объединяет две области Body""" -# newFields = xpath.Evaluate('child::field',newBody) -# xmlNewAreas = xpath.Evaluate('child::area',newBody) -# for xmlNewArea in xmlNewAreas: -# self.joinArea(baseBody,xmlNewArea) -# joinNewFields = xpath.Evaluate("child::field[child::action='join']" -# ,newBody) -# self.addNewFielsOldArea(newFields, joinNewFields, baseBody) - - -# def getRemoveNodeSepList(self, removeNodesDict, baseNode, xmNewlField): -# """Находит элементы разделенного списка - -# Параметры: -# removeNodesDict - Cловарь удаляемых полей разделенного списка -# формируется программой -# baseNode - Нода в которой идет поиск -# xmNewlField - Нода field которая проверяется на принадлежность -# к разделенному списку -# """ -# flagNewNodeSeplist = False -# if self.getTypeField(xmNewlField) == "seplist": -# flagNewNodeSeplist = True -# nameNewField = self.getNameField(xmNewlField) -# if nameNewField: -# if nameNewField in removeNodesDict: -# return removeNodesDict[nameNewField] -# else: -# oldFields = xpath.Evaluate('child::field', baseNode) -# removeNodes = [] -# lenOldFields = len(oldFields) -# for i in range(lenOldFields): -# oldNode = oldFields[i] -# flagSep = self.getTypeField(oldNode) == "seplist" -# if flagNewNodeSeplist: -# flagSep = True -# if flagSep and\ -# nameNewField == self.getNameField(oldNode): -# removeNodes.append(oldNode) -# if i+1 1: -# for node in listNodes: -# node.set("type", "seplist") - -# def insertBRtoBody(self, xmlArea): -# """Добавляет необходимые переводы строк -# """ -# # Потомки -# childNodes = self.getFieldsArea(xmlArea) -# # нода BR -# fieldXMLBr = self.createField("br",[],"",[],False, False) -# # разделитель поля -# fieldSplit = False -# # Предыдущая нода -# lastNode = False -# # Cледующая нода -# nextNode = False -# lenChildNodes = len(childNodes) -# for i in range(lenChildNodes): -# node = childNodes[i] -# lastTmpNode = node -# # Нода area -# if node.tag == "area": -# if self.getActionArea(node) == "append" or\ -# self.getActionArea(node) == "join": -# self.delActionNodeArea(node) -# if lastNode and "type" in lastNode.keys() and\ -# lastNode.get("type") == "br" or\ -# lastNode and "type" in lastNode.keys() and\ -# lastNode.get("type") == "comment": -# indNext = i + 1 -# if indNext == lenChildNodes: -# xmlArea.append(deepcopy(fieldXMLBr)) -# else: -# nextNode = childNodes[indNext] -# lastTmpNode = insertBefore(xmlArea, deepcopy(fieldXMLBr), -# nextNode) -# else: -# insertBefore(xmlArea, deepcopy(fieldXMLBr), -# node) -# self.insertBRtoBody(node) -# # Нода field -# else: -# if self.getActionField(node) == "append" or\ -# self.getActionField(node) == "join": -# self.delActionNodeField(node) -# if lastNode and "type" in lastNode.keys() and\ -# lastNode.get("type") == "br" or\ -# lastNode and "type" in lastNode.keys() and\ -# lastNode.get("type") == "comment": -# indNext = i + 1 -# if indNext == lenChildNodes: -# xmlArea.append(deepcopy(fieldXMLBr)) -# else: -# nextNode = childNodes[indNext] -# lastTmpNode = insertBefore(xmlArea, -# deepcopy(fieldXMLBr), -# nextNode) -# else: -# insertBefore(xmlArea, deepcopy(fieldXMLBr), -# node) -# lastNode = lastTmpNode - - - -# def postParserList(self): -# """Находит подходящие XML области и делаем из них поля-массивы""" -# xmlAreas = xpath.Evaluate('descendant::area', self.body) -# for xmlArea in xmlAreas: -# flagListXml = True -# fieldValues = [] -# xmlFields = xpath.Evaluate('child::field',xmlArea) -# if not xmlFields: -# flagListXml = False -# lenXmlFields = len(xmlFields) -# lenBrArea = 0 -# for xmlField in xmlFields: -# xmlNames = xpath.Evaluate('child::name',xmlField) -# xmlVals = xpath.Evaluate('child::value',xmlField) -# if "type" in xmlField.keys() and\ -# xmlField.get("type") == "br": -# lenBrArea += 1 -# continue -# if not xmlNames and not xmlVals: -# flagListXml = False -# break -# if xmlNames and firstChild(xmlNames[0]) is not None and\ -# firstChild(xmlNames[0]).text: -# flagListXml = False -# break -# if not (xmlVals and firstChild(xmlVals[0]) is not None and\ -# firstChild(xmlVals[0]).text): -# flagListXml = False -# break -# else: -# fieldValues.append(firstChild(xmlVals[0]).text) - -# if lenXmlFields == lenBrArea: -# flagListXml = False -# if flagListXml: -# nameNode = xpath.Evaluate('child::caption/name',xmlArea)[0] -# fieldName = "" -# if firstChild(nameNode) is not None: -# fieldName = firstChild(nameNode).text -# listArea = [] -# self.xmlToText([xmlArea],listArea) -# fieldQuote = "".join(listArea) -# fieldXMLBr = False -# if fieldQuote and fieldQuote[-1] == "\n": -# fieldQuote = fieldQuote[:-1] -# fieldXMLBr = self.createField("br",[],"",[],False, False) -# fieldXML = self.createField("list", -# [fieldQuote], -# fieldName, fieldValues, -# False, False) -# areaAction = self.getActionArea(xmlArea) -# if areaAction: -# self.setActionField(fieldXML, areaAction) -# parentNode = xmlArea.getparent() -# insertBefore(parentNode, fieldXML, xmlArea) -# if fieldXMLBr: -# insertBefore(parentNode, fieldXMLBr, xmlArea) -# parentNode.remove(xmlArea) - - class blocText: """Разбиваем текст на блоки""" diff --git a/pym/cl_xml.py b/pym/cl_xml.py index 146849b..fe40a49 100644 --- a/pym/cl_xml.py +++ b/pym/cl_xml.py @@ -15,7 +15,6 @@ # limitations under the License. -# import lxml from lxml import etree as ET from copy import deepcopy From 222aff7f24f5de28feedcbc664eef4cf5f5541ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Tue, 7 Sep 2021 18:01:11 +0300 Subject: [PATCH 17/24] encoding fixes in dns --- pym/cl_ldap.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 22d29a2..d48116b 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -11063,6 +11063,7 @@ example: --range 192.168.0.2,192.168.0.50') 'help':_("password for distinguished name (dn) - service DNS from \ file") }, + #{'progAccess':(0,1,2,4,5,6), #'shortOption':"s", #'longOption':"set", @@ -14497,7 +14498,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): title=_("Information about the slave DNS zones in \ /etc/bind/named.conf") headerList = [_("DNS zone"),_("IP master DNS servers")] - dataList = ([x] for x in forwardZones + reverseZones) + dataList = [[x] for x in forwardZones + reverseZones] dataList = [dataList[x] + [slaveIPs[x]] for x in range(len(dataList))] repObj = report(title, headerList, dataList) print("") @@ -14785,7 +14786,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): self.printERROR(_("IP address %s incorrectly")%ip) return False hostNamePTR, domainNamePTR, zoneNamePTR = dataIP - dataRecords=servDnsObj.searchAllDomainNamesInLDAP(domainNamePTR) + dataRecords = servDnsObj.searchAllDomainNamesInLDAP(domainNamePTR) if not dataRecords: self.printERROR(_("Record %s not exists in LDAP")\ %domainNamePTR) @@ -17261,6 +17262,7 @@ class servDns(shareLdap): """Находим DNS зону в LDAP""" relZonesDN = self.getRelZonesDN(zoneName) resSearch = self.searchLdapDN(zoneName, relZonesDN, "zoneName") + #returns encoded bytes list return resSearch def searchAllZonesInLDAP(self): @@ -17269,7 +17271,7 @@ class servDns(shareLdap): ["zoneName"]) resSearchRev = self.searchLdapDN('*', self.relReverseDN, "zoneName", ["zoneName"]) - return [x[0][1]['zoneName'][0] for x in resSearchFwd + resSearchRev] + return [x[0][1]['zoneName'][0].decode("UTF-8") for x in resSearchFwd + resSearchRev] def searchAllRecordInZone(self, zoneName): @@ -17282,7 +17284,8 @@ class servDns(shareLdap): resSearch = self.searchLdapDN("*", relZoneDN,"relativeDomainName") if resSearch: resSearch = [x for x in resSearch - if not x[0][1]["relativeDomainName"][0] == "@"] + if not x[0][1]["relativeDomainName"][0] == b"@"] + #returns encoded bytes list return resSearch def searchAllDomainNamesInLDAP(self, domainName): @@ -17295,6 +17298,7 @@ class servDns(shareLdap): if hostName == "*": hostName = r"\*" resSearch = self.searchLdapDN(hostName, relZoneDN, "relativeDomainName") + #returns encoded bytes list return resSearch def searchDomainNameInLDAP(self, domainName): @@ -17306,6 +17310,7 @@ class servDns(shareLdap): if resSearch: resSearch = [x for x in resSearch if "cNAMERecord" not in x[0][1]] + #returns encoded bytes list return resSearch def searchCNameInLDAP(self, domainName): @@ -17317,6 +17322,7 @@ class servDns(shareLdap): if resSearch: resSearch = [x for x in resSearch if "cNAMERecord" in x[0][1]] + #returns encoded bytes list return resSearch def searchIPinForward(self, ip): @@ -17327,7 +17333,8 @@ class servDns(shareLdap): resSearch = self._searchLdapDNSub(ip, self.relForwardDN, "aRecord") if resSearch: resSearch = [x for x in resSearch - if not x[0][1]["relativeDomainName"][0] == "@"] + if not x[0][1]["relativeDomainName"][0] == b"@"] + #returns encoded bytes list return resSearch def searchHostsForIPinForward(self, ip): @@ -17337,9 +17344,10 @@ class servDns(shareLdap): if foundNames: for aRecord in foundNames: relDomainNames = aRecord[0][1]['relativeDomainName'] - zoneName = aRecord[0][1]['zoneName'][0] - domainNames = ["%s.%s" % (x, zoneName) for x in relDomainNames] + zoneName = aRecord[0][1]['zoneName'][0].decode("UTF-8") + domainNames = ["%s.%s" % (x.decode("UTF-8"), zoneName) for x in relDomainNames] hostNames += domainNames + #returns decoded str list return hostNames def searchHostinReverse(self, host): @@ -17348,10 +17356,11 @@ class servDns(shareLdap): Ищет в LDAP """ hostDot = "%s." % host - resSearch = self._searchLdapDNSub(hostDot,self.relReverseDN,"pTRRecord") + resSearch = self._searchLdapDNSub(hostDot,self.relReverseDN, "pTRRecord") if resSearch: resSearch = [x for x in resSearch - if not x[0][1]["relativeDomainName"][0] == "@"] + if not x[0][1]["relativeDomainName"][0] == b"@"] + #returns encoded bytes list return resSearch def searchIPForHostInReverse(self, host): From 25c8045ffd25edac4323b7087c348df97f5d0fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Wed, 8 Sep 2021 17:45:25 +0300 Subject: [PATCH 18/24] minor fixes related to dhcp --- pym/cl_ldap.py | 30 +++++++++++++++--------------- pym/cl_xml.py | 14 +++++++------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index d48116b..2a2d8d0 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -7448,8 +7448,8 @@ class servLdap(shareLdap): deltaTime = timeLocal - timeFile if deltaTime.days == 0: deltaSec = deltaTime.seconds - dHours = int(deltaSec/3600) - dMinutes = int((deltaSec - dHours*3600)/60) + dHours = int(deltaSec//3600) + dMinutes = int((deltaSec - dHours*3600)//60) dSeconds = deltaSec - dHours*3600 - dMinutes*60 hours = _("hours") minutes = _("minutes") @@ -13950,7 +13950,7 @@ use the new version. (openldap > 2.4)")%openLdapVesion) i[0][1]["filtersender"])) else: listGroupMail.append((i[0][1]["cn"][0], - i[0][1]["mailAlternateAddress"],[])) + i[0][1]["mailAlternateAddress"], [])) return listGroupMail def setupReplServer(self, options, service): @@ -13999,9 +13999,9 @@ file %s")%bFile) deltaTime = timeLocal - timeFile if deltaTime.days == 0: deltaSec = deltaTime.seconds - dHours = int(deltaSec/3600) - dMinutes = int((deltaSec - dHours*3600)/60) - dSeconds = deltaSec - dHours*3600 - dMinutes*60 + dHours = int(deltaSec // 3600) + dMinutes = int((deltaSec - dHours * 3600) // 60) + dSeconds = deltaSec - dHours * 3600 - dMinutes * 60 hours = _("hours") minutes = _("minutes") seconds = _("seconds") @@ -16589,8 +16589,8 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): binList = [] numb = int(string) while numb: - binList.append(numb%2) - numb = numb/2 + binList.append(numb % 2) + numb = numb // 2 return binList[::-1] listOctMask = ipNetMask.split('.') @@ -16776,12 +16776,12 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): for node in deletesNodes: nNode = node nNode = nextNode(nNode) - while nNode and self.docObj.getTypeField(nNode)=="br": + while nNode is not None and self.docObj.getTypeField(nNode)=="br": delNodesNext.append(nNode) nNode = nextNode(nNode) pNode = node pNode = prevNode(pNode) - while pNode and self.docObj.getTypeField(pNode)=="br": + while pNode is not None and self.docObj.getTypeField(pNode)=="br": delNodesPrev.append(pNode) pNode = prevNode(pNode) @@ -16832,12 +16832,12 @@ class dncpTxt(cl_profile.dhcp, shareTxt, shareIP): for node in deletesNodes: nNode = node nNode = nextNode(nNode) - while nNode and self.docObj.getTypeField(nNode)=="br": + while nNode is not None and self.docObj.getTypeField(nNode)=="br": delNodesNext.append(nNode) nNode = nextNode(nNode) pNode = node pNode = prevNode(pNode) - while pNode and self.docObj.getTypeField(pNode)=="br": + while pNode is not None and self.docObj.getTypeField(pNode)=="br": delNodesPrev.append(pNode) pNode = prevNode(pNode) @@ -17064,12 +17064,12 @@ class dnsTxt(cl_profile.bind,shareTxt): for node, zoneNameTmp in deletesNodes: nNode = node nNode = nextNode(nNode) - while nNode and self.docObj.getTypeField(nNode)=="br": + while nNode is not None and self.docObj.getTypeField(nNode)=="br": delNodesNext.append(nNode) nNode = nextNode(nNode) pNode = node pNode = prevNode(pNode) - while pNode and self.docObj.getTypeField(pNode)=="br": + while pNode is not None and self.docObj.getTypeField(pNode)=="br": delNodesPrev.append(pNode) pNode = prevNode(pNode) # Оставляем два перевода строки сверху @@ -21093,7 +21093,7 @@ incompatible, use one of the options")) self.printERROR(_("DHCP static host %s")%hostname) self.printERROR(_("DHCP ip %s")%ip) self.printERROR(_("DNS host %s")%fullDomainName) - self.printERROR(_("DNS ip %s")%",".join(x.decode("UTF_8" for x in aRecords))) + self.printERROR(_("DNS ip %s")%",".join(x.decode("UTF_8") for x in aRecords)) self.printERROR(_("IP addresses do not match")) flagError = True break diff --git a/pym/cl_xml.py b/pym/cl_xml.py index fe40a49..60a8eba 100644 --- a/pym/cl_xml.py +++ b/pym/cl_xml.py @@ -374,7 +374,7 @@ class xmlDoc(): newInsNode = deepcopy(nodeSeplist) self.setActionField(newInsNode, "append") - if nextNode: + if nextNode is not None: appSplLst.append((newInsNode, nextNode, "insert")) @@ -386,7 +386,7 @@ class xmlDoc(): newInsNode = deepcopy(nodeSeplist) if self.getActionField(newInsNode) == "join": self.setActionField(newInsNode, "append") - if xmlOldField: + if xmlOldField is not None: insSplLst.append((newInsNode, xmlOldField, "insert")) @@ -414,7 +414,7 @@ class xmlDoc(): flagCompareSeplist = True break if not flagCompareSeplist: - if xmlOldField: + if xmlOldField is not None: insNodesRepl.append((newNode, nxtNode, app)) for newNode, nxtNode, app in insNodesRepl: @@ -422,9 +422,9 @@ class xmlDoc(): insertBefore(xmlArea, newNode, nxtNode) elif app == "append": xmlArea.append(newNode) - if xmlOldField: + if xmlOldField is not None: parentNode = xmlOldField.getparent() - if parentNode and newFieldsAction != "join": + if parentNode is not None and newFieldsAction != "join": parentNode.remove(xmlOldField) for newNode, nxtNode, app in appSplLst: @@ -449,7 +449,7 @@ class xmlDoc(): if actionOldNode == "insert" or actionOldNode == "append": pass else: - if nodeFieldOld.getnext() and \ + if nodeFieldOld.getnext() is not None and \ self.getTypeField( nodeFieldOld.getnext()) == "br": xmlArea.remove(nodeFieldOld.getnext()) @@ -466,7 +466,7 @@ class xmlDoc(): if not nameField: return [] parentNode = xmlField.getparent() - if parentNode: + if parentNode is not None: fieldsVal = xpath.Evaluate( "child::field[attribute::type='seplist'][child::name='%s'] " \ % nameField, parentNode) From 2491f64a43f11cd2df370bd196f07074ca20f47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Thu, 9 Sep 2021 12:32:37 +0300 Subject: [PATCH 19/24] fixed value modification for print --- pym/cl_ldap.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 2a2d8d0..9611175 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -14496,7 +14496,7 @@ class cl_info(cl_utils2.cl_smartcon, prnServ): forwardZones = [x for x in slaveZones if '.in-addr.arpa' not in x] # Формирование строки для отчета title=_("Information about the slave DNS zones in \ -/etc/bind/named.conf") + /etc/bind/named.conf") headerList = [_("DNS zone"),_("IP master DNS servers")] dataList = [[x] for x in forwardZones + reverseZones] dataList = [dataList[x] + [slaveIPs[x]] for x in range(len(dataList))] @@ -15500,17 +15500,17 @@ with another option.")) retValue = self._getUserGroupName(retValue, service) # Ставим Y в случае выставленного флага elif attr == "initials": - if value == "No": + if retValue == "No": retValue = _("Yes") else: retValue = _("No") elif attr == "accountStatus": - if value == "passive": + if retValue == "passive": retValue = _("Yes") else: retValue = _("No") elif attr == "shadowExpire": - if value == "1": + if retValue == "1": retValue = _("Yes") else: retValue = _("No") @@ -15520,12 +15520,12 @@ with another option.")) else: retValue = _("No") elif attr == "userPassword": - if value == "crypt{xxx}": + if retValue == "crypt{xxx}": retValue = _("No") else: retValue = _("Yes") elif attr == "shadowFlag": - if value == "1": + if retValue == "1": retValue = _("Yes") else: retValue = _("No") From 5ebeb22900abd065a728f09f7998253459e4f64f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Tue, 14 Sep 2021 13:26:53 +0300 Subject: [PATCH 20/24] fixed crash on setup mail --- pym/cl_ldap.py | 298 +++++++++++++++++++++++----------------------- pym/cl_profile.py | 2 +- 2 files changed, 153 insertions(+), 147 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 9611175..bdf89b1 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -1114,7 +1114,7 @@ in a sambaDomainName', [not x in retList and retList.append(x) for x in listEl] return retList - #TODO debug jpeg encoding + #TODO debug magick png to jpeg encoding def setJpegPhotoUser(self, userName, photoPath, attr="uid"): """Добавляем jpeg фотографию пользователя в LDAP""" import subprocess @@ -2797,7 +2797,6 @@ service")) addUsers.append(user) modAttrs = [] for userName in addUsers: - #TODO check userName encoding modAttrs.append((ldap.MOD_ADD, 'memberUid', userName.encode("UTF-8"))) if modAttrs: groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) @@ -5947,10 +5946,9 @@ of version > 2.1.10, then you can delete this file.") + "\n" foundUserNames = [] if searchUsers: for data in searchUsers: - #TODO check encoding - foundUserNames.append(data[0][1]["uid"][0]) + foundUserNames.append(data[0][1]["uid"][0].decode("UTF-8")) if foundUserNames: - primaryUsers = list(set(foundUserNames)&set(users)) + primaryUsers = list(set(foundUserNames) & set(users)) if primaryUsers: self.printERROR(_("%s is primary group")% groupName + " " +\ _("for users (%s)")%", ".join(primaryUsers)) @@ -10066,6 +10064,12 @@ the password will be changed only for Samba account") 'helpChapter':_("DHCP service options"), 'help':_("forced setup service") }, + {'progAccess':(6,), + 'shortOption':"f", + 'longOption':"force", + 'helpChapter':_("Samba service options"), + 'help':_("forced setup service") + }, {'progAccess':(6,), 'longOption':"net", 'optVal':"NET", @@ -14930,7 +14934,7 @@ with another option.")) headers = [_("Field"),_("Value")] attributes = [x[0] for x in data] retrAttrs = [x[1] for x in data] - retClVars=False + retClVars = False #TODO check encoding searchRes = self.getQueryLDAP(service, "computers", searchAttr, searchStr, retrAttrs) @@ -14953,7 +14957,7 @@ with another option.")) flagFirst = False for value in ldapValue: if not flagFirst: - data.append((attrName, value.decode("UTF-8"))) + data.append((attrName, value)) flagFirst = True else: data.append(("", value.decode("UTF-8"))) @@ -14965,12 +14969,12 @@ with another option.")) if value: memberGroups.insert(0, value.decode("UTF-8")) flagFirst = False - for value in memberGroups: + for member_group in memberGroups: if not flagFirst: - data.append((attrApp, value)) + data.append((attrApp, member_group)) flagFirst = True else: - data.append(("", value)) + data.append(("", member_group)) else: data.append((attrName, _("No"))) return (headers, data) @@ -16899,22 +16903,23 @@ class dnsTxt(cl_profile.bind,shareTxt): # прямая зона dnsDN = "ou=Forward,%s"%dnsBaseDN template = 'zone "%s" in {\n\ -\ttype %s;\n\ -\tdatabase "ldap ldap://127.0.0.1/zoneName=%s,%s????\ -!bindname=%s,!x-bindpw=%s 178600";\n\ -};' %(zoneName,zoneType,zoneName,dnsDN,dnsCommaSplDN,dnsBasePw) + \ttype %s;\n\ + \tdatabase "ldap ldap://127.0.0.1/zoneName=%s,%s????\ + !bindname=%s,!x-bindpw=%s 178600";\n\ + };' %(zoneName,zoneType,zoneName,dnsDN,dnsCommaSplDN,dnsBasePw) return template elif zoneType == "slave": if not zoneMasters: self.setError(\ - _('Can not found master DNS server in the DNS zone "%s"')%zoneName) + _('Can not found master DNS server\ + in the DNS zone "%s"')%zoneName) return False zoneFile = "%s.zone" %zoneName.split(".in-addr.arpa")[0] template = 'zone "%s" {\n\ -\ttype %s;\n\ -\tfile "sec/%s";\n\ -\tmasters { %s; };\n\ -};' %(zoneName,zoneType,zoneFile, "; ".join(zoneMasters)) + \ttype %s;\n\ + \tfile "sec/%s";\n\ + \tmasters { %s; };\n\ + };' %(zoneName,zoneType,zoneFile, "; ".join(zoneMasters)) return template else: self.setError(_('DNS zone type %s unsupported')%zoneType) @@ -17479,7 +17484,7 @@ class servDns(shareLdap): flagDeleteZone = True else: self.printWARNING(_("Can not found zone %s in \ -/etc/bind/named.conf")%zoneName) + /etc/bind/named.conf")%zoneName) # Если зона найдена в LDAP удаляем ее if self.searchZoneInLDAP(zoneName): # Удаление зоны из LDAP @@ -17631,7 +17636,7 @@ class servDns(shareLdap): incompKeys = ["host","ip"] if set(incompKeys)<=set(optKeys): self.printERROR(_('Command line option "--host" (A-record) \ -incompatible with option "--ip" (PTR-record)')) + incompatible with option "--ip" (PTR-record)')) return False # Флаг MX - записи flagDeleteMX = False @@ -17654,7 +17659,7 @@ incompatible with option "--ip" (PTR-record)')) elif 'ip' in options: if flagDeleteMX: self.printERROR(_('Command line option "--mx" (MX-record) \ -incompatible with option "--ip" (PTR-record)')) + incompatible with option "--ip" (PTR-record)')) return False # ip адрес typeRec = "ptr" @@ -17782,9 +17787,8 @@ incompatible with option "--ip" (PTR-record)')) if not netmask == "24" or \ not self.isCorrectStringNet(zoneName): self.printERROR(_('Incorrect network %s for reverse zone')\ - %zoneName) - self.printWARNING(_("Example network for reverse zone") +\ - " :") + %zoneName) + self.printWARNING(_("Example network for reverse zone") + " :") self.printWARNING('"-n 192.168.0.0/24"') return False dataIP = self.getDomainAndZoneFromIP(network) @@ -17800,27 +17804,27 @@ incompatible with option "--ip" (PTR-record)')) zoneData = self.searchAllDomainNamesInLDAP("@.%s"%zoneName) if not zoneData: self.printERROR(_("Can not found SOA-record in zone %s")\ - %zoneName) + %zoneName) return False # Удаление A записи if 'ip' in options: if 'aRecord' not in zoneData[0][0][1]: self.printERROR(_("Can not found A-records in zone %s")\ - %zoneName) + %zoneName) return False if 'mx' in options: if 'mXRecord' not in zoneData[0][0][1]: self.printERROR(\ _("Can not found MX-records in zone %s")\ - %zoneName) + %zoneName) return False relZoneDN = self.getRelZoneDN(zoneName) modAttrs =[(ldap.MOD_DELETE, 'aRecord', None)] DN = self.addDN("relativeDomainName=@", relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(\ - _("Can not delete A-records for zone %s")\ - %zoneName) + _("Can not delete A-records for zone %s")\ + %zoneName) return False self.printSUCCESS(_("Deleted A-records for zone %s")%zoneName) ret = True @@ -17828,11 +17832,10 @@ incompatible with option "--ip" (PTR-record)')) if 'mx' in options: if 'mXRecord' not in zoneData[0][0][1]: self.printERROR(_("Can not found MX-records in zone %s")\ - %zoneName) + %zoneName) return False # Удаляем все MX записи в записи зоны - ret = self.modMXRecord("@", zoneName, zoneName, - True, []) + ret = self.modMXRecord("@", zoneName, zoneName, True, []) # Увеличиваем на 1 серийный номер зоны if not self.incrementSerialNumberZone(zoneName): return False @@ -17866,14 +17869,14 @@ incompatible with option "--ip" (PTR-record)')) else: self.printERROR(_("Zone type %s unsupported")%zoneType) self.printWARNING(_("Supported zone types: %s")\ - %", ".join(["master","slave"])) + %", ".join(["master","slave"])) return False if not set(minKeys) <= set(optKeys): notFoundKeys = list(set(minKeys)-set(optKeys)) notFoundKeys (len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys) self.printERROR(_("Not enough command line options: %s")\ - %", ".join(notFoundKeys)) + %", ".join(notFoundKeys)) return False # Удаляет лишние точки в названии delDot = lambda y: ".".join(x for x in y.split(".") if x) @@ -17899,20 +17902,20 @@ incompatible with option "--ip" (PTR-record)')) # ip зоны для обратной зоны недопустим if 'ip' in options: self.printERROR(_('Command line option "--ip" \ -incompatible with reverse DNS zone %s')%zoneName) + incompatible with reverse DNS zone %s')%zoneName) return False # MX записи для обратной зоны недопустимы if 'mx' in options: self.printERROR(_('Command line option "--mx" \ -incompatible with reverse DNS zone %s')%zoneName) + incompatible with reverse DNS zone %s')%zoneName) return False network, spl, netmask = zoneName.rpartition("/") if not netmask == "24" or \ not self.isCorrectStringNet(zoneName): self.printERROR(_('Incorrect network %s for reverse zone')\ - %zoneName) + %zoneName) self.printWARNING(_("Example network for reverse zone") +\ - " :") + " :") self.printWARNING('"-n 192.168.0.0/24"') return False netSpl = network.split(".") @@ -17929,7 +17932,7 @@ incompatible with reverse DNS zone %s')%zoneName) objTxtZone = dnsTxt() if zoneName in objTxtZone.getAllNamesZones(): self.printERROR(_("DNS zone %s exists in /etc/bind/named.conf")\ - %zoneName) + %zoneName) return False # ip зоны zoneIP = "" @@ -17957,7 +17960,7 @@ incompatible with reverse DNS zone %s')%zoneName) if not self.isCorrectStringNet(options['servers'], False): self.printERROR(_('Incorrect autoritatives servers IP')) self.printERROR(_('Error in command line option \ -"--servers"')) + "--servers"')) self.printWARNING(_('Example:')) self.printWARNING('--servers 192.168.0.1,192.168.0.2') return False @@ -17970,7 +17973,7 @@ incompatible with reverse DNS zone %s')%zoneName) if flagErrorNs: self.printERROR(_('Incorrect autoritatives servers names')) self.printERROR(_('Error in command line option \ -"--servers"')) + "--servers"')) self.printWARNING(_('Example:')) self.printWARNING('--servers ns.domain.ru,ns1.domain.ru') return False @@ -17986,14 +17989,14 @@ incompatible with reverse DNS zone %s')%zoneName) if self.isCorrectStringNet(nameServer, False): self.printERROR(_('Incorrect autoritative server')) self.printERROR(_('Error in command line option \ -"--server"')) + "--server"')) self.printWARNING(_('Example:')) self.printWARNING('--server ns.domain.com') return False if not nameServer: self.printERROR(_('Incorrect autoritative server name')) self.printERROR(_('Error in command line option \ -"--server"')) + "--server"')) return False # Добавляем мастер сервер в имена авторитативаных серверов if not nameServer in namesServers: @@ -18007,14 +18010,14 @@ incompatible with reverse DNS zone %s')%zoneName) not self.searchDomainNameInLDAP(nameServer)): if 'ipserver' not in options: self.printERROR(_('Not found A-record for "%s" \ -(master server DNS)')%nameServer) + (master server DNS)')%nameServer) self.printERROR(_('Not enough command line option \ -"--ipserver"')) + "--ipserver"')) return False else: if nameServer == zoneName and zoneIP: self.printERROR(_("The same zone name and name of \ -the primary authoritative server for the zone")) + the primary authoritative server for the zone")) self.printERROR(_('We do not need the option "--ip"')) return False ipserver = options["ipserver"] @@ -18027,11 +18030,13 @@ the primary authoritative server for the zone")) if self.searchZoneInLDAP(nsZoneName) and\ self.searchDomainNameInLDAP(nameServer): self.printERROR(_('Command line option "--ipserver" \ -is not needed, as the host name "%s" found in the DNS server')%nameServer) + is not needed, as the host name "%s" found in\ + the DNS server')%nameServer) else: self.printERROR(_('Command line option "--ipserver" \ -is not needed, as the host name "%s" does not belong to the existing zones on \ -this DNS server')%nameServer) + is not needed, as the host name "%s" does not\ + belong to the existing zones on \ + this DNS server')%nameServer) return False # Почтовый адрес администратора зоны # по умолчанию @@ -18350,7 +18355,7 @@ this DNS server')%nameServer) # Проверка на mx совместно с mxmod if 'mx' in options and 'mxmod' in options: self.printERROR('Command line option "-mx" is incompatible \ -with option "--mxmod"') + with option "--mxmod"') return False # MX серверы mxServers = [] @@ -18495,7 +18500,7 @@ with option "--mxmod"') if self.searchZoneInLDAP(nsZoneName) and\ not self.searchDomainNameInLDAP(nameServer): self.printERROR(_("Can not found host name %s in LDAP")\ - %nameServer) + %nameServer) self.printWARNING(\ _("Add A-record %s (autoritative DNS server) in LDAP")\ % nameServer) @@ -18550,7 +18555,7 @@ with option "--mxmod"') DN = self.addDN("relativeDomainName=@", relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(_("Can not modify new SOA-record for zone %s \ -in LDAP") % zoneName) + in LDAP") % zoneName) return False # Результат исполнения для пользователя # Изменен ли главный сервер авторизации @@ -18563,7 +18568,7 @@ in LDAP") % zoneName) # Изменены ли авторитативные DNS сервера зоны if set(oldNamesServers) != set(namesServers): self.printSUCCESS(\ - _("Modified all autoritative DNS servers for zone")) + _("Modified all autoritative DNS servers for zone")) # Вывод модифицированных параметров времени for nameOpt in zoneTimeIntervals.keys(): valueOld = zoneTimeIntervals[nameOpt] @@ -18588,7 +18593,7 @@ in LDAP") % zoneName) # Проверка на имя хоста вместе с ip if 'ip' in options and 'host' in options: self.printERROR('Command line option "--host" is incompatible \ -with option "--ip"') + with option "--ip"') return False # Удаляет лишние точки в названии delDot = lambda y: ".".join(x for x in y.split(".") if x) @@ -18602,7 +18607,7 @@ with option "--ip"') modOther = False else: self.printERROR(_('Command line option "--automod %s" \ -incorrect, use "--automod on" or "--automod off"')%autoMod) + incorrect, use "--automod on" or "--automod off"')%autoMod) return False # По умолчанию прямой тип записи typeRec = "a" @@ -18613,12 +18618,12 @@ incorrect, use "--automod on" or "--automod off"')%autoMod) if not typeRec in supportTypes: self.printERROR(_("Record type %s unsupported")%typeRec) self.printWARNING(_("Supported record types: %s")\ - %", ".join(supportTypes)) + %", ".join(supportTypes)) return False # Проверка на mx совместно с mxmod if 'mx' in options and 'mxmod' in options: self.printERROR('Command line option "-mx" is incompatible \ -with option "--mxmod"') + with option "--mxmod"') return False # Добавляем кавычки и -- addQ = lambda y: [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in y] @@ -18656,14 +18661,14 @@ with option "--mxmod"') typeRec = "cname" else: self.printERROR(_("Incorrect command line options %s")\ - %", ".join(addQ(optKeys))) + %", ".join(addQ(optKeys))) return False # Проверка обязательных опций if not set(requiredOpt) <= set(optKeys): notFoundReqOpt = list(set(requiredOpt) - set(optKeys)) self.printERROR(_('Can not found required command line options %s')\ - %", ".join(addQ(notFoundReqOpt))) + %", ".join(addQ(notFoundReqOpt))) return False if "f" in options.keys(): optionalOpt['f'] = options['f'] @@ -18676,17 +18681,17 @@ with option "--mxmod"') break if errorOptionalOpt: self.printERROR(\ - _('Optional comand line option %s it has a wrong value')\ - %addQ([key])[0]) + _('Optional comand line option %s it has a wrong value')\ + %addQ([key])[0]) self.printWARNING(_('Valid values are the options %s')\ - %addQ([key])[0] + " " + '(%s)'\ - % (" "+_("or")+" ").join(('"%s"' % x for x in value))) + %addQ([key])[0] + " " + '(%s)'\ + % (" "+_("or")+" ").join(('"%s"' % x for x in value))) return False # Проверка лишних опций unnecessaryOpt = list(set(optKeys) - set(requiredOpt + list(optionalOpt.keys()))) if unnecessaryOpt: self.printERROR(_("Exists unnecessary command line options %s")\ - %",".join(addQ(unnecessaryOpt))) + %",".join(addQ(unnecessaryOpt))) return False mxServers = [] @@ -18696,11 +18701,11 @@ with option "--mxmod"') # Почтовые серверы для доменного имени if typeRec == "ptr": self.printERROR(_('Command line option "--mx" \ -incompatible with PTR-record (option "-t")')) + incompatible with PTR-record (option "-t")')) return False if typeRec == "cname": self.printERROR(_('Command line option "--mx" \ -incompatible with CNAME-record (option "-t")')) + incompatible with CNAME-record (option "-t")')) return False mxServers = [delDot(x.lower()) for x in options['mx'].split(",")] mxServers = self.unicList(mxServers) @@ -18714,11 +18719,11 @@ incompatible with CNAME-record (option "-t")')) # Почтовые cерверы для доменного имени if typeRec == "ptr": self.printERROR(_('Command line option "--mxmod" \ -incompatible with PTR-record (option "-t")')) + incompatible with PTR-record (option "-t")')) return False if typeRec == "cname": self.printERROR(_('Command line option "--mxmod" \ -incompatible with CNAME-record (option "-t")')) + incompatible with CNAME-record (option "-t")')) return False modMxServers = [delDot(x.lower()) for x in options['mxmod'].split(",")] modMxServers = self.unicList(modMxServers) @@ -18760,12 +18765,12 @@ incompatible with CNAME-record (option "-t")')) if foundNewDomain: if foundNewCnameRecord: self.printERROR(_("CNAME-record %s exists in LDAP")\ - %newDomainName) + %newDomainName) self.printERROR("%s --> %s"%(newDomainName,\ delDot(foundNewDomain[0][0][1]['cNAMERecord'][0].decode("UTF-8")))) else: self.printERROR(_("A-record %s exists in LDAP")\ - %newDomainName) + %newDomainName) self.printERROR("%s --> %s"\ %(newDomainName, foundNewDomain[0][0][1]['aRecord'][0].decode("UTF-8"))) self.printERROR("") @@ -18797,14 +18802,15 @@ incompatible with CNAME-record (option "-t")')) if foundNewDomain: if foundNewCnameRecord: self.printERROR(_("CNAME-record %s exists in LDAP")\ - %newDomainName) + %newDomainName) self.printERROR("%s --> %s"%(newDomainName,\ delDot(foundNewDomain[0][0][1]['cNAMERecord'][0].decode("UTF-8")))) else: self.printERROR(_("A-record %s exists in LDAP")\ - %newDomainName) + %newDomainName) self.printERROR("%s --> %s"\ - %(newDomainName, foundNewDomain[0][0][1]['aRecord'][0].decode("UTF-8"))) + %(newDomainName, foundNewDomain[0][0][1]['aRecord'][0]\ + .decode("UTF-8"))) self.printERROR("") return False newIP = "" @@ -18813,7 +18819,7 @@ incompatible with CNAME-record (option "-t")')) if 'ip' in options: if typeRec == "cname": self.printERROR('Command line option "-t cname" \ -is incompatible with option "--ip"') + is incompatible with option "--ip"') return False # newIP адрес newIP = options['ip'] @@ -18839,7 +18845,7 @@ is incompatible with option "--ip"') if foundNewIp: self.printERROR(_("IP address %s exists in LDAP")%newIP) self.printERROR("%s --> %s"%(newIP,\ - delDot(foundNewIp[0][0][1]['pTRRecord'][0].decode("UTF-8")))) + delDot(foundNewIp[0][0][1]['pTRRecord'][0].decode("UTF-8")))) self.printERROR("") return False # Проверка существования обратной записи @@ -18870,7 +18876,7 @@ is incompatible with option "--ip"') if foundNewIp: self.printERROR(_("IP address %s exists in LDAP")%newIP) self.printERROR("%s --> %s"%(newIP,\ - delDot(foundNewIp[0][0][1]['pTRRecord'][0].decode("UTF-8")))) + delDot(foundNewIp[0][0][1]['pTRRecord'][0].decode("UTF-8")))) self.printERROR("") return False # Имена изменяемых зон @@ -18898,13 +18904,13 @@ is incompatible with option "--ip"') # найдена CNAME запись? if self.searchCNameInLDAP(domainName): self.printERROR(_("CNAME-record %s exists in LDAP")\ - %domainName) + %domainName) self.printWARNING(_('Use command line option "-t cname"')) return False foundMain = self.searchDomainNameInLDAP(domainName) if not foundMain: self.printERROR(_("Record %s not exists in LDAP")\ - %domainName) + %domainName) return False otherIP = delDot(foundMain[0][0][1]['aRecord'][0].decode("UTF-8")) # Поиcк в обратной зоне в случае необходимости @@ -18917,12 +18923,12 @@ is incompatible with option "--ip"') foundOther = self.searchAllDomainNamesInLDAP(otherDomain) if not foundOther: self.printERROR(_("PTR-record %s not exists in LDAP")\ - %otherDomain) + %otherDomain) return False # Проверка на соответствие имени хоста if domainName!=delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")): self.printERROR(_("Found PTR-record %s in LDAP")\ - %otherDomain) + %otherDomain) self.printERROR("%s --> %s"%(otherIP,\ delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")))) self.printERROR("") @@ -18985,7 +18991,7 @@ is incompatible with option "--ip"') IPs = self.searchIPForHostInReverse(domainName) if not IPs: self.printERROR(_("Can not found %s in reverse zone")\ - %domainName) + %domainName) return False if len(IPs)>1: self.printERROR(_("Found multiple records in reverse zone")) @@ -19010,7 +19016,7 @@ is incompatible with option "--ip"') foundMain = self.searchAllDomainNamesInLDAP(domainNamePTR) if not foundMain: self.printERROR(_("PTR-record %s not exists in LDAP")\ - %domainNamePTR) + %domainNamePTR) return False # Поиcк в обратной зоне в случае необходимости if modOther: @@ -19018,14 +19024,14 @@ is incompatible with option "--ip"') foundOther = self.searchAllDomainNamesInLDAP(otherDomain) if not foundOther: self.printERROR(_("A-record %s not exists in LDAP")\ - %otherDomain) + %otherDomain) return False # Проверка на соответствие ip хоста if ip != foundOther[0][0][1]['aRecord'][0].decode("UTF-8"): self.printERROR(_("Found A-record %s in LDAP")\ - %otherDomain) + %otherDomain) self.printERROR("%s --> %s"\ - %(otherDomain, foundOther[0][0][1]['aRecord'][0].decode("UTF-8"))) + %(otherDomain, foundOther[0][0][1]['aRecord'][0].decode("UTF-8"))) self.printERROR("") return False # Модифицируем PTR запись @@ -19037,7 +19043,7 @@ is incompatible with option "--ip"') return False # Изменение IP A записи (прямая зона) if not self.modARecord(hostName, domainName, zoneName, - otherIP, newIP): + otherIP, newIP): return False # Изменяемая обратная зона namesZones.append(otherZoneName) @@ -19076,8 +19082,8 @@ is incompatible with option "--ip"') # Если изменяется доменное имя # Изменение доменного имени PTR записи (обратная зона) if not self.modPTRRecord(otherIP, otherHostName, - otherDomainName, otherZoneName, - newDomainName): + otherDomainName, otherZoneName, + newDomainName): return False # Изменяемая обратная зона namesZones.append(otherZoneName) @@ -19085,12 +19091,12 @@ is incompatible with option "--ip"') foundMain = self.searchCNameInLDAP(domainName) if not foundMain: self.printERROR(_("CNAME-record %s not exists in LDAP")\ - %domainName) + %domainName) return False # Изменяем cname указатель if cnameServer: if not self.modCNAMERecord(hostName, domainName, zoneName, - cnameServer): + cnameServer): return False # Изменяемая прямая зона namesZones.append(zoneName) @@ -19098,7 +19104,7 @@ is incompatible with option "--ip"') if newDomainName: oldCname = delDot(foundMain[0][0][1]['cNAMERecord'][0].decode("UTF-8")) if not self.moveCNAMERecord(oldCname,domainName, - newDomainName): + newDomainName): return False # Изменяемая прямая зона namesZones.append(zoneName) @@ -19109,7 +19115,7 @@ is incompatible with option "--ip"') foundMain = self.searchDomainNameInLDAP(domainName) if not foundMain: self.printERROR(_("Record %s not exists in LDAP")\ - %domainName) + %domainName) return False flagFoundMX = False if 'mXRecord' in foundMain[0][0][1]: @@ -19118,19 +19124,19 @@ is incompatible with option "--ip"') if modMxServers: if not flagFoundMX: self.printERROR(\ - _("Can not found MX-record in A-record %s")\ - %domainName) + _("Can not found MX-record in A-record %s")\ + %domainName) return False # Находим нужную запись foundMxServers = [len(x.decode("UTF-8").split(" ")) == 1\ - and delDot(x.decode("UTF-8")) - or delDot(x.decode("UTF-8").split(" ")[1]) - for x in foundMain[0][0][1]['mXRecord']] + and delDot(x.decode("UTF-8")) + or delDot(x.decode("UTF-8").split(" ")[1]) + for x in foundMain[0][0][1]['mXRecord']] oldMxHost = modMxServers[0] newMxHost = modMxServers[1] if not oldMxHost in foundMxServers: self.printERROR(_("Can not found MX host %s")\ - %oldMxHost +" " + _("in A-record %s")%domainName) + %oldMxHost +" " + _("in A-record %s")%domainName) return False # Проверка наличия новой MX записи в A записи if newMxHost in foundMxServers: @@ -19149,7 +19155,7 @@ is incompatible with option "--ip"') else: addMxServers.append(foundMxServer) if not self.modMXRecord(hostName, domainName, zoneName, - flagFoundMX, addMxServers): + flagFoundMX, addMxServers): return False # Изменяемая прямая зона namesZones.append(zoneName) @@ -19159,7 +19165,7 @@ is incompatible with option "--ip"') if not self.checkMXDomains(mxServers): return False if not self.modMXRecord(hostName, domainName, zoneName, - flagFoundMX, mxServers): + flagFoundMX, mxServers): return False # Изменяемая прямая зона namesZones.append(zoneName) @@ -19173,11 +19179,11 @@ is incompatible with option "--ip"') otherIP = ip if typeRec == "cname": self.printERROR(_('IP address %s')%ip + " " +\ - _('incompatible with CNAME-record (option "-t")')) + _('incompatible with CNAME-record (option "-t")')) return False if "cname" in optKeys: self.printERROR(_('IP address %s')%ip + " " +\ - _('incompatible with CNAME-record (option "--cname")')) + _('incompatible with CNAME-record (option "--cname")')) return False # Поиск модифицируемой записи в DNS # Поиск основной записи @@ -19196,7 +19202,7 @@ is incompatible with option "--ip"') foundMain = self.searchAllDomainNamesInLDAP(domainNamePTR) if not foundMain: self.printERROR(_("PTR-record %s not exists in LDAP")\ - %domainNamePTR) + %domainNamePTR) return False otherDomain = delDot(foundMain[0][0][1]['pTRRecord'][0].decode("UTF-8")) # Модификация @@ -19208,14 +19214,14 @@ is incompatible with option "--ip"') foundOther = self.searchAllDomainNamesInLDAP(otherDomain) if not foundOther: self.printERROR(_("A-record %s not exists in LDAP")\ - %otherDomain) + %otherDomain) return False # Проверка на соответствие ip хоста if ip != foundOther[0][0][1]['aRecord'][0].decode("UTF-8"): self.printERROR(_("Found A-record %s in LDAP")\ - %otherDomain) + %otherDomain) self.printERROR("%s --> %s"\ - %(otherDomain, foundOther[0][0][1]['aRecord'][0].decode("UTF-8"))) + %(otherDomain, foundOther[0][0][1]['aRecord'][0].decode("UTF-8"))) self.printERROR("") return False # Модифицируем PTR запись @@ -19287,13 +19293,13 @@ is incompatible with option "--ip"') # найдена CNAME запись? if self.searchCNameInLDAP(domainName): self.printERROR(_("CNAME-record %s exists in LDAP")\ - %domainName) + %domainName) self.printWARNING(_('Use command line option "-t cname"')) return False foundMain = self.searchDomainNameInLDAP(domainName) if not foundMain: self.printERROR(_("Record %s not exists in LDAP")\ - %domainName) + %domainName) return False # Поиcк в обратной зоне в случае необходимости if modOther: @@ -19306,14 +19312,14 @@ is incompatible with option "--ip"') foundOther = self.searchAllDomainNamesInLDAP(otherDomain) if not foundOther: self.printERROR(_("PTR-record %s not exists in LDAP")\ - %otherDomain) + %otherDomain) return False # Проверка на соответствие имени хоста if domainName != delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")): self.printERROR(_("Found PTR-record %s in LDAP")\ - %otherDomain) + %otherDomain) self.printERROR("%s --> %s"%(otherIP,\ - delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")))) + delDot(foundOther[0][0][1]['pTRRecord'][0].decode("UTF-8")))) self.printERROR("") return False # Изменяем в двух зонах @@ -19392,8 +19398,8 @@ is incompatible with option "--ip"') if modMxServers: if not flagFoundMX: self.printERROR(\ - _("Can not found MX-record in A-record %s")\ - %domainName) + _("Can not found MX-record in A-record %s")\ + %domainName) return False # Находим нужную запись foundMxServers = [len(x.decode("UTF-8").split(" ")) == 1\ @@ -19404,7 +19410,7 @@ is incompatible with option "--ip"') newMxHost = modMxServers[1] if not oldMxHost in foundMxServers: self.printERROR(_("Can not found MX host %s")\ - %oldMxHost +" " + _("in A-record %s")%domainName) + %oldMxHost +" " + _("in A-record %s")%domainName) return False # Проверка существования A записи для MX хоста if not self.checkMXDomains([newMxHost]): @@ -19536,7 +19542,7 @@ is incompatible with option "--ip"') if not typeRec in supportTypes: self.printERROR(_("Record type %s unsupported")%typeRec) self.printWARNING(_("Supported record types: %s")\ - %", ".join(supportTypes)) + %", ".join(supportTypes)) return False if typeRec == "cname": minKeys = ["cname","host"] @@ -19546,18 +19552,18 @@ is incompatible with option "--ip"') notFoundKeys = list(set(minKeys)-set(optKeys)) notFoundKeys = [len(x) > 1 and '"--%s"' % x or '"-%s"' % x for x in notFoundKeys] self.printERROR(_("Not enough command line options: %s")\ - %", ".join(notFoundKeys)) + %", ".join(notFoundKeys)) return False # Флаг автоматического создания PTR записи createPtr = True if 'autoptr' in options: if typeRec == "ptr": self.printERROR(_('Command line option "--autoptr" \ -incompatible with type DNS record PTR (option "-t")')) + incompatible with type DNS record PTR (option "-t")')) return False if typeRec == "cname": self.printERROR(_('Command line option "--autoptr" \ -incompatible with type DNS record CNAME (option "-t")')) + incompatible with type DNS record CNAME (option "-t")')) return False autoPtr = options['autoptr'] if autoPtr == "on": @@ -19566,7 +19572,7 @@ incompatible with type DNS record CNAME (option "-t")')) createPtr = False else: self.printERROR(_('Command line option "--autoptr %s" \ -incorrect, use "--autoptr on" or "--autoptr off"')%autoPtr) + incorrect, use "--autoptr on" or "--autoptr off"')%autoPtr) return False # Удаляет лишние точки в названии delDot = lambda y: ".".join(x for x in y.split(".") if x) @@ -19587,11 +19593,11 @@ incorrect, use "--autoptr on" or "--autoptr off"')%autoPtr) if 'cname' in options: if 'ip' in options: self.printERROR(_('Command line option "--ip" incompatible \ -with type DNS record CNAME (option "-t")')) + with type DNS record CNAME (option "-t")')) return False if 'mx' in options: self.printERROR(_('Command line option "--mx" incompatible \ -with type DNS record CNAME (option "-t")')) + with type DNS record CNAME (option "-t")')) return False # Доменное каноническое имя (имя включающее домен) для CNAME cnDomainName = delDot(options['cname'].lower()) @@ -19620,7 +19626,7 @@ with type DNS record CNAME (option "-t")')) # Почтовые серверы для доменного имени if typeRec == "ptr": self.printERROR(_('Command line option "--mx" incompatible \ -with type DNS record PTR (option "-t")')) + with type DNS record PTR (option "-t")')) return False mxServers = [delDot(x.lower()) for x in options['mx'].split(",")] mxServers = self.unicList(mxServers) @@ -19676,7 +19682,7 @@ with type DNS record PTR (option "-t")')) # Поиск имени хоста if not self.searchDomainNameInLDAP(cnDomainName): self.printERROR(_("Can not found A-record %s in LDAP")\ - %cnDomainName) + %cnDomainName) return False # Поиск зоны if not self.searchZoneInLDAP(zoneName): @@ -19686,7 +19692,7 @@ with type DNS record PTR (option "-t")')) findCName = self.searchCNameInLDAP(domainName) if findCName: self.printERROR(_("CNAME-record %s exists in LDAP")\ - %domainName) + %domainName) cnameHosts = findCName[0][0][1]['cNAMERecord'] for cnameHost in cnameHosts: self.printERROR("%s --> %s"%(domainName,cnameHost.decode("UTF-8"))) @@ -19695,10 +19701,10 @@ with type DNS record PTR (option "-t")')) # Метод добавляющий в конце текста точку если ее нет addDot = lambda x: (len(x)>0 and x[-1]!="." and "%s."%x) or x domainEntry = [('objectclass', [b'top', b'dNSZone']), - ('relativeDomainName', [hostName.encode("UTF-8")]), - ('dNSClass', [b'IN']), - ('zoneName', [zoneName.encode("UTF-8")]), - ('cNAMERecord', [addDot(cnDomainName).encode("UTF-8")])] + ('relativeDomainName', [hostName.encode("UTF-8")]), + ('dNSClass', [b'IN']), + ('zoneName', [zoneName.encode("UTF-8")]), + ('cNAMERecord', [addDot(cnDomainName).encode("UTF-8")])] baseDN = self.clVars.Get("ld_dns_dn") ouZonesDN = self.getOUZonesDN(zoneName) zoneBaseDN = "zoneName=%s,%s,%s" %(zoneName, ouZonesDN, baseDN) @@ -19753,8 +19759,8 @@ with type DNS record PTR (option "-t")')) notFoundMailServers = self.getNotFoundRecords(namesMailServers) if notFoundMailServers: self.printERROR(\ - _("Can not found A-records for MX-records - %s")\ - %", ".join(notFoundMailServers)) + _("Can not found A-records for MX-records - %s")\ + %", ".join(notFoundMailServers)) self.printWARNING(\ _("First, add the A-records required for MX-records")) return False @@ -19771,12 +19777,12 @@ with type DNS record PTR (option "-t")')) return False if self.searchDomainNameInLDAP(domainName): self.printERROR(_("Record %s exists in LDAP")\ - %domainName) + %domainName) return False # Поиск CNAME записи if self.searchCNameInLDAP(domainName): self.printERROR(_("CNAME-record %s exists in LDAP")\ - %domainName) + %domainName) return False flagForward = self.isForwardZone(zoneName) # Метод добавляющий в конце текста точку если ее нет @@ -19787,10 +19793,10 @@ with type DNS record PTR (option "-t")')) return False namesMailServersDot = [addDot(x).encode("UTF-8") for x in namesMailServers] domainEntry = [('objectclass', [b'top', b'dNSZone']), - ('relativeDomainName', [hostName.encode("UTF-8")]), - ('dNSClass', [b'IN']), - ('zoneName',[zoneName.encode("UTF-8")]), - ('aRecord',[ipAddrOrHost.encode("UTF-8")])] + ('relativeDomainName', [hostName.encode("UTF-8")]), + ('dNSClass', [b'IN']), + ('zoneName',[zoneName.encode("UTF-8")]), + ('aRecord',[ipAddrOrHost.encode("UTF-8")])] mxValues = [b"%s %s" % (x * 10 + 10, namesMailServersDot[x]) for x in range(len(namesMailServersDot))] if mxValues: @@ -19798,9 +19804,9 @@ with type DNS record PTR (option "-t")')) domainEntry.append(('mXRecord', mxValues)) else: domainEntry = [('objectclass', [b'top', b'dNSZone']), - ('relativeDomainName', [hostName.encode("UTF-8")]), - ('zoneName',[zoneName.encode("UTF-8")]), - ('pTRRecord',[addDot(ipAddrOrHost).encode("UTF-8")])] + ('relativeDomainName', [hostName.encode("UTF-8")]), + ('zoneName',[zoneName.encode("UTF-8")]), + ('pTRRecord',[addDot(ipAddrOrHost).encode("UTF-8")])] baseDN = self.clVars.Get("ld_dns_dn") ouZonesDN = self.getOUZonesDN(zoneName) zoneBaseDN = "zoneName=%s,%s,%s" %(zoneName, ouZonesDN, baseDN) @@ -19845,7 +19851,7 @@ with type DNS record PTR (option "-t")')) foundNames = self.searchDomainNameInLDAP("@.%s"%zoneName) if not foundNames: self.printERROR(_("Can not found SOA-record in DNS zone %s")\ - %zoneName) + %zoneName) return False sOARecord = foundNames[0][0][1]['sOARecord'][0].decode("UTF-8") sOAList = sOARecord.split(" ") @@ -19857,7 +19863,7 @@ with type DNS record PTR (option "-t")')) except: self.printERROR(_("Incorrect SOA-record in DNS zone %s")%zoneName) self.printERROR(_("Incorrect serial number %s in SOA-record")\ - %str(sOAList[2])) + %str(sOAList[2])) return False sOAList[2] = serialNumber sOARecord = " ".join(sOAList) @@ -19866,7 +19872,7 @@ with type DNS record PTR (option "-t")')) DN = self.addDN("relativeDomainName=@", relZoneDN) if not self.modAttrsDN(DN, modAttrs): self.printERROR(_("Can not write new serial number for zone %s \ -in LDAP")%zoneName) + in LDAP")%zoneName) return False return True @@ -19923,7 +19929,7 @@ in LDAP")%zoneName) if not self.checkSDBLDAP(): self.printERROR(_('Can not found USE="sdb-ldap" in package bind')) self.printWARNING(_('Key USE="sdb-ldap" added to the package \ -net-dns/bind version>=9.6.1')) + net-dns/bind version>=9.6.1')) return False # Принудительная установка forceOptions = False @@ -19940,7 +19946,7 @@ net-dns/bind version>=9.6.1')) if self.clVars.Get("sr_dns_set") == "on" and\ not forceOptions: self.printWARNING (_("WARNING") + ": " +\ - _("DNS server is configured")+ ".") + _("DNS server is configured")+ ".") return True # Доверительные сети по умолчанию allowNet = self.clVars.Get("os_net_allow") @@ -20281,7 +20287,7 @@ class servDhcp(shareLdap, shareIP): if [x for x in dataMinMaxIP if isRange(minNumber, x[0], x[1]) and isRange(maxNumber, x[0], x[1])]: return True self.printERROR("Can not found network %s in network interfaces: \ -eth0, eth1, ... etc."%net) + eth0, eth1, ... etc."%net) if osNets: self.printWARNING(_("Existing nets: %s") % osNets) return False diff --git a/pym/cl_profile.py b/pym/cl_profile.py index 7985f78..c6c4322 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -4535,7 +4535,7 @@ class dovecot(bind): def __init__(self, text): bind.__init__(self,text) - def postXML(self, xmlArea=False): + def postXML(self, xmlArea=None): """Последующая постобработка XML""" # Добавляем перевод строки если его нет в конец области if xmlArea is None: From c23f429c8ae9088a8f8a4238a072f95ff2e4a5ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Wed, 15 Sep 2021 10:44:47 +0300 Subject: [PATCH 21/24] fixed xml in xfce format --- pym/cl_base.py | 31 +++++++++++++++---------------- pym/cl_ldap.py | 16 ++++++++-------- pym/cl_log.py | 14 +++++++------- pym/cl_profile.py | 4 ++-- pym/cl_utils.py | 2 +- 5 files changed, 33 insertions(+), 34 deletions(-) diff --git a/pym/cl_base.py b/pym/cl_base.py index a99f440..cfe2437 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -641,17 +641,17 @@ class DataVars(): pass # добавляем пути к модулям если они не добавлены if not os.path.abspath(\ - '/usr/lib/calculate/calculate-server/pym') in sys.path: + '/usr/lib/calculate/calculate-server/pym') in sys.path: sys.path.insert(0,os.path.abspath(\ - '/usr/lib/calculate/calculate-server/pym')) + '/usr/lib/calculate/calculate-server/pym')) if not os.path.abspath(\ - '/usr/lib/calculate/calculate-lib/pym') in sys.path: + '/usr/lib/calculate/calculate-lib/pym') in sys.path: sys.path.insert(0,os.path.abspath(\ - '/usr/lib/calculate/calculate-lib/pym')) + '/usr/lib/calculate/calculate-lib/pym')) if not os.path.abspath(\ - '/usr/lib/calculate/calculate-builder/pym') in sys.path: + '/usr/lib/calculate/calculate-builder/pym') in sys.path: sys.path.insert(0,os.path.abspath(\ - '/usr/lib/calculate/calculate-builder/pym')) + '/usr/lib/calculate/calculate-builder/pym')) # Импортируемые модули - (раздел: модуль переменных, модуль заполнения #переменных) __modlist={ @@ -699,7 +699,7 @@ class DataVars(): flagFindFillModule = False else: err1 = _("Error in import module %s")%modFill - err2 = _("error") + ": " +str(e) + err2 = _("error") + ": " + str(e) raise self.DataVarsError("%s\n%s"%(err1,err2)) if flagFindFillModule: # Создаем объект с методами заполнения переменных @@ -731,11 +731,11 @@ class DataVars(): if dataVar: break if dataVar == False: - err1 = _("Not found variable %s")%nameVar + err1 = _("Not found variable %s") % nameVar err2 = "" if err: err2 = _("error") + ": " +str(err) - raise self.DataVarsError("%s\n%s"%(err1, err2)) + raise self.DataVarsError("%s\n%s" % (err1, err2)) dataVar['service'] = section # Ищем метод в объекте методов заполнения nameMethod = "get_" + nameVar @@ -794,13 +794,12 @@ class DataVars(): return ret def Get(self, nameVar): - tmp = self.__Get(nameVar) - #TODO remove this - #DEBUG - isBytes = isinstance(tmp, bytes) - if isBytes: - print(f"DEBUG: var {nameVar} returned bytes value: {tmp}") - return tmp.decode("UTF-8") if isBytes else tmp + # tmp = self.__Get(nameVar) + # isBytes = isinstance(tmp, bytes) + # if isBytes: + # print(f"DEBUG: var {nameVar} returned bytes value: {tmp}") + # return tmp.decode("UTF-8") if isBytes else tmp + return self.__Get(nameVar) def __Set(self, nameVar, value, force=False): diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index bdf89b1..8cc7c1e 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -362,14 +362,14 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon, prnServ): 'Administrators':self.addInfoGroup('Administrators', '544', 'Domain Members can fully \ -administer the computer/sambaDomainName', + administer the computer/sambaDomainName', '544', '5', "S-1-5-32-544"), 'Account Operators':self.addInfoGroup('Account Operators', '548', 'Domain Users to manipulate \ -users accounts', + users accounts', '548', '5', "S-1-5-32-548"), @@ -388,14 +388,14 @@ users accounts', 'Backup Operators':self.addInfoGroup('Backup Operators', '551', 'Domain Members can bypass \ -file security to back up files', + file security to back up files', '551', '5', "S-1-5-32-551"), 'Replicators':self.addInfoGroup('Replicators', '552', 'Domain Supports file replication \ -in a sambaDomainName', + in a sambaDomainName', '552', '5', "S-1-5-32-552"), @@ -1128,7 +1128,7 @@ in a sambaDomainName', searchUser = self.searchLdapDN(userName, self.relUsersDN, attr) if not searchUser: self.printERROR(_("User") + " " + str(userName) + " "+\ - _("not found")) + _("not found")) return False modAttrs = [] if not self.dataIsJpeg(photoData): @@ -1147,14 +1147,14 @@ in a sambaDomainName', retcode = pipe.wait() if retcode != 0: self.printERROR(_("Can not convert file '%s' in jpeg format")\ - %photoPath) + % photoPath) flagError = True fErr.close() if not flagError: photoData = fOut.read() if not self.dataIsJpeg(photoData): self.printERROR(\ - _("Can not convert file '%s' in jpeg format") %photoPath) + _("Can not convert file '%s' in jpeg format") % photoPath) flagError = True fOut.close() if flagError: @@ -14953,7 +14953,7 @@ with another option.")) # Изменяем значения аттрибутов для вывода на печать #modUserAttr already decodes ldapValue[0] = self.modUserAttr(attr, ldapValue[0], - service) + service) flagFirst = False for value in ldapValue: if not flagFirst: diff --git a/pym/cl_log.py b/pym/cl_log.py index 6256b3c..d6aca9c 100644 --- a/pym/cl_log.py +++ b/pym/cl_log.py @@ -33,27 +33,27 @@ class log(): fd = os.open(self.logFile, os.O_CREAT,0o600) os.close(fd) except: - print("Error creating file %s"%self.logFile) + print("Error creating file %s" % self.logFile) return False textWrite = textLog if not textLog[-1:] == "\n" : - textWrite = "%s\n"%textLog + textWrite = "%s\n" % textLog if self.addDataTime: - textWrite = "%s %s"%(time.strftime("%d/%m/%Y %H:%M:%S",\ - time.localtime()),textWrite) + textWrite = "%s %s" % (time.strftime("%d/%m/%Y %H:%M:%S",\ + time.localtime()), textWrite) try: FD = open (self.logFile, "a") FD.write(textWrite) FD.close() except: - print("Error writing to file %s"%self.logFile) + print("Error writing to file %s" % self.logFile) return False return True def writeError(self, textLog): """Добавляет сообщение об ошибке в log""" - return self.addLog("ERROR: %s" %textLog) + return self.addLog("ERROR: %s" % textLog) def writeSuccess(self, textLog): """Добавляет сообщение об успехе в log""" - return self.addLog("SUCCESS: %s" %textLog) + return self.addLog("SUCCESS: %s" % textLog) diff --git a/pym/cl_profile.py b/pym/cl_profile.py index c6c4322..03773f1 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -5670,9 +5670,9 @@ class xml_xfce(_error): # Объединение нод if flagJoin: if "value" in nextOldNode.keys(): - oValue = nextOldNode.getAttribute("value") + oValue = nextOldNode.get("value") if nValue != oValue: - nextOldNode.setAttribute("value", nValue) + nextOldNode.set("value", nValue) # Замещение ноды elif flagReplace: replaceXmlNode = deepcopy(xmlNode) diff --git a/pym/cl_utils.py b/pym/cl_utils.py index 4087fda..5c0190e 100644 --- a/pym/cl_utils.py +++ b/pym/cl_utils.py @@ -606,4 +606,4 @@ def getIpNet(ip,mask=None,cidr=None): mask = cidrToMask(net) mask = strIpToIntIp(mask) return "{ip}/{net}".format(ip=intIpToStrIp(ip&mask), - net=net) + net=net) From c2d56e2aaeef74c9a01b94e4c7b82ad3f14cfb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Wed, 15 Sep 2021 11:03:03 +0300 Subject: [PATCH 22/24] Fixed getMachine --- pym/cl_ldap.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 8cc7c1e..0178857 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -14935,7 +14935,6 @@ with another option.")) attributes = [x[0] for x in data] retrAttrs = [x[1] for x in data] retClVars = False - #TODO check encoding searchRes = self.getQueryLDAP(service, "computers", searchAttr, searchStr, retrAttrs) if searchRes == False: @@ -14960,14 +14959,14 @@ with another option.")) data.append((attrName, value)) flagFirst = True else: - data.append(("", value.decode("UTF-8"))) + data.append(("", value)) if service == "samba" and attr == "gidNumber": memberGroups = self._getUserMemberGroups(machName, service) attrApp = _("Supplementary groups") if service == "samba": if value: - memberGroups.insert(0, value.decode("UTF-8")) + memberGroups.insert(0, value) flagFirst = False for member_group in memberGroups: if not flagFirst: From 85c655bc8fc1daae8deccad1330fcf4acdb446fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Thu, 16 Sep 2021 09:40:32 +0300 Subject: [PATCH 23/24] minor clean up --- pym/cl_ldap.py | 8 ++++---- scripts/sortmilter | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index 0178857..95176e7 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -7600,7 +7600,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) fullHostName = options['host'] if not "." in fullHostName: fullHostName = "%s.%s" %(fullHostName, - self.clVars.Get('os_net_domain')) + self.clVars.Get('os_net_domain')) self.clVars.Set("sr_proxy_host",fullHostName,True) # Настройка почты if serviceUpdate in ["all","mail"]: @@ -7641,7 +7641,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) newHostName = options['host'] if not "." in newHostName: newHostName = "%s.%s" %(newHostName, - self.clVars.Get('os_net_domain')) + self.clVars.Get('os_net_domain')) if newHostName != previousJabberHost: # Устанавливаем перемемнную self.clVars.Set("sr_jabber_host",newHostName,True) @@ -7660,7 +7660,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) apHost = host if not "." in host: apHost = "%s.%s" %(host, - self.clVars.Get('os_net_domain')) + self.clVars.Get('os_net_domain')) jabberHostsList.append(apHost) unicHostsList = [] for host in jabberHostsList: @@ -7699,7 +7699,7 @@ outdated. If the backup is obsolete, use cl-backup-server.")) adminPw = ldapParser.getVar(servicePwd,"PASS") if not adminPw: self.printERROR(_("Not found password from service %s")\ - %servicePwd) + %servicePwd) flagError = True break self.clVars.Set("ld_%s_pw"%servicePwd, adminPw, True) diff --git a/scripts/sortmilter b/scripts/sortmilter index 96df376..cc43e59 100755 --- a/scripts/sortmilter +++ b/scripts/sortmilter @@ -120,7 +120,7 @@ class Letter: self.cacheReceiver = None # letter by filename if file: - content = open(file,"r").read() + content = open(file, "r").read() self.filepath = file self.mail = message_from_string(content) # letter by content @@ -186,7 +186,7 @@ class Letter: charset = self.mail.get_charsets() # if charset specified and it is not utf-8 try: - if charset and charset[0] and not charset[0].lower() in ['utf-8','utf8']: + if charset and charset[0] and not charset[0].lower() in ['utf-8', 'utf8']: letter_text = letter_text.decode(charset[0]).encode('utf-8') except Exception as e: Logger().printDEBUG("wrong decode from %s: %s" % (charset[0], e)) @@ -359,7 +359,7 @@ class MailBox: def fixMtime(self): # fix mtime of mailbox directory by date (latest letter) - os.utime(self.getDirectory(),(self.date,)*2) + os.utime(self.getDirectory(),(self.date,) * 2) def getDirectory(self): """Get full path to mail box""" From e0aee0dd88769ff155742679380a2534bb7e260a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=20=D0=94=D0=B7=D1=8E=D0=B1=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE?= Date: Thu, 16 Sep 2021 09:46:13 +0300 Subject: [PATCH 24/24] Fixed pam cracklib passwdqc --- profile/unix/etc/pam.d/system-auth | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/profile/unix/etc/pam.d/system-auth b/profile/unix/etc/pam.d/system-auth index 96ed33a..c31e735 100644 --- a/profile/unix/etc/pam.d/system-auth +++ b/profile/unix/etc/pam.d/system-auth @@ -9,7 +9,13 @@ auth required pam_deny.so account required pam_unix.so account sufficient pam_ldap.so - + +#?pkg(cracklib)!=# +password required pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 try_first_pass retry=3 +#pkg# +#?pkg(passwdqc)!=# +password required pam_passwdqc.so min=8,8,8,8,8 retry=3 +#pkg# password required pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 try_first_pass retry=3 password sufficient pam_unix.so try_first_pass use_authtok nullok md5 shadow