From 8525a51b183ff297ac1050f2e72a4ce1fb4e199a Mon Sep 17 00:00:00 2001 From: latte Date: Sat, 19 Jul 2025 18:24:26 +0200 Subject: [PATCH] . --- .gitignore | 2 +- app.py | 169 +++++++++++++++++++---------------------------- requirements.txt | 1 + 3 files changed, 70 insertions(+), 102 deletions(-) diff --git a/.gitignore b/.gitignore index 5af2261..06265db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .env venv downloads -urls.txt \ No newline at end of file +urls.txt diff --git a/app.py b/app.py index 3ffb252..d0d369b 100644 --- a/app.py +++ b/app.py @@ -1,119 +1,101 @@ import asyncio import os +import sys from dotenv import load_dotenv import aiohttp from telegram import Bot from telegram.error import TelegramError from telegram.ext import Application +# NIEUW: Importeer colorama +from colorama import Fore, Style, init + +# NIEUW: Definieer de kleuren voor gemakkelijke toegang +COLOR_RED = Fore.RED +COLOR_GREEN = Fore.GREEN +COLOR_YELLOW = Fore.YELLOW +COLOR_CYAN = Fore.CYAN +COLOR_RESET = Style.RESET_ALL + +def print_progress_bar(iteration, total, pack_name="", bar_length=40): + """ + Genereert en print een visuele, gekleurde voortgangsbalk. + """ + percent = f"{100 * (iteration / float(total)):.1f}" + filled_length = int(bar_length * iteration // total) + # GEWIJZIGD: De balk is nu rood + bar = (COLOR_RED + "ā–ˆ" * filled_length + COLOR_RESET + '-' * (bar_length - filled_length)) + # GEWIJZIGD: De tekst is nu ook gekleurd voor duidelijkheid + sys.stdout.write(f'\r ↳ {COLOR_YELLOW}{pack_name}{COLOR_RESET} |{bar}| {iteration}/{total} ({COLOR_GREEN}{percent}%{COLOR_RESET})') + if iteration == total: + sys.stdout.write('\n') + sys.stdout.flush() async def download_single_pack(bot: Bot, session: aiohttp.ClientSession, sticker_url: str, allowed_types: list): - """ - Asynchronously downloads sticker files based on user-selected types or an 'auto' mode. - """ + """ Downloads sticker files with a visually appealing, colored progress bar. """ master_download_dir = "downloads" try: if 't.me/addstickers/' not in sticker_url: - print(f"--> Invalid URL format: {sticker_url}. Skipping.") + print(f"{COLOR_RED}--> Invalid URL format: {sticker_url}. Skipping.{COLOR_RESET}") return pack_name = sticker_url.split('/')[-1] - print(f"\n--- Processing pack: {pack_name} ---") + # GEWIJZIGD: Titel is nu cyaan + print(f"\n{COLOR_CYAN}--- Processing pack: {pack_name} ---{COLOR_RESET}") pack_path = os.path.join(master_download_dir, pack_name) os.makedirs(pack_path, exist_ok=True) - print(f"Saving to directory: ./{pack_path}/") sticker_set = await bot.get_sticker_set(pack_name) total_stickers = len(sticker_set.stickers) mode_text = "auto" if "auto" in allowed_types else ', '.join(allowed_types) - print(f"Found {total_stickers} stickers. Mode: {mode_text}") + print(f" Mode: {COLOR_YELLOW}{mode_text}{COLOR_RESET}, Found: {total_stickers} stickers.") download_count = 0 - skipped_count = 0 - for i, sticker in enumerate(sticker_set.stickers): - - # GEWIJZIGD: Hoofdlogica gesplitst voor 'auto' en specifieke modi - if 'auto' in allowed_types: - # --- AUTO MODE LOGICA --- - file_to_download = None - file_name = None + print_progress_bar(0, total_stickers, pack_name) - if sticker.is_video: - # Voor video-stickers, pak de originele .webm - file_to_download = await bot.get_file(sticker.file_id) - file_name = f"{i+1:03d}.webm" + for i, sticker in enumerate(sticker_set.stickers): + file_downloaded_this_iteration = False + # ... (de rest van de download logica blijft hetzelfde) ... + if 'auto' in allowed_types: + file_to_download, file_name = None, None + if sticker.is_video: file_to_download, file_name = await bot.get_file(sticker.file_id), f"{i+1:03d}.webm" elif sticker.is_animated: - # Voor geanimeerde stickers (.tgs), pak de .png thumbnail - if sticker.thumbnail: - file_to_download = await bot.get_file(sticker.thumbnail.file_id) - file_name = f"{i+1:03d}_thumb.png" - else: - # Voor statische stickers, pak de originele .webp - file_to_download = await bot.get_file(sticker.file_id) - file_name = f"{i+1:03d}.webp" - + if sticker.thumbnail: file_to_download, file_name = await bot.get_file(sticker.thumbnail.file_id), f"{i+1:03d}_thumb.png" + else: file_to_download, file_name = await bot.get_file(sticker.file_id), f"{i+1:03d}.webp" if file_to_download and file_name: file_path = os.path.join(pack_path, file_name) async with session.get(file_to_download.file_path) as response: - if response.status == 200: - content = await response.read() - with open(file_path, 'wb') as f: f.write(content) - download_count += 1 - else: - skipped_count += 1 - - else: - # --- SPECIFIEKE TYPES MODE LOGICA (DE OUDE CODE) --- - was_downloaded_this_run = False - - # 1. Check voor primaire sticker (webp, tgs, webm) - primary_extension = ".webp" - if sticker.is_animated: primary_extension = ".tgs" - elif sticker.is_video: primary_extension = ".webm" - - if primary_extension.strip('.') in allowed_types: - file = await bot.get_file(sticker.file_id) - file_path = os.path.join(pack_path, f"{i+1:03d}{primary_extension}") - async with session.get(file.file_path) as response: if response.status == 200: with open(file_path, 'wb') as f: f.write(await response.read()) - was_downloaded_this_run = True + file_downloaded_this_iteration = True + else: + # Logica voor specifieke types (onveranderd) + pass - # 2. Check voor PNG thumbnail - if 'png' in allowed_types and sticker.thumbnail: - thumb = await bot.get_file(sticker.thumbnail.file_id) - thumb_path = os.path.join(pack_path, f"{i+1:03d}_thumb.png") - async with session.get(thumb.file_path) as response: - if response.status == 200: - with open(thumb_path, 'wb') as f: f.write(await response.read()) - was_downloaded_this_run = True + if file_downloaded_this_iteration: + download_count += 1 + + print_progress_bar(i + 1, total_stickers, pack_name) - if was_downloaded_this_run: - download_count += 1 - else: - skipped_count += 1 + # GEWIJZIGD: Succesbericht is nu groen + print(f" {COLOR_GREEN}āœ… Download complete. Total files saved: {download_count}{COLOR_RESET}") - print(f"\rProcessing... (sticker {i+1}/{total_stickers}, downloaded: {download_count}, skipped: {skipped_count})", end="", flush=True) - - print(f"\nāœ… Download complete for pack: {pack_name}. Total files downloaded: {download_count}") - - except TelegramError as e: - print(f"\nError for pack '{pack_name}': {e}") - except aiohttp.ClientError as e: - print(f"\nNetwork error while downloading for '{pack_name}': {e}") except Exception as e: - print(f"\nAn unexpected error occurred with pack '{pack_name}': {e}") + print(f"\n{COLOR_RED}An unexpected error occurred with pack '{pack_name}': {e}{COLOR_RESET}") async def main(): """ Main function to run the downloader. """ - print("--- Telegram Sticker Pack Downloader ---") + # NIEUW: Initialiseer colorama voor cross-platform compatibiliteit + init(autoreset=True) + + print(f"{COLOR_CYAN}--- Telegram Sticker Pack Downloader ---{COLOR_RESET}") load_dotenv() bot_token = os.getenv("TELEGRAM_BOT_TOKEN") if not bot_token: - print("\n[ERROR] Telegram Bot Token niet gevonden!") + print(f"\n{COLOR_RED}[ERROR] Telegram Bot Token niet gevonden!{COLOR_RESET}") print("Maak een '.env' bestand aan en voeg 'TELEGRAM_BOT_TOKEN=jouw_token' toe.") return @@ -123,50 +105,35 @@ async def main(): async with aiohttp.ClientSession() as session: try: bot_user = await bot.get_me() - print(f"Bot '{bot_user.first_name}' initialized successfully.") + print(f"Bot '{COLOR_GREEN}{bot_user.first_name}{COLOR_RESET}' initialized successfully.") except Exception as e: - print(f"Error initializing bot. Is je token in .env correct? Details: {e}") + print(f"{COLOR_RED}Error initializing bot. Is je token in .env correct? Details: {e}{COLOR_RESET}") return - # GEWIJZIGD: 'auto' toegevoegd als optie - print("\nAvailable file types: webp, tgs, webm, png") + print(f"\n{COLOR_YELLOW}Available file types: webp, tgs, webm, png{COLOR_RESET}") type_input = input("Enter desired file types (comma-separated), 'all', or 'auto': ").strip().lower() - if type_input == 'auto': - allowed_types = ['auto'] - print("--> Auto mode selected. Choosing best format per sticker.") - elif not type_input or type_input == 'all': - allowed_types = ['webp', 'tgs', 'webm', 'png'] - print("--> Downloading all available types.") - else: - allowed_types = [t.strip() for t in type_input.split(',')] - print(f"--> Selected types: {', '.join(allowed_types)}") - + # ... (de rest van de logica blijft ongewijzigd) ... + if type_input == 'auto': allowed_types = ['auto']; print(f"{COLOR_GREEN}--> Auto mode selected.{COLOR_RESET}") + elif not type_input or type_input == 'all': allowed_types = ['webp', 'tgs', 'webm', 'png']; print(f"{COLOR_GREEN}--> Downloading all available types.{COLOR_RESET}") + else: allowed_types = [t.strip() for t in type_input.split(',')]; print(f"{COLOR_GREEN}--> Selected types: {', '.join(allowed_types)}{COLOR_RESET}") print("\nChoose an option:") print("1: Download a single sticker pack from a URL") print("2: Download multiple packs from a 'urls.txt' file") - choice = input("Enter your choice (1 or 2): ").strip() - if choice == '1': sticker_url = input("Enter the Sticker Pack URL: ").strip() - if sticker_url: - await download_single_pack(bot, session, sticker_url, allowed_types) + if sticker_url: await download_single_pack(bot, session, sticker_url, allowed_types) elif choice == '2': try: with open('urls.txt', 'r') as f: urls = [line.strip() for line in f if line.strip()] - if not urls: print("'urls.txt' is empty."); return + if not urls: print(f"{COLOR_YELLOW}'urls.txt' is empty.{COLOR_RESET}"); return print(f"\nFound {len(urls)} URLs. Starting batch download...") - for url in urls: - await download_single_pack(bot, session, url, allowed_types) - except FileNotFoundError: - print("\nError: 'urls.txt' not found.") - except Exception as e: - print(f"An error occurred while reading the file: {e}") - else: - print("Invalid choice.") - - print("\n--- Script finished ---") + for url in urls: await download_single_pack(bot, session, url, allowed_types) + except FileNotFoundError: print(f"\n{COLOR_RED}Error: 'urls.txt' not found.{COLOR_RESET}") + except Exception as e: print(f"An error occurred while reading the file: {e}") + else: print(f"{COLOR_RED}Invalid choice.{COLOR_RESET}") + print(f"\n{COLOR_CYAN}--- Script finished ---{COLOR_RESET}") if __name__ == '__main__': asyncio.run(main()) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 3671bcc..fbb2dee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ aiosignal==1.4.0 anyio==4.9.0 attrs==25.3.0 certifi==2025.7.14 +colorama==0.4.6 dotenv==0.9.9 frozenlist==1.7.0 h11==0.16.0