Sayiqa commited on
Commit
d1e6180
Β·
verified Β·
1 Parent(s): 3dbaa5e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +916 -927
app.py CHANGED
@@ -1,863 +1,727 @@
1
- import subprocess
2
- subprocess.check_call(["pip", "install", "transformers==4.34.0"])
3
- subprocess.check_call(["pip", "install", "torch>=1.7.1"])
4
- subprocess.check_call(["pip", "install", "youtube_transcript_api>=0.6.3"])
5
- subprocess.check_call(["pip", "install", "pytube"])
6
- subprocess.check_call(["pip", "install", "huggingface_hub>=0.19.0"])
7
- subprocess.check_call(["pip", "install", "PyPDF2>=3.0.1"])
8
- subprocess.check_call(["pip", "install", "google-generativeai"])
9
- subprocess.check_call(["pip", "install", "textblob>=0.17.1"])
10
- subprocess.check_call(["pip", "install", "python-dotenv>=1.0.0"])
11
- subprocess.check_call(["pip", "install", "genai"])
12
- subprocess.check_call(["pip", "install", "google-cloud-aiplatform==1.34.0"])
13
- import transformers
14
- import torch
15
- import os
16
- import youtube_transcript_api
17
- import pytube
18
- import gradio
19
- import PyPDF2
20
- import pathlib
21
- import pandas
22
- import numpy
23
- import textblob
24
- import gradio as gr
25
- from youtube_transcript_api import YouTubeTranscriptApi
26
- import google.generativeai as genai
27
- import requests
28
- from textblob import TextBlob
29
- import re
30
- #from google.cloud import generativeai
31
- from huggingface_hub import login
32
- from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
33
- def install_missing_packages():
34
- required_packages = {
35
- "torch":">=1.11.0",
36
- "transformers":">=4.34.0",
37
- "youtube_transcript_api" :">=0.6.3" ,
38
- "pytube":None,
39
- "huggingface_hub": ">=0.19.0",
40
- "PyPDF2": ">=3.0.1",
41
- "textblob":">=0.17.1",
42
- "python-dotenv":">=1.0.0",
43
- "genai":None,
44
- "google-generativeai": None,
45
- "google-cloud-aiplatform":"==1.34.0"
46
- }
47
 
48
 
49
- for package, version in required_packages.items():
50
- try:
51
- __import__(package)
52
- except ImportError:
53
- package_name = f"{package}{version}" if version else package
54
- subprocess.check_call(["pip", "install", package_name])
55
 
56
- install_missing_packages()
57
- # Configuration
58
 
59
- hf_token = os.getenv("HF_TOKEN")
60
- if hf_token:
61
- login(hf_token)
62
- else:
63
- raise ValueError("HF_TOKEN environment variable not set.")
64
 
65
- # Configuration
66
- USER_CREDENTIALS = {
67
- "admin": "password123",
68
- "teacher": "teach2024",
69
- "student": "learn2024"
70
- }
71
 
72
- import os
73
- from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
74
 
75
- # Use environment variables
76
- GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
77
- YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY")
78
 
79
- if not GOOGLE_API_KEY or not YOUTUBE_API_KEY:
80
- raise ValueError("Please set GOOGLE_API_KEY and YOUTUBE_API_KEY environment variables")
81
 
82
- genai.configure(api_key=GOOGLE_API_KEY)
83
 
84
- # Database
85
- students_data = [
86
- (1, "Alice", "A", "Computer Science"),
87
- (2, "Aliaa", "B", "Mathematics"),
88
- (3, "Charlie", "A", "Machine Learning"),
89
- (4, "Daan", "A", "Physics"),
90
- (5, "Jhon", "C", "Math"),
91
- (6, "Emma", "A+", "Computer Science")
92
- ]
93
 
94
- teachers_data = [
95
- (1, "Dr. Smith", "Math", "MS Mathematics"),
96
- (2, "Ms. Johnson", "Science", "MSc Physics"),
97
- (3, "Ms. Jack", "Artificial Intelligence Engineer", "MSc AI"),
98
- (4, "Ms. Evelyn", "Computer Science", "MSc Computer Science"),
99
- ]
100
 
101
- courses_data = [
102
- (1, "Algebra", "Dr. Smith", "Advanced"),
103
- (2, "Biology", "Ms. Mia", "Intermediate"),
104
- (3, "Machine Learning", "Ms. Jack", "Intermediate"),
105
- (4, "Computer Science", "Ms. Evelyn", "Intermediate"),
106
- (5, "Mathematics", "Ms. Smith", "Intermediate")
107
- ]
108
 
109
- def sanitize_text(text):
110
- """Remove invalid Unicode characters."""
111
- return text.encode("utf-8", "replace").decode("utf-8")
112
 
113
- def extract_video_id(url):
114
- if not url:
115
- return None
116
- patterns = [
117
- r'(?:v=|\/videos\/|embed\/|youtu.be\/|\/v\/|\/e\/|watch\?v=|\/watch\?v=)([^#\&\?]*)'
118
- ]
119
- for pattern in patterns:
120
- match = re.search(pattern, url)
121
- if match:
122
- return match.group(1)
123
- return None
124
 
125
 
126
 
127
- from textblob import TextBlob
128
- from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
129
- 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 subprocess
448
- # subprocess.check_call(["pip", "install", "transformers==4.34.0"])
449
- # subprocess.check_call(["pip", "install", "torch>=1.7.1"])
450
- # subprocess.check_call(["pip", "install", "youtube_transcript_api>=0.6.3"])
451
- # subprocess.check_call(["pip", "install", "pytube"])
452
- # subprocess.check_call(["pip", "install", "huggingface_hub>=0.19.0"])
453
- # subprocess.check_call(["pip", "install", "PyPDF2>=3.0.1"])
454
- # subprocess.check_call(["pip", "install", "google-generativeai"])
455
- # subprocess.check_call(["pip", "install", "textblob>=0.17.1"])
456
- # subprocess.check_call(["pip", "install", "python-dotenv>=1.0.0"])
457
- # subprocess.check_call(["pip", "install", "genai"])
458
- # subprocess.check_call(["pip", "install", "google-cloud-aiplatform==1.34.0"])
459
- # import transformers
460
- # import torch
461
- # import os
462
- # import youtube_transcript_api
463
- # import pytube
464
- # import gradio
465
- # import PyPDF2
466
- # import pathlib
467
- # import pandas
468
- # import numpy
469
- # import textblob
470
- # import gradio as gr
471
- # from youtube_transcript_api import YouTubeTranscriptApi
472
- # import google.generativeai as genai
473
- # import requests
474
- # from textblob import TextBlob
475
- # import re
476
- # #from google.cloud import generativeai
477
- # from huggingface_hub import login
478
- # from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
479
- # def install_missing_packages():
480
- # required_packages = {
481
- # "torch":">=1.11.0",
482
- # "transformers":">=4.34.0",
483
- # "youtube_transcript_api" :">=0.6.3" ,
484
- # "pytube":None,
485
- # "huggingface_hub": ">=0.19.0",
486
- # "PyPDF2": ">=3.0.1",
487
- # "textblob":">=0.17.1",
488
- # "python-dotenv":">=1.0.0",
489
- # "genai":None,
490
- # "google-generativeai": None,
491
- # "google-cloud-aiplatform":"==1.34.0"
492
- # }
493
-
494
-
495
- # for package, version in required_packages.items():
496
- # try:
497
- # __import__(package)
498
- # except ImportError:
499
- # package_name = f"{package}{version}" if version else package
500
- # subprocess.check_call(["pip", "install", package_name])
501
-
502
- # install_missing_packages()
503
- # # Configuration
504
-
505
- # hf_token = os.getenv("HF_TOKEN")
506
- # if hf_token:
507
- # login(hf_token)
508
- # else:
509
- # raise ValueError("HF_TOKEN environment variable not set.")
510
-
511
-
512
- # # Configuration
513
- # USER_CREDENTIALS = {
514
- # "admin": "password123",
515
- # "teacher": "teach2024",
516
- # "student": "learn2024"
517
- # }
518
-
519
- # import os
520
- # from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
521
 
522
- # # Use environment variables
523
- # GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
524
- # YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY")
525
 
526
- # if not GOOGLE_API_KEY or not YOUTUBE_API_KEY:
527
- # raise ValueError("Please set GOOGLE_API_KEY and YOUTUBE_API_KEY environment variables")
 
 
 
 
528
 
529
- # genai.configure(api_key=GOOGLE_API_KEY)
 
530
 
531
- # # Database
532
- # students_data = [
533
- # (1, "Alice", "A", "Computer Science"),
534
- # (2, "Aliaa", "B", "Mathematics"),
535
- # (3, "Charlie", "A", "Machine Learning"),
536
- # (4, "Daan", "A", "Physics"),
537
- # (5, "Jhon", "C", "Math"),
538
- # (6, "Emma", "A+", "Computer Science")
539
- # ]
540
 
541
- # teachers_data = [
542
- # (1, "Dr. Smith", "Math", "MS Mathematics"),
543
- # (2, "Ms. Johnson", "Science", "MSc Physics"),
544
- # (3, "Ms. Jack", "Artificial Intelligence Engineer", "MSc AI"),
545
- # (4, "Ms. Evelyn", "Computer Science", "MSc Computer Science"),
546
- # ]
547
 
548
- # courses_data = [
549
- # (1, "Algebra", "Dr. Smith", "Advanced"),
550
- # (2, "Biology", "Ms. Mia", "Intermediate"),
551
- # (3, "Machine Learning", "Ms. Jack", "Intermediate"),
552
- # (4, "Computer Science", "Ms. Evelyn", "Intermediate"),
553
- # (5, "Mathematics", "Ms. Smith", "Intermediate")
554
- # ]
555
 
556
- # def sanitize_text(text):
557
- # """Remove invalid Unicode characters."""
558
- # return text.encode("utf-8", "replace").decode("utf-8")
559
 
560
- # def extract_video_id(url):
561
- # if not url:
562
- # return None
563
- # patterns = [
564
- # r'(?:v=|\/videos\/|embed\/|youtu.be\/|\/v\/|\/e\/|watch\?v=|\/watch\?v=)([^#\&\?]*)'
565
- # ]
566
- # for pattern in patterns:
567
- # match = re.search(pattern, url)
568
- # if match:
569
- # return match.group(1)
570
- # return None
571
 
 
 
572
 
573
- # # def process_youtube_video(url="", keywords=""):
574
- # # try:
575
- # # # Initialize variables
576
- # # thumbnail = None # Default value for thumbnail
577
- # # summary = "No transcript available"
578
- # # sentiment_label = "N/A"
579
 
580
- # # if not url.strip():
581
- # # return None, "Please enter a YouTube URL", "N/A", ""
582
-
583
- # # video_id = extract_video_id(url)
584
- # # if not video_id:
585
- # # return None, "Invalid YouTube URL", "N/A", ""
 
 
 
586
 
587
- # # thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
 
 
 
 
 
588
 
589
- # # try:
590
- # # # Try multiple transcript options
591
- # # transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
592
-
593
- # # try:
594
- # # transcript = transcript_list.find_transcript(['en'])
595
- # # except:
596
- # # try:
597
- # # transcript = transcript_list.find_transcript(['en-US'])
598
- # # except:
599
- # # try:
600
- # # # Try auto-generated
601
- # # transcript = transcript_list.find_generated_transcript(['en'])
602
- # # except:
603
- # # raise NoTranscriptFound()
604
-
605
- # # text = " ".join([t['text'] for t in transcript.fetch()])
606
-
607
- # # # Generate summary
608
- # # model = genai.GenerativeModel("gemini-pro")
609
- # # summary = model.generate_content(f"Summarize this: {text[:4000]}").text
610
-
611
- # # # Analysis
612
- # # sentiment = TextBlob(text[:1000]).sentiment
613
- # # sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
614
-
615
- # # except TranscriptsDisabled:
616
- # # # Fallback: Use video metadata if available
617
- # # metadata = get_video_metadata(video_id)
618
- # # summary = metadata.get("description", "⚠️ This video has disabled subtitles. No transcript available.")
619
- # # except NoTranscriptFound:
620
- # # # Fallback: Use video metadata if available
621
- # # metadata = get_video_metadata(video_id)
622
- # # summary = metadata.get("description", "⚠️ No English transcript available. No transcript available.")
623
- # # except Exception as e:
624
- # # return thumbnail, f"⚠️ Error: {str(e)}", "N/A", ""
625
-
626
- # # # Get recommendations
627
- # # if keywords.strip():
628
- # # recommendations = get_recommendations(keywords)
629
- # # else:
630
- # # recommendations = ""
631
-
632
- # # return thumbnail, summary, sentiment_label, recommendations
633
-
634
- # # except Exception as e:
635
- # # return None, f"Error: {str(e)}", "N/A", ""
636
-
637
-
638
- # # def get_video_metadata(video_id):
639
- # # """
640
- # # Fetches video metadata such as title and description using the YouTube Data API.
641
- # # """
642
- # # try:
643
- # # from googleapiclient.discovery import build
644
-
645
- # # # Replace with your YouTube Data API key
646
- # # API_KEY = "AIzaSyB7X-RYjZmUuDSMTQsvCfyzURw5bhqOto4"
647
- # # youtube = build("youtube", "v3", developerKey=API_KEY)
648
- # # request = youtube.videos().list(part="snippet", id=video_id)
649
- # # response = request.execute()
650
-
651
- # # if "items" in response and len(response["items"]) > 0:
652
- # # snippet = response["items"][0]["snippet"]
653
- # # return {
654
- # # "title": snippet.get("title", "No title available"),
655
- # # "description": snippet.get("description", "No description available"),
656
- # # }
657
- # # return {}
658
-
659
- # # except Exception as e:
660
- # # return {"title": "Error fetching metadata", "description": str(e)}
661
-
662
- # # # Get recommendations
663
- # # if keywords.strip():
664
- # # recommendations = get_recommendations(keywords)
665
- # # else:
666
- # # recommendations = ""
667
-
668
- # # return thumbnail, summary, sentiment_label, recommendations
669
-
670
- # # except Exception as e:
671
- # # return None, f"Error: {str(e)}", "N/A", ""
672
 
673
- # from textblob import TextBlob
674
- # from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
675
- # import re
676
- # from collections import Counter
677
- # from googleapiclient.discovery import build
678
- # # def process_youtube_video(url="", keywords=""):
679
- # # try:
680
- # # # Initialize variables
681
- # # thumbnail = None
682
- # # summary = "No transcript available"
683
- # # sentiment_label = "N/A"
684
- # # recommendations = ""
685
- # # subtitle_info = "No additional information available"
686
-
687
- # # if not url.strip():
688
- # # return None, "Please enter a YouTube URL", "N/A", "", ""
689
-
690
- # # video_id = extract_video_id(url)
691
- # # if not video_id:
692
- # # return None, "Invalid YouTube URL", "N/A", "", ""
693
-
694
- # # thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
695
-
696
- # # try:
697
- # # # Fetch transcript
698
- # # transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
699
- # # transcript = None
700
- # # try:
701
- # # transcript = transcript_list.find_transcript(['en'])
702
- # # except:
703
- # # transcript = transcript_list.find_generated_transcript(['en'])
704
-
705
- # # text = " ".join([t['text'] for t in transcript.fetch()])
706
- # # if not text.strip():
707
- # # raise ValueError("Transcript is empty")
708
-
709
- # # # Generate summary
710
- # # model = genai.GenerativeModel("gemini-pro")
711
- # # summary = model.generate_content(f"Summarize this: {text[:4000]}").text
712
-
713
- # # # Extract subtitle information
714
- # # subtitle_info = extract_subtitle_info(text)
715
-
716
- # # # Sentiment analysis
717
- # # sentiment = TextBlob(text[:1000]).sentiment
718
- # # sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
719
-
720
- # # except TranscriptsDisabled:
721
- # # metadata = get_video_metadata(video_id)
722
- # # summary = metadata.get("description", "⚠️ This video has disabled subtitles.")
723
- # # sentiment_label = "N/A"
724
- # # subtitle_info = "No subtitles available for analysis."
725
- # # except NoTranscriptFound:
726
- # # metadata = get_video_metadata(video_id)
727
- # # summary = metadata.get("description", "⚠️ No English transcript available.")
728
- # # sentiment_label = "N/A"
729
- # # subtitle_info = "No subtitles available for analysis."
730
- # # except Exception as e:
731
- # # return thumbnail, f"⚠️ Error processing transcript: {str(e)}", "N/A", "", ""
732
-
733
- # # # Get recommendations
734
- # # if keywords.strip():
735
- # # recommendations = get_recommendations(keywords)
736
-
737
- # # return thumbnail, summary, sentiment_label, subtitle_info, recommendations
738
-
739
- # # except Exception as e:
740
- # # return None, f"Error: {str(e)}", "N/A", "", ""
741
-
742
-
743
- # # def extract_video_id(url):
744
- # # """
745
- # # Extracts the video ID from a YouTube URL.
746
- # # """
747
- # # import re
748
- # # match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11})", url)
749
- # # return match.group(1) if match else None
750
-
751
-
752
- # # def get_video_metadata(video_id):
753
- # # """
754
- # # Fetches video metadata such as title and description using the YouTube Data API.
755
- # # """
756
- # # try:
757
- # # from googleapiclient.discovery import build
758
-
759
- # # # Replace with your YouTube Data API key
760
- # # YOUTUBE_API_KEY = "AIzaSyD_SDF4lC3vpHVAMnBOcN2ZCTz7dRjUc98"
761
- # # youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
762
- # # request = youtube.videos().list(part="snippet", id=video_id)
763
- # # response = request.execute()
764
-
765
- # # if "items" in response and len(response["items"]) > 0:
766
- # # snippet = response["items"][0]["snippet"]
767
- # # return {
768
- # # "title": snippet.get("title", "No title available"),
769
- # # "description": snippet.get("description", "No description available"),
770
- # # }
771
- # # return {}
772
-
773
- # # except Exception as e:
774
- # # return {"title": "Error fetching metadata", "description": str(e)}
775
-
776
-
777
- # # def extract_subtitle_info(text):
778
- # # """
779
- # # Extracts meaningful information from the subtitles.
780
- # # This could include topics, key insights, or a breakdown of the content.
781
- # # """
782
- # # try:
783
- # # # Split text into sentences for better analysis
784
- # # sentences = text.split(". ")
785
-
786
- # # # Example: Extract key topics or keywords
787
- # # from collections import Counter
788
- # # words = text.split()
789
- # # common_words = Counter(words).most_common(10)
790
- # # key_topics = ", ".join([word for word, count in common_words])
791
-
792
- # # # Example: Provide a breakdown of the content
793
- # # info = f"Key topics discussed: {key_topics}. \nNumber of sentences: {len(sentences)}. \nTotal words: {len(words)}."
794
-
795
- # # return info
796
- # # except Exception as e:
797
- # # return f"Error extracting subtitle information: {str(e)}"
798
- # from textblob import TextBlob
799
- # from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
800
- # import re
801
- # from collections import Counter
802
- # from googleapiclient.discovery import build
803
 
 
 
 
 
 
 
 
 
 
 
 
804
 
805
- # from textblob import TextBlob
806
- # from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
807
- # import re
808
- # from collections import Counter
809
- # from googleapiclient.discovery import build
810
 
811
  # def process_youtube_video(url="", keywords=""):
812
  # try:
813
  # # Initialize variables
814
- # thumbnail = None
815
  # summary = "No transcript available"
816
  # sentiment_label = "N/A"
817
- # recommendations = ""
818
- # subtitle_info = "No additional information available"
819
 
820
  # if not url.strip():
821
- # return None, "Please enter a YouTube URL", "N/A", "", ""
822
-
823
  # video_id = extract_video_id(url)
824
  # if not video_id:
825
- # return None, "Invalid YouTube URL", "N/A", "", ""
826
 
827
  # thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
828
 
829
  # try:
830
- # # Fetch transcript
831
  # transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
832
- # transcript = None
833
  # try:
834
  # transcript = transcript_list.find_transcript(['en'])
835
  # except:
836
- # transcript = transcript_list.find_generated_transcript(['en'])
 
 
 
 
 
 
 
837
 
838
  # text = " ".join([t['text'] for t in transcript.fetch()])
839
- # if not text.strip():
840
- # raise ValueError("Transcript is empty")
841
-
842
- # # Clean up the text for sentiment analysis
843
- # cleaned_text = clean_text_for_analysis(text)
844
-
845
- # # Sentiment analysis
846
- # sentiment = TextBlob(cleaned_text).sentiment # Use cleaned text for sentiment analysis
847
- # sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
848
-
849
  # # Generate summary
850
  # model = genai.GenerativeModel("gemini-pro")
851
- # summary = model.generate_content(f"Summarize this: {cleaned_text[:4000]}").text
852
-
853
- # # Extract subtitle information
854
- # subtitle_info = extract_subtitle_info(cleaned_text)
 
855
 
856
  # except TranscriptsDisabled:
 
857
  # metadata = get_video_metadata(video_id)
858
- # summary = metadata.get("description", "⚠️ This video has disabled subtitles.")
859
- # sentiment_label = "N/A"
860
- # subtitle_info = "No subtitles available for analysis."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
861
  # except NoTranscriptFound:
862
  # metadata = get_video_metadata(video_id)
863
  # summary = metadata.get("description", "⚠️ No English transcript available.")
@@ -880,6 +744,7 @@ if __name__ == "__main__":
880
  # """
881
  # Extracts the video ID from a YouTube URL.
882
  # """
 
883
  # match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11})", url)
884
  # return match.group(1) if match else None
885
 
@@ -889,7 +754,10 @@ if __name__ == "__main__":
889
  # Fetches video metadata such as title and description using the YouTube Data API.
890
  # """
891
  # try:
892
- # YOUTUBE_API_KEY = "AIzaSyD_SDF4lC3vpHVAMnBOcN2ZCTz7dRjUc98" # Replace with your YouTube Data API key
 
 
 
893
  # youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
894
  # request = youtube.videos().list(part="snippet", id=video_id)
895
  # response = request.execute()
@@ -916,6 +784,7 @@ if __name__ == "__main__":
916
  # sentences = text.split(". ")
917
 
918
  # # Example: Extract key topics or keywords
 
919
  # words = text.split()
920
  # common_words = Counter(words).most_common(10)
921
  # key_topics = ", ".join([word for word, count in common_words])
@@ -928,195 +797,315 @@ if __name__ == "__main__":
928
  # return f"Error extracting subtitle information: {str(e)}"
929
 
930
 
931
- # def clean_text_for_analysis(text):
932
- # """
933
- # Cleans the transcript text by removing extra spaces, line breaks, and non-text elements.
934
- # """
935
- # # Remove extra spaces and line breaks
936
- # cleaned_text = " ".join(text.split())
937
- # return cleaned_text
 
938
 
 
 
939
 
940
- # def get_recommendations(keywords):
941
- # """
942
- # Fetches related video recommendations based on the provided keywords.
943
- # This function can be expanded with a proper API or custom logic.
944
- # """
945
- # # Placeholder for fetching recommendations based on keywords
946
- # return f"Recommendations for: {keywords}" # Dummy return for now
947
 
 
948
 
 
 
 
 
 
 
 
 
949
 
950
- # def get_recommendations(keywords, max_results=5):
951
- # if not keywords:
952
- # return "Please provide search keywords"
953
- # try:
954
- # response = requests.get(
955
- # "https://www.googleapis.com/youtube/v3/search",
956
- # params={
957
- # "part": "snippet",
958
- # "q": f"educational {keywords}",
959
- # "type": "video",
960
- # "maxResults": max_results,
961
- # "relevanceLanguage": "en",
962
- # "key": YOUTUBE_API_KEY
963
- # }
964
- # ).json()
965
-
966
- # results = []
967
- # for item in response.get("items", []):
968
- # title = item["snippet"]["title"]
969
- # channel = item["snippet"]["channelTitle"]
970
- # video_id = item["id"]["videoId"]
971
- # results.append(f"πŸ“Ί {title}\nπŸ‘€ {channel}\nπŸ”— https://youtube.com/watch?v={video_id}\n")
972
-
973
- # return "\n".join(results) if results else "No recommendations found"
974
- # except Exception as e:
975
- # return f"Error: {str(e)}"
976
 
977
- # # Gradio Interface
978
- # with gr.Blocks(theme=gr.themes.Soft()) as app:
979
- # # Login Page
980
- # with gr.Group() as login_page:
981
- # gr.Markdown("# πŸŽ“ Educational Learning Management System")
982
- # username = gr.Textbox(label="Username")
983
- # password = gr.Textbox(label="Password", type="password")
984
- # login_btn = gr.Button("Login", variant="primary")
985
- # login_msg = gr.Markdown()
986
-
987
- # # Main Interface
988
- # with gr.Group(visible=False) as main_page:
989
- # with gr.Row():
990
- # with gr.Column(scale=1):
991
- # gr.Markdown("### πŸ“‹ Navigation")
992
- # nav_dashboard = gr.Button("πŸ“Š Dashboard", variant="primary")
993
- # nav_students = gr.Button("πŸ‘₯ Students")
994
- # nav_teachers = gr.Button("πŸ‘¨β€πŸ« Teachers")
995
- # nav_courses = gr.Button("πŸ“š Courses")
996
- # nav_youtube = gr.Button("πŸŽ₯ YouTube Tool")
997
- # logout_btn = gr.Button("πŸšͺ Logout", variant="stop")
998
-
999
- # with gr.Column(scale=3):
1000
- # # Dashboard Content
1001
- # dashboard_page = gr.Group()
1002
- # with dashboard_page:
1003
- # gr.Markdown("## πŸ“Š Dashboard")
1004
- # gr.Markdown(f"""
1005
- # ### System Overview
1006
- # - πŸ‘₯ Total Students: {len(students_data)}
1007
- # - πŸ‘¨β€πŸ« Total Teachers: {len(teachers_data)}
1008
- # - πŸ“š Total Courses: {len(courses_data)}
1009
-
1010
- # ### Quick Actions
1011
- # - View student performance
1012
- # - Access course materials
1013
- # - Generate learning insights
1014
- # """)
1015
-
1016
- # # Students Content
1017
- # students_page = gr.Group(visible=False)
1018
- # with students_page:
1019
- # gr.Markdown("## πŸ‘₯ Students")
1020
- # gr.DataFrame(
1021
- # value=students_data,
1022
- # headers=["ID", "Name", "Grade", "Program"]
1023
- # )
1024
-
1025
- # # Teachers Content
1026
- # teachers_page = gr.Group(visible=False)
1027
- # with teachers_page:
1028
- # gr.Markdown("## πŸ‘¨β€πŸ« Teachers")
1029
- # gr.DataFrame(
1030
- # value=teachers_data,
1031
- # headers=["ID", "Name", "Subject", "Qualification"]
1032
- # )
1033
-
1034
- # # Courses Content
1035
- # courses_page = gr.Group(visible=False)
1036
- # with courses_page:
1037
- # gr.Markdown("## πŸ“š Courses")
1038
- # gr.DataFrame(
1039
- # value=courses_data,
1040
- # headers=["ID", "Name", "Instructor", "Level"]
1041
- # )
1042
-
1043
- # # YouTube Tool Content
1044
- # youtube_page = gr.Group(visible=False)
1045
- # with youtube_page:
1046
- # gr.Markdown("## Agent for YouTube Content Exploration")
1047
- # with gr.Row():
1048
- # with gr.Column(scale=2):
1049
- # video_url = gr.Textbox(
1050
- # label="YouTube URL",
1051
- # placeholder="https://youtube.com/watch?v=..."
1052
- # )
1053
- # keywords = gr.Textbox(
1054
- # label="Keywords for Recommendations",
1055
- # placeholder="e.g., python programming, machine learning"
1056
- # )
1057
- # analyze_btn = gr.Button("πŸ” Analyze Video", variant="primary")
1058
-
1059
- # with gr.Column(scale=1):
1060
- # video_thumbnail = gr.Image(label="Video Preview")
1061
-
1062
- # with gr.Row():
1063
- # with gr.Column():
1064
- # summary = gr.Textbox(label="πŸ“ Summary", lines=8)
1065
- # sentiment = gr.Textbox(label="😊 Content Sentiment")
1066
- # with gr.Column():
1067
- # recommendations = gr.Textbox(label="🎯 Related Videos", lines=10)
1068
 
1069
- # def login_check(user, pwd):
1070
- # if USER_CREDENTIALS.get(user) == pwd:
1071
- # return {
1072
- # login_page: gr.update(visible=False),
1073
- # main_page: gr.update(visible=True),
1074
- # login_msg: ""
1075
- # }
1076
- # return {
1077
- # login_page: gr.update(visible=True),
1078
- # main_page: gr.update(visible=False),
1079
- # login_msg: "❌ Invalid credentials"
1080
- # }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1081
 
1082
- # def show_page(page_name):
1083
- # updates = {
1084
- # dashboard_page: gr.update(visible=False),
1085
- # students_page: gr.update(visible=False),
1086
- # teachers_page: gr.update(visible=False),
1087
- # courses_page: gr.update(visible=False),
1088
- # youtube_page: gr.update(visible=False)
1089
- # }
1090
- # updates[page_name] = gr.update(visible=True)
1091
- # return updates
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1092
 
1093
- # # Event Handlers
1094
- # login_btn.click(
1095
- # login_check,
1096
- # inputs=[username, password],
1097
- # outputs=[login_page, main_page, login_msg]
1098
- # )
 
 
 
 
1099
 
1100
- # nav_dashboard.click(lambda: show_page(dashboard_page), outputs=list(show_page(dashboard_page).keys()))
1101
- # nav_students.click(lambda: show_page(students_page), outputs=list(show_page(students_page).keys()))
1102
- # nav_teachers.click(lambda: show_page(teachers_page), outputs=list(show_page(teachers_page).keys()))
1103
- # nav_courses.click(lambda: show_page(courses_page), outputs=list(show_page(courses_page).keys()))
1104
- # nav_youtube.click(lambda: show_page(youtube_page), outputs=list(show_page(youtube_page).keys()))
 
1105
 
1106
- # analyze_btn.click(
1107
- # process_youtube_video,
1108
- # inputs=[video_url, keywords],
1109
- # outputs=[video_thumbnail, summary, sentiment, recommendations]
1110
- # )
1111
 
1112
- # logout_btn.click(
1113
- # lambda: {
1114
- # login_page: gr.update(visible=True),
1115
- # main_page: gr.update(visible=False)
1116
- # },
1117
- # outputs=[login_page, main_page]
1118
- # )
 
 
 
 
 
 
1119
 
1120
- # if __name__ == "__main__":
1121
- # app.launch()
1122
 
 
1
+ # import subprocess
2
+ # subprocess.check_call(["pip", "install", "transformers==4.34.0"])
3
+ # subprocess.check_call(["pip", "install", "torch>=1.7.1"])
4
+ # subprocess.check_call(["pip", "install", "youtube_transcript_api>=0.6.3"])
5
+ # subprocess.check_call(["pip", "install", "pytube"])
6
+ # subprocess.check_call(["pip", "install", "huggingface_hub>=0.19.0"])
7
+ # subprocess.check_call(["pip", "install", "PyPDF2>=3.0.1"])
8
+ # subprocess.check_call(["pip", "install", "google-generativeai"])
9
+ # subprocess.check_call(["pip", "install", "textblob>=0.17.1"])
10
+ # subprocess.check_call(["pip", "install", "python-dotenv>=1.0.0"])
11
+ # subprocess.check_call(["pip", "install", "genai"])
12
+ # subprocess.check_call(["pip", "install", "google-cloud-aiplatform==1.34.0"])
13
+ # import transformers
14
+ # import torch
15
+ # import os
16
+ # import youtube_transcript_api
17
+ # import pytube
18
+ # import gradio
19
+ # import PyPDF2
20
+ # import pathlib
21
+ # import pandas
22
+ # import numpy
23
+ # import textblob
24
+ # import gradio as gr
25
+ # from youtube_transcript_api import YouTubeTranscriptApi
26
+ # import google.generativeai as genai
27
+ # import requests
28
+ # from textblob import TextBlob
29
+ # import re
30
+ # #from google.cloud import generativeai
31
+ # from huggingface_hub import login
32
+ # from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
33
+ # def install_missing_packages():
34
+ # required_packages = {
35
+ # "torch":">=1.11.0",
36
+ # "transformers":">=4.34.0",
37
+ # "youtube_transcript_api" :">=0.6.3" ,
38
+ # "pytube":None,
39
+ # "huggingface_hub": ">=0.19.0",
40
+ # "PyPDF2": ">=3.0.1",
41
+ # "textblob":">=0.17.1",
42
+ # "python-dotenv":">=1.0.0",
43
+ # "genai":None,
44
+ # "google-generativeai": None,
45
+ # "google-cloud-aiplatform":"==1.34.0"
46
+ # }
47
 
48
 
49
+ # for package, version in required_packages.items():
50
+ # try:
51
+ # __import__(package)
52
+ # except ImportError:
53
+ # package_name = f"{package}{version}" if version else package
54
+ # subprocess.check_call(["pip", "install", package_name])
55
 
56
+ # install_missing_packages()
57
+ # # Configuration
58
 
59
+ # hf_token = os.getenv("HF_TOKEN")
60
+ # if hf_token:
61
+ # login(hf_token)
62
+ # else:
63
+ # raise ValueError("HF_TOKEN environment variable not set.")
64
 
65
+ # # Configuration
66
+ # USER_CREDENTIALS = {
67
+ # "admin": "password123",
68
+ # "teacher": "teach2024",
69
+ # "student": "learn2024"
70
+ # }
71
 
72
+ # import os
73
+ # from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
74
 
75
+ # # Use environment variables
76
+ # GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
77
+ # YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY")
78
 
79
+ # if not GOOGLE_API_KEY or not YOUTUBE_API_KEY:
80
+ # raise ValueError("Please set GOOGLE_API_KEY and YOUTUBE_API_KEY environment variables")
81
 
82
+ # genai.configure(api_key=GOOGLE_API_KEY)
83
 
84
+ # # Database
85
+ # students_data = [
86
+ # (1, "Alice", "A", "Computer Science"),
87
+ # (2, "Aliaa", "B", "Mathematics"),
88
+ # (3, "Charlie", "A", "Machine Learning"),
89
+ # (4, "Daan", "A", "Physics"),
90
+ # (5, "Jhon", "C", "Math"),
91
+ # (6, "Emma", "A+", "Computer Science")
92
+ # ]
93
 
94
+ # teachers_data = [
95
+ # (1, "Dr. Smith", "Math", "MS Mathematics"),
96
+ # (2, "Ms. Johnson", "Science", "MSc Physics"),
97
+ # (3, "Ms. Jack", "Artificial Intelligence Engineer", "MSc AI"),
98
+ # (4, "Ms. Evelyn", "Computer Science", "MSc Computer Science"),
99
+ # ]
100
 
101
+ # courses_data = [
102
+ # (1, "Algebra", "Dr. Smith", "Advanced"),
103
+ # (2, "Biology", "Ms. Mia", "Intermediate"),
104
+ # (3, "Machine Learning", "Ms. Jack", "Intermediate"),
105
+ # (4, "Computer Science", "Ms. Evelyn", "Intermediate"),
106
+ # (5, "Mathematics", "Ms. Smith", "Intermediate")
107
+ # ]
108
 
109
+ # def sanitize_text(text):
110
+ # """Remove invalid Unicode characters."""
111
+ # return text.encode("utf-8", "replace").decode("utf-8")
112
 
113
+ # def extract_video_id(url):
114
+ # if not url:
115
+ # return None
116
+ # patterns = [
117
+ # r'(?:v=|\/videos\/|embed\/|youtu.be\/|\/v\/|\/e\/|watch\?v=|\/watch\?v=)([^#\&\?]*)'
118
+ # ]
119
+ # for pattern in patterns:
120
+ # match = re.search(pattern, url)
121
+ # if match:
122
+ # return match.group(1)
123
+ # return None
124
 
125
 
126
 
127
+ # from textblob import TextBlob
128
+ # from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
129
+ # 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 subprocess
448
+ subprocess.check_call(["pip", "install", "transformers==4.34.0"])
449
+ subprocess.check_call(["pip", "install", "torch>=1.7.1"])
450
+ subprocess.check_call(["pip", "install", "youtube_transcript_api>=0.6.3"])
451
+ subprocess.check_call(["pip", "install", "pytube"])
452
+ subprocess.check_call(["pip", "install", "huggingface_hub>=0.19.0"])
453
+ subprocess.check_call(["pip", "install", "PyPDF2>=3.0.1"])
454
+ subprocess.check_call(["pip", "install", "google-generativeai"])
455
+ subprocess.check_call(["pip", "install", "textblob>=0.17.1"])
456
+ subprocess.check_call(["pip", "install", "python-dotenv>=1.0.0"])
457
+ subprocess.check_call(["pip", "install", "genai"])
458
+ subprocess.check_call(["pip", "install", "google-cloud-aiplatform==1.34.0"])
459
+ import transformers
460
+ import torch
461
+ import os
462
+ import youtube_transcript_api
463
+ import pytube
464
+ import gradio
465
+ import PyPDF2
466
+ import pathlib
467
+ import pandas
468
+ import numpy
469
+ import textblob
470
+ import gradio as gr
471
+ from youtube_transcript_api import YouTubeTranscriptApi
472
+ import google.generativeai as genai
473
+ import requests
474
+ from textblob import TextBlob
475
+ import re
476
+ #from google.cloud import generativeai
477
+ from huggingface_hub import login
478
+ from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
479
+ def install_missing_packages():
480
+ required_packages = {
481
+ "torch":">=1.11.0",
482
+ "transformers":">=4.34.0",
483
+ "youtube_transcript_api" :">=0.6.3" ,
484
+ "pytube":None,
485
+ "huggingface_hub": ">=0.19.0",
486
+ "PyPDF2": ">=3.0.1",
487
+ "textblob":">=0.17.1",
488
+ "python-dotenv":">=1.0.0",
489
+ "genai":None,
490
+ "google-generativeai": None,
491
+ "google-cloud-aiplatform":"==1.34.0"
492
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
493
 
 
 
 
494
 
495
+ for package, version in required_packages.items():
496
+ try:
497
+ __import__(package)
498
+ except ImportError:
499
+ package_name = f"{package}{version}" if version else package
500
+ subprocess.check_call(["pip", "install", package_name])
501
 
502
+ install_missing_packages()
503
+ # Configuration
504
 
505
+ hf_token = os.getenv("HF_TOKEN")
506
+ if hf_token:
507
+ login(hf_token)
508
+ else:
509
+ raise ValueError("HF_TOKEN environment variable not set.")
 
 
 
 
510
 
 
 
 
 
 
 
511
 
512
+ # Configuration
513
+ USER_CREDENTIALS = {
514
+ "admin": "password123",
515
+ "teacher": "teach2024",
516
+ "student": "learn2024"
517
+ }
 
518
 
519
+ import os
520
+ from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
 
521
 
522
+ # Use environment variables
523
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
524
+ YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY")
 
 
 
 
 
 
 
 
525
 
526
+ if not GOOGLE_API_KEY or not YOUTUBE_API_KEY:
527
+ raise ValueError("Please set GOOGLE_API_KEY and YOUTUBE_API_KEY environment variables")
528
 
529
+ genai.configure(api_key=GOOGLE_API_KEY)
 
 
 
 
 
530
 
531
+ # Database
532
+ students_data = [
533
+ (1, "Alice", "A", "Computer Science"),
534
+ (2, "Aliaa", "B", "Mathematics"),
535
+ (3, "Charlie", "A", "Machine Learning"),
536
+ (4, "Daan", "A", "Physics"),
537
+ (5, "Jhon", "C", "Math"),
538
+ (6, "Emma", "A+", "Computer Science")
539
+ ]
540
 
541
+ teachers_data = [
542
+ (1, "Dr. Smith", "Math", "MS Mathematics"),
543
+ (2, "Ms. Johnson", "Science", "MSc Physics"),
544
+ (3, "Ms. Jack", "Artificial Intelligence Engineer", "MSc AI"),
545
+ (4, "Ms. Evelyn", "Computer Science", "MSc Computer Science"),
546
+ ]
547
 
548
+ courses_data = [
549
+ (1, "Algebra", "Dr. Smith", "Advanced"),
550
+ (2, "Biology", "Ms. Mia", "Intermediate"),
551
+ (3, "Machine Learning", "Ms. Jack", "Intermediate"),
552
+ (4, "Computer Science", "Ms. Evelyn", "Intermediate"),
553
+ (5, "Mathematics", "Ms. Smith", "Intermediate")
554
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
 
556
+ def sanitize_text(text):
557
+ """Remove invalid Unicode characters."""
558
+ return text.encode("utf-8", "replace").decode("utf-8")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559
 
560
+ def extract_video_id(url):
561
+ if not url:
562
+ return None
563
+ patterns = [
564
+ r'(?:v=|\/videos\/|embed\/|youtu.be\/|\/v\/|\/e\/|watch\?v=|\/watch\?v=)([^#\&\?]*)'
565
+ ]
566
+ for pattern in patterns:
567
+ match = re.search(pattern, url)
568
+ if match:
569
+ return match.group(1)
570
+ return None
571
 
 
 
 
 
 
572
 
573
  # def process_youtube_video(url="", keywords=""):
574
  # try:
575
  # # Initialize variables
576
+ # thumbnail = None # Default value for thumbnail
577
  # summary = "No transcript available"
578
  # sentiment_label = "N/A"
 
 
579
 
580
  # if not url.strip():
581
+ # return None, "Please enter a YouTube URL", "N/A", ""
582
+
583
  # video_id = extract_video_id(url)
584
  # if not video_id:
585
+ # return None, "Invalid YouTube URL", "N/A", ""
586
 
587
  # thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
588
 
589
  # try:
590
+ # # Try multiple transcript options
591
  # transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
592
+
593
  # try:
594
  # transcript = transcript_list.find_transcript(['en'])
595
  # except:
596
+ # try:
597
+ # transcript = transcript_list.find_transcript(['en-US'])
598
+ # except:
599
+ # try:
600
+ # # Try auto-generated
601
+ # transcript = transcript_list.find_generated_transcript(['en'])
602
+ # except:
603
+ # raise NoTranscriptFound()
604
 
605
  # text = " ".join([t['text'] for t in transcript.fetch()])
606
+
 
 
 
 
 
 
 
 
 
607
  # # Generate summary
608
  # model = genai.GenerativeModel("gemini-pro")
609
+ # summary = model.generate_content(f"Summarize this: {text[:4000]}").text
610
+
611
+ # # Analysis
612
+ # sentiment = TextBlob(text[:1000]).sentiment
613
+ # sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
614
 
615
  # except TranscriptsDisabled:
616
+ # # Fallback: Use video metadata if available
617
  # metadata = get_video_metadata(video_id)
618
+ # summary = metadata.get("description", "⚠️ This video has disabled subtitles. No transcript available.")
619
+ # except NoTranscriptFound:
620
+ # # Fallback: Use video metadata if available
621
+ # metadata = get_video_metadata(video_id)
622
+ # summary = metadata.get("description", "⚠️ No English transcript available. No transcript available.")
623
+ # except Exception as e:
624
+ # return thumbnail, f"⚠️ Error: {str(e)}", "N/A", ""
625
+
626
+ # # Get recommendations
627
+ # if keywords.strip():
628
+ # recommendations = get_recommendations(keywords)
629
+ # else:
630
+ # recommendations = ""
631
+
632
+ # return thumbnail, summary, sentiment_label, recommendations
633
+
634
+ # except Exception as e:
635
+ # return None, f"Error: {str(e)}", "N/A", ""
636
+
637
+
638
+ # def get_video_metadata(video_id):
639
+ # """
640
+ # Fetches video metadata such as title and description using the YouTube Data API.
641
+ # """
642
+ # try:
643
+ # from googleapiclient.discovery import build
644
+
645
+ # # Replace with your YouTube Data API key
646
+ # API_KEY = "AIzaSyB7X-RYjZmUuDSMTQsvCfyzURw5bhqOto4"
647
+ # youtube = build("youtube", "v3", developerKey=API_KEY)
648
+ # request = youtube.videos().list(part="snippet", id=video_id)
649
+ # response = request.execute()
650
+
651
+ # if "items" in response and len(response["items"]) > 0:
652
+ # snippet = response["items"][0]["snippet"]
653
+ # return {
654
+ # "title": snippet.get("title", "No title available"),
655
+ # "description": snippet.get("description", "No description available"),
656
+ # }
657
+ # return {}
658
+
659
+ # except Exception as e:
660
+ # return {"title": "Error fetching metadata", "description": str(e)}
661
+
662
+ # # Get recommendations
663
+ # if keywords.strip():
664
+ # recommendations = get_recommendations(keywords)
665
+ # else:
666
+ # recommendations = ""
667
+
668
+ # return thumbnail, summary, sentiment_label, recommendations
669
+
670
+ # except Exception as e:
671
+ # return None, f"Error: {str(e)}", "N/A", ""
672
+
673
+ from textblob import TextBlob
674
+ from youtube_transcript_api import YouTubeTranscriptApi, TranscriptsDisabled, NoTranscriptFound
675
+ import re
676
+ from collections import Counter
677
+ from googleapiclient.discovery import build
678
+ # def process_youtube_video(url="", keywords=""):
679
+ # try:
680
+ # # Initialize variables
681
+ # thumbnail = None
682
+ # summary = "No transcript available"
683
+ # sentiment_label = "N/A"
684
+ # recommendations = ""
685
+ # subtitle_info = "No additional information available"
686
+
687
+ # if not url.strip():
688
+ # return None, "Please enter a YouTube URL", "N/A", "", ""
689
+
690
+ # video_id = extract_video_id(url)
691
+ # if not video_id:
692
+ # return None, "Invalid YouTube URL", "N/A", "", ""
693
+
694
+ # thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
695
+
696
+ # try:
697
+ # # Fetch transcript
698
+ # transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
699
+ # transcript = None
700
+ # try:
701
+ # transcript = transcript_list.find_transcript(['en'])
702
+ # except:
703
+ # transcript = transcript_list.find_generated_transcript(['en'])
704
+
705
+ # text = " ".join([t['text'] for t in transcript.fetch()])
706
+ # if not text.strip():
707
+ # raise ValueError("Transcript is empty")
708
+
709
+ # # Generate summary
710
+ # model = genai.GenerativeModel("gemini-pro")
711
+ # summary = model.generate_content(f"Summarize this: {text[:4000]}").text
712
+
713
+ # # Extract subtitle information
714
+ # subtitle_info = extract_subtitle_info(text)
715
+
716
+ # # Sentiment analysis
717
+ # sentiment = TextBlob(text[:1000]).sentiment
718
+ # sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
719
+
720
+ # except TranscriptsDisabled:
721
+ # metadata = get_video_metadata(video_id)
722
+ # summary = metadata.get("description", "⚠️ This video has disabled subtitles.")
723
+ # sentiment_label = "N/A"
724
+ # subtitle_info = "No subtitles available for analysis."
725
  # except NoTranscriptFound:
726
  # metadata = get_video_metadata(video_id)
727
  # summary = metadata.get("description", "⚠️ No English transcript available.")
 
744
  # """
745
  # Extracts the video ID from a YouTube URL.
746
  # """
747
+ # import re
748
  # match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11})", url)
749
  # return match.group(1) if match else None
750
 
 
754
  # Fetches video metadata such as title and description using the YouTube Data API.
755
  # """
756
  # try:
757
+ # from googleapiclient.discovery import build
758
+
759
+ # # Replace with your YouTube Data API key
760
+ # YOUTUBE_API_KEY = "AIzaSyD_SDF4lC3vpHVAMnBOcN2ZCTz7dRjUc98"
761
  # youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
762
  # request = youtube.videos().list(part="snippet", id=video_id)
763
  # response = request.execute()
 
784
  # sentences = text.split(". ")
785
 
786
  # # Example: Extract key topics or keywords
787
+ # from collections import Counter
788
  # words = text.split()
789
  # common_words = Counter(words).most_common(10)
790
  # key_topics = ", ".join([word for word, count in common_words])
 
797
  # return f"Error extracting subtitle information: {str(e)}"
798
 
799
 
800
+ def process_youtube_video(url="", keywords=""):
801
+ try:
802
+ # Initialize variables
803
+ thumbnail = None
804
+ summary = "No transcript available"
805
+ sentiment_label = "N/A"
806
+ recommendations = ""
807
+ subtitle_info = "No additional information available"
808
 
809
+ if not url.strip():
810
+ return None, "Please enter a YouTube URL", "N/A", "", ""
811
 
812
+ video_id = extract_video_id(url)
813
+ if not video_id:
814
+ return None, "Invalid YouTube URL", "N/A", "", ""
 
 
 
 
815
 
816
+ thumbnail = f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg"
817
 
818
+ try:
819
+ # Fetch transcript
820
+ transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
821
+ transcript = None
822
+ try:
823
+ transcript = transcript_list.find_transcript(['en'])
824
+ except:
825
+ transcript = transcript_list.find_generated_transcript(['en'])
826
 
827
+ text = " ".join([t['text'] for t in transcript.fetch()])
828
+ if not text.strip():
829
+ raise ValueError("Transcript is empty")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
830
 
831
+ # Clean up the text for sentiment analysis
832
+ cleaned_text = clean_text_for_analysis(text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
833
 
834
+ # Sentiment analysis
835
+ sentiment = TextBlob(cleaned_text).sentiment # Use cleaned text for sentiment analysis
836
+ sentiment_label = f"{'Positive' if sentiment.polarity > 0 else 'Negative' if sentiment.polarity < 0 else 'Neutral'} ({sentiment.polarity:.2f})"
837
+
838
+ # Generate summary
839
+ model = genai.GenerativeModel("gemini-pro")
840
+ summary = model.generate_content(f"Summarize this: {cleaned_text[:4000]}").text
841
+
842
+ # Extract subtitle information
843
+ subtitle_info = extract_subtitle_info(cleaned_text)
844
+
845
+ except TranscriptsDisabled:
846
+ metadata = get_video_metadata(video_id)
847
+ summary = metadata.get("description", "⚠️ This video has disabled subtitles.")
848
+ sentiment_label = "N/A"
849
+ subtitle_info = "No subtitles available for analysis."
850
+ except NoTranscriptFound:
851
+ metadata = get_video_metadata(video_id)
852
+ summary = metadata.get("description", "⚠️ No English transcript available.")
853
+ sentiment_label = "N/A"
854
+ subtitle_info = "No subtitles available for analysis."
855
+ except Exception as e:
856
+ return thumbnail, f"⚠️ Error processing transcript: {str(e)}", "N/A", "", ""
857
+
858
+ # Get recommendations
859
+ if keywords.strip():
860
+ recommendations = get_recommendations(keywords)
861
+
862
+ return thumbnail, summary, sentiment_label, subtitle_info, recommendations
863
+
864
+ except Exception as e:
865
+ return None, f"Error: {str(e)}", "N/A", "", ""
866
+
867
+
868
+ def extract_video_id(url):
869
+ """
870
+ Extracts the video ID from a YouTube URL.
871
+ """
872
+ match = re.search(r"(?:v=|\/)([0-9A-Za-z_-]{11})", url)
873
+ return match.group(1) if match else None
874
+
875
+
876
+ def get_video_metadata(video_id):
877
+ """
878
+ Fetches video metadata such as title and description using the YouTube Data API.
879
+ """
880
+ try:
881
+ YOUTUBE_API_KEY = "AIzaSyD_SDF4lC3vpHVAMnBOcN2ZCTz7dRjUc98" # Replace with your YouTube Data API key
882
+ youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
883
+ request = youtube.videos().list(part="snippet", id=video_id)
884
+ response = request.execute()
885
+
886
+ if "items" in response and len(response["items"]) > 0:
887
+ snippet = response["items"][0]["snippet"]
888
+ return {
889
+ "title": snippet.get("title", "No title available"),
890
+ "description": snippet.get("description", "No description available"),
891
+ }
892
+ return {}
893
+
894
+ except Exception as e:
895
+ return {"title": "Error fetching metadata", "description": str(e)}
896
+
897
+
898
+ def extract_subtitle_info(text):
899
+ """
900
+ Extracts meaningful information from the subtitles.
901
+ This could include topics, key insights, or a breakdown of the content.
902
+ """
903
+ try:
904
+ # Split text into sentences for better analysis
905
+ sentences = text.split(". ")
906
+
907
+ # Example: Extract key topics or keywords
908
+ words = text.split()
909
+ common_words = Counter(words).most_common(10)
910
+ key_topics = ", ".join([word for word, count in common_words])
911
+
912
+ # Example: Provide a breakdown of the content
913
+ info = f"Key topics discussed: {key_topics}. \nNumber of sentences: {len(sentences)}. \nTotal words: {len(words)}."
914
+
915
+ return info
916
+ except Exception as e:
917
+ return f"Error extracting subtitle information: {str(e)}"
918
+
919
+
920
+ def clean_text_for_analysis(text):
921
+ """
922
+ Cleans the transcript text by removing extra spaces, line breaks, and non-text elements.
923
+ """
924
+ # Remove extra spaces and line breaks
925
+ cleaned_text = " ".join(text.split())
926
+ return cleaned_text
927
+
928
+
929
+ def get_recommendations(keywords):
930
+ """
931
+ Fetches related video recommendations based on the provided keywords.
932
+ This function can be expanded with a proper API or custom logic.
933
+ """
934
+ # Placeholder for fetching recommendations based on keywords
935
+ return f"Recommendations for: {keywords}" # Dummy return for now
936
+
937
+
938
+
939
+ def get_recommendations(keywords, max_results=5):
940
+ if not keywords:
941
+ return "Please provide search keywords"
942
+ try:
943
+ response = requests.get(
944
+ "https://www.googleapis.com/youtube/v3/search",
945
+ params={
946
+ "part": "snippet",
947
+ "q": f"educational {keywords}",
948
+ "type": "video",
949
+ "maxResults": max_results,
950
+ "relevanceLanguage": "en",
951
+ "key": YOUTUBE_API_KEY
952
+ }
953
+ ).json()
954
+
955
+ results = []
956
+ for item in response.get("items", []):
957
+ title = item["snippet"]["title"]
958
+ channel = item["snippet"]["channelTitle"]
959
+ video_id = item["id"]["videoId"]
960
+ results.append(f"πŸ“Ί {title}\nπŸ‘€ {channel}\nπŸ”— https://youtube.com/watch?v={video_id}\n")
961
+
962
+ return "\n".join(results) if results else "No recommendations found"
963
+ except Exception as e:
964
+ return f"Error: {str(e)}"
965
+
966
+ # Gradio Interface
967
+ with gr.Blocks(theme=gr.themes.Soft()) as app:
968
+ # Login Page
969
+ with gr.Group() as login_page:
970
+ gr.Markdown("# πŸŽ“ Educational Learning Management System")
971
+ username = gr.Textbox(label="Username")
972
+ password = gr.Textbox(label="Password", type="password")
973
+ login_btn = gr.Button("Login", variant="primary")
974
+ login_msg = gr.Markdown()
975
 
976
+ # Main Interface
977
+ with gr.Group(visible=False) as main_page:
978
+ with gr.Row():
979
+ with gr.Column(scale=1):
980
+ gr.Markdown("### πŸ“‹ Navigation")
981
+ nav_dashboard = gr.Button("πŸ“Š Dashboard", variant="primary")
982
+ nav_students = gr.Button("πŸ‘₯ Students")
983
+ nav_teachers = gr.Button("πŸ‘¨β€πŸ« Teachers")
984
+ nav_courses = gr.Button("πŸ“š Courses")
985
+ nav_youtube = gr.Button("πŸŽ₯ YouTube Tool")
986
+ logout_btn = gr.Button("πŸšͺ Logout", variant="stop")
987
+
988
+ with gr.Column(scale=3):
989
+ # Dashboard Content
990
+ dashboard_page = gr.Group()
991
+ with dashboard_page:
992
+ gr.Markdown("## πŸ“Š Dashboard")
993
+ gr.Markdown(f"""
994
+ ### System Overview
995
+ - πŸ‘₯ Total Students: {len(students_data)}
996
+ - πŸ‘¨β€πŸ« Total Teachers: {len(teachers_data)}
997
+ - πŸ“š Total Courses: {len(courses_data)}
998
+
999
+ ### Quick Actions
1000
+ - View student performance
1001
+ - Access course materials
1002
+ - Generate learning insights
1003
+ """)
1004
+
1005
+ # Students Content
1006
+ students_page = gr.Group(visible=False)
1007
+ with students_page:
1008
+ gr.Markdown("## πŸ‘₯ Students")
1009
+ gr.DataFrame(
1010
+ value=students_data,
1011
+ headers=["ID", "Name", "Grade", "Program"]
1012
+ )
1013
+
1014
+ # Teachers Content
1015
+ teachers_page = gr.Group(visible=False)
1016
+ with teachers_page:
1017
+ gr.Markdown("## πŸ‘¨β€πŸ« Teachers")
1018
+ gr.DataFrame(
1019
+ value=teachers_data,
1020
+ headers=["ID", "Name", "Subject", "Qualification"]
1021
+ )
1022
+
1023
+ # Courses Content
1024
+ courses_page = gr.Group(visible=False)
1025
+ with courses_page:
1026
+ gr.Markdown("## πŸ“š Courses")
1027
+ gr.DataFrame(
1028
+ value=courses_data,
1029
+ headers=["ID", "Name", "Instructor", "Level"]
1030
+ )
1031
+
1032
+ # YouTube Tool Content
1033
+ youtube_page = gr.Group(visible=False)
1034
+ with youtube_page:
1035
+ gr.Markdown("## Agent for YouTube Content Exploration")
1036
+ with gr.Row():
1037
+ with gr.Column(scale=2):
1038
+ video_url = gr.Textbox(
1039
+ label="YouTube URL",
1040
+ placeholder="https://youtube.com/watch?v=..."
1041
+ )
1042
+ keywords = gr.Textbox(
1043
+ label="Keywords for Recommendations",
1044
+ placeholder="e.g., python programming, machine learning"
1045
+ )
1046
+ analyze_btn = gr.Button("πŸ” Analyze Video", variant="primary")
1047
+
1048
+ with gr.Column(scale=1):
1049
+ video_thumbnail = gr.Image(label="Video Preview")
1050
+
1051
+ with gr.Row():
1052
+ with gr.Column():
1053
+ summary = gr.Textbox(label="πŸ“ Summary", lines=8)
1054
+ sentiment = gr.Textbox(label="😊 Content Sentiment")
1055
+ with gr.Column():
1056
+ recommendations = gr.Textbox(label="🎯 Related Videos", lines=10)
1057
+
1058
+ def login_check(user, pwd):
1059
+ if USER_CREDENTIALS.get(user) == pwd:
1060
+ return {
1061
+ login_page: gr.update(visible=False),
1062
+ main_page: gr.update(visible=True),
1063
+ login_msg: ""
1064
+ }
1065
+ return {
1066
+ login_page: gr.update(visible=True),
1067
+ main_page: gr.update(visible=False),
1068
+ login_msg: "❌ Invalid credentials"
1069
+ }
1070
 
1071
+ def show_page(page_name):
1072
+ updates = {
1073
+ dashboard_page: gr.update(visible=False),
1074
+ students_page: gr.update(visible=False),
1075
+ teachers_page: gr.update(visible=False),
1076
+ courses_page: gr.update(visible=False),
1077
+ youtube_page: gr.update(visible=False)
1078
+ }
1079
+ updates[page_name] = gr.update(visible=True)
1080
+ return updates
1081
 
1082
+ # Event Handlers
1083
+ login_btn.click(
1084
+ login_check,
1085
+ inputs=[username, password],
1086
+ outputs=[login_page, main_page, login_msg]
1087
+ )
1088
 
1089
+ nav_dashboard.click(lambda: show_page(dashboard_page), outputs=list(show_page(dashboard_page).keys()))
1090
+ nav_students.click(lambda: show_page(students_page), outputs=list(show_page(students_page).keys()))
1091
+ nav_teachers.click(lambda: show_page(teachers_page), outputs=list(show_page(teachers_page).keys()))
1092
+ nav_courses.click(lambda: show_page(courses_page), outputs=list(show_page(courses_page).keys()))
1093
+ nav_youtube.click(lambda: show_page(youtube_page), outputs=list(show_page(youtube_page).keys()))
1094
 
1095
+ analyze_btn.click(
1096
+ process_youtube_video,
1097
+ inputs=[video_url, keywords],
1098
+ outputs=[video_thumbnail, summary, sentiment, recommendations]
1099
+ )
1100
+
1101
+ logout_btn.click(
1102
+ lambda: {
1103
+ login_page: gr.update(visible=True),
1104
+ main_page: gr.update(visible=False)
1105
+ },
1106
+ outputs=[login_page, main_page]
1107
+ )
1108
 
1109
+ if __name__ == "__main__":
1110
+ app.launch()
1111