#!/usr/bin/env python3 import os, json from pathlib import Path from datetime import datetime from collections import Counter G="\033[92m"; Y="\033[93m"; R="\033[91m"; C="\033[96m" W="\033[1m\033[97m"; DIM="\033[2m"; RST="\033[0m"; BLD="\033[1m" def section(t): print(f"\n{C}{'─'*62}{RST}\n{W} {t}{RST}\n{C}{'─'*62}{RST}") def fmt_size(b): for u in ["B","KB","MB","GB"]: if b < 1024: return f"{b:.1f} {u}" b /= 1024 return f"{b:.1f} TB" def check_hf_cache(): section("1 · HUGGINGFACE CACHED MODELS") cache = Path.home() / ".cache" / "huggingface" / "hub" if not cache.exists(): print(f" {Y}HF cache not found at {cache}{RST}"); return model_dirs = sorted(cache.glob("models--*")) if not model_dirs: print(f" {Y}Cache empty{RST}"); return for md in model_dirs: name = md.name.replace("models--","").replace("--","/") total = sum(f.stat().st_size for f in md.rglob("*") if f.is_file()) snaps = list((md/"snapshots").glob("*")) if (md/"snapshots").exists() else [] snap_files = [f for s in snaps for f in (s.iterdir() if s.is_dir() else [])] has_config = any("config.json" in f.name for f in snap_files) has_tokenizer = any("tokenizer" in f.name for f in snap_files) has_weights = any(f.suffix in (".bin",".safetensors") for f in snap_files) print(f"\n {W}{name}{RST} {DIM}({fmt_size(total)}){RST}") print(f" config.json : {G+'✓'+RST if has_config else R+'✗ MISSING'+RST}") print(f" tokenizer : {G+'✓'+RST if has_tokenizer else R+'✗ MISSING'+RST}") print(f" weights : {G+'✓'+RST if has_weights else R+'✗ MISSING'+RST}") print(f" snapshots : {G+str(len(snaps))+RST}") def check_json_files(): section("2 · JSON FILES") roots = [Path.home()/"leotsha_project", Path.home()] all_json = [] for root in roots: if not root.exists(): continue for p in root.rglob("*.json"): if any(x in p.parts for x in [".cache","node_modules",".git","__pycache__"]): continue all_json.append(p) if not all_json: print(f" {Y}No JSON files found{RST}"); return for p in sorted(all_json): st = p.stat() size = fmt_size(st.st_size) mod = datetime.fromtimestamp(st.st_mtime).strftime("%Y-%m-%d %H:%M") print(f"\n {W}{p.name}{RST} {DIM}({size}, modified {mod}){RST}") print(f" {DIM}{p}{RST}") try: with open(p, encoding="utf-8", errors="ignore") as f: data = json.load(f) except Exception as e: print(f" {R}⚠ Parse error: {e}{RST}"); continue if isinstance(data, list): total = len(data) print(f" Records : {BLD}{W}{total:,}{RST}") if total and isinstance(data[0], dict): print(f" Keys : {list(data[0].keys())}") lk = next((k for k in data[0] if k in ("label","sentiment","output")), None) if lk: dist = Counter(str(r.get(lk,"?")) for r in data) parts = [f"{G if 'pos' in l.lower() else R if 'neg' in l.lower() else Y}{l}{RST}:{c}" for l,c in dist.most_common()] print(f" Labels : {' | '.join(parts)}") ok = G+"✓ ready"+RST if total>=500 else R+f"✗ need {500-total} more"+RST print(f" Finetune ready (≥500): {ok} {' '+Y+'(2000+ recommended)'+RST if 500<=total<2000 else ''}") elif isinstance(data, dict): print(f" Keys : {list(data.keys())[:8]}") def check_local_models(): section("3 · LOCAL MODEL CHECKPOINTS") found = [] for root in [Path.home()/"leotsha_project", Path.home()/"models"]: if not root.exists(): continue for p in root.rglob("config.json"): if ".cache" not in str(p): found.append(p.parent) if not found: print(f" {DIM}None found outside HF cache{RST}"); return for folder in found: files = list(folder.iterdir()) names = {f.name for f in files} weights = [f for f in files if f.suffix in (".bin",".safetensors",".pt",".ckpt")] total = sum(f.stat().st_size for f in files if f.is_file()) print(f"\n {W}{folder}{RST} ({fmt_size(total)})") print(f" config.json : {G+'✓'+RST if 'config.json' in names else R+'✗'+RST}") print(f" tokenizer_config : {G+'✓'+RST if 'tokenizer_config.json' in names else R+'✗'+RST}") print(f" weight files : {G+str(len(weights))+' file(s)'+RST if weights else R+'none'+RST}") print(f"\n{G}{'═'*62}{RST}") print(f"{W} Leotša la Sepedi — Resource & JSON Checker{RST}") print(f"{G}{'═'*62}{RST}") print(f"{DIM} {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}{RST}") check_hf_cache() check_json_files() check_local_models() print(f"\n{DIM}{'─'*62}{RST}\n")