This commit is contained in:
stephentoth 2024-03-09 19:41:04 -06:00
parent 05067532e2
commit 8d0c42dfe2
1 changed files with 57 additions and 42 deletions

99
ls.py
View File

@ -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)