From 8d0c42dfe2720bbc09531de83442d7a198c27690 Mon Sep 17 00:00:00 2001 From: stephentoth Date: Sat, 9 Mar 2024 19:41:04 -0600 Subject: [PATCH] fixup --- ls.py | 99 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 42 deletions(-) diff --git a/ls.py b/ls.py index 42afb3d..07857ce 100755 --- a/ls.py +++ b/ls.py @@ -35,6 +35,8 @@ class Filetype(Enum): S_IFIFO = 0o010000 ERR = 0 +FileMeta = namedtuple("FileMeta", "name rel_file_path abs_file_path stats") + Permissions = namedtuple("Permissions", "mode type char color prettybits") FileString = namedtuple("FileString", ["path", "file", "file_color", @@ -160,53 +162,34 @@ def git_gud(path): +def short_listing(files_meta): + for file in files_meta: + colored_file = file_string_gen(file.name, file.stats.st_mode).colored_filepath + print(colored_file) + #colored_file = gen_color_file_string(file.abs_file_path, file.stats.st_mode) + # rel is broken + #print(colored_file) +def long_listing(files_meta): + use_full_path = True + print(f"ls.py {' '.join(sys.argv[1:])}") + print(f"files: {len(files_meta)}") - - - -def list_files(directory='.', args={}): - filenames = os.listdir(directory) + term_width = os.get_terminal_size() - #get file metadata - FileMeta = namedtuple("FileMeta", "name rel_file_path abs_file_path stats") - def get_file_metadata(path, name): - rel_file_path = os.path.join(path, name) # for rel paths - abs_file_path = os.path.abspath(rel_file_path) # for full path - stats = os.lstat(rel_file_path) - return FileMeta(name, rel_file_path, abs_file_path, stats) - - files = [ get_file_metadata(directory, name) for name in os.listdir(directory) ] + longest_size_string_len = len(str(functools.reduce(lambda a, b: a if len(str(a.stats.st_size)) > len(str(b.stats.st_size)) else b, files_meta).stats.st_size)) - longest_size_length = len(str(functools.reduce(lambda a, b: a if len(str(a.stats.st_size)) > len(str(b.stats.st_size)) else b, files).stats.st_size)) - - print(f"files: {len(files)}") - - # Sort stuff - if args.time_sorted: - files.sort(key=lambda f: f.stats.st_mtime, reverse=(not args.reverse)) - elif args.size_sorted: - files.sort(key=lambda f: f.stats.st_size, reverse=(not args.reverse)) - else: - files.sort(key=lambda f:f.name, reverse=(args.reverse)) - - - # filter out hidden if not specify -a - if not args.all: - files = [file for file in files if not file.name.startswith('.')] - - if not args.long: - for file in files: - colored_file = gen_color_file_string(file.abs_file_path, file.stats.st_mode) - # rel is broken - print(colored_file) - return + # if use_full_path: + # longest_filename_string_len = len(functools.reduce(lambda a, b: a if len(a.abs_file_path) > len(b.abs_file_path) else b, files_meta).abs_file_path) + # else: + # longest_filename_string_len = len(functools.reduce(lambda a, b: a if len(a.rel_file_path) > len(b.rel_file_path) else b, files_meta).rel_file_path) + # - for file in files: + for file in files_meta: size = file.stats.st_size user = pwd.getpwuid(file.stats.st_uid).pw_name group = grp.getgrgid(file.stats.st_gid).gr_name @@ -239,7 +222,7 @@ def list_files(directory='.', args={}): gitstat = git_gud(file.abs_file_path) if (args.extend and is_path_git_repo_dir(file.abs_file_path, file.stats.st_mode)) else '' ## do printing - print(f"{perm_prettybits} {nlinks:2d} {user:<8s} {group:<8s} {size:>{longest_size_length}} {timestring} {file_str} {gitstat}") + print(f"{perm_prettybits} {nlinks:2d} {user:<8s} {group:<8s} {size:>{longest_size_string_len}} {timestring} {file_str} {gitstat}") @@ -247,6 +230,41 @@ def list_files(directory='.', args={}): +def list_files(directory='.', args={}): + + dir_filenames = os.listdir(directory) + + #get file metadata + files = [] + + # since os.listdir does not handle . or .. dirs + files += [FileMeta('.', directory + '/.', os.path.abspath(directory )+'/.', os.lstat(directory +'/.'))] + files += [FileMeta('..', directory + '/..', os.path.abspath(directory )+'/..', os.lstat(directory +'/..'))] + + for name in dir_filenames: + rel_file_path = os.path.join(directory, name) # for rel paths + abs_file_path = os.path.abspath(rel_file_path) # for full path + stats = os.lstat(rel_file_path) + files.append(FileMeta(name, rel_file_path, abs_file_path, stats)) + + + # filter out options + if not args.all: + files = [file for file in files if not file.name.startswith('.')] + + # Sort stuff + if args.time_sorted: + files.sort(key=lambda f: f.stats.st_mtime, reverse=(not args.reverse)) + elif args.size_sorted: + files.sort(key=lambda f: f.stats.st_size, reverse=(not args.reverse)) + else: + files.sort(key=lambda f:f.name, reverse=(args.reverse)) + + # normal listing basically + if not args.long: + short_listing(files) + else: + long_listing(files) @@ -262,7 +280,6 @@ if __name__ == "__main__": parser.add_argument('-F', '--full-time', action='store_true', help="Show full full time") parser.add_argument('-s', '--sparse', action='store_true', help="Blank irrelevant information") - # ouput format options sortargs = parser.add_mutually_exclusive_group() sortargs.add_argument('-t', '--time-sorted', action='store_true', help="Sort by time") @@ -270,12 +287,10 @@ if __name__ == "__main__": parser.add_argument('-r', '--reverse', action='store_true', help="Reverse sort order") parser.add_argument('-h', '--human', action='store_true', help="Human Readable size") - # extra parser.add_argument('-e', '--extend', action='store_true', help="Do some extra processing on the directory") args = parser.parse_args() - print(f"ls.py {' '.join(sys.argv[1:])}") list_files(args.directory, args)