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"),