File size: 7,110 Bytes
a1c77ae
 
 
 
 
 
 
 
 
 
 
 
227a7a6
a1c77ae
 
 
 
 
 
 
 
 
 
227a7a6
a1c77ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227a7a6
19b79ca
227a7a6
 
a1c77ae
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
from django.shortcuts import render
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.conf import settings
import json
import logging
from gtts import gTTS
import io
import base64
import tempfile
import os
from google import genai as google_genai
import whisper
import numpy as np
from pydub import AudioSegment
from pydub.utils import which
from dotenv import load_dotenv
load_dotenv()
import os
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

gemini_client = google_genai.Client(api_key=os.getenv('GEMINI_API_KEY'))

whisper_model = whisper.load_model("medium")

def chatbot(request):
    return render(request, 'index.html')

@csrf_exempt
@require_http_methods(["POST"])
def ask_ai(request):
    try:
        body = json.loads(request.body.decode('utf-8'))
        user_message = body.get('message', '').strip()
        
        if not user_message:
            return JsonResponse({
                'error': 'Message cannot be empty'
            }, status=400)
        
        logger.info(f"User message: {user_message}")
        
        ai_response = generate_gemini_response(user_message)
        
        logger.info(f"AI response: {ai_response}")
        
        return JsonResponse({
            'reply': ai_response,
            'success': True
        })
        
    except json.JSONDecodeError:
        return JsonResponse({
            'error': 'Invalid JSON in request body'
        }, status=400)
    except Exception as e:
        logger.error(f"Error in ask_ai: {str(e)}")
        return JsonResponse({
            'error': 'An internal server error occurred'
        }, status=500)

@csrf_exempt
@require_http_methods(["POST"])
def speech_to_text(request):
    try:
        if 'audio' not in request.FILES:
            return JsonResponse({
                'error': 'No audio file provided'
            }, status=400)
        
        audio_file = request.FILES['audio']
        language = request.POST.get('language', 'en')
        
        if language not in ['en', 'hi']:
            language = 'en'  
        
        with tempfile.NamedTemporaryFile(suffix='.webm', delete=False) as temp_input:
            for chunk in audio_file.chunks():
                temp_input.write(chunk)
            temp_input_path = temp_input.name
        
        try:
            # Convert audio to format compatible with Whisper
            audio_segment = AudioSegment.from_file(temp_input_path)
            
            # Convert to WAV format for Whisper
            with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as temp_wav:
                audio_segment.export(temp_wav.name, format="wav")
                temp_wav_path = temp_wav.name
            
            # Transcribe using Whisper
            result = whisper_model.transcribe(
                temp_wav_path, 
                language=language,
                fp16=False 
            )
            
            transcript = result['text'].strip()
            detected_language = result.get('language', language)
            
            os.unlink(temp_input_path)
            os.unlink(temp_wav_path)
            
            return JsonResponse({
                'transcript': transcript,
                'detected_language': detected_language,
                'success': True
            })
            
        except Exception as e:
            # Clean up temp files on error
            if os.path.exists(temp_input_path):
                os.unlink(temp_input_path)
            if 'temp_wav_path' in locals() and os.path.exists(temp_wav_path):
                os.unlink(temp_wav_path)
            raise e
            
    except Exception as e:
        logger.error(f"Error in speech_to_text: {str(e)}")
        return JsonResponse({
            'error': 'Failed to process audio'
        }, status=500)

@csrf_exempt
@require_http_methods(["POST"])
def text_to_speech(request):
    """Convert text to speech using gTTS"""
    import json
    import base64
    import os
    import tempfile
    import logging
    from django.http import JsonResponse
    from gtts import gTTS

    logger = logging.getLogger(__name__)

    try:
        body = json.loads(request.body.decode('utf-8'))
        text = body.get('text', '').strip()
        language = body.get('language', 'en')

        if not text:
            return JsonResponse({'error': 'Text cannot be empty'}, status=400)

        gtts_language_map = {'en': 'en', 'hi': 'hi'}

        if language not in gtts_language_map:
            return JsonResponse({'error': 'Unsupported language'}, status=400)

        gtts_lang = gtts_language_map[language]
        tts = gTTS(text=text, lang=gtts_lang, slow=False)

        with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as temp_file:
            tts.save(temp_file.name)

        with open(temp_file.name, 'rb') as audio_file:
            audio_data = audio_file.read()
            audio_base64 = base64.b64encode(audio_data).decode('utf-8')

        os.unlink(temp_file.name)

        return JsonResponse({'audio_data': audio_base64, 'success': True})

    except Exception as e:
        logger.error(f"Error in text_to_speech: {str(e)}")
        return JsonResponse({'error': 'Failed to generate speech'}, status=500)


def generate_gemini_response(message):
    """
    Generate AI responses using Google's Gemini API
    """
    try:
        # Create a specilized prompt for constellation and astronomy topics
        prompt = f"""
        You are an enthusiastic and friendly astronomy assistant who loves teaching people about constellations and the night sky

        You help beginners understand stars constellations and space in a clear and exciting way

        When someone asks a question give a helpful accurate and engaging answer focused on astronomy especially constellations

        Do not use any punctuation marks emojis or special characters because your response will be converted to speech using a voice engine

        Speak clearly and naturally as if you are talking to someone who is curious about space

        If the question is not related to astronomy gently steer the conversation back to stars constellations or space exploration in a positive and helpful way

        User question {message}
"""


        # Generate response using Gemini
        response = gemini_client.models.generate_content(
            model='gemini-3.5-flash',
            contents=prompt
        )
        return response.text
        
    except Exception as e:
        logger.error(f"Error generating Gemini response: {str(e)}")
        return """🌟 I apologize, but I'm having trouble accessing my astronomical database right now. 

Please try asking your question again in a moment. I'm here to help you explore the wonders of the night sky, including constellations, stars, planets, and cosmic phenomena!

In the meantime, did you know that on any clear night, you can see about 2,000 to 3,000 stars with the naked eye? ✨"""