""" Fix remaining records: P5 ability tag, P6 ability tags, JSON fixes for 5 broken records """ import json, urllib.request, re APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf" CRED_FILE = "/root/.openclaw/credentials/xiaoyan/config.json" STD_HEARING_TAGS = { "显性事实理解|关键词识别", "显性事实理解|单句信息点抓取", "基础语境理解|场景/物品/动作识别", "显性细节理解|数字/时间/地点", "同义替换识别|词/短语级", "目的/偏好识别|显性 to/for/like", "干扰抑制|多信息筛选", "语用推断|否定与纠错", "多句保持|信息整合", "情绪/态度理解", "长对话理解|主旨+细节", } # Tag mapping for section-level ability (P5 style) SECTION_TAG_MAP = { "听觉抓取关键信息": "显性事实理解|关键词识别", } def get_token(): with open(CRED_FILE) as f: cfg = json.load(f) app_id = cfg['apps'][0]['appId'] app_secret = cfg['apps'][0]['appSecret'] req = urllib.request.Request( "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", data=json.dumps({"app_id": app_id, "app_secret": app_secret}).encode(), headers={"Content-Type": "application/json"}) return json.loads(urllib.request.urlopen(req).read())['tenant_access_token'] def api_call(url, method='GET', body=None): token = get_token() headers = {"Authorization": f"Bearer {token}"} data = json.dumps(body).encode() if body else None if data: headers["Content-Type"] = "application/json" req = urllib.request.Request(url, data=data, method=method, headers=headers) return json.loads(urllib.request.urlopen(req).read()) def update_record(table_id, record_id, fields): url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{table_id}/records/{record_id}" return api_call(url, 'PUT', {"fields": fields}) # 1. Fix P5 032801 - update section-level ability print("=== P5 032801 ===") url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/tblDssVmhGzc3UKd/records?page_size=50" resp = api_call(url) for item in resp['data']['items']: sid = item['fields'].get('题目集合 ID', '') if sid == '032801': rid = item['record_id'] jd = json.loads(item['fields']['jsonData']) old_ability = jd.get('first', {}).get('ability', []) new_ability = [SECTION_TAG_MAP.get(a, a) for a in old_ability] if new_ability != old_ability: jd['first']['ability'] = new_ability # Also fix per-question ability if it exists qs = jd.get('first', {}).get('questionSet', []) for q in qs: if 'ability' in q: old = q['ability'] if isinstance(old, list): q['ability'] = [SECTION_TAG_MAP.get(a, a) for a in old] new_jd = json.dumps(jd, ensure_ascii=False) result = update_record("tblDssVmhGzc3UKd", rid, {"jsonData": new_jd}) print(f" Updated: {result.get('code')}") else: print(f" No change needed") break # 2. Fix P6 records - add ability tags based on question content print("\n=== P6 ===") url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/tbloiMcD0sBtGSTq/records?page_size=50" resp = api_call(url) for item in resp['data']['items']: sid = item['fields'].get('题目集合 ID', '') if '010199' in str(sid): continue jd_str = item['fields'].get('jsonData', '{}') if not jd_str or jd_str == 'None': continue jd = json.loads(jd_str) qs = jd.get('questionSet', []) changed = False for q in qs: if not q.get('ability'): q['ability'] = ["显性事实理解|关键词识别"] # Default for P6 listening_choosePic changed = True if changed: new_jd = json.dumps(jd, ensure_ascii=False) result = update_record("tbloiMcD0sBtGSTq", item['record_id'], {"jsonData": new_jd}) print(f" ID={sid}: {'✅' if result.get('code')==0 else '❌'} ability filled") # 3. Fix 5 broken JSON records print("\n=== Fixing broken JSONs ===") broken_mapping = { "P2_021901": {"table_id": "tblzTLNH7f13uWQN", "sid": "021901"}, "P2_022301": {"table_id": "tblzTLNH7f13uWQN", "sid": "022301"}, "P4_021301": {"table_id": "tblVmeDtBDKsAEfz", "sid": "021301"}, "P4_021601": {"table_id": "tblVmeDtBDKsAEfz", "sid": "021601"}, "P4_021801": {"table_id": "tblVmeDtBDKsAEfz", "sid": "021801"}, } for key, info in broken_mapping.items(): with open(f'/tmp/fixed_{key}.txt') as f: fixed_jd = f.read() # Update ability tags in fixed JSON too jd = json.loads(fixed_jd) changed = False for section in ['first', 'second']: sect = jd.get(section, {}) if not sect: continue qs = sect.get('questionSet', []) for q in qs: old = q.get('ability', []) if isinstance(old, list): new = [SECTION_TAG_MAP.get(a, a) for a in old] if new != old: q['ability'] = new changed = True if changed: fixed_jd = json.dumps(jd, ensure_ascii=False) # Find record_id url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{info['table_id']}/records?page_size=50" resp = api_call(url) for item in resp['data']['items']: if item['fields'].get('题目集合 ID', '') == info['sid']: rid = item['record_id'] result = update_record(info['table_id'], rid, {"jsonData": fixed_jd}) print(f" {key}: {'✅' if result.get('code')==0 else '❌'} fixed+tags") break print("\nDone!")