Spaces:
Paused
Paused
| from pyrogram import Client | |
| from config import API_ID, API_HASH, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT | |
| import os | |
| import asyncio | |
| import logging | |
| from PIL import Image | |
| import uuid | |
| import subprocess | |
| logger = logging.getLogger("user_handler") | |
| async def generate_thumbnail(file_path, mime_type): | |
| """生成縮略圖並提供極詳細日誌""" | |
| filename = os.path.basename(file_path) | |
| logger.info(f"[THUMB-FLOW] Starting generation for: {filename}") | |
| if not os.path.exists(file_path): | |
| logger.error(f"[THUMB-FLOW] Source NOT FOUND: {file_path}") | |
| return None | |
| temp_thumb_name = f"thumb_{uuid.uuid4().hex}.jpg" | |
| thumbnail_output_path = os.path.normpath(os.path.join(os.path.dirname(file_path), temp_thumb_name)) | |
| try: | |
| if mime_type.startswith("image/"): | |
| img = Image.open(file_path) | |
| if img.mode in ('RGBA', 'P'): img = img.convert('RGB') | |
| img.thumbnail((THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT)) | |
| img.save(thumbnail_output_path, "JPEG", quality=85) | |
| logger.info(f"[THUMB-FLOW] Image thumb SUCCESS: {thumbnail_output_path}") | |
| elif mime_type.startswith("video/"): | |
| command = [ | |
| "ffmpeg", "-y", "-i", file_path, | |
| "-ss", "00:00:02", "-vframes", "1", | |
| "-vf", f"scale='min({THUMBNAIL_WIDTH},iw)':-1", | |
| "-q:v", "4", thumbnail_output_path | |
| ] | |
| logger.info(f"[THUMB-FLOW] Executing FFmpeg: {' '.join(command)}") | |
| process = await asyncio.create_subprocess_exec( | |
| *command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE | |
| ) | |
| stdout, stderr = await process.communicate() | |
| if process.returncode == 0 and os.path.exists(thumbnail_output_path): | |
| logger.info(f"[THUMB-FLOW] Video thumb SUCCESS: {thumbnail_output_path}") | |
| else: | |
| err_msg = stderr.decode() | |
| logger.error(f"[THUMB-FLOW] FFmpeg FAILED (Code {process.returncode}). Output: {err_msg[-500:]}") | |
| return None | |
| return thumbnail_output_path | |
| except Exception as e: | |
| logger.error(f"[THUMB-FLOW] Critical exception for {filename}: {str(e)}") | |
| return None | |
| async def get_bot_client(): | |
| app = Client("bot_account_session", api_id=API_ID, api_hash=API_HASH, bot_token=TELEGRAM_BOT_TOKEN) | |
| await app.start() | |
| return app | |
| async def send_file_with_pyrogram(file_path, file_name, mime_type, file_size, thumbnail_path=None): | |
| app = await get_bot_client() | |
| try: | |
| target_chat_id = int(TELEGRAM_CHAT_ID) if str(TELEGRAM_CHAT_ID).startswith('-100') else TELEGRAM_CHAT_ID | |
| thumb_id = None | |
| # 這裡不單獨上傳,讓 send_video/document 處理 | |
| message = None | |
| if mime_type.startswith("video/"): | |
| message = await app.send_video(target_chat_id, video=file_path, file_name=file_name, thumb=thumbnail_path) | |
| else: | |
| message = await app.send_document(target_chat_id, document=file_path, file_name=file_name, thumb=thumbnail_path) | |
| if message: | |
| item = message.video or message.document | |
| # 從回傳訊息提取 thumb ID | |
| final_thumb_id = None | |
| if hasattr(item, 'thumbs') and item.thumbs: | |
| final_thumb_id = item.thumbs[-1].file_id | |
| elif hasattr(item, 'thumbnail') and item.thumbnail: | |
| final_thumb_id = item.thumbnail.file_id | |
| return item.file_id, file_name, mime_type, item.file_size, final_thumb_id, message.id | |
| return None, "Upload failed", None, None, None, None | |
| finally: await app.stop() | |