同步操作将从 fufuok/FF.PyAdmin 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
"""__init__.py~~~~~~~~初始化 app注册蓝图到 app日志及环境配置:author: Fufu, 2019年9月2日"""import loggingimport osfrom collections import namedtuplefrom datetime import datetime, datefrom decimal import Decimalfrom concurrent_log_handler import ConcurrentRotatingFileHandlerfrom flask import Flask as _Flask, render_templatefrom flask.json import JSONEncoder as _JSONEncoder, jsonifyfrom werkzeug.middleware.proxy_fix import ProxyFixfrom .forms import csrffrom .libs.exceptions import APIException, APIServerError, APIFailurefrom .libs.helper import is_accept_json, get_intfrom .models import db, DBModelfrom .models.dbcache import init_db_cachefrom .services.auth import oauth, login_managerfrom .services.mail import mailfrom .services.observers import observerfrom .views import init_blueprint, init_template_globalclass JSONEncoder(_JSONEncoder):"""重写 Flask JSON encoder"""def default(self, o):"""支持 DBModel 和日期时间. (注: ``UUID``, ``dataclasses`` 等未继承)e.g.::# {job_number: 114, mobile: "13880000009", last_login: "2019-09-10 09:04:59", status: 1}return jsonify(TBUser.query.get(114).hide_keys('realname', 'role_id')):param o::return:"""if isinstance(o, datetime):return o.strftime('%Y-%m-%d %H:%M:%S')if isinstance(o, date):return o.strftime('%Y-%m-%d')if isinstance(o, Decimal):return float(o)if hasattr(o, 'keys') and hasattr(o, '__getitem__'):return dict(o)raise APIServerError()class Flask(_Flask):json_encoder = JSONEncoderdef make_response(self, rv):"""支持视图函数直接返回 DBModel, list, dict(1.1.0+官方支持)e.g.::# {job_number: 114, mobile: "13880000009", last_login: "2019-09-10 09:04:59", status: 1}return TBUser.query.get(114).hide_keys('realname', 'role'):param rv::return:"""if isinstance(rv, set):rv = list(rv)if isinstance(rv, (list, dict, DBModel)):rv = jsonify(rv)return super(Flask, self).make_response(rv=rv)def init_config(app, config_name=None, config=None):"""加载各类环境配置:param app: Flask:param config_name: str, 指定配置文件名或环境变量配置名 e.g. development / testing / production:param config: str / dict 最高优先级配置, 字典或文件名:return: None"""# 加载生产环境配置app.config.from_object('app.conf.secret_settings')app.config.from_object('app.conf.settings')# 加载指定名称的文件配置if not config_name:config_name = os.getenv(app.config.get('APP_NAME', 'FLASK_CONFIG'))if config_name:try:app.config.from_object('app.conf.{}_settings'.format(config_name))except ImportError:pass# 加载指定的参数配置if config is not None:if isinstance(config, dict):app.config.update(config)elif config.endswith('.py'):app.config.from_pyfile(config, silent=True)def init_logger(app):"""初始化日志(按大小滚动):param app: Flask:return: None"""log_maxsize = app.config.get('LOG_MAXSIZE', 100)log_backup = app.config.get('LOG_BACKUP', 20)log_level = app.config.get('LOG_LEVEL', logging.INFO)app_log = app.config.get('LOG_FILE')if not app_log:app_log = os.path.join(os.path.dirname(app.root_path), 'logs', 'app.log')fh = ConcurrentRotatingFileHandler(app_log, maxBytes=log_maxsize * 1024 * 1024, backupCount=log_backup,encoding='utf-8', use_gzip=True)fh.setLevel(log_level)fh.setFormatter(logging.Formatter(app.config.get('LOG_FORMAT', '%(asctime)s %(levelname)s %(module)s.%(funcName)s: %(message)s')))app.logger.addHandler(fh)app.logger.setLevel(logging.DEBUG if app.debug else log_level)def init_error(app):"""全局异常处理:param app: Flask:return: None"""@app.errorhandler(Exception)def global_exception_handler(e):# 500 错误时记录日志code = getattr(e, 'code', 500)code in app.config.get('EXCEPTION_LOG_CODE', [500]) and app.logger.error(e, exc_info=True)if isinstance(e, APIException):return eif app.debug:raise e# 自定义异常描述err = namedtuple('MyError', ['code', 'description'])(code, app.config.get('EXCEPTION_DESC', {}).get(code, getattr(e, 'description', str(e))))if app.config.get('API') or is_accept_json():return APIFailure(description=err.description)return render_template('base-msg.html', e=err), codedef create_app(config_name=None, config=None):"""初始化 Flask 应用:param config_name: str:param config: str / dict 扩展配置或配置文件:return: Flask"""app = Flask(__name__)# 加载环境配置init_config(app, config_name=config_name, config=config)x_for = get_int(app.config.get('PROXY_FIX_X_FOR'))if x_for:app.wsgi_app = ProxyFix(app.wsgi_app, x_for=x_for, x_host=x_for)# 日志配置init_logger(app)# 自定义错误页init_error(app)# 注册蓝图init_blueprint(app)# 注册 OAuth2oauth.init_app(app)# 注册 flask_loginlogin_manager.init_app(app)# 注册邮件mail.init_app(app)# 注册自定义信号observer.init_app(app)# CSRF 保护csrf.init_app(app)# 注册模板全局函数init_template_global(app)# 初始化数据库配置db.init_app(app)with app.app_context():db.create_all()init_db_cache(app)@app.after_requestdef after_request(resp):if app.debug and app.config.get('DEBUG_RESPONSE') and is_accept_json():app.logger.debug("Response: {}, {}, {}".format(resp.status, resp.mimetype, resp.get_data(as_text=True)))return respreturn app
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。