Created
August 24, 2023 21:47
-
-
Save YUKI2eN3e/4a37d23a05cbdf8cab94de111c997d04 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import argparse | |
| from dataclasses import dataclass | |
| from math import floor, log, pow | |
| from os import path, walk | |
| from typing import List | |
| @dataclass | |
| class CliArgs: | |
| file_extensions: str | |
| verbose: bool | |
| recursive: bool | |
| def get_args() -> CliArgs: | |
| parser = argparse.ArgumentParser( | |
| prog=path.basename(__file__) | |
| ) | |
| parser.add_argument( | |
| "-e", | |
| "-f", | |
| "--exts", | |
| "--file-extensions", | |
| dest="file_extensions", | |
| default="*", | |
| help="the file extensions to look for when getting total size", | |
| ) | |
| parser.add_argument( | |
| "-v", | |
| "--verbose", | |
| action="store_true", | |
| default=False, | |
| help="list all files found", | |
| ) | |
| parser.add_argument( | |
| "-r", | |
| "--recursive", | |
| dest="recursive", | |
| action="store_true", | |
| default=False, | |
| help="search for files recursively", | |
| ) | |
| return CliArgs(**vars(parser.parse_args())) | |
| def get_filepaths( | |
| exts: List[str] = ["*"], dir_path: str = ".", recursive: bool = False | |
| ) -> List[str]: | |
| """Get file paths (based on https://stackoverflow.com/a/3207973#comment128971338_3207973). | |
| Args: | |
| exts (List[str]): List of file extensions to look for. Defaults to ["*"]. | |
| dir_path (str, optional): The path to the base dir to search from. Defaults to ".". | |
| Returns: | |
| List[str]: List of file paths. | |
| """ | |
| file_paths = [] | |
| if recursive: | |
| for file_path in [ | |
| path.join(dirpath, f) | |
| for (dirpath, dirnames, filenames) in walk(dir_path) | |
| for f in filenames | |
| ]: | |
| if file_path.split(".")[-1] in exts or exts == ["*"]: | |
| file_paths.append(file_path) | |
| else: | |
| for file_path in next(walk(dir_path), (None, None, []))[2]: | |
| if file_path.split(".")[-1] in exts or exts == ["*"]: | |
| file_paths.append(file_path) | |
| return file_paths | |
| def convert_size(size_bytes: int) -> str: | |
| """Convert Size (from https://stackoverflow.com/a/14822210). | |
| Args: | |
| size_bytes (int): The size in bytes. | |
| Returns: | |
| str: String with the formatted and converted size. | |
| """ | |
| if size_bytes == 0: | |
| return "0B" | |
| size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") | |
| i = int(floor(log(size_bytes, 1024))) | |
| p = pow(1024, i) | |
| s = round(size_bytes / p, 2) | |
| return "%s %s" % (s, size_name[i]) | |
| def run(): | |
| args = get_args() | |
| file_paths = get_filepaths( | |
| exts=args.file_extensions.split(",") | |
| if "," in args.file_extensions | |
| else [args.file_extensions], | |
| recursive=args.recursive, | |
| ) | |
| total_size = 0 | |
| for file in file_paths: | |
| if args.verbose: | |
| size = convert_size(path.getsize(file)) | |
| spacing = "\t" if len(size) >= 8 else "\t\t" | |
| print(f"{size}{spacing}{file}") | |
| total_size = total_size + path.getsize(file) | |
| if args.verbose: | |
| print("-" * 64) | |
| print(f"Total Size:\t{convert_size(total_size)}") | |
| if __name__ == "__main__": | |
| run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment