#!/usr/bin/env python3
"""从阿里云帮助页面提取全部音色并下载音频样本"""
import json, os, re, requests, subprocess, time

OUTPUT_DIR = "docs/voices/audio"
os.makedirs(OUTPUT_DIR, exist_ok=True)

# 用 playwright 提取音色数据
print("正在提取音色列表...")
result = subprocess.run([
    "npx", "playwright-cli", "run-code",
    r"""async (page) => {
  const data = [];
  // 遍历所有包含音频的表格行
  const rows = document.querySelectorAll('tr');
  rows.forEach(tr => {
    const audioEl = tr.querySelector('audio');
    if (!audioEl) return;
    const src = audioEl.querySelector('source')?.src || audioEl.src;
    if (!src) return;
    
    // 提取voice参数
    const text = tr.textContent || '';
    const voiceMatch = text.match(/voice参数[：:]\s*(\S+)/);
    const nameMatch = voiceMatch ? text.match(/名称[：:]\s*(\S+)/) : null;
    const sceneMatch = text.match(/(?:^|\n)([^\n]{3,20}?)\s*名称[：:]/);
    
    data.push({
      url: src,
      voice: voiceMatch ? voiceMatch[1] : '',
      name: nameMatch ? nameMatch[1] : '',
      scene: sceneMatch ? sceneMatch[1].trim() : ''
    });
  });
  return JSON.stringify(data);
}"""], capture_output=True, text=True, cwd="c:/Users/caoyg/ai/audio-tts/audio_codebuddy")

# 解析输出
output = result.stdout
# 提取 JSON
json_start = output.find('[')
json_end = output.rfind(']') + 1
if json_start < 0 or json_end <= json_start:
    print("未找到音色数据")
    print(output[:500])
    exit(1)

voices = json.loads(output[json_start:json_end])
print(f"找到 {len(voices)} 个音色")

# 写音色索引
index_lines = ["# 官方音色样本索引\n", f"\n共 {len(voices)} 个音色，来源：阿里云百炼帮助中心\n\n"]
index_lines.append("| 音色名称 | voice参数 | 适用场景 | 文件名 |\n")
index_lines.append("|---------|----------|---------|--------|\n")

downloaded = 0
for i, v in enumerate(voices):
    url = v['url']
    voice_param = v['voice']
    name = v['name']
    scene = v['scene']
    
    # 文件名：场景_音色名_voice参数.mp3
    safe_name = f"{scene}_{name}_{voice_param}" if scene else f"{name}_{voice_param}"
    safe_name = re.sub(r'[\\/:*?"<>|]', '_', safe_name)
    fname = f"{safe_name}.mp3"
    fpath = os.path.join(OUTPUT_DIR, fname)
    
    index_lines.append(f"| {name} | `{voice_param}` | {scene} | [{fname}](audio/{fname}) |\n")
    
    if os.path.exists(fpath):
        print(f"  [{i+1}/{len(voices)}] 跳过(已存在): {fname}")
        downloaded += 1
        continue
    
    try:
        print(f"  [{i+1}/{len(voices)}] 下载: {voice_param} -> {fname}")
        resp = requests.get(url, timeout=30)
        if resp.status_code == 200:
            with open(fpath, 'wb') as f:
                f.write(resp.content)
            downloaded += 1
        else:
            print(f"    HTTP {resp.status_code}")
    except Exception as e:
        print(f"    错误: {e}")
    time.sleep(0.3)

# 写索引文件
index_path = os.path.join(OUTPUT_DIR, "INDEX.md")
with open(index_path, 'w', encoding='utf-8') as f:
    f.writelines(index_lines)

print(f"\n完成！下载 {downloaded}/{len(voices)} 个音色到 {OUTPUT_DIR}/")
