monitor: scope per chat_id (перенесено из AGENTS.MD)
This commit is contained in:
parent
d5f84d6254
commit
76dcb8ed52
1 changed files with 45 additions and 30 deletions
75
deltabot.py
75
deltabot.py
|
|
@ -847,11 +847,23 @@ def dns_lookup(domain):
|
|||
# --- Site monitors ---
|
||||
|
||||
def load_monitors():
|
||||
return load_json(MONITORS_FILE, [])
|
||||
data = load_json(MONITORS_FILE, {})
|
||||
if isinstance(data, list):
|
||||
old = data
|
||||
data = {}
|
||||
for m in old:
|
||||
cid = m.pop("added_chat", None)
|
||||
if cid:
|
||||
data.setdefault(str(cid), []).append(m)
|
||||
save_monitors(data)
|
||||
return data
|
||||
|
||||
def save_monitors(data):
|
||||
save_json(MONITORS_FILE, data)
|
||||
|
||||
def get_chat_monitors(data, chat_id):
|
||||
return data.get(str(chat_id), [])
|
||||
|
||||
def check_url(url):
|
||||
try:
|
||||
r = requests.get(url, timeout=MONITOR_TIMEOUT, allow_redirects=True)
|
||||
|
|
@ -868,25 +880,24 @@ def monitor_worker(account):
|
|||
time.sleep(MONITOR_INTERVAL)
|
||||
monitors = load_monitors()
|
||||
changed = False
|
||||
for m in monitors:
|
||||
ok, detail = check_url(m["url"])
|
||||
was_ok = m.get("last_ok")
|
||||
m["last_check"] = time.time()
|
||||
if was_ok is not None and ok != was_ok:
|
||||
if ok:
|
||||
alert = f"Сайт восстановлен\n{m['url']}"
|
||||
else:
|
||||
alert = f"САЙТ НЕДОСТУПЕН\n{m['url']}\nСтатус: {detail}"
|
||||
chat_id = m.get("added_chat")
|
||||
if chat_id:
|
||||
for chat_id, chat_monitors in monitors.items():
|
||||
for m in chat_monitors:
|
||||
ok, detail = check_url(m["url"])
|
||||
was_ok = m.get("last_ok")
|
||||
m["last_check"] = time.time()
|
||||
if was_ok is not None and ok != was_ok:
|
||||
if ok:
|
||||
alert = f"Сайт восстановлен\n{m['url']}"
|
||||
else:
|
||||
alert = f"САЙТ НЕДОСТУПЕН\n{m['url']}\nСтатус: {detail}"
|
||||
try:
|
||||
account._rpc.send_msg(account.id, chat_id, {"text": alert})
|
||||
account._rpc.send_msg(account.id, int(chat_id), {"text": alert})
|
||||
except Exception as e:
|
||||
logger.error(f"Monitor alert error: {e}")
|
||||
logger.info(f"Monitor: {m['url']} {'UP' if ok else 'DOWN'} ({detail})")
|
||||
m["last_ok"] = ok
|
||||
m["last_detail"] = detail
|
||||
changed = True
|
||||
logger.info(f"Monitor: {m['url']} {'UP' if ok else 'DOWN'} ({detail})")
|
||||
m["last_ok"] = ok
|
||||
m["last_detail"] = detail
|
||||
changed = True
|
||||
if changed:
|
||||
save_monitors(monitors)
|
||||
|
||||
|
|
@ -1979,32 +1990,33 @@ def handle_message(event):
|
|||
parts = text.split(maxsplit=1)
|
||||
subcmd = parts[1].strip().lower() if len(parts) > 1 else ""
|
||||
monitors = load_monitors()
|
||||
chat_monitors = get_chat_monitors(monitors, chat_id)
|
||||
|
||||
if subcmd.startswith("add "):
|
||||
url = subcmd[4:].strip()
|
||||
if not url.startswith("http"):
|
||||
url = "https://" + url
|
||||
if any(m["url"] == url for m in monitors):
|
||||
if any(m["url"] == url for m in chat_monitors):
|
||||
message.chat.send_text(f"Уже в мониторинге: {url}")
|
||||
else:
|
||||
ok, detail = check_url(url)
|
||||
monitors.append({
|
||||
chat_monitors.append({
|
||||
"url": url,
|
||||
"added_chat": chat_id,
|
||||
"last_ok": ok,
|
||||
"last_check": time.time(),
|
||||
"last_detail": detail,
|
||||
})
|
||||
monitors[str(chat_id)] = chat_monitors
|
||||
save_monitors(monitors)
|
||||
status = "доступен" if ok else f"НЕДОСТУПЕН ({detail})"
|
||||
message.chat.send_text(f"Добавлен: {url}\nСтатус: {status}")
|
||||
|
||||
elif subcmd in ("list", "список", ""):
|
||||
if not monitors:
|
||||
if not chat_monitors:
|
||||
message.chat.send_text("Список пуст. /monitor add <url>")
|
||||
else:
|
||||
lines = [f"Мониторинг ({len(monitors)}):"]
|
||||
for i, m in enumerate(monitors, 1):
|
||||
lines = [f"Мониторинг ({len(chat_monitors)}):"]
|
||||
for i, m in enumerate(chat_monitors, 1):
|
||||
icon = "OK" if m.get("last_ok") else "DOWN"
|
||||
checked = datetime.fromtimestamp(m["last_check"], tz=IRKUTSK_TZ).strftime("%H:%M") if m.get("last_check") else "—"
|
||||
lines.append(f"{i}. [{icon}] {m['url']} (проверен {checked})")
|
||||
|
|
@ -2014,34 +2026,37 @@ def handle_message(event):
|
|||
arg = subcmd[7:].strip()
|
||||
if arg.isdigit():
|
||||
idx = int(arg) - 1
|
||||
if 0 <= idx < len(monitors):
|
||||
removed = monitors.pop(idx)
|
||||
if 0 <= idx < len(chat_monitors):
|
||||
removed = chat_monitors.pop(idx)
|
||||
monitors[str(chat_id)] = chat_monitors
|
||||
save_monitors(monitors)
|
||||
message.chat.send_text(f"Удалён: {removed['url']}")
|
||||
else:
|
||||
message.chat.send_text("Неверный номер. /monitor list — список.")
|
||||
else:
|
||||
url = arg if arg.startswith("http") else "https://" + arg
|
||||
before = len(monitors)
|
||||
monitors = [m for m in monitors if m["url"] != url]
|
||||
if len(monitors) < before:
|
||||
before = len(chat_monitors)
|
||||
chat_monitors = [m for m in chat_monitors if m["url"] != url]
|
||||
if len(chat_monitors) < before:
|
||||
monitors[str(chat_id)] = chat_monitors
|
||||
save_monitors(monitors)
|
||||
message.chat.send_text(f"Удалён: {url}")
|
||||
else:
|
||||
message.chat.send_text(f"Не найден: {url}")
|
||||
|
||||
elif subcmd == "check":
|
||||
if not monitors:
|
||||
if not chat_monitors:
|
||||
message.chat.send_text("Список пуст.")
|
||||
else:
|
||||
lines = ["Проверка:"]
|
||||
for m in monitors:
|
||||
for m in chat_monitors:
|
||||
ok, detail = check_url(m["url"])
|
||||
m["last_ok"] = ok
|
||||
m["last_check"] = time.time()
|
||||
m["last_detail"] = detail
|
||||
icon = "OK" if ok else f"DOWN: {detail}"
|
||||
lines.append(f"[{icon}] {m['url']}")
|
||||
monitors[str(chat_id)] = chat_monitors
|
||||
save_monitors(monitors)
|
||||
message.chat.send_text("\n".join(lines))
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue