AzurLaneAutoScript/gui.py
2022-01-16 00:25:25 +08:00

135 lines
4.6 KiB
Python

import argparse
import os
import socket
import sys
from typing import List, Union
import click
import uvicorn
import uvicorn.config
from module.logger import logger
from module.webui.config import WebuiConfig
reuseaddr = True
def bind(self) -> socket.socket:
logger = uvicorn.config.logger
logger_args: List[Union[str, int]]
if self.uds: # pragma: py-win32
path = self.uds
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
sock.bind(path)
uds_perms = 0o666
os.chmod(self.uds, uds_perms)
except OSError as exc:
logger.error(exc)
sys.exit(1)
message = "Uvicorn running on unix socket %s (Press CTRL+C to quit)"
sock_name_format = "%s"
color_message = (
"Uvicorn running on "
+ click.style(sock_name_format, bold=True)
+ " (Press CTRL+C to quit)"
)
logger_args = [self.uds]
elif self.fd: # pragma: py-win32
sock = socket.fromfd(self.fd, socket.AF_UNIX, socket.SOCK_STREAM)
message = "Uvicorn running on socket %s (Press CTRL+C to quit)"
fd_name_format = "%s"
color_message = (
"Uvicorn running on "
+ click.style(fd_name_format, bold=True)
+ " (Press CTRL+C to quit)"
)
logger_args = [sock.getsockname()]
else:
family = socket.AF_INET
addr_format = "%s://%s:%d"
if self.host and ":" in self.host: # pragma: py-win32
# It's an IPv6 address.
family = socket.AF_INET6
addr_format = "%s://[%s]:%d"
sock = socket.socket(family=family)
if reuseaddr:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.bind((self.host, self.port))
except OSError as exc:
logger.error(exc)
logger.error(f"Already bind on address ({self.host}, {self.port})")
sys.exit(1)
message = f"Uvicorn running on {addr_format} (Press CTRL+C to quit)"
color_message = (
"Uvicorn running on "
+ click.style(addr_format, bold=True)
+ " (Press CTRL+C to quit)"
)
protocol_name = "https" if self.is_ssl else "http"
logger_args = [protocol_name, self.host, self.port]
logger.info(message, *logger_args, extra={"color_message": color_message})
sock.set_inheritable(True)
return sock
# monkey patch Config.bing_socket
uvicorn.Config.bind_socket = bind
def run_with_reload(host, port):
"""
Same as command below, but without reuse address patch.
uvicorn module.webui.app:app --factory --host 127.0.0.1 --port 22267 --reload --reload-include="reloadflag" --reload-exclude="*.py" --reload-dir="./config/"
"""
uvicorn.run('module.webui.app:app', host=host, port=port, factory=True, reload_dirs=[os.path.join(os.getcwd(), './config/')],
reload=True, reload_includes=['reloadflag'], reload_excludes=['*.py'], reload_delay=1)
def run_without_reload(host, port):
from module.webui.app import app
uvicorn.run(app, host=host, port=port, factory=True)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Alas web service')
parser.add_argument('--host', type=str,
help='Host to listen. Default to WebuiHost in deploy setting')
parser.add_argument('-p', '--port', type=int,
help='Port to listen. Default to WebuiPort in deploy setting')
parser.add_argument('-d', '--disable-address-reuse', action="store_true",
help='Disable SO_REUSEADDR.')
parser.add_argument('--electron', action="store_true",
help='Runs by electron client.')
parser.add_argument('--reload', action="store_true",
help='Able to use auto update and builtin updater')
args, _ = parser.parse_known_args()
webui_config = WebuiConfig()
host = args.host or webui_config.WebuiHost or '0.0.0.0'
port = args.port or int(webui_config.WebuiPort) or 22267
reload = args.reload or webui_config.bool('EnableReload')
if args.disable_address_reuse or args.electron:
reuseaddr = False
logger.hr('Launcher config')
logger.attr('Host', host)
logger.attr('Port', port)
logger.attr('Address reuse', reuseaddr)
logger.attr('Electron', args.electron)
logger.attr('Reload', reload)
try:
os.remove('./config/reloadflag')
except:
pass
if reload:
run_with_reload(host=host, port=port)
else:
run_without_reload(host=host, port=port)