Merge pull request 'feature/adding_styling' (#1) from feature/adding_styling into dev

Reviewed-on: https://gitea.hiddenden.cafe/Latte/telegram-sticker-downloader/pulls/1
This commit was merged in pull request #1.
This commit is contained in:
2025-07-19 16:39:16 +00:00
4 changed files with 70 additions and 199 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,4 @@
.env
venv
downloads
urls.txt
urls.txt

169
app.py
View File

@@ -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())

View File

@@ -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

View File

@@ -1,97 +0,0 @@
me/addstickers/LokisStickers
https://t.me/addstickers/KelixFox
https://t.me/addstickers/KingLewd
https://t.me/addstickers/WildeFoxy3
https://t.me/addstickers/RolenTheFox
https://t.me/addstickers/Coast39101NaL
https://t.me/addstickers/ceriseypooltoy
https://t.me/addstickers/FelkinMak
https://t.me/addstickers/austincollie
https://t.me/addstickers/Fatehunter
https://t.me/addstickers/LoonaNudesSFW
https://t.me/addstickers/DoubleColon
https://t.me/addstickers/SassyLuna
https://t.me/addstickers/MiksStickers
https://t.me/addstickers/b6e551ea_f0ff_4190_b528_2a4df3098f40_by_sticat_bot
https://t.me/addstickers/pa_qL3H3ebK7Tb8cAyK4vZp_by_SigStickBot
https://t.me/addstickers/skyzito
https://t.me/addstickers/cultofthelambstickersidk
https://t.me/addstickers/Garnyeen
https://t.me/addstickers/pk_969062_by_Ctikerubot
https://t.me/addstickers/Kiritsu
https://t.me/addstickers/Mewglestickerpack
https://t.me/addstickers/LoonaNudes_NSFW
https://t.me/addstickers/flspack
https://t.me/addstickers/Hux12811NaL
https://t.me/addstickers/JuicepsAnim
https://t.me/addstickers/COL_kinkystuff_5d8e45c73274d_by_FavoriteStickerBot
https://t.me/addstickers/Ulven_giru_0
https://t.me/addstickers/f06b8b03_d391_45ce_88cf_8704657a7329_by_sticat_bot
https://t.me/addstickers/KITTYqqqqqq_by_fStikBot
https://t.me/addstickers/JuicepsB
https://t.me/addstickers/spottedhyenaNL
https://t.me/addstickers/SudoBun
https://t.me/addstickers/AltoUwU
https://t.me/addstickers/things_gay_furries_say
https://t.me/addstickers/Bondagefurry
https://t.me/addstickers/Meroks
https://t.me/addstickers/MapleReactions
https://t.me/addstickers/Lilpussi2004
https://t.me/addstickers/cuteshat
https://t.me/addstickers/BambiStickersbyJeniak
https://t.me/addstickers/Umbreon_pack
https://t.me/addstickers/WolvesbyPulex
https://t.me/addstickers/ChocoVee
https://t.me/addstickers/sp589d3e5778bde2076e5cd1ed94cb7473_by_stckrRobot
https://t.me/addstickers/Shoxnfriends
https://t.me/addstickers/Shintuh
https://t.me/addstickers/vespernsfw
https://t.me/addstickers/sp4d5a2fbb30e3e46a7c93fe267e24e635_by_stckrRobot
https://t.me/addstickers/SleetAF
https://t.me/addstickers/Coconut90321NaL
https://t.me/addstickers/FelixStickersPack
https://t.me/addstickers/Eeveelotions
https://t.me/addstickers/SnepBlep
https://t.me/addstickers/Meesk
https://t.me/addstickers/NSFWcumCatFan_by_fStikBot
https://t.me/addstickers/AcePanda
https://t.me/addstickers/RainerByZempy
https://t.me/addstickers/PossSticks2
https://t.me/addstickers/sticked_6796952980_1_by_StickedApp_bot
https://t.me/addstickers/Lewdposs
https://t.me/addstickers/ZodiacPolaris56892NaL
https://t.me/addstickers/SalebatFavVideos
https://t.me/addstickers/PockyPack
https://t.me/addstickers/r4sput1n
https://t.me/addstickers/animated_boykisser_by_fStikBot
https://t.me/addstickers/MervynFoxe
https://t.me/addstickers/EdgyCatboy
https://t.me/addstickers/spb655017c033bcd284b9489ddab8ec191_by_stckrRobot
https://t.me/addstickers/mykiro
https://t.me/addstickers/saturnschmoovin
https://t.me/addstickers/forwardbias
https://t.me/addstickers/JFshit
https://t.me/addstickers/sp2d9c1642ca2cdff0b9c9467a453c315c_by_stckrRobot
https://t.me/addstickers/NekoHD
https://t.me/addstickers/BurlingtonTheCat
https://t.me/addstickers/sil1y
https://t.me/addstickers/Feroxdoon
https://t.me/addstickers/IkarusRelik
https://t.me/addstickers/spf892f03b96038158884d19ce0c148d70_by_stckrRobot
https://t.me/addstickers/Jinxed84910NaL
https://t.me/addstickers/tajistickers
https://t.me/addstickers/Blues41924NaL
https://t.me/addstickers/Bugamashoo2
https://t.me/addstickers/PurpleDug
https://t.me/addstickers/fruitflavored
https://t.me/addstickers/spf73c0a02b79e7af5bc087966a4cdfe67_by_stckrRobot
https://t.me/addstickers/Cyndragon
https://t.me/addstickers/zFursee
https://t.me/addstickers/Russ_and_Ruckus
https://t.me/addstickers/Zimty
https://t.me/addstickers/CorginRedclaw81115NaL
https://t.me/addstickers/Stuffiepack
https://t.me/addstickers/DLWRubi
https://t.me/addstickers/KazSubstances
https://t.me/addstickers/MoneroSticker0
https://t.me/addstickers/DuckyDalmatian