|
|
|
from flask import Flask, render_template, jsonify, request |
|
from pyrogram import Client |
|
import os |
|
import psutil |
|
import time |
|
import shutil |
|
import asyncio |
|
from utils import get_settings, save_group_settings, get_size, humanbytes, get_time, admin_check |
|
from database.users_chats_db import db |
|
from database.ia_filterdb import Media, get_search_results, get_file_details, save_file |
|
from database.filters_mdb import add_filter, get_filters, delete_filter, del_all |
|
from database.gfilters_mdb import add_gfilter, get_gfilters, delete_gfilter, del_allg |
|
from database.connections_mdb import add_connection, all_connections, if_active, delete_connection, make_active, make_inactive |
|
from info import ADMINS, LOG_CHANNEL, CHANNELS, DATABASE_URL, DATABASE_NAME, CACHE_TIME, API_ID, API_HASH, BOT_TOKEN, UPTIME, WEB_SUPPORT, LOG_MSG |
|
from pymongo import MongoClient |
|
|
|
app = Flask(__name__) |
|
|
|
|
|
bot = Client( |
|
name="Professor-Bot", |
|
api_id=API_ID, |
|
api_hash=API_HASH, |
|
bot_token=BOT_TOKEN, |
|
plugins=dict(root="plugins") |
|
) |
|
|
|
|
|
mongo_client = MongoClient(DATABASE_URL) |
|
mongo_db = mongo_client[DATABASE_NAME] |
|
|
|
@app.route('/') |
|
def dashboard(): |
|
return render_template('dashboard.html') |
|
|
|
@app.route('/api/system-info') |
|
def system_info(): |
|
uptime = time.time() - UPTIME |
|
uptime_str = get_time(uptime) |
|
storage = shutil.disk_usage("/") |
|
return jsonify({ |
|
"os": { |
|
"name": os.name, |
|
"version": os.uname().version |
|
}, |
|
"uptime": uptime_str, |
|
"storage": { |
|
"total": storage.total, |
|
"free": storage.free |
|
} |
|
}) |
|
|
|
@app.route('/api/bot-stats') |
|
def bot_stats(): |
|
loop = asyncio.get_event_loop() |
|
total_files = loop.run_until_complete(Media.count_documents()) |
|
total_users = loop.run_until_complete(db.total_users_count()) |
|
total_chats = loop.run_until_complete(db.total_chat_count()) |
|
monsize = loop.run_until_complete(db.get_db_size()) |
|
free = 536870912 - monsize |
|
monsize = get_size(monsize) |
|
free = get_size(free) |
|
return jsonify({ |
|
"total_files": total_files, |
|
"total_users": total_users, |
|
"total_chats": total_chats, |
|
"storage_used": monsize, |
|
"storage_free": free |
|
}) |
|
|
|
@app.route('/api/filters') |
|
def get_filters_api(): |
|
chat_id = request.args.get('chat_id') |
|
if not chat_id: |
|
return jsonify({"error": "Chat ID is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
filters = loop.run_until_complete(get_filters(chat_id)) |
|
return jsonify({"filters": filters}) |
|
|
|
@app.route('/api/add-filter', methods=['POST']) |
|
def add_filter_api(): |
|
chat_id = request.form.get('chat_id') |
|
text = request.form.get('text') |
|
reply_text = request.form.get('reply_text') |
|
btn = request.form.get('btn') |
|
file = request.form.get('file') |
|
alert = request.form.get('alert') |
|
if not chat_id or not text or not reply_text: |
|
return jsonify({"error": "Chat ID, text, and reply text are required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(add_filter(chat_id, text, reply_text, btn, file, alert)) |
|
return jsonify({"message": "Filter added successfully"}) |
|
|
|
@app.route('/api/delete-filter', methods=['POST']) |
|
def delete_filter_api(): |
|
chat_id = request.form.get('chat_id') |
|
text = request.form.get('text') |
|
if not chat_id or not text: |
|
return jsonify({"error": "Chat ID and text are required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(delete_filter(request, text, chat_id)) |
|
return jsonify({"message": "Filter deleted successfully"}) |
|
|
|
@app.route('/api/gfilters') |
|
def get_gfilters_api(): |
|
gfilters = 'gfilters' |
|
loop = asyncio.get_event_loop() |
|
filters = loop.run_until_complete(get_gfilters(gfilters)) |
|
return jsonify({"filters": filters}) |
|
|
|
@app.route('/api/add-gfilter', methods=['POST']) |
|
def add_gfilter_api(): |
|
gfilters = 'gfilters' |
|
text = request.form.get('text') |
|
reply_text = request.form.get('reply_text') |
|
btn = request.form.get('btn') |
|
file = request.form.get('file') |
|
alert = request.form.get('alert') |
|
if not text or not reply_text: |
|
return jsonify({"error": "Text and reply text are required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(add_gfilter(gfilters, text, reply_text, btn, file, alert)) |
|
return jsonify({"message": "Global filter added successfully"}) |
|
|
|
@app.route('/api/delete-gfilter', methods=['POST']) |
|
def delete_gfilter_api(): |
|
gfilters = 'gfilters' |
|
text = request.form.get('text') |
|
if not text: |
|
return jsonify({"error": "Text is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(delete_gfilter(request, text, gfilters)) |
|
return jsonify({"message": "Global filter deleted successfully"}) |
|
|
|
@app.route('/api/users') |
|
def get_users_api(): |
|
loop = asyncio.get_event_loop() |
|
users = loop.run_until_complete(db.get_all_users()) |
|
user_list = [] |
|
loop.run_until_complete(asyncio.gather(*(user_list.append({ |
|
"id": user['id'], |
|
"name": user['name'], |
|
"ban_status": user['ban_status'] |
|
}) for user in users))) |
|
return jsonify({"users": user_list}) |
|
|
|
@app.route('/api/chats') |
|
def get_chats_api(): |
|
loop = asyncio.get_event_loop() |
|
chats = loop.run_until_complete(db.get_all_chats()) |
|
chat_list = [] |
|
loop.run_until_complete(asyncio.gather(*(chat_list.append({ |
|
"id": chat['id'], |
|
"title": chat['title'], |
|
"username": chat['username'], |
|
"chat_status": chat['chat_status'] |
|
}) for chat in chats))) |
|
return jsonify({"chats": chat_list}) |
|
|
|
@app.route('/api/files') |
|
def get_files_api(): |
|
loop = asyncio.get_event_loop() |
|
files = loop.run_until_complete(Media.find().to_list(None)) |
|
file_list = [] |
|
for file in files: |
|
file_list.append({ |
|
"file_id": file['file_id'], |
|
"file_name": file['file_name'], |
|
"file_size": file['file_size'], |
|
"file_type": file['file_type'], |
|
"mime_type": file['mime_type'], |
|
"caption": file['caption'] |
|
}) |
|
return jsonify({"files": file_list}) |
|
|
|
@app.route('/api/add-file', methods=['POST']) |
|
def add_file_api(): |
|
if 'fileUpload' not in request.files: |
|
return jsonify({"error": "No file part"}), 400 |
|
file = request.files['fileUpload'] |
|
if file.filename == '': |
|
return jsonify({"error": "No selected file"}), 400 |
|
if file: |
|
file_path = os.path.join("/app/uploads", file.filename) |
|
file.save(file_path) |
|
loop = asyncio.get_event_loop() |
|
file_id, file_ref = loop.run_until_complete(save_file(file_path)) |
|
os.remove(file_path) |
|
return jsonify({"file_id": file_id, "file_ref": file_ref, "message": "File uploaded successfully"}) |
|
return jsonify({"error": "Failed to upload file"}), 500 |
|
|
|
@app.route('/api/delete-file', methods=['POST']) |
|
def delete_file_api(): |
|
file_id = request.form.get('file_id') |
|
if not file_id: |
|
return jsonify({"error": "File ID is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
result = loop.run_until_complete(Media.collection.delete_one({'_id': file_id})) |
|
if result.deleted_count: |
|
return jsonify({"message": "File deleted successfully"}) |
|
else: |
|
return jsonify({"error": "File not found"}), 404 |
|
|
|
@app.route('/api/settings/<chat_id>') |
|
def get_settings_api(chat_id): |
|
loop = asyncio.get_event_loop() |
|
settings = loop.run_until_complete(get_settings(chat_id)) |
|
return jsonify({"settings": settings}) |
|
|
|
@app.route('/api/save-settings', methods=['POST']) |
|
def save_settings_api(): |
|
chat_id = request.form.get('chat_id') |
|
setting_key = request.form.get('setting_key') |
|
setting_value = request.form.get('setting_value') |
|
if not chat_id or not setting_key or not setting_value: |
|
return jsonify({"error": "Chat ID, setting key, and setting value are required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(save_group_settings(chat_id, setting_key, setting_value)) |
|
return jsonify({"message": "Settings saved successfully"}) |
|
|
|
@app.route('/api/ban-user', methods=['POST']) |
|
def ban_user_api(): |
|
user_id = request.form.get('user_id') |
|
ban_reason = request.form.get('ban_reason', "No Reason") |
|
if not user_id: |
|
return jsonify({"error": "User ID is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(db.ban_user(int(user_id), ban_reason)) |
|
temp.BANNED_USERS.append(int(user_id)) |
|
return jsonify({"message": "User banned successfully"}) |
|
|
|
@app.route('/api/unban-user', methods=['POST']) |
|
def unban_user_api(): |
|
user_id = request.form.get('user_id') |
|
if not user_id: |
|
return jsonify({"error": "User ID is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(db.remove_ban(int(user_id))) |
|
temp.BANNED_USERS.remove(int(user_id)) |
|
return jsonify({"message": "User unbanned successfully"}) |
|
|
|
@app.route('/api/disable-chat', methods=['POST']) |
|
def disable_chat_api(): |
|
chat_id = request.form.get('chat_id') |
|
reason = request.form.get('reason', "No Reason") |
|
if not chat_id: |
|
return jsonify({"error": "Chat ID is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(db.disable_chat(int(chat_id), reason)) |
|
temp.BANNED_CHATS.append(int(chat_id)) |
|
return jsonify({"message": "Chat disabled successfully"}) |
|
|
|
@app.route('/api/enable-chat', methods=['POST']) |
|
def enable_chat_api(): |
|
chat_id = request.form.get('chat_id') |
|
if not chat_id: |
|
return jsonify({"error": "Chat ID is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(db.re_enable_chat(int(chat_id))) |
|
temp.BANNED_CHATS.remove(int(chat_id)) |
|
return jsonify({"message": "Chat enabled successfully"}) |
|
|
|
@app.route('/api/upload-file', methods=['POST']) |
|
def upload_file_api(): |
|
if 'fileUpload' not in request.files: |
|
return jsonify({"error": "No file part"}), 400 |
|
file = request.files['fileUpload'] |
|
if file.filename == '': |
|
return jsonify({"error": "No selected file"}), 400 |
|
if file: |
|
file_path = os.path.join("/app/uploads", file.filename) |
|
file.save(file_path) |
|
loop = asyncio.get_event_loop() |
|
file_id, file_ref = loop.run_until_complete(save_file(file_path)) |
|
os.remove(file_path) |
|
return jsonify({"file_id": file_id, "file_ref": file_ref, "message": "File uploaded successfully"}) |
|
return jsonify({"error": "Failed to upload file"}), 500 |
|
|
|
@app.route('/api/download-file/<file_id>') |
|
def download_file_api(file_id): |
|
loop = asyncio.get_event_loop() |
|
file_details = loop.run_until_complete(get_file_details(file_id)) |
|
if not file_details: |
|
return jsonify({"error": "File not found"}), 404 |
|
file = file_details[0] |
|
return jsonify({ |
|
"file_name": file['file_name'], |
|
"file_size": file['file_size'], |
|
"file_type": file['file_type'], |
|
"mime_type": file['mime_type'], |
|
"caption": file['caption'] |
|
}) |
|
|
|
@app.route('/api/search-files', methods=['GET']) |
|
def search_files_api(): |
|
query = request.args.get('query') |
|
file_type = request.args.get('file_type') |
|
if not query: |
|
return jsonify({"error": "Query is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
files, next_offset, total = loop.run_until_complete(get_search_results(query, file_type=file_type)) |
|
file_list = [] |
|
for file in files: |
|
file_list.append({ |
|
"file_id": file['file_id'], |
|
"file_name": file['file_name'], |
|
"file_size": file['file_size'], |
|
"file_type": file['file_type'], |
|
"mime_type": file['mime_type'], |
|
"caption": file['caption'] |
|
}) |
|
return jsonify({"files": file_list, "next_offset": next_offset, "total": total}) |
|
|
|
@app.route('/api/broadcast', methods=['POST']) |
|
def broadcast_api(): |
|
message_text = request.form.get('message_text') |
|
if not message_text: |
|
return jsonify({"error": "Message text is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
users = loop.run_until_complete(db.get_all_users()) |
|
total_users = loop.run_until_complete(db.total_users_count()) |
|
done = 0 |
|
blocked = 0 |
|
deleted = 0 |
|
failed = 0 |
|
success = 0 |
|
|
|
async def handle_user(user): |
|
nonlocal success, blocked, deleted, failed, done |
|
try: |
|
await bot.send_message(user['id'], message_text) |
|
success += 1 |
|
except UserIsBlocked: |
|
blocked += 1 |
|
except InputUserDeactivated: |
|
deleted += 1 |
|
except Exception as e: |
|
failed += 1 |
|
done += 1 |
|
|
|
loop.run_until_complete(asyncio.gather(*(handle_user(user) for user in users))) |
|
|
|
return jsonify({ |
|
"total_users": total_users, |
|
"completed": done, |
|
"success": success, |
|
"blocked": blocked, |
|
"deleted": deleted, |
|
"failed": failed |
|
}) |
|
|
|
@app.route('/api/ban-users') |
|
def ban_users_api(): |
|
loop = asyncio.get_event_loop() |
|
users = loop.run_until_complete(db.get_all_users()) |
|
banned_users = [] |
|
loop.run_until_complete(asyncio.gather(*(banned_users.append({ |
|
"id": user['id'], |
|
"name": user['name'], |
|
"ban_reason": user['ban_status']['ban_reason'] |
|
}) for user in users if user['ban_status']['is_banned']))) |
|
return jsonify({"banned_users": banned_users}) |
|
|
|
@app.route('/api/banned-chats') |
|
def banned_chats_api(): |
|
loop = asyncio.get_event_loop() |
|
chats = loop.run_until_complete(db.get_all_chats()) |
|
banned_chats = [] |
|
loop.run_until_complete(asyncio.gather(*(banned_chats.append({ |
|
"id": chat['id'], |
|
"title": chat['title'], |
|
"username": chat['username'], |
|
"reason": chat['chat_status']['reason'] |
|
}) for chat in chats if chat['chat_status']['is_disabled']))) |
|
return jsonify({"banned_chats": banned_chats}) |
|
|
|
@app.route('/api/user-info/<user_id>') |
|
def user_info_api(user_id): |
|
try: |
|
loop = asyncio.get_event_loop() |
|
user = loop.run_until_complete(bot.get_users(int(user_id))) |
|
return jsonify({ |
|
"first_name": user.first_name, |
|
"last_name": user.last_name, |
|
"username": user.username, |
|
"id": user.id, |
|
"dc_id": user.dc_id |
|
}) |
|
except Exception as e: |
|
return jsonify({"error": str(e)}), 500 |
|
|
|
@app.route('/api/chat-info/<chat_id>') |
|
def chat_info_api(chat_id): |
|
try: |
|
loop = asyncio.get_event_loop() |
|
chat = loop.run_until_complete(bot.get_chat(int(chat_id))) |
|
members_count = loop.run_until_complete(bot.get_chat_members_count(int(chat_id))) |
|
return jsonify({ |
|
"title": chat.title, |
|
"username": chat.username, |
|
"id": chat.id, |
|
"members_count": members_count |
|
}) |
|
except Exception as e: |
|
return jsonify({"error": str(e)}), 500 |
|
|
|
@app.route('/api/restart-bot', methods=['POST']) |
|
def restart_bot_api(): |
|
admin_id = request.form.get('admin_id') |
|
if not admin_id or int(admin_id) not in ADMINS: |
|
return jsonify({"error": "Unauthorized access"}), 401 |
|
loop = asyncio.get_event_loop() |
|
loop.run_until_complete(bot.stop()) |
|
loop.run_until_complete(bot.start()) |
|
return jsonify({"message": "Bot restarted successfully"}) |
|
|
|
@app.route('/api/add-connection', methods=['POST']) |
|
def add_connection_api(): |
|
group_id = request.form.get('group_id') |
|
user_id = request.form.get('user_id') |
|
if not group_id or not user_id: |
|
return jsonify({"error": "Group ID and User ID are required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
result = loop.run_until_complete(add_connection(group_id, user_id)) |
|
if result: |
|
return jsonify({"message": "Connection added successfully"}) |
|
else: |
|
return jsonify({"error": "Connection already exists"}), 400 |
|
|
|
@app.route('/api/delete-connection', methods=['POST']) |
|
def delete_connection_api(): |
|
group_id = request.form.get('group_id') |
|
user_id = request.form.get('user_id') |
|
if not group_id or not user_id: |
|
return jsonify({"error": "Group ID and User ID are required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
result = loop.run_until_complete(delete_connection(user_id, group_id)) |
|
if result: |
|
return jsonify({"message": "Connection deleted successfully"}) |
|
else: |
|
return jsonify({"error": "Connection not found"}), 404 |
|
|
|
@app.route('/api/group-stats') |
|
def group_stats_api(): |
|
chat_id = request.args.get('chat_id') |
|
if not chat_id: |
|
return jsonify({"error": "Chat ID is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
chat = loop.run_until_complete(db.get_chat(chat_id)) |
|
if not chat: |
|
return jsonify({"error": "Chat not found"}), 404 |
|
return jsonify({ |
|
"chat_id": chat['id'], |
|
"title": chat['title'], |
|
"username": chat['username'], |
|
"chat_status": chat['chat_status'] |
|
}) |
|
|
|
@app.route('/api/bot-status') |
|
def bot_status(): |
|
cpu_usage = psutil.cpu_percent() |
|
ram_usage = psutil.virtual_memory().percent |
|
total_storage, used_storage, free_storage = shutil.disk_usage("/") |
|
return jsonify({ |
|
"cpu_usage": cpu_usage, |
|
"ram_usage": ram_usage, |
|
"total_storage": humanbytes(total_storage), |
|
"used_storage": humanbytes(used_storage), |
|
"free_storage": humanbytes(free_storage), |
|
"uptime": get_time(time.time() - UPTIME) |
|
}) |
|
|
|
@app.route('/api/connections') |
|
def connections_api(): |
|
user_id = request.args.get('user_id') |
|
if not user_id: |
|
return jsonify({"error": "User ID is required"}), 400 |
|
loop = asyncio.get_event_loop() |
|
groupids = loop.run_until_complete(all_connections(str(user_id))) |
|
if groupids is None: |
|
return jsonify({"connections": []}) |
|
connections = [] |
|
for groupid in groupids: |
|
try: |
|
loop = asyncio.get_event_loop() |
|
ttl = loop.run_until_complete(bot.get_chat(int(groupid))) |
|
title = ttl.title |
|
active = loop.run_until_complete(if_active(str(user_id), str(groupid))) |
|
connections.append({ |
|
"group_id": groupid, |
|
"title": title, |
|
"active": active |
|
}) |
|
except Exception as e: |
|
print(f"Error fetching chat info: {e}") |
|
return jsonify({"connections": connections}) |
|
|
|
if __name__ == '__main__': |
|
bot.run() |
|
app.run(host='0.0.0.0', port=7860, debug=False) |