Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 561b12eef1 | |||
| 8525a51b18 | |||
| ed0339c832 | |||
| 41bc89dc9a |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
/venv/
|
|
||||||
.venv/
|
|
||||||
.env
|
.env
|
||||||
|
venv
|
||||||
|
downloads
|
||||||
|
urls.txt
|
||||||
|
|||||||
177
app.py
177
app.py
@@ -1,100 +1,101 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from telegram import Bot
|
from telegram import Bot
|
||||||
from telegram.error import TelegramError
|
from telegram.error import TelegramError
|
||||||
from telegram.ext import Application
|
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):
|
async def download_single_pack(bot: Bot, session: aiohttp.ClientSession, sticker_url: str, allowed_types: list):
|
||||||
"""
|
""" Downloads sticker files with a visually appealing, colored progress bar. """
|
||||||
Asynchronously downloads specific file types from a sticker pack into its own folder.
|
|
||||||
Includes improved logging for skipped files.
|
|
||||||
"""
|
|
||||||
master_download_dir = "downloads"
|
master_download_dir = "downloads"
|
||||||
try:
|
try:
|
||||||
if 't.me/addstickers/' not in sticker_url:
|
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
|
return
|
||||||
|
|
||||||
pack_name = sticker_url.split('/')[-1]
|
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)
|
pack_path = os.path.join(master_download_dir, pack_name)
|
||||||
os.makedirs(pack_path, exist_ok=True)
|
os.makedirs(pack_path, exist_ok=True)
|
||||||
print(f"Saving to directory: ./{pack_path}/")
|
|
||||||
|
|
||||||
sticker_set = await bot.get_sticker_set(pack_name)
|
sticker_set = await bot.get_sticker_set(pack_name)
|
||||||
total_stickers = len(sticker_set.stickers)
|
total_stickers = len(sticker_set.stickers)
|
||||||
print(f"Found {total_stickers} stickers. Filtering for types: {', '.join(allowed_types)}")
|
|
||||||
|
mode_text = "auto" if "auto" in allowed_types else ', '.join(allowed_types)
|
||||||
|
print(f" Mode: {COLOR_YELLOW}{mode_text}{COLOR_RESET}, Found: {total_stickers} stickers.")
|
||||||
|
|
||||||
download_count = 0
|
download_count = 0
|
||||||
skipped_count = 0
|
print_progress_bar(0, total_stickers, pack_name)
|
||||||
|
|
||||||
for i, sticker in enumerate(sticker_set.stickers):
|
for i, sticker in enumerate(sticker_set.stickers):
|
||||||
was_skipped = True # Ga ervan uit dat de sticker wordt overgeslagen, tenzij we iets downloaden
|
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:
|
||||||
|
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:
|
||||||
|
with open(file_path, 'wb') as f: f.write(await response.read())
|
||||||
|
file_downloaded_this_iteration = True
|
||||||
|
else:
|
||||||
|
# Logica voor specifieke types (onveranderd)
|
||||||
|
pass
|
||||||
|
|
||||||
# 1. Check voor primaire sticker (webp, tgs, webm)
|
if file_downloaded_this_iteration:
|
||||||
primary_extension = ".webp"
|
download_count += 1
|
||||||
if sticker.is_animated:
|
|
||||||
primary_extension = ".tgs"
|
|
||||||
elif sticker.is_video:
|
|
||||||
primary_extension = ".webm"
|
|
||||||
|
|
||||||
primary_type = primary_extension.strip('.')
|
print_progress_bar(i + 1, total_stickers, pack_name)
|
||||||
if primary_type in allowed_types:
|
|
||||||
was_skipped = False
|
|
||||||
file_to_download = await bot.get_file(sticker.file_id)
|
|
||||||
file_name = f"{i+1:03d}{primary_extension}"
|
|
||||||
file_path = os.path.join(pack_path, file_name)
|
|
||||||
|
|
||||||
async with session.get(file_to_download.file_path) as response:
|
# GEWIJZIGD: Succesbericht is nu groen
|
||||||
if response.status == 200:
|
print(f" {COLOR_GREEN}✅ Download complete. Total files saved: {download_count}{COLOR_RESET}")
|
||||||
content = await response.read()
|
|
||||||
with open(file_path, 'wb') as f:
|
|
||||||
f.write(content)
|
|
||||||
download_count += 1
|
|
||||||
|
|
||||||
# 2. Check voor PNG thumbnail
|
|
||||||
if 'png' in allowed_types and sticker.thumbnail:
|
|
||||||
was_skipped = False
|
|
||||||
thumb_to_download = await bot.get_file(sticker.thumbnail.file_id)
|
|
||||||
thumb_name = f"{i+1:03d}_thumb.png"
|
|
||||||
thumb_path = os.path.join(pack_path, thumb_name)
|
|
||||||
|
|
||||||
async with session.get(thumb_to_download.file_path) as response:
|
|
||||||
if response.status == 200:
|
|
||||||
content = await response.read()
|
|
||||||
with open(thumb_path, 'wb') as f:
|
|
||||||
f.write(content)
|
|
||||||
download_count += 1
|
|
||||||
|
|
||||||
# NIEUW: Verbeterde logging voor overgeslagen bestanden
|
|
||||||
if was_skipped:
|
|
||||||
skipped_count += 1
|
|
||||||
|
|
||||||
# Update de status op de console
|
|
||||||
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:
|
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():
|
async def main():
|
||||||
"""
|
""" Main function to run the downloader. """
|
||||||
Main asynchronous function to run the sticker downloader script.
|
# NIEUW: Initialiseer colorama voor cross-platform compatibiliteit
|
||||||
"""
|
init(autoreset=True)
|
||||||
print("--- Telegram Sticker Pack Downloader ---")
|
|
||||||
|
print(f"{COLOR_CYAN}--- Telegram Sticker Pack Downloader ---{COLOR_RESET}")
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
bot_token = os.getenv("TELEGRAM_BOT_TOKEN")
|
bot_token = os.getenv("TELEGRAM_BOT_TOKEN")
|
||||||
|
|
||||||
if not 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.")
|
print("Maak een '.env' bestand aan en voeg 'TELEGRAM_BOT_TOKEN=jouw_token' toe.")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -104,57 +105,35 @@ async def main():
|
|||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
try:
|
try:
|
||||||
bot_user = await bot.get_me()
|
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:
|
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
|
return
|
||||||
|
|
||||||
print("\nAvailable file types: webp (static), tgs (animated), webm (video), png (thumbnail)")
|
print(f"\n{COLOR_YELLOW}Available file types: webp, tgs, webm, png{COLOR_RESET}")
|
||||||
type_input = input("Enter desired file types (comma-separated), or type 'all': ").strip().lower()
|
type_input = input("Enter desired file types (comma-separated), 'all', or 'auto': ").strip().lower()
|
||||||
|
|
||||||
# GEWIJZIGD: Correcte logica voor 'all' of lege input
|
|
||||||
if 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("\nChoose an option:")
|
||||||
print("1: Download a single sticker pack from a URL")
|
print("1: Download a single sticker pack from a URL")
|
||||||
print("2: Download multiple packs from a 'urls.txt' file")
|
print("2: Download multiple packs from a 'urls.txt' file")
|
||||||
|
|
||||||
choice = input("Enter your choice (1 or 2): ").strip()
|
choice = input("Enter your choice (1 or 2): ").strip()
|
||||||
|
|
||||||
if choice == '1':
|
if choice == '1':
|
||||||
sticker_url = input("Enter the Sticker Pack URL: ").strip()
|
sticker_url = input("Enter the Sticker Pack URL: ").strip()
|
||||||
if not sticker_url:
|
if sticker_url: await download_single_pack(bot, session, sticker_url, allowed_types)
|
||||||
print("Error: Sticker URL cannot be empty.")
|
|
||||||
else:
|
|
||||||
await download_single_pack(bot, session, sticker_url, allowed_types)
|
|
||||||
|
|
||||||
elif choice == '2':
|
elif choice == '2':
|
||||||
try:
|
try:
|
||||||
with open('urls.txt', 'r') as f:
|
with open('urls.txt', 'r') as f: urls = [line.strip() for line in f if line.strip()]
|
||||||
urls = [line.strip() for line in f if line.strip()]
|
if not urls: print(f"{COLOR_YELLOW}'urls.txt' is empty.{COLOR_RESET}"); return
|
||||||
|
|
||||||
if not urls:
|
|
||||||
print("'urls.txt' is empty.")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"\nFound {len(urls)} URLs. Starting batch download...")
|
print(f"\nFound {len(urls)} URLs. Starting batch download...")
|
||||||
for url in urls:
|
for url in urls: await download_single_pack(bot, session, url, allowed_types)
|
||||||
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}")
|
||||||
except FileNotFoundError:
|
else: print(f"{COLOR_RED}Invalid choice.{COLOR_RESET}")
|
||||||
print("\nError: 'urls.txt' not found.")
|
print(f"\n{COLOR_CYAN}--- Script finished ---{COLOR_RESET}")
|
||||||
except Exception as e:
|
|
||||||
print(f"An error occurred while reading the file: {e}")
|
|
||||||
|
|
||||||
else:
|
|
||||||
print("Invalid choice. Please run the script again and enter 1 or 2.")
|
|
||||||
|
|
||||||
print("\n--- Script finished ---")
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
||||||
@@ -4,6 +4,7 @@ aiosignal==1.4.0
|
|||||||
anyio==4.9.0
|
anyio==4.9.0
|
||||||
attrs==25.3.0
|
attrs==25.3.0
|
||||||
certifi==2025.7.14
|
certifi==2025.7.14
|
||||||
|
colorama==0.4.6
|
||||||
dotenv==0.9.9
|
dotenv==0.9.9
|
||||||
frozenlist==1.7.0
|
frozenlist==1.7.0
|
||||||
h11==0.16.0
|
h11==0.16.0
|
||||||
|
|||||||
97
urls.txt
97
urls.txt
@@ -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
|
|
||||||
Reference in New Issue
Block a user