223 lines
6.1 KiB
Python
223 lines
6.1 KiB
Python
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()
|