#!/usr/bin/env python3 """家纺情报的中文标题翻译与术语校准。""" from __future__ import annotations import re from pathlib import Path from typing import Any import requests if __package__: from .update_textile_trends import load_zh_cache, save_zh_cache, translate_to_zh_cn else: from update_textile_trends import load_zh_cache, save_zh_cache, translate_to_zh_cn BROWSER_UA = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0 Safari/537.36" ) CALENDAR_TITLE_OVERRIDES = { "New Year's Day": "元旦", "New Year’s Day": "元旦", "New Year's Eve": "跨年夜", "St. Stephen's Day": "圣斯蒂芬节", "Christmas Eve": "平安夜", "Pentecost": "圣灵降临节", "Immaculate Conception": "圣母无染原罪节", "Maundy Thursday": "濯足节", "Chuseok": "韩国秋夕", "All Saints Day": "诸圣节", "All Saints' Day Eve": "诸圣节前夜", "All Souls' Day": "追思亡者节", "Armistice Day": "停战纪念日", "Summer bank holiday": "夏季银行假日", "Early May bank holiday": "五月初银行假日", "Spring bank holiday": "春季银行假日", "May Day": "五一劳动节", "Good Friday": "耶稣受难日", "Holy Saturday": "圣周六", "Easter Monday": "复活节星期一", "Christmas Day": "圣诞节", "Boxing Day": "节礼日", "Saint Patrick's Day": "圣帕特里克节", "St Patrick’s Day": "圣帕特里克节", "National Heroes Day": "国家英雄日", "National Day for Truth and Reconciliation": "真相与和解国家纪念日", "National Day of Spain": "西班牙国庆日", "German Unity Day": "德国统一日", "National Foundation Day": "建国纪念日", "Hangul Day": "韩文日", "Labour Thanksgiving Day": "勤劳感谢之日", "Thanksgiving": "感恩节", "Remembrance Day": "阵亡将士纪念日", "Veterans Day": "退伍军人节", "Day of Reconciliation": "和解日", "Day of Goodwill": "友善日", "Deepavali": "屠妖节", "Hari Raya Puasa": "开斋节", "Hari Raya Haji": "哈芝节", "Vesak Day": "卫塞节", "Eid al-Fitr First Day (Tentative Date)": "开斋节首日(暂定)", "Eid al-Fitr Second Day (Tentative Date)": "开斋节次日(暂定)", "Eid al-Fitr Third Day (Tentative Date)": "开斋节第三日(暂定)", "Eid al-Adha First Day (Tentative Date)": "宰牲节首日(暂定)", "Eid al-Adha Second Day (Tentative Date)": "宰牲节次日(暂定)", "Eid al-Adha Third Day (Tentative Date)": "宰牲节第三日(暂定)", "Eid al-Adha Fourth Day (Tentative Date)": "宰牲节第四日(暂定)", "Anzac Day": "澳新军团日", "Waitangi Day": "怀唐伊日", "Matariki": "毛利新年 Matariki", "Juneteenth National Independence Day": "六月节国家独立日", } def normalize_text(value: str) -> str: return " ".join((value or "").replace("\u00a0", " ").split()) def refine_calendar_translation(value: str) -> str: replacements = { "假定日期": "暂定日期", "第一天(暂定日期)": "首日(暂定)", "第二天(暂定日期)": "次日(暂定)", "第三天(暂定日期)": "第三日(暂定)", "第四天(暂定日期)": "第四日(暂定)", "银行关闭日": "银行休业日", "家庭日": "家庭日", } output = normalize_text(value) for source, target in replacements.items(): output = output.replace(source, target) return output def translate_calendar_titles(items: list[dict[str, Any]], output_dir: Path, max_new: int = 260) -> None: cache = load_zh_cache(output_dir) session = requests.Session() session.headers.update({"User-Agent": BROWSER_UA, "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"}) translated_count = 0 cache_changed = False for item in items: current = normalize_text(str(item.get("title") or "")) if not current: continue english = normalize_text(str(item.get("title_english") or current)) translated = CALENDAR_TITLE_OVERRIDES.get(english) if translated: if item.get("source_id") != "calendar_nager" or not item.get("title_original"): item["title_original"] = current item["title"] = translated item["translation_status"] = "已按权威节日名称校准并保留当地名称" continue if re.search(r"[\u4e00-\u9fff]", current): continue translated = cache.get(english) if not translated and translated_count < max_new: translated = translate_to_zh_cn(session, english) if translated: cache[english] = translated translated_count += 1 cache_changed = True if not translated or not re.search(r"[\u4e00-\u9fff]", translated): translated = f"{english}({item.get('region') or '当地'}公共假日)" item["translation_status"] = "保留官方名称并补充中文语境" else: translated = refine_calendar_translation(translated) item["translation_status"] = "已翻译并保留官方名称" if item.get("source_id") != "calendar_nager" or not item.get("title_original"): item["title_original"] = current item["title"] = translated if cache_changed: save_zh_cache(output_dir, cache)