import os from pathlib import Path def find_file(filename, file_folders): for folder in file_folders: folder_path = Path(folder) if not folder_path.exists(): continue for file_path in folder_path.rglob(filename): return folder_path return None def get_size_format(b, factor=1024, suffix="B"): for unit in ["", "K", "M", "G", "T"]: if b < factor: return f"{b:.2f} {unit}{suffix}" b /= factor return f"{b:.2f} P{suffix}" def get_dir_size(path): total = 0 if os.path.exists(path): for f in os.listdir(path): fp = os.path.join(path, f) if os.path.isfile(fp): total += os.path.getsize(fp) return total def get_file_list_size(file_list: list[str]): total = 0 for fp in file_list: if os.path.isfile(fp): total += os.path.getsize(fp) return total def calculate_analytic(database, config): all_db = database.get_all() explicit_db = database.get_search(["e"], []) sensitive_db = database.get_search(["s"], []) questionable_db = database.get_search(["q"], []) general_db = database.get_search(["g"], []) rating_list_file_path = {"explicit":[], "sensitive":[], "questionable":[], "general":[]} for one_post in all_db: file_path = find_file(one_post["local_filename"], config["file"]["repos"]) if file_path != None: rating_list_file_path[one_post["rating"]].append(file_path) ratings_stats = { "explicit": { "count": len(explicit_db), "size_formatted": get_size_format(get_file_list_size(rating_list_file_path["explicit"])) }, "sensitive": { "count": len(sensitive_db), "size_formatted": get_size_format(get_file_list_size(rating_list_file_path["sensitive"])) }, "questionable": { "count": len(questionable_db), "size_formatted": get_size_format(get_file_list_size(rating_list_file_path["questionable"])) }, "general": { "count": len(general_db), "size_formatted": get_size_format(get_file_list_size(rating_list_file_path["general"])) } }, result = { "total_images_analyzed": len(all_db), "average_weight": { "bytes": round(avg_size_bytes, 2), "formatted": get_size_format(avg_size_bytes) }, "storage_stats": { "folders": { "img": get_size_format(size_img), "json_db": get_size_format(size_json), "thumb": get_size_format(size_thumb), "logs": get_size_format(size_logs) }, "types_in_img": { "images": get_size_format(type_sizes["IMG"]), "videos": get_size_format(type_sizes["VID"]), "gifs": get_size_format(type_sizes["GIF"]), "logs": get_size_format(type_sizes["LOGS"]) }, "grand_total": get_size_format(grand_total) }, "ratings_stats": ratings_stats, "resolution_stats": { "largest": { "filename": max_res["filename"], "md5": max_res["md5"], "resolution": f'{max_res["width"]}x{max_res["height"]}' }, "smallest": { "filename": min_res["filename"], "md5": min_res["md5"] if min_res["area"] != float('inf') else "", "resolution": f'{min_res["width"]}x{min_res["height"]}' if min_res["area"] != float('inf') else "N/A" } }, "weight_stats": { "largest": { "filename": max_weight["filename"], "md5": max_weight["md5"], "size_formatted": get_size_format(max_weight["size"]) }, "smallest": { "filename": min_weight["filename"], "md5": min_weight["md5"] if min_weight["size"] != float('inf') else "", "size_formatted": get_size_format(min_weight["size"]) if min_weight["size"] != float('inf') else "N/A" } }, "tag_top":database.get_top_tag("") }