#!/usr/bin/env python3 """ 英文台词优化 & 回填脚本 v2 — 使用精确行号 规则:MEMORY.md 对话台词优化通用规则 知识点:grandmother, grandfather, visit, today 句型知识点:... visit+sb, Today is... """ import json, subprocess # (sheet_row, optimized_F_value) — exact sheet row numbers rows = [ (3, "Open up!"), (4, "Your letter is here!"), (6, "Nobody answers?"), (7, "Alright... I'll go in myself."), (9, "Whoa! What a mess!"), (11, "What's wrong?"), (12, "Vicky? Can you hear me?"), (14, "Today is a No-Mom-and-Dad day!"), (15, "Our parents aren't home!"), (16, "So we can do whatever we want!"), (17, "Really?"), (19, "Yes!"), (20, "Today is a good day!"), (21, "Huh?"), (22, "Are you sure today is a good day?"), (23, "So on a good day, nobody says sorry?"), (24, "Eva, Peter, say sorry."), (25, "Okay. We're sorry."), (27, "Ah, kids."), (28, "Come visit us!"), (29, "Oh, I'm not here to visit."), (30, "I'm here to give you something."), (32, "Wait a moment."), (34, "Hello? Grandfather and grandmother, how are you?"), (35, "Good, good! We're great!"), (36, "How are you all, my lovely grandchildren?"), (37, "We're great! Today is so much fun!"), (38, "Great to hear that!"), (39, "Are you ready for us?"), (40, "I'm so excited to visit you all!"), (41, "Sure! When will you visit us?"), (42, "Today is the day, of course!"), (43, "What? You're both coming today?"), (44, "Yes! Me and Justin. Your grandmother and grandfather."), (45, "We sent you a letter. Remember?"), (46, "See you later!"), (47, "I love you! Bye!"), (49, "Oh no! What did they say on the phone?"), (50, "Your grandfather and grandmother are coming to visit you!"), (51, "On your good day."), (53, "Eva! Peter! Alex! We're in trouble!"), (55, "What happened?"), (56, "Grandfather and grandmother are coming to visit us!"), (57, "So what?"), (58, "Today! Right now!"), (60, "No, not today..."), (61, "Look at this place!"), (62, "Yes, today is a total mess."), (63, "It's not the best day for visitors."), (64, "They could be here at any minute!"), (65, "How will they feel about this?"), (67, "Grandfather and grandmother will be so upset!"), (69, "What should we do?"), (70, "Don't worry! I'll help you clean up!"), (71, "Okay, first pick up the toys from the floor."), (73, "Oh no! No time to put these away!"), (74, "Put them in the cupboard!"), (75, "Your grandfather and grandmother won't see!"), (76, "Good idea!"), (79, "All done!"), (80, "We need to clean the floor!"), (81, "I'll do it!"), (84, "Will Grandfather and Grandmother be happy?"), (85, "Well... this will do for now."), (86, "Before your grandfather and grandmother come to visit."), (88, "Alex! The sofa is a mess!"), (89, "I'll clean it."), (91, "I can't get the chocolate off!"), (92, "I'm good at many things. Just not housework!"), (94, "Oh no! We can't clean up in time!"), (95, "I wish we had more time for this!"), (96, "Why today, of all days?"), (97, "I don't want them to see our house like this."), (98, "Why didn't they tell us earlier?"), (100, "I think they did tell you..."), (101, "In this letter."), (102, "What is in this letter?"), (104, "Hi, your grandfather is writing this letter."), (105, "I will come to visit you guys."), (106, "Your grandmother will visit you too!"), (107, "We love you, see you soon!"), (108, "They were so happy to visit you!"), (109, "Yes. We should be happy too."), (110, "We should not be grumpy like this."), (111, "Let's do something to welcome them!"), (112, "You can make something they like!"), (113, "What is their favourite food?"), (114, "Grandmother likes apples."), (115, "Grandfather likes pie."), (116, "Then you can make apple pie for them!"), (117, "I remember the recipe."), (118, "I can fix the cooking robot."), (119, "Okay! Apple pie is today's welcome gift!"), (121, "You did it!"), (122, "Now we just wait for them to arrive."), (124, "They're coming!"), (126, "Who wants a big hug from Grandfather?"), (127, "Me! Me!"), (128, "Who wants Grandmother's homemade candy?"), (129, "Me! Me!"), (131, "We made something for you."), (132, "Mmm! What's that smell? Is that a pie?"), (133, "I smell apples!"), (134, "Whoa! I know that smell! Apple pie!"), (135, "That is our favourite!"), (137, "Oh, you have a friend over!"), (138, "Hello! I am here to visit Vicky."), (139, "Nice to meet you again!"), (140, "I guess you helped out today too."), (142, "Today seems pretty busy."), (143, "Yes, we made a little mess before you came."), (144, "Today was not easy."), (145, "That's okay."), (146, "Grandfather and Grandmother can fix anything."), (147, "That's what family is for!"), (148, "Mess or not, we love seeing you!"), ] print(f"Total dialogue lines: {len(rows)}") # Build the complete column F data (one value per row, 1-based sheet rows 2-149) # We need to clear the ENTIRE column first, then fill only dialogue rows. # The API PUT overwrites the specified range. Write all rows 2-149. # Use a dict for fast lookup f_map = {r: v for r, v in rows} # Get token with open("/root/.openclaw/credentials/xiaoyan/config.json") as f: cfg = json.load(f) app_id = "cli_a931175d41799cc7" app_secret = cfg["apps"][0]["appSecret"] result = subprocess.run([ "curl", "-s", "-X", "POST", "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", "-H", "Content-Type: application/json", "-d", json.dumps({"app_id": app_id, "app_secret": app_secret}) ], capture_output=True, text=True) token = json.loads(result.stdout)["tenant_access_token"] spreadsheet_token = "DA7csROG6hmnQMt59oScOLRfnWc" sheet_id = "Nr3Ovs" # Step 1: Clear entire column F (rows 2-149) print("Clearing column F (rows 2-149)...") empty_payload = { "valueRange": { "range": f"{sheet_id}!F2:F149", "values": [[""] for _ in range(148)] # 149-2+1 = 148 rows } } result = subprocess.run([ "curl", "-s", "-X", "PUT", f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values", "-H", f"Authorization: Bearer {token}", "-H", "Content-Type: application/json", "-d", json.dumps(empty_payload) ], capture_output=True, text=True) resp = json.loads(result.stdout) print(f" Clear: code={resp.get('code')}, msg={resp.get('msg')}") assert resp.get("code") == 0, f"Clear failed: {result.stdout[:200]}" # Step 2: Write optimized values to each dialogue row # Group consecutive rows for batching batch_start = None batch_end = None batch_values = [] def flush_batch(): global batch_start, batch_end, batch_values if not batch_values: return range_str = f"{sheet_id}!F{batch_start}:F{batch_end}" payload = {"valueRange": {"range": range_str, "values": batch_values}} result = subprocess.run([ "curl", "-s", "-X", "PUT", f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values", "-H", f"Authorization: Bearer {token}", "-H", "Content-Type: application/json", "-d", json.dumps(payload) ], capture_output=True, text=True) resp = json.loads(result.stdout) print(f" Write {range_str}: code={resp.get('code')}, msg={resp.get('msg')}") assert resp.get("code") == 0, f"Write failed: {result.stdout[:200]}" batch_start = None batch_end = None batch_values = [] # Also need to fill empty rows between dialogue rows # Strategy: write row by row, merging consecutive rows into batches for sheet_row in range(2, 150): value = f_map.get(sheet_row, "") if batch_start is None: batch_start = sheet_row batch_end = sheet_row batch_values = [[value]] else: batch_end = sheet_row batch_values.append([value]) flush_batch() print("Done! Verifying...") # Step 3: Verify key rows check_rows = [3, 7, 14, 23, 28, 34, 44, 49, 56, 64, 92, 97, 111, 121, 134, 147] for r in check_rows: result = subprocess.run([ "curl", "-s", "-X", "GET", f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values/{sheet_id}!D{r}:F{r}?valueRenderOption=ToString", "-H", f"Authorization: Bearer {token}" ], capture_output=True, text=True) vals = json.loads(result.stdout).get("data", {}).get("valueRange", {}).get("values", [[]])[0] role = vals[0] if len(vals) > 0 else "-" e_val = vals[1] if len(vals) > 1 else "-" f_val = vals[2] if len(vals) > 2 else "-" expected = f_map.get(r, "-") status = "✓" if f_val == (expected or "") else "✗ MISMATCH" if status != "✓": print(f" Row {r}: [{role}] E='{e_val}' F='{f_val}' expected='{expected}' {status}") else: print(f" Row {r}: [{role}] F='{f_val}' {status}") print("\nAll verified!")