def __list(self, parent: CDirTree, do_hash=False): assert isinstance(parent, CDirTree) path_names: List[str] = self.__fs.listdir(parent) parent_names: Tuple[str, ...] = parent.names # transform path into cpath, but don't do hash because: the file might already be ignored by a fs matcher # config file. hash in listing block child_cpaths = [] for path_name in path_names: names = (*parent_names, path_name) child_cpath = CPath(names) if self.__fs.is_file(child_cpath): mtime = self.__fs.getmtime(child_cpath) size = self.__fs.getsize(child_cpath) child_cpath = CFile(names, mtime, size) else: child_cpath = CDir(names) child_cpaths.append(child_cpath) # matcher file finding block # search for fs matcher config files for child_cpath in child_cpaths: if self.__fs.is_real_fs() and child_cpath.is_file(): if FsMatcherMapper.exists(child_cpath.name): matcher_cfile = child_cpath # check includer or excluder # TODO: read content of fs matcher files (e.g. gitignore) and then match further relative to that. # make a fs matcher and attache it to the parent. content = "" with self.__fs.open(matcher_cfile, "r", encoding="utf-8") as f: content = f.read() fs_matcher: AbcFsMatcher fs_matcher = FsMatcherMapper.get(matcher_cfile.name)(content) # group will decide where to place includer and where excluder. # root group will forward to appropriate matcher group self.__fs_matcher_root_group.add(fs_matcher, parent) # now list & hash if not ignored for child_cpath in child_cpaths: if not self.__fs_matcher_root_group.should_include(child_cpath): continue if child_cpath.is_file() and do_hash: hash_value = self.__fs.gethash(child_cpath) child_cpath = CFileHashed(child_cpath.names, child_cpath.mtime, child_cpath.size, hash_value) if child_cpath.is_dir(): last_subtree = parent.add(child_cpath) self.__list(last_subtree, do_hash=do_hash) else: parent.add(child_cpath)
def getsize(self, cpath: CPath): if not cpath.is_file(): raise CFSException( f'File System Error (occurred during getsize on cpath: {cpath}):\n' ) try: res = os.path.getsize(self._full_path(cpath)) except (OSError, IOError) as e: raise CFSException( f'File System Error (occurred during gethash on cpath: {cpath}):\n' f'{str(e)}' ) return res
def gethash(self, cpath: CPath): inside_cpath: CFileHashed = self.__cdir_tree.get(cpath) if inside_cpath is None: raise CFSException( f'File System Error (occurred during gethash on cpath: {cpath}):\n' f'X Path not found') if not cpath.is_file() or not inside_cpath.is_file(): raise CFSException( f'File System Error (occurred during gethash on cpath: {cpath}):\n' f'get hash can only be used on Files') if not isinstance(inside_cpath, CFileHashed): raise CFSException( f'File System Error (occurred during gethash on cpath: {cpath}):\n' f'X file was not hashed') return cpath.hash
def gethash(self, cpath: CPath): if not cpath.is_file(): raise CFSException( f'File System Error (occurred during gethash on cpath: {cpath}):\n' f'get hash can only be used on Files' ) try: BLOCKSIZE = 65536 hasher = config.HASHER() with open(self._full_path(cpath), 'rb') as afile: buf = afile.read(BLOCKSIZE) while len(buf) > 0: hasher.update(buf) buf = afile.read(BLOCKSIZE) res = hasher.hexdigest() except (OSError, IOError) as e: raise CFSException( f'File System Error (occurred during gethash on cpath: {cpath}):\n' f'{str(e)}' ) return res