58 lines
1.9 KiB
Python
58 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
||||
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
"""项目管理界面的**启动器**(计划任务动作指向它,⛔ 不许直起 `project-board.py`)。
|
|||
|
|
|
|||
|
|
## 为什么必须有这一层(同族 P0-73/74)
|
|||
|
|
|
|||
|
|
· 计划任务的**动作没有 env 字段** ⇒ 变量只能在**进程内**设;
|
|||
|
|
· 直接用 `python.exe` 起 ⇒ 控制台程序 ⇒ 计划任务**每次触发闪一个黑窗口**;
|
|||
|
|
· 直起业务脚本 ⇒ 将来加变量/判活时**没有落点**,只能再开第二条旁路(闪黑窗的真因)。
|
|||
|
|
|
|||
|
|
## 本启动器做什么
|
|||
|
|
|
|||
|
|
① 设好编码与上游地址(⛔ 不依赖宿主 env);
|
|||
|
|
② 调 `project-board.py --serve 20100`;
|
|||
|
|
③ **判活**:端口已在听 ⇒ 直接退出 0(⛔ 不重复起第二实例)。
|
|||
|
|
|
|||
|
|
⚠️ 必须用 `pythonw.exe` 跑本文件(无控制台 ⇒ 不闪窗)。
|
|||
|
|
"""
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
import socket
|
|||
|
|
import sys
|
|||
|
|
import runpy
|
|||
|
|
|
|||
|
|
PORT = int(os.environ.get("DSH_PROJECT_BOARD_PORT") or "20100")
|
|||
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|||
|
|
TARGET = os.path.join(HERE, "project-board.py")
|
|||
|
|
|
|||
|
|
# ── 变量只在这里设(计划任务动作没有 env 字段)──
|
|||
|
|
os.environ.setdefault("PYTHONIOENCODING", "utf-8")
|
|||
|
|
os.environ.setdefault("DSH_PROJECT_BOARD_UPSTREAM", "http://127.0.0.1:20099/board.json")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def port_listening(port: int) -> bool:
|
|||
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|||
|
|
s.settimeout(0.4)
|
|||
|
|
try:
|
|||
|
|
return s.connect_ex(("127.0.0.1", port)) == 0
|
|||
|
|
finally:
|
|||
|
|
s.close()
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main() -> int:
|
|||
|
|
if port_listening(PORT):
|
|||
|
|
return 0 # 已在跑 ⇒ 静默退出(⛔ 不起第二实例)
|
|||
|
|
sys.argv = [TARGET, "--serve", str(PORT)]
|
|||
|
|
try:
|
|||
|
|
runpy.run_path(TARGET, run_name="__main__")
|
|||
|
|
except SystemExit:
|
|||
|
|
raise
|
|||
|
|
except Exception:
|
|||
|
|
return 1
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
sys.exit(main())
|