| from rest_framework.views import APIView |
| from rest_framework.response import Response |
| from rest_framework import status, permissions |
| from .rag_service import generate_chat_response |
| from finance.utils_mongo import get_user_db_id |
| import tempfile |
| import os |
| import pdfplumber |
|
|
| class ChatView(APIView): |
| permission_classes = [permissions.IsAuthenticated] |
|
|
| def post(self, request): |
| query = request.data.get('message', '') |
| provider = request.data.get('provider') |
| is_voice = request.data.get('is_voice', False) |
| attached_file = request.FILES.get('file') |
|
|
| |
| if attached_file and attached_file.name.lower().endswith('.pdf'): |
| try: |
| with pdfplumber.open(attached_file) as pdf: |
| pdf_text = "" |
| for page in pdf.pages: |
| pdf_text += (page.extract_text() or "") + "\n" |
| if pdf_text: |
| query = f"[ATTACHED PDF CONTENT: {attached_file.name}]\n{pdf_text}\n\nUSER QUESTION: {query}" |
| except Exception as e: |
| print(f"PDF extraction error: {e}") |
|
|
| |
| image_path = None |
| if attached_file and any(attached_file.name.lower().endswith(ext) for ext in ['.png', '.jpg', '.jpeg', '.webp']): |
| try: |
| suffix = os.path.splitext(attached_file.name)[1] |
| with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp: |
| for chunk in attached_file.chunks(): |
| tmp.write(chunk) |
| image_path = tmp.name |
| except Exception as e: |
| print(f"Image save error: {e}") |
|
|
| if not query and not image_path: |
| return Response({"error": "Message or attachment is required"}, status=status.HTTP_400_BAD_REQUEST) |
| |
| mongo_user_id = get_user_db_id(request.user) |
| auth_header = request.headers.get('Authorization', '') |
| access_token = auth_header.replace('Bearer ', '').strip() if auth_header.startswith('Bearer ') else None |
| |
| if is_voice: |
| from finance.ai_helper import generate_voice_response |
| result = generate_voice_response(query, provider=provider) |
| else: |
| result = generate_chat_response( |
| mongo_user_id, |
| query, |
| provider=provider, |
| access_token=access_token, |
| image_path=image_path |
| ) |
| |
| |
| if image_path and os.path.exists(image_path): |
| try: |
| os.remove(image_path) |
| except: |
| pass |
| |
| |
| try: |
| from expense_tracker.utils import MongoDBClient |
| from datetime import datetime |
| from bson import ObjectId |
| |
| db = MongoDBClient.get_client() |
| chat_log = { |
| '_id': ObjectId(), |
| 'query': query, |
| 'response': result.get('response'), |
| 'context_used': result.get('context_used'), |
| 'timestamp': datetime.now() |
| } |
| db.users.update_one( |
| {'_id': mongo_user_id}, |
| {'$push': {'chat_history': chat_log}} |
| ) |
| except Exception as e: |
| pass |
|
|
| return Response(result) |
|
|
| def get(self, request): |
| """Retrieve chat history for the user""" |
| try: |
| from expense_tracker.utils import MongoDBClient |
| from bson import ObjectId |
| |
| db = MongoDBClient.get_client() |
| db = MongoDBClient.get_client() |
| mongo_user_id = get_user_db_id(request.user) |
| user = db.users.find_one({'_id': mongo_user_id}, {'chat_history': 1}) |
| |
| history = [] |
| if user and 'chat_history' in user: |
| |
| raw_history = user['chat_history'][-50:] |
| for h in raw_history: |
| |
| history.append({ |
| 'id': str(h.get('_id', '')), |
| 'sender': 'user', |
| 'text': h.get('query'), |
| 'timestamp': h.get('timestamp') |
| }) |
| history.append({ |
| 'id': str(h.get('_id', '')), |
| 'sender': 'bot', |
| 'text': h.get('response'), |
| 'timestamp': h.get('timestamp') |
| }) |
| |
| return Response(history) |
| except Exception as e: |
| return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) |
|
|
| def delete(self, request, msg_id=None): |
| """Delete a specific chat entry from history""" |
| if not msg_id: |
| return Response({"error": "Message ID required"}, status=status.HTTP_400_BAD_REQUEST) |
| |
| try: |
| from expense_tracker.utils import MongoDBClient |
| from bson import ObjectId |
| |
| db = MongoDBClient.get_client() |
| db = MongoDBClient.get_client() |
| mongo_user_id = get_user_db_id(request.user) |
| if msg_id == 'all': |
| result = db.users.update_one( |
| {'_id': mongo_user_id}, |
| {'$set': {'chat_history': []}} |
| ) |
| if result.modified_count > 0: |
| return Response({"message": "All chat history cleared"}, status=status.HTTP_200_OK) |
| return Response({"message": "No chat history to clear"}, status=status.HTTP_200_OK) |
|
|
| result = db.users.update_one( |
| {'_id': mongo_user_id}, |
| {'$pull': {'chat_history': {'_id': ObjectId(msg_id)}}} |
| ) |
| |
| if result.modified_count > 0: |
| return Response({"message": "Chat deleted successfully"}, status=status.HTTP_200_OK) |
| else: |
| return Response({"error": "Chat not found"}, status=status.HTTP_404_NOT_FOUND) |
| |
| except Exception as e: |
| return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) |
|
|