dexsecon commited on
Commit
c83166f
Β·
verified Β·
1 Parent(s): 6dc38a2

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -0
app.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import string
4
+ import random
5
+ import subprocess
6
+ import threading
7
+ import time
8
+ import requests
9
+ from flask import Flask
10
+ import telebot
11
+ from telebot import types
12
+
13
+ # === CONFIG ===
14
+ BOT_TOKEN = "8018538301:AAGRSngj4Bj5nqizPsU3Zux48Yr6fpaZ7To" # πŸ” Replace this with your Telegram Bot Token
15
+ SCRIPT_DIR = "scripts"
16
+ DB_FILE = "scripts.json"
17
+ PORT = int(os.environ.get('PORT', 7860))
18
+ PING_URL = "https://dexsecon-xoomhost.hf.space/ping" # βœ… Auto-ping URL (your space)
19
+
20
+ # === INIT ===
21
+ os.makedirs(SCRIPT_DIR, exist_ok=True)
22
+ app = Flask(__name__)
23
+ bot = telebot.TeleBot(BOT_TOKEN)
24
+ file_upload_mode = {}
25
+ status_map = {}
26
+
27
+ # === UTILITIES ===
28
+ def generate_filename():
29
+ return ''.join(random.choices(string.ascii_letters + string.digits, k=6)) + ".py"
30
+
31
+ def load_db():
32
+ if not os.path.exists(DB_FILE):
33
+ with open(DB_FILE, "w") as f:
34
+ json.dump({}, f)
35
+ with open(DB_FILE, "r") as f:
36
+ return json.load(f)
37
+
38
+ def save_db(data):
39
+ with open(DB_FILE, "w") as f:
40
+ json.dump(data, f, indent=4)
41
+
42
+ def update_status(filename, proc):
43
+ stdout, stderr = proc.communicate()
44
+ if proc.returncode == 0:
45
+ status_map[filename] = 'sleep'
46
+ else:
47
+ status_map[filename] = 'error'
48
+
49
+ def auto_ping():
50
+ while True:
51
+ try:
52
+ requests.get(PING_URL)
53
+ print("βœ… Ping sent to HF")
54
+ except Exception as e:
55
+ print(f"❌ Ping failed: {e}")
56
+ time.sleep(300) # 5 minutes
57
+
58
+ # === TELEGRAM COMMANDS ===
59
+ @bot.message_handler(commands=['start'])
60
+ def start_message(message):
61
+ markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
62
+ markup.add('πŸ“₯ Upload Script', 'πŸ“œ My Scripts')
63
+ markup.add('πŸ“Š Status', 'πŸ”„ Refresh')
64
+ bot.send_message(message.chat.id, "πŸ‘‹ Welcome to XOOM Bot!", reply_markup=markup)
65
+
66
+ @bot.message_handler(commands=['help'])
67
+ def help_message(message):
68
+ bot.send_message(message.chat.id, "Available:\n/start – Menu\n/help – Help info\n/status – Status of your scripts\n/myscripts – Show your scripts")
69
+
70
+ @bot.message_handler(commands=['status'])
71
+ def status_all(message):
72
+ chat_id = str(message.chat.id)
73
+ db = load_db()
74
+ scripts = db.get(chat_id, [])
75
+ counts = {"running": 0, "error": 0, "sleep": 0}
76
+ for s in scripts:
77
+ stat = status_map.get(s, 'unknown')
78
+ if stat in counts:
79
+ counts[stat] += 1
80
+ msg = f"πŸ“Š Status:\nRunning: {counts['running']} πŸ”„\nDone: {counts['sleep']} βœ…\nError: {counts['error']} ❌"
81
+ bot.send_message(message.chat.id, msg)
82
+
83
+ @bot.message_handler(commands=['myscripts'])
84
+ def my_scripts(message):
85
+ chat_id = str(message.chat.id)
86
+ db = load_db()
87
+ scripts = db.get(chat_id, [])
88
+ if not scripts:
89
+ bot.send_message(message.chat.id, "πŸ“‚ No scripts found.")
90
+ return
91
+ msg = "πŸ“œ Your Scripts:\n"
92
+ for s in scripts:
93
+ stat = status_map.get(s, 'unknown')
94
+ icon = {'running': 'πŸ”„', 'sleep': 'βœ…', 'error': '❌'}.get(stat, '❓')
95
+ msg += f"{icon} {s} - {stat}\n"
96
+ bot.send_message(message.chat.id, msg)
97
+
98
+ # === BUTTON HANDLERS ===
99
+ @bot.message_handler(func=lambda m: m.text == 'πŸ“₯ Upload Script')
100
+ def upload_script_btn(message):
101
+ bot.send_message(message.chat.id, "πŸ“‚ Send your .py file now.")
102
+ file_upload_mode[message.chat.id] = True
103
+
104
+ @bot.message_handler(func=lambda m: m.text == 'πŸ“œ My Scripts')
105
+ def my_scripts_btn(message):
106
+ my_scripts(message)
107
+
108
+ @bot.message_handler(func=lambda m: m.text == 'πŸ“Š Status')
109
+ def status_btn(message):
110
+ status_all(message)
111
+
112
+ @bot.message_handler(func=lambda m: m.text == 'πŸ”„ Refresh')
113
+ def refresh_btn(message):
114
+ start_message(message)
115
+
116
+ # === FILE HANDLER ===
117
+ @bot.message_handler(content_types=['document'])
118
+ def handle_file(message):
119
+ if message.chat.id not in file_upload_mode:
120
+ return
121
+ file_info = bot.get_file(message.document.file_id)
122
+ if not file_info.file_path.endswith(".py"):
123
+ bot.send_message(message.chat.id, "❌ Only .py files allowed.")
124
+ return
125
+
126
+ file_data = bot.download_file(file_info.file_path)
127
+ filename = generate_filename()
128
+ filepath = os.path.join(SCRIPT_DIR, filename)
129
+
130
+ with open(filepath, "wb") as f:
131
+ f.write(file_data)
132
+
133
+ chat_id = str(message.chat.id)
134
+ db = load_db()
135
+ db.setdefault(chat_id, []).append(filename)
136
+ save_db(db)
137
+
138
+ try:
139
+ proc = subprocess.Popen(["python3", filepath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
140
+ status_map[filename] = 'running'
141
+ bot.send_message(message.chat.id, f"βœ… Script `{filename}` is running.")
142
+ threading.Thread(target=lambda: update_status(filename, proc)).start()
143
+ except Exception as e:
144
+ status_map[filename] = 'error'
145
+ bot.send_message(message.chat.id, f"❌ Failed: {e}")
146
+
147
+ file_upload_mode.pop(message.chat.id, None)
148
+
149
+ # === FLASK ROUTES ===
150
+ @app.route('/')
151
+ def home():
152
+ return "βœ… XOOM Bot Running - dexsecon/xoomhost"
153
+
154
+ @app.route('/ping')
155
+ def ping():
156
+ return "βœ… Ping OK"
157
+
158
+ # === START EVERYTHING ===
159
+ threading.Thread(target=lambda: bot.infinity_polling(), daemon=True).start()
160
+ threading.Thread(target=auto_ping, daemon=True).start()
161
+
162
+ if __name__ == '__main__':
163
+ app.run(host='0.0.0.0', port=PORT)