summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gnoutcheff <gnoutchd@softwarefreedom.org>2016-07-14 19:12:18 (GMT)
committerDaniel Gnoutcheff <gnoutchd@softwarefreedom.org>2016-07-14 19:12:18 (GMT)
commit08b5cc27eb37ea9996aea7561d8352e23a11014c (patch)
treec74ec0bca0048ce10ff7e0f7449150e0f277f21c
parent3969154e6c497dde2897e9c65a9e1d078c534370 (diff)
Rewrite avfs.find()
Don't break on symlinks. Have less copy&paste.
-rw-r--r--avfs.py61
1 files changed, 37 insertions, 24 deletions
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