色々言語を勉強して、ツールを作るときに毎度毎度作成する自分のライブラリ
io.ioutil.py
# -*- coding:utf-8 -*-
from typing import List,Callable,Tuple
import os
import os.path
from ..excollections.elist import Enumerable as Elist
import re
import shutil
from pathlib import Path
class DirectoryNotFoundError(Exception):
pass
class DirectoryExistsError(Exception):
pass
def file_exists(file:str) -> bool:
return os.path.isfile(file)
def dir_exists(dirpath:str) -> bool:
return os.path.isdir(dirpath)
def file_exists_with_exp(file:str) -> None:
if not file_exists(file):
raise FileNotFoundError("ファイルがありません:" + file)
def dir_exists_with_exp(dirpath:str) -> None:
if not dir_exists(dirpath):
raise DirectoryNotFoundError("ディレクトリがありません:" + dirpath)
def _curry_path_join(dirpath:str) -> Callable[[str],str]:
dir_exists_with_exp(dirpath)
def f(file:str):
return os.path.join(dirpath,file)
return f
def file_dir_divide(dirpath:str) -> Tuple[List[str],List[str]]:
dir_exists_with_exp(dirpath)
et,ef = Elist(os.listdir(dirpath)).select(_curry_path_join(dirpath)).divide(os.path.isfile)
return (et.tolist(),ef.tolist())
def find_file(dirpath:str,filterfunc:Callable[[str],bool]) -> List[str]:
fs,_ = file_dir_divide(dirpath)
return Elist(fs).where(filterfunc).tolist()
def find_dir(dirpath:str,filterfunc:Callable[[str],bool]) -> List[str]:
_,ds = file_dir_divide(dirpath)
return Elist(ds).where(filterfunc).tolist()
def find_file_recur(dirpath:str,filterfunc:Callable[[str],bool]) -> List[str]:
ds = find_dir_recur(dirpath,PathFilter.all())
ds.append(dirpath)
def f(acc:List[str],d:str) -> List[str]:
acc.extend(find_file(d,filterfunc))
return acc
return Elist(ds).aggregate([],f)
def find_dir_recur(dirpath:str,filterfunc:Callable[[str],bool]) -> List[str]:
dir_exists_with_exp(dirpath)
return Elist(_find_dir_recur(dirpath)).where(filterfunc).tolist()
def _find_dir_recur(dirpath:str) -> List[str]:
ds = find_dir(dirpath,PathFilter.all())
r:List[str] = []
for d in ds:
r.extend(_find_dir_recur(d))
r.extend(ds)
return r
class PathFilter:
@staticmethod
def all() -> Callable[[str],bool]:
def f(path:str):
return True
return f
@staticmethod
def extension(ext:str) -> Callable[[str],bool]:
def f(path:str):
return path.endswith("." + ext)
return f
@staticmethod
def regex(r:str) -> Callable[[str],bool]:
def f(path:str):
return re.search(r,os.path.basename(path)) != None
return f
def file_copy_file_specify(ff:str,tf:str,force:bool=True) -> bool:
file_exists_with_exp(ff)
if os.path.isdir(tf):
raise DirectoryExistsError(tf)
parent = Path(tf).parent
if os.path.isdir(parent):
if force:
shutil.copy(ff,tf)
return True
else:
if not os.path.exists(tf):
shutil.copy(ff,tf)
return True
else:
return False
else:
raise DirectoryNotFoundError(parent)
def file_copy_file_specify_reg(fd:str,ffreg:str,tf:str,selectFunc:Callable[[List[str]],str|None],force:bool=True) -> bool:
DirectoryExistsError(fd)
parent = Path(tf).parent
if os.path.isdir(parent):
raise DirectoryNotFoundError(parent)
if os.path.isdir(tf):
raise DirectoryExistsError(tf)
if (not force) and os.path.isfile(tf):
return False
ffs = find_file(fd,PathFilter.regex(ffreg))
ff = selectFunc(ffs)
if ff == None:
return False
shutil.copy(os.path.join(fd,ff),tf)
return True