File size: 6,106 Bytes
eaf5eaa 576915b eaf5eaa e6d0867 1b69afa 85d1bc3 eaf5eaa f0a8931 576915b eaf5eaa 576915b eaf5eaa 576915b eaf5eaa 576915b eaf5eaa 576915b eaf5eaa 576915b eaf5eaa 576915b eaf5eaa 576915b eaf5eaa e6d0867 1b69afa e6d0867 1b69afa e6d0867 1b69afa 85d1bc3 e6d0867 1b69afa e6d0867 1b69afa e6d0867 1b69afa e6d0867 eaf5eaa 576915b eaf5eaa 576915b e6d0867 576915b eaf5eaa 576915b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
import requests
from telegram import Update, ReplyKeyboardMarkup, ReplyKeyboardRemove, InputFile
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters, ContextTypes, ConversationHandler
import os
import time
import threading
import asyncio
import io
# Replace with your actual Hugging Face Space backend URL
BACKEND_URL = "https://dragxd-host.hf.space"
SELECT_REPO, UPLOAD_ENV = range(2)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("Send /connect to link your GitHub account.")
async def connect(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = str(update.effective_user.id)
resp = requests.get(f"{BACKEND_URL}/github/login", params={"user_id": user_id})
if resp.status_code == 200:
auth_url = resp.json()["auth_url"]
await update.message.reply_text(f"Connect your GitHub: {auth_url}\nAfter connecting, send /repos to choose a repo.")
else:
await update.message.reply_text("Failed to get GitHub auth URL.")
async def repos(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = str(update.effective_user.id)
resp = requests.get(f"{BACKEND_URL}/github/repos", params={"user_id": user_id})
if resp.status_code == 200:
repos = resp.json()
if not repos:
await update.message.reply_text("No repos found.")
return ConversationHandler.END
repo_names = [r["full_name"] for r in repos]
markup = ReplyKeyboardMarkup([[name] for name in repo_names], one_time_keyboard=True)
await update.message.reply_text("Select a repo:", reply_markup=markup)
return SELECT_REPO
else:
await update.message.reply_text("Failed to fetch repos. Make sure you are connected with GitHub.")
return ConversationHandler.END
async def select_repo(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = str(update.effective_user.id)
repo_full_name = update.message.text
resp = requests.post(f"{BACKEND_URL}/repo/select", json={"user_id": user_id, "repo_full_name": repo_full_name})
if resp.status_code == 200:
await update.message.reply_text(f"Repo selected: {repo_full_name}\nNow upload your .env file.", reply_markup=ReplyKeyboardRemove())
return UPLOAD_ENV
else:
await update.message.reply_text("Failed to select repo.", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
async def upload_env(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = str(update.effective_user.id)
if update.message.document:
file = await update.message.document.get_file()
file_bytes = await file.download_as_bytearray()
files = {"file": (update.message.document.file_name, file_bytes)}
data = {"user_id": user_id}
resp = requests.post(f"{BACKEND_URL}/env/upload", data=data, files=files)
if resp.status_code == 200:
await update.message.reply_text(".env uploaded! Now you can /deploy your project.")
else:
await update.message.reply_text("Failed to upload .env.")
else:
await update.message.reply_text("Please upload your .env file as a document.")
return ConversationHandler.END
async def deploy(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = str(update.effective_user.id)
# Trigger deployment
resp = requests.post(f"{BACKEND_URL}/deploy", json={"user_id": user_id, "github_url": ""})
if resp.status_code != 200 or "deploy_id" not in resp.json():
await update.message.reply_text("Failed to start deployment. Make sure you have selected a repo and uploaded your .env file.")
return
deploy_id = resp.json()["deploy_id"]
await update.message.reply_text(f"Deployment started! ID: {deploy_id}\nStreaming logs:")
async def poll_logs():
last_line = 0
finished = False
while not finished:
try:
logs_resp = requests.get(f"{BACKEND_URL}/logs/{deploy_id}", params={"last_line": last_line})
if logs_resp.status_code == 200:
data = logs_resp.json()
logs = data.get("logs", [])
status = data.get("status", "unknown")
if logs:
for log in logs:
await update.message.reply_text(log)
last_line = data.get("next_line", last_line)
if status != "deploying":
finished = True
await update.message.reply_text(f"Deployment finished with status: {status}")
# Download logs.txt and send as file
logs_file_resp = requests.get(f"{BACKEND_URL}/logs/{deploy_id}/download")
if logs_file_resp.status_code == 200:
log_bytes = io.BytesIO(logs_file_resp.content)
log_bytes.name = "logs.txt"
await update.message.reply_document(document=InputFile(log_bytes))
break
await asyncio.sleep(2)
except Exception as e:
await update.message.reply_text(f"Error streaming logs: {e}")
break
context.application.create_task(poll_logs())
def main():
TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN") # Set your bot token as env variable
app = ApplicationBuilder().token(TOKEN).build()
conv_handler = ConversationHandler(
entry_points=[CommandHandler("repos", repos)],
states={
SELECT_REPO: [MessageHandler(filters.TEXT & ~filters.COMMAND, select_repo)],
UPLOAD_ENV: [MessageHandler(filters.Document.ALL, upload_env)]
},
fallbacks=[]
)
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("connect", connect))
app.add_handler(CommandHandler("deploy", deploy))
app.add_handler(conv_handler)
app.run_polling()
if __name__ == "__main__":
main() |