diff --git a/pym/cl_base.py b/pym/cl_base.py index b36b210..3554577 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -403,16 +403,7 @@ class fillVars: #Вернуть результат выполнения команды ОС def __runos(self,cmd,ret_first=None): - res=None - res=os.popen(cmd).readlines() - if res: - if len(res)>1: - if ret_first: - return res[0] - return res - else: - return res[0].strip() - + return cl_utils.runOsCommand(cmd, None, ret_first) def __getinifile(self,fname,def_sect): s=ConfigParser.ConfigParser() diff --git a/pym/cl_utils.py b/pym/cl_utils.py index e1cc6e9..b4285e2 100644 --- a/pym/cl_utils.py +++ b/pym/cl_utils.py @@ -17,9 +17,11 @@ import filecmp import string from random import choice -from re import search +from re import search, compile, S import os import types +import popen2 +import types def getdirlist(s_path): #Получить список директорий по указаному пути @@ -27,6 +29,159 @@ def getdirlist(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 + for i in xrange(0,len(cols),2): + if type(cols[i]) == types.UnicodeType: + noconvert = True + 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 brfind != None: + # для текущего вывода в колонку + # берем часть строки до перевода + partstr = partstr[:brfind.start()] + # остальная часть идет в остаток (без перевода) + cols[q] = cols[q][brfind.start()+1:] + # если используется перевод каретки + if brfind.group() == '\r': + # то выравниваем по ширине колонки + partstr = justify(partstr, cols[q+1]) + else: + # добавить отступы чтобы закончить колонку + partstr = partstr.ljust(cols[q+1], ' ') + # если взята часть строки + elif len(partstr) == cols[q+1]: + # если взята часть строки (разрыв в слове) + 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 = justify(partstr, cols[q+1]) + # остатки строки + else: + # добавить отступы чтобы закончить колонку + partstr = partstr.ljust(cols[q+1], ' ') + cols[q] = '' + + # добавить к возвращаемой строки полученную + пробел + if noconvert: + retstr+= partstr + u' ' + else: + retstr+= partstr.encode('utf8') + " " + # остальную часть строки оставить на следующую итерацию + # если от строки что то осаталось + if len(cols[q]) > 0: + # отметить запуск еще одной итерации по параметрам + repeat = True + # следующая пара + q += 2 + # колонки отображены + retstr += "\n" + return retstr + +def columnStr(*cols): + '''Вывод данных по колонкам, причем, если данные не вмещаются в указнаную + колонку, то они переносятся на следующую строку в нужную колонку. В строку. + + Параметры: + cols множестово пар: текст, ширина колонки, причем, если у последней + колонки не указывать ширину, то она будет выведена вся. + + Возвращаемые параметры: + строка, которую можно использовать для вывода на экран + + Пример: columnWrite( "Some text", 10, "Next column", 20 ) + ''' + retstr = "" + # перевести кортеж в список, т.к. изменяется + cols = list(cols) + # перевести текст в юникод, заодно перевести числа в строку + for i in xrange(0,len(cols),2): + cols[i] = (str(cols[i])).decode('utf8') + + # флаг "есть еще текст для вывода" + repeat = True + while repeat: + # сбросить итератор на первый элемент + q = 0 + repeat = False + # пока не закончили перебирать параметры (перебираем по парам) + while q < len(cols): + # если это последний параметр, и для него не указана ширина + if q == len(cols)-1: + # выводим его полностью не смотря на ширину окна + retstr += cols[q] + " " + cols[q] = '' + else: + # вывести часть строки не больше указанной ширины колонки + retstr+=(cols[q][:cols[q+1]].ljust(cols[q+1])).encode('utf8') \ + + " " + # остальную часть строки оставить на следующую итерацию + cols[q] = cols[q][cols[q+1]:] + # если от строки что то осаталось + if len(cols[q]) > 0: + # отметить запуск еще одной итерации по параметрам + repeat = True + # следующая пара + q += 2 + # колонки отображены + retstr += "\n" + return retstr + def columnWrite(*cols): '''Вывод данных по колонкам, причем, если данные не вмещаются в указнаную колонку, то они переносятся на следующую строку в нужную колонку. @@ -85,7 +240,12 @@ def justify(s,width): return s pos = 0 # переводим в юникод для правильного вычисления длины - s = s.decode( 'utf-8' ) + try: + s = s.decode( 'utf-8' ) + needConver = True + # пропуск если это не utf-8 + except UnicodeEncodeError: + needConver = False # пока длина строки меньше указанной while len(s) < width: # находим очередной пробел @@ -97,8 +257,36 @@ def justify(s,width): s = s[:pos] +' ' +s[pos:] # оставить удвоенный пробел pos += 3 - # вернуть строку в utf - return s.encode('utf-8') + # вернуть строку в utf если она пришла в utf8 + if needConver: + return s.encode('utf-8') + else: + return s + +def runOsCommand(cmd, inStr=None, ret_first=None): + """Выполняет внешнюю программу + + Параметры: + cmdStrProg внешняя программа + inStr данные передаваемые программе на страндартный вход. + ret_first вернуть только первую строку + Возвращаемые параметры: + строка/строки которую выведет внешняя программа + """ + fout, fin = popen2.popen2(cmd) + # если есть данные на вход, передать их + if inStr: + fin.write(inStr) + fin.close() + res = fout.readlines() + if res: + if len(res) > 1: + if ret_first: + return res[0] + else: + return res + else: + return res[0].strip() def genpassword(passlen=9): @@ -115,7 +303,7 @@ def genpassword(passlen=9): return res def fillstr(char, width): - '''Заполнить строку указанным числом символов. Псеводоник символ*кол-во''' + '''Заполнить строку указанным числом символов. Псеводоним символ*кол-во''' return str(char) * width #вернуть пути для запуска утилит @@ -301,3 +489,10 @@ def convertStrListDict(val): # если это просто строка else: return val + +def _toUNICODE(val): + """перевод текста в юникод""" + if type(val) == types.UnicodeType: + return val + else: + return str(val).decode('UTF-8')