| |
| 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) |