File size: 5,112 Bytes
ec9b387
1deacc5
3ebc508
 
 
 
1deacc5
 
465bca7
 
3ebc508
 
 
 
ec9b387
14c0817
ec9b387
 
14c0817
3ebc508
1deacc5
ec9b387
 
 
 
 
 
 
 
 
 
 
 
76141c4
 
14c0817
 
3ebc508
14c0817
ec9b387
 
14c0817
3ebc508
ec9b387
 
 
 
 
 
1deacc5
76141c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ebc508
ec9b387
3ebc508
 
ec9b387
3ebc508
263ee79
ec9b387
3ebc508
76141c4
 
 
263ee79
ec9b387
76141c4
 
 
 
 
 
 
 
 
 
 
 
 
ec9b387
3ebc508
ec9b387
 
76141c4
 
ec9b387
3ebc508
 
ec9b387
 
14c0817
 
ec9b387
14c0817
 
ec9b387
 
 
14c0817
ec9b387
 
 
 
 
76141c4
ec9b387
 
14c0817
ec9b387
 
14c0817
465bca7
76141c4
ec9b387
 
 
 
 
3ebc508
76141c4
 
 
 
3ebc508
 
1deacc5
 
 
 
 
3ebc508
e81567c
ec9b387
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
# app.py - Flask Backend
from flask import Flask, request, jsonify, send_from_directory
import google.generativeai as genai
from dotenv import load_dotenv
import os
from flask_cors import CORS
import markdown2
import re
from gtts import gTTS
import uuid

# Load environment variables
load_dotenv()

# Define paths and create static audio directory if it doesn't exist
AUDIO_FOLDER = os.path.join('static', 'audio')
if not os.path.exists(AUDIO_FOLDER):
    os.makedirs(AUDIO_FOLDER)

# Initialize Flask app
app = Flask(__name__, static_folder='static')
CORS(app)  # Enable CORS for all routes

# Configure Gemini with a system instruction
system_instruction_text = """
You are a helpful, friendly, and informative AI assistant named Athspi.
Your goal is to provide clear, concise, and natural-sounding answers to user queries.
When you respond:
- Use clear and simple language.
- Avoid overly complex sentence structures that might be hard to read aloud.
- Keep the user engaged and offer follow-up questions or related topics where appropriate.
- Ensure your responses are suitable for text-to-speech conversion.
- Provide factual and accurate information.
- If the user asks for audio or to speak the response, include πŸ”Š at the start of your response.
- For coding questions, provide well-formatted code blocks with syntax highlighting.
"""

genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
model = genai.GenerativeModel(
    'gemini-2.5-flash',
    system_instruction=system_instruction_text
)

def convert_markdown_to_html(text):
    html = markdown2.markdown(text, extras=["fenced-code-blocks", "tables"])
    html = re.sub(r'<pre><code(.*?)>', r'<pre class="code-block"><code\1>', html)
    html = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', html)
    html = re.sub(r'\*(.*?)\*', r'<em>\1</em>', html)
    return html

def detect_audio_request(text):
    """Detect if user is requesting audio"""
    audio_keywords = ['audio', 'speak', 'say it', 'read aloud', 'hear', 'listen']
    return any(keyword in text.lower() for keyword in audio_keywords)

def generate_audio_file(text):
    """Generate audio file from text and return filename"""
    cleaned_text = re.sub(r'[\*_`#]', '', text)
    cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()

    if not cleaned_text:
        return None

    filename = f"{uuid.uuid4()}.mp3"
    filepath = os.path.join(AUDIO_FOLDER, filename)

    tts = gTTS(text=cleaned_text, lang='en', slow=False)
    tts.save(filepath)

    return filename

@app.route('/chat', methods=['POST'])
def chat():
    try:
        data = request.json
        user_message = data.get('message')
        
        if not user_message:
            return jsonify({"error": "No message provided"}), 400
        
        # Detect if user is requesting audio
        audio_requested = detect_audio_request(user_message)
        
        response = model.generate_content(user_message)
        plain_text_response = response.text
        
        # Generate audio if requested
        audio_url = None
        if audio_requested:
            # Add audio indicator if not already present
            if not plain_text_response.startswith("πŸ”Š"):
                plain_text_response = "πŸ”Š " + plain_text_response
            
            # Generate audio file
            audio_filename = generate_audio_file(plain_text_response)
            if audio_filename:
                audio_url = f"/static/audio/{audio_filename}"
        
        html_response = convert_markdown_to_html(plain_text_response)
        
        return jsonify({
            "response_html": html_response,
            "response_text": plain_text_response,
            "audio_url": audio_url
        })
        
    except Exception as e:
        app.logger.error(f"Chat Error: {e}")
        return jsonify({"error": str(e)}), 500

@app.route('/generate-audio', methods=['POST'])
def generate_audio():
    try:
        data = request.json
        text_to_speak = data.get('text')

        if not text_to_speak:
            return jsonify({"error": "No text provided"}), 400

        cleaned_text = re.sub(r'[\*_`#]', '', text_to_speak)
        cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()

        if not cleaned_text:
            return jsonify({"error": "Text became empty after cleaning"}), 400

        filename = f"{uuid.uuid4()}.mp3"
        filepath = os.path.join(AUDIO_FOLDER, filename)

        tts = gTTS(text=cleaned_text, lang='en', slow=False)
        tts.save(filepath)

        audio_url = f"/static/audio/{filename}"
        return jsonify({"audio_url": audio_url})

    except Exception as e:
        app.logger.error(f"Audio Generation Error: {e}")
        return jsonify({"error": str(e)}), 500

@app.route('/static/audio/<filename>')
def serve_audio(filename):
    return send_from_directory(AUDIO_FOLDER, filename)

@app.route('/')
def serve_index():
    return send_from_directory('static', 'index.html')

@app.route('/<path:path>')
def serve_static(path):
    return send_from_directory('static', path)

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=7860)