From 08b5cc27eb37ea9996aea7561d8352e23a11014c Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Thu, 14 Jul 2016 15:12:18 -0400 Subject: Rewrite avfs.find() Don't break on symlinks. Have less copy&paste. --- avfs.py | 61 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 24 deletions(-) (limited to 'avfs.py') diff --git a/avfs.py b/avfs.py index fda6c72..ca75062 100644 --- a/avfs.py +++ b/avfs.py @@ -7,6 +7,7 @@ Traversing directories and archives with AVFS/fuse import os import os.path import subprocess +import stat avfs_sys_mount = os.environ['HOME'] + '/.avfs' avfs_started = False @@ -76,33 +77,45 @@ def guesscmd(filename): return cmd + guesscmd(filename[:-len(ext)]) return '' -def find(rootdir, prunedirs): +def get_lstat_mode(filename): """ - Recursively list all files under rootdir, including files in archives - supported by AVFS. + Get the st_mode stat value of the given file, or None if the stat fails + (doesn't exist, I/O error) """ + try: + return os.lstat(filename).st_mode + except: + return None - sys_rootdir = sys_name(rootdir) - - for name in os.listdir(sys_rootdir): - path = rootdir + '/' + name - sys_path = sys_rootdir + '/' + name - - if os.path.isdir(sys_path): - if name not in prunedirs: - yield from find(path, prunedirs) - else: - cmd = guesscmd(name) - filtered_path = path + cmd - sys_filtered_path = sys_path + cmd - - if cmd and os.path.exists(sys_filtered_path): - if os.path.isdir(sys_filtered_path): - yield from find(filtered_path, prunedirs) - else: - yield filtered_path - else: - yield path +def find(path, excludes): + """ + Recursively list all files under path, including files in archives + supported by AVFS. + """ + sys_path = sys_name(path) + name = os.path.basename(path) + mode = get_lstat_mode(sys_path) + + if name in excludes: + return + + # If AVFS provides a cooked view of the file, substitute the view + # for the original file. + if stat.S_ISREG(mode): + cmd = guesscmd(name) + if cmd: + cmd_mode = get_lstat_mode(sys_path + cmd) + if cmd_mode is not None: + path = path + cmd + sys_path = sys_path + cmd + name = name + cmd + mode = cmd_mode + + if stat.S_ISDIR(mode): + for entry in os.listdir(sys_path): + yield from find(path + '/' + entry, excludes) + elif stat.S_ISREG(mode): + yield path if __name__ == "__main__": import sys -- cgit v1.2.1