diff --git a/main.py b/main.py index 86ca390..3442998 100644 --- a/main.py +++ b/main.py @@ -822,8 +822,78 @@ def get_val(arr, idx, default="-"): # List to Grist format {"fields": {"A": ..., "B": ...}} def to_grist_record(row_list): - # chr(65+i) change to A, B, C... - return {"fields": {chr(65 + i): val for i, val in enumerate(row_list)}} + return {"fields": {col_to_letter(i + 1): val for i, val in enumerate(row_list)}} + +def is_price_slot_table_id(table_id: str): + return re.match(r"^PriceSlot[1-9]\d*$", table_id or "") is not None + +def build_grist_columns_from_price_content(content: list): + max_col = 0 + labels = {} + + for item in content: + item_header = item.get("header", []) + if isinstance(item_header, list): + for idx, label in enumerate(item_header, start=1): + if label: + labels[idx] = str(label) + max_col = max(max_col, idx) + + cells = item.get("cells", []) + if isinstance(cells, list): + for idx, cell in enumerate(cells, start=1): + coord = cell.get("coord", {}) if isinstance(cell, dict) else {} + col = coord.get("col", idx) if isinstance(coord, dict) else idx + try: + max_col = max(max_col, int(col)) + except Exception: + max_col = max(max_col, idx) + + if max_col <= 0: + max_col = 1 + + columns = [] + for col in range(1, max_col + 1): + col_id = col_to_letter(col) + columns.append({ + "id": col_id, + "fields": {"label": labels.get(col, col_id)} + }) + + return columns + +def ensure_price_slot_table(doc_id: str, table_id: str, content: list): + if not is_price_slot_table_id(table_id): + return + + headers = {"Authorization": f"Bearer {GRIST_API_KEY}", "Content-Type": "application/json"} + base_url = f"{GRIST_URL.rstrip('/')}/api/docs/{doc_id}/tables" + + check_resp = request_with_retry( + "GET", + f"{base_url}/{table_id}/records", + headers=headers + ) + + if check_resp.status_code == 200: + return + + if check_resp.status_code != 404: + raise Exception(f"[{SERVICE_NAME}] Cannot check price slot table {table_id}: {check_resp.text}") + + column_defs = build_grist_columns_from_price_content(content) + create_resp = request_with_retry( + "POST", + base_url, + headers=headers, + json={"tables": [{"id": table_id, "columns": column_defs}]} + ) + + if create_resp.status_code != 200: + raise Exception(f"[{SERVICE_NAME}] Create price slot table {table_id} failed: {create_resp.text}") + + print(f"[{SERVICE_NAME}] Created price slot table {table_id} with {len(column_defs)} columns") + time.sleep(1) def handle_add_menu(country: str, catalog: str, content: list): try: @@ -1893,6 +1963,7 @@ def handle_add_price(country: str, content: list, option: str = ""): raise Exception (f"[{SERVICE_NAME}] No price records to add") headers = {"Authorization": f"Bearer {GRIST_API_KEY}", "Content-Type": "application/json"} + ensure_price_slot_table(doc_price, table_id, content) url = f"{GRIST_URL.rstrip('/')}/api/docs/{doc_price}/tables/{table_id}/records" try: