import os
import subprocess
import threading
import time
import re
import tkinter as tk
from tkinter import filedialog, messagebox, Scrollbar, Text, END
from googleapiclient.discovery import build
# YouTube API key
YOUTUBE_API_KEY = 'AIzaSyCzS7PGThVFxD83UFbfU5DOSZBMTxNpEeA'
class AdvancedFileSearchApp(tk.Tk):
def __init__(self):
super().__init__()
self.title("Najeeb Advanced File Search with YouTube and Media Controls")
self.geometry("900x700")
self.configure(bg="#282C34")
self.folder_path = None
self.lines = []
self.stop_event = threading.Event()
self.create_widgets()
def create_widgets(self):
# Top Frame for main controls
self.top_frame = tk.Frame(self, bg="#282C34")
self.top_frame.pack(fill=tk.X, pady=10)
# Drive Selector
self.drive_var = tk.StringVar()
self.drive_dropdown = tk.OptionMenu(self.top_frame, self.drive_var, *self.get_drives())
self.drive_dropdown.config(width=10)
self.drive_var.set(self.get_drives()[0] if self.get_drives() else "")
self.drive_dropdown.pack(side=tk.LEFT, padx=5)
# First Search Entry
self.search_var = tk.StringVar()
self.search_entry = tk.Entry(self.top_frame, textvariable=self.search_var, width=30)
self.search_entry.pack(side=tk.LEFT, padx=5)
# Search Button
self.search_btn = tk.Button(self.top_frame, text="Search Text", command=self.search_files, bg='lightcoral', fg='black')
self.search_btn.pack(side=tk.LEFT, padx=5)
# Search Drive Button
self.search_drive_btn = tk.Button(self.top_frame, text="Search Drive", command=self.search_drive, bg='lightgreen', fg='black')
self.search_drive_btn.pack(side=tk.LEFT, padx=5)
# YouTube Search Button
self.youtube_search_btn = tk.Button(self.top_frame, text="Search YouTube", command=self.search_youtube, bg='lightyellow', fg='black')
self.youtube_search_btn.pack(side=tk.LEFT, padx=5)
# Play Button
self.play_btn = tk.Button(self.top_frame, text="Play Selected", command=self.play_selected, bg='lightpink', fg='black')
self.play_btn.pack(side=tk.LEFT, padx=5)
# Capture Video Button
self.capture_video_btn = tk.Button(self.top_frame, text="Capture Video", command=self.capture_video, bg='lightblue', fg='black')
self.capture_video_btn.pack(side=tk.LEFT, padx=5)
# Record Audio Button
self.record_audio_btn = tk.Button(self.top_frame, text="Record Audio", command=self.record_audio, bg='lightgreen', fg='black')
self.record_audio_btn.pack(side=tk.LEFT, padx=5)
# Capture Screenshots Button
self.capture_screenshots_btn = tk.Button(self.top_frame, text="Capture Screenshots", command=self.capture_screenshots, bg='lightcoral', fg='black')
self.capture_screenshots_btn.pack(side=tk.LEFT, padx=5)
# Second Line Frame for additional controls
self.second_line_frame = tk.Frame(self, bg="#282C34")
self.second_line_frame.pack(fill=tk.X, pady=10)
# Select Folder Button
self.select_folder_btn = tk.Button(self.second_line_frame, text="Select Folder", command=self.select_folder, bg='lightgreen', fg='black')
self.select_folder_btn.pack(side=tk.LEFT, padx=5)
# Second Search Entry
self.search_var2 = tk.StringVar()
self.search_entry2 = tk.Entry(self.second_line_frame, textvariable=self.search_var2, width=30)
self.search_entry2.pack(side=tk.LEFT, padx=5)
# Search Button
self.search_btn = tk.Button(self.second_line_frame, text="Search Text All", command=self.search_files, bg='lightcoral', fg='black')
self.search_btn.pack(side=tk.LEFT, padx=5)
# Save List Button
self.save_list_btn = tk.Button(self.second_line_frame, text="Save List", command=self.save_list, bg='lightblue', fg='black')
self.save_list_btn.pack(side=tk.LEFT, padx=5)
# Text widget with Scrollbars
self.text_frame = tk.Frame(self, bg="#282C34")
self.text_frame.pack(fill=tk.BOTH, expand=True)
self.result_area = Text(self.text_frame, wrap=tk.NONE, bg='#1E2127', fg='#ABB2BF')
self.result_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.scrollbar_y = Scrollbar(self.text_frame, orient=tk.VERTICAL)
self.scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
self.scrollbar_x = Scrollbar(self, orient=tk.HORIZONTAL)
self.scrollbar_x.pack(fill=tk.X)
self.result_area.config(yscrollcommand=self.scrollbar_y.set, xscrollcommand=self.scrollbar_x.set)
self.scrollbar_y.config(command=self.result_area.yview)
self.scrollbar_x.config(command=self.result_area.xview)
def get_drives(self):
"""Return a list of all available drives on the system."""
drives = []
for drive in range(ord('A'), ord('Z')+1):
drive_letter = f"{chr(drive)}:\\"
if os.path.exists(drive_letter):
drives.append(drive_letter)
return drives
def select_folder(self):
self.folder_path = filedialog.askdirectory()
if self.folder_path:
messagebox.showinfo("Selected Folder", f"Selected folder: {self.folder_path}")
def search_files(self):
keyword1 = self.search_entry.get().strip()
keyword2 = self.search_entry2.get().strip()
if not self.folder_path:
self.result_area.insert(END, "Please select a folder first.\n")
return
if not keyword1 and not keyword2:
self.result_area.insert(END, "Please enter at least one keyword to search for.\n")
return
self.result_area.delete(1.0, END) # Clear the text field
for root, dirs, files in os.walk(self.folder_path):
for file in files:
if file.endswith(('.txt', '.ls', '.ini', '.m3u', '.m3u8', '.py', '.pyw', '.ahk', '.bat', '.cmd', '.vbs', '.htm', '.html', '.au3', '.reg')):
file_path = os.path.join(root, file)
self.search_in_file(file_path, keyword1, keyword2)
def search_in_file(self, file_path, keyword1, keyword2):
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
lines = f.readlines()
for i, line in enumerate(lines):
if (keyword1.lower() in line.lower()) or (keyword2.lower() in line.lower()):
self.result_area.insert(END, f"{file_path} - Line {i+1}: {line.strip()}\n")
except Exception as e:
self.result_area.insert(END, f"Error reading {file_path}: {str(e)}\n")
def save_list(self):
save_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
if save_path:
with open(save_path, "w", encoding="utf-8") as file:
file.writelines(self.lines)
messagebox.showinfo("Save List", f"List saved to {save_path}")
def search(self, event=None):
drive = self.drive_var.get()
search_term = self.search_var.get().lower()
self.result_area.delete(1.0, END)
if not drive or not search_term:
messagebox.showwarning("Warning", "Please select a drive and enter a search term.")
return
# Search for files
for root, dirs, files in os.walk(drive):
for file in files:
if search_term in file.lower():
self.result_area.insert(END, os.path.join(root, file) + "\n")
def search_drive(self):
self.search() # Reuse the search function for drive-specific searches
def search_youtube(self):
search_term = self.search_var.get().strip()
if not search_term:
messagebox.showwarning("Warning", "Please enter a search term.")
return
self.result_area.delete(1.0, END)
youtube = build('youtube', 'v3', developerKey=YOUTUBE_API_KEY)
request = youtube.search().list(
q=search_term,
part='snippet',
type='video',
maxResults=5
)
response = request.execute()
self.video_urls = []
for item in response['items']:
video_title = item['snippet']['title']
video_id = item['id']['videoId']
video_url = f"https://www.youtube.com/watch?v={video_id}"
self.result_area.insert(END, f"{video_title}\n{video_url}\n\n")
self.video_urls.append(video_url)
def play_selected(self):
try:
selected_text = self.result_area.get(tk.SEL_FIRST, tk.SEL_LAST).strip()
if selected_text:
potplayer_path = "C:\Program Files\DAUM\PotPlayer\PotPlayerMini.exe"
if os.path.exists(potplayer_path):
subprocess.Popen([potplayer_path, selected_text], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
else:
messagebox.showerror("Error", "PotPlayer not found at the specified path.")
else:
messagebox.showwarning("Warning", "No text selected to play.")
except tk.TclError:
messagebox.showwarning("Warning", "No text selected to play.")
def capture_video(self):
try:
selected_text = self.result_area.get(tk.SEL_FIRST, tk.SEL_LAST).strip()
url_match = re.search(r'(https?://\S+)', selected_text)
if url_match:
url = url_match.group(0)
filename = filedialog.asksaveasfilename(defaultextension=".mp4", filetypes=[("MP4 files", "*.mp4")])
if filename:
command = ['ffmpeg', '-y', '-i', url, '-t', '00:03:55', '-c', 'copy', filename]
threading.Thread(target=lambda: subprocess.run(command)).start()
messagebox.showinfo("Capturing", f"Capturing 03:55 minutes of video to {filename}")
else:
messagebox.showerror("Error", "Selected text is not a valid URL.")
except tk.TclError:
messagebox.showerror("Error", "No text selected.")
def record_audio(self):
try:
selected_text = self.result_area.get(tk.SEL_FIRST, tk.SEL_LAST).strip()
url_match = re.search(r'(https?://\S+)', selected_text)
if url_match:
url = url_match.group(0)
filename = filedialog.asksaveasfilename(defaultextension=".mp3", filetypes=[("MP3 files", "*.mp3")])
if filename:
command = ['ffmpeg', '-y', '-i', url, '-f', 'mp3', '-c:a', 'libmp3lame', filename]
threading.Thread(target=lambda: subprocess.run(command)).start()
messagebox.showinfo("Recording", f"Recording audio to {filename}")
else:
messagebox.showerror("Error", "Selected text is not a valid URL.")
except tk.TclError:
messagebox.showerror("Error", "No text selected.")
def capture_screenshots(self):
def take_screenshots(url, filename_base, interval, num_screenshots):
for i in range(num_screenshots):
if self.stop_event.is_set():
break
filename = f"{filename_base}_{i + 1}.png"
command = ['ffmpeg', '-y', '-i', url, '-vframes', '1', filename]
subprocess.run(command)
time.sleep(interval)
messagebox.showinfo("Capturing Screenshots", f"Captured {i + 1} screenshots every {interval} seconds to {filename_base}")
try:
selected_text = self.result_area.get(tk.SEL_FIRST, tk.SEL_LAST).strip()
url_match = re.search(r'(https?://\S+)', selected_text)
if url_match:
url = url_match.group(0)
filename_base = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png")])
if filename_base:
self.stop_event.clear()
interval = 2
num_screenshots = 10
threading.Thread(target=take_screenshots, args=(url, filename_base, interval, num_screenshots)).start()
else:
messagebox.showerror("Error", "Selected text is not a valid URL.")
except tk.TclError:
messagebox.showerror("Error", "No text selected.")
def stop_screenshots_capture(self):
self.stop_event.set()
messagebox.showinfo("Screenshot Capture", "Stopping screenshot capture.")
if __name__ == "__main__":
app = AdvancedFileSearchApp()
app.mainloop()