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()