blivechat/main.py

169 lines
4.0 KiB
Python
Raw Normal View History

2019-05-21 19:15:12 +08:00
# -*- coding: utf-8 -*-
2019-05-26 17:14:59 +08:00
import argparse
2023-09-06 21:34:04 +08:00
import asyncio
2019-05-22 14:10:27 +08:00
import logging
2020-09-03 20:01:54 +08:00
import logging.handlers
2019-05-21 19:15:12 +08:00
import os
2023-09-06 21:34:04 +08:00
import signal
2023-09-10 09:48:12 +08:00
import sys
2019-09-16 20:48:03 +08:00
import webbrowser
2023-09-06 21:34:04 +08:00
from typing import *
2019-05-21 19:15:12 +08:00
import tornado.ioloop
import tornado.web
2020-02-03 16:18:21 +08:00
import api.chat
import api.main
2023-09-08 20:53:04 +08:00
import api.open_live
2020-02-03 16:18:21 +08:00
import config
import models.database
2022-02-15 00:18:46 +08:00
import services.avatar
import services.chat
import services.translate
2019-09-16 20:48:03 +08:00
import update
2023-07-29 01:22:21 +08:00
import utils.request
2019-05-22 01:11:23 +08:00
2019-05-22 14:10:27 +08:00
logger = logging.getLogger(__name__)
2023-09-06 21:34:04 +08:00
ROUTES = [
2023-09-08 20:53:04 +08:00
*api.main.ROUTES,
*api.chat.ROUTES,
*api.open_live.ROUTES,
*api.main.LAST_ROUTES,
2020-02-03 16:18:21 +08:00
]
2023-09-06 21:34:04 +08:00
server: Optional[tornado.httpserver.HTTPServer] = None
shut_down_event: Optional[asyncio.Event] = None
async def main():
if not init():
return 1
try:
await run()
finally:
await shut_down()
return 0
def init():
init_signal_handlers()
2019-05-21 19:15:12 +08:00
2020-02-03 16:18:21 +08:00
args = parse_args()
init_logging(args.debug)
2023-09-06 21:34:04 +08:00
logger.info('App started, initializing')
2020-02-03 16:18:21 +08:00
config.init()
2023-07-29 01:22:21 +08:00
2023-07-29 12:48:57 +08:00
utils.request.init()
2020-02-03 16:18:21 +08:00
models.database.init(args.debug)
2023-07-29 01:22:21 +08:00
2022-02-15 00:18:46 +08:00
services.avatar.init()
services.translate.init()
services.chat.init()
2023-07-29 01:22:21 +08:00
2020-02-03 16:18:21 +08:00
update.check_update()
2023-09-06 21:34:04 +08:00
init_server(args.host, args.port, args.debug)
return server is not None
def init_signal_handlers():
global shut_down_event
shut_down_event = asyncio.Event()
signums = (signal.SIGINT, signal.SIGTERM)
try:
loop = asyncio.get_running_loop()
for signum in signums:
loop.add_signal_handler(signum, on_shut_down_signal)
except NotImplementedError:
# 不太安全但Windows只能用这个
for signum in signums:
signal.signal(signum, on_shut_down_signal)
def on_shut_down_signal(*_args):
shut_down_event.set()
2020-02-03 16:18:21 +08:00
def parse_args():
2020-09-03 20:01:54 +08:00
parser = argparse.ArgumentParser(description='用于OBS的仿YouTube风格的bilibili直播评论栏')
2023-08-26 17:01:19 +08:00
parser.add_argument('--host', help='服务器host默认和配置中的一样', default=None)
parser.add_argument('--port', help='服务器端口,默认和配置中的一样', type=int, default=None)
2019-05-26 17:14:59 +08:00
parser.add_argument('--debug', help='调试模式', action='store_true')
2020-02-03 16:18:21 +08:00
return parser.parse_args()
2019-05-26 17:14:59 +08:00
2020-02-03 16:18:21 +08:00
def init_logging(debug):
filename = os.path.join(config.BASE_PATH, 'log', 'blivechat.log')
2020-09-03 20:01:54 +08:00
stream_handler = logging.StreamHandler()
file_handler = logging.handlers.TimedRotatingFileHandler(
filename, encoding='utf-8', when='midnight', backupCount=7, delay=True
2020-09-03 20:01:54 +08:00
)
2019-05-22 14:10:27 +08:00
logging.basicConfig(
format='{asctime} {levelname} [{name}]: {message}',
style='{',
2020-09-03 20:01:54 +08:00
level=logging.INFO if not debug else logging.DEBUG,
handlers=[stream_handler, file_handler]
2019-05-22 14:10:27 +08:00
)
# 屏蔽访问日志
logging.getLogger('tornado.access').setLevel(logging.WARNING)
2019-09-16 20:48:03 +08:00
2023-09-06 21:34:04 +08:00
def init_server(host, port, debug):
2023-08-26 17:01:19 +08:00
cfg = config.get_config()
if host is None:
host = cfg.host
if port is None:
port = cfg.port
2019-05-26 17:14:59 +08:00
app = tornado.web.Application(
2023-09-06 21:34:04 +08:00
ROUTES,
2020-02-03 16:18:21 +08:00
websocket_ping_interval=10,
debug=debug,
2019-05-26 17:14:59 +08:00
autoreload=False
)
2019-09-16 20:48:03 +08:00
try:
2023-09-06 21:34:04 +08:00
global server
server = app.listen(
2020-08-22 18:38:52 +08:00
port,
host,
2022-02-27 22:05:37 +08:00
xheaders=cfg.tornado_xheaders,
max_body_size=1024 * 1024,
max_buffer_size=1024 * 1024
2020-08-22 18:38:52 +08:00
)
2019-09-16 20:48:03 +08:00
except OSError:
2020-02-03 16:18:21 +08:00
logger.warning('Address is used %s:%d', host, port)
2019-09-16 20:48:03 +08:00
return
finally:
if cfg.open_browser_at_startup:
url = 'http://localhost/' if port == 80 else f'http://localhost:{port}/'
webbrowser.open(url)
2020-02-03 16:18:21 +08:00
logger.info('Server started: %s:%d', host, port)
2023-09-06 21:34:04 +08:00
async def run():
logger.info('Running event loop')
await shut_down_event.wait()
logger.info('Received shutdown signal')
async def shut_down():
logger.info('Closing server')
server.stop()
await server.close_all_connections()
logger.info('Closing websocket connections')
await services.chat.shut_down()
await utils.request.shut_down()
logger.info('App shut down')
2019-05-21 19:15:12 +08:00
if __name__ == '__main__':
2023-09-10 09:48:12 +08:00
sys.exit(asyncio.run(main()))