v1.0
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
from flask import Flask, render_template, request, jsonify, session, redirect, url_for, send_from_directory
|
||||
import os
|
||||
from flask_socketio import SocketIO
|
||||
from flask_cors import CORS
|
||||
import sys
|
||||
|
||||
from config import Config
|
||||
from auth import infi_login, login_required
|
||||
from database import UserManager, ChatManager
|
||||
from websocket_handler import WebSocketHandler
|
||||
from file_handler import FileHandler
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(Config)
|
||||
CORS(app)
|
||||
|
||||
# 初始化SocketIO
|
||||
# 在 Windows 上避免使用 eventlet 的 monkey_patch,改用 threading
|
||||
use_eventlet = False
|
||||
if not sys.platform.startswith('win'):
|
||||
try:
|
||||
import eventlet
|
||||
eventlet.monkey_patch()
|
||||
use_eventlet = True
|
||||
except Exception:
|
||||
use_eventlet = False
|
||||
|
||||
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet' if use_eventlet else 'threading')
|
||||
|
||||
# 初始化管理器
|
||||
user_manager = UserManager()
|
||||
chat_manager = ChatManager()
|
||||
|
||||
# 初始化WebSocket处理器
|
||||
ws_handler = WebSocketHandler(socketio, user_manager)
|
||||
|
||||
@app.route('/')
|
||||
@login_required
|
||||
def index():
|
||||
"""主页面"""
|
||||
user_account = session.get('user_account')
|
||||
user_info = user_manager.get_user(user_account)['user_info']
|
||||
return render_template('index.html', user_info=user_info)
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
"""登录页面"""
|
||||
if request.method == 'GET':
|
||||
return render_template('login.html')
|
||||
|
||||
# POST请求处理登录
|
||||
data = request.json
|
||||
account = data.get('account')
|
||||
password = data.get('password')
|
||||
|
||||
# 检查本地是否已保存用户
|
||||
if user_manager.verify_user(account, password):
|
||||
session['user_account'] = account
|
||||
user_manager.update_user_status(account, online=True)
|
||||
return jsonify({'success': True, 'message': '登录成功'})
|
||||
|
||||
# 使用英飞API登录
|
||||
result, error = infi_login(account, password)
|
||||
if error:
|
||||
return jsonify({'success': False, 'message': error})
|
||||
|
||||
# 保存用户信息到本地
|
||||
user_manager.add_user(account, password, result['token'], result['user_info'])
|
||||
|
||||
# 设置session
|
||||
session['user_account'] = account
|
||||
user_manager.update_user_status(account, online=True)
|
||||
|
||||
return jsonify({'success': True, 'message': '登录成功'})
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
"""登出"""
|
||||
account = session.get('user_account')
|
||||
if account:
|
||||
user_manager.update_user_status(account, online=False)
|
||||
session.clear()
|
||||
return redirect(url_for('login'))
|
||||
|
||||
@app.route('/api/users')
|
||||
@login_required
|
||||
def get_users():
|
||||
"""获取用户列表"""
|
||||
current_user = session.get('user_account')
|
||||
users = []
|
||||
|
||||
for account, data in user_manager.users.items():
|
||||
if account != current_user:
|
||||
users.append({
|
||||
'account': account,
|
||||
'name': data['user_info'].get('name', '未知用户'),
|
||||
'online': data.get('online', False),
|
||||
'org': data['user_info'].get('orgFullList', [{}])[0].get('name', '')
|
||||
})
|
||||
|
||||
return jsonify(users)
|
||||
|
||||
@app.route('/api/upload', methods=['POST'])
|
||||
@login_required
|
||||
def upload_file():
|
||||
"""文件上传"""
|
||||
if 'file' not in request.files:
|
||||
return jsonify({'success': False, 'message': '没有文件'})
|
||||
|
||||
# 检查是否可以上传新文件
|
||||
if not chat_manager.can_upload_file():
|
||||
return jsonify({'success': False, 'message': '同时最多只能有5个文件存在'})
|
||||
|
||||
file = request.files['file']
|
||||
uploader = session.get('user_account')
|
||||
|
||||
# 检查文件大小
|
||||
file.seek(0, 2) # 移动到文件末尾
|
||||
file_size = file.tell()
|
||||
file.seek(0) # 重置文件指针
|
||||
|
||||
if file_size > Config.MAX_CONTENT_LENGTH:
|
||||
return jsonify({'success': False, 'message': '文件太大,最大100MB'})
|
||||
|
||||
# 保存文件
|
||||
file_info = FileHandler.save_file(file, uploader)
|
||||
if not file_info:
|
||||
return jsonify({'success': False, 'message': '不支持的文件类型'})
|
||||
|
||||
# 添加到活跃文件列表
|
||||
chat_manager.add_file(file_info)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'filename': file_info.get('filename', file_info.get('original_name')),
|
||||
'url': file_info['url']
|
||||
})
|
||||
|
||||
@app.route('/api/files')
|
||||
@login_required
|
||||
def list_files():
|
||||
"""获取文件列表"""
|
||||
files = []
|
||||
for file_info in chat_manager.active_files:
|
||||
files.append({
|
||||
'filename': file_info.get('filename', file_info.get('original_name')),
|
||||
'uploader': file_info['uploader'],
|
||||
'upload_time': file_info['upload_time'].isoformat(),
|
||||
'size': file_info['size'],
|
||||
'url': file_info['url']
|
||||
})
|
||||
|
||||
return jsonify(files)
|
||||
|
||||
|
||||
@app.route('/favicon.ico')
|
||||
def favicon():
|
||||
# 从 static/favicon.ico 返回 favicon
|
||||
favicon_path = os.path.join(app.root_path, 'static', 'favicon.ico')
|
||||
if os.path.exists(favicon_path):
|
||||
return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico')
|
||||
return ('', 404)
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("Starting Web WeChat server...")
|
||||
print(f"Access at: http://localhost:5000")
|
||||
socketio.run(app, debug=True, host='::', port=5000)
|
||||
|
||||
|
||||
@app.route('/favicon.ico')
|
||||
def favicon():
|
||||
# 从 static/favicon.ico 返回 favicon
|
||||
favicon_path = os.path.join(app.root_path, 'static', 'favicon.ico')
|
||||
if os.path.exists(favicon_path):
|
||||
return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico')
|
||||
return ('', 404)
|
||||
Reference in New Issue
Block a user