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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +917 -917
app.py CHANGED
@@ -1,727 +1,863 @@
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,7 +880,6 @@ from googleapiclient.discovery import build
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,10 +889,7 @@ from googleapiclient.discovery import build
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,7 +916,6 @@ from googleapiclient.discovery import build
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])
@@ -795,328 +926,197 @@ from googleapiclient.discovery import build
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.")
864
- sentiment_label = "N/A"
865
- subtitle_info = "No subtitles available for analysis."
866
- except Exception as e:
867
- return thumbnail, f"⚠️ Error processing transcript: {str(e)}", "N/A", "", ""
868
-
869
- # Get recommendations
870
- if keywords.strip():
871
- recommendations = get_recommendations(keywords)
872
-
873
- return thumbnail, summary, sentiment_label, subtitle_info, recommendations
874
-
875
- except Exception as e:
876
- return None, f"Error: {str(e)}", "N/A", "", ""
877
-
878
 
879
- def extract_video_id(url):
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
 
 
 
 
 
 
 
 
886
 
887
- def get_video_metadata(video_id):
888
- """
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()
896
 
897
- if "items" in response and len(response["items"]) > 0:
898
- snippet = response["items"][0]["snippet"]
899
- return {
900
- "title": snippet.get("title", "No title available"),
901
- "description": snippet.get("description", "No description available"),
902
- }
903
- return {}
904
 
905
- except Exception as e:
906
- return {"title": "Error fetching metadata", "description": str(e)}
907
 
908
 
909
- def extract_subtitle_info(text):
910
- """
911
- Extracts meaningful information from the subtitles.
912
- This could include topics, key insights, or a breakdown of the content.
913
- """
914
- try:
915
- # Split text into sentences for better analysis
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])
922
-
923
- # Example: Provide a breakdown of the content
924
- info = f"Key topics discussed: {key_topics}. \nNumber of sentences: {len(sentences)}. \nTotal words: {len(words)}."
925
-
926
- return info
927
- except Exception as e:
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.")
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
  # """
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
  # 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
  # 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])
 
926
  # return info
927
  # except Exception as e:
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