refactor: P2 core+common 建设(应用工厂/扩展/工具层迁入 src/)

【结构】
- src/core/:database/response/jwt/password/security/redis_client/mail/scheduler
- src/common/:base_model/base_db/forms(base_form+fields)/constants/utils
- src/models_registry.py:模型聚合器(Flask-Migrate 全量表识别)

【绞杀者 shim】extensions/、utils/、application/constants|forms|models 打兼容转发
【兼容修复】应用工厂抽取至 application/factory.py(P2 前置,P1 已完成)

【基线修复】application/models(25) + middleware(7) 原被嵌套 .gitignore(*)
误排除出版本库,已补入(base_model/base_db 现为 shim,原版在 src/common/)

【登记既有缺陷】
1. flask db CLI 因 .env FLASK_VERSION 与 --version 冲突报错 → Makefile 已加 FLASK_SKIP_DOTENV=1
2. 本机 Redis 未设密码但 REDIS_AUTH=True,/captcha 报 AUTH 错误(环境问题)

【验收】22 模型表全量识别;src/ flake8 零告警;pytest 5 passed;应用启动;
/login 表单校验、/user/page 鉴权拦截冒烟正常

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DjangoAdmin Dev
2026-08-07 13:20:46 +08:00
co-authored by Claude
parent 92130ef070
commit 658ee6d596
96 changed files with 9926 additions and 4153 deletions
+4 -71
View File
@@ -1,75 +1,8 @@
"""
User-Agent解析工具模块
兼容 shim(绞杀者迁移期间保留)
=============================================================
提供HTTP请求User-Agent的解析功能:
- parse_user_agent: 解析操作系统和浏览器信息
UA 解析工具已迁移至 src.common.utils.user_agent。
本文件仅作兼容转发,最终在 P7(切尾)阶段删除。
"""
import re
def parse_user_agent():
"""
解析User-Agent,获取操作系统和浏览器信息
通过正则匹配User-Agent字符串,识别客户端操作系统和浏览器类型。
支持 Windows、macOS、Linux、Android、iOS 及主流浏览器识别。
Returns:
dict: 包含os和browser的字典
{
'os': 'Windows 10', # 操作系统信息
'browser': 'Chrome' # 浏览器名称
}
无法识别时返回 '未知'
"""
from flask import request
user_agent = request.headers.get('User-Agent', '')
result = {
'os': '未知',
'browser': '未知'
}
if not user_agent:
return result
ua_lower = user_agent.lower()
# 操作系统识别规则(按优先级从高到低排列)
os_patterns = [
(r'windows nt 10\.0', 'Windows 10'),
(r'windows nt 6\.1', 'Windows 7'),
(r'windows nt 6\.2', 'Windows 8'),
(r'windows nt 6\.3', 'Windows 8.1'),
(r'windows nt', 'Windows'),
(r'mac os x', 'macOS'),
(r'linux', 'Linux'),
(r'android', 'Android'),
(r'iphone', 'iOS'),
(r'ipad', 'iOS'),
]
for pattern, os_name in os_patterns:
if re.search(pattern, ua_lower):
result['os'] = os_name
break
# 浏览器识别规则(按优先级从高到低排列)
browser_patterns = [
(r'edg', 'Edge'), # Edge 浏览器(基于Chromium)
(r'chrome', 'Chrome'), # Chrome 浏览器
(r'safari', 'Safari'), # Safari 浏览器
(r'firefox', 'Firefox'),# Firefox 浏览器
(r'msie', 'IE'), # Internet Explorer
(r'trident', 'IE'), # IE 11(Trident内核)
]
for pattern, browser_name in browser_patterns:
if re.search(pattern, ua_lower):
result['browser'] = browser_name
break
return result
from src.common.utils.user_agent import * # noqa: F401,F403