Last active
June 11, 2024 10:31
-
-
Save erseco/9ea3052e3b2e441606a13de093eabe22 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Telegram Channel Media Downloader | |
Este script descarga archivos multimedia de un canal de Telegram especificado y evita descargar archivos ya existentes. | |
Las variables de configuración se leen desde un archivo `.env`. | |
### Instrucciones: | |
1. Instala las dependencias necesarias: | |
pip install telethon python-dotenv | |
2. Crea un archivo `.env` en el mismo directorio que este script con el siguiente contenido: | |
API_ID=your_api_id | |
API_HASH=your_api_hash | |
PHONE_NUMBER=your_phone_number | |
CHANNEL_ID=your_channel_id | |
SAVE_DIR=downloads | |
LOG_FILE=log.txt | |
3. Ejecuta el script: | |
python tg_downloader.py | |
Este script utiliza el modo sincrónico de Telethon y verifica si los archivos ya existen antes de descargarlos. | |
También registra todas las descargas y errores en un archivo log. | |
""" | |
import os | |
from telethon.sync import TelegramClient | |
from telethon.errors import ChannelPrivateError, ChannelInvalidError, ChatAdminRequiredError | |
from datetime import datetime | |
import sys | |
import time | |
# Function to read configuration from a file | |
def read_config(filename): | |
config = {} | |
with open(filename, 'r') as file: | |
for line in file: | |
name, value = line.strip().split('=') | |
config[name] = value | |
return config | |
# Read configuration | |
config = read_config('config.txt') | |
# Extract variables from config | |
api_id = int(config['API_ID']) | |
api_hash = config['API_HASH'] | |
phone = config['PHONE_NUMBER'] | |
channel_id = int(config['CHANNEL_ID']) | |
save_dir = config['SAVE_DIR'] | |
log_file = config['LOG_FILE'] | |
# Ensure the save directory exists | |
if not os.path.exists(save_dir): | |
os.makedirs(save_dir) | |
# Initialize the Telegram client | |
client = TelegramClient('session_name', api_id, api_hash) | |
# Function to log messages | |
def log_message(message): | |
with open(log_file, 'a') as log: | |
log.write(f"{datetime.now()}: {message}\n") | |
# Function to download media from a message and check if the file size is correct | |
def download_media(message): | |
if message.media: | |
filename = message.file.name or f"{message.id}_{message.date.strftime('%Y-%m-%d_%H-%M-%S')}.unknown" | |
file_path = os.path.join(save_dir, filename) | |
if os.path.exists(file_path) and os.path.getsize(file_path) == message.file.size: | |
print(f"Skipped (already exists and is complete): {file_path}") | |
log_message(f"Skipped (already exists and is complete): {file_path}") | |
return | |
download_successful = False | |
retry_count = 0 | |
while not download_successful and retry_count < 5: | |
try: | |
client.download_media(message.media, file_path) | |
# Check if the file size matches the expected size | |
if os.path.exists(file_path) and os.path.getsize(file_path) == message.file.size: | |
download_successful = True | |
print(f"\nDownloaded: {file_path}") | |
log_message(f"Downloaded: {file_path}") | |
else: | |
raise Exception("File size does not match, retrying download.") | |
except Exception as e: | |
retry_count += 1 | |
error_message = f"Failed to download message ID {message.id} ({file_path}): {e}" | |
print(f"\n{error_message}") | |
log_message(error_message) | |
if os.path.exists(file_path): | |
os.remove(file_path) # Remove incomplete file | |
# Progress bar with dots | |
print(f"Retry {retry_count}/5. Retrying in 3 seconds...", end='', flush=True) | |
time.sleep(3) | |
for _ in range(3): | |
print('.', end='', flush=True) | |
time.sleep(1) | |
print('') | |
# Main function to download all media from the channel | |
def main(): | |
client.start() | |
try: | |
entity = client.get_entity(channel_id) | |
for message in client.iter_messages(entity): | |
filename = message.file.name if message.file else "No Title" | |
print(f"\nProcessing message ID {message.id} - {filename}") | |
download_media(message) | |
except (ChannelPrivateError, ChannelInvalidError, ChatAdminRequiredError) as e: | |
error_message = f"An error occurred: {e}" | |
print(error_message) | |
log_message(error_message) | |
except Exception as e: | |
error_message = f"An unexpected error occurred: {e}" | |
print(error_message) | |
log_message(error_message) | |
finally: | |
client.disconnect() | |
if __name__ == '__main__': | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment