Skip to content

Instantly share code, notes, and snippets.

@YUKI2eN3e
Created August 24, 2023 21:47
Show Gist options
  • Select an option

  • Save YUKI2eN3e/4a37d23a05cbdf8cab94de111c997d04 to your computer and use it in GitHub Desktop.

Select an option

Save YUKI2eN3e/4a37d23a05cbdf8cab94de111c997d04 to your computer and use it in GitHub Desktop.
#!/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