Sayiqa commited on
Commit
d515772
Β·
verified Β·
1 Parent(s): 00ec342

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +247 -405
app.py CHANGED
@@ -130,366 +130,146 @@ import re
130
  from collections import Counter
131
  from googleapiclient.discovery import build
132
 
133
- # def process_youtube_video(url="", keywords=""):
134
- # try:
135
- # #Initialize variables
136
- # thumbnail = None
137
- # summary = "No transcript available"
138
- # sentiment_label = "N/A"
139
- # recommendations = ""
140
- # subtitle_info = "No additional information available"
141
-
142
- # if not url.strip():
143
- # return None, "Please enter a YouTube URL", "N/A", "", ""
144
-
145
- # video_id = extract_video_id(url)
146
- # if not video_id:
147
- # return None, "Invalid YouTube URL", "N/A", "", ""
148
-
149
- # thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
150
-
151
- # try:
152
- # # Fetch transcript
153
- # transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
154
- # transcript = None
155
- # try:
156
- # transcript = transcript_list.find_transcript(['en'])
157
- # except:
158
- # transcript = transcript_list.find_generated_transcript(['en'])
159
-
160
- # text = " ".join([t['text'] for t in transcript.fetch()])
161
- # if not text.strip():
162
- # raise ValueError("Transcript is empty")
163
-
164
- # # Clean up the text for sentiment analysis
165
- # cleaned_text = clean_text_for_analysis(text)
166
-
167
- # # Sentiment analysis
168
- # sentiment = TextBlob(cleaned_text).sentiment # Use cleaned text for sentiment analysis
169
- # sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
170
-
171
- # # Generate summary
172
- # model = genai.GenerativeModel("gemini-pro")
173
- # summary = model.generate_content(f"Summarize this: {cleaned_text[:4000]}").text
174
-
175
- # # Extract subtitle information
176
- # subtitle_info = extract_subtitle_info(cleaned_text)
177
-
178
- # except TranscriptsDisabled:
179
- # metadata = get_video_metadata(video_id)
180
- # summary = metadata.get("description", "⚠️ This video has disabled subtitles.")
181
- # sentiment_label = "N/A"
182
- # subtitle_info = "No subtitles available for analysis."
183
- # except NoTranscriptFound:
184
- # metadata = get_video_metadata(video_id)
185
- # summary = metadata.get("description", "⚠️ No English transcript available.")
186
- # sentiment_label = "N/A"
187
- # subtitle_info = "No subtitles available for analysis."
188
- # except Exception as e:
189
- # return thumbnail, f"⚠️ Error processing transcript: {str(e)}", "N/A", "", ""
190
-
191
- # # Get recommendations
192
- # if keywords.strip():
193
- # recommendations = get_recommendations(keywords)
194
-
195
- # return thumbnail, summary, sentiment_label, subtitle_info, recommendations
196
-
197
- # except Exception as e:
198
- # return None, f"Error: {str(e)}", "N/A", "", ""
199
 
 
 
200
 
201
- # def extract_video_id(url):
202
- # """
203
- # Extracts the video ID from a YouTube URL.
204
- # """
205
- # match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11})", url)
206
- # return match.group(1) if match else None
207
-
208
-
209
- # def get_video_metadata(video_id):
210
- # """
211
- # Fetches video metadata such as title and description using the YouTube Data API.
212
- # """
213
- # try:
214
- # YOUTUBE_API_KEY = "AIzaSyD_SDF4lC3vpHVAMnBOcN2ZCTz7dRjUc98" # Replace with your YouTube Data API key
215
- # youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
216
- # request = youtube.videos().list(part="snippet", id=video_id)
217
- # response = request.execute()
218
-
219
- # if "items" in response and len(response["items"]) > 0:
220
- # snippet = response["items"][0]["snippet"]
221
- # return {
222
- # "title": snippet.get("title", "No title available"),
223
- # "description": snippet.get("description", "No description available"),
224
- # }
225
- # return {}
226
-
227
- # except Exception as e:
228
- # return {"title": "Error fetching metadata", "description": str(e)}
229
-
230
-
231
- # def extract_subtitle_info(text):
232
- # """
233
- # Extracts meaningful information from the subtitles.
234
- # This could include topics, key insights, or a breakdown of the content.
235
- # """
236
- # try:
237
- # # Split text into sentences for better analysis
238
- # sentences = text.split(". ")
239
-
240
- # # Example: Extract key topics or keywords
241
- # words = text.split()
242
- # common_words = Counter(words).most_common(10)
243
- # key_topics = ", ".join([word for word, count in common_words])
244
-
245
- # # Example: Provide a breakdown of the content
246
- # info = f"Key topics discussed: {key_topics}. \nNumber of sentences: {len(sentences)}. \nTotal words: {len(words)}."
247
-
248
- # return info
249
- # except Exception as e:
250
- # return f"Error extracting subtitle information: {str(e)}"
251
-
252
-
253
- # def clean_text_for_analysis(text):
254
- # """
255
- # Cleans the transcript text by removing extra spaces, line breaks, and non-text elements.
256
- # """
257
- # # Remove extra spaces and line breaks
258
- # cleaned_text = " ".join(text.split())
259
- # return cleaned_text
260
-
261
-
262
- # def get_recommendations(keywords):
263
- # """
264
- # Fetches related video recommendations based on the provided keywords.
265
- # This function can be expanded with a proper API or custom logic.
266
- # """
267
- # # Placeholder for fetching recommendations based on keywords
268
- # return f"Recommendations for: {keywords}" # Dummy return for now
269
-
270
-
271
- # def get_recommendations(keywords, max_results=5):
272
- # if not keywords:
273
- # return "Please provide search keywords"
274
- # try:
275
- # response = requests.get(
276
- # "https://www.googleapis.com/youtube/v3/search",
277
- # params={
278
- # "part": "snippet",
279
- # "q": f"educational {keywords}",
280
- # "type": "video",
281
- # "maxResults": max_results,
282
- # "relevanceLanguage": "en",
283
- # "key": YOUTUBE_API_KEY
284
- # }
285
- # ).json()
286
-
287
- # results = []
288
- # for item in response.get("items", []):
289
- # title = item["snippet"]["title"]
290
- # channel = item["snippet"]["channelTitle"]
291
- # video_id = item["id"]["videoId"]
292
- # results.append(f"πŸ“Ί {title}\nπŸ‘€ {channel}\nπŸ”— https://youtube.com/watch?v={video_id}\n")
293
-
294
- # return "\n".join(results) if results else "No recommendations found"
295
- # except Exception as e:
296
- # return f"Error: {str(e)}"
297
-
298
- # # Gradio Interface
299
- # with gr.Blocks(theme=gr.themes.Soft()) as app:
300
- # # Login Page
301
- # with gr.Group() as login_page:
302
- # gr.Markdown("# πŸŽ“ Educational Learning Management System")
303
- # username = gr.Textbox(label="Username")
304
- # password = gr.Textbox(label="Password", type="password")
305
- # login_btn = gr.Button("Login", variant="primary")
306
- # login_msg = gr.Markdown()
307
-
308
- # # Main Interface
309
- # with gr.Group(visible=False) as main_page:
310
- # with gr.Row():
311
- # with gr.Column(scale=1):
312
- # gr.Markdown("### πŸ“‹ Navigation")
313
- # nav_dashboard = gr.Button("πŸ“Š Dashboard", variant="primary")
314
- # nav_students = gr.Button("πŸ‘₯ Students")
315
- # nav_teachers = gr.Button("πŸ‘¨β€πŸ« Teachers")
316
- # nav_courses = gr.Button("πŸ“š Courses")
317
- # nav_youtube = gr.Button("πŸŽ₯ YouTube Tool")
318
- # logout_btn = gr.Button("πŸšͺ Logout", variant="stop")
319
-
320
- # with gr.Column(scale=3):
321
- # # Dashboard Content
322
- # dashboard_page = gr.Group()
323
- # with dashboard_page:
324
- # gr.Markdown("## πŸ“Š Dashboard")
325
- # gr.Markdown(f"""
326
- # ### System Overview
327
- # - πŸ‘₯ Total Students: {len(students_data)}
328
- # - πŸ‘¨β€πŸ« Total Teachers: {len(teachers_data)}
329
- # - πŸ“š Total Courses: {len(courses_data)}
330
-
331
- # ### Quick Actions
332
- # - View student performance
333
- # - Access course materials
334
- # - Generate learning insights
335
- # """)
336
-
337
- # # Students Content
338
- # students_page = gr.Group(visible=False)
339
- # with students_page:
340
- # gr.Markdown("## πŸ‘₯ Students")
341
- # gr.DataFrame(
342
- # value=students_data,
343
- # headers=["ID", "Name", "Grade", "Program"]
344
- # )
345
-
346
- # # Teachers Content
347
- # teachers_page = gr.Group(visible=False)
348
- # with teachers_page:
349
- # gr.Markdown("## πŸ‘¨β€πŸ« Teachers")
350
- # gr.DataFrame(
351
- # value=teachers_data,
352
- # headers=["ID", "Name", "Subject", "Qualification"]
353
- # )
354
-
355
- # # Courses Content
356
- # courses_page = gr.Group(visible=False)
357
- # with courses_page:
358
- # gr.Markdown("## πŸ“š Courses")
359
- # gr.DataFrame(
360
- # value=courses_data,
361
- # headers=["ID", "Name", "Instructor", "Level"]
362
- # )
363
-
364
- # # YouTube Tool Content
365
- # youtube_page = gr.Group(visible=False)
366
- # with youtube_page:
367
- # gr.Markdown("## Agent for YouTube Content Exploration")
368
- # with gr.Row():
369
- # with gr.Column(scale=2):
370
- # video_url = gr.Textbox(
371
- # label="YouTube URL",
372
- # placeholder="https://youtube.com/watch?v=..."
373
- # )
374
- # keywords = gr.Textbox(
375
- # label="Keywords for Recommendations",
376
- # placeholder="e.g., python programming, machine learning"
377
- # )
378
- # analyze_btn = gr.Button("πŸ” Analyze Video", variant="primary")
379
-
380
- # with gr.Column(scale=1):
381
- # video_thumbnail = gr.Image(label="Video Preview")
382
-
383
- # with gr.Row():
384
- # with gr.Column():
385
- # summary = gr.Textbox(label="πŸ“ Summary", lines=8)
386
- # sentiment = gr.Textbox(label="😊 Content Sentiment")
387
- # with gr.Column():
388
- # recommendations = gr.Textbox(label="🎯 Related Videos", lines=10)
389
-
390
- # def login_check(user, pwd):
391
- # if USER_CREDENTIALS.get(user) == pwd:
392
- # return {
393
- # login_page: gr.update(visible=False),
394
- # main_page: gr.update(visible=True),
395
- # login_msg: ""
396
- # }
397
- # return {
398
- # login_page: gr.update(visible=True),
399
- # main_page: gr.update(visible=False),
400
- # login_msg: "❌ Invalid credentials"
401
- # }
402
-
403
- # def show_page(page_name):
404
- # updates = {
405
- # dashboard_page: gr.update(visible=False),
406
- # students_page: gr.update(visible=False),
407
- # teachers_page: gr.update(visible=False),
408
- # courses_page: gr.update(visible=False),
409
- # youtube_page: gr.update(visible=False)
410
- # }
411
- # updates[page_name] = gr.update(visible=True)
412
- # return updates
413
-
414
- # # Event Handlers
415
- # login_btn.click(
416
- # login_check,
417
- # inputs=[username, password],
418
- # outputs=[login_page, main_page, login_msg]
419
- # )
420
-
421
- # nav_dashboard.click(lambda: show_page(dashboard_page), outputs=list(show_page(dashboard_page).keys()))
422
- # nav_students.click(lambda: show_page(students_page), outputs=list(show_page(students_page).keys()))
423
- # nav_teachers.click(lambda: show_page(teachers_page), outputs=list(show_page(teachers_page).keys()))
424
- # nav_courses.click(lambda: show_page(courses_page), outputs=list(show_page(courses_page).keys()))
425
- # nav_youtube.click(lambda: show_page(youtube_page), outputs=list(show_page(youtube_page).keys()))
426
-
427
- # analyze_btn.click(
428
- # process_youtube_video,
429
- # inputs=[video_url, keywords],
430
- # outputs=[video_thumbnail, summary, sentiment, recommendations]
431
- # )
432
-
433
- # logout_btn.click(
434
- # lambda: {
435
- # login_page: gr.update(visible=True),
436
- # main_page: gr.update(visible=False)
437
- # },
438
- # outputs=[login_page, main_page]
439
- # )
440
 
441
- # if __name__ == "__main__":
442
- # app.launch()
443
 
 
 
 
 
 
 
 
 
444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
 
446
- #############################
447
- import requests
448
- from textblob import TextBlob
449
- from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
450
- import gradio as gr
451
 
452
- # Helper Functions
453
  def extract_video_id(url):
454
- import re
 
 
455
  match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11})", url)
456
  return match.group(1) if match else None
457
 
458
- def clean_text_for_analysis(text):
459
- import re
460
- return re.sub(r"[^a-zA-Z0-9\s]", "", text)
461
-
462
- def extract_subtitle_info(cleaned_text):
463
- from collections import Counter
464
- words = cleaned_text.split()
465
- common_words = Counter(words).most_common(5)
466
- return f"Most common words: {', '.join([word for word, _ in common_words])}"
467
 
468
  def get_video_metadata(video_id):
469
- YOUTUBE_API_KEY = "YOUR_YOUTUBE_API_KEY"
 
 
470
  try:
471
- response = requests.get(
472
- f"https://www.googleapis.com/youtube/v3/videos",
473
- params={
474
- "part": "snippet",
475
- "id": video_id,
476
- "key": YOUTUBE_API_KEY
477
- }
478
- ).json()
479
- if "items" in response and response["items"]:
480
  snippet = response["items"][0]["snippet"]
481
  return {
482
- "title": snippet.get("title", "N/A"),
483
- "description": snippet.get("description", "N/A"),
484
- "channelTitle": snippet.get("channelTitle", "N/A")
485
  }
486
  return {}
 
487
  except Exception as e:
488
- return {"error": str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
 
490
  def get_recommendations(keywords, max_results=5):
491
- YOUTUBE_API_KEY = "YOUR_YOUTUBE_API_KEY"
492
- if not keywords.strip():
493
  return "Please provide search keywords"
494
  try:
495
  response = requests.get(
@@ -503,103 +283,165 @@ def get_recommendations(keywords, max_results=5):
503
  "key": YOUTUBE_API_KEY
504
  }
505
  ).json()
506
-
507
  results = []
508
  for item in response.get("items", []):
509
  title = item["snippet"]["title"]
510
  channel = item["snippet"]["channelTitle"]
511
  video_id = item["id"]["videoId"]
512
  results.append(f"πŸ“Ί {title}\nπŸ‘€ {channel}\nπŸ”— https://youtube.com/watch?v={video_id}\n")
513
-
514
  return "\n".join(results) if results else "No recommendations found"
515
  except Exception as e:
516
  return f"Error: {str(e)}"
517
 
518
- def process_youtube_video(url):
519
- try:
520
- video_id = extract_video_id(url)
521
- if not video_id:
522
- return None, "Invalid YouTube URL", "N/A", "", ""
523
-
524
- thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
525
-
526
- try:
527
- transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
528
- transcript = None
529
- try:
530
- transcript = transcript_list.find_transcript(['en'])
531
- except:
532
- transcript = transcript_list.find_generated_transcript(['en'])
533
-
534
- text = " ".join([t['text'] for t in transcript.fetch()])
535
- cleaned_text = clean_text_for_analysis(text)
536
-
537
- sentiment = TextBlob(cleaned_text).sentiment
538
- sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
539
- summary = f"Summary: {cleaned_text[:400]}..."
540
- subtitle_info = extract_subtitle_info(cleaned_text)
541
-
542
- return thumbnail, summary, sentiment_label, subtitle_info
543
- except TranscriptsDisabled:
544
- metadata = get_video_metadata(video_id)
545
- return thumbnail, metadata.get("description", "No transcript available"), "N/A", "No subtitles available"
546
- except NoTranscriptFound:
547
- metadata = get_video_metadata(video_id)
548
- return thumbnail, metadata.get("description", "No transcript available"), "N/A", "No subtitles available"
549
- except Exception as e:
550
- return None, f"Error: {str(e)}", "N/A", ""
551
-
552
- def fetch_recommendations(keywords):
553
- return get_recommendations(keywords)
554
-
555
- # User credentials
556
- USER_CREDENTIALS = {
557
- "admin": "admin"
558
- }
559
-
560
  # Gradio Interface
561
  with gr.Blocks(theme=gr.themes.Soft()) as app:
 
562
  with gr.Group() as login_page:
563
  gr.Markdown("# πŸŽ“ Educational Learning Management System")
564
  username = gr.Textbox(label="Username")
565
  password = gr.Textbox(label="Password", type="password")
566
  login_btn = gr.Button("Login", variant="primary")
567
  login_msg = gr.Markdown()
568
-
 
569
  with gr.Group(visible=False) as main_page:
570
  with gr.Row():
571
  with gr.Column(scale=1):
572
  gr.Markdown("### πŸ“‹ Navigation")
 
 
 
 
573
  nav_youtube = gr.Button("πŸŽ₯ YouTube Tool")
574
  logout_btn = gr.Button("πŸšͺ Logout", variant="stop")
575
-
576
  with gr.Column(scale=3):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  youtube_page = gr.Group(visible=False)
578
  with youtube_page:
579
  gr.Markdown("## Agent for YouTube Content Exploration")
580
- video_url = gr.Textbox(label="YouTube URL", placeholder="https://youtube.com/watch?v=...")
581
- keywords = gr.Textbox(label="Keywords for Recommendations", placeholder="e.g., python programming")
582
- analyze_btn = gr.Button("πŸ” Analyze Video", variant="primary")
583
- recommend_btn = gr.Button("πŸ” Get Recommendations", variant="secondary")
584
- video_thumbnail = gr.Image(label="Video Preview")
585
- summary = gr.Textbox(label="πŸ“ Summary", lines=8)
586
- sentiment = gr.Textbox(label="😊 Content Sentiment")
587
- subtitle_info = gr.Textbox(label="πŸ“œ Subtitle Info")
588
- recommendations = gr.Textbox(label="🎯 Related Videos", lines=10)
 
 
 
 
 
 
 
 
 
 
 
 
589
 
590
  def login_check(user, pwd):
591
  if USER_CREDENTIALS.get(user) == pwd:
592
- return {login_page: gr.update(visible=False), main_page: gr.update(visible=True), login_msg: ""}
593
- return {login_page: gr.update(visible=True), main_page: gr.update(visible=False), login_msg: "❌ Invalid credentials"}
594
-
595
- def show_youtube_page():
596
- return {youtube_page: gr.update(visible=True)}
597
-
598
- login_btn.click(login_check, inputs=[username, password], outputs=[login_page, main_page, login_msg])
599
- nav_youtube.click(show_youtube_page, outputs=[youtube_page])
600
- analyze_btn.click(process_youtube_video, inputs=[video_url], outputs=[video_thumbnail, summary, sentiment, subtitle_info])
601
- recommend_btn.click(fetch_recommendations, inputs=[keywords], outputs=[recommendations])
602
- logout_btn.click(lambda: {login_page: gr.update(visible=True), main_page: gr.update(visible=False)}, outputs=[login_page, main_page])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
603
 
604
  if __name__ == "__main__":
605
  app.launch()
 
 
 
 
 
 
130
  from collections import Counter
131
  from googleapiclient.discovery import build
132
 
133
+ def process_youtube_video(url="", keywords=""):
134
+ try:
135
+ #Initialize variables
136
+ thumbnail = None
137
+ summary = "No transcript available"
138
+ sentiment_label = "N/A"
139
+ recommendations = ""
140
+ subtitle_info = "No additional information available"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
+ if not url.strip():
143
+ return None, "Please enter a YouTube URL", "N/A", "", ""
144
 
145
+ video_id = extract_video_id(url)
146
+ if not video_id:
147
+ return None, "Invalid YouTube URL", "N/A", "", ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
+ thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
 
150
 
151
+ try:
152
+ # Fetch transcript
153
+ transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
154
+ transcript = None
155
+ try:
156
+ transcript = transcript_list.find_transcript(['en'])
157
+ except:
158
+ transcript = transcript_list.find_generated_transcript(['en'])
159
 
160
+ text = " ".join([t['text'] for t in transcript.fetch()])
161
+ if not text.strip():
162
+ raise ValueError("Transcript is empty")
163
+
164
+ # Clean up the text for sentiment analysis
165
+ cleaned_text = clean_text_for_analysis(text)
166
+
167
+ # Sentiment analysis
168
+ sentiment = TextBlob(cleaned_text).sentiment # Use cleaned text for sentiment analysis
169
+ sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
170
+
171
+ # Generate summary
172
+ model = genai.GenerativeModel("gemini-pro")
173
+ summary = model.generate_content(f"Summarize this: {cleaned_text[:4000]}").text
174
+
175
+ # Extract subtitle information
176
+ subtitle_info = extract_subtitle_info(cleaned_text)
177
+
178
+ except TranscriptsDisabled:
179
+ metadata = get_video_metadata(video_id)
180
+ summary = metadata.get("description", "⚠️ This video has disabled subtitles.")
181
+ sentiment_label = "N/A"
182
+ subtitle_info = "No subtitles available for analysis."
183
+ except NoTranscriptFound:
184
+ metadata = get_video_metadata(video_id)
185
+ summary = metadata.get("description", "⚠️ No English transcript available.")
186
+ sentiment_label = "N/A"
187
+ subtitle_info = "No subtitles available for analysis."
188
+ except Exception as e:
189
+ return thumbnail, f"⚠️ Error processing transcript: {str(e)}", "N/A", "", ""
190
+
191
+ # Get recommendations
192
+ if keywords.strip():
193
+ recommendations = get_recommendations(keywords)
194
+
195
+ return thumbnail, summary, sentiment_label, subtitle_info, recommendations
196
+
197
+ except Exception as e:
198
+ return None, f"Error: {str(e)}", "N/A", "", ""
199
 
 
 
 
 
 
200
 
 
201
  def extract_video_id(url):
202
+ """
203
+ Extracts the video ID from a YouTube URL.
204
+ """
205
  match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11})", url)
206
  return match.group(1) if match else None
207
 
 
 
 
 
 
 
 
 
 
208
 
209
  def get_video_metadata(video_id):
210
+ """
211
+ Fetches video metadata such as title and description using the YouTube Data API.
212
+ """
213
  try:
214
+ YOUTUBE_API_KEY = "AIzaSyD_SDF4lC3vpHVAMnBOcN2ZCTz7dRjUc98" # Replace with your YouTube Data API key
215
+ youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
216
+ request = youtube.videos().list(part="snippet", id=video_id)
217
+ response = request.execute()
218
+
219
+ if "items" in response and len(response["items"]) > 0:
 
 
 
220
  snippet = response["items"][0]["snippet"]
221
  return {
222
+ "title": snippet.get("title", "No title available"),
223
+ "description": snippet.get("description", "No description available"),
 
224
  }
225
  return {}
226
+
227
  except Exception as e:
228
+ return {"title": "Error fetching metadata", "description": str(e)}
229
+
230
+
231
+ def extract_subtitle_info(text):
232
+ """
233
+ Extracts meaningful information from the subtitles.
234
+ This could include topics, key insights, or a breakdown of the content.
235
+ """
236
+ try:
237
+ # Split text into sentences for better analysis
238
+ sentences = text.split(". ")
239
+
240
+ # Example: Extract key topics or keywords
241
+ words = text.split()
242
+ common_words = Counter(words).most_common(10)
243
+ key_topics = ", ".join([word for word, count in common_words])
244
+
245
+ # Example: Provide a breakdown of the content
246
+ info = f"Key topics discussed: {key_topics}. \nNumber of sentences: {len(sentences)}. \nTotal words: {len(words)}."
247
+
248
+ return info
249
+ except Exception as e:
250
+ return f"Error extracting subtitle information: {str(e)}"
251
+
252
+
253
+ def clean_text_for_analysis(text):
254
+ """
255
+ Cleans the transcript text by removing extra spaces, line breaks, and non-text elements.
256
+ """
257
+ # Remove extra spaces and line breaks
258
+ cleaned_text = " ".join(text.split())
259
+ return cleaned_text
260
+
261
+
262
+ def get_recommendations(keywords):
263
+ """
264
+ Fetches related video recommendations based on the provided keywords.
265
+ This function can be expanded with a proper API or custom logic.
266
+ """
267
+ # Placeholder for fetching recommendations based on keywords
268
+ return f"Recommendations for: {keywords}" # Dummy return for now
269
+
270
 
271
  def get_recommendations(keywords, max_results=5):
272
+ if not keywords:
 
273
  return "Please provide search keywords"
274
  try:
275
  response = requests.get(
 
283
  "key": YOUTUBE_API_KEY
284
  }
285
  ).json()
286
+
287
  results = []
288
  for item in response.get("items", []):
289
  title = item["snippet"]["title"]
290
  channel = item["snippet"]["channelTitle"]
291
  video_id = item["id"]["videoId"]
292
  results.append(f"πŸ“Ί {title}\nπŸ‘€ {channel}\nπŸ”— https://youtube.com/watch?v={video_id}\n")
293
+
294
  return "\n".join(results) if results else "No recommendations found"
295
  except Exception as e:
296
  return f"Error: {str(e)}"
297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  # Gradio Interface
299
  with gr.Blocks(theme=gr.themes.Soft()) as app:
300
+ # Login Page
301
  with gr.Group() as login_page:
302
  gr.Markdown("# πŸŽ“ Educational Learning Management System")
303
  username = gr.Textbox(label="Username")
304
  password = gr.Textbox(label="Password", type="password")
305
  login_btn = gr.Button("Login", variant="primary")
306
  login_msg = gr.Markdown()
307
+
308
+ # Main Interface
309
  with gr.Group(visible=False) as main_page:
310
  with gr.Row():
311
  with gr.Column(scale=1):
312
  gr.Markdown("### πŸ“‹ Navigation")
313
+ nav_dashboard = gr.Button("πŸ“Š Dashboard", variant="primary")
314
+ nav_students = gr.Button("πŸ‘₯ Students")
315
+ nav_teachers = gr.Button("πŸ‘¨β€πŸ« Teachers")
316
+ nav_courses = gr.Button("πŸ“š Courses")
317
  nav_youtube = gr.Button("πŸŽ₯ YouTube Tool")
318
  logout_btn = gr.Button("πŸšͺ Logout", variant="stop")
319
+
320
  with gr.Column(scale=3):
321
+ # Dashboard Content
322
+ dashboard_page = gr.Group()
323
+ with dashboard_page:
324
+ gr.Markdown("## πŸ“Š Dashboard")
325
+ gr.Markdown(f"""
326
+ ### System Overview
327
+ - πŸ‘₯ Total Students: {len(students_data)}
328
+ - πŸ‘¨β€πŸ« Total Teachers: {len(teachers_data)}
329
+ - πŸ“š Total Courses: {len(courses_data)}
330
+
331
+ ### Quick Actions
332
+ - View student performance
333
+ - Access course materials
334
+ - Generate learning insights
335
+ """)
336
+
337
+ # Students Content
338
+ students_page = gr.Group(visible=False)
339
+ with students_page:
340
+ gr.Markdown("## πŸ‘₯ Students")
341
+ gr.DataFrame(
342
+ value=students_data,
343
+ headers=["ID", "Name", "Grade", "Program"]
344
+ )
345
+
346
+ # Teachers Content
347
+ teachers_page = gr.Group(visible=False)
348
+ with teachers_page:
349
+ gr.Markdown("## πŸ‘¨β€πŸ« Teachers")
350
+ gr.DataFrame(
351
+ value=teachers_data,
352
+ headers=["ID", "Name", "Subject", "Qualification"]
353
+ )
354
+
355
+ # Courses Content
356
+ courses_page = gr.Group(visible=False)
357
+ with courses_page:
358
+ gr.Markdown("## πŸ“š Courses")
359
+ gr.DataFrame(
360
+ value=courses_data,
361
+ headers=["ID", "Name", "Instructor", "Level"]
362
+ )
363
+
364
+ # YouTube Tool Content
365
  youtube_page = gr.Group(visible=False)
366
  with youtube_page:
367
  gr.Markdown("## Agent for YouTube Content Exploration")
368
+ with gr.Row():
369
+ with gr.Column(scale=2):
370
+ video_url = gr.Textbox(
371
+ label="YouTube URL",
372
+ placeholder="https://youtube.com/watch?v=..."
373
+ )
374
+ keywords = gr.Textbox(
375
+ label="Keywords for Recommendations",
376
+ placeholder="e.g., python programming, machine learning"
377
+ )
378
+ analyze_btn = gr.Button("πŸ” Analyze Video", variant="primary")
379
+
380
+ with gr.Column(scale=1):
381
+ video_thumbnail = gr.Image(label="Video Preview")
382
+
383
+ with gr.Row():
384
+ with gr.Column():
385
+ summary = gr.Textbox(label="πŸ“ Summary", lines=8)
386
+ sentiment = gr.Textbox(label="😊 Content Sentiment")
387
+ with gr.Column():
388
+ recommendations = gr.Textbox(label="🎯 Related Videos", lines=10)
389
 
390
  def login_check(user, pwd):
391
  if USER_CREDENTIALS.get(user) == pwd:
392
+ return {
393
+ login_page: gr.update(visible=False),
394
+ main_page: gr.update(visible=True),
395
+ login_msg: ""
396
+ }
397
+ return {
398
+ login_page: gr.update(visible=True),
399
+ main_page: gr.update(visible=False),
400
+ login_msg: "❌ Invalid credentials"
401
+ }
402
+
403
+ def show_page(page_name):
404
+ updates = {
405
+ dashboard_page: gr.update(visible=False),
406
+ students_page: gr.update(visible=False),
407
+ teachers_page: gr.update(visible=False),
408
+ courses_page: gr.update(visible=False),
409
+ youtube_page: gr.update(visible=False)
410
+ }
411
+ updates[page_name] = gr.update(visible=True)
412
+ return updates
413
+
414
+ # Event Handlers
415
+ login_btn.click(
416
+ login_check,
417
+ inputs=[username, password],
418
+ outputs=[login_page, main_page, login_msg]
419
+ )
420
+
421
+ nav_dashboard.click(lambda: show_page(dashboard_page), outputs=list(show_page(dashboard_page).keys()))
422
+ nav_students.click(lambda: show_page(students_page), outputs=list(show_page(students_page).keys()))
423
+ nav_teachers.click(lambda: show_page(teachers_page), outputs=list(show_page(teachers_page).keys()))
424
+ nav_courses.click(lambda: show_page(courses_page), outputs=list(show_page(courses_page).keys()))
425
+ nav_youtube.click(lambda: show_page(youtube_page), outputs=list(show_page(youtube_page).keys()))
426
+
427
+ analyze_btn.click(
428
+ process_youtube_video,
429
+ inputs=[video_url, keywords],
430
+ outputs=[video_thumbnail, summary, sentiment, recommendations]
431
+ )
432
+
433
+ logout_btn.click(
434
+ lambda: {
435
+ login_page: gr.update(visible=True),
436
+ main_page: gr.update(visible=False)
437
+ },
438
+ outputs=[login_page, main_page]
439
+ )
440
 
441
  if __name__ == "__main__":
442
  app.launch()
443
+
444
+
445
+
446
+ #############################
447
+