PK!22cjk_commons/__about__.py__version__ = '3.3.4' PK!誠覗oocjk_commons/__init__.py# -*- coding: utf-8 -*- # noinspection PyUnresolvedReferences from cjk_commons.__about__ import __version__ PK!渽$cjk_commons/logging_.py# -*- coding: utf-8 -*- # noinspection PyUnresolvedReferences import logging from pathlib import Path def add_logging_arguments(parser) -> None: parser.add_argument( '-l', '--level', nargs='?', help='Set log\'s level' ) parser.add_argument( '--log-file', nargs='?', help='Set log file' ) parser.add_argument( '--log-file-level', nargs='?', help='Set log file\'s level' ) def add_loggers(args, main_logger: logging.Logger, log_file_name: str = '') -> None: # noinspection PyUnresolvedReferences formatter: logging.Formatter = logging.Formatter( '[%(asctime)s,%(msecs)03d][%(name)s:%(lineno)d][%(levelname)s] %(message)s', datefmt='%y-%m-%d %H:%M:%S') if args.level is not None: level_str = args.level else: level_str = 'INFO' level_str = level_str.upper() level_int = getattr(logging, level_str, None) if not isinstance(level_int, int): raise ValueError('Invalid log level \'{0}\''.format(level_str)) # noinspection PyUnresolvedReferences ch: logging.StreamHandler = logging.StreamHandler() ch.setLevel(level_int) ch.setFormatter(formatter) main_logger.addHandler(ch) if args.log_file is not None: log_file_path = Path(args.log_file) if log_file_path.is_dir(): if Path(log_file_name).stem == log_file_name: log_file_name += '.log' log_file_path = Path(log_file_path, log_file_name) if args.log_file_level is not None: log_file_level_str = args.log_file_level else: log_file_level_str = 'INFO' log_file_level_str = log_file_level_str.upper() log_file_level_int = getattr(logging, log_file_level_str, None) if not isinstance(log_file_level_int, int): raise ValueError('Invalid log file level \'{0}\''.format(log_file_level_str)) # noinspection PyUnresolvedReferences fh: logging.FileHandler = logging.FileHandler(log_file_path) fh.setLevel(log_file_level_int) fh.setFormatter(formatter) main_logger.addHandler(fh) PK!娆Zcjk_commons/settings.py# -*- coding: utf-8 -*- from collections import OrderedDict from pathlib import Path from typing import Any from appdirs import site_data_dir, user_data_dir import yaml import yodl def get_attribute( kwargs: dict, kwargs_key: str, settings: OrderedDict = None, settings_key: str = None, default: Any = None, type_: type = str, allow_none: bool = False) -> Any: result = None type__ = type_ if default is not None: type__ = type(default) if kwargs_key in kwargs: result = kwargs[kwargs_key] if not isinstance(result, type__) and default is not None: raise TypeError('{0}'.format(kwargs_key) if kwargs_key else None) if settings is not None and settings_key is not None: if settings_key in settings: result = settings[settings_key] if not isinstance(result, type__) and default is not None: raise TypeError('{0}'.format(settings_key) if settings_key else None) if result is None: result = default if result is None and not allow_none: raise AttributeError('{0}'.format(settings_key)) return result def get_path_attribute( kwargs: dict, kwargs_key: str, settings: OrderedDict = None, settings_key: str = None, default_path: Path = None, is_dir: bool = True, check_if_exists: bool = True, create_dir: bool = True, create_parents: bool = True) -> Path: result = None if kwargs_key in kwargs: result = kwargs[kwargs_key] if not isinstance(result, Path): raise TypeError('{0}'.format(kwargs_key) if kwargs_key else None) elif settings is not None and settings_key is not None: if settings_key in settings: result_str = settings[settings_key] if not isinstance(result_str, str): raise TypeError('{0}'.format(settings_key) if settings_key else None) result = Path(result_str) if not isinstance(result, Path): raise TypeError('{0}'.format(settings_key) if settings_key else None) if result is None and isinstance(default_path, Path): result = default_path if result is None: raise AttributeError('{0}'.format(settings_key)) if result.exists(): if not is_dir and result.is_dir(): raise FileExistsError('{0} Not A File'.format(kwargs_key) if kwargs_key else None, result) elif is_dir and result.is_file(): raise NotADirectoryError('{0}'.format(kwargs_key) if kwargs_key else None, result) else: if check_if_exists: raise FileExistsError('{0}'.format(kwargs_key) if kwargs_key else None, result) if is_dir and create_dir: result.mkdir(parents=create_parents) return result class SettingsError(Exception): """Settings Error""" def get_settings(file_path=Path('settings.yaml'), **kwargs) -> OrderedDict: if not file_path.is_file(): app_name = get_attribute(kwargs, 'app_name', allow_none=True) app_author = get_attribute(kwargs, 'app_author', allow_none=True) file_path = Path(user_data_dir(app_name, app_author, roaming=True), file_path.name) if not file_path.is_file(): file_path = Path(site_data_dir(app_name, app_author), file_path.name) if file_path.is_file(): with file_path.open(encoding='utf-8') as settings_file: settings = yaml.load(settings_file, yodl.OrderedDictYAMLLoader) if settings is None: settings = OrderedDict() else: settings = OrderedDict() return settings class OrderedDictMergeException(Exception): """Ordered Dict Merge Exception""" def merge(a: dict, b: dict, path=None) -> dict: if path is None: path = [] for key in b: if key in a: if isinstance(a[key], dict) and isinstance(b[key], dict): merge(a[key], b[key], path + [str(key)]) elif a[key] == b[key]: pass else: raise OrderedDictMergeException('Conflict at \'{0}\''.format('.'.join(path + [str(key)]))) else: a[key] = b[key] return a PK!#萇灹cjk_commons/zip.py# -*- coding: utf-8 -*- import os from pathlib import Path import time from typing import List import zipfile def extract_from_zip(zip_path: Path, dir_path: Path) -> None: with zipfile.ZipFile(zip_path) as zip_file: for zip_member in zip_file.infolist(): zip_file.extract(zip_member, dir_path) zip_member_time = time.mktime(zip_member.date_time + (0, 0, -1)) os.utime(Path(dir_path, zip_member.filename), (zip_member_time, zip_member_time)) def write_to_zip(zip_path: Path, in_path: Path, file_paths: List[Path] = None) -> float: with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zip_file: mtime = -1. if in_path.is_file(): zip_file.write(in_path, in_path.name) mtime = in_path.stat().st_mtime elif in_path.is_dir(): if not file_paths: file_paths = [] for root, dirnames, filenames in os.walk(str(in_path)): for filename in filenames: file_paths.append(Path(root, filename)) for file_path in file_paths: if file_path.is_file(): zip_file.write(file_path, file_path.relative_to(in_path)) file_stat_result = file_path.stat() # todo if mtime < file_stat_result.st_mtime: mtime = file_stat_result.st_mtime return mtime PK!H腾絋U!cjk_commons-3.3.4.dist-info/WHEEL 蔄 薪ю#Z;/"⒅d&F[x鹺雡蹳Z硃戳y3仭〾F歷隴\fi4WZ^E蒰碝_-]#0(q7PK!HBfβq$cjk_commons-3.3.4.dist-info/METADATA晵KO翤咓吃凬AP崍 墍剣壦苯柫蚊y@絻鮍肂w潪餃;鱠︵X罼甦J蝖'1)啥痲P褾_r梫i/Zz!槱R2;% 脂@燮9m$)港鴊 扇o斋J>&<i潕W=T{er嬻jy栎F>戈c 傫∶想"淏v磤7 豿^!7己煲~k校韍T2k L粎擩 悗,s迴4%=鞝亷機N> 3d砬l終 朿2在Z用v焤2冕啎d耫岜怖.<蔐6腹Q卆BpY4貜E肳骺<7+劌zq{f鄃K巧点%w靪穹芎0錳8潗摣藄趇 .h7麓喂眮樾^kpv劑T^~赖稅箈綐`O爼錘櫔鯂圅PK!H蓑b"cjk_commons-3.3.4.dist-info/RECORD}猩R獲@呀憂媾[腀D"螃 0訍f綦玠満u营F)n[軕g剴<鷯"Ey醎肅64敏艓吻y(辡砚P5nVo}後蹪K慚(>;式1n9<鑒稷ΩV!标u蔵獾踏烦:`58纤.蛪X慩艴们r"_L毘韋釃U$偶鳑牭謦 BV貀$莖忟騌 愫 `S斗k伿镀棖幆撈 嬷┕Q戧Xa妰捈缶漱/C渚: 6.赖SF鶮衻b烁o 8qw巉靵;|杁に顜]U?藫=_騥嘕15#V$J踗L縪:赖$﨩識荩rt?舨TK9濐琽}们怲g,#況錰'2uwv(戝o晟)豸PK!22cjk_commons/__about__.pyPK!誠覗ooMcjk_commons/__init__.pyPK!渽$cjk_commons/logging_.pyPK!娆Z cjk_commons/settings.pyPK!#萇灹cjk_commons/zip.pyPK!H腾絋U! cjk_commons-3.3.4.dist-info/WHEELPK!HBfβq$\!cjk_commons-3.3.4.dist-info/METADATAPK!H蓑b"#cjk_commons-3.3.4.dist-info/RECORDPKF$