diff --git a/ch05_modules/ls.py b/ch05_modules/ls.py index 842c4c4..bbc8eca 100755 --- a/ch05_modules/ls.py +++ b/ch05_modules/ls.py @@ -1,51 +1,149 @@ #!/usr/bin/env python3 +import locale import os -from pprint import pprint +from datetime import datetime +from optparse import OptionParser + +FULL_PATH, IS_FILE, FILE_SIZE, FILE_MTIME = range(4) def is_hidden_path(path): return path.startswith(".") -def main(): - # TODO: sanitize input roots - expanduser, expandvars, abspath - roots = ["/home/mkiryanov/", ".local/"] +def by_path_name(stat_item): + return stat_item[FULL_PATH] + + +def by_file_size(stat_item): + size = stat_item[FILE_SIZE] + return size if size else 0 + + +def by_file_mtime(stat_item): + mtime = stat_item[FILE_MTIME] + return mtime if mtime else 0 + - recursive = True - show_hidden = False +def gather_fs_stats_simply(root, show_hidden): + stats = [] + for filename in os.listdir(root): + if not show_hidden and is_hidden_path(filename): + continue + full_path = os.path.join(root, filename) + if not os.path.isdir(full_path): + stat = os.stat(full_path, follow_symlinks=False) + data = (full_path, True, stat.st_size, stat.st_mtime) + else: + data = (full_path, False, None, None) + stats.append(data) + return stats - stats = {} + +def gather_fs_stats_recursively(root_name, show_hidden): + stats = [] + for root, dirnames, filenames in os.walk(root_name): + for path in dirnames: + if not show_hidden and is_hidden_path(path): + continue + full_path = os.path.join(root, path) + stats.append((full_path, False, None, None)) + for path in filenames: + if not show_hidden and is_hidden_path(path): + continue + full_path = os.path.join(root, path) + stat = os.stat(full_path, follow_symlinks=False) + stats.append((full_path, True, stat.st_size, stat.st_mtime)) + + dirnames[:] = [dir for dir in dirnames if not is_hidden_path(dir)] + return stats + + +def gather_fs_stats(root_names, recursive, show_hidden): + stats = [] if not recursive: - for root in roots: - abs_root = os.path.abspath(root) - for path in os.listdir(root): - if not show_hidden and is_hidden_path(path): - continue - abs_path = os.path.join(abs_root, path) - data = None - if not os.path.isdir(abs_path): - stat = os.stat(abs_path) - rel_path = os.path.join(root, path) - data = (rel_path, stat.st_size, stat.st_mtime_ns) - stats.update({abs_path: data}) + for root_name in root_names: + stats.extend(gather_fs_stats_simply(root_name, show_hidden)) + else: + for root_name in root_names: + stats.extend(gather_fs_stats_recursively(root_name, show_hidden)) + return stats + + +def print_stats(stats, show_size, show_time, locale_id): + locale.setlocale(locale.LC_ALL, locale_id) + + print_template = "{name: