diff --git a/main.py b/main.py deleted file mode 100644 index 6a1676b..0000000 --- a/main.py +++ /dev/null @@ -1,246 +0,0 @@ -# encoding: utf-8 - -import json -import os -from importlib import import_module - -from core.config_manager import Config, ConfigManager - -if os.path.exists('config.py') or os.path.exists('config'): - # 导入用户自定义配置 - ConfigManager.load(import_module("config").Config) -else: - # Allow importing the config from a custom path given through an environment variable - configPath = os.environ.get("ARCAEA_JSON_CONFIG_PATH") - if configPath and os.path.exists(configPath): - with open(configPath, 'r') as file: - ConfigManager.load_dict(json.load(file)) - - -if Config.DEPLOY_MODE == 'gevent': - # 异步 - from gevent import monkey - monkey.patch_all() - - -import sys -from logging.config import dictConfig -from multiprocessing import Process, current_process, set_start_method -from traceback import format_exc - -from flask import Flask, make_response, request, send_from_directory - -import api -import server -import web.index -import web.login -# import webapi -from core.bundle import BundleDownload -from core.constant import Constant -from core.download import UserDownload -from core.error import ArcError, NoAccess, RateLimit -from core.init import FileChecker -from core.sql import Connect -from server.func import error_return - -app = Flask(__name__) - -if Config.USE_PROXY_FIX: - # 代理修复 - from werkzeug.middleware.proxy_fix import ProxyFix - app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1) -if Config.USE_CORS: - # 服务端跨域 - from flask_cors import CORS - CORS(app, supports_credentials=True) - - -os.chdir(sys.path[0]) # 更改工作路径,以便于愉快使用相对路径 - - -app.config.from_mapping(SECRET_KEY=Config.SECRET_KEY) -app.config['SESSION_TYPE'] = 'filesystem' -app.register_blueprint(web.login.bp) -app.register_blueprint(web.index.bp) -app.register_blueprint(api.bp) -list(map(app.register_blueprint, server.get_bps())) -# app.register_blueprint(webapi.bp) - - -@app.route('/') -def hello(): - return "Hello World!" - - -@app.route('/favicon.ico', methods=['GET']) # 图标 -def favicon(): - # Pixiv ID: 82374369 - # 我觉得这张图虽然并不是那么精细,但很有感觉,色彩的强烈对比下给人带来一种惊艳 - # 然后在压缩之下什么也看不清了:( - - return app.send_static_file('favicon.ico') - - -@app.route('/download/', methods=['GET']) # 下载 -def download(file_path): - with Connect(in_memory=True) as c: - try: - x = UserDownload(c) - x.token = request.args.get('t') - x.song_id, x.file_name = file_path.split('/', 1) - x.select_for_check() - if x.is_limited: - raise RateLimit( - f'User `{x.user.user_id}` has reached the download limit.', 903) - if not x.is_valid: - raise NoAccess('Expired token.') - x.download_hit() - if Config.DOWNLOAD_USE_NGINX_X_ACCEL_REDIRECT: - # nginx X-Accel-Redirect - response = make_response() - response.headers['Content-Type'] = 'application/octet-stream' - response.headers['X-Accel-Redirect'] = Config.NGINX_X_ACCEL_REDIRECT_PREFIX + file_path - return response - return send_from_directory(Constant.SONG_FILE_FOLDER_PATH, file_path, as_attachment=True, conditional=True) - except ArcError as e: - if Config.ALLOW_WARNING_LOG: - app.logger.warning(format_exc()) - return error_return(e) - return error_return() - - -@app.route('/bundle_download/', methods=['GET']) # 热更新下载 -def bundle_download(token: str): - with Connect(in_memory=True) as c_m: - try: - file_path = BundleDownload(c_m).get_path_by_token( - token, request.remote_addr) - if Config.DOWNLOAD_USE_NGINX_X_ACCEL_REDIRECT: - # nginx X-Accel-Redirect - response = make_response() - response.headers['Content-Type'] = 'application/octet-stream' - response.headers['X-Accel-Redirect'] = Config.BUNDLE_NGINX_X_ACCEL_REDIRECT_PREFIX + file_path - return response - return send_from_directory(Constant.CONTENT_BUNDLE_FOLDER_PATH, file_path, as_attachment=True, conditional=True) - except ArcError as e: - if Config.ALLOW_WARNING_LOG: - app.logger.warning(format_exc()) - return error_return(e) - return error_return() - - -if Config.DEPLOY_MODE == 'waitress': - # 给waitress加个日志 - @app.after_request - def after_request(response): - app.logger.info( - f'{request.remote_addr} - - {request.method} {request.path} {response.status_code}') - return response - -# @app.before_request -# def before_request(): -# print(request.path) -# print(request.headers) -# print(request.data) - - -def tcp_server_run(): - if Config.DEPLOY_MODE == 'gevent': - # 异步 gevent WSGI server - host_port = (Config.HOST, Config.PORT) - app.logger.info('Running gevent WSGI server... (%s:%s)' % host_port) - from gevent.pywsgi import WSGIServer - WSGIServer(host_port, app, log=app.logger).serve_forever() - elif Config.DEPLOY_MODE == 'waitress': - # waitress WSGI server - import logging - from waitress import serve # type: ignore - logger = logging.getLogger('waitress') - logger.setLevel(logging.INFO) - serve(app, host=Config.HOST, port=Config.PORT) - else: - if Config.SSL_CERT and Config.SSL_KEY: - app.run(Config.HOST, Config.PORT, ssl_context=( - Config.SSL_CERT, Config.SSL_KEY)) - else: - app.run(Config.HOST, Config.PORT) - - -def generate_log_file_dict(level: str, filename: str) -> dict: - return { - "class": "logging.handlers.RotatingFileHandler", - "maxBytes": 1024 * 1024, - "backupCount": 1, - "encoding": "utf-8", - "level": level, - "formatter": "default", - "filename": filename - } - - -def pre_main(): - log_dict = { - 'version': 1, - 'root': { - 'level': 'INFO', - 'handlers': ['wsgi', 'error_file'] - }, - 'handlers': { - 'wsgi': { - 'class': 'logging.StreamHandler', - 'stream': 'ext://flask.logging.wsgi_errors_stream', - 'formatter': 'default' - }, - "error_file": generate_log_file_dict('ERROR', f'{Config.LOG_FOLDER_PATH}/error.log') - }, - 'formatters': { - 'default': { - 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s' - } - } - } - if Config.ALLOW_INFO_LOG: - log_dict['root']['handlers'].append('info_file') - log_dict['handlers']['info_file'] = generate_log_file_dict( - 'INFO', f'{Config.LOG_FOLDER_PATH}/info.log') - if Config.ALLOW_WARNING_LOG: - log_dict['root']['handlers'].append('warning_file') - log_dict['handlers']['warning_file'] = generate_log_file_dict( - 'WARNING', f'{Config.LOG_FOLDER_PATH}/warning.log') - - dictConfig(log_dict) - - Connect.logger = app.logger - if not FileChecker(app.logger).check_before_run(): - app.logger.error('Some errors occurred. The server will not run.') - input('Press ENTER key to exit.') - sys.exit() - - -def main(): - if Config.LINKPLAY_HOST and Config.SET_LINKPLAY_SERVER_AS_SUB_PROCESS: - from linkplay_server import link_play - process = [Process(target=link_play, args=( - Config.LINKPLAY_HOST, int(Config.LINKPLAY_UDP_PORT), int(Config.LINKPLAY_TCP_PORT)))] - [p.start() for p in process] - app.logger.info( - f"Link Play UDP server is running on {Config.LINKPLAY_HOST}:{Config.LINKPLAY_UDP_PORT} ...") - app.logger.info( - f"Link Play TCP server is running on {Config.LINKPLAY_HOST}:{Config.LINKPLAY_TCP_PORT} ...") - tcp_server_run() - [p.join() for p in process] - else: - tcp_server_run() - - -# must run for init -# this ensures avoiding duplicate init logs for some reason -if current_process().name == 'MainProcess': - pre_main() - -if __name__ == '__main__': - set_start_method("spawn") - main() - - -# Made By Lost 2020.9.11