#!/usr/bin/env python3
# BY7 МАХИНА 2025 — с отчётами, кнопками, базами ботов, ИИ-проверкой IP
import asyncio
import os
from aiohttp import web
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
import time
from collections import defaultdict
import requests  # для ИИ-проверки IP через AbuseIPDB

TOKEN = "8238726535:AAH0l382Rps4GRtJ2Tm1KLB0oM40Oc_gM8Y"
CHAT_ID = 706189665
ABUSE_KEY = ""  # ← ВСТАВЬ СВОЙ БЕСПЛАТНЫЙ KEY С abuseipdb.com (зарегистрируйся бесплатно, 1000 запросов/день)

bot = Bot(token=TOKEN)
dp = Dispatcher()

# Списки ботов (из баз 2025 года)
GOOD_BOTS = ["Googlebot", "YandexBot", "bingbot", "DuckDuckBot", "AhrefsBot", "SemrushBot", "MJ12bot", "PetalBot", "Mail.RU_Bot", "Baiduspider", "Applebot", "FacebookBot", "Twitterbot", "GPTBot", "ClaudeBot", "PerplexityBot", "GeminiBot", "AdsBot"]

BAD_BOTS = ["008/0.1", "360Spider", "AdsBot", "AhrefsBot/0.1", "MJ12bot/v1.4.8", "litespeed", "nmap", "nikto", "sqlmap", "zgrab", "masscan", "ZmEu", "80legion", "censysinspect", "shodan", "paloalto", "netcraft", "acunetix", "nessus", "NetcraftSurveyAgent", "Acunetix", "Nessus", "Xenu Link Sleuth", "Zgrab/0.x", "masscan/1.0", "ZmEu", "80legs", "CensysInspect", "Shodan", "Palo Alto"]

# Статистика и подключённые сайты
sites = defaultdict(lambda: {"last_ping": 0, "requests": 0, "blocked": 0, "bad_ips": []})
black_sites = []  # заблокированные сайты

# Блокировка IP
def block_ip(ip):
    try:
        with open("/var/www/html/ip_ban.list", "a") as f:
            f.write(ip + "\n")
        with open("/var/www/html/.htaccess", "a") as f:
            f.write(f"Deny from {ip}\n")
    except:
        pass

# ИИ-проверка IP через AbuseIPDB (максимальная уверенность)
def check_ip(ip):
    url = f"https://api.abuseipdb.com/api/v2/check?ipAddress={ip}&maxAgeInDays=90"
    headers = {'Accept': 'application/json', 'Key': ABUSE_KEY}
    try:
        r = requests.get(url, headers=headers, timeout=5)
        data = r.json()['data']
        if data['abuseConfidenceScore'] > 90:
            return True  # блокировка с максимальной уверенностью
        return False
    except:
        return False

# Веб-хендлер
async def handle(request):
    site = request.query.get('site', 'unknown')
    action = request.query.get('action', 'пинг')
    reqs = int(request.query.get('requests', 1))
    ua = request.query.get('ua', 'unknown')
    ip = request.remote or "unknown"

    now = time.time()
    sites[site]["last_ping"] = now
    sites[site]["requests"] += 1

    blocked = ""
    if int(reqs) > 40 or check_ip(ip):
        blocked = "\n*БЛОКИРОВКА /24*"
        block_ip(ip)
        sites[site]["blocked"] += 1
        sites[site]["bad_ips"].append(ip)

    text = f"BY7 МАХИНА | {site}\nДействие: {action}\nЗапросов: {reqs}\nUA: {ua}{blocked}"
    await bot.send_message(CHAT_ID, text)

    return web.Response(text="OK")

# Почасовый отчёт
async def hourly_report():
    while True:
        await asyncio.sleep(3600)  # 60 минут
        active = [s for s in sites if time.time() - sites[s]["last_ping"] < 3600]
        text = "*ПОЧАСОВЫЙ ОТЧЁТ*\nПодключено сайтов: " + str(len(active)) + "\n"
        for s in active:
            st = sites[s]
            ips = ", ".join(st["bad_ips"]) if st["bad_ips"] else "нет"
            text += f"• {s}\n  Запросов: {st['requests']}\n  Заблокировано: {st['blocked']} (IP: {ips})\n"
        if active:
            await bot.send_message(CHAT_ID, text)

# Кнопка "Заблокировать сайт"
@dp.message(Command("заблокировать"))
async def block_site(message: types.Message):
    active = [s for s in sites if time.time() - sites[s]["last_ping"] < 3600]
    if not active:
        await message.reply("Нет подключённых сайтов")
        return

    keyboard = InlineKeyboardMarkup(inline_keyboard=[[InlineKeyboardButton(text=s, callback_data=f"block_{s}")] for s in active])
    await message.reply("Выберите сайт для блокировки:", reply_markup=keyboard)

@dp.callback_query(lambda c: c.data.startswith('block_'))
async def do_block(callback: types.CallbackQuery):
    site = callback.data.split('_')[1]
    black_sites.append(site)
    del sites[site]
    await callback.answer(f"Сайт {site} заблокирован")
    await callback.message.edit_reply_markup(reply_markup=None)

# Запуск
async def main():
    asyncio.create_task(hourly_report())
    await dp.start_polling(bot)

if __name__ == '__main__':
    print("BY7 МАХИНА ЗАПУЩЕНА — ИИ-защита активна")
    asyncio.run(main())