初始化奇妙小屏幕控制器项目
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
DIRECTORY = Path(__file__).resolve().parent
|
||||
EXAMPLE_NAME = "用户名密码ip.example.txt"
|
||||
PRIVATE_NAME = "用户名密码ip.txt"
|
||||
REQUIRED_KEYS = (
|
||||
"设备",
|
||||
"主机名",
|
||||
"用户名",
|
||||
"密码",
|
||||
"IP",
|
||||
"SSH",
|
||||
"镜像默认用户名",
|
||||
"镜像默认账户密码",
|
||||
"镜像默认WiFi SSID",
|
||||
"镜像默认WiFi密码",
|
||||
)
|
||||
PLACEHOLDER_MARKERS = ("<", ">", "示例", "example", "请填写", "待填写")
|
||||
|
||||
|
||||
class CredentialPreparationError(RuntimeError):
|
||||
"""A safe, user-actionable credential preparation failure."""
|
||||
|
||||
|
||||
def _parse_fields(path: Path) -> dict[str, str]:
|
||||
fields: dict[str, str] = {}
|
||||
for raw_line in path.read_text(encoding="utf-8").splitlines():
|
||||
line = raw_line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
separator = ":" if ":" in line else ":" if ":" in line else None
|
||||
if separator is None:
|
||||
raise CredentialPreparationError("凭据文件含有无法识别的非注释行。")
|
||||
key, value = (part.strip() for part in line.split(separator, 1))
|
||||
if not key or key in fields:
|
||||
raise CredentialPreparationError("凭据文件含有空字段名或重复字段。")
|
||||
fields[key] = value
|
||||
return fields
|
||||
|
||||
|
||||
def ensure_credentials(directory: Path = DIRECTORY) -> bool:
|
||||
example_path = directory / EXAMPLE_NAME
|
||||
private_path = directory / PRIVATE_NAME
|
||||
if not example_path.is_file():
|
||||
raise CredentialPreparationError(f"缺少示例文件:{EXAMPLE_NAME}")
|
||||
|
||||
if not private_path.exists():
|
||||
payload = example_path.read_bytes()
|
||||
try:
|
||||
with private_path.open("xb") as stream:
|
||||
stream.write(payload)
|
||||
except FileExistsError:
|
||||
pass
|
||||
print(f"已创建私有凭据副本:测试相关资料/核桃派的用户名和密码和ip/{PRIVATE_NAME}")
|
||||
print("请填写全部字段后重新运行本检查;在此之前不要继续 SSH、部署或镜像定制。")
|
||||
return False
|
||||
if not private_path.is_file():
|
||||
raise CredentialPreparationError(f"私有凭据路径不是普通文件:{PRIVATE_NAME}")
|
||||
|
||||
fields = _parse_fields(private_path)
|
||||
missing = [key for key in REQUIRED_KEYS if key not in fields]
|
||||
if missing:
|
||||
raise CredentialPreparationError("凭据文件缺少字段:" + "、".join(missing))
|
||||
unfinished = [
|
||||
key
|
||||
for key in REQUIRED_KEYS
|
||||
if not fields[key]
|
||||
or any(marker.casefold() in fields[key].casefold() for marker in PLACEHOLDER_MARKERS)
|
||||
]
|
||||
if unfinished:
|
||||
raise CredentialPreparationError("凭据文件仍有未填写字段:" + "、".join(unfinished))
|
||||
|
||||
print("私有凭据文件可用;未输出任何凭据值。")
|
||||
return True
|
||||
|
||||
|
||||
def main() -> int:
|
||||
try:
|
||||
return 0 if ensure_credentials() else 2
|
||||
except (CredentialPreparationError, OSError, UnicodeError) as error:
|
||||
print(f"凭据检查未通过:{error}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user