|
|
|
|
|
|
|
|
|
|
|
|
|
import os |
|
import sys |
|
from collections import Counter |
|
import gettext |
|
import locale |
|
from pathlib import Path |
|
import logging |
|
|
|
|
|
def setup_i18n(): |
|
"""Set up internationalization""" |
|
try: |
|
|
|
locale.setlocale(locale.LC_ALL, '') |
|
current_locale = locale.getlocale()[0] |
|
locale_path = Path(__file__).parent / 'locales' |
|
|
|
|
|
trans = gettext.translation('stats', locale_path, languages=[current_locale]) |
|
trans.install() |
|
return trans.gettext |
|
except: |
|
|
|
return gettext.gettext |
|
|
|
|
|
_ = setup_i18n() |
|
|
|
|
|
RED = "\033[91m" |
|
GREEN = "\033[92m" |
|
ORANGE = "\033[93m" |
|
BLUE = "\033[94m" |
|
MAGENTA = "\033[95m" |
|
CYAN = "\033[96m" |
|
RESET = "\033[0m" |
|
|
|
EXT2COLOR = { |
|
"jxl": CYAN, |
|
"png": MAGENTA, |
|
"jpg": RED, |
|
"jpeg": RED, |
|
"webp": MAGENTA, |
|
"caption": BLUE, |
|
"e621": BLUE, |
|
"txt": BLUE, |
|
"wd": BLUE, |
|
"json": ORANGE, |
|
"md": ORANGE, |
|
"tags": BLUE, |
|
} |
|
EXT2ORDER = {ext: i for i, ext in enumerate(EXT2COLOR.keys())} |
|
SORT_KEYS = ["name", "count", "image", "text", *EXT2COLOR.keys()] |
|
|
|
TEXT_FORMATS = {"txt", "caption", "wd", "json", "e621", "md", "tags"} |
|
IMAGE_FORMATS = EXT2COLOR.keys() - TEXT_FORMATS |
|
|
|
|
|
def setup_logging(debug=False): |
|
if debug: |
|
logging.basicConfig(level=logging.DEBUG, filename='debug.log', filemode='w', |
|
format='%(asctime)s - %(levelname)s - %(message)s') |
|
else: |
|
logging.basicConfig(level=logging.INFO) |
|
|
|
|
|
def count_files(directory, debug=False): |
|
if debug: |
|
logging.debug(f"Scanning directory: {directory}") |
|
file_counts = Counter() |
|
for root, dirs, files in os.walk(directory): |
|
for file in files: |
|
if file.startswith('.'): |
|
if debug: |
|
logging.debug(f"Skipping hidden file: {os.path.join(root, file)}") |
|
continue |
|
base_name, ext = os.path.splitext(file) |
|
if len(ext) > 1: |
|
if debug: |
|
logging.debug(f"Processing file: {file}, Base: {base_name}, Extension: {ext}") |
|
ext = ext[1:].lower() |
|
file_counts[ext] += 1 |
|
if ext in IMAGE_FORMATS: |
|
file_counts["image"] += 1 |
|
elif ext in TEXT_FORMATS: |
|
file_counts["text"] += 1 |
|
else: |
|
file_counts["no_extension"] += 1 |
|
if debug: |
|
logging.debug(f"File without extension: {os.path.join(root, file)}") |
|
return file_counts |
|
|
|
|
|
def main(): |
|
sort_key_name = "name" |
|
sort_reverse = False |
|
debug = False |
|
|
|
|
|
args = sys.argv[1:] |
|
if "--debug" in args: |
|
debug = True |
|
args.remove("--debug") |
|
|
|
|
|
setup_logging(debug) |
|
|
|
if debug: |
|
logging.debug(f"Debug mode enabled") |
|
logging.debug(f"Sort key name: {sort_key_name}, Sort reverse: {sort_reverse}") |
|
|
|
if len(args) > 0: |
|
sort_key_name = args[0] |
|
if sort_key_name.endswith("_r"): |
|
sort_reverse = True |
|
sort_key_name = sort_key_name[:-2] |
|
|
|
|
|
if sort_key_name == "name": |
|
sort_key = lambda x: x[0] |
|
elif sort_key_name == "count": |
|
sort_key = lambda x: x[1] |
|
elif sort_key_name in SORT_KEYS: |
|
sort_key = lambda x: x[2].get(sort_key_name, 0) |
|
else: |
|
print(_('Valid sort keys are {}').format(", ".join(f'"{k}"' for k in SORT_KEYS))) |
|
print(_('Append "_r" to reverse the sort order')) |
|
sys.exit(1) |
|
|
|
current_directory = os.getcwd() |
|
directories = ( |
|
d |
|
for d in os.listdir(current_directory) |
|
if os.path.isdir(os.path.join(current_directory, d)) |
|
) |
|
|
|
stats = [] |
|
grand_total = Counter() |
|
for directory in directories: |
|
dir_path = os.path.join(current_directory, directory) |
|
counts = count_files(dir_path, debug=debug) |
|
total_files = sum(v for k, v in counts.items() if k in EXT2ORDER) |
|
stats.append((directory, total_files, counts)) |
|
grand_total.update(counts) |
|
|
|
stats.sort(key=sort_key, reverse=sort_reverse) |
|
stats.append((None, sum(v for k, v in grand_total.items() if k in EXT2ORDER), grand_total)) |
|
|
|
for directory, total_files, counts in stats: |
|
if total_files == 0: |
|
continue |
|
if directory is None: |
|
print(_('Grand Total:')) |
|
else: |
|
print(_('Directory: {}').format(directory)) |
|
for txt_format in TEXT_FORMATS: |
|
if counts.get(txt_format, 0) == 0: |
|
print(f"{RED}{_('❌ {txt_format} not found').format(txt_format=txt_format)}{RESET}") |
|
if counts.get("no_extension", 0) > 0: |
|
print(f"{ORANGE}⚠️ {_('Files without extensions found: {}').format(counts['no_extension'])}{RESET}") |
|
for ext, count in sorted( |
|
counts.items(), key=lambda x: EXT2ORDER.get(x[0], -1) |
|
): |
|
if counts[ext] == 0 or ext not in EXT2COLOR: |
|
continue |
|
print(f"{EXT2COLOR[ext]}{ext} {_('files')}: {counts[ext]}{RESET}") |
|
tally_color = GREEN if total_files >= 200 else ORANGE |
|
print(f"{tally_color}{_('Total files: {}').format(total_files)}{RESET}") |
|
print() |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |
|
|