It's version 0.6.2 I clear code
This commit is contained in:
@@ -18,3 +18,6 @@ storage/message.txt
|
|||||||
/addons/todo/todo.db
|
/addons/todo/todo.db
|
||||||
/addons/rule34/urls.db
|
/addons/rule34/urls.db
|
||||||
/addons/x_days_to/days_to_new_year.db
|
/addons/x_days_to/days_to_new_year.db
|
||||||
|
/addons/hello/photo_2025-11-17_20-57-54.jpg
|
||||||
|
/addons/poll/img.png
|
||||||
|
/addons/hello/мемы/
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
def register(dp, state, bot):
|
def register(dp, state, bot):
|
||||||
from . import handlers
|
from . import handlers
|
||||||
|
|
||||||
handlers.register_handlers(dp, state, bot)
|
handlers.register_handlers(dp, state, bot)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from mutagen.id3 import ID3, APIC, error
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def get_video_info(url: str) -> dict:
|
async def get_video_info(url: str) -> Optional[dict]:
|
||||||
"""Получает информацию о видео через yt-dlp"""
|
"""Получает информацию о видео через yt-dlp"""
|
||||||
try:
|
try:
|
||||||
process = await asyncio.create_subprocess_exec(
|
process = await asyncio.create_subprocess_exec(
|
||||||
@@ -63,8 +63,8 @@ def apply_metadata(mp3_path: str, metadata: dict):
|
|||||||
# Сначала удаляем старые теги ID3 если есть
|
# Сначала удаляем старые теги ID3 если есть
|
||||||
try:
|
try:
|
||||||
ID3(mp3_path).delete()
|
ID3(mp3_path).delete()
|
||||||
except:
|
except Exception as e:
|
||||||
pass
|
logger.warning(f"Не удалось удалить старые ID3 теги: {e}")
|
||||||
|
|
||||||
# Добавляем текстовые теги
|
# Добавляем текстовые теги
|
||||||
try:
|
try:
|
||||||
|
|||||||
+15
-10
@@ -3,7 +3,7 @@ import base64
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import asyncio
|
import asyncio
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
from PIL import Image
|
||||||
from aiogram import Dispatcher, Bot
|
from aiogram import Dispatcher, Bot
|
||||||
from aiogram.types import Message, BufferedInputFile
|
from aiogram.types import Message, BufferedInputFile
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
@@ -43,6 +43,11 @@ async def generate_img2img(prompt: str, init_image: BytesIO) -> BytesIO | None:
|
|||||||
:return: BytesIO с результатом или None при ошибке
|
:return: BytesIO с результатом или None при ошибке
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# Определяем размеры оригинала
|
||||||
|
init_image.seek(0)
|
||||||
|
with Image.open(init_image) as img:
|
||||||
|
width, height = img.size
|
||||||
|
|
||||||
# кодируем входное изображение в base64
|
# кодируем входное изображение в base64
|
||||||
init_image_base64 = base64.b64encode(init_image.getvalue()).decode("utf-8")
|
init_image_base64 = base64.b64encode(init_image.getvalue()).decode("utf-8")
|
||||||
|
|
||||||
@@ -50,15 +55,15 @@ async def generate_img2img(prompt: str, init_image: BytesIO) -> BytesIO | None:
|
|||||||
"init_images": [init_image_base64],
|
"init_images": [init_image_base64],
|
||||||
"prompt": prompt,
|
"prompt": prompt,
|
||||||
"negative_prompt": "blurry, low quality, bad anatomy, watermark, text, cropped",
|
"negative_prompt": "blurry, low quality, bad anatomy, watermark, text, cropped",
|
||||||
"steps": 20, # можно 15–20
|
"steps": 25,
|
||||||
"width": 1024, # лучше подставлять размеры исходного фото
|
"width": width, # берём ширину оригинала
|
||||||
"height": 1024,
|
"height": height, # берём высоту оригинала
|
||||||
"sampler_name": "Euler a", # мягкий и стабильный для img2img
|
"sampler_name": "Euler a",
|
||||||
"Schedule_type": "Karras",
|
"scheduler": "Karras", # исправлен ключ
|
||||||
"cfg_scale": 6, # чуть ниже, чем для txt2img
|
"cfg_scale": 10,
|
||||||
"seed": -1,
|
"seed": -1,
|
||||||
"denoising_strength": 0.8, # 0.3–0.5 для «сохранить стиль», 0.6–0.8 для «перерисовать»
|
"denoising_strength": 0.45,
|
||||||
"restore_faces": True, # если работаешь с людьми
|
"restore_faces": True,
|
||||||
"override_settings": {
|
"override_settings": {
|
||||||
"sd_model_checkpoint": "waiNSFWIllustrious_v150.safetensors"
|
"sd_model_checkpoint": "waiNSFWIllustrious_v150.safetensors"
|
||||||
},
|
},
|
||||||
@@ -101,7 +106,7 @@ async def generate_image(prompt: str) -> BytesIO | None:
|
|||||||
"hr_scale": 2, # во сколько раз увеличить при highres fix
|
"hr_scale": 2, # во сколько раз увеличить при highres fix
|
||||||
"hr_upscaler": "Latent", # апскейлер для highres fix
|
"hr_upscaler": "Latent", # апскейлер для highres fix
|
||||||
"override_settings": {
|
"override_settings": {
|
||||||
"sd_model_checkpoint": "waiNSFWIllustrious_v150.safetensors" # выбор модели
|
"sd_model_checkpoint": "sd_xl_base_1.safetensors" # выбор модели
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,66 @@
|
|||||||
from aiogram import Dispatcher, Bot
|
from aiogram import Dispatcher, Bot
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message, FSInputFile
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
from models.state import BotState
|
from models.state import BotState
|
||||||
from config import Config
|
from config import Config
|
||||||
import logging
|
import logging
|
||||||
from utils.antispam import admin_required
|
from utils.antispam import admin_required
|
||||||
from storage.message_storage import save_message # импортируем функцию
|
from storage.message_storage import save_message # импортируем функцию
|
||||||
|
import os
|
||||||
|
import asyncio
|
||||||
|
from random import choice, seed
|
||||||
|
from time import time
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def list_files():
|
||||||
|
# Запускаем синхронный os.listdir в отдельном потоке
|
||||||
|
return await asyncio.to_thread(os.listdir, "/Users/mac/myfirstprogramm/addons/hello/мемы")
|
||||||
|
|
||||||
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
||||||
|
i = 0
|
||||||
@dp.message(Command("hello"))
|
@dp.message(Command("hello"))
|
||||||
@admin_required(1)
|
@admin_required(1)
|
||||||
async def hello(message: Message):
|
async def hello(message: Message):
|
||||||
# сохраняем саму команду пользователя
|
# сохраняем саму команду пользователя
|
||||||
|
nonlocal i
|
||||||
save_message(message.chat.id, message.message_id)
|
save_message(message.chat.id, message.message_id)
|
||||||
|
|
||||||
for admin_id in Config.ADMINS:
|
for admin_id in Config.ADMINS:
|
||||||
try:
|
try:
|
||||||
name = Config.Names.get(admin_id, "Админ")
|
if 1345058877 == admin_id:
|
||||||
msg = await bot.send_message(
|
name = Config.Names.get(admin_id, "Админ")
|
||||||
chat_id=admin_id, text=f"🤖 Я готов к работе, господин {name}!"
|
photo = FSInputFile("/Users/mac/myfirstprogramm/addons/hello/photo_2025-11-17_20-57-54.jpg")
|
||||||
)
|
msg = await bot.send_photo(
|
||||||
# сохраняем сообщение, отправленное админу
|
chat_id=admin_id, photo=photo, caption=f"🤖 Я готов к работе, господин {name}!"
|
||||||
save_message(msg.chat.id, msg.message_id)
|
)
|
||||||
|
|
||||||
logger.info(f"Сообщение отправлено админу {admin_id} ({name})")
|
save_message(msg.chat.id, msg.message_id)
|
||||||
|
logger.info(f"Фото отправлено админу {admin_id} ({name})")
|
||||||
|
elif 6394047531 == admin_id:
|
||||||
|
png = choice(await list_files())
|
||||||
|
i += 1
|
||||||
|
seed(time() + i)
|
||||||
|
name = Config.Names.get(admin_id, "Админ")
|
||||||
|
photo = FSInputFile(f"/Users/mac/myfirstprogramm/addons/hello/мемы/{png}")
|
||||||
|
msg = await bot.send_photo(
|
||||||
|
chat_id=admin_id, photo=photo, caption=f"🤖 Я готов к работе, господин {name}!"
|
||||||
|
)
|
||||||
|
|
||||||
|
save_message(msg.chat.id, msg.message_id)
|
||||||
|
logger.info(f"Фото {f"/Users/mac/myfirstprogramm/addons/hello/мемы/{png}"} отправлено админу {admin_id} ({name})")
|
||||||
|
|
||||||
|
else:
|
||||||
|
name = Config.Names.get(admin_id, "Админ")
|
||||||
|
msg = await bot.send_message(
|
||||||
|
chat_id=admin_id, text=f"🤖 Я готов к работе, господин {name}!"
|
||||||
|
)
|
||||||
|
# сохраняем сообщение, отправленное админу
|
||||||
|
save_message(msg.chat.id, msg.message_id)
|
||||||
|
|
||||||
|
logger.info(f"Сообщение отправлено админу {admin_id} ({name})")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Ошибка при отправке админу {admin_id}: {e}")
|
logger.error(f"Ошибка при отправке админу {admin_id}: {e}")
|
||||||
|
|
||||||
|
|||||||
+24
-5
@@ -3,7 +3,6 @@ from aiogram import Dispatcher, Bot
|
|||||||
from aiogram.types import Message
|
from aiogram.types import Message
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
from models.state import BotState
|
from models.state import BotState
|
||||||
from utils.antispam import saving
|
|
||||||
|
|
||||||
API_URL = "http://127.0.0.1:7700/speak"
|
API_URL = "http://127.0.0.1:7700/speak"
|
||||||
|
|
||||||
@@ -12,7 +11,27 @@ logger = getLogger(__name__)
|
|||||||
|
|
||||||
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
||||||
@dp.message(Command("id"))
|
@dp.message(Command("id"))
|
||||||
@saving
|
async def id_handler(message: Message):
|
||||||
async def id(message: Message):
|
# Разбираем аргументы команды
|
||||||
id = message.from_user.id
|
args = message.text.split()
|
||||||
msg = await message.reply(str(id))
|
if len(args) > 1:
|
||||||
|
try:
|
||||||
|
user_id = int(args[1]) # берём ID из аргумента
|
||||||
|
except ValueError:
|
||||||
|
await message.reply("ID должен быть числом")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
# если аргумента нет — берём ID самого пользователя
|
||||||
|
user_id = message.from_user.id
|
||||||
|
|
||||||
|
# Получаем фото профиля
|
||||||
|
photos = await bot.get_user_profile_photos(user_id=user_id)
|
||||||
|
|
||||||
|
if photos.total_count > 0:
|
||||||
|
for i, photo_sizes in enumerate(photos.photos):
|
||||||
|
file_id = photo_sizes[-1].file_id # самое большое разрешение
|
||||||
|
await message.answer_photo(file_id, caption=f"Аватар #{i + 1}")
|
||||||
|
await message.reply(f"ID пользователя: {user_id}")
|
||||||
|
else:
|
||||||
|
await message.reply(f"У пользователя {user_id} нет аватара")
|
||||||
|
|
||||||
|
|||||||
+22
-12
@@ -1,7 +1,7 @@
|
|||||||
from config import Config
|
from config import Config
|
||||||
from utils.antispam import admin_required
|
from utils.antispam import admin_required
|
||||||
from aiogram import Dispatcher, Bot
|
from aiogram import Dispatcher, Bot
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message, FSInputFile
|
||||||
from models.state import BotState
|
from models.state import BotState
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
@@ -20,7 +20,7 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
|||||||
poll_msg = await bot.send_poll(
|
poll_msg = await bot.send_poll(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
question="Кто опоздает?",
|
question="Кто опоздает?",
|
||||||
options=["Я", "Я очень сильно опоздаю", "Я пиздец как опоздаю", "Наверное", "Не опоздаю"],
|
options=["Я", "Я очень сильно опоздаю", "Я пиздец как опоздаю", "Наверное", "я ДОЛБОЯЩЕР и я к 2 паре", "Не опоздаю"],
|
||||||
is_anonymous=False,
|
is_anonymous=False,
|
||||||
allows_multiple_answers=False,
|
allows_multiple_answers=False,
|
||||||
)
|
)
|
||||||
@@ -44,39 +44,49 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
|||||||
|
|
||||||
# всегда пишем в первый чат из Config.CHAT_IDS
|
# всегда пишем в первый чат из Config.CHAT_IDS
|
||||||
# 6394047531
|
# 6394047531
|
||||||
|
#850906163
|
||||||
|
STARAST = 6394047531
|
||||||
|
|
||||||
if option_ids and option_ids[0] == 0:
|
if not option_ids:
|
||||||
msg = await bot.send_message(
|
msg = await bot.send_message(
|
||||||
chat_id=6394047531, text=f"{username} опоздает"
|
chat_id=STARAST, text=f"{username} Отменил свой голос"
|
||||||
|
)
|
||||||
|
save_message(msg.chat.id, msg.message_id)
|
||||||
|
elif option_ids and option_ids[0] == 0:
|
||||||
|
msg = await bot.send_message(
|
||||||
|
chat_id=STARAST, text=f"{username} опоздает"
|
||||||
)
|
)
|
||||||
save_message(msg.chat.id, msg.message_id)
|
save_message(msg.chat.id, msg.message_id)
|
||||||
elif option_ids and option_ids[0] == 1:
|
elif option_ids and option_ids[0] == 1:
|
||||||
msg = await bot.send_message(
|
msg = await bot.send_message(
|
||||||
chat_id=6394047531, text=f"{username} сильно опоздает"
|
chat_id=STARAST, text=f"{username} сильно опоздает"
|
||||||
)
|
)
|
||||||
save_message(msg.chat.id, msg.message_id)
|
save_message(msg.chat.id, msg.message_id)
|
||||||
elif option_ids and option_ids[0] == 2:
|
elif option_ids and option_ids[0] == 2:
|
||||||
msg = await bot.send_message(
|
msg = await bot.send_message(
|
||||||
chat_id=6394047531, text=f"{username} Пиздец опоздает"
|
chat_id=STARAST, text=f"{username} Пиздец опоздает"
|
||||||
)
|
)
|
||||||
save_message(msg.chat.id, msg.message_id)
|
save_message(msg.chat.id, msg.message_id)
|
||||||
elif option_ids[0] == 3:
|
elif option_ids[0] == 3:
|
||||||
msg = await bot.send_message(
|
msg = await bot.send_message(
|
||||||
chat_id=6394047531, text=f"{username} возможно опоздает"
|
chat_id=STARAST, text=f"{username} возможно опоздает"
|
||||||
)
|
)
|
||||||
save_message(msg.chat.id, msg.message_id)
|
save_message(msg.chat.id, msg.message_id)
|
||||||
|
|
||||||
elif option_ids[0] == 4:
|
elif option_ids[0] == 4:
|
||||||
msg = await bot.send_message(
|
photo = FSInputFile("/Users/mac/myfirstprogramm/addons/poll/img.png")
|
||||||
chat_id=6394047531, text=f"{username} возможно опоздает"
|
msg = await bot.send_photo(
|
||||||
|
chat_id=STARAST, photo=photo, caption=f"{username} ДОЛБОЯЩЕР"
|
||||||
)
|
)
|
||||||
save_message(msg.chat.id, msg.message_id)
|
save_message(msg.chat.id, msg.message_id)
|
||||||
elif not option_ids:
|
|
||||||
|
elif option_ids[0] == 5:
|
||||||
msg = await bot.send_message(
|
msg = await bot.send_message(
|
||||||
chat_id=6394047531, text=f"{username} Отменил свой голос"
|
chat_id=STARAST, text=f"{username} не опоздает"
|
||||||
)
|
)
|
||||||
save_message(msg.chat.id, msg.message_id)
|
save_message(msg.chat.id, msg.message_id)
|
||||||
else:
|
else:
|
||||||
msg = await bot.send_message(
|
msg = await bot.send_message(
|
||||||
chat_id=6394047531, text=f"{username} выбрал вариант {option_ids}"
|
chat_id=STARAST, text=f"{username} выбрал вариант {option_ids}"
|
||||||
)
|
)
|
||||||
save_message(msg.chat.id, msg.message_id)
|
save_message(msg.chat.id, msg.message_id)
|
||||||
|
|||||||
+61
-45
@@ -1,11 +1,8 @@
|
|||||||
import requests
|
import asyncio
|
||||||
from random import randint, choice
|
from random import randint, choice
|
||||||
from bs4 import BeautifulSoup
|
from playwright.async_api import async_playwright
|
||||||
|
|
||||||
BASE_URL = "https://rule34.xxx"
|
BASE_URL = "https://rule34.xxx"
|
||||||
HEADERS = {
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
|
||||||
}
|
|
||||||
URL = f"{BASE_URL}/index.php?page=post&s=list"
|
URL = f"{BASE_URL}/index.php?page=post&s=list"
|
||||||
MAXIMUM = 999
|
MAXIMUM = 999
|
||||||
|
|
||||||
@@ -25,49 +22,68 @@ def get_tags_str() -> str:
|
|||||||
def get_tags() -> str:
|
def get_tags() -> str:
|
||||||
return "+".join(TAGS) if TAGS else ""
|
return "+".join(TAGS) if TAGS else ""
|
||||||
|
|
||||||
def get_url():
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
tags = get_tags()
|
|
||||||
pid = randint(1, MAXIMUM)
|
|
||||||
|
|
||||||
# Формируем корректный URL с query‑параметрами
|
async def get_url():
|
||||||
if tags:
|
async with async_playwright() as p:
|
||||||
url_page = f"{URL}&tags={tags}&pid={pid}"
|
browser = await p.firefox.launch(headless=True)
|
||||||
else:
|
page = await browser.new_page(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
|
||||||
url_page = f"{URL}&pid={pid}"
|
|
||||||
|
|
||||||
r = requests.get(url_page, headers=HEADERS, timeout=5)
|
while True:
|
||||||
soup = BeautifulSoup(r.text, 'lxml')
|
try:
|
||||||
block = soup.find(class_="image-list")
|
tags = get_tags()
|
||||||
if not block:
|
pid = randint(1, MAXIMUM)
|
||||||
continue
|
|
||||||
block = block.find_all("span")
|
# Формируем корректный URL
|
||||||
if not block:
|
if tags:
|
||||||
|
url_page = f"{URL}&tags={tags}&pid={pid}"
|
||||||
|
else:
|
||||||
|
url_page = f"{URL}&pid={pid}"
|
||||||
|
|
||||||
|
await page.goto(url_page, timeout=5000)
|
||||||
|
|
||||||
|
# Ищем блок с картинками
|
||||||
|
block = await page.query_selector(".image-list")
|
||||||
|
if not block:
|
||||||
|
continue
|
||||||
|
|
||||||
|
spans = await block.query_selector_all("span")
|
||||||
|
if not spans:
|
||||||
|
continue
|
||||||
|
|
||||||
|
link_el = await choice(spans).query_selector("a")
|
||||||
|
if not link_el:
|
||||||
|
continue
|
||||||
|
|
||||||
|
href = await link_el.get_attribute("href")
|
||||||
|
if not href:
|
||||||
|
continue
|
||||||
|
|
||||||
|
await page.goto(f"{BASE_URL}{href}", timeout=30000)
|
||||||
|
|
||||||
|
flexi = await page.query_selector(".flexi")
|
||||||
|
if not flexi:
|
||||||
|
continue
|
||||||
|
|
||||||
|
img_el = await flexi.query_selector("img")
|
||||||
|
if not img_el:
|
||||||
|
continue
|
||||||
|
|
||||||
|
url = await img_el.get_attribute("src")
|
||||||
|
if not url:
|
||||||
|
continue
|
||||||
|
|
||||||
|
await browser.close()
|
||||||
|
return url
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[get_url ERROR] {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
link = choice(block).find("a")
|
|
||||||
if not link:
|
|
||||||
continue
|
|
||||||
|
|
||||||
r2 = requests.get(f"{BASE_URL}{link.get('href')}", headers=HEADERS, timeout=10)
|
# Пример использования
|
||||||
soup_two = BeautifulSoup(r2.text, 'lxml')
|
async def main():
|
||||||
|
result = await get_url()
|
||||||
flexi = soup_two.find(class_="flexi")
|
print("Result URL:", result)
|
||||||
if not flexi:
|
|
||||||
continue
|
|
||||||
|
|
||||||
img = flexi.find("img")
|
|
||||||
if not img:
|
|
||||||
continue
|
|
||||||
|
|
||||||
url = img.get("src")
|
|
||||||
if not url:
|
|
||||||
continue
|
|
||||||
|
|
||||||
return url
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[get_url ERROR] {e}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ def register_handlers(dp: Dispatcher, state, bot: Bot):
|
|||||||
@dp.message(Command("rule34"))
|
@dp.message(Command("rule34"))
|
||||||
async def rule34(message: Message):
|
async def rule34(message: Message):
|
||||||
msg = await message.answer_photo(
|
msg = await message.answer_photo(
|
||||||
photo=get_url(),
|
photo= await get_url(),
|
||||||
caption="Вот фото 📷",
|
caption="Вот фото 📷",
|
||||||
reply_markup=get_keyboard()
|
reply_markup=get_keyboard()
|
||||||
)
|
)
|
||||||
@@ -39,7 +39,7 @@ def register_handlers(dp: Dispatcher, state, bot: Bot):
|
|||||||
for attempt in range(3): # максимум 3 попытки
|
for attempt in range(3): # максимум 3 попытки
|
||||||
try:
|
try:
|
||||||
media = InputMediaPhoto(
|
media = InputMediaPhoto(
|
||||||
media=get_url(),
|
media=await get_url(),
|
||||||
caption=f"Новое фото 🌄 (попытка {attempt + 1})"
|
caption=f"Новое фото 🌄 (попытка {attempt + 1})"
|
||||||
)
|
)
|
||||||
await callback.message.edit_media(
|
await callback.message.edit_media(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from aiogram.types import Message
|
|||||||
from models.state import BotState
|
from models.state import BotState
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
|
|
||||||
logger = getLogger(__name__)
|
logger = getLogger(__name__)
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ class TelegramBot:
|
|||||||
self.addons.load("poll")
|
self.addons.load("poll")
|
||||||
self.addons.load("hello")
|
self.addons.load("hello")
|
||||||
# self.addons.load("draw")
|
# self.addons.load("draw")
|
||||||
# self.addons.load("gpt")
|
self.addons.load("gpt")
|
||||||
# self.addons.load("rule34")
|
# self.addons.load("rule34")
|
||||||
# self.addons.load("todo")
|
# self.addons.load("todo")
|
||||||
self.addons.load("miniapps")
|
self.addons.load("miniapps")
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class Config:
|
|||||||
# Admins (user_id: уровень)
|
# Admins (user_id: уровень)
|
||||||
ADMINS: Dict[int, int] = {850906163: 0, 6394047531: 4, 1345058877: 3}
|
ADMINS: Dict[int, int] = {850906163: 0, 6394047531: 4, 1345058877: 3}
|
||||||
|
|
||||||
Names: Dict[int, str] = {850906163: "Ляпич", 6394047531: "Прокопович"}
|
Names: Dict[int, str] = {850906163: "Ляпич", 6394047531: "Прокопович", 1345058877: "Сом"}
|
||||||
|
|
||||||
# Chats
|
# Chats
|
||||||
CHAT_IDS = [-1003038389942]
|
CHAT_IDS = [-1003038389942]
|
||||||
@@ -32,7 +32,7 @@ class Config:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Settings
|
# Settings
|
||||||
ANTISPAM_DELAY = 600
|
ANTISPAM_DELAY = 20
|
||||||
WATCHER_BASE_DELAY = 600
|
WATCHER_BASE_DELAY = 600
|
||||||
|
|
||||||
# Пути
|
# Пути
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ def register_handlers(dp: Dispatcher, state: BotState):
|
|||||||
|
|
||||||
@dp.message(Command("prasp"))
|
@dp.message(Command("prasp"))
|
||||||
@saving
|
@saving
|
||||||
async def send_schedule(message: types.Message):
|
async def send_pschedule(message: types.Message):
|
||||||
"""Отправка расписания"""
|
"""Отправка расписания"""
|
||||||
if is_chat_spam(message.chat.id, state):
|
if is_chat_spam(message.chat.id, state):
|
||||||
await message.answer("НЕ СПАМЬТЕ!!!")
|
await message.answer("НЕ СПАМЬТЕ!!!")
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ class ScheduleService:
|
|||||||
return result, url, day, month
|
return result, url, day, month
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def exact_group_regex(self, group: str) -> re.Pattern:
|
def exact_group_regex(group: str) -> re.Pattern:
|
||||||
# ищем как отдельный токен: граница слева/справа или начало/конец
|
# ищем как отдельный токен: граница слева/справа или начало/конец
|
||||||
pattern = rf"(^|{BOUNDARY}){re.escape(group)}({BOUNDARY}|$)"
|
pattern = rf"(^|{BOUNDARY}){re.escape(group)}({BOUNDARY}|$)"
|
||||||
return re.compile(pattern)
|
return re.compile(pattern)
|
||||||
|
|||||||
+4
-5
@@ -157,16 +157,15 @@ def analyze_bot_logs(log_file_path="bot.log"):
|
|||||||
return stats
|
return stats
|
||||||
|
|
||||||
|
|
||||||
def calculate_duration_hours(start_str, end_str):
|
def calculate_duration_hours(start_str: str, end_str: str) -> float:
|
||||||
"""Вычисляет продолжительность в часах"""
|
"""Вычисляет продолжительность в часах"""
|
||||||
|
fmt = "%Y-%m-%d %H:%M:%S"
|
||||||
try:
|
try:
|
||||||
fmt = "%Y-%m-%d %H:%M:%S"
|
|
||||||
start = datetime.strptime(start_str, fmt)
|
start = datetime.strptime(start_str, fmt)
|
||||||
end = datetime.strptime(end_str, fmt)
|
end = datetime.strptime(end_str, fmt)
|
||||||
return round((end - start).total_seconds() / 3600, 2)
|
return round((end - start).total_seconds() / 3600, 2)
|
||||||
except:
|
except (ValueError, TypeError):
|
||||||
return 0
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
def calculate_success_rate(stats):
|
def calculate_success_rate(stats):
|
||||||
"""Рассчитывает процент успешных операций"""
|
"""Рассчитывает процент успешных операций"""
|
||||||
|
|||||||
Reference in New Issue
Block a user