# https://t.me/ZGQinc
# 建立数据报告

import os
import csv
from bs4 import BeautifulSoup
from urllib.parse import urljoin, unquote, quote

MIRROR_ROOT_DIR = 'myrient_index_mirror' 
BASE_URL = 'https://myrient.erista.me/files/'

def parse_size_to_bytes(size_str):
    size_str = size_str.strip()
    if not size_str or size_str == '-':
        return 0
    
    units = {"B": 1, "KiB": 1024, "MiB": 1024**2, "GiB": 1024**3, "TiB": 1024**4}
    try:
        number_str = ""
        unit_str = ""
        for char in size_str:
            if char.isdigit() or char == '.':
                number_str += char
            else:
                unit_str += char
        
        number = float(number_str)
        unit = unit_str.strip()
        
        unit_upper = unit.upper()
        if unit_upper.endswith('B'):
            if len(unit_upper) > 1 and unit_upper[0] == 'K':
                unit = 'KiB'
            elif len(unit_upper) > 1 and unit_upper[0] == 'M':
                unit = 'MiB'
            elif len(unit_upper) > 1 and unit_upper[0] == 'G':
                unit = 'GiB'
            elif len(unit_upper) > 1 and unit_upper[0] == 'T':
                unit = 'TiB'
            else:
                 unit = 'B'

        return int(number * units.get(unit, 1))
    except (ValueError, KeyError):
        return 0

def format_bytes_to_human_readable(byte_count):
    if byte_count is None or byte_count == 0:
        return "0 B"
    power = 1024
    n = 0
    power_labels = {0: 'B', 1: 'KiB', 2: 'MiB', 3: 'GiB', 4: 'TiB'}
    while byte_count >= power and n < len(power_labels) - 1:
        byte_count /= power
        n += 1
    return f"{byte_count:.2f} {power_labels[n]}"

def analyze_local_mirror():
    if not os.path.isdir(MIRROR_ROOT_DIR):
        print(f"错误：找不到指定的镜像根目录 '{MIRROR_ROOT_DIR}'。")
        return

    all_files_data = []
    print("开始生成分析文件...")

    for dirpath, _, filenames in os.walk(MIRROR_ROOT_DIR):
        if 'index.html' in filenames:
            html_file_path = os.path.join(dirpath, 'index.html')
            print(f"  正在处理: {html_file_path}")

            local_files_data = []
            try:
                with open(html_file_path, 'r', encoding='utf-8') as f:
                    soup = BeautifulSoup(f, 'html.parser')
                    
                    for row in soup.select('table#list tbody tr'):
                        cells = row.find_all('td')
                        if len(cells) != 3 or 'parent' in cells[0].get('class', []):
                            continue

                        link_tag = cells[0].find('a')
                        if not link_tag: continue

                        href = link_tag.get('href')
                        if not href or href.startswith('?') or href.endswith('/'):
                            continue

                        relative_dir = os.path.relpath(dirpath, MIRROR_ROOT_DIR)
                        if relative_dir == '.': relative_dir = ''
                        path_components = relative_dir.split(os.path.sep)
                        
                        encoded_path_components = [quote(unquote(part)) for part in path_components]
                        web_path_segment = '/'.join(encoded_path_components)
                        
                        fully_encoded_href = quote(unquote(href))
                        
                        if web_path_segment:
                            full_web_path = f"{web_path_segment}/{fully_encoded_href}"
                        else:
                            full_web_path = fully_encoded_href
                        
                        full_url = urljoin(BASE_URL, full_web_path)
                        
                        file_info = {
                            "Filename": link_tag.get_text(strip=True),
                            "Size (str)": cells[1].get_text(strip=True),
                            "Size (bytes)": parse_size_to_bytes(cells[1].get_text(strip=True)),
                            "Date": cells[2].get_text(strip=True),
                            "URL": full_url,
                        }
                        local_files_data.append(file_info)

            except Exception as e:
                print(f"    处理文件时出错 {html_file_path}: {e}")
                continue

            if local_files_data:
                csv_path = os.path.join(dirpath, 'files.csv')
                with open(csv_path, 'w', newline='', encoding='utf-8') as f:
                    writer = csv.DictWriter(f, fieldnames=["Filename", "Size (str)", "Date", "URL"], extrasaction='ignore')
                    writer.writeheader()
                    writer.writerows(sorted(local_files_data, key=lambda x: x["Filename"]))
                print(f"    已生成: files.csv")
                
                size_path = os.path.join(dirpath, 'size.txt')
                dir_total_size = sum(f["Size (bytes)"] for f in local_files_data)
                with open(size_path, 'w', encoding='utf-8') as f:
                    f.write(f"Directory Total Size: {format_bytes_to_human_readable(dir_total_size)}\n")
                    f.write(f"File Count: {len(local_files_data)}\n")
                print(f"    已生成: size.txt")

                for item in local_files_data:
                    item['Directory'] = dirpath
                all_files_data.extend(local_files_data)

    if all_files_data:
        total_csv_path = os.path.join(MIRROR_ROOT_DIR, 'total_files.csv')
        with open(total_csv_path, 'w', newline='', encoding='utf-8') as f:
            fieldnames = ["Filename", "Size (str)", "Date", "URL", "Directory"]
            writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction='ignore')
            writer.writeheader()
            writer.writerows(sorted(all_files_data, key=lambda x: x["URL"]))
        
        total_size_path = os.path.join(MIRROR_ROOT_DIR, 'total_size.txt')
        grand_total_size = sum(f["Size (bytes)"] for f in all_files_data)
        with open(total_size_path, 'w', encoding='utf-8') as f:
            f.write(f"Grand Total Size: {format_bytes_to_human_readable(grand_total_size)}\n")
            f.write(f"Total File Count: {len(all_files_data)}\n")
        
        print(f"\n处理完成。")
        print(f"共处理 {len(all_files_data)} 个文件。")
        print(f"总报告文件已保存至 '{os.path.abspath(MIRROR_ROOT_DIR)}' 目录。")
    else:
        print("\n未找到任何可提取的文件数据。")

if __name__ == '__main__':
    analyze_local_mirror()