重新整理项目结构
This commit is contained in:
BIN
backend/modules/__pycache__/aimodelapp.cpython-313.pyc
Normal file
BIN
backend/modules/__pycache__/aimodelapp.cpython-313.pyc
Normal file
Binary file not shown.
BIN
backend/modules/__pycache__/api_60s.cpython-313.pyc
Normal file
BIN
backend/modules/__pycache__/api_60s.cpython-313.pyc
Normal file
Binary file not shown.
BIN
backend/modules/__pycache__/api_scanner.cpython-313.pyc
Normal file
BIN
backend/modules/__pycache__/api_scanner.cpython-313.pyc
Normal file
Binary file not shown.
BIN
backend/modules/__pycache__/auth.cpython-313.pyc
Normal file
BIN
backend/modules/__pycache__/auth.cpython-313.pyc
Normal file
Binary file not shown.
BIN
backend/modules/__pycache__/email_service.cpython-313.pyc
Normal file
BIN
backend/modules/__pycache__/email_service.cpython-313.pyc
Normal file
Binary file not shown.
BIN
backend/modules/__pycache__/smallgame.cpython-313.pyc
Normal file
BIN
backend/modules/__pycache__/smallgame.cpython-313.pyc
Normal file
Binary file not shown.
BIN
backend/modules/__pycache__/user_management.cpython-313.pyc
Normal file
BIN
backend/modules/__pycache__/user_management.cpython-313.pyc
Normal file
Binary file not shown.
@@ -1,78 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
AI应用模块 - 提供AI应用静态文件服务和目录扫描
|
||||
Created by: 神奇万事通
|
||||
Date: 2025-09-02
|
||||
"""
|
||||
|
||||
from flask import Blueprint, jsonify
|
||||
import os
|
||||
|
||||
aimodelapp_bp = Blueprint('aimodelapp', __name__)
|
||||
|
||||
@aimodelapp_bp.route('/scan-directories', methods=['GET'])
|
||||
def scan_directories():
|
||||
"""扫描aimodelapp目录结构"""
|
||||
try:
|
||||
# 获取项目根目录
|
||||
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
ai_directory = os.path.join(project_root, 'frontend', 'aimodelapp')
|
||||
|
||||
if not os.path.exists(ai_directory):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': 'aimodelapp目录不存在'
|
||||
}), 404
|
||||
|
||||
apps = []
|
||||
|
||||
# 颜色渐变配置
|
||||
gradient_colors = [
|
||||
'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||||
'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
|
||||
'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
|
||||
'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)',
|
||||
'linear-gradient(135deg, #fa709a 0%, #fee140 100%)'
|
||||
]
|
||||
|
||||
# 扫描目录
|
||||
for i, app_name in enumerate(os.listdir(ai_directory)):
|
||||
app_path = os.path.join(ai_directory, app_name)
|
||||
index_path = os.path.join(app_path, 'index.html')
|
||||
|
||||
if os.path.isdir(app_path) and os.path.exists(index_path) and not app_name.endswith('.txt'):
|
||||
# 读取HTML文件获取标题
|
||||
try:
|
||||
with open(index_path, 'r', encoding='utf-8') as f:
|
||||
html_content = f.read()
|
||||
title_match = html_content.find('<title>')
|
||||
if title_match != -1:
|
||||
title_end = html_content.find('</title>', title_match)
|
||||
if title_end != -1:
|
||||
title = html_content[title_match + 7:title_end].strip()
|
||||
else:
|
||||
title = app_name
|
||||
else:
|
||||
title = app_name
|
||||
except:
|
||||
title = app_name
|
||||
|
||||
apps.append({
|
||||
'title': title,
|
||||
'description': f'{app_name}AI应用',
|
||||
'link': f'/aimodelapp/{app_name}/index.html',
|
||||
'status': 'active',
|
||||
'color': gradient_colors[i % len(gradient_colors)]
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'apps': apps
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'扫描目录时出错: {str(e)}'
|
||||
}), 500
|
||||
@@ -1,103 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
60s API模块 - 提供各种实时数据接口
|
||||
Created by: 神奇万事通
|
||||
Date: 2025-09-02
|
||||
"""
|
||||
|
||||
from flask import Blueprint, jsonify
|
||||
import os
|
||||
|
||||
api_60s_bp = Blueprint('api_60s', __name__)
|
||||
|
||||
@api_60s_bp.route('/scan-directories', methods=['GET'])
|
||||
def scan_directories():
|
||||
"""扫描60sapi目录结构"""
|
||||
try:
|
||||
# 获取项目根目录
|
||||
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
api_directory = os.path.join(project_root, 'frontend', '60sapi')
|
||||
|
||||
if not os.path.exists(api_directory):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': '60sapi目录不存在'
|
||||
}), 404
|
||||
|
||||
categories = []
|
||||
|
||||
# 定义分类配置
|
||||
category_config = {
|
||||
'热搜榜单': {'color': '#66bb6a'},
|
||||
'日更资讯': {'color': '#4caf50'},
|
||||
'实用功能': {'color': '#388e3c'},
|
||||
'娱乐消遣': {'color': '#66bb6a'}
|
||||
}
|
||||
|
||||
# 颜色渐变配置
|
||||
gradient_colors = [
|
||||
'linear-gradient(135deg, #81c784 0%, #66bb6a 100%)',
|
||||
'linear-gradient(135deg, #a5d6a7 0%, #81c784 100%)',
|
||||
'linear-gradient(135deg, #c8e6c9 0%, #a5d6a7 100%)',
|
||||
'linear-gradient(135deg, #66bb6a 0%, #4caf50 100%)',
|
||||
'linear-gradient(135deg, #4caf50 0%, #388e3c 100%)'
|
||||
]
|
||||
|
||||
# 扫描目录
|
||||
for category_name in os.listdir(api_directory):
|
||||
category_path = os.path.join(api_directory, category_name)
|
||||
|
||||
if os.path.isdir(category_path) and category_name in category_config:
|
||||
apis = []
|
||||
|
||||
# 扫描分类下的模块
|
||||
for i, module_name in enumerate(os.listdir(category_path)):
|
||||
module_path = os.path.join(category_path, module_name)
|
||||
index_path = os.path.join(module_path, 'index.html')
|
||||
|
||||
if os.path.isdir(module_path) and os.path.exists(index_path):
|
||||
# 读取HTML文件获取标题
|
||||
try:
|
||||
with open(index_path, 'r', encoding='utf-8') as f:
|
||||
html_content = f.read()
|
||||
title_match = html_content.find('<title>')
|
||||
if title_match != -1:
|
||||
title_end = html_content.find('</title>', title_match)
|
||||
if title_end != -1:
|
||||
title = html_content[title_match + 7:title_end].strip()
|
||||
else:
|
||||
title = module_name
|
||||
else:
|
||||
title = module_name
|
||||
except:
|
||||
title = module_name
|
||||
|
||||
# 根据环境获取基础URL
|
||||
base_url = 'https://infogenie.api.shumengya.top'
|
||||
|
||||
apis.append({
|
||||
'title': title,
|
||||
'description': f'{module_name}相关功能',
|
||||
'link': f'{base_url}/60sapi/{category_name}/{module_name}/index.html',
|
||||
'status': 'active',
|
||||
'color': gradient_colors[i % len(gradient_colors)]
|
||||
})
|
||||
|
||||
if apis:
|
||||
categories.append({
|
||||
'title': category_name,
|
||||
'color': category_config[category_name]['color'],
|
||||
'apis': apis
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'categories': categories
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'扫描目录时出错: {str(e)}'
|
||||
}), 500
|
||||
@@ -10,11 +10,53 @@ from flask import Blueprint, request, jsonify, session, current_app
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
import hashlib
|
||||
import re
|
||||
from datetime import datetime
|
||||
import jwt
|
||||
from datetime import datetime, timedelta
|
||||
from functools import wraps
|
||||
from .email_service import send_verification_email, verify_code, is_qq_email, get_qq_avatar_url
|
||||
|
||||
auth_bp = Blueprint('auth', __name__)
|
||||
|
||||
def generate_token(user_data):
|
||||
"""生成JWT token"""
|
||||
payload = {
|
||||
'user_id': user_data['user_id'],
|
||||
'email': user_data['email'],
|
||||
'username': user_data['username'],
|
||||
'exp': datetime.utcnow() + timedelta(days=7), # 7天过期
|
||||
'iat': datetime.utcnow()
|
||||
}
|
||||
return jwt.encode(payload, current_app.config['SECRET_KEY'], algorithm='HS256')
|
||||
|
||||
def verify_token(token):
|
||||
"""验证JWT token"""
|
||||
try:
|
||||
payload = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=['HS256'])
|
||||
return {'success': True, 'data': payload}
|
||||
except jwt.ExpiredSignatureError:
|
||||
return {'success': False, 'message': 'Token已过期'}
|
||||
except jwt.InvalidTokenError:
|
||||
return {'success': False, 'message': 'Token无效'}
|
||||
|
||||
def token_required(f):
|
||||
"""JWT token验证装饰器"""
|
||||
@wraps(f)
|
||||
def decorated(*args, **kwargs):
|
||||
token = request.headers.get('Authorization')
|
||||
if not token:
|
||||
return jsonify({'success': False, 'message': '缺少认证token'}), 401
|
||||
|
||||
if token.startswith('Bearer '):
|
||||
token = token[7:]
|
||||
|
||||
result = verify_token(token)
|
||||
if not result['success']:
|
||||
return jsonify({'success': False, 'message': result['message']}), 401
|
||||
|
||||
request.current_user = result['data']
|
||||
return f(*args, **kwargs)
|
||||
return decorated
|
||||
|
||||
def validate_qq_email(email):
|
||||
"""验证QQ邮箱格式"""
|
||||
return is_qq_email(email)
|
||||
@@ -313,16 +355,18 @@ def login():
|
||||
}
|
||||
)
|
||||
|
||||
# 设置会话
|
||||
session['user_id'] = str(user['_id'])
|
||||
session['email'] = email
|
||||
session['username'] = user.get('用户名', '')
|
||||
session['logged_in'] = True
|
||||
session.permanent = True
|
||||
|
||||
# 生成JWT token
|
||||
user_data = {
|
||||
'user_id': str(user['_id']),
|
||||
'email': email,
|
||||
'username': user.get('用户名', '')
|
||||
}
|
||||
token = generate_token(user_data)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '登录成功!',
|
||||
'token': token,
|
||||
'user': {
|
||||
'id': str(user['_id']),
|
||||
'email': email,
|
||||
@@ -373,17 +417,11 @@ def login():
|
||||
def logout():
|
||||
"""用户登出"""
|
||||
try:
|
||||
if 'logged_in' in session:
|
||||
session.clear()
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '已成功登出'
|
||||
}), 200
|
||||
else:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': '用户未登录'
|
||||
}), 401
|
||||
# JWT是无状态的,客户端删除token即可
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '已成功登出'
|
||||
}), 200
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
@@ -395,14 +433,26 @@ def logout():
|
||||
def check_login():
|
||||
"""检查登录状态"""
|
||||
try:
|
||||
if session.get('logged_in') and session.get('user_id'):
|
||||
token = request.headers.get('Authorization')
|
||||
if not token:
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'logged_in': False
|
||||
}), 200
|
||||
|
||||
if token.startswith('Bearer '):
|
||||
token = token[7:]
|
||||
|
||||
result = verify_token(token)
|
||||
if result['success']:
|
||||
user_data = result['data']
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'logged_in': True,
|
||||
'user': {
|
||||
'id': session.get('user_id'),
|
||||
'email': session.get('email'),
|
||||
'username': session.get('username')
|
||||
'id': user_data['user_id'],
|
||||
'email': user_data['email'],
|
||||
'username': user_data['username']
|
||||
}
|
||||
}), 200
|
||||
else:
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
小游戏模块 - 提供小游戏静态文件服务和目录扫描
|
||||
Created by: 神奇万事通
|
||||
Date: 2025-09-02
|
||||
"""
|
||||
|
||||
from flask import Blueprint, jsonify
|
||||
import os
|
||||
|
||||
smallgame_bp = Blueprint('smallgame', __name__)
|
||||
|
||||
@smallgame_bp.route('/scan-directories', methods=['GET'])
|
||||
def scan_directories():
|
||||
"""扫描smallgame目录结构"""
|
||||
try:
|
||||
# 获取项目根目录
|
||||
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
game_directory = os.path.join(project_root, 'frontend', 'smallgame')
|
||||
|
||||
if not os.path.exists(game_directory):
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': 'smallgame目录不存在'
|
||||
}), 404
|
||||
|
||||
games = []
|
||||
|
||||
# 颜色渐变配置
|
||||
gradient_colors = [
|
||||
'linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%)',
|
||||
'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)',
|
||||
'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)',
|
||||
'linear-gradient(135deg, #ff8a80 0%, #ffab91 100%)',
|
||||
'linear-gradient(135deg, #81c784 0%, #aed581 100%)'
|
||||
]
|
||||
|
||||
# 扫描目录
|
||||
for i, game_name in enumerate(os.listdir(game_directory)):
|
||||
game_path = os.path.join(game_directory, game_name)
|
||||
index_path = os.path.join(game_path, 'index.html')
|
||||
|
||||
if os.path.isdir(game_path) and os.path.exists(index_path) and not game_name.endswith('.txt'):
|
||||
# 读取HTML文件获取标题
|
||||
try:
|
||||
with open(index_path, 'r', encoding='utf-8') as f:
|
||||
html_content = f.read()
|
||||
title_match = html_content.find('<title>')
|
||||
if title_match != -1:
|
||||
title_end = html_content.find('</title>', title_match)
|
||||
if title_end != -1:
|
||||
title = html_content[title_match + 7:title_end].strip()
|
||||
else:
|
||||
title = game_name
|
||||
else:
|
||||
title = game_name
|
||||
except:
|
||||
title = game_name
|
||||
|
||||
games.append({
|
||||
'title': title,
|
||||
'description': f'{game_name}小游戏',
|
||||
'link': f'/smallgame/{game_name}/index.html',
|
||||
'status': 'active',
|
||||
'color': gradient_colors[i % len(gradient_colors)]
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'games': games
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'扫描目录时出错: {str(e)}'
|
||||
}), 500
|
||||
Reference in New Issue
Block a user