Files
blivedm/live_status_ntf.py
2026-03-14 07:57:27 +08:00

223 lines
6.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import time
import requests
import schedule
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import json
import db
import re
path = "logs"
room_id_re = re.compile(rf"{path}/(\d+)\.jsonl$")
notify_qq_group = {
"12571885": lambda room, is_online: notify_group(room, ["831867573", "138981147"], is_online),
"147482": lambda room, is_online: notify_group(room, ["175545447"], is_online),
"20571": lambda room, is_online: notify_group(room, ["891117762"], is_online),
}
class Room:
def __init__(self, room_id: str) -> None:
self.room_id = room_id
self.db_room = db.get_room(room_id)
self.position = 0
self.state = 0
self.state_changed = False
def reset(self):
self.position = 0
self.state = 0
self.state_changed = False
def update_state(self, state):
self.state = state
self.state_changed = True
_rooms: dict[str, Room] = {}
def notify_group(room: Room, groups: list[str], is_online: bool):
status = "开锅了" if is_online else "下锅了"
msg = "\n".join([
f"{room.db_room.liver_name} {status}",
f"https://live.bilibili.com/{room.room_id}"
])
for qq_group_id in groups:
send_qq_group_msg(qq_group_id, msg)
def notify_group_and_mc(room: Room, groups: list[str], is_online: bool):
notify_group(room, groups, is_online)
try:
msg = "\n".join([
f"{room.db_room.liver_name} {'开锅了' if is_online else '下锅了'}",
f"https://live.bilibili.com/{room.room_id}"
])
requests.post("http://mc1:5000/msg", json={"msg": msg})
except BaseException as e:
print(f"notify mc error: {e}")
def get_room(src_path):
src_path_str = str(src_path)
room_id = room_id_re.findall(src_path_str)[0]
room = _rooms.get(room_id, None)
if room is None:
room = Room(room_id)
_rooms[room_id] = room
return room
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
if event.is_directory:
return
src_path_str = str(event.src_path)
if not room_id_re.search(src_path_str):
return
room: Room = get_room(src_path_str)
try:
with open(event.src_path, "r", encoding="utf-8") as f:
file_size = os.path.getsize(event.src_path)
if room.position > file_size:
room.reset()
f.seek(room.position)
for line in f:
try:
data = json.loads(line)
except json.decoder.JSONDecodeError:
continue
self._handle_data(room, data)
room.position = os.path.getsize(event.src_path)
except UnicodeDecodeError:
pass
self._check_room_state_change(room)
def on_created(self, event):
if event.is_directory:
return
src_path_str = str(event.src_path)
if not room_id_re.search(src_path_str):
return
room: Room = get_room(src_path_str)
try:
with open(event.src_path, "r", encoding="utf-8") as f:
for line in f:
try:
data = json.loads(line)
except json.decoder.JSONDecodeError:
continue
self._handle_data(room, data)
room.position = os.path.getsize(event.src_path)
except UnicodeDecodeError:
pass
self._check_room_state_change(room)
def on_deleted(self, event):
if event.is_directory:
return
src_path_str = str(event.src_path)
if not room_id_re.search(src_path_str):
return
room_id = room_id_re.findall(src_path_str)[0]
room = _rooms.get(room_id, Room(room_id))
room.reset()
def _handle_data(self, room: Room, data):
if data["cmd"] == "LIVE":
if room.state == 1:
return
room.update_state(1)
elif data["cmd"] == "PREPARING":
if room.state == 2:
return
room.update_state(2)
def _check_room_state_change(self, room: Room):
if not room.state_changed:
return
room.state_changed = False
if room.state == 1:
msg = "\n".join([
f"{room.db_room.liver_name} 开锅了!",
f"https://live.bilibili.com/{room.room_id}"
])
try:
requests.post("http://turntf:18846/notify", json={"msg": msg})
except BaseException as e:
print(f"notify turntf error: {e}")
notify_func = notify_qq_group.get(room.room_id)
if notify_func:
notify_func(room, True)
elif room.state == 2:
msg = "\n".join([
f"{room.db_room.liver_name} 下锅了!",
f"https://live.bilibili.com/{room.room_id}"
])
try:
requests.post("http://turntf:18846/notify", json={"msg": msg})
except BaseException as e:
print(f"notify turntf error: {e}")
notify_func = notify_qq_group.get(room.room_id)
if notify_func:
notify_func(room, False)
def send_qq_group_msg(group_id: str, msg: str):
try:
requests.post("http://napcat:3000/send_group_msg", json={
"group_id": group_id,
"message": msg
})
except BaseException as e:
print(f"send qq group msg error: {e}")
def main():
for f in os.listdir(path):
f = path+"/"+str(f)
if not room_id_re.search(f):
continue
get_room(f).position = os.path.getsize(f)
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
schedule.run_pending()
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
if __name__ == "__main__":
main()