106 lines
3.3 KiB
Python
106 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
将行课记录结果分组写入飞书表格 (Sheet1 55b0eb)
|
|
"""
|
|
import json
|
|
import requests
|
|
import os
|
|
|
|
SPREADSHEET_TOKEN = "RFIJsXT8FhGHhctY4RwczcOfnac"
|
|
SHEET_ID = "55b0eb"
|
|
CRED_DIR = "/root/.openclaw/credentials/xiaoxi"
|
|
|
|
def get_token():
|
|
with open(os.path.join(CRED_DIR, "config.json")) as f:
|
|
cfg = json.load(f)
|
|
app_id = cfg['apps'][0]['appId']
|
|
app_secret = cfg['apps'][0]['appSecret']
|
|
resp = requests.post("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
|
|
json={"app_id": app_id, "app_secret": app_secret})
|
|
return resp.json()['tenant_access_token']
|
|
|
|
def write_range(token, range_str, values):
|
|
"""Write values to a sheet range"""
|
|
url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values"
|
|
body = {
|
|
"valueRange": {
|
|
"range": f"{SHEET_ID}!{range_str}",
|
|
"values": values
|
|
}
|
|
}
|
|
resp = requests.put(url, headers={
|
|
"Authorization": f"Bearer {token}",
|
|
"Content-Type": "application/json"
|
|
}, json=body)
|
|
result = resp.json()
|
|
return result.get('code') == 0
|
|
|
|
def main():
|
|
with open('/tmp/sheet_course_results.json') as f:
|
|
data = json.load(f)
|
|
|
|
results = data['results']
|
|
results.sort(key=lambda x: x['row_idx'])
|
|
|
|
# Group consecutive rows into batches
|
|
batches = []
|
|
current_batch = []
|
|
prev_row = None
|
|
|
|
for r in results:
|
|
if prev_row is not None and r['row_idx'] != prev_row + 1:
|
|
# Gap found, start new batch
|
|
if current_batch:
|
|
batches.append(current_batch)
|
|
current_batch = [r]
|
|
else:
|
|
current_batch.append(r)
|
|
prev_row = r['row_idx']
|
|
|
|
if current_batch:
|
|
batches.append(current_batch)
|
|
|
|
print(f"Total batches: {len(batches)}, total rows: {len(results)}")
|
|
|
|
token = get_token()
|
|
print("Token obtained")
|
|
|
|
written = 0
|
|
failed = 0
|
|
|
|
for idx, batch in enumerate(batches):
|
|
start_row = batch[0]['row_idx']
|
|
end_row = batch[-1]['row_idx']
|
|
|
|
# Build values array: [record, update_time] for each row
|
|
# For contiguous batches, fill all rows
|
|
values = []
|
|
batch_idx = 0
|
|
for row_num in range(start_row, end_row + 1):
|
|
if batch_idx < len(batch) and batch[batch_idx]['row_idx'] == row_num:
|
|
values.append([batch[batch_idx]['record'], batch[batch_idx]['update_time']])
|
|
batch_idx += 1
|
|
else:
|
|
# Empty cell for non-target rows (important for non-contiguous fills in contiguous range)
|
|
values.append(['', ''])
|
|
|
|
range_str = f"D{start_row}:E{end_row}"
|
|
|
|
if write_range(token, range_str, values):
|
|
written += len(batch)
|
|
if (idx + 1) % 20 == 0:
|
|
print(f" ... {idx+1}/{len(batches)} batches done, {written} rows written")
|
|
else:
|
|
failed += len(batch)
|
|
print(f" FAILED batch {idx+1}: rows {start_row}-{end_row} ({len(batch)} rows)")
|
|
|
|
print(f"\nDone: {written} wrote, {failed} failed")
|
|
|
|
# Show sample result from first batch
|
|
if batches:
|
|
sample = batches[0][0]
|
|
print(f"\nSample: Row {sample['row_idx']}: {sample['record'][:100]}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|