# -*- coding: utf-8 -*-
"""上传图片到百家号并返回 URL，然后插入到 UEditor 正文"""
import sys, socket, json, time, os, glob, base64, mimetypes
sys.stdout.reconfigure(encoding="utf-8")

HOST = "localhost"
PORT = 28800

# 获取 page id
import urllib.request as ur
try:
    pages = json.loads(ur.urlopen("http://127.0.0.1:28800/json").read())
    PAGE_ID = pages[0]["id"]
except:
    PAGE_ID = None
print("[INFO] PAGE_ID:", PAGE_ID)

# 获取图片
imgs = glob.glob(r"D:\wxpic\*.jpg") + glob.glob(r"D:\wxpic\*.png")
IMG_PATH = max(imgs, key=os.path.getmtime) if imgs else None
print("[INFO] IMG:", IMG_PATH)

if not IMG_PATH:
    sys.exit("No image found")

with open(IMG_PATH, "rb") as f:
    IMG_B64 = base64.b64encode(f.read()).decode()
IMG_MIME = mimetypes.guess_type(IMG_PATH)[0] or "image/jpeg"
print("[INFO] IMG size:", len(IMG_B64), "mime:", IMG_MIME)

# === CDP WebSocket ===
import urllib.parse
u = "ws://%s:%s/devtools/page/%s" % (HOST, PORT, PAGE_ID)
p = urllib.parse.urlparse(u)
s = socket.create_connection((p.hostname, p.port or 80), timeout=15)
req = (
    "GET %s HTTP/1.1\r\nHost: %s:%s\r\nUpgrade: websocket\r\n"
    "Connection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
    "Sec-WebSocket-Version: 13\r\n\r\n"
) % (p.path, p.hostname, p.port)
s.send(req.encode())
resp = b""
while b"\r\n\r\n" not in resp:
    resp += s.recv(4096)

def ws_send(data):
    data = data.encode("utf-8")
    n = len(data)
    m = b"\x01\x02\x03\x04"
    if n <= 125:
        h = bytes([0x81, n | 0x80]) + m
    elif n <= 65535:
        h = bytes([0x81, 0xFE]) + n.to_bytes(2, "big") + m
    else:
        h = bytes([0x81, 0xFF]) + n.to_bytes(8, "big") + m
    s.send(h + bytes(data[i] ^ m[i % 4] for i in range(n)))

def ws_recv():
    h = b""
    while len(h) < 2:
        h += s.recv(2 - len(h))
    n = h[1] & 0x7F
    if n == 126:
        nb = b""
        while len(nb) < 2:
            nb += s.recv(2 - len(nb))
        n = int.from_bytes(nb, "big")
    elif n == 127:
        nb = b""
        while len(nb) < 8:
            nb += s.recv(8 - len(nb))
        n = int.from_bytes(nb, "big")
    body = b""
    while len(body) < n:
        body += s.recv(n - len(body))
    return body.decode("utf-8")

_mid = [0]

def cdp(method, params=None):
    if params is None:
        params = {}
    _mid[0] += 1
    ws_send(json.dumps({"id": _mid[0], "method": method, "params": params}))
    s.settimeout(30)
    for _ in range(600):
        try:
            r = json.loads(ws_recv())
            if r.get("id") == _mid[0]:
                return r
        except Exception:
            pass
    return None

# Step 1: 在浏览器中上传图片到百家号
print("\n[1] 上传图片到百家号...")
# 使用 fetch + FormData 上传
js_code = """
async () => {
  try {
    const b64 = '%s';
    const mime = '%s';
    const byteString = atob(b64);
    const ab = new ArrayBuffer(byteString.length);
    const ia = new Uint8Array(ab);
    for (let j = 0; j < byteString.length; j++) ia[j] = byteString.charCodeAt(j);
    const blob = new Blob([ab], {type: mime});
    const file = new File([blob], 'cover.jpg', {type: mime});
    
    const formData = new FormData();
    formData.append('media', file);
    
    const resp = await fetch('https://baijiahao.baidu.com/materialui/picture/uploadProxy', {
      method: 'POST',
      body: formData,
      credentials: 'include'
    });
    
    const text = await resp.text();
    return JSON.stringify({status: resp.status, body: text.substring(0, 500)});
  } catch(e) {
    return JSON.stringify({error: e.message});
  }
}
""" % (IMG_B64, IMG_MIME)

r = cdp("Runtime.evaluate", {
    "expression": js_code,
    "returnByValue": True,
    "awaitPromise": True
})
val = r.get("result", {}).get("result", {}).get("value", "") if r else ""
if isinstance(val, dict):
    val = json.dumps(val, ensure_ascii=False)
elif not isinstance(val, str):
    val = str(val)
print("  上传结果:", val[:500])

# 解析 URL
try:
    upload_result = json.loads(val)
    if "body" in upload_result:
        body = json.loads(upload_result["body"])
        pic_url = body.get("data", {}).get("pic_url") or body.get("data", {}).get("url") or body.get("pic_url") or body.get("url")
        if not pic_url:
            # 遍历查找任何 URL
            data = body.get("data", body)
            if isinstance(data, dict):
                for k, v in data.items():
                    if isinstance(v, str) and ("http" in v or "pic" in v.lower()):
                        pic_url = v
                        break
        print("  图片URL:", pic_url)
except:
    pic_url = None
    print("  无法解析 URL")

s.close()
print("\nDone")
