from flask import Flask, request, jsonify from flask_cors import CORS from flask_socketio import SocketIO, emit import pymongo from bson.objectid import ObjectId import redis import json from redis.exceptions import RedisError # Khởi tạo Flask app và SocketIO app = Flask(__name__) CORS(app) socketio = SocketIO(app, cors_allowed_origins="*") # Khởi tạo Redis client redis_client = redis.Redis(host='localhost', port=6379, db=0) CACHE_EXPIRE_TIME = 300 # 5 phút # MongoDB connection mongo_url = "mongodb+srv://ip6ofme:JL1S4hjMWRoko8AJ@cluster0.x0vo0.mongodb.net/" client = pymongo.MongoClient(mongo_url) db = client["test"] pdf_collection = db["PdfDetails"] voter_collection = db["Voters"] # API để upload file và lưu thông tin vào MongoDB @app.route('/upload-files', methods=['POST']) def upload_file(): # Chỉ lưu thông tin vào MongoDB title = request.form.get('title') group = request.form.get('group') firebase_url = request.form.get('url') new_pdf = { 'title': title, 'group': group, 'url': firebase_url, 'votes': 0 } result = pdf_collection.insert_one(new_pdf) return jsonify({'status': 'ok', 'id': str(result.inserted_id)}) # API để lấy số lượng votes của file theo ID @app.route('/get-votes', methods=['GET']) def get_votes(): file_id = request.args.get('id') try: file = pdf_collection.find_one({'_id': ObjectId(file_id)}) if not file: return jsonify({'status': 'error', 'message': 'File not found'}), 404 return jsonify({'status': 'ok', 'votes': file.get('votes', 0)}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # API để lấy danh sách tất cả các file @app.route('/get-files', methods=['GET']) def get_files(): try: files = pdf_collection.find({}) file_list = [] for file in files: file_list.append({ 'id': str(file['_id']), 'title': file['title'], 'group': file['group'], 'url': file['url'], 'votes': file.get('votes', 0) }) return jsonify({'status': 'ok', 'data': file_list}) except Exception as e: print(f"Error: {str(e)}") return jsonify({'status': 'error', 'message': str(e)}), 500 # API để đăng ký người bình chọn @app.route('/register-voter', methods=['POST']) def register_voter(): data = request.json name = data.get('name') group = data.get('group') role = data.get('role') # Thêm trường role new_voter = { 'name': name, 'group': group, 'role': role, # Lưu role vào MongoDB 'number_of_votes': 0 } result = voter_collection.insert_one(new_voter) return jsonify({'status': 'ok', 'id': str(result.inserted_id)}) # API để bình chọn @app.route('/vote-by-voter', methods=['POST']) def vote_by_voter(): data = request.json voter_id = data.get('voter_id') file_id = data.get('file_id') vote_count = data.get('vote_count', 1) if vote_count <= 0: return jsonify({'status': 'error', 'message': 'Vote count must be greater than 0'}), 400 voter = voter_collection.find_one({'_id': ObjectId(voter_id)}) if not voter: return jsonify({'status': 'error', 'message': 'Voter not found'}), 404 max_votes = 10 if voter['role'] == 'judge' else 2 if voter['number_of_votes'] + vote_count > max_votes: return jsonify({'status': 'error', 'message': 'Maximum votes exceeded'}), 400 try: # Cập nhật MongoDB voter_collection.update_one({'_id': ObjectId(voter_id)}, {'$inc': {'number_of_votes': vote_count}}) pdf_collection.update_one({'_id': ObjectId(file_id)}, {'$inc': {'votes': vote_count}}) # Xóa cache redis_client.delete('all_files') redis_client.delete(f'voter:{voter_id}') # Emit socket event updated_file = pdf_collection.find_one({'_id': ObjectId(file_id)}) socketio.emit('vote_update', { 'file_id': file_id, 'votes': updated_file.get('votes', 0) }) return jsonify({'status': 'ok', 'message': f'Vote recorded successfully with {vote_count} votes'}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # API để lấy thông tin người bình chọn @app.route('/get-voter', methods=['GET']) def get_voter(): voter_id = request.args.get('id') # Kiểm tra cache cached_voter = redis_client.get(f'voter:{voter_id}') if cached_voter: return jsonify(json.loads(cached_voter)) voter = voter_collection.find_one({'_id': ObjectId(voter_id)}) if not voter: return jsonify({'status': 'error', 'message': 'Voter not found'}), 404 voter_data = { 'status': 'ok', 'name': voter['name'], 'group': voter['group'], 'role': voter['role'], 'number_of_votes': voter['number_of_votes'] } # Lưu vào cache redis_client.setex(f'voter:{voter_id}', CACHE_EXPIRE_TIME, json.dumps(voter_data)) return jsonify(voter_data) # Socket events @socketio.on('connect') def handle_connect(): print('Client connected') @socketio.on('disconnect') def handle_disconnect(): print('Client disconnected') # Khởi chạy server if __name__ == "__main__": socketio.run(app, port=5000, debug=True)