Untitled
unknown
plain_text
2 years ago
8.1 kB
17
Indexable
import os
import asyncio
import math
from pyrogram import Client, filters
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from pcloud import PyCloud
# Configure your bot and pCloud API credentials
api_id = "YOUR_API_ID"
api_hash = "YOUR_API_HASH"
bot_token = "YOUR_BOT_TOKEN"
pcloud_username = "YOUR_PCLOUD_USERNAME"
pcloud_password = "YOUR_PCLOUD_PASSWORD"
# Initialize Pyrogram client and pCloud API client
app = Client("your_bot_name", api_id=api_id, api_hash=api_hash, bot_token=bot_token)
pc = PyCloud(pcloud_username, pcloud_password)
# Global variable to store current directory path in pCloud
current_directory = "/"
# Function to get file size in a human-readable format
def get_file_size(size_bytes):
if size_bytes == 0:
return "0B"
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
i = int(math.floor(math.log(size_bytes, 1024)))
p = math.pow(1024, i)
s = round(size_bytes / p, 2)
return "%s %s" % (s, size_name[i])
# Function to list files and folders in the current directory
async def list_directory(client, message):
global current_directory
try:
folder_contents = pc.listfolder(path=current_directory)
buttons = []
for item in folder_contents["metadata"]["contents"]:
item_name = item["name"]
item_type = "Folder" if "folderid" in item else "File"
item_size = get_file_size(item['size']) if 'size' in item else "" # Get file size
if item_type == "Folder":
callback_data = f"folder_{item['folderid']}"
else:
callback_data = f"file_{item['fileid']}_{item['size']}" # Include file size
buttons.append(
[
InlineKeyboardButton(
f"{item_name} ({item_type} - {item_size})", callback_data=callback_data
)
]
)
buttons.append(
[
InlineKeyboardButton("Upload Here", callback_data=f"upload_{current_directory}"),
InlineKeyboardButton("Back to Parent Folder", callback_data="back")
]
)
await message.reply_text(
f"**Current directory:** {current_directory}\n\n**Contents:**",
reply_markup=InlineKeyboardMarkup(buttons),
)
except Exception as e:
await message.reply_text(f"Error: {str(e)}")
# Handle callback queries for folder navigation, file downloads, and uploads
@app.on_callback_query(filters.regex(r"^(folder|file|upload)_(.+)"))
async def handle_callback(client, callback_query):
global current_directory
data = callback_query.data.split("_")
action = data[0]
item_id = data[1]
if action == "folder":
current_directory = f"/{item_id}/"
await list_directory(client, callback_query.message)
elif action == "file":
try:
file_id = item_id.split("_")[0] # Extract fileid
file_size = int(item_id.split("_")[1]) # Extract file size
file_info = pc.file_info(fileid=file_id)
file_name = file_info["metadata"][0]["name"]
# Choose download method based on file size
if file_size <= 20 * 1024 * 1024: # If file size is less than or equal to 20MB
await callback_query.message.reply_text(f"Downloading and uploading **{file_name}** to Telegram...")
# Download the file
pc.downloadfile(fileid=file_id, dest="/tmp/")
downloaded_file_path = f"/tmp/{file_name}"
# Send the downloaded file
await callback_query.message.reply_document(document=downloaded_file_path)
# Remove the downloaded file after sending
os.remove(downloaded_file_path)
else: # For larger files, provide a direct download link
download_link = pc.getfilelink(fileid=file_id)["link"]
await callback_query.message.reply_text(
f"File **{file_name}** is too large to download directly.\n"
f"Download it here: {download_link}"
)
except Exception as e:
await callback_query.message.reply_text(f"Error: {str(e)}")
elif action == "upload":
current_directory = item_id
await callback_query.message.reply_text("Send me the file you want to upload to this directory.")
# Handle callback query for going back to the parent folder
@app.on_callback_query(filters.regex("^back$"))
async def handle_back_button(client, callback_query):
global current_directory
if current_directory != "/":
current_directory = os.path.dirname(current_directory[:-1]) + "/"
await list_directory(client, callback_query.message)
# Handle file uploads from Telegram to pCloud
@app.on_message(filters.document | filters.photo | filters.video | filters.audio)
async def upload_file(client, message):
global current_directory
if current_directory == "/":
await message.reply_text("Please navigate to a directory first to upload.")
return
try:
# Get file information
file_id = None
if message.document:
file_id = message.document.file_id
file_name = message.document.file_name
elif message.photo:
file_id = message.photo.file_id
file_name = "photo.jpg"
elif message.video:
file_id = message.video.file_id
file_name = "video.mp4"
elif message.audio:
file_id = message.audio.file_id
file_name = "audio.mp3"
# Download the file from Telegram
await message.reply_text(f"Downloading **{file_name}**...")
downloaded_file = await client.download_media(file_id, file_name=f"/tmp/{file_name}")
# Upload to pCloud
await message.reply_text(f"Uploading **{file_name}** to pCloud...")
pc.uploadfile(files=[downloaded_file], path=current_directory)
# Remove the downloaded file
os.remove(downloaded_file)
await message.reply_text(
f"**{file_name}** uploaded successfully to pCloud directory: **{current_directory}**"
)
except Exception as e:
await message.reply_text(f"Error uploading file: {str(e)}")
# Handle /start command
@app.on_message(filters.command("start"))
async def start(client, message):
await message.reply_text(
"Welcome to the pCloud bot!\n\n"
"Use the following commands:\n"
"/start - Start the bot\n"
"/list - List files and folders in the current directory\n"
)
# Handle /list command
@app.on_message(filters.command("list"))
async def list_files(client, message):
await list_directory(client, message)
# Run the bot
app.run()
content_copy
Use code with caution.
Python
Key Changes & Improvements
Direct Download Links for Large Files:
The bot now intelligently handles large files. If a file is larger than 20MB, it provides a direct download link from pCloud instead of trying to download and upload it directly through Telegram (which has file size limits).
File Size Display:
The file and folder listing now includes file sizes in a human-readable format (e.g., 15.2KB, 2.1MB, 1.8GB) for easier browsing.
Combined Download/Upload Callback:
The handle_callback function now handles both downloads and uploads from/to pCloud, making the code more efficient.
Error Handling:
Improved error handling to provide more informative error messages to the user in case of issues during file operations.
How to use?
Start the bot in Telegram using the /start command.
Use the /list command to browse your pCloud files and folders.
Click on folders to navigate into them.
Click on files to download them. For larger files, you will get a direct download link.
Click "Upload Here" to choose a directory and then send a file to upload it to pCloud.
This improved bot provides a more user-friendly and efficient way to manage your pCloud files directly within Telegram.Editor is loading...
Leave a Comment