Update app.py
Browse files
app.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
| 1 |
import os
|
| 2 |
import threading
|
| 3 |
import time
|
|
|
|
| 4 |
import random
|
|
|
|
| 5 |
from datetime import datetime
|
| 6 |
|
| 7 |
from flask_srvr import run_flask
|
|
@@ -25,7 +27,9 @@ start_flask()
|
|
| 25 |
# =========================
|
| 26 |
BOT_TOKEN = os.getenv("tgtkn")
|
| 27 |
GROUP_ID = -1003799294466
|
|
|
|
| 28 |
MAX_STORAGE = 15 * 1024 * 1024 * 1024
|
|
|
|
| 29 |
|
| 30 |
# =========================
|
| 31 |
# π§ STATE
|
|
@@ -35,32 +39,53 @@ user_state = {}
|
|
| 35 |
# =========================
|
| 36 |
# π DB
|
| 37 |
# =========================
|
| 38 |
-
def
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
"
|
| 44 |
-
"folders": {
|
| 45 |
-
"root": {
|
| 46 |
-
"files": [],
|
| 47 |
-
"folders": []
|
| 48 |
-
}
|
| 49 |
-
}
|
| 50 |
}
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
def save_data(uid, data):
|
| 54 |
mdb.set(f"user_{uid}", "json", data)
|
| 55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
# =========================
|
| 57 |
# π STORAGE BAR
|
| 58 |
# =========================
|
| 59 |
-
def storage_bar(used
|
|
|
|
| 60 |
ratio = used / total if total else 0
|
| 61 |
filled = int(ratio * 10)
|
| 62 |
return "β"*filled + "β"*(10-filled)
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
# =========================
|
| 65 |
# π MENU
|
| 66 |
# =========================
|
|
@@ -70,25 +95,20 @@ def main_menu(uid):
|
|
| 70 |
|
| 71 |
return f"""βοΈ Cloud Bot
|
| 72 |
|
| 73 |
-
|
|
|
|
| 74 |
{round(used/1024/1024,2)} MB / 15360 MB
|
| 75 |
"""
|
| 76 |
|
| 77 |
def main_kb():
|
| 78 |
return InlineKeyboardMarkup([
|
| 79 |
[InlineKeyboardButton("π€ Upload", callback_data="upload_root")],
|
| 80 |
-
[InlineKeyboardButton("π Files", callback_data="open_root")]
|
|
|
|
| 81 |
])
|
| 82 |
|
| 83 |
# =========================
|
| 84 |
-
#
|
| 85 |
-
# =========================
|
| 86 |
-
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 87 |
-
uid = update.effective_user.id
|
| 88 |
-
await update.message.reply_text(main_menu(uid), reply_markup=main_kb())
|
| 89 |
-
|
| 90 |
-
# =========================
|
| 91 |
-
# π FOLDER UI
|
| 92 |
# =========================
|
| 93 |
def build_folder(data, folder):
|
| 94 |
f = data["folders"][folder]
|
|
@@ -101,13 +121,27 @@ def build_folder(data, folder):
|
|
| 101 |
for fid in f["files"]:
|
| 102 |
file = data["index"][fid]
|
| 103 |
kb.append([InlineKeyboardButton(
|
| 104 |
-
file[
|
| 105 |
callback_data=f"file_{fid}"
|
| 106 |
)])
|
| 107 |
|
| 108 |
-
kb.append([
|
| 109 |
-
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
return f"π {folder}", InlineKeyboardMarkup(kb)
|
| 113 |
|
|
@@ -122,12 +156,12 @@ async def buttons(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
| 122 |
uid = q.from_user.id
|
| 123 |
data = get_data(uid)
|
| 124 |
|
| 125 |
-
#
|
| 126 |
-
if q.data == "
|
| 127 |
-
user_state
|
| 128 |
-
return await q.message.edit_text(
|
| 129 |
|
| 130 |
-
# OPEN
|
| 131 |
if q.data.startswith("open_"):
|
| 132 |
folder = q.data.split("_",1)[1]
|
| 133 |
text, kb = build_folder(data, folder)
|
|
@@ -136,40 +170,95 @@ async def buttons(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
| 136 |
# UPLOAD
|
| 137 |
if q.data.startswith("upload_"):
|
| 138 |
folder = q.data.split("_",1)[1]
|
| 139 |
-
|
| 140 |
user_state[uid] = {"mode":"upload","folder":folder}
|
| 141 |
return await q.message.edit_text(f"π€ Upload to {folder}")
|
| 142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
# NEW FOLDER
|
| 144 |
if q.data.startswith("newfolder_"):
|
| 145 |
parent = q.data.split("_",1)[1]
|
| 146 |
-
|
| 147 |
user_state[uid] = {"mode":"new_folder","parent":parent}
|
| 148 |
return await q.message.edit_text("π Send folder name")
|
| 149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
except Exception as e:
|
| 151 |
-
print("ERROR:", e)
|
| 152 |
|
| 153 |
# =========================
|
| 154 |
-
# π€
|
| 155 |
# =========================
|
| 156 |
async def handle_file(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 157 |
try:
|
| 158 |
uid = update.effective_user.id
|
| 159 |
|
| 160 |
-
if uid not in user_state:
|
| 161 |
-
return
|
| 162 |
-
|
| 163 |
-
state = user_state[uid]
|
| 164 |
-
if state["mode"] != "upload":
|
| 165 |
return
|
| 166 |
|
| 167 |
-
folder =
|
| 168 |
data = get_data(uid)
|
| 169 |
|
| 170 |
doc = update.message.document
|
| 171 |
-
|
| 172 |
-
|
|
|
|
|
|
|
| 173 |
|
| 174 |
sent = await context.bot.send_document(GROUP_ID, doc.file_id)
|
| 175 |
|
|
@@ -188,7 +277,6 @@ async def handle_file(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
| 188 |
data["folders"][folder]["files"].append(name)
|
| 189 |
|
| 190 |
save_data(uid, data)
|
| 191 |
-
|
| 192 |
user_state.pop(uid)
|
| 193 |
|
| 194 |
await update.message.reply_text("β
Uploaded", reply_markup=main_kb())
|
|
@@ -197,7 +285,7 @@ async def handle_file(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
| 197 |
print("UPLOAD ERROR:", e)
|
| 198 |
|
| 199 |
# =========================
|
| 200 |
-
# π TEXT
|
| 201 |
# =========================
|
| 202 |
async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 203 |
try:
|
|
@@ -209,17 +297,65 @@ async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
| 209 |
state = user_state[uid]
|
| 210 |
data = get_data(uid)
|
| 211 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
if state["mode"] == "new_folder":
|
| 213 |
name = update.message.text
|
| 214 |
parent = state["parent"]
|
| 215 |
|
| 216 |
-
data["folders"][name] = {"files":
|
| 217 |
data["folders"][parent]["folders"].append(name)
|
| 218 |
|
| 219 |
save_data(uid, data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
|
|
|
|
| 221 |
user_state.pop(uid)
|
| 222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
|
| 224 |
except Exception as e:
|
| 225 |
print("TEXT ERROR:", e)
|
|
@@ -234,5 +370,5 @@ app.add_handler(CallbackQueryHandler(buttons))
|
|
| 234 |
app.add_handler(MessageHandler(filters.Document.ALL, handle_file))
|
| 235 |
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text))
|
| 236 |
|
| 237 |
-
print("π₯ BOT RUNNING")
|
| 238 |
app.run_polling()
|
|
|
|
| 1 |
import os
|
| 2 |
import threading
|
| 3 |
import time
|
| 4 |
+
import hashlib
|
| 5 |
import random
|
| 6 |
+
import string
|
| 7 |
from datetime import datetime
|
| 8 |
|
| 9 |
from flask_srvr import run_flask
|
|
|
|
| 27 |
# =========================
|
| 28 |
BOT_TOKEN = os.getenv("tgtkn")
|
| 29 |
GROUP_ID = -1003799294466
|
| 30 |
+
PAGE_SIZE = 5
|
| 31 |
MAX_STORAGE = 15 * 1024 * 1024 * 1024
|
| 32 |
+
HARDCODE_ADMIN = 83939584939485
|
| 33 |
|
| 34 |
# =========================
|
| 35 |
# π§ STATE
|
|
|
|
| 39 |
# =========================
|
| 40 |
# π DB
|
| 41 |
# =========================
|
| 42 |
+
def default_data():
|
| 43 |
+
return {
|
| 44 |
+
"files": [],
|
| 45 |
+
"index": {},
|
| 46 |
+
"folders": {
|
| 47 |
+
"root": {"files": [], "folders": [], "parent": None}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
}
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
def get_data(uid):
|
| 52 |
+
return mdb.get(f"user_{uid}", "json") or default_data()
|
| 53 |
|
| 54 |
def save_data(uid, data):
|
| 55 |
mdb.set(f"user_{uid}", "json", data)
|
| 56 |
|
| 57 |
+
def is_admin(uid):
|
| 58 |
+
admins = mdb.get("admins", "json") or []
|
| 59 |
+
return uid == HARDCODE_ADMIN or uid in admins
|
| 60 |
+
|
| 61 |
# =========================
|
| 62 |
# π STORAGE BAR
|
| 63 |
# =========================
|
| 64 |
+
def storage_bar(used):
|
| 65 |
+
total = MAX_STORAGE
|
| 66 |
ratio = used / total if total else 0
|
| 67 |
filled = int(ratio * 10)
|
| 68 |
return "β"*filled + "β"*(10-filled)
|
| 69 |
|
| 70 |
+
# =========================
|
| 71 |
+
# π§Ύ ICON
|
| 72 |
+
# =========================
|
| 73 |
+
def get_icon(name):
|
| 74 |
+
ext = name.lower().split('.')[-1]
|
| 75 |
+
if ext == "pdf": return "π"
|
| 76 |
+
if ext in ["mp4","mkv"]: return "π₯"
|
| 77 |
+
if ext in ["jpg","png","jpeg"]: return "πΌ"
|
| 78 |
+
return "π¦"
|
| 79 |
+
|
| 80 |
+
# =========================
|
| 81 |
+
# π PASSWORD
|
| 82 |
+
# =========================
|
| 83 |
+
def gen_pass():
|
| 84 |
+
return ''.join(random.choices(string.ascii_letters+string.digits,k=16))
|
| 85 |
+
|
| 86 |
+
def hash_pass(p):
|
| 87 |
+
return hashlib.sha256(p.encode()).hexdigest()
|
| 88 |
+
|
| 89 |
# =========================
|
| 90 |
# π MENU
|
| 91 |
# =========================
|
|
|
|
| 95 |
|
| 96 |
return f"""βοΈ Cloud Bot
|
| 97 |
|
| 98 |
+
π Storage:
|
| 99 |
+
{storage_bar(used)}
|
| 100 |
{round(used/1024/1024,2)} MB / 15360 MB
|
| 101 |
"""
|
| 102 |
|
| 103 |
def main_kb():
|
| 104 |
return InlineKeyboardMarkup([
|
| 105 |
[InlineKeyboardButton("π€ Upload", callback_data="upload_root")],
|
| 106 |
+
[InlineKeyboardButton("π My Files", callback_data="open_root")],
|
| 107 |
+
[InlineKeyboardButton("π Search", callback_data="search")],
|
| 108 |
])
|
| 109 |
|
| 110 |
# =========================
|
| 111 |
+
# π FOLDER VIEW
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
# =========================
|
| 113 |
def build_folder(data, folder):
|
| 114 |
f = data["folders"][folder]
|
|
|
|
| 121 |
for fid in f["files"]:
|
| 122 |
file = data["index"][fid]
|
| 123 |
kb.append([InlineKeyboardButton(
|
| 124 |
+
f"{get_icon(file['original_name'])} {file['original_name']}",
|
| 125 |
callback_data=f"file_{fid}"
|
| 126 |
)])
|
| 127 |
|
| 128 |
+
kb.append([
|
| 129 |
+
InlineKeyboardButton("β Folder", callback_data=f"newfolder_{folder}"),
|
| 130 |
+
InlineKeyboardButton("βοΈ Rename", callback_data=f"renamefolder_{folder}")
|
| 131 |
+
])
|
| 132 |
+
|
| 133 |
+
if folder != "root":
|
| 134 |
+
kb.append([
|
| 135 |
+
InlineKeyboardButton("π Delete", callback_data=f"delfolder_{folder}")
|
| 136 |
+
])
|
| 137 |
+
|
| 138 |
+
kb.append([
|
| 139 |
+
InlineKeyboardButton("π€ Upload Here", callback_data=f"upload_{folder}")
|
| 140 |
+
])
|
| 141 |
+
|
| 142 |
+
kb.append([
|
| 143 |
+
InlineKeyboardButton("π Back", callback_data=f"open_{f['parent'] or 'root'}")
|
| 144 |
+
])
|
| 145 |
|
| 146 |
return f"π {folder}", InlineKeyboardMarkup(kb)
|
| 147 |
|
|
|
|
| 156 |
uid = q.from_user.id
|
| 157 |
data = get_data(uid)
|
| 158 |
|
| 159 |
+
# SEARCH MODE
|
| 160 |
+
if q.data == "search":
|
| 161 |
+
user_state[uid] = {"mode":"search"}
|
| 162 |
+
return await q.message.edit_text("π Send file name")
|
| 163 |
|
| 164 |
+
# OPEN
|
| 165 |
if q.data.startswith("open_"):
|
| 166 |
folder = q.data.split("_",1)[1]
|
| 167 |
text, kb = build_folder(data, folder)
|
|
|
|
| 170 |
# UPLOAD
|
| 171 |
if q.data.startswith("upload_"):
|
| 172 |
folder = q.data.split("_",1)[1]
|
|
|
|
| 173 |
user_state[uid] = {"mode":"upload","folder":folder}
|
| 174 |
return await q.message.edit_text(f"π€ Upload to {folder}")
|
| 175 |
|
| 176 |
+
# FILE
|
| 177 |
+
if q.data.startswith("file_"):
|
| 178 |
+
fid = q.data.split("_",1)[1]
|
| 179 |
+
f = data["index"][fid]
|
| 180 |
+
|
| 181 |
+
kb = [
|
| 182 |
+
[InlineKeyboardButton("π Preview", callback_data=f"preview_{fid}")],
|
| 183 |
+
[InlineKeyboardButton("π₯ Download", callback_data=f"download_{fid}")],
|
| 184 |
+
[InlineKeyboardButton("π Share", callback_data=f"share_{fid}")],
|
| 185 |
+
[InlineKeyboardButton("π Back", callback_data="open_root")]
|
| 186 |
+
]
|
| 187 |
+
|
| 188 |
+
return await q.message.edit_text(f"π {f['original_name']}", reply_markup=kb)
|
| 189 |
+
|
| 190 |
+
# PREVIEW
|
| 191 |
+
if q.data.startswith("preview_"):
|
| 192 |
+
fid = q.data.split("_",1)[1]
|
| 193 |
+
f = data["index"][fid]
|
| 194 |
+
ext = f["original_name"].lower().split('.')[-1]
|
| 195 |
+
|
| 196 |
+
if ext in ["jpg","png","jpeg"]:
|
| 197 |
+
await context.bot.send_photo(uid, f["file_id"])
|
| 198 |
+
elif ext in ["mp4","mkv"]:
|
| 199 |
+
await context.bot.send_video(uid, f["file_id"])
|
| 200 |
+
else:
|
| 201 |
+
await context.bot.send_document(uid, f["file_id"])
|
| 202 |
+
return
|
| 203 |
+
|
| 204 |
+
# DOWNLOAD
|
| 205 |
+
if q.data.startswith("download_"):
|
| 206 |
+
fid = q.data.split("_",1)[1]
|
| 207 |
+
await context.bot.send_document(uid, data["index"][fid]["file_id"])
|
| 208 |
+
return
|
| 209 |
+
|
| 210 |
+
# SHARE
|
| 211 |
+
if q.data.startswith("share_"):
|
| 212 |
+
fid = q.data.split("_",1)[1]
|
| 213 |
+
|
| 214 |
+
pwd = gen_pass()
|
| 215 |
+
data["index"][fid]["share"] = hash_pass(pwd)
|
| 216 |
+
save_data(uid, data)
|
| 217 |
+
|
| 218 |
+
link = f"https://t.me/{context.bot.username}?start=share_{fid}_{uid}"
|
| 219 |
+
|
| 220 |
+
return await q.message.edit_text(f"π {link}\n\nπ Password:\n{pwd}")
|
| 221 |
+
|
| 222 |
# NEW FOLDER
|
| 223 |
if q.data.startswith("newfolder_"):
|
| 224 |
parent = q.data.split("_",1)[1]
|
|
|
|
| 225 |
user_state[uid] = {"mode":"new_folder","parent":parent}
|
| 226 |
return await q.message.edit_text("π Send folder name")
|
| 227 |
|
| 228 |
+
# RENAME FOLDER
|
| 229 |
+
if q.data.startswith("renamefolder_"):
|
| 230 |
+
folder = q.data.split("_",1)[1]
|
| 231 |
+
user_state[uid] = {"mode":"rename_folder","folder":folder}
|
| 232 |
+
return await q.message.edit_text("βοΈ Send new name")
|
| 233 |
+
|
| 234 |
+
# DELETE FOLDER
|
| 235 |
+
if q.data.startswith("delfolder_"):
|
| 236 |
+
folder = q.data.split("_",1)[1]
|
| 237 |
+
code = str(random.randint(100000,999999))
|
| 238 |
+
user_state[uid] = {"mode":"delete_folder","folder":folder,"code":code}
|
| 239 |
+
return await q.message.edit_text(f"Type code:\n{code}")
|
| 240 |
+
|
| 241 |
except Exception as e:
|
| 242 |
+
print("BTN ERROR:", e)
|
| 243 |
|
| 244 |
# =========================
|
| 245 |
+
# π€ UPLOAD
|
| 246 |
# =========================
|
| 247 |
async def handle_file(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 248 |
try:
|
| 249 |
uid = update.effective_user.id
|
| 250 |
|
| 251 |
+
if uid not in user_state or user_state[uid]["mode"] != "upload":
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
return
|
| 253 |
|
| 254 |
+
folder = user_state[uid]["folder"]
|
| 255 |
data = get_data(uid)
|
| 256 |
|
| 257 |
doc = update.message.document
|
| 258 |
+
used = sum(f["file_size"] for f in data["files"])
|
| 259 |
+
|
| 260 |
+
if not is_admin(uid) and used + doc.file_size > MAX_STORAGE:
|
| 261 |
+
return await update.message.reply_text("β Storage full")
|
| 262 |
|
| 263 |
sent = await context.bot.send_document(GROUP_ID, doc.file_id)
|
| 264 |
|
|
|
|
| 277 |
data["folders"][folder]["files"].append(name)
|
| 278 |
|
| 279 |
save_data(uid, data)
|
|
|
|
| 280 |
user_state.pop(uid)
|
| 281 |
|
| 282 |
await update.message.reply_text("β
Uploaded", reply_markup=main_kb())
|
|
|
|
| 285 |
print("UPLOAD ERROR:", e)
|
| 286 |
|
| 287 |
# =========================
|
| 288 |
+
# π TEXT HANDLER
|
| 289 |
# =========================
|
| 290 |
async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 291 |
try:
|
|
|
|
| 297 |
state = user_state[uid]
|
| 298 |
data = get_data(uid)
|
| 299 |
|
| 300 |
+
# SEARCH
|
| 301 |
+
if state["mode"] == "search":
|
| 302 |
+
q = update.message.text.lower()
|
| 303 |
+
res = [f for f in data["files"] if q in f["original_name"].lower()]
|
| 304 |
+
|
| 305 |
+
kb = []
|
| 306 |
+
for f in res[:5]:
|
| 307 |
+
kb.append([InlineKeyboardButton(
|
| 308 |
+
f["original_name"],
|
| 309 |
+
callback_data=f"file_{f['file_name']}"
|
| 310 |
+
)])
|
| 311 |
+
|
| 312 |
+
return await update.message.reply_text("π Results", reply_markup=InlineKeyboardMarkup(kb))
|
| 313 |
+
|
| 314 |
+
# CREATE FOLDER
|
| 315 |
if state["mode"] == "new_folder":
|
| 316 |
name = update.message.text
|
| 317 |
parent = state["parent"]
|
| 318 |
|
| 319 |
+
data["folders"][name] = {"files":[],"folders":[],"parent":parent}
|
| 320 |
data["folders"][parent]["folders"].append(name)
|
| 321 |
|
| 322 |
save_data(uid, data)
|
| 323 |
+
user_state.pop(uid)
|
| 324 |
+
|
| 325 |
+
return await update.message.reply_text("β
Folder Created", reply_markup=main_kb())
|
| 326 |
+
|
| 327 |
+
# RENAME FOLDER
|
| 328 |
+
if state["mode"] == "rename_folder":
|
| 329 |
+
new = update.message.text
|
| 330 |
+
old = state["folder"]
|
| 331 |
+
|
| 332 |
+
data["folders"][new] = data["folders"].pop(old)
|
| 333 |
+
|
| 334 |
+
parent = data["folders"][new]["parent"]
|
| 335 |
+
data["folders"][parent]["folders"].remove(old)
|
| 336 |
+
data["folders"][parent]["folders"].append(new)
|
| 337 |
|
| 338 |
+
save_data(uid, data)
|
| 339 |
user_state.pop(uid)
|
| 340 |
+
|
| 341 |
+
return await update.message.reply_text("β
Renamed", reply_markup=main_kb())
|
| 342 |
+
|
| 343 |
+
# DELETE FOLDER
|
| 344 |
+
if state["mode"] == "delete_folder":
|
| 345 |
+
if update.message.text == state["code"]:
|
| 346 |
+
folder = state["folder"]
|
| 347 |
+
|
| 348 |
+
if data["folders"][folder]["files"] or data["folders"][folder]["folders"]:
|
| 349 |
+
return await update.message.reply_text("β Not empty")
|
| 350 |
+
|
| 351 |
+
parent = data["folders"][folder]["parent"]
|
| 352 |
+
data["folders"][parent]["folders"].remove(folder)
|
| 353 |
+
del data["folders"][folder]
|
| 354 |
+
|
| 355 |
+
save_data(uid, data)
|
| 356 |
+
user_state.pop(uid)
|
| 357 |
+
|
| 358 |
+
return await update.message.reply_text("π Deleted", reply_markup=main_kb())
|
| 359 |
|
| 360 |
except Exception as e:
|
| 361 |
print("TEXT ERROR:", e)
|
|
|
|
| 370 |
app.add_handler(MessageHandler(filters.Document.ALL, handle_file))
|
| 371 |
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text))
|
| 372 |
|
| 373 |
+
print("π₯ FULL BOT RUNNING")
|
| 374 |
app.run_polling()
|