Anupam007 commited on
Commit
49fd313
·
verified ·
1 Parent(s): deefeaa

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +742 -0
app.py ADDED
@@ -0,0 +1,742 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ import pandas as pd
5
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModelForSequenceClassification, pipeline
6
+ from transformers import MarianMTModel, MarianTokenizer
7
+ import nltk
8
+ import random
9
+ import json
10
+ import os
11
+ import io
12
+ import sqlite3
13
+ import PyPDF2
14
+ import pdfplumber
15
+ import re
16
+ import csv
17
+ from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
18
+ from sklearn.metrics.pairwise import cosine_similarity
19
+ from sentence_transformers import SentenceTransformer
20
+ import faiss
21
+ import tabula
22
+ import pdf2image
23
+ import pytesseract
24
+ from PIL import Image
25
+ from youtube_transcript_api import YouTubeTranscriptApi
26
+ from pytube import YouTube
27
+ import requests
28
+ from bs4 import BeautifulSoup
29
+ from datetime import datetime, timedelta
30
+ import uuid
31
+ from gtts import gTTS
32
+ from reportlab.lib.pagesizes import letter
33
+ from reportlab.pdfgen import canvas
34
+
35
+ # Download NLTK resources
36
+ nltk.download('punkt')
37
+ nltk.download('stopwords')
38
+
39
+ # Check GPU availability
40
+ print("Checking GPU availability...")
41
+ print(f"CUDA available: {torch.cuda.is_available()}")
42
+ if torch.cuda.is_available():
43
+ print(f"CUDA device: {torch.cuda.get_device_name(0)}")
44
+ else:
45
+ print("Device set to use CPU")
46
+
47
+ # Initialize SQLite database
48
+ def init_sqlite_db():
49
+ os.makedirs('/data', exist_ok=True) # Create /data/ directory if it doesn't exist
50
+ if not os.access('/data', os.W_OK):
51
+ raise PermissionError("No write permission for /data directory")
52
+ conn = sqlite3.connect('/data/vernacular_learning.db')
53
+ c = conn.cursor()
54
+ c.execute('''
55
+ CREATE TABLE IF NOT EXISTS users (
56
+ user_id TEXT PRIMARY KEY,
57
+ username TEXT,
58
+ age INTEGER,
59
+ education_level TEXT,
60
+ language_preference TEXT,
61
+ learning_goal TEXT,
62
+ learning_style TEXT,
63
+ progress TEXT,
64
+ quiz_results TEXT,
65
+ feedback TEXT
66
+ )
67
+ ''')
68
+ c.execute('''
69
+ CREATE TABLE IF NOT EXISTS content (
70
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
71
+ source TEXT,
72
+ text TEXT,
73
+ language TEXT,
74
+ category TEXT,
75
+ subcategory TEXT,
76
+ embedding TEXT
77
+ )
78
+ ''')
79
+ c.execute('''
80
+ CREATE TABLE IF NOT EXISTS embeddings (
81
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
82
+ source TEXT,
83
+ embedding TEXT
84
+ )
85
+ ''')
86
+ c.execute('''
87
+ CREATE TABLE IF NOT EXISTS feedback (
88
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
89
+ user_id TEXT,
90
+ text TEXT,
91
+ sentiment TEXT,
92
+ score REAL,
93
+ FOREIGN KEY (user_id) REFERENCES users (user_id)
94
+ )
95
+ ''')
96
+ c.execute('''
97
+ CREATE TABLE IF NOT EXISTS video_sessions (
98
+ session_id TEXT PRIMARY KEY,
99
+ user_id TEXT,
100
+ session_name TEXT,
101
+ start_time TEXT,
102
+ duration INTEGER,
103
+ participants TEXT,
104
+ content_id TEXT,
105
+ scheduled_time TEXT,
106
+ FOREIGN KEY (user_id) REFERENCES users (user_id)
107
+ )
108
+ ''')
109
+ c.execute('''
110
+ CREATE TABLE IF NOT EXISTS forum (
111
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
112
+ user_id TEXT,
113
+ message TEXT,
114
+ timestamp TEXT,
115
+ FOREIGN KEY (user_id) REFERENCES users (user_id)
116
+ )
117
+ ''')
118
+ conn.commit()
119
+ return conn
120
+
121
+ # Create file storage directory
122
+ os.makedirs('/content/files', exist_ok=True)
123
+
124
+ # Define supported languages
125
+ SUPPORTED_LANGUAGES = {
126
+ "Hindi": "hi",
127
+ "Tamil": "ta",
128
+ "Bengali": "bn",
129
+ "English": "en"
130
+ }
131
+
132
+ # Define learning paths
133
+ LEARNING_PATHS = {
134
+ "Vocational Skills": [
135
+ "Basic Communication",
136
+ "Technical Vocabulary",
137
+ "Practical Applications"
138
+ ],
139
+ "Exam Preparation": [
140
+ "Subject Terminology",
141
+ "Question Formats",
142
+ "Speed Learning Techniques"
143
+ ]
144
+ }
145
+
146
+ # Initialize models
147
+ sentence_model = SentenceTransformer('all-MiniLM-L6-v2')
148
+ translation_model_name = "Helsinki-NLP/opus-mt-en-hi"
149
+ translation_tokenizer = MarianTokenizer.from_pretrained(translation_model_name)
150
+ translation_model = MarianMTModel.from_pretrained(translation_model_name)
151
+ summarization_model = pipeline("summarization", model="facebook/bart-large-cnn")
152
+ sentiment_model = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english")
153
+ lesson_plan_model = pipeline("text2text-generation", model="t5-small")
154
+
155
+ # FAISS index for similarity search
156
+ dimension = 384
157
+ index = faiss.IndexFlatL2(dimension)
158
+
159
+ # Initialize database
160
+ conn = init_sqlite_db()
161
+
162
+ def preprocess_text(text):
163
+ text = re.sub(r'\s+', ' ', text).strip()
164
+ sentences = nltk.sent_tokenize(text)
165
+ return sentences
166
+
167
+ def translate_text(text, target_lang):
168
+ if target_lang not in SUPPORTED_LANGUAGES.values():
169
+ return text
170
+ model_name = f"Helsinki-NLP/opus-mt-en-{target_lang}"
171
+ try:
172
+ tokenizer = MarianTokenizer.from_pretrained(model_name)
173
+ model = MarianMTModel.from_pretrained(model_name)
174
+ inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
175
+ translated = model.generate(**inputs)
176
+ return tokenizer.batch_decode(translated, skip_special_tokens=True)[0]
177
+ except:
178
+ return text
179
+
180
+ def summarize_text(text, max_length=130, min_length=30):
181
+ try:
182
+ summary = summarization_model(text, max_length=max_length, min_length=min_length, do_sample=False)
183
+ return summary[0]['summary_text']
184
+ except:
185
+ return text[:max_length]
186
+
187
+ def generate_tts(text, language, output_file):
188
+ try:
189
+ tts = gTTS(text=text, lang=language, slow=False)
190
+ tts.save(output_file)
191
+ return output_file
192
+ except:
193
+ return None
194
+
195
+ def generate_pdf(content, output_file):
196
+ try:
197
+ c = canvas.Canvas(output_file, pagesize=letter)
198
+ c.drawString(100, 750, "Vernacular Learning Content")
199
+ y = 700
200
+ for line in content.split('\n'):
201
+ if y < 50:
202
+ c.showPage()
203
+ y = 750
204
+ c.drawString(100, y, line[:100])
205
+ y -= 15
206
+ c.save()
207
+ return output_file
208
+ except:
209
+ return None
210
+
211
+ def extract_text_from_pdf(pdf_file):
212
+ text = ""
213
+ try:
214
+ with pdfplumber.open(pdf_file) as pdf:
215
+ for page in pdf.pages:
216
+ text += page.extract_text() or ""
217
+ if not text.strip():
218
+ images = pdf2image.convert_from_path(pdf_file)
219
+ for image in images:
220
+ text += pytesseract.image_to_string(image)
221
+ except:
222
+ text = "Error extracting text from PDF."
223
+ return text
224
+
225
+ def extract_text_from_youtube(youtube_url):
226
+ try:
227
+ video_id = YouTube(youtube_url).video_id
228
+ transcript = YouTubeTranscriptApi.get_transcript(video_id)
229
+ text = " ".join([entry['text'] for entry in transcript])
230
+ return text
231
+ except:
232
+ return "Error extracting transcript."
233
+
234
+ def extract_text_from_url(url):
235
+ try:
236
+ response = requests.get(url)
237
+ soup = BeautifulSoup(response.content, 'html.parser')
238
+ paragraphs = soup.find_all('p')
239
+ text = " ".join([p.get_text() for p in paragraphs])
240
+ return text
241
+ except:
242
+ return "Error extracting text from URL."
243
+
244
+ def create_embedding(text):
245
+ sentences = preprocess_text(text)
246
+ embeddings = sentence_model.encode(sentences, convert_to_tensor=False)
247
+ return np.mean(embeddings, axis=0)
248
+
249
+ def store_embedding(source, embedding):
250
+ embedding = embedding.astype(np.float32)
251
+ index.add(np.array([embedding]))
252
+ conn = init_sqlite_db()
253
+ c = conn.cursor()
254
+ c.execute("INSERT INTO embeddings (source, embedding) VALUES (?, ?)",
255
+ (source, json.dumps(embedding.tolist())))
256
+ conn.commit()
257
+ conn.close()
258
+
259
+ def store_content(source, text, language, category, subcategory):
260
+ embedding = create_embedding(text)
261
+ store_embedding(source, embedding)
262
+ conn = init_sqlite_db()
263
+ c = conn.cursor()
264
+ c.execute("INSERT INTO content (source, text, language, category, subcategory, embedding) VALUES (?, ?, ?, ?, ?, ?)",
265
+ (source, text, language, category, subcategory, json.dumps(embedding.tolist())))
266
+ conn.commit()
267
+ conn.close()
268
+
269
+ def search_similar_content(query, top_k=3):
270
+ query_embedding = create_embedding(query).astype(np.float32)
271
+ distances, indices = index.search(np.array([query_embedding]), top_k)
272
+ conn = init_sqlite_db()
273
+ c = conn.cursor()
274
+ results = []
275
+ for idx in indices[0]:
276
+ c.execute("SELECT source, text, language, category, subcategory FROM content WHERE id = ?", (idx + 1,))
277
+ result = c.fetchone()
278
+ if result:
279
+ results.append(result)
280
+ conn.close()
281
+ return results
282
+
283
+ def generate_quiz(content, num_questions=3):
284
+ sentences = preprocess_text(content)
285
+ questions = []
286
+ for _ in range(min(num_questions, len(sentences))):
287
+ sentence = random.choice(sentences)
288
+ words = sentence.split()
289
+ if len(words) > 5:
290
+ answer = random.choice(words)
291
+ question = sentence.replace(answer, "____")
292
+ questions.append({"question": question, "answer": answer})
293
+ return questions
294
+
295
+ def evaluate_quiz(questions, answers):
296
+ score = 0
297
+ total = len(questions)
298
+ for i, q in enumerate(questions):
299
+ if i < len(answers) and answers[i].strip().lower() == q['answer'].lower():
300
+ score += 1
301
+ return score, total
302
+
303
+ def analyze_feedback(feedback_text):
304
+ sentiment = sentiment_model(feedback_text)[0]
305
+ return sentiment['label'], sentiment['score']
306
+
307
+ def store_user_feedback(user_id, feedback_text):
308
+ sentiment, score = analyze_feedback(feedback_text)
309
+ conn = init_sqlite_db()
310
+ c = conn.cursor()
311
+ c.execute("INSERT INTO feedback (user_id, text, sentiment, score) VALUES (?, ?, ?, ?)",
312
+ (user_id, feedback_text, sentiment, score))
313
+ conn.commit()
314
+ conn.close()
315
+ return sentiment, score
316
+
317
+ def create_user_profile(username, age, education_level, language_preference, learning_goal, learning_style):
318
+ user_id = str(uuid.uuid4())
319
+ conn = init_sqlite_db()
320
+ c = conn.cursor()
321
+ c.execute('''
322
+ INSERT OR REPLACE INTO users (user_id, username, age, education_level, language_preference, learning_goal, learning_style, progress, quiz_results, feedback)
323
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
324
+ ''', (user_id, username, age, education_level, language_preference, learning_goal, learning_style, json.dumps({}), json.dumps({}), json.dumps({})))
325
+ conn.commit()
326
+ conn.close()
327
+ return user_id
328
+
329
+ def update_user_progress(user_id, content_id, status):
330
+ conn = init_sqlite_db()
331
+ c = conn.cursor()
332
+ c.execute("SELECT progress FROM users WHERE user_id = ?", (user_id,))
333
+ progress = json.loads(c.fetchone()[0])
334
+ progress[content_id] = status
335
+ c.execute("UPDATE users SET progress = ? WHERE user_id = ?", (json.dumps(progress), user_id))
336
+ conn.commit()
337
+ conn.close()
338
+
339
+ def store_quiz_results(user_id, quiz_results):
340
+ conn = init_sqlite_db()
341
+ c = conn.cursor()
342
+ c.execute("SELECT quiz_results FROM users WHERE user_id = ?", (user_id,))
343
+ results = json.loads(c.fetchone()[0])
344
+ results[str(datetime.now())] = quiz_results
345
+ c.execute("UPDATE users SET quiz_results = ? WHERE user_id = ?", (json.dumps(results), user_id))
346
+ conn.commit()
347
+ conn.close()
348
+
349
+ def start_video_session(user_id, session_name, content_id, scheduled_time):
350
+ session_id = str(uuid.uuid4())
351
+ start_time = datetime.now().isoformat()
352
+ jitsi_url = f"https://meet.jit.si/{session_id}"
353
+ conn = init_sqlite_db()
354
+ c = conn.cursor()
355
+ c.execute('''
356
+ INSERT INTO video_sessions (session_id, user_id, session_name, start_time, duration, participants, content_id, scheduled_time)
357
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
358
+ ''', (session_id, user_id, session_name, start_time, 0, json.dumps([user_id]), content_id or "", scheduled_time or ""))
359
+ conn.commit()
360
+ conn.close()
361
+ return session_id, jitsi_url
362
+
363
+ def end_video_session(session_id):
364
+ conn = init_sqlite_db()
365
+ c = conn.cursor()
366
+ c.execute("SELECT start_time FROM video_sessions WHERE session_id = ?", (session_id,))
367
+ result = c.fetchone()
368
+ if result:
369
+ start_time = datetime.fromisoformat(result[0])
370
+ duration = int((datetime.now() - start_time).total_seconds() / 60)
371
+ c.execute("UPDATE video_sessions SET duration = ? WHERE session_id = ?", (duration, session_id))
372
+ conn.commit()
373
+ conn.close()
374
+
375
+ def generate_lesson_plan(topic, grade_level, objectives, language):
376
+ try:
377
+ prompt = f"Generate a lesson plan for {topic} for {grade_level} students with objectives: {objectives}. Include an introduction, activities, and assessment. Language: {language}."
378
+ result = lesson_plan_model(prompt, max_length=200, num_return_sequences=1)[0]['generated_text']
379
+ return translate_text(result, SUPPORTED_LANGUAGES.get(language, 'en'))
380
+ except:
381
+ return "Error generating lesson plan."
382
+
383
+ def generate_flashcards(content_id, num_cards=5):
384
+ conn = init_sqlite_db()
385
+ c = conn.cursor()
386
+ c.execute("SELECT text FROM content WHERE id = ?", (content_id,))
387
+ result = c.fetchone()
388
+ conn.close()
389
+ if not result:
390
+ return []
391
+ text = result[0]
392
+ vectorizer = TfidfVectorizer(stop_words='english')
393
+ tfidf_matrix = vectorizer.fit_transform([text])
394
+ feature_names = vectorizer.get_feature_names_out()
395
+ scores = tfidf_matrix.toarray()[0]
396
+ keywords = sorted(zip(feature_names, scores), key=lambda x: x[1], reverse=True)[:num_cards]
397
+ flashcards = [{"front": kw[0], "back": f"Key term in {text[:50]}..."} for kw in keywords]
398
+ return flashcards
399
+
400
+ def get_student_progress(user_id):
401
+ conn = init_sqlite_db()
402
+ c = conn.cursor()
403
+ c.execute("SELECT quiz_results FROM users WHERE user_id = ?", (user_id,))
404
+ result = c.fetchone()
405
+ conn.close()
406
+ if result:
407
+ quiz_results = json.loads(result[0])
408
+ scores = [r['score'] for r in quiz_results.values()]
409
+ totals = [r['total'] for r in quiz_results.values()]
410
+ return scores, totals
411
+ return [], []
412
+
413
+ def store_forum_message(user_id, message):
414
+ conn = init_sqlite_db()
415
+ c = conn.cursor()
416
+ timestamp = datetime.now().isoformat()
417
+ c.execute("INSERT INTO forum (user_id, message, timestamp) VALUES (?, ?, ?)",
418
+ (user_id, message, timestamp))
419
+ conn.commit()
420
+ conn.close()
421
+ return "Message posted."
422
+
423
+ def get_forum_messages():
424
+ conn = init_sqlite_db()
425
+ c = conn.cursor()
426
+ c.execute("SELECT u.username, f.message, f.timestamp FROM forum f JOIN users u ON f.user_id = u.user_id ORDER BY f.timestamp DESC LIMIT 20")
427
+ messages = c.fetchall()
428
+ conn.close()
429
+ return messages
430
+
431
+ def create_gradio_interface():
432
+ with gr.Blocks(theme='default') as interface:
433
+ gr.Markdown("# 🌍 Vernacular Learning Platform")
434
+ gr.Markdown("Interactive learning platform for teachers and rural students with enhanced video chat, offline content, and community forum")
435
+
436
+ with gr.Tabs():
437
+ with gr.Tab("User Guide"):
438
+ gr.Markdown("""
439
+ ### 📘 How to Use This Platform
440
+ Follow these steps to learn and make decisions:
441
+ 1. **User Profile**: Create your profile to personalize learning.
442
+ 2. **Content Upload**: Upload content, listen via TTS, or download as PDF for offline use.
443
+ 3. **Lesson Planning**: Teachers can generate lesson plans.
444
+ 4. **Student Progress**: Teachers can view quiz score visualizations.
445
+ 5. **Flashcards**: Students can learn key terms interactively.
446
+ 6. **Community Forum**: Discuss ideas and share insights.
447
+ 7. **Search Content**: Find similar content.
448
+ 8. **Take Quiz**: Test knowledge with quizzes.
449
+ 9. **Video Chat**: Schedule and join video sessions linked to content.
450
+ 10. **Feedback**: Provide feedback to improve the platform.
451
+
452
+ **Tips for Decision-Making**:
453
+ - Teachers: Use progress dashboards and lesson plans to tailor teaching, schedule video sessions for discussions.
454
+ - Students: Use flashcards, TTS, and forum to enhance learning, join video chats to clarify doubts.
455
+ """)
456
+
457
+ with gr.Tab("User Profile"):
458
+ username = gr.Textbox(label="Username")
459
+ age = gr.Slider(minimum=10, maximum=100, step=1, label="Age")
460
+ education_level = gr.Dropdown(choices=["High School", "Undergraduate", "Graduate", "Other"], label="Education Level")
461
+ language_preference = gr.Dropdown(choices=list(SUPPORTED_LANGUAGES.keys()), label="Language Preference")
462
+ learning_goal = gr.Dropdown(choices=list(LEARNING_PATHS.keys()), label="Learning Goal")
463
+ learning_style = gr.Dropdown(choices=["Visual", "Auditory", "Kinesthetic", "Reading/Writing"], label="Learning Style")
464
+ create_profile_button = gr.Button("Create/Update Profile")
465
+ profile_output = gr.Textbox(label="Profile Status")
466
+ create_profile_button.click(
467
+ fn=create_user_profile,
468
+ inputs=[username, age, education_level, language_preference, learning_goal, learning_style],
469
+ outputs=profile_output
470
+ )
471
+
472
+ with gr.Tab("Content Upload"):
473
+ content_type = gr.Radio(choices=["PDF", "YouTube", "URL"], label="Content Type", value="PDF")
474
+ pdf_input = gr.File(label="Upload PDF", visible=True)
475
+ url_input = gr.Textbox(label="Enter YouTube/URL", visible=False)
476
+ language = gr.Dropdown(choices=list(SUPPORTED_LANGUAGES.keys()), label="Target Language")
477
+ category = gr.Textbox(label="Category (e.g., Math, Science)")
478
+ subcategory = gr.Textbox(label="Subcategory (e.g., Algebra, Physics)")
479
+ process_button = gr.Button("Process Content")
480
+ tts_button = gr.Button("Listen to Content")
481
+ download_button = gr.Button("Download Content as PDF")
482
+ content_output = gr.Textbox(label="Content Processing Output", lines=10)
483
+ tts_output = gr.Audio(label="Content Audio")
484
+ download_output = gr.File(label="Download PDF")
485
+
486
+ def update_input_visibility(content_type):
487
+ return gr.update(visible=content_type == "PDF"), gr.update(visible=content_type != "PDF")
488
+
489
+ content_type.change(
490
+ fn=update_input_visibility,
491
+ inputs=content_type,
492
+ outputs=[pdf_input, url_input]
493
+ )
494
+
495
+ def process_content(content_type, pdf_input, url_input, language, category, subcategory):
496
+ if content_type == "PDF":
497
+ if not pdf_input:
498
+ return "Please upload a PDF file."
499
+ text = extract_text_from_pdf(pdf_input.name)
500
+ source = pdf_input.name
501
+ else:
502
+ if not url_input:
503
+ return "Please enter a YouTube or URL."
504
+ source = url_input
505
+ text = extract_text_from_youtube(url_input) if content_type == "YouTube" else extract_text_from_url(url_input)
506
+
507
+ if "Error" in text:
508
+ return text
509
+ translated_text = translate_text(text, SUPPORTED_LANGUAGES[language])
510
+ summary = summarize_text(translated_text)
511
+ store_content(source, translated_text, language, category, subcategory)
512
+ return f"Content processed:\nSummary: {summary}\nStored in database."
513
+
514
+ def generate_content_tts(content_output, language):
515
+ if not content_output or "Error" in content_output:
516
+ return None
517
+ summary = content_output.split("Summary: ")[-1].split("\n")[0]
518
+ output_file = f"/content/files/tts_{uuid.uuid4()}.mp3"
519
+ lang_code = SUPPORTED_LANGUAGES.get(language, 'en')
520
+ return generate_tts(summary, lang_code, output_file)
521
+
522
+ def download_content(content_output):
523
+ if not content_output or "Error" in content_output:
524
+ return None
525
+ output_file = f"/content/files/content_{uuid.uuid4()}.pdf"
526
+ return generate_pdf(content_output, output_file)
527
+
528
+ process_button.click(
529
+ fn=process_content,
530
+ inputs=[content_type, pdf_input, url_input, language, category, subcategory],
531
+ outputs=content_output
532
+ )
533
+ tts_button.click(
534
+ fn=generate_content_tts,
535
+ inputs=[content_output, language],
536
+ outputs=tts_output
537
+ )
538
+ download_button.click(
539
+ fn=download_content,
540
+ inputs=content_output,
541
+ outputs=download_output
542
+ )
543
+
544
+ with gr.Tab("Lesson Planning"):
545
+ topic = gr.Textbox(label="Topic (e.g., Fractions)")
546
+ grade_level = gr.Dropdown(choices=["1-5", "6-8", "9-12"], label="Grade Level")
547
+ objectives = gr.Textbox(label="Learning Objectives (e.g., Understand fraction addition)")
548
+ language_plan = gr.Dropdown(choices=list(SUPPORTED_LANGUAGES.keys()), label="Language")
549
+ generate_plan_button = gr.Button("Generate Lesson Plan")
550
+ plan_output = gr.Textbox(label="Lesson Plan", lines=10)
551
+ generate_plan_button.click(
552
+ fn=generate_lesson_plan,
553
+ inputs=[topic, grade_level, objectives, language_plan],
554
+ outputs=plan_output
555
+ )
556
+
557
+ with gr.Tab("Student Progress"):
558
+ user_id_progress = gr.Textbox(label="Student User ID")
559
+ fetch_progress_button = gr.Button("Fetch Progress")
560
+ progress_output = gr.Textbox(label="Quiz Results")
561
+ progress_chart = gr.JSON(label="Quiz Scores Chart")
562
+ def fetch_progress(user_id):
563
+ scores, totals = get_student_progress(user_id)
564
+ if not scores:
565
+ return "No quiz results found.", {}
566
+ result_text = "\n".join([f"Quiz {i+1}: {s}/{t}" for i, (s, t) in enumerate(zip(scores, totals))])
567
+ chart_data = {
568
+ "type": "bar",
569
+ "data": {
570
+ "labels": [f"Quiz {i+1}" for i in range(len(scores))],
571
+ "datasets": [{
572
+ "label": "Scores",
573
+ "data": scores,
574
+ "backgroundColor": "rgba(75, 192, 192, 0.2)",
575
+ "borderColor": "rgba(75, 192, 192, 1)",
576
+ "borderWidth": 1
577
+ }]
578
+ },
579
+ "options": {
580
+ "scales": {
581
+ "y": {
582
+ "beginAtZero": True,
583
+ "title": {"display": True, "text": "Score"}
584
+ },
585
+ "x": {
586
+ "title": {"display": True, "text": "Quiz"}
587
+ }
588
+ }
589
+ }
590
+ }
591
+ return result_text, chart_data
592
+ fetch_progress_button.click(
593
+ fn=fetch_progress,
594
+ inputs=user_id_progress,
595
+ outputs=[progress_output, progress_chart]
596
+ )
597
+
598
+ with gr.Tab("Flashcards"):
599
+ content_id_flash = gr.Textbox(label="Content ID")
600
+ num_cards = gr.Slider(minimum=1, maximum=10, step=1, value=5, label="Number of Flashcards")
601
+ generate_flashcards_button = gr.Button("Generate Flashcards")
602
+ flashcard_output = gr.HTML(label="Flashcards")
603
+ def display_flashcards(content_id, num_cards):
604
+ flashcards = generate_flashcards(content_id, num_cards)
605
+ if not flashcards:
606
+ return "Content not found or no flashcards generated."
607
+ html = "<div style='text-align: center;'>"
608
+ for i, card in enumerate(flashcards):
609
+ html += f"""
610
+ <div style='border: 1px solid #ccc; padding: 10px; margin: 10px; width: 200px; display: inline-block;'>
611
+ <h4>Card {i+1}</h4>
612
+ <p><strong>Front:</strong> {card['front']}</p>
613
+ <p><strong>Back:</strong> {card['back']}</p>
614
+ </div>
615
+ """
616
+ html += "</div>"
617
+ return html
618
+ generate_flashcards_button.click(
619
+ fn=display_flashcards,
620
+ inputs=[content_id_flash, num_cards],
621
+ outputs=flashcard_output
622
+ )
623
+
624
+ with gr.Tab("Community Forum"):
625
+ user_id_forum = gr.Textbox(label="User ID")
626
+ message = gr.Textbox(label="Message")
627
+ post_button = gr.Button("Post Message")
628
+ forum_output = gr.Textbox(label="Forum Messages", lines=10)
629
+ refresh_button = gr.Button("Refresh Forum")
630
+ def post_message(user_id, message):
631
+ return store_forum_message(user_id, message)
632
+ def display_forum():
633
+ messages = get_forum_messages()
634
+ return "\n".join([f"[{m[2]}] {m[0]}: {m[1]}" for m in messages])
635
+ post_button.click(
636
+ fn=post_message,
637
+ inputs=[user_id_forum, message],
638
+ outputs=forum_output
639
+ )
640
+ refresh_button.click(
641
+ fn=display_forum,
642
+ inputs=[],
643
+ outputs=forum_output
644
+ )
645
+
646
+ with gr.Tab("Search Content"):
647
+ search_query = gr.Textbox(label="Search Query")
648
+ search_button = gr.Button("Search")
649
+ search_output = gr.Textbox(label="Search Results", lines=10)
650
+ search_button.click(
651
+ fn=search_similar_content,
652
+ inputs=search_query,
653
+ outputs=search_output
654
+ )
655
+
656
+ with gr.Tab("Quiz"):
657
+ content_id = gr.Textbox(label="Content ID (from Content Upload)")
658
+ num_questions = gr.Slider(minimum=1, maximum=10, step=1, value=3, label="Number of Questions")
659
+ generate_quiz_button = gr.Button("Generate Quiz")
660
+ quiz_output = gr.Textbox(label="Quiz Questions", lines=10)
661
+ answers = gr.Textbox(label="Enter Answers (one per line)")
662
+ evaluate_quiz_button = gr.Button("Evaluate Quiz")
663
+ quiz_result = gr.Textbox(label="Quiz Results")
664
+ user_id_quiz = gr.Textbox(label="User ID")
665
+ def generate_quiz_action(content_id, num_questions):
666
+ conn = init_sqlite_db()
667
+ c = conn.cursor()
668
+ c.execute("SELECT text FROM content WHERE id = ?", (content_id,))
669
+ result = c.fetchone()
670
+ conn.close()
671
+ if result:
672
+ questions = generate_quiz(result[0], num_questions)
673
+ return json.dumps(questions), questions
674
+ return "Content not found.", []
675
+ generate_quiz_button.click(
676
+ fn=generate_quiz_action,
677
+ inputs=[content_id, num_questions],
678
+ outputs=[quiz_output, gr.State()]
679
+ )
680
+ def evaluate_quiz_action(questions, answers, user_id):
681
+ questions = json.loads(questions) if questions else []
682
+ answers = answers.split("\n")
683
+ score, total = evaluate_quiz(questions, answers)
684
+ store_quiz_results(user_id, {"score": score, "total": total})
685
+ return f"Score: {score}/{total}"
686
+ evaluate_quiz_button.click(
687
+ fn=evaluate_quiz_action,
688
+ inputs=[quiz_output, answers, user_id_quiz],
689
+ outputs=quiz_result
690
+ )
691
+
692
+ with gr.Tab("Video Chat"):
693
+ user_id_video = gr.Textbox(label="User ID")
694
+ session_name = gr.Textbox(label="Session Name", value="Learning Session")
695
+ content_id_video = gr.Textbox(label="Content ID (optional)")
696
+ scheduled_time = gr.Textbox(label="Scheduled Time (YYYY-MM-DD HH:MM, optional)", placeholder="e.g., 2025-05-25 14:00")
697
+ start_video_button = gr.Button("Start Video Session")
698
+ video_output = gr.HTML(label="Video Chat")
699
+ video_url = gr.Textbox(label="Video Chat URL")
700
+ end_video_button = gr.Button("End Video Session")
701
+ video_status = gr.Textbox(label="Video Session Status")
702
+ def start_video_action(user_id, session_name, content_id, scheduled_time):
703
+ if not user_id:
704
+ return "", "", "Please provide a valid User ID."
705
+ try:
706
+ if scheduled_time:
707
+ datetime.strptime(scheduled_time, "%Y-%m-%d %H:%M")
708
+ except ValueError:
709
+ return "", "", "Invalid scheduled time format. Use YYYY-MM-DD HH:MM."
710
+ session_id, jitsi_url = start_video_session(user_id, session_name, content_id, scheduled_time)
711
+ iframe = f'<iframe allow="camera; microphone" src="{jitsi_url}" width="800" height="600"></iframe>'
712
+ return iframe, jitsi_url, f"Video session started: {session_id}"
713
+ start_video_button.click(
714
+ fn=start_video_action,
715
+ inputs=[user_id_video, session_name, content_id_video, scheduled_time],
716
+ outputs=[video_output, video_url, video_status]
717
+ )
718
+ def end_video_action(session_id):
719
+ end_video_session(session_id)
720
+ return "Video session ended."
721
+ end_video_button.click(
722
+ fn=end_video_action,
723
+ inputs=video_status,
724
+ outputs=video_status
725
+ )
726
+
727
+ with gr.Tab("Feedback"):
728
+ user_id_feedback = gr.Textbox(label="User ID")
729
+ feedback_text = gr.Textbox(label="Feedback")
730
+ submit_feedback_button = gr.Button("Submit Feedback")
731
+ feedback_output = gr.Textbox(label="Feedback Analysis")
732
+ submit_feedback_button.click(
733
+ fn=store_user_feedback,
734
+ inputs=[user_id_feedback, feedback_text],
735
+ outputs=feedback_output
736
+ )
737
+
738
+ return interface
739
+
740
+ if __name__ == "__main__":
741
+ interface = create_gradio_interface()
742
+ interface.launch(server_name="0.0.0.0", server_port=7860)