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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -155
app.py CHANGED
@@ -451,34 +451,22 @@ 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",
@@ -500,10 +488,7 @@ def get_video_metadata(video_id):
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:
@@ -524,177 +509,97 @@ def get_recommendations(keywords, max_results=5):
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:
535
- # Initialize variables
536
- thumbnail = None
537
- summary = "No transcript available"
538
- sentiment_label = "N/A"
539
- recommendations = ""
540
- subtitle_info = "No additional information available"
541
 
542
- # If URL is provided, process the YouTube video
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
 
 
 
 
550
  try:
551
- # Fetch transcript
552
- transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
553
- transcript = None
554
- try:
555
- transcript = transcript_list.find_transcript(['en'])
556
- except:
557
- transcript = transcript_list.find_generated_transcript(['en'])
558
-
559
- text = " ".join([t['text'] for t in transcript.fetch()])
560
- if not text.strip():
561
- raise ValueError("Transcript is empty")
562
-
563
- # Clean up the text for sentiment analysis
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():
591
- recommendations = get_recommendations(keywords)
592
-
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")
611
  login_msg = gr.Markdown()
612
 
613
- # Main Interface
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),
654
- main_page: gr.update(visible=True),
655
- login_msg: ""
656
- }
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)
668
- return updates
669
-
670
- # Event Handlers
671
- login_btn.click(
672
- login_check,
673
- inputs=[username, password],
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(
692
- lambda: {
693
- login_page: gr.update(visible=True),
694
- main_page: gr.update(visible=False)
695
- },
696
- outputs=[login_page, main_page]
697
- )
698
 
699
  if __name__ == "__main__":
700
- app.launch()
 
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",
 
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:
 
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()