Py2Exe: https://github.com/pyinstaller/pyinstaller *python-help Download multiple youtube links to mp4 -------------------------------------- from pytubefix import YouTube import os import re import tkinter as tk from tkinter import ttk def sanitize_filename(filename): """ Removes special characters from the filename. """ return re.sub(r'[^\w\-_\. ]', '_', filename) def log_error(video_url, error_message): """ Appends an error message to log.txt. """ with open("log.txt", "a") as log_file: log_file.write(f"Error downloading {video_url}: {error_message}\n") def download_video(video_url): """ Downloads a single YouTube video by URL. """ try: video = YouTube(video_url) filename = f"{sanitize_filename(video.title)}.mp4" print(f"Downloading: {filename}") stream = video.streams.filter(file_extension='mp4').first() # Check if the stream is available if not stream: print(f"No MP4 streams available for: {video_url}") log_error(video_url, "No MP4 streams available.") return stream.download(filename=filename) print(f"Download complete: {filename}") except Exception as e: print(f"Error downloading video {video_url}: {e}") log_error(video_url, str(e)) def download_videos_from_list(video_urls): """ Downloads multiple YouTube videos from a list of URLs. """ for url in video_urls.splitlines(): url = url.strip() # Remove any extra whitespace if url: # Ensure the URL is not empty download_video(url) def main(): root = tk.Tk() root.title("YouTube Video Downloader") url_label = ttk.Label(root, text="YouTube Video URLs (one per line):") url_label.pack(pady=10) url_entry = tk.Text(root, height=10, width=50) # Use tk.Text for multi-line input url_entry.pack(pady=10) download_button = ttk.Button(root, text="Download Videos", command=lambda: download_videos_from_list(url_entry.get("1.0", tk.END))) download_button.pack(pady=10) root.mainloop() if __name__ == "__main__": main() __________________________________ Audio File combiner (+ txt with timestamps writer) -------------------------------------------------- import mutagen from mutagen.mp3 import MP3 from mutagen.id3 import ID3, TIT2, TPE1 from tkinter import Tk, Label, Entry, Button, Text from tkinterdnd2 import DND_FILES, TkinterDnD import os class MP3Combiner: def __init__(self, root): self.root = root self.root.title("MP3 Combiner") self.label = Label(root, text="Drag and drop MP3 files here:") self.label.pack() self.text = Text(root, height=10, width=50) self.text.pack() self.delay_label = Label(root, text="Enter delay in seconds:") self.delay_label.pack() self.delay_entry = Entry(root) self.delay_entry.pack() self.combine_button = Button(root, text="Combine MP3s", command=self.combine_mp3s) self.combine_button.pack() self.mp3_files = [] self.root.drop_target_register(DND_FILES) self.root.dnd_bind('<>', self.on_drop) def on_drop(self, event): files = self.root.tk.splitlist(event.data) for file in files: if file.endswith('.mp3'): self.mp3_files.append(file) self.text.insert('end', f"{file}\n") def combine_mp3s(self): if not self.mp3_files: self.text.insert('end', "Please drop some MP3 files.\n") return try: delay_seconds = float(self.delay_entry.get()) except ValueError: self.text.insert('end', "Please enter a valid number for the delay.\n") return # Create silent delay file as bytes (no AudioSegment needed) delay_data = b'\x00' * int(44100 * 2 * delay_seconds) # 44100 sample rate, 2 bytes per sample (16-bit) # Initialize cumulative time for calculating timestamps cumulative_time = 0.0 txt_output_lines = [] with open("combined_output.mp3", "wb") as output_file: for file in self.mp3_files: # Read MP3 metadata for title audio = MP3(file, ID3=ID3) title = audio.get("TIT2", "Unknown Title") # Get title, default to "Unknown Title" duration = audio.info.length # Get the duration of the track # Write MP3 data to the combined file with open(file, "rb") as mp3_file: mp3_data = mp3_file.read() output_file.write(mp3_data) # Add current track's timestamp and title to the list minutes, seconds = divmod(int(cumulative_time), 60) timestamp = f"{minutes:02}:{seconds:02}" txt_output_lines.append(f"{timestamp} {title}") # Update cumulative time with track duration and delay cumulative_time += duration + delay_seconds # Append delay to the output file output_file.write(delay_data) # Save metadata to the combined MP3 file combined_audio = MP3("combined_output.mp3", ID3=ID3) combined_audio["TIT2"] = TIT2(encoding=3, text="Combined MP3") combined_audio["TPE1"] = TPE1(encoding=3, text="Various Artists") combined_audio.save() # Write timestamps and song titles to a text file with open("combined_output_timestamps.txt", "w") as txt_file: txt_file.write("\n".join(txt_output_lines)) self.text.insert('end', "Combined audio saved as 'combined_output.mp3'\n") self.text.insert('end', "Tracklist with timestamps saved as 'combined_output_timestamps.txt'\n") if __name__ == "__main__": root = TkinterDnD.Tk() app = MP3Combiner(root) root.mainloop() ____________________________________ MMD file copier (vmd, camera, audio) - drag n drop -------------------------------------------- import tkinter as tk from tkinterdnd2 import DND_FILES, TkinterDnD import os import shutil class FileCopyApp: def __init__(self, root): self.root = root self.root.title("File Copy Tool") # Initialize variables for file paths and base path self.base_path = tk.StringVar(value="E:\\Dropbox\\Public\\00_Html\\Examples\\3D_Model_render\\MMD\\SampleWebMMD-master") self.camera_path = "" self.vmd_path = "" self.audio_path = "" # Create GUI elements self.create_gui() def create_gui(self): # Create label and entry for base path base_path_label = tk.Label(self.root, text="Base Path:") base_path_label.grid(row=0, column=0, padx=10, pady=10, sticky="e") self.base_path_entry = tk.Entry(self.root, textvariable=self.base_path, width=50) self.base_path_entry.grid(row=0, column=1, padx=10, pady=10, sticky="ew") # Create labels for drop boxes tk.Label(self.root, text="Camera").grid(row=1, column=0, padx=10, pady=10) tk.Label(self.root, text="VMD").grid(row=1, column=1, padx=10, pady=10) tk.Label(self.root, text="Audio").grid(row=1, column=2, padx=10, pady=10) # Create drop boxes self.create_drop_box("camera", row=2, column=0) self.create_drop_box("vmd", row=2, column=1) self.create_drop_box("audio", row=2, column=2) # Entry for name name_label = tk.Label(self.root, text="Enter a name:") name_label.grid(row=3, column=0, columnspan=3, padx=10, pady=10) self.name_entry = tk.Entry(self.root) self.name_entry.grid(row=4, column=0, columnspan=3, padx=10, pady=10, sticky="ew") # Button to initiate copy process copy_button = tk.Button(self.root, text="Copy Files", command=self.copy_files) copy_button.grid(row=5, column=0, columnspan=3, padx=10, pady=10, sticky="ew") # Label for success message self.success_label = tk.Label(self.root, text="", fg="green") self.success_label.grid(row=6, column=0, columnspan=3, padx=10, pady=10) # Configure grid layout self.root.grid_rowconfigure(2, weight=1) self.root.grid_columnconfigure(0, weight=1) self.root.grid_columnconfigure(1, weight=1) self.root.grid_columnconfigure(2, weight=1) def create_drop_box(self, target_path, row, column): frame = tk.Frame(self.root, borderwidth=2, relief="groove") frame.grid(row=row, column=column, padx=10, pady=10, sticky="nsew") label = tk.Label(frame, text=target_path.capitalize(), anchor="w") label.pack(fill="x", padx=10, pady=(10, 5)) drop_box = tk.Listbox(frame, relief="sunken", bd=2, height=5, width=40) drop_box.pack(fill="both", padx=10, pady=(0, 10)) # Enable drag and drop handling using tkinterdnd2 drop_box.drop_target_register(DND_FILES) drop_box.dnd_bind('<>', lambda event, target=target_path: self.on_drop(event, target, drop_box)) def on_drop(self, event, target_path, drop_box): # Handle dropped files file_paths = event.data.split() # Split by spaces to get individual file paths if file_paths: print(f"Dropped file paths: {file_paths}") # Debug print for dropped files for file_path in file_paths: self.on_file_drop(file_path, target_path, drop_box) def on_file_drop(self, file_path, target_path, drop_box): # Handle dropped file path print(f"Dropped file path: {file_path}") # Debug print # Concatenate parts back into full path if necessary if not os.path.isabs(file_path): file_path = os.path.join(os.getcwd(), file_path) if target_path == "camera": self.camera_path = file_path elif target_path == "vmd": self.vmd_path = file_path elif target_path == "audio": self.audio_path = file_path # Update drop box display file_name = os.path.basename(file_path) drop_box.delete(0, tk.END) drop_box.insert(tk.END, f"Dropped: {file_name}") def copy_files(self): name = self.name_entry.get().strip() if name == "": self.success_label.config(text="Please enter a name.", fg="red") return self.base_path_value = self.base_path.get().strip() if not self.base_path_value: self.success_label.config(text="Please enter a base path.", fg="red") return if self.camera_path: camera_file_name = os.path.basename(self.camera_path) _, camera_file_ext = os.path.splitext(camera_file_name) new_camera_file_name = f"{name}{camera_file_ext}" shutil.copy(self.camera_path, os.path.join(self.base_path_value, "camera", new_camera_file_name)) print(f"Copied '{camera_file_name}' to {os.path.join(self.base_path_value, 'camera')} as '{new_camera_file_name}'") if self.vmd_path: vmd_file_name = os.path.basename(self.vmd_path) _, vmd_file_ext = os.path.splitext(vmd_file_name) new_vmd_file_name = f"{name}{vmd_file_ext}" shutil.copy(self.vmd_path, os.path.join(self.base_path_value, "vmd", new_vmd_file_name)) print(f"Copied '{vmd_file_name}' to {os.path.join(self.base_path_value, 'vmd')} as '{new_vmd_file_name}'") if self.audio_path: audio_file_name = os.path.basename(self.audio_path) _, audio_file_ext = os.path.splitext(audio_file_name) new_audio_file_name = f"{name}{audio_file_ext}" shutil.copy(self.audio_path, os.path.join(self.base_path_value, "audio", new_audio_file_name)) print(f"Copied '{audio_file_name}' to {os.path.join(self.base_path_value, 'audio')} as '{new_audio_file_name}'") self.success_label.config(text="Files copied successfully.", fg="green") if __name__ == "__main__": root = TkinterDnD.Tk() app = FileCopyApp(root) root.mainloop() ___________________________________________ Youtube MP3 Playlist Downloader -------------------------------- from pytube import Playlist import os from pydub import AudioSegment import re import tkinter as tk from tkinter import ttk def sanitize_filename(filename): """ Removes special characters from the filename. """ return re.sub(r'[^\w\-_\. ]', '_', filename) def download_playlist(playlist_url): playlist = Playlist(playlist_url) print(f"Downloading {len(playlist)} videos from the playlist.") for index, video in enumerate(playlist.videos, start=1): filename = f"{index:03d} - {sanitize_filename(video.title)}.mp3" print(f"Downloading {filename}") try: # Download the audio stream as MP3 with 128 kbps bitrate audio = video.streams.filter(only_audio=True).first() audio.download(filename=filename) # Adjust the bitrate to 192 kbps audio_segment = AudioSegment.from_file(filename, format="mp3") audio_segment.export(filename, format="mp3", bitrate="192k") except Exception as e: print(f"Error downloading {filename}: {e}") print("Playlist download complete.") def main(): root = tk.Tk() root.title("YouTube Playlist Downloader") url_label = ttk.Label(root, text="YouTube Playlist URL:") url_label.pack(pady=10) url_entry = ttk.Entry(root, width=50) url_entry.pack(pady=10) download_button = ttk.Button(root, text="Download Playlist", command=lambda: download_playlist(url_entry.get())) download_button.pack(pady=10) root.mainloop() if __name__ == "__main__": main() _________________________ Poweramp adb Control ----------------------------- import subprocess import tkinter as tk from pynput import keyboard def send_adb_command(command): ip_address = ip_entry.get() port = port_entry.get() adb_shell_command = f"adb -s {ip_address}:{port} shell am broadcast 'intent:#Intent;action=com.maxmpz.audioplayer.API_COMMAND;package=com.maxmpz.audioplayer;i.cmd={command};end'" subprocess.run(adb_shell_command, shell=True) def restart(): ip_address = ip_entry.get() port = port_entry.get() command = f'adb kill-server && adb start-server && adb connect {ip_address}:{port}' subprocess.Popen(['cmd.exe', '/c', 'start', 'cmd.exe', '/k', command]) def handle_key_press(key): if key == keyboard.Key.media_play_pause: send_adb_command(1) # Play/Pause elif key == keyboard.Key.media_next: send_adb_command(4) # Next Track elif key == keyboard.Key.media_previous: send_adb_command(5) # Previous Track # Create the main window window = tk.Tk() window.title("ADB Audio Player Control") # Create IP address label and text entry ip_label = tk.Label(window, text="IP Address:") ip_label.pack() ip_entry = tk.Entry(window) ip_entry.insert(0, "192.168.0.101") # Pre-fill with IP address ip_entry.pack() # Create port label and text entry port_label = tk.Label(window, text="Port:") port_label.pack() port_entry = tk.Entry(window) port_entry.insert(0, "5555") # Pre-fill with port port_entry.pack() # Create previous track button prev_button = tk.Button(window, text="Previous Track", command=lambda: send_adb_command(5)) prev_button.pack() # Create play/pause button play_pause_button = tk.Button(window, text="Play/Pause", command=lambda: send_adb_command(1)) play_pause_button.pack() # Create next track button next_button = tk.Button(window, text="Next Track", command=lambda: send_adb_command(4)) next_button.pack() # Create restart button restart_button = tk.Button(window, text="Restart", command=restart) restart_button.pack() # Bind key presses to button actions def on_key_press(event): key = event.keysym.lower() if key == 'xf86audioplay': send_adb_command(1) # Play/Pause elif key == 'xf86audionext': send_adb_command(4) # Next Track elif key == 'xf86audioprev': send_adb_command(5) # Previous Track window.bind("", on_key_press) # Start the tkinter event loop window.mainloop() __________________ Video Converter GUI (ffmpeg) ------------------------------- import tkinter as tk from tkinter import filedialog from tkinter import ttk import subprocess from tqdm import tqdm import configparser import os settings_file = "videoconverter_settings.ini" settings = configparser.ConfigParser() if os.path.exists(settings_file): settings.read(settings_file) # Create the settings.ini file if it doesn't exist if not os.path.exists(settings_file): settings.add_section("General") settings.set("General", "OutputPath", "") with open(settings_file, "w") as configfile: settings.write(configfile) def calculate_bitrate(width, height, mode): if mode == 'CBR': if width <= 640 and height <= 480: return 500 elif width <= 1280 and height <= 720: return 1000 elif width <= 1920 and height <= 1080: return 2000 else: return 4000 def open_folder_picker(): folder_path = filedialog.askdirectory() output_path_var.set(folder_path) settings.set("General", "OutputPath", folder_path) with open(settings_file, "w") as configfile: settings.write(configfile) def convert_videos(): filetypes = (("Video files", "*.mp4 *.avi"), ("All files", "*.*")) filenames = filedialog.askopenfilenames(filetypes=filetypes) resolution = resolution_var.get() bitrate_mode = bitrate_var.get() output_path = output_path_var.get() if not output_path: output_path = filedialog.askdirectory() settings.set("General", "OutputPath", output_path) with open(settings_file, "w") as configfile: settings.write(configfile) for filename in filenames: output_filename = os.path.join(output_path, filename.split('/')[-1]) command = ['ffmpeg', '-i', filename] command += ['-vf', f"scale={resolution}"] width, height = map(int, resolution.split('x')) bitrate = calculate_bitrate(width, height, bitrate_mode) command += ['-b:v', f"{bitrate}k"] command.append(output_filename) with tqdm(total=100, ncols=80, bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt}') as pbar: process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) for line in process.stderr: line = line.decode().strip() if line.startswith('frame='): frame = int(line.split('frame=')[1].split()[0]) pbar.update(frame - pbar.n) progress_var.set(pbar.n) progress_text.insert(tk.END, line + '\n') progress_text.see(tk.END) print(f"Converted {filename} to {output_filename}") root = tk.Tk() root.title("Video Converter") resolution_frame = tk.Frame(root) resolution_frame.pack(pady=10) resolution_label = tk.Label(resolution_frame, text="Resolution:") resolution_label.pack(side=tk.LEFT) # Dropdown menu with video resolutions resolution_var = tk.StringVar(value="640x480") resolution_dropdown = tk.OptionMenu(resolution_frame, resolution_var, "640x480", "1280x720", "1920x1080") resolution_dropdown.pack(side=tk.LEFT) bitrate_frame = tk.Frame(root) bitrate_frame.pack(pady=10) bitrate_label = tk.Label(bitrate_frame, text="Bitrate Mode:") bitrate_label.pack(side=tk.LEFT) bitrate_var = tk.StringVar(value="CBR") bitrate_cbr_radio = tk.Radiobutton(bitrate_frame, text="CBR", variable=bitrate_var, value="CBR") bitrate_cbr_radio.pack(side=tk.LEFT) bitrate_vbr_radio = tk.Radiobutton(bitrate_frame, text="VBR", variable=bitrate_var, value="VBR") bitrate_vbr_radio.pack(side=tk.LEFT) output_path_frame = tk.Frame(root) output_path_frame.pack(pady=10) output_path_label = tk.Label(output_path_frame, text="Output Path:") output_path_label.pack(side=tk.LEFT) output_path_var = tk.StringVar(value=settings.get("General", "OutputPath", fallback="")) output_path_entry = tk.Entry(output_path_frame, textvariable=output_path_var, state="readonly") output_path_entry.pack(side=tk.LEFT, fill=tk.X, expand=True) folder_picker_button = tk.Button(output_path_frame, text="Select Folder", command=open_folder_picker) folder_picker_button.pack(side=tk.LEFT) progress_text = tk.Text(root, height=10, width=50) progress_text.pack(pady=10) progress_var = tk.DoubleVar(value=0.0) progress_bar = ttk.Progressbar(root, variable=progress_var, maximum=100) progress_bar.pack(pady=10) convert_button = tk.Button(root, text="Convert", command=convert_videos) convert_button.pack(pady=10) root.mainloop() ________________________________ Youtube Downloader: ------------------- import tkinter as tk from pytube import YouTube from tkinter import ttk import os def download(): # Get the URL from the text box url = url_textbox.get() # Create a YouTube object yt = YouTube(url) # Get the video format from the radio buttons if mp4_radio_button.get(): video_format = "mp4" extension = ".mp4" res = res_textbox.get() stream = yt.streams.filter(res=res).first() else: video_format = "mp3" extension = ".mp3" streams = yt.streams.filter(only_audio=True).all() # Create a new window to display the available audio streams stream_window = tk.Toplevel(root) stream_window.title("Select Audio Stream") # Display the available audio streams in a listbox stream_listbox = tk.Listbox(stream_window) for stream in streams: stream_listbox.insert(tk.END, f"{stream.abr} ({stream.mime_type})") stream_listbox.pack(padx=10, pady=10) def select_stream(): # Get the selected stream selected_stream_index = stream_listbox.curselection()[0] selected_stream = streams[selected_stream_index] # Destroy the stream window stream_window.destroy() # Set up the progress bar progress_bar["maximum"] = selected_stream.filesize progress_bar["value"] = 0 # Set up the title label title_label.config(text=f"Downloading: {yt.title}") # Download the audio filename = yt.title.encode('utf-8') + extension selected_stream.download(output_path="downloads", filename=filename) # Reset the progress bar and title label progress_bar["value"] = 0 title_label.config(text="") # Create a select button to download the selected audio stream select_button = tk.Button(stream_window, text="Select", command=select_stream) select_button.pack(padx=10, pady=10) # Wait for the user to select a stream stream_window.wait_window() # Download the video or audio filename = yt.title + extension stream.download(output_path="downloads", filename=filename) # Reset the progress bar and title label progress_bar["value"] = 0 title_label.config(text="") def open_download_folder(): # Open the download folder os.startfile(os.path.abspath("downloads")) def check_url(*args): # Get the URL from the text box url = url_textbox.get() # Replace https://m.youtube. with https://www.youtube. url = url.replace("https://m.youtube.", "https://www.youtube.") # Check if the URL is valid if not url.startswith("https://www.youtube.com/watch?v="): return # Create a YouTube object yt = YouTube(url) # Get the available audio streams streams = yt.streams.filter(only_audio=True).all() # Create a new window to display the available audio streams stream_window = tk.Toplevel(root) stream_window.title("Select Audio Stream") # Display the available audio streams in a listbox stream_listbox = tk.Listbox(stream_window) for stream in streams: stream_listbox.insert(tk.END, f"{stream.abr} ({stream.mime_type})") stream_listbox.pack(padx=10, pady=10) def select_stream(): # Get the selected stream selected_stream_index = stream_listbox.curselection()[0] selected_stream = streams[selected_stream_index] # Destroy the stream window stream_window.destroy() # Set up the progress bar progress_bar["maximum"] = selected_stream.filesize progress_bar["value"] = 0 # Set up the title label title_label.config(text=f"Downloading: {yt.title}") # Download the audio filename = yt.title + ".mp3" selected_stream.download(output_path="downloads", filename=filename) # Reset the progress bar and title label progress_bar["value"] = 0 title_label.config(text="") # Create a select button to download the selected audio stream select_button = tk.Button(stream_window, text="Select", command=select_stream) select_button.pack(padx=10, pady=10) # Wait for the user to select a stream stream_window.wait_window() # Create the GUI root = tk.Tk() root.title("YouTube Downloader") # Create the text box for the video resolution res_textbox = tk.Entry(root, width=10) res_textbox.pack() res_textbox.insert(0, "360p") # Create the text box for the URL url_textbox =tk.Entry(root, width=50) url_textbox.pack(padx=10, pady=10) url_textbox.bind("", check_url) # Create the radio buttons to choose the download format mp4_radio_button = tk.BooleanVar(value=True) mp4_radio = ttk.Radiobutton(root, text="MP4", variable=mp4_radio_button, value=True) mp4_radio.pack() mp3_radio = ttk.Radiobutton(root, text="MP3", variable=mp4_radio_button, value=False) mp3_radio.pack() # Create the download button download_button = tk.Button(root, text="Download", command=download) download_button.pack(padx=10, pady=10) # Create the progress bar progress_bar = ttk.Progressbar(root, orient=tk.HORIZONTAL, length=300, mode="determinate") progress_bar.pack(padx=10, pady=10) # Create the title label title_label = tk.Label(root, text="") title_label.pack(padx=10, pady=10) # Create the button to open the download folder open_folder_button = tk.Button(root, text="Open Download Folder", command=open_download_folder) open_folder_button.pack(padx=10, pady=10) # Start the GUI root.mainloop() _________________________________________________________________________ MeteoCtrl Lister (with date search, keyword search and hyperlink support): ------------------------------------------------------------------------ import os import sys import tkinter as tk from datetime import datetime, timezone, timedelta directory = r'C:\Konfi-Data\Export\json' german_tz = timezone(timedelta(hours=1), 'CET') def display_files(file_list): for file in file_list: file_path = os.path.join(directory, file) file_time = os.path.getmtime(file_path) dt = datetime.fromtimestamp(file_time, tz=timezone.utc) german_time = dt.astimezone(german_tz) file_timestamp = f'{file} - {german_time.strftime("%d/%m/%Y %I:%M:%S %p")} ({german_tz.tzname(None)})' file_label = tk.Label(root, text=file_timestamp, anchor='w', justify='left', fg='blue', cursor='hand2') file_label.pack(fill='x') file_label.bind('', lambda event, file_path=file_path: open_file(file_path)) def open_file(file_path): try: with open(file_path, 'r') as f: file_content = f.read() text_editor = tk.Toplevel(root) text_editor.title(file_path) text_editor_text = tk.Text(text_editor) text_editor_text.pack(fill='both', expand=True) text_editor_text.insert('1.0', file_content) except Exception as e: tk.messagebox.showerror('Error', str(e)) def get_file_date(file): # Get the last modification time of the file last_modified_time = os.path.getmtime(os.path.join(directory, file)) # Convert the last modification time to a datetime object last_modified_datetime = datetime.fromtimestamp(last_modified_time, tz=german_tz) # Extract the date from the datetime object return last_modified_datetime.date() def search_files(keyword, date_str): # Clear the previous search results for widget in root.winfo_children(): if isinstance(widget, tk.Label) or isinstance(widget, tk.Button): widget.destroy() if keyword or date_str: count = 0 for file in file_list: file_date = get_file_date(file) if (not keyword or keyword.lower() in file.lower()) and (not date_str or file_date == datetime.strptime(date_str, "%d/%m/%Y").date()): count += 1 file_path = os.path.join(directory, file) file_time = os.path.getmtime(file_path) dt = datetime.fromtimestamp(file_time, tz=timezone.utc) german_time = dt.astimezone(german_tz) file_timestamp = f'{file} - {german_time.strftime("%d/%m/%Y %I:%M:%S %p")} ({german_tz.tzname(None)})' file_label = tk.Label(root, text=file_timestamp, anchor='w', justify='left', fg='blue', cursor='hand2') file_label.pack(fill='x') file_label.bind('', lambda event, file_path=file_path: open_file(file_path)) if keyword: with open(file_path, 'r') as f: for line in f: if keyword.lower() in line.lower(): line_label = tk.Label(root, text=line.strip(), anchor='w', justify='left') line_label.pack(fill='x') total_count.set(f'Occurrences: {count}') else: display_files(file_list_sorted) total_count.set('Occurrences: 0') def reload_program(): python = sys.executable args = [os.path.abspath(__file__)] os.execl(python, python, *args) # Close the current instance of the program root.destroy() file_list = os.listdir(directory) file_info_list = [(file, os.path.getmtime(os.path.join(directory, file))) for file in file_list] file_info_list_sorted = sorted(file_info_list, key=lambda x: x[1], reverse=True)[:100] file_list_sorted = [file_info[0] for file_info in file_info_list_sorted] root = tk.Tk() root.title('Newest 100 Files') search_entry = tk.Entry(root) search_entry.pack() filter_frame = tk.Frame(root) filter_frame.pack(side='top', fill='x') date_label = tk.Label(filter_frame, text='Date (dd/mm/yyyy) [t-todays date:]', font='Helvetica 12', anchor='w', justify='left') date_label.pack(side='left') date_entry = tk.Entry(filter_frame) date_entry.pack(side='left', padx=5) total_count = tk.StringVar() total_count.set('Occurrences: 0') count_label = tk.Label(filter_frame, textvariable=total_count, font='Helvetica 12', anchor='e', justify='right') count_label.pack(side='right', fill='x', expand=True) # Create the "RELOAD" button reload_button = tk.Button(root, text='RELOAD / F5', command=reload_program) reload_button.pack(side='top', pady=10) root.bind('', lambda event: reload_program()) display_files(file_list_sorted) root.after_id = None def on_search_entry_change(event): # Cancel any existing call to the search function if root.after_id is not None: root.after_cancel(root.after_id) # Schedule a new call to the search function in 1 second root.after_id = root.after(1500, search_files, search_entry.get(), date_entry.get()) # Check if "t" is entered in the date entry if event.widget == date_entry and event.char.lower() == "t": # Replace "t" with the current date in the format "dd/mm/yyyy" today = datetime.now(german_tz).strftime("%d/%m/%Y") date_entry.delete(0, tk.END) date_entry.insert(0, today) search_entry.bind('', on_search_entry_change) date_entry.bind('', on_search_entry_change) root.mainloop() ( Source: https://poe.com/Pythonmachine ) ============================= ===PythonHelp================= Set virtual environment (for scot free usage of special programs) ----------------------------------------------------------------- pip install virtualenv virtualenv openmmd-env openmmd-env\Scripts\activate _____________________________________________________________ Stop Win 11 from auto opening store on cmd "python" -------------------------------------------------- To prevent Windows from redirecting python to the Microsoft Store, disable the App Execution Alias for Python. Open Settings: Press Win + I to open Settings. Go to Apps > Apps & features. Manage App Execution Aliases: Scroll down and click on Manage app execution aliases. Find the Python entry in the list and toggle it off. _______________________________________________________ Set python36 as path: --------------------- setx PATH "%PATH%;C:\Users\User\AppData\Local\Programs\Python\Python36;C:\Users\User\AppData\Local\Programs\Python\Python36\Scripts" _____________________________________ Start .py without visible cmd (save as *.vbs) ----------------------------------------------- Set objShell = CreateObject("WScript.Shell") objShell.Run "C:\adb\PowerampCtrl.py", 0, True Set objShell = Nothing ________________________________ Start py with minimized cmd: --------------------------------------------- cmd /c start /min "C:\adb\PowerampCtrl.py" _________________________ Figure out url from pip installer: ---------------------------------- pip install PyQt5 --log log.txt ________________________________________ Install py for specific version: -------------------------------- C:\Users\User\AppData\Local\Programs\Python\Python310\Scripts\pip install torch-2.0.1+cu118-cp310-cp310-win_amd64.whl ________________________________________ Install whl: ------------ pip install *.whl _________________________________________ Python on Android: ------------------ Download: termux.en.download.it/android/downloading Install the Termux app from the Play Store or F-Droid. pkg update && pkg upgrade pkg install python pkg install python-pip