Compare commits
2
Commits
caa646e89c
...
65bab7e25c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65bab7e25c | ||
|
|
4c0572f73c |
@@ -114,17 +114,39 @@ def save_settings(enabled=None, subnets=None, interval=None, port=None):
|
||||
|
||||
|
||||
# ================== 网段展开与端口探测 ==================
|
||||
def _local_ips():
|
||||
"""本机自身 IP 集合(尽力而为):扫描时排除,避免探测到自己的 5555。
|
||||
|
||||
优先 `hostname -I`(Linux/macOS 支持,一行空格分隔多 IP);不支持/失败的
|
||||
平台退回 socket.getaddrinfo 枚举。关键:外部命令必须用 bytes 收——Windows
|
||||
上 git-bash 的 coreutils hostname 不支持 -I,会把 GBK 报错写进 stderr,
|
||||
text=True 在 subprocess 后台读线程里 utf-8 严格解码会直接炸线程(主线程
|
||||
try/except 接不住异步线程异常)。
|
||||
"""
|
||||
import subprocess
|
||||
ips = set()
|
||||
try:
|
||||
r = subprocess.run(["hostname", "-I"], capture_output=True, timeout=3)
|
||||
if r.returncode == 0:
|
||||
ips.update(p for p in
|
||||
r.stdout.decode("utf-8", errors="ignore").split() if p)
|
||||
except Exception:
|
||||
pass
|
||||
if not ips: # 兜底:主机名解析出的接口 IPv4
|
||||
try:
|
||||
for info in socket.getaddrinfo(socket.gethostname(), None):
|
||||
ip = info[4][0]
|
||||
if ":" not in ip:
|
||||
ips.add(ip)
|
||||
except Exception:
|
||||
pass
|
||||
return ips
|
||||
|
||||
|
||||
def _expand_subnets(subnets, max_hosts=_MAX_HOSTS_PER_SUBNET):
|
||||
"""CIDR 列表 → IP 列表。排除 220 自身(USB_ADB_HOST)与本机 IP;
|
||||
非法网段跳过记日志;单网段超过 max_hosts 截断并告警。"""
|
||||
self_ips = {USB_ADB_HOST}
|
||||
try: # 本机自身 IP(接口枚举,尽力而为;无 hostname -I 的平台跳过)
|
||||
import subprocess
|
||||
out = subprocess.run(["hostname", "-I"], capture_output=True, text=True,
|
||||
timeout=3).stdout or ""
|
||||
self_ips.update(p for p in out.split() if p)
|
||||
except Exception:
|
||||
pass
|
||||
self_ips = {USB_ADB_HOST} | _local_ips()
|
||||
ips = []
|
||||
for cidr in subnets:
|
||||
try:
|
||||
|
||||
+12
-1
@@ -305,7 +305,18 @@ def _migrate_schema():
|
||||
if version <= current:
|
||||
continue
|
||||
if sql:
|
||||
db.session.execute(text(sql))
|
||||
try:
|
||||
db.session.execute(text(sql))
|
||||
except Exception as e:
|
||||
# 幂等兜底:目标结构已存在也视为该迁移生效。典型场景——
|
||||
# create_all 已按当前模型把列/表直接建好(如 perms、device.model),
|
||||
# 而 schema_version 又因历史中断没记录,导致每次启动重复 ALTER 报错。
|
||||
# duplicate column name 说明列已存在=迁移目标已达成:回滚本次语句后
|
||||
# 仍记录版本号,一次启动即自愈;其它异常才中止本批迁移。
|
||||
if "duplicate column name" not in str(e).lower():
|
||||
raise
|
||||
db.session.rollback()
|
||||
_log.info(f"schema 迁移 {version} 目标已存在,跳过: {desc}")
|
||||
db.session.execute(
|
||||
text("INSERT OR REPLACE INTO app_meta(key,value) VALUES('schema_version',:v)"),
|
||||
{"v": str(version)})
|
||||
|
||||
Reference in New Issue
Block a user