Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, HTTPException, Form, Request | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import JSONResponse | |
| from fastapi_socketio import SocketManager | |
| from typing import Optional | |
| import pymongo | |
| from bson.objectid import ObjectId | |
| import redis | |
| import json | |
| from redis.exceptions import RedisError | |
| from pydantic import BaseModel | |
| # Initialize FastAPI app | |
| app = FastAPI() | |
| socket_manager = SocketManager(app=app) | |
| # Add CORS middleware | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Initialize Redis client | |
| redis_client = redis.Redis(host='localhost', port=6379, db=0) | |
| CACHE_EXPIRE_TIME = 300 # 5 minutes | |
| # 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"] | |
| # Pydantic models for request validation | |
| class VoterRegistration(BaseModel): | |
| name: str | |
| group: str | |
| role: str | |
| class VoteRequest(BaseModel): | |
| voter_id: str | |
| file_id: str | |
| vote_count: Optional[int] = 1 | |
| async def upload_file( | |
| title: str = Form(...), | |
| group: str = Form(...), | |
| url: str = Form(...) | |
| ): | |
| new_pdf = { | |
| 'title': title, | |
| 'group': group, | |
| 'url': url, | |
| 'votes': 0 | |
| } | |
| result = pdf_collection.insert_one(new_pdf) | |
| return {'status': 'ok', 'id': str(result.inserted_id)} | |
| async def get_votes(file_id: str): | |
| try: | |
| file = pdf_collection.find_one({'_id': ObjectId(file_id)}) | |
| if not file: | |
| raise HTTPException(status_code=404, detail="File not found") | |
| return {'status': 'ok', 'votes': file.get('votes', 0)} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_files(): | |
| try: | |
| files = pdf_collection.find({}) | |
| file_list = [ | |
| { | |
| 'id': str(file['_id']), | |
| 'title': file['title'], | |
| 'group': file['group'], | |
| 'url': file['url'], | |
| 'votes': file.get('votes', 0) | |
| } | |
| for file in files | |
| ] | |
| return {'status': 'ok', 'data': file_list} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def register_voter(voter: VoterRegistration): | |
| new_voter = { | |
| 'name': voter.name, | |
| 'group': voter.group, | |
| 'role': voter.role, | |
| 'number_of_votes': 0 | |
| } | |
| result = voter_collection.insert_one(new_voter) | |
| return {'status': 'ok', 'id': str(result.inserted_id)} | |
| async def vote_by_voter(vote_request: VoteRequest): | |
| if vote_request.vote_count <= 0: | |
| raise HTTPException(status_code=400, detail="Vote count must be greater than 0") | |
| voter = voter_collection.find_one({'_id': ObjectId(vote_request.voter_id)}) | |
| if not voter: | |
| raise HTTPException(status_code=404, detail="Voter not found") | |
| max_votes = 10 if voter['role'] == 'judge' else 2 | |
| if voter['number_of_votes'] + vote_request.vote_count > max_votes: | |
| raise HTTPException(status_code=400, detail="Maximum votes exceeded") | |
| try: | |
| # Update MongoDB | |
| voter_collection.update_one( | |
| {'_id': ObjectId(vote_request.voter_id)}, | |
| {'$inc': {'number_of_votes': vote_request.vote_count}} | |
| ) | |
| pdf_collection.update_one( | |
| {'_id': ObjectId(vote_request.file_id)}, | |
| {'$inc': {'votes': vote_request.vote_count}} | |
| ) | |
| # Clear cache | |
| redis_client.delete('all_files') | |
| redis_client.delete(f'voter:{vote_request.voter_id}') | |
| # Emit socket event | |
| updated_file = pdf_collection.find_one({'_id': ObjectId(vote_request.file_id)}) | |
| await socket_manager.emit('vote_update', { | |
| 'file_id': vote_request.file_id, | |
| 'votes': updated_file.get('votes', 0) | |
| }) | |
| return {'status': 'ok', 'message': f'Vote recorded successfully with {vote_request.vote_count} votes'} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_voter(voter_id: str): | |
| # Check cache | |
| cached_voter = redis_client.get(f'voter:{voter_id}') | |
| if cached_voter: | |
| return json.loads(cached_voter) | |
| voter = voter_collection.find_one({'_id': ObjectId(voter_id)}) | |
| if not voter: | |
| raise HTTPException(status_code=404, detail="Voter not found") | |
| voter_data = { | |
| 'status': 'ok', | |
| 'name': voter['name'], | |
| 'group': voter['group'], | |
| 'role': voter['role'], | |
| 'number_of_votes': voter['number_of_votes'] | |
| } | |
| # Save to cache | |
| redis_client.setex(f'voter:{voter_id}', CACHE_EXPIRE_TIME, json.dumps(voter_data)) | |
| return voter_data | |
| async def handle_connect(): | |
| print('Client connected') | |
| async def handle_disconnect(): | |
| print('Client disconnected') | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=5000) |