===== Twitch Status ===== import requests import tkinter as tk from tkinter import ttk import webbrowser import os import sys # Try to import plyer notifications try: from plyer import notification HAS_NOTIFICATIONS = True except ImportError: HAS_NOTIFICATIONS = False # Get app directory (works for .py and PyInstaller .exe) def get_app_dir(): if getattr(sys, 'frozen', False): # Running as compiled .exe return os.path.dirname(sys.executable) else: # Running as normal script return os.path.dirname(os.path.abspath(__file__)) APP_DIR = get_app_dir() CHANNEL_FILE = os.path.join(APP_DIR, "channels.txt") # Remember live status live_channels = set() # Ensure the file exists def ensure_channel_file_exists(): if not os.path.exists(CHANNEL_FILE): with open(CHANNEL_FILE, "w", encoding="utf-8") as f: pass # Load channels from file def load_channels(): if not os.path.exists(CHANNEL_FILE): return [] with open(CHANNEL_FILE, "r", encoding="utf-8") as f: return [line.strip() for line in f if line.strip()] # Save all channels def save_channels_to_file(channel_list): with open(CHANNEL_FILE, "w", encoding="utf-8") as f: for channel in channel_list: f.write(channel + "\n") # Add new channel def add_channel_to_file(channel_name): existing = load_channels() if channel_name not in existing: with open(CHANNEL_FILE, "a", encoding="utf-8") as f: f.write(channel_name + "\n") # Check if channel is live def check_if_live(channel_name): url = f'https://www.twitch.tv/{channel_name}' try: response = requests.get(url) response.raise_for_status() return 'isLiveBroadcast' in response.text except requests.RequestException: return None # Status for all channels def get_channel_statuses(channels): results = {} for channel in channels: status = check_if_live(channel) if status is None: results[channel] = '❌ Error' elif status: results[channel] = '🟒 Live' else: results[channel] = 'βšͺ Offline' return results # Open Twitch in browser def open_channel(channel_name): webbrowser.open(f"https://www.twitch.tv/{channel_name}") # Send notification def notify_live(channel_name): if HAS_NOTIFICATIONS: notification.notify( title="Twitch Channel is Live!", message=f"{channel_name} is now live on Twitch.", timeout=5 ) # Build GUI def build_gui(): root = tk.Tk() root.title("Twitch Live Status") # Input field entry_frame = ttk.Frame(root) entry_frame.pack(pady=10) ttk.Label(entry_frame, text="New Channel:").pack(side="left", padx=5) channel_entry = ttk.Entry(entry_frame, width=30) channel_entry.pack(side="left", padx=5) def add_channel(): new_channel = channel_entry.get().strip() if new_channel and new_channel not in channels: channels.append(new_channel) add_channel_to_file(new_channel) update_table() channel_entry.delete(0, tk.END) ttk.Button(entry_frame, text="Add", command=add_channel).pack(side="left", padx=5) # Table with scrollbar table_frame = ttk.Frame(root) table_frame.pack(padx=20, pady=10, fill="both", expand=True) tree = ttk.Treeview(table_frame, columns=("Channel", "Status", "Open", "Remove"), show="headings") for col, text in zip(("Channel", "Status", "Open", "Remove"), ("Channel", "Status", "Open", "Remove")): tree.heading(col, text=text) tree.column(col, width=120, anchor="center") tree.column("Channel", anchor="w", width=150) tree.pack(side="left", fill="both", expand=True) scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=tree.yview) scrollbar.pack(side="right", fill="y") tree.configure(yscrollcommand=scrollbar.set) def update_table(): global live_channels for row in tree.get_children(): tree.delete(row) statuses = get_channel_statuses(channels) for channel, status in statuses.items(): tree.insert("", "end", iid=channel, values=(channel, status, "Open", "Remove")) # Notify on new live status if status == '🟒 Live' and channel not in live_channels: notify_live(channel) live_channels.add(channel) elif status != '🟒 Live' and channel in live_channels: live_channels.remove(channel) def schedule_refresh(): update_table() root.after(60000, schedule_refresh) def on_tree_click(event): item = tree.identify_row(event.y) column = tree.identify_column(event.x) if item: if column == "#3": # Open open_channel(item) elif column == "#4": # Remove channels.remove(item) save_channels_to_file(channels) update_table() tree.bind("", on_tree_click) update_table() schedule_refresh() root.mainloop() # Start app ensure_channel_file_exists() channels = load_channels() build_gui() ===== Worldclock ===== import tkinter as tk from datetime import datetime from zoneinfo import ZoneInfo def update_clocks(): berlin_time = datetime.now(ZoneInfo("Europe/Berlin")).strftime("%H:%M:%S") melbourne_time = datetime.now(ZoneInfo("Australia/Melbourne")).strftime("%H:%M:%S") victoria_time = datetime.now(ZoneInfo("America/Vancouver")).strftime("%H:%M:%S") charleston_time = datetime.now(ZoneInfo("America/New_York")).strftime("%H:%M:%S") berlin_label.config(text=f"Berlin πŸ‡©πŸ‡ͺ: {berlin_time}") melbourne_label.config(text=f"Melbourne πŸ‡¦πŸ‡Ί: {melbourne_time}") victoria_label.config(text=f"Victoria πŸ‡¨πŸ‡¦: {victoria_time}") charleston_label.config(text=f"Charleston πŸ‡ΊπŸ‡Έ: {charleston_time}") root.after(1000, update_clocks) root = tk.Tk() root.title("🌍 Weltzeit-Uhren") berlin_label = tk.Label(root, font=("Helvetica", 20), fg="black") melbourne_label = tk.Label(root, font=("Helvetica", 20), fg="blue") victoria_label = tk.Label(root, font=("Helvetica", 20), fg="green") charleston_label = tk.Label(root, font=("Helvetica", 20), fg="purple") berlin_label.pack(pady=10) melbourne_label.pack(pady=10) victoria_label.pack(pady=10) charleston_label.pack(pady=10) update_clocks() root.mainloop()