125 lines
6.8 KiB
Python
125 lines
6.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Task 1: Fix all structured empty seconds → "second": {}
|
|
Task 2: Add 图片描述 to 021601, 021801, 022001"""
|
|
import requests, json, time
|
|
|
|
APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf"
|
|
APP_ID = "cli_a931175d41799cc7"
|
|
APP_SECRET = "Iw2vEfbjT6GtV0GhbxbZqfQ4nAPtbR14"
|
|
|
|
def get_token():
|
|
r = requests.post("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
|
|
json={"app_id": APP_ID, "app_secret": APP_SECRET}, timeout=10)
|
|
return r.json()["tenant_access_token"]
|
|
|
|
token = get_token()
|
|
|
|
# List all tables in the bitable
|
|
r = requests.get(f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables",
|
|
headers={"Authorization": f"Bearer {token}"}, timeout=15)
|
|
tables = r.json().get("data", {}).get("items", [])
|
|
print(f"共 {len(tables)} 个表\n")
|
|
|
|
# ====== Task 1: Scan all tables for structured empty second blocks ======
|
|
fixes_second = [] # (table_id, table_name, qsid, rid)
|
|
|
|
for t in tables:
|
|
tid = t["table_id"]
|
|
tname = t["name"]
|
|
r = requests.get(f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{tid}/records?page_size=200",
|
|
headers={"Authorization": f"Bearer {token}"}, timeout=15)
|
|
items = r.json().get("data", {}).get("items", [])
|
|
for it in items:
|
|
f = it["fields"]
|
|
qsid = f.get("题目集合 ID", "") or ""
|
|
jd_raw = f.get("jsonData", "")
|
|
if not jd_raw: continue
|
|
try:
|
|
jd = json.loads(jd_raw) if isinstance(jd_raw, str) else jd_raw
|
|
except:
|
|
continue
|
|
|
|
second = jd.get("second", None)
|
|
if not second or not isinstance(second, dict):
|
|
continue
|
|
|
|
# Check if structured empty: has type/questionSetID but empty questionSet
|
|
qs = second.get("questionSet", None)
|
|
if qs is not None and isinstance(qs, list) and len(qs) == 0:
|
|
# Has structure but no content → fix to {}
|
|
fixes_second.append((tid, tname, qsid, it["record_id"], second))
|
|
|
|
print(f"=== Task 1: 修复结构化空 second → {{}} ===")
|
|
print(f"发现 {len(fixes_second)} 条需要修复\n")
|
|
|
|
for tid, tname, qsid, rid, old_second in fixes_second:
|
|
# Fetch fresh record to get current jsonData
|
|
r = requests.get(f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{tid}/records/{rid}",
|
|
headers={"Authorization": f"Bearer {token}"}, timeout=10)
|
|
rec = r.json()["data"]["record"]
|
|
jd = json.loads(rec["fields"]["jsonData"])
|
|
|
|
# Before
|
|
old_type = jd["second"].get("type", "?")
|
|
|
|
# Replace with empty object
|
|
jd["second"] = {}
|
|
|
|
new_jd = json.dumps(jd, ensure_ascii=False)
|
|
r = requests.put(
|
|
f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{tid}/records/{rid}",
|
|
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
|
|
json={"fields": {"jsonData": new_jd}}, timeout=15)
|
|
code = r.json().get("code")
|
|
print(f" {'✅' if code==0 else '❌'} [{tname}] {qsid}: second({old_type}) → {{}}")
|
|
time.sleep(0.3)
|
|
|
|
# ====== Task 2: Add 图片描述 to 021601, 021801, 022001 ======
|
|
print(f"\n=== Task 2: 补充图片描述 ===")
|
|
|
|
pic_map = {
|
|
"021601": '[1-组图]:{"prompt_2":"黑白线条图:一个孩子在公园里焦急地四处张望,似乎在寻找丢失的玩具,背景有秋千、滑梯和大树,远处是公园的出口","prompt_3":"黑白线条图:一个小男孩正在爬滑梯的顶部,一个较大的孩子站在下面焦急地伸手示意他下来,表情紧张","prompt_4":"黑白线条图:公园入口处可以看到周围的商店、图书馆和警察亭,一位公园工作人员站在指示牌旁微笑着指路"}',
|
|
"021801": '[1-组图]:{"prompt_2":"黑白线条图:一个孩子躺在床上盖着被子,额头上放着湿毛巾,他的朋友坐在床边端来一杯水,床头柜上放着药瓶","prompt_3":"黑白线条图:两个同学坐在教室的课桌前,一个正在耐心地指着作业本给另一个讲解题目,旁边放着课本和铅笔","prompt_4":"黑白线条图:两个孩子并肩坐在草地上,一个孩子指着远方天空中的热气球,脸上带着鼓励和期待的表情","prompt_5":"黑白线条图:教室里,一个孩子帮忙扶住同学够高处的书本,另一个孩子在帮老师整理教具,气氛温馨互助"}',
|
|
"022001": '[1-组图]:{"prompt_2":"黑白线条图:学校走廊里,一个孩子脸上带着担忧的表情蹲在墙角,另一个孩子走过来蹲下身关切地询问","prompt_3":"黑白线条图:一位爷爷坐在沙发上拉着孩子的手认真地说话,表情温和而坚定,孩子脸上露出理解的神情","prompt_4":"黑白线条图:教室里,一个孩子站在讲台上自信地展示自己的画作,台下的同学们都在热烈鼓掌,孩子脸上带着自豪的笑容","prompt_5":"黑白线条图:书房里,一位家长蹲在孩子面前轻声解释着笔记本上的内容,墙上贴着学习计划表和各种鼓励标语"}',
|
|
}
|
|
|
|
# Speaking-P2 table
|
|
SP2_TABLE = "tblGoWYBmVI0IrvQ"
|
|
r = requests.get(f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{SP2_TABLE}/records?page_size=200",
|
|
headers={"Authorization": f"Bearer {token}"}, timeout=15)
|
|
|
|
for it in r.json()["data"]["items"]:
|
|
qsid = it["fields"].get("题目集合 ID", "")
|
|
if qsid not in pic_map: continue
|
|
rid = it["record_id"]
|
|
r = requests.put(
|
|
f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{SP2_TABLE}/records/{rid}",
|
|
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
|
|
json={"fields": {"图片描述": pic_map[qsid]}}, timeout=15)
|
|
code = r.json().get("code")
|
|
print(f" {'✅' if code==0 else '❌'} {qsid}: 图片描述已写入")
|
|
|
|
# ====== Verify ======
|
|
print(f"\n=== 验证 ===")
|
|
# Spot-check one from each table
|
|
for tid, tname, qsid, rid, _ in fixes_second[:3]: # first 3
|
|
r = requests.get(f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{tid}/records/{rid}",
|
|
headers={"Authorization": f"Bearer {token}"}, timeout=10)
|
|
jd = json.loads(r.json()["data"]["record"]["fields"]["jsonData"])
|
|
second = jd.get("second", None)
|
|
status = "✅ {}" if second == {} else f"❌ {json.dumps(second, ensure_ascii=False)[:50]}"
|
|
print(f" [{tname}] {qsid}: second={status}")
|
|
|
|
# Verify pic
|
|
for qsid in pic_map:
|
|
r = requests.get(f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{SP2_TABLE}/records?page_size=200",
|
|
headers={"Authorization": f"Bearer {token}"}, timeout=15)
|
|
for it in r.json()["data"]["items"]:
|
|
if it["fields"].get("题目集合 ID") == qsid:
|
|
pic = it["fields"].get("图片描述", "")
|
|
print(f" {qsid}: 图片描述={'✅' if pic else '❌空'}")
|
|
break
|
|
time.sleep(0.2)
|
|
|
|
print("\n全部完成")
|