diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a46123b --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# ALL FILE Ignore +* + +# Use Dir Register +!*/ + +# Ignore Dir Register +__pycache__/ +build/ +dist/ +*.egg-info/ + +# Use File Register +!.gitignore +!*.md +!*.py +!*.in +!LICENSE diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..c1a7121 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,2 @@ +include LICENSE +include README.md diff --git a/pykun/__init__.py b/pykun/__init__.py new file mode 100644 index 0000000..57ab2be --- /dev/null +++ b/pykun/__init__.py @@ -0,0 +1,7 @@ + + +__author__ = "kunrunic (kunrunic7272@gamil.com)" +__version__ = "0.1.0" +__copyright__ = "Copyright (c) 2021 kunrunic" +__license__ = "MIT" + diff --git a/pykun/file/__init__.py b/pykun/file/__init__.py new file mode 100644 index 0000000..22a12dc --- /dev/null +++ b/pykun/file/__init__.py @@ -0,0 +1,2 @@ + +__all__ = [ "configure", "copier", "log" ] diff --git a/pykun/file/configure.py b/pykun/file/configure.py new file mode 100644 index 0000000..c3fea3e --- /dev/null +++ b/pykun/file/configure.py @@ -0,0 +1,60 @@ +#-*- coding:utf-8 -*- +import json + +class DictUpper(object): + __slots__ = ["__funcs","__data"] + def __init__(self): + self.__funcs = {list:self._list, dict:self._dict} + self.__data = list() + + @property + def funcs(self): + return self.__funcs + + def _dict( self, data ): + val = dict() + for dName, dVal in data.items(): + try : + val[dName.upper()] = self.funcs[type(dVal)](dVal) + except: + val[dName.upper()] = dVal + return val + + + def _list( self, data ): + val = list() + for item in data: + try : + val.append(self.funcs[type(item)](item)) + except: + val.append(item) + return val + + #Multi data 처리 + def process( self, data ): + return self.funcs[type(data)](data) + +def isJson(data): + try : + json.loads(data) + except ValueError : + return False + return True + +def read(data): + if isJson(data) == True : + jData = json.loads(data) + # Dict 경우 key의 값을 대문자로 변경한다. + dictUpper = DictUpper() + return dictUpper.process(jData) + elif data.find("/") < 0 : + raise ValueError("Not Supported Format [{0}]".format(data)) + + with open(data,'r') as conf: + return json.loads(conf.read()) + +if __name__ == "__main__" : + data = read('{"data":[{"key":"val", "key2":"val2", "KeY3":"Val3"}]}') + print("result :",data) + data = read('{"Data":[{"Key":"INVITE","vaL":"TTT","OpT":"T."}, {"key":"from","val":"ttfrom","opt":"T<"}]}') + print("result :",data) \ No newline at end of file diff --git a/pykun/file/copier.py b/pykun/file/copier.py new file mode 100644 index 0000000..6bca6bf --- /dev/null +++ b/pykun/file/copier.py @@ -0,0 +1,280 @@ +#-*- coding:utf-8 -*- +import sys +import os +import time +from os import path +import shutil +'''pkgs in Pykun''' +from pykun.file import log as logger +from pykun.file import configure as cfg + +class MatchInfo(object): + """ This Class is information carrier. + it's handled option about match key and convert value used in Reproducer + """ + __solts__ = ["__convertKey", "__convertVal", "__option"] + def __init__(self, convertKey, convertVal, option): + self.__convertKey = convertKey + self.__convertVal = convertVal + self.__option = option + + def __str__(self): + return "KEY:[{0}], VAL:[{1}], OPT:[{2}]".format(self.key, self.val, self.opt) + + @property + def key(self): + return self.__convertKey + @property + def val(self): + return self.__convertVal + @property + def opt(self): + return self.__option + + +class Reproducer(object): + """ This Class is Reproducer about file. + Find the ''KEY'' value of ''MatchInfo'' in the file and change it to ''VAL'' according to ''OPT''. + Create a file with the changed information. + """ + __slots__ = ["__factors", "__converts", "__match", "__writeOptionMap"] + def __init__(self): + self.__factors = list() + self.__converts = list() + self.__match = False + self.__writeOptionMap = { + "T^": self._textUp, + "T_": self._textDown, + "T<": self._textBefore, + "T>": self._textAfter, + "T.": self._textCurrent, + } + @property + def factors(self): + return self.__factors + @factors.setter + def factors(self, items): + def _cvtToMatchInfoForDict(): + try : + val = items["DATA"] + if isinstance(val, list) == False : + raise SyntaxError("Unknow Format") + return val + except KeyError : + raise SyntaxError("Unknow Format") + #make MatchInfo Instance + for item in _cvtToMatchInfoForDict(): + self.__factors.append( MatchInfo(item["KEY"].encode("ascii"), item["VAL"].encode("ascii"), item["OPT"])) + @property + def converts(self): + return self.__converts + @converts.setter + def converts(self, item): + self.__converts.append(item) + @property + def match(self): + return self.__match + @match.setter + def match(self, flag): + self.__match = flag + + def __iter__(self): + return iter(self.converts) + + def _textUp(self, line, mInfo): + return "{0}\n{1}".format(mInfo.val.decode('ascii'), line.decode('ascii')).encode('ascii') + + def _textDown(self, line, mInfo): + return "{0}{1}\n".format(line.decode('ascii'), mInfo.val.decode('ascii')).encode('ascii') + + def _textCurrent(self, line, mInfo): + return line.replace(mInfo.key, mInfo.val) + + def _textBefore(self, line, mInfo): + sPos = line.find(mInfo.key) + return b"".join([line[:sPos], mInfo.val, line[sPos:]]) + + def _textAfter(self, line, mInfo): + sPos = line.find(mInfo.key) + ePos = sPos + len(mInfo.key) + return b"".join([line[:ePos], mInfo.val, line[ePos:]]) + + def _convert(self, line, matchList): + if len(matchList) <= 0 : + return line + + self.match = True + cvtLine = line + for mInfo in matchList: + cvtLine = self.__writeOptionMap[mInfo.opt](cvtLine, mInfo) + return cvtLine + + def process(self, line): + self.converts = self._convert( line, [mInfo for mInfo in self.factors if line.find(mInfo.key) > -1] ) + + def write(self, path): + os.rename(path, "{0}_{1}_bk".format(path, time.strftime('%Y_%m_%d_%X', time.localtime(time.time())))) + with open(path, "wb") as w: + for line in self: + w.write(line) + print("ok ... Write : {0}".format(path)) + +def makeIter( data ): + if isinstance(data, dict) == True: + data = data.items() + for val in data : + yield val + +def convertFile(sPath, dPath, factors): + if sPath.endswith("_bk") == True : + return + reproducer = Reproducer() + reproducer.factors = factors + with open(sPath, "rb") as p: + for lino, line in enumerate(makeIter(p)): + reproducer.process(line) + if reproducer.match == True : + reproducer.write(dPath) + +def isDir( dirName ): + rv = path.isdir(dirName) + if rv == False : + raise OSError("ERROR : Atrribute isn't Dir : {dirName}".format(**locals())) + return dirName + +def searchFilesInDir( dirName ): + fNames = os.listdir(dirName) + if len(fNames) == 0 : + return [] + return fNames + +def cvtFilesSrcToDest( src, dest, factors ): + for name in searchFilesInDir(src): + try : + cvtFilesSrcToDest( + isDir("{src}/{name}".format(**locals())), + "{dest}/{name}".format(**locals()), + factors + ) + continue + except OSError : + pass + except Exception as e: + print(e) + srcName = "{src}/{name}".format(**locals()) + destName = "{dest}/{name}".format(**locals()) + convertFile( srcName, destName, factors) + +def compareLine( sIter, dIter ): + return [ (lino, "SRC >>", sLine, "DEST >>", dLine) for lino, (sLine, dLine) in enumerate(zip(sIter, dIter)) if sLine != dLine ] + +def diffFile_3x(srcPath, destPath): + with open(srcPath, "rb") as s , open(destPath, "rb") as d: + cmpResult = compareLine(makeIter(s), makeIter(d)) + if len(cmpResult) > 0 : + print("find ... Different : {srcPath} - {destPath}".format(**locals())) + logger.display(cmpResult, "Different") + return True + print("find ... Same : {srcPath} - {destPath}".format(**locals())) + return False + +def diffFile_2x(srcPath, destPath): + with open(srcPath, "rb") as s : + with open(destPath, "rb") as d: + cmpResult = compareLine(makeIter(s), makeIter(d)) + if len(cmpResult) > 0 : + print("find ... Different : {srcPath} - {destPath}".format(**locals())) + logger.display(cmpResult, "Different") + return True + print("find ... Same : {srcPath} - {destPath}".format(**locals())) + return False + +def cpFilesSrcToDest( src, dest, prefix ) : + diffFile = diffFile_2x + from platform import python_version + if python_version()[0] >= "3" : # version 3 + diffFile = diffFile_3x + + for name in searchFilesInDir(src): + try : + cpFilesSrcToDest( + isDir("{src}/{name}".format(**locals())), + "{dest}/{name}".format(**locals()), + prefix + ) + continue + except OSError: + pass + except Exception as e: + print(e) + if name.startswith(prefix) == True or prefix == False : + srcName = "{src}/{name}".format(**locals()) + destName = "{dest}/{name}".format(**locals()) + if diffFile(srcName, destName) == True: + print("ok ... Copy : {srcName} -> {destName}".format(**locals())) + shutil.copy2(srcName, destName) + +def copy(src, dest, prefix): + """ Process Directory files Copy + :param src : soruce directory + :param dest : destination directory + :param prefix : start file name + """ + try : + cpFilesSrcToDest( src, dest, prefix ) + except Exception as e: + print(e) + +def convert(src, dest, factors): + """ Process Directory files reproduce + :param src : soruce directory + :param dest : destination directory + :param factors : reproduce condition + """ + print("Process ...") + try : + cvtFilesSrcToDest(src, dest, cfg.read(factors)) + except Exception as e: + print(e) + +def quickHelp(): + print("Usege : copier [ option ] [ option arg ]") + print("Option :") + print("> cp - inputs [ src, dest, prefix ] ") + print("> cvt - inputs [src, dest, factors ] ... cvt factors input format is json") + print("> cvt factors format \'{\"DATA\":[{\"KEY\":\"CVT_MATCH_KEY\", \"VAL\":\"CVT_VAL\", \"OPT\":\"Insert Position\"}]}\' ") + print("> cvt factors option ") + print(">> [T^] - text added up") + print(">> [T_] - text added down") + print(">> [T<] - text before") + print(">> [T>] - text after") + print(">> [T.] - text convert") + +def quickMain(): + try : + src = sys.argv[2] + dest = sys.argv[3] + prefix = "" + isDir(src) + isDir(dest) + except OSError as e: + print(e) + return + except IndexError as e: + quickHelp() + return + + if sys.argv[1] == "cvt" : + if len(sys.argv) >= 5 : + factors = sys.argv[4] + convert(src, dest, factors) + elif sys.argv[1] == "cp" : + prefix = False + if len(sys.argv) >= 5 : + prefix = sys.argv[4] + copy(src, dest, prefix) + else : + quickHelp() + +if __name__ == "__main__": + quickMain() diff --git a/pykun/file/log.py b/pykun/file/log.py new file mode 100644 index 0000000..79b8066 --- /dev/null +++ b/pykun/file/log.py @@ -0,0 +1,55 @@ +#-*- coding : utf-8 -*- +class Distribute(object): + def __init__(self): + self.__layout = 0 + self.__funcs = {list:self._list, dict:self._dict} + + @property + def funcs(self): + return self.__funcs + + def _drowTab( self, tab, add=' |' ): + add = add * tab + return " {add}".format(**locals()) + + def _dict( self, data, tab ): + for idx, (dName, dVal) in enumerate(data.items(), 1): + #print(self.__layout, tab) + try : + if self.__layout < tab : + self.__layout = tab + print("{0} {1}".format(self._drowTab(tab),type(data))) + print("{0} \"{dName}\"".format(self._drowTab(tab), **locals())) + self.funcs[type(dVal)](dVal, tab+1) + except: + if self.__layout > tab : + self.__layout -= 1 + print("{0} | \"{dVal}\"<\'{dName} value\'>".format(self._drowTab(tab),**locals())) + + def _list( self, data, tab ): + for item in data: + #print(self.__layout, tab) + try : + if self.__layout < tab : + self.__layout = tab + print("{0} {1}".format(self._drowTab(tab),type(data))) + self.funcs[type(item)](item, tab+1 ) + except: + if self.__layout > tab : + self.__layout -= 1 + print("{0} \"{item}\"".format(self._drowTab(tab), **locals())) + + def process( self, data ): + self.funcs[type(data)](data, 1) + + +def display(data, title=None): + if title == None : + title = "Display" + print("< {title} >".format(**locals())) + distri = Distribute() + distri.process(data) + +if __name__ == "__main__" : + display([1,2,3,4,5,6,[7],0,0,0, [8]]) + display({"key":[1,2,3,4,5,6,[7,{"InKey_val_array":[9,9,9,9]}],0,{"K":"v","K2":[10,9,8,7],"K3":"v3"},0,0,[8]]}) \ No newline at end of file diff --git a/pykun/strControl.py b/pykun/strControl.py new file mode 100644 index 0000000..a1a84d3 --- /dev/null +++ b/pykun/strControl.py @@ -0,0 +1,7 @@ +def multi_replace( chars, string ): + for char in chars: + string = string.replace(char,'') + return string + +if __name__ == "__main__": + pass diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..6e347ce --- /dev/null +++ b/setup.py @@ -0,0 +1,28 @@ + +from setuptools import setup, find_packages + + + +setup(name='pykun', + + version='0.1.1', + + url='https://github.com/kunrunic/pykun', + + license='MIT', + + author='Jho Sung Jun', + + author_email='kunrunic7272@gmail.com', + + description='Develop a Callection of useful packages', + + packages=find_packages(), + + long_description=open('README.md').read(), + + zip_safe=False, + + setup_requires=[], + + test_suite='')