Sayiqa commited on
Commit
30815b9
·
verified ·
1 Parent(s): cbb5aa1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -94
app.py CHANGED
@@ -444,33 +444,91 @@ from googleapiclient.discovery import build
444
 
445
 
446
  #############################
447
- import gradio as gr
448
- from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
449
- from textblob import TextBlob
450
  import requests
451
- import re
 
 
452
 
453
  # Helper Functions
454
  def extract_video_id(url):
455
  """
456
- Extracts the video ID from a YouTube URL.
457
  """
458
- pattern = r"(?:v=|\/)([0-9A-Za-z_-]{11}).*"
459
- match = re.search(pattern, url)
460
  return match.group(1) if match else None
461
 
462
  def clean_text_for_analysis(text):
463
  """
464
- Cleans text for sentiment analysis.
465
  """
466
- return re.sub(r"[^a-zA-Z0-9 .,!?']", "", text)
 
 
 
 
 
 
 
 
 
 
467
 
468
  def get_video_metadata(video_id):
469
  """
470
- Fetches video metadata using YouTube Data API.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471
  """
472
- # Dummy implementation for metadata fetching.
473
- return {"description": "No metadata available."}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
 
475
  def process_youtube_video(url="", keywords=""):
476
  try:
@@ -485,7 +543,7 @@ def process_youtube_video(url="", keywords=""):
485
  if url.strip():
486
  video_id = extract_video_id(url)
487
  if not video_id:
488
- return None, "Invalid YouTube URL", "N/A", ""
489
 
490
  thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
491
 
@@ -506,27 +564,27 @@ def process_youtube_video(url="", keywords=""):
506
  cleaned_text = clean_text_for_analysis(text)
507
 
508
  # Sentiment analysis
509
- sentiment = TextBlob(cleaned_text).sentiment
510
  sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
511
 
512
- # Generate summary (Dummy implementation)
513
- summary = f"Summary: {cleaned_text[:200]}..."
514
 
515
- # Extract subtitle information (Dummy implementation)
516
- subtitle_info = "Subtitle processed successfully."
517
 
518
  except TranscriptsDisabled:
519
  metadata = get_video_metadata(video_id)
520
- summary = metadata.get("description", "⚠️ This video has disabled subtitles.")
521
  sentiment_label = "N/A"
522
  subtitle_info = "No subtitles available for analysis."
523
  except NoTranscriptFound:
524
  metadata = get_video_metadata(video_id)
525
- summary = metadata.get("description", "⚠️ No English transcript available.")
526
  sentiment_label = "N/A"
527
  subtitle_info = "No subtitles available for analysis."
528
  except Exception as e:
529
- return thumbnail, f"⚠️ Error processing transcript: {str(e)}", "N/A", ""
530
 
531
  # If keywords are provided, get recommendations
532
  if keywords.strip():
@@ -535,44 +593,18 @@ def process_youtube_video(url="", keywords=""):
535
  return thumbnail, summary, sentiment_label, subtitle_info, recommendations
536
 
537
  except Exception as e:
538
- return None, f"Error: {str(e)}", "N/A", ""
539
-
540
- def get_recommendations(keywords, max_results=5):
541
- """
542
- Fetches related video recommendations based on the provided keywords.
543
- """
544
- YOUTUBE_API_KEY = "AIzaSyD_SDF4lC3vpHVAMnBOcN2ZCTz7dRjUc98" # Replace with your YouTube Data API key
545
- if not keywords.strip():
546
- return "Please provide search keywords"
547
- try:
548
- response = requests.get(
549
- "https://www.googleapis.com/youtube/v3/search",
550
- params={
551
- "part": "snippet",
552
- "q": f"educational {keywords}",
553
- "type": "video",
554
- "maxResults": max_results,
555
- "relevanceLanguage": "en",
556
- "key": YOUTUBE_API_KEY
557
- }
558
- ).json()
559
 
560
- results = []
561
- for item in response.get("items", []):
562
- title = item["snippet"]["title"]
563
- channel = item["snippet"]["channelTitle"]
564
- video_id = item["id"]["videoId"]
565
- results.append(f"📺 {title}\n👤 {channel}\n🔗 https://youtube.com/watch?v={video_id}\n")
566
-
567
- return "\n".join(results) if results else "No recommendations found"
568
- except Exception as e:
569
- return f"Error: {str(e)}"
570
 
571
  # Gradio Interface
572
  with gr.Blocks(theme=gr.themes.Soft()) as app:
573
  # Login Page
574
  with gr.Group() as login_page:
575
- gr.Markdown("# 🎓 Educational Learning Management System")
576
  username = gr.Textbox(label="Username")
577
  password = gr.Textbox(label="Password", type="password")
578
  login_btn = gr.Button("Login", variant="primary")
@@ -582,48 +614,40 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
582
  with gr.Group(visible=False) as main_page:
583
  with gr.Row():
584
  with gr.Column(scale=1):
585
- gr.Markdown("### 📋 Navigation")
586
- nav_dashboard = gr.Button("📊 Dashboard", variant="primary")
587
- nav_students = gr.Button("👥 Students")
588
- nav_teachers = gr.Button("👨‍🏫 Teachers")
589
- nav_courses = gr.Button("📚 Courses")
590
- nav_youtube = gr.Button("🎥 YouTube Tool")
591
- logout_btn = gr.Button("🚪 Logout", variant="stop")
592
 
593
  with gr.Column(scale=3):
594
- # Dashboard Content
595
- dashboard_page = gr.Group()
596
- with dashboard_page:
597
- gr.Markdown("## 📊 Dashboard")
598
-
599
  # YouTube Tool Content
600
  youtube_page = gr.Group(visible=False)
601
  with youtube_page:
602
  gr.Markdown("## Agent for YouTube Content Exploration")
603
  with gr.Row():
604
- video_url = gr.Textbox(
605
- label="YouTube URL",
606
- placeholder="https://youtube.com/watch?v=..."
607
- )
608
- analyze_btn = gr.Button("🔍 Analyze Video", variant="primary")
 
 
 
 
 
 
 
 
 
609
 
610
  with gr.Row():
611
- keywords = gr.Textbox(
612
- label="Keywords for Recommendations",
613
- placeholder="e.g., python programming, machine learning"
614
- )
615
- recommend_btn = gr.Button("🔍 Get Recommendations", variant="primary")
616
-
617
- with gr.Row():
618
- video_thumbnail = gr.Image(label="Video Preview")
619
-
620
- with gr.Row():
621
- summary = gr.Textbox(label="📝 Summary", lines=8)
622
- sentiment = gr.Textbox(label="😊 Content Sentiment")
623
- recommendations = gr.Textbox(label="🎯 Related Videos", lines=10)
624
 
625
  def login_check(user, pwd):
626
- USER_CREDENTIALS = {"admin": "admin"}
627
  if USER_CREDENTIALS.get(user) == pwd:
628
  return {
629
  login_page: gr.update(visible=False),
@@ -633,12 +657,11 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
633
  return {
634
  login_page: gr.update(visible=True),
635
  main_page: gr.update(visible=False),
636
- login_msg: " Invalid credentials"
637
  }
638
 
639
  def show_page(page_name):
640
  updates = {
641
- dashboard_page: gr.update(visible=False),
642
  youtube_page: gr.update(visible=False)
643
  }
644
  updates[page_name] = gr.update(visible=True)
@@ -651,19 +674,18 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
651
  outputs=[login_page, main_page, login_msg]
652
  )
653
 
654
- nav_dashboard.click(lambda: show_page(dashboard_page), outputs=list(show_page(dashboard_page).keys()))
655
  nav_youtube.click(lambda: show_page(youtube_page), outputs=list(show_page(youtube_page).keys()))
656
 
657
  analyze_btn.click(
658
  process_youtube_video,
659
- inputs=[video_url, gr.Textbox(label="")], # Empty input for keywords
660
  outputs=[video_thumbnail, summary, sentiment, recommendations]
661
  )
662
 
663
  recommend_btn.click(
664
- lambda keywords: (None, "", "", get_recommendations(keywords)),
665
  inputs=[keywords],
666
- outputs=[video_thumbnail, summary, sentiment, recommendations]
667
  )
668
 
669
  logout_btn.click(
@@ -675,7 +697,4 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
675
  )
676
 
677
  if __name__ == "__main__":
678
- app.launch()
679
-
680
-
681
-
 
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
  """
455
+ Extract the video ID from a YouTube URL.
456
  """
457
+ import re
458
+ match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11})", url)
459
  return match.group(1) if match else None
460
 
461
  def clean_text_for_analysis(text):
462
  """
463
+ Clean text for sentiment analysis.
464
  """
465
+ import re
466
+ return re.sub(r"[^a-zA-Z0-9\s]", "", text)
467
+
468
+ def extract_subtitle_info(cleaned_text):
469
+ """
470
+ Extract additional information from subtitles (e.g., keywords, summary).
471
+ """
472
+ from collections import Counter
473
+ words = cleaned_text.split()
474
+ common_words = Counter(words).most_common(5)
475
+ return f"Most common words: {', '.join([word for word, _ in common_words])}"
476
 
477
  def get_video_metadata(video_id):
478
  """
479
+ Fetch metadata for a YouTube video using the YouTube Data API.
480
+ """
481
+ YOUTUBE_API_KEY = "YOUR_YOUTUBE_API_KEY" # Replace with your YouTube Data API key
482
+ try:
483
+ response = requests.get(
484
+ f"https://www.googleapis.com/youtube/v3/videos",
485
+ params={
486
+ "part": "snippet",
487
+ "id": video_id,
488
+ "key": YOUTUBE_API_KEY
489
+ }
490
+ ).json()
491
+ if "items" in response and response["items"]:
492
+ snippet = response["items"][0]["snippet"]
493
+ return {
494
+ "title": snippet.get("title", "N/A"),
495
+ "description": snippet.get("description", "N/A"),
496
+ "channelTitle": snippet.get("channelTitle", "N/A")
497
+ }
498
+ return {}
499
+ except Exception as e:
500
+ return {"error": str(e)}
501
+
502
+ def get_recommendations(keywords, max_results=5):
503
+ """
504
+ Fetches related video recommendations based on the provided keywords.
505
  """
506
+ YOUTUBE_API_KEY = "YOUR_YOUTUBE_API_KEY" # Replace with your YouTube Data API key
507
+ if not keywords.strip():
508
+ return "Please provide search keywords"
509
+ try:
510
+ response = requests.get(
511
+ "https://www.googleapis.com/youtube/v3/search",
512
+ params={
513
+ "part": "snippet",
514
+ "q": f"educational {keywords}",
515
+ "type": "video",
516
+ "maxResults": max_results,
517
+ "relevanceLanguage": "en",
518
+ "key": YOUTUBE_API_KEY
519
+ }
520
+ ).json()
521
+
522
+ results = []
523
+ for item in response.get("items", []):
524
+ title = item["snippet"]["title"]
525
+ channel = item["snippet"]["channelTitle"]
526
+ video_id = item["id"]["videoId"]
527
+ results.append(f"\ud83d\udcfa {title}\n\ud83d\udc64 {channel}\n\ud83d\udd17 https://youtube.com/watch?v={video_id}\n")
528
+
529
+ return "\n".join(results) if results else "No recommendations found"
530
+ except Exception as e:
531
+ return f"Error: {str(e)}"
532
 
533
  def process_youtube_video(url="", keywords=""):
534
  try:
 
543
  if url.strip():
544
  video_id = extract_video_id(url)
545
  if not video_id:
546
+ return None, "Invalid YouTube URL", "N/A", "", ""
547
 
548
  thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
549
 
 
564
  cleaned_text = clean_text_for_analysis(text)
565
 
566
  # Sentiment analysis
567
+ sentiment = TextBlob(cleaned_text).sentiment # Use cleaned text for sentiment analysis
568
  sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
569
 
570
+ # Generate summary
571
+ summary = f"Summary: {cleaned_text[:400]}..."
572
 
573
+ # Extract subtitle information
574
+ subtitle_info = extract_subtitle_info(cleaned_text)
575
 
576
  except TranscriptsDisabled:
577
  metadata = get_video_metadata(video_id)
578
+ summary = metadata.get("description", "\u26a0\ufe0f This video has disabled subtitles.")
579
  sentiment_label = "N/A"
580
  subtitle_info = "No subtitles available for analysis."
581
  except NoTranscriptFound:
582
  metadata = get_video_metadata(video_id)
583
+ summary = metadata.get("description", "\u26a0\ufe0f No English transcript available.")
584
  sentiment_label = "N/A"
585
  subtitle_info = "No subtitles available for analysis."
586
  except Exception as e:
587
+ return thumbnail, f"\u26a0\ufe0f Error processing transcript: {str(e)}", "N/A", "", ""
588
 
589
  # If keywords are provided, get recommendations
590
  if keywords.strip():
 
593
  return thumbnail, summary, sentiment_label, subtitle_info, recommendations
594
 
595
  except Exception as e:
596
+ return None, f"Error: {str(e)}", "N/A", "", ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
597
 
598
+ # User credentials (replace with a secure method in production)
599
+ USER_CREDENTIALS = {
600
+ "admin": "admin"
601
+ }
 
 
 
 
 
 
602
 
603
  # Gradio Interface
604
  with gr.Blocks(theme=gr.themes.Soft()) as app:
605
  # Login Page
606
  with gr.Group() as login_page:
607
+ gr.Markdown("# \ud83c\udf93 Educational Learning Management System")
608
  username = gr.Textbox(label="Username")
609
  password = gr.Textbox(label="Password", type="password")
610
  login_btn = gr.Button("Login", variant="primary")
 
614
  with gr.Group(visible=False) as main_page:
615
  with gr.Row():
616
  with gr.Column(scale=1):
617
+ gr.Markdown("### \ud83d\udccb Navigation")
618
+ nav_dashboard = gr.Button("\ud83d\udcca Dashboard", variant="primary")
619
+ nav_youtube = gr.Button("\ud83c\udfa5 YouTube Tool")
620
+ logout_btn = gr.Button("\ud83d\udeaa Logout", variant="stop")
 
 
 
621
 
622
  with gr.Column(scale=3):
 
 
 
 
 
623
  # YouTube Tool Content
624
  youtube_page = gr.Group(visible=False)
625
  with youtube_page:
626
  gr.Markdown("## Agent for YouTube Content Exploration")
627
  with gr.Row():
628
+ with gr.Column(scale=2):
629
+ video_url = gr.Textbox(
630
+ label="YouTube URL",
631
+ placeholder="https://youtube.com/watch?v=..."
632
+ )
633
+ keywords = gr.Textbox(
634
+ label="Keywords for Recommendations",
635
+ placeholder="e.g., python programming, machine learning"
636
+ )
637
+ analyze_btn = gr.Button("\ud83d\udd0d Analyze Video", variant="primary")
638
+ recommend_btn = gr.Button("\ud83d\udd0d Get Recommendations", variant="secondary")
639
+
640
+ with gr.Column(scale=1):
641
+ video_thumbnail = gr.Image(label="Video Preview")
642
 
643
  with gr.Row():
644
+ with gr.Column():
645
+ summary = gr.Textbox(label="\ud83d\udd8b\ufe0f Summary", lines=8)
646
+ sentiment = gr.Textbox(label="\ud83d\ude0a Content Sentiment")
647
+ with gr.Column():
648
+ recommendations = gr.Textbox(label="\ud83c\udfaf Related Videos", lines=10)
 
 
 
 
 
 
 
 
649
 
650
  def login_check(user, pwd):
 
651
  if USER_CREDENTIALS.get(user) == pwd:
652
  return {
653
  login_page: gr.update(visible=False),
 
657
  return {
658
  login_page: gr.update(visible=True),
659
  main_page: gr.update(visible=False),
660
+ login_msg: "\u274c Invalid credentials"
661
  }
662
 
663
  def show_page(page_name):
664
  updates = {
 
665
  youtube_page: gr.update(visible=False)
666
  }
667
  updates[page_name] = gr.update(visible=True)
 
674
  outputs=[login_page, main_page, login_msg]
675
  )
676
 
 
677
  nav_youtube.click(lambda: show_page(youtube_page), outputs=list(show_page(youtube_page).keys()))
678
 
679
  analyze_btn.click(
680
  process_youtube_video,
681
+ inputs=[video_url, ""],
682
  outputs=[video_thumbnail, summary, sentiment, recommendations]
683
  )
684
 
685
  recommend_btn.click(
686
+ lambda keywords: process_youtube_video("", keywords)[-1],
687
  inputs=[keywords],
688
+ outputs=[recommendations]
689
  )
690
 
691
  logout_btn.click(
 
697
  )
698
 
699
  if __name__ == "__main__":
700
+ app.launch()