Files
Roblox-Buyer/services/admin.py
T

198 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
import asyncio
import os
from aiogram.enums import ParseMode
from aiogram.types import FSInputFile, InlineKeyboardButton, InlineKeyboardMarkup
from config import ADMIN_ID, BOT_USERNAME, ROBSEC_FILE
from db.storage import load_config, save_config, load_stats, save_stats
from db.users import all_users, get, save, find_by_username
from keyboards.admin import admin_menu_kb
from models.user import UserProfile
from runtime import get_log_bot
from utils.logging import log_admin, log_admin_document, safe_edit
def is_admin(user_id: int) -> bool:
if user_id == ADMIN_ID:
return True
profile = get(user_id)
return bool(profile and profile.is_admin)
def toggle_shop() -> bool:
cfg = load_config()
cfg.shop_enabled = not cfg.shop_enabled
save_config(cfg)
return cfg.shop_enabled
def toggle_bot() -> bool:
cfg = load_config()
cfg.bot_enabled = not cfg.bot_enabled
save_config(cfg)
return cfg.bot_enabled
def update_rate(key: str, price: float) -> None:
cfg = load_config()
if key in cfg.rates:
cfg.rates[key].price = price
save_config(cfg)
def update_min_withdraw(value: float) -> None:
cfg = load_config()
cfg.min_withdraw = value
save_config(cfg)
def add_treasury(amount_rub: float) -> float:
cfg = load_config()
cfg.treasury += amount_rub
save_config(cfg)
return cfg.treasury
def subtract_treasury(amount_rub: float) -> float:
cfg = load_config()
cfg.treasury = max(0.0, cfg.treasury - amount_rub)
save_config(cfg)
return cfg.treasury
def robsec_info() -> tuple[int, int]:
if not os.path.exists(ROBSEC_FILE):
return 0, 0
size = os.path.getsize(ROBSEC_FILE)
try:
with open(ROBSEC_FILE, "r", encoding="utf-8", errors="ignore") as fh:
lines = sum(1 for _ in fh)
except Exception:
lines = 0
return lines, size
def clear_robsec() -> None:
with open(ROBSEC_FILE, "w", encoding="utf-8") as fh:
fh.write("")
async def send_user_card(target, uid: int) -> None:
profile = get(uid)
if not profile:
return
text = (
f"👤 <b>Пользователь</b>\n\n"
f"🆔 ID: <code>{uid}</code>\n"
f"👤 @{profile.username or ''}\n"
f"📅 Рег: {profile.registered or '?'}\n"
f"💳 Баланс: {profile.balance:.2f}\n"
f"💰 Всего: {profile.total_earned:.2f}\n"
f"🍪 Куки: {profile.cookies_loaded}\n"
f"👥 Рефералов: {len(profile.referrals)}\n"
f"👑 Админ: {'' if profile.is_admin else ''}\n"
f"🚫 Бан: {'' + profile.ban_reason if profile.is_banned else ''}"
)
kb = InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(text=" Баланс", callback_data=f"u_bal_add_{uid}"),
InlineKeyboardButton(text=" Баланс", callback_data=f"u_bal_sub_{uid}"),
],
[
InlineKeyboardButton(
text="🚫 Разбанить" if profile.is_banned else "🚫 Забанить",
callback_data=f"u_ban_{uid}",
)
],
[
InlineKeyboardButton(
text="👑 Убрать админку" if profile.is_admin else "👑 Выдать админку",
callback_data=f"u_admin_{uid}",
)
],
[InlineKeyboardButton(text="🔙 Назад", callback_data="admin_back")],
]
)
if hasattr(target, "answer"):
await target.answer(text, parse_mode=ParseMode.HTML, reply_markup=kb)
else:
await safe_edit(target, text, reply_markup=kb)
async def broadcast(bot, text: str | None = None, photo_id: str | None = None, caption: str | None = None) -> tuple[int, int]:
ok = 0
fail = 0
for uid in all_users():
try:
if photo_id:
await bot.send_photo(uid, photo_id, caption=caption or "", parse_mode=ParseMode.HTML)
else:
await bot.send_message(uid, text or caption or "-", parse_mode=ParseMode.HTML)
ok += 1
except Exception:
fail += 1
await asyncio.sleep(0.05)
return ok, fail
def find_user(query: str) -> int | None:
if query.isdigit():
uid = int(query)
return uid if get(uid) else None
return find_by_username(query)
def set_balance(uid: int, value: float) -> None:
profile = get(uid)
if not profile:
return
profile.balance = value
save(uid, profile)
def add_balance(uid: int, amount: float) -> None:
profile = get(uid)
if not profile:
return
profile.balance += amount
save(uid, profile)
def sub_balance(uid: int, amount: float) -> None:
profile = get(uid)
if not profile:
return
profile.balance = max(0.0, profile.balance - amount)
save(uid, profile)
def toggle_user_admin(uid: int) -> bool:
profile = get(uid)
if not profile:
return False
profile.is_admin = not profile.is_admin
save(uid, profile)
return profile.is_admin
def ban_user(uid: int, reason: str) -> None:
profile = get(uid)
if not profile:
return
profile.is_banned = True
profile.ban_reason = reason
save(uid, profile)
def unban_user(uid: int) -> None:
profile = get(uid)
if not profile:
return
profile.is_banned = False
profile.ban_reason = ""
save(uid, profile)