#!/usr/bin/env python3
"""Build the GHC-05 and GHC-06 galleries from the existing KSP screenshots."""
from __future__ import annotations
import html
import os
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SOURCE_ROOT = ROOT / "user_input" / "广寒计划"
WIKI_ROOT = ROOT / "data" / "wiki"
STAGING_ROOT = ROOT / "output" / "wiki-gallery-upload"
GALLERIES = {
"GHC-05": {
"title": "广寒基地建设任务-05 任务图集",
"page": "home/mission/Guanghan_Program/GHC-05",
"previous": ("GHC-04", "/home/mission/Guanghan_Program/GHC-04/Gallery"),
"next": ("GHC-06", "/home/mission/Guanghan_Program/GHC-06/Gallery"),
"folder": "guanghan-ghc-05",
"output": "guanghan_ghc05_gallery_zh.html",
"intro": "现有任务影像按任务阶段整理,共 28 张。点击图片可打开大图并使用方向键切换。",
"items": [
("载人发射与地月转移", "CZ-16A二级视角-夜间发射.png", "crew_launch_night.png", "CZ-16A 夜间发射", "CZ-16A 搭载嫦娥六号与吴刚二号升空,画面为夜间上升段的二级视角。"),
("载人发射与地月转移", "CZ-16A执行TLI燃烧.png", "crew_tli_burn.png", "CZ-16A 执行 TLI", "运载火箭上面级执行地月转移注入,将嫦娥六号与吴刚二号组合体送往月球。"),
("载人发射与地月转移", "嫦娥6号分离.png", "change6_separation.png", "嫦娥六号分离", "嫦娥六号与上面级分离,准备执行掉头和着陆器提取操作。"),
("载人发射与地月转移", "嫦娥6号掉头,准备取出吴刚2.png", "change6_turnaround.png", "嫦娥六号掉头", "嫦娥六号完成掉头,接近仍固定在桁架上的吴刚二号。"),
("载人发射与地月转移", "嫦娥6号取出吴刚2.png", "change6_extracts_wugang2.png", "嫦娥六号取出吴刚二号", "嫦娥六号对接吴刚二号并将其从发射桁架中拖出,组合体进入巡航构型。"),
("载人发射与地月转移", "嫦娥6号近月制动.png", "change6_loi.png", "嫦娥六号近月制动", "嫦娥六号与吴刚二号组合体执行近月制动,进入绕月轨道。"),
("吴刚二号着陆", "吴刚2号与嫦娥分离准备着陆.png", "wugang2_separation.png", "吴刚二号分离", "吴刚二号与嫦娥六号分离,开始独立下降与着陆准备。"),
("吴刚二号着陆", "吴刚2号主减速段.png", "wugang2_descent_burn.png", "吴刚二号主减速", "吴刚二号主发动机点火执行下降主减速。"),
("吴刚二号着陆", "吴刚2号着陆.png", "wugang2_landing.png", "吴刚二号着陆", "吴刚二号在东方海广寒基地附近完成月面着陆。"),
("广寒 03 模块运输", "CZ-16发射广寒03模块.png", "gh03_launch.png", "CZ-16 发射广寒 03", "CZ-16 搭载广寒 03 扩建模块从文昌升空。"),
("广寒 03 模块运输", "CZ-16发射广寒03模块2.png", "gh03_launch_second_view.png", "广寒 03 发射另一视角", "广寒 03 模块发射上升段的另一视角。"),
("广寒 03 模块运输", "金蟾1号与广寒03模块对接.png", "jinchan1_docks_gh03.png", "金蟾一号对接广寒 03", "金蟾一号在近地轨道与广寒 03 模块完成对接。"),
("广寒 03 模块运输", "金蟾1号携带广寒03TLI.png", "jinchan1_gh03_tli.png", "金蟾一号携带广寒 03 执行 TLI", "金蟾一号携带广寒 03 模块执行地月转移点火。"),
("广寒 03 模块运输", "冰轮3号和金蟾1号交汇.png", "binglun3_rendezvous_jinchan1.png", "冰轮三号与金蟾一号交会", "冰轮三号在绕月轨道接近携带广寒 03 模块的金蟾一号。"),
("广寒 03 模块运输", "冰轮3号着陆.png", "binglun3_landing_gh03.png", "冰轮三号运送广寒 03 着陆", "冰轮三号携带广寒 03 模块在广寒基地着陆。"),
("冰轮运输调度", "冰轮2号起飞.png", "binglun2_takeoff.png", "冰轮二号起飞", "冰轮二号从月面起飞,执行燃料运输任务。"),
("冰轮运输调度", "冰轮2号与金蟾1号对接.png", "binglun2_docks_jinchan1.png", "冰轮二号对接金蟾一号", "冰轮二号在绕月轨道与金蟾一号对接并转移燃料。"),
("冰轮运输调度", "金蟾1号点火返回地球(可见后方冰轮2号).png", "jinchan1_return_burn_binglun2.png", "金蟾一号返航点火", "金蟾一号执行返回地球点火,画面后方可见冰轮二号。"),
("冰轮运输调度", "金蟾1号近地制动.png", "jinchan1_earth_braking.png", "金蟾一号近地制动", "金蟾一号返回地球附近并执行近地制动。"),
("冰轮运输调度", "冰轮2号着陆中.png", "binglun2_descent.png", "冰轮二号下降", "冰轮二号完成轨道补给后返回月面。"),
("冰轮运输调度", "冰轮2号着陆.png", "binglun2_landing.png", "冰轮二号着陆", "冰轮二号重新着陆于广寒基地。"),
("乘组撤离与返回", "吴刚2号起飞(01-19).png", "wugang2_takeoff.png", "吴刚二号起飞", "吴刚二号搭载 GHC-05 乘组从月面起飞。"),
("乘组撤离与返回", "嫦娥6号与吴刚2号对接(01-19).png", "change6_docks_wugang2.png", "嫦娥六号对接吴刚二号", "嫦娥六号在绕月轨道与吴刚二号完成对接。"),
("乘组撤离与返回", "嫦娥6号携带吴刚2号升轨(01-19).png", "change6_wugang2_raise_orbit.png", "嫦娥六号携带吴刚二号升轨", "组合体升轨至停泊轨道,吴刚二号随后留轨复用。"),
("乘组撤离与返回", "冰轮3号起飞.png", "binglun3_takeoff.png", "冰轮三号起飞", "冰轮三号从月面起飞执行下一轮轨道运输。"),
("乘组撤离与返回", "冰轮3号起飞过程中,从嫦娥6号45公里处略过.png", "binglun3_passes_change6.png", "冰轮三号掠过嫦娥六号", "冰轮三号上升过程中从嫦娥六号约 45 公里外掠过。"),
("乘组撤离与返回", "嫦娥6号点火返回地球(01-20).png", "change6_return_burn.png", "嫦娥六号返回点火", "嫦娥六号离开绕月轨道,执行返回地球点火。"),
("乘组撤离与返回", "嫦娥6号再入(01-22).png", "change6_reentry.png", "嫦娥六号再入", "嫦娥六号返回舱再入地球大气层。"),
],
},
"GHC-06": {
"title": "广寒基地建设任务-06 任务图集",
"page": "home/mission/Guanghan_Program/GHC-06",
"previous": ("GHC-05", "/home/mission/Guanghan_Program/GHC-05/Gallery"),
"next": None,
"folder": "guanghan-ghc-06",
"output": "guanghan_ghc06_gallery_zh.html",
"intro": "现有任务影像按任务阶段整理,共 25 张。点击图片可打开大图并使用方向键切换。",
"items": [
("载人飞行与月面着陆", "CZ-16A二级携带组合体进行TLI.png", "crew_tli.png", "CZ-16A 二级执行 TLI", "CZ-16A 二级携带嫦娥七号与吴刚三号组合体执行地月转移注入。"),
("载人飞行与月面着陆", "嫦娥7号准备和吴刚飞船对接(1月6日).png", "change7_dock_approach.png", "嫦娥七号接近吴刚三号", "嫦娥七号完成掉头,准备与吴刚三号对接。"),
("载人飞行与月面着陆", "嫦娥7号取出吴刚飞船.png", "change7_extracts_wugang3.png", "嫦娥七号取出吴刚三号", "嫦娥七号将吴刚三号从发射桁架中拖出。"),
("载人飞行与月面着陆", "嫦娥7号近月制动.png", "change7_loi.png", "嫦娥七号近月制动", "嫦娥七号与吴刚三号组合体执行近月制动。"),
("载人飞行与月面着陆", "吴刚3号准备着陆(1月11号).png", "wugang3_landing_approach.png", "吴刚三号准备着陆", "吴刚三号脱离绕月轨道,开始月面下降。"),
("载人飞行与月面着陆", "吴刚3号着陆中.png", "wugang3_landing.png", "吴刚三号着陆", "吴刚三号执行末段下降并着陆于东方海。"),
("广寒 04 模块运输", "CZ-10E发射广寒04模块(02-01).png", "gh04_launch.png", "CZ-10E 发射广寒 04", "CZ-10E 搭载广寒 04 扩建模块升空。"),
("广寒 04 模块运输", "金蟾3号准备和广寒04模块对接(02-01).png", "jinchan3_dock_gh04.png", "金蟾三号接近广寒 04", "金蟾三号在近地轨道接近并准备对接广寒 04 模块。"),
("广寒 04 模块运输", "金蟾3号携带广寒04模块执行TLI.png", "jinchan3_gh04_tli.png", "金蟾三号携带广寒 04 执行 TLI", "金蟾三号携带广寒 04 模块开始地月转移。"),
("广寒 04 模块运输", "冰轮3号变轨(02-08).png", "binglun3_deorbit_gh04.png", "冰轮三号变轨", "冰轮三号接收广寒 04 模块后执行下降变轨。"),
("广寒 04 模块运输", "冰轮3号着陆主减速段(02-08).png", "binglun3_descent_gh04.png", "冰轮三号主减速", "冰轮三号携带广寒 04 模块执行着陆主减速。"),
("广寒 04 模块运输", "冰轮3号着陆(02-08).png", "binglun3_landing_gh04.png", "冰轮三号运送广寒 04 着陆", "冰轮三号将广寒 04 模块送达广寒基地。"),
("冰轮编队调度", "冰轮2号起飞(02-08).png", "binglun2_takeoff.png", "冰轮二号起飞", "冰轮二号从月面起飞执行轨道燃料运输。"),
("冰轮编队调度", "冰轮2号与金蟾1号交汇(02-08).png", "binglun2_rendezvous_jinchan1.png", "冰轮二号与金蟾一号交会", "冰轮二号在绕月轨道接近金蟾一号。"),
("冰轮编队调度", "冰轮2号着陆(02-08).png", "binglun2_landing.png", "冰轮二号返回月面", "冰轮二号完成补给任务后返回广寒基地。"),
("冰轮编队调度", "冰轮3号起飞(02-08).png", "binglun3_takeoff.png", "冰轮三号起飞", "完成广寒 04 卸载后,冰轮三号再次起飞执行轨道任务。"),
("冰轮编队调度", "金蟾1号泊入近地轨道(02-13).png", "jinchan1_leo_arrival.png", "金蟾一号泊入近地轨道", "金蟾一号返回地球附近并泊入近地轨道。"),
("乘组撤离与返回", "吴刚3号准备起飞(25-03-14).png", "wugang3_prepares_takeoff.png", "吴刚三号准备起飞", "燃料系统修复完成后,吴刚三号进行月面起飞准备。"),
("乘组撤离与返回", "吴刚3号起飞(25-03-15).png", "wugang3_takeoff.png", "吴刚三号起飞", "吴刚三号搭载 GHC-06 乘组从月面起飞。"),
("乘组撤离与返回", "吴刚3号与嫦娥7号准备对接(25-03-15).png", "wugang3_change7_rendezvous.png", "吴刚三号接近嫦娥七号", "吴刚三号在绕月轨道接近嫦娥七号并完成乘组转移;随后组合体升轨至 400×400 km,吴刚三号留轨复用。"),
("乘组撤离与返回", "嫦娥7号点火返回地球(25-03-16).png", "change7_return_burn.png", "嫦娥七号返回点火", "嫦娥七号离开绕月轨道,开始返回地球。"),
("乘组撤离与返回", "嫦娥7号抛服务舱(25-03-19).png", "change7_service_module_sep.png", "嫦娥七号抛离服务舱", "再入前,嫦娥七号返回舱与服务舱分离。"),
("乘组撤离与返回", "嫦娥7号再入(25-03-19).png", "change7_reentry.png", "嫦娥七号再入", "嫦娥七号返回舱穿越地球大气层。"),
("乘组撤离与返回", "嫦娥7号开主伞(25-03-19).png", "change7_main_chutes.png", "嫦娥七号打开主伞", "返回舱主降落伞展开,进入最终下降阶段。"),
("乘组撤离与返回", "嫦娥7号返回文昌(25-03-19).png", "change7_wenchang_landing.png", "嫦娥七号返回文昌", "嫦娥七号返回舱在文昌回收场安全着陆,GHC-06 任务完成。"),
],
},
}
BASE_STYLE = """"""
def create_staged_asset(source: Path, staged: Path) -> None:
staged.parent.mkdir(parents=True, exist_ok=True)
if staged.exists():
if staged.stat().st_size != source.stat().st_size:
staged.unlink()
else:
return
try:
os.link(source, staged)
except OSError:
staged.write_bytes(source.read_bytes())
def build_gallery(code: str, config: dict) -> None:
source_dir = SOURCE_ROOT / code
staging_dir = STAGING_ROOT / code.lower()
sections: dict[str, list[str]] = {}
for section, source_name, upload_name, alt, caption in config["items"]:
source = source_dir / source_name
if not source.exists():
raise FileNotFoundError(source)
create_staged_asset(source, staging_dir / upload_name)
asset_path = f'/{config["folder"]}/{upload_name}'
card = (
f'

{html.escape(caption)}
'
)
sections.setdefault(section, []).append(card)
previous = config["previous"]
next_item = config["next"]
nav_parts = [f'← {previous[0]} 图集']
if next_item:
nav_parts.append(f'{next_item[0]} 图集 →')
nav = " | ".join(nav_parts)
body = [BASE_STYLE, '']
body.append(f'{config["title"]}
')
body.append(f'← 返回任务页 | 共 {len(config["items"])} 张现有影像
')
body.append(f'任务图集导航:{nav}
')
body.append(f'{config["intro"]}
')
for section, cards in sections.items():
body.extend((f'{section}
', '', *cards, '
'))
body.append(f'任务图集导航:{nav}
')
body.append(f'← 返回任务页
')
body.append('')
output_path = WIKI_ROOT / config["output"]
output_path.write_text("\n".join(body) + "\n", encoding="utf-8", newline="\n")
print(f"gallery_built mission={code} images={len(config['items'])} output={output_path}")
def main() -> int:
for code, config in GALLERIES.items():
build_gallery(code, config)
return 0
if __name__ == "__main__":
raise SystemExit(main())