importloggingimportosfromshutilimportcopyfileobjfromrich.progressimporttracklogger=logging.getLogger("fastdev")def_ensure_directory(path:str):dirname=os.path.dirname(path)ifnotos.path.isdir(dirname):os.makedirs(dirname)def_truncate(text:str,length:int=15)->str:returntextiflen(text)<=lengthelsetext[:length-3]+"..."def_extract_zipfile(filename:str,extract_dir:str,remove_top_dir:bool=False):importzipfile# lazy importifnotzipfile.is_zipfile(filename):raiseValueError(f"{filename} is not a valid zip file.")withzipfile.ZipFile(filename)aszip:names=[info.filenameforinfoinzip.infolist()]# check if the zip file contains a common top-level directorycontain_top_dir=os.path.commonprefix(names).count("/")>0fornameintrack(names,description=_truncate(os.path.basename(filename))):# don't extract absolute paths or ones with .. in themifname.startswith("/")or".."inname:continueifremove_top_dirandcontain_top_dir:targetpath=os.path.join(extract_dir,*name.split("/")[1:])else:targetpath=os.path.join(extract_dir,*name.split("/"))ifnottargetpath:continue_ensure_directory(targetpath)ifnotname.endswith("/"):# filewithzip.open(name,"r")assource,open(targetpath,"wb")astarget:copyfileobj(source,target)
[docs]defextract_archive(filename:str,extract_dir:str,remove_top_dir:bool=False):"""Extract archive file to a directory. Currently only supports zip files. Args: filename (str): Local path to the archive file. extract_dir (str): Directory to extract the archive file. remove_top_dir (bool, optional): Whether to remove the top-level directory in the archive. If True, the top-level common prefix directory will be removed. Defaults to False. """logger.info(f"Extracting {filename} to {extract_dir}")ifos.path.splitext(filename)[-1]==".zip":_extract_zipfile(filename,extract_dir,remove_top_dir)else:raiseNotImplementedError(f"Unsupported archive format: {filename}")