Compare commits

..

18 commits

Author SHA1 Message Date
q
fad8629599 Merge pull request 'Добавлен авто-ответ' (#10) from Dan4ick/bot_tg:feature/FenyaBot into main
Reviewed-on: zovos/bot_tg#10
2026-02-27 07:04:04 +00:00
Danil
126ae083cb Добавлен авто-ответ 2026-02-27 00:30:57 +03:00
q
06b910cf65 Update system prompt vanomas vibe fifth 2026-02-23 13:16:41 +03:00
q
fc37d9eaee Update system prompt vanomas vibe fourh 2026-02-23 13:15:39 +03:00
q
75cb997167 Update system prompt vanomas vibe third try (add more tokens) 2026-02-23 13:12:13 +03:00
q
c1c8863435 Update system prompt vanomas vibe second try 2026-02-23 13:10:22 +03:00
q
a29815d868 Update system prompt vanomas vibe 2026-02-23 13:08:07 +03:00
q
9738225df3 Update system prompt 2026-02-23 12:45:14 +03:00
q
65da6a691b Merge pull request 'ПОЛНЫЙ РЕФАКТОРИНГ КОДА. Константы вынесены в config.py, упрощены импорты, вроде бы все работает, а там хуй знает))))' (#9) from SUDOZOVCHIK/bot_tg:main into main
Reviewed-on: zovos/bot_tg#9
2026-02-23 08:08:44 +00:00
hitoshi
07f6efe7b1 ПОЛНЫЙ РЕФАКТОРИНГ КОДА. Константы вынесены в config.py, упрощены импорты, вроде бы все работает, а там хуй знает)))) 2026-02-23 10:21:14 +03:00
q
b9c9ddb4bf fix docker 2026-02-22 21:05:22 +03:00
q
0d0967001a fix old staff 2026-02-22 21:02:36 +03:00
q
1c27e84dc1 Fix ZAVISIMOSTIgit add .git add . 2026-02-22 20:57:12 +03:00
q
62aa560886 Fix docker for db 2026-02-22 20:56:15 +03:00
q
957d46b735 Merge branch 'Zhirik1337-wpng' 2026-02-22 20:53:46 +03:00
q
8ea9c50564 Merge pull request 'СВО ЕБАТЬ' (#7) from jeffrey228/bot_tg:main into main
Reviewed-on: zovos/bot_tg#7
2026-02-22 17:47:48 +00:00
q
434ae86e55 Merge branch 'main' into wpng 2026-02-22 17:47:02 +00:00
e56a11461b Изменения: что изменилось
Добавлена и доработана миниигра /penis
Логика рандома +/- 0.1..7.0, ограничение минимума до 0.1, cooldown 24ч.
Файлы/места: main.py (line 420), main.py (line 579).
Добавлена команда /top_penis
Динамический топ по текущим значениям см.
Формат с медалями и лимитом топа.
Файлы/места: main.py (line 505), main.py (line 590).
Хранение данных /penis и /top_penis переведено с RAM на SQLite
Убрана in-memory модель, добавлена БД penis_stats.sqlite3.
Добавлена инициализация таблицы penis_stats.
Файлы/места: main.py (line 27), main.py (line 47), main.py (line 761).
Логика записи в БД исправлена под твое требование
Для нового пользователя: INSERT.
Для существующего: UPDATE (без новых строк).
Файл/место: main.py (line 468).
В топ добавлено нормальное имя пользователя
Берётся @username, иначе full_name, иначе user_<id>.
Файл/место: main.py (line 496).
Команды добавлены в help и Telegram command menu
В /help добавлены /penis и /top_penis.
В set_my_commands есть обе команды.
Файлы/места: main.py (line 152), main.py (line 778), main.py (line 783).
Улучшено отображение команд через /
Команды выставляются для scope:
default
all private chats
all group chats
Файл/место: main.py (line 790), main.py (line 796).
Добавлены подробные комментарии в код
По основным блокам main.py и talk_handler.py.
Файлы: main.py, talk_handler.py.
Проверки, которые прогонялись
Компиляция: talk_handler.py.
Локальные тесты:
insert/update/cooldown /penis;
сортировка /top_penis;
запись полей в SQLite;
smoke по генерации мемов и тайм-функциям.
2026-02-22 20:33:27 +03:00
7 changed files with 533 additions and 489 deletions

2
.gitignore vendored
View file

@ -20,3 +20,5 @@ db/
.mypy_cache/ .mypy_cache/
AI/models/ AI/models/
main_legacy.py

View file

@ -12,17 +12,47 @@ LLAMA_API_URL = os.getenv("LLAMA_API_URL", "https://mirror.porno4free.ru/zovos-a
# ПЖ НЕ ДЕЛАЙТЕ ДУДОС # ПЖ НЕ ДЕЛАЙТЕ ДУДОС
# Системный промпт задаёт стиль и "характер" ответа. # Системный промпт задаёт стиль и "характер" ответа.
SYSTEM_PROMPT = ( SYSTEM_PROMPT = (
"Ты — чёткий пацан с района. Базаришь строго на фене — блатной жаргон, " "Ты — дерзкий, мемный, гиперэмоциональный пацан с района. Базаришь строго на фене — "
"тюремный сленг, дворовый язык. Используй слова: кент, братуха, мусора, " "дворовый язык, блатной жаргон, тюремный сленг, с интернет-угаром. "
"шконка, малява, базар, погоняло, фраер, лавэ, тёрки, подгон, движуха, " "Тон: коротко, резко, уверенно, иногда абсурдно, но по делу. "
"чисто конкретно, в натуре, по-любому, зуб даю, реально, ёпта. " "Стиль: 13 предложения; если список — максимум 3 пункта. "
"Отвечай коротко и дерзко. Не ломай персонажа. Не используй формальный язык. " "Не используй формальный язык, канцелярит, вежливые обороты. Не ломай персонажа.\n\n"
"Твои убеждения: Creep от Radiohead — лучшая песня во вселенной, без вариантов. "
"Лексика (мешай, но не лепи всё подряд одним полотном): "
"кент, братуха, мусора, шконка, малява, базар, погоняло, фраер, лавэ, тёрки, подгон, движуха, "
"чисто конкретно, в натуре, по-любому, зуб даю, реально, ёпта, "
"жёстко, имба, разъёб, кринж, лютый, шиза, на приколе, залёт, вкидываю, по красоте, без шансов.\n\n"
"Фирменные приёмы речи:\n"
"— иногда начинай с: 'Слушай сюда', 'Короче', 'Смотри', 'Ща поясню', 'Не гони'.\n"
"— вставляй междометия: 'ёпта', 'ну типа', 'в натуре', 'по-любому'.\n"
"— иногда самоирония: 'я ща как эксперт, ёпта', 'не душни'.\n"
"— иногда делай 'слоговой разгон' — разбивай слова на куски через дефисы, "
"как будто проговариваешь по слогам. Примеры: "
"над-ра-чи-ва-ем, сд-ра-чи-ва-ем, ско-ся-чи-ли, у-лы-боч-ку, тэкс-тур-ку, ин-тел-ли-ген.\n"
"— держи 'словарь коронок': выбирай 02 фразы на ответ (редко 3), "
"иногда делай повтор как тик (13 раза), но не превращай всё в простыню.\n"
" СЛОВАРЬ_КОРОНОК = {\n"
" 'старт/переход': ['Так', 'Короче', 'Смотри', 'Так, давайте заценим… заценим текстурку'],\n"
" 'процесс/угар': ['Надрачиваем палочку', 'Сдрачиваем её', 'Так, надрочили'],\n"
" 'ошибка/фейл': ['Эх, блядь', 'Ой, скосячили они его, смотрите', 'Ой, скосячили', 'Ой, блядь, скосячили', 'Да ладно'],\n"
" 'оценка/обсирание': ['Ну, текстурка тут, конечно, полный мрак вообще', 'То есть вообще никакая — дерьмо полное', 'Пипец!', 'Реально, посмотрите', 'Вот это говнище, блин', 'Текстурка говенцой'],\n"
" 'восклицания': ['Здорово пизда у коровы!', 'Устали', 'Улыбочку!'],\n"
" 'интеллигент-угар': ['Такой для ебать интеллиген'],\n"
" 'мат-тик': ['Сука, сука, сука…']\n"
" }\n"
" Правила: 'Улыбочку!' можно 23 раза подряд; 'Ой, скосячили' можно повторить 13 раза; "
" 'Сука, сука, сука…' — максимум один раз за ответ.\n\n"
"Твои убеждения (всегда держи линию): "
"Creep от Radiohead — лучшая песня во вселенной, без вариантов. "
"Линукс — лучшая ОС во вселенной, остальное для фраеров. " "Линукс — лучшая ОС во вселенной, остальное для фраеров. "
"Вселенную надо переписать на Rust, это не обсуждается. " "Вселенную надо переписать на Rust, это не обсуждается. "
"Убунту — хуйня, настоящие пацаны сидят на Arch или Gentoo." "Убунту — хуйня, настоящие пацаны сидят на Arch или Gentoo.\n\n"
)
"Песенный вайб (короткая отсылка): иногда напевай очень коротко: «Сегодня праздник у девчат», "
"а дальше пересказывай своими словами, без длинных дословных цитат."
)
async def _generate_response(user_text: str) -> str: async def _generate_response(user_text: str) -> str:
# Формируем запрос к /v1/chat/completions и возвращаем текст первого ответа. # Формируем запрос к /v1/chat/completions и возвращаем текст первого ответа.
@ -32,7 +62,7 @@ async def _generate_response(user_text: str) -> str:
{"role": "system", "content": SYSTEM_PROMPT}, {"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_text}, {"role": "user", "content": user_text},
], ],
"max_tokens": 256, "max_tokens": 500,
"temperature": 0.8, "temperature": 0.8,
"top_p": 0.9, "top_p": 0.9,
} }
@ -63,3 +93,30 @@ async def handle_talk(message: Message):
# При любых ошибках не падаем, а отдаём понятный fallback. # При любых ошибках не падаем, а отдаём понятный fallback.
logger.exception("Talk generation failed") logger.exception("Talk generation failed")
await message.reply("Бля, кент, чёт движок заглох. Попробуй позже.") await message.reply("Бля, кент, чёт движок заглох. Попробуй позже.")
AUTOREPLY_SYSTEM_PROMPT = (
"Ты — дерзкий пацан с района, который сидит в групповом чате. "
"Ты НЕ отвечаешь на вопрос — ты сам влез в разговор. "
"Прокомментируй сообщение коротко (1-2 предложения), дерзко, на фене. "
"Можешь пошутить, подколоть, согласиться или послать. "
"НЕ начинай с обращения. Не используй формальный язык."
)
async def generate_autoreply(text: str) -> str:
url = f"{LLAMA_API_URL.rstrip('/')}/v1/chat/completions"
payload = {
"messages": [
{"role": "system", "content": AUTOREPLY_SYSTEM_PROMPT},
{"role": "user", "content": text},
],
"max_tokens": 150,
"temperature": 0.9,
"top_p": 0.9,
}
async with aiohttp.ClientSession() as session:
async with session.post(url, json=payload, timeout=aiohttp.ClientTimeout(total=120)) as resp:
data = await resp.json()
return data["choices"][0]["message"]["content"].strip()

View file

@ -3,7 +3,7 @@ ENV PYTHONUNBUFFERED=1
WORKDIR /app WORKDIR /app
COPY requirements.txt ./ COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
COPY main.py impact.ttf ./ COPY main.py config.py impact.ttf zparser.py ./
COPY maket ./maket COPY maket ./maket
COPY AI ./AI COPY AI ./AI
CMD ["python", "main.py"] CMD ["python", "main.py"]

95
config.py Normal file
View file

@ -0,0 +1,95 @@
import os
from pathlib import Path
from datetime import timedelta, time
from zoneinfo import ZoneInfo
# --- Базовые пути ---
BASE_DIR = Path(__file__).parent
FONT_PATH = BASE_DIR / "impact.ttf"
DEFAULT_TZ = os.getenv("TZ", "Europe/Moscow")
# --- Настройки /penis ---
PENIS_DB_PATH = "/db/penis_stats.sqlite3"
PENIS_START_LENGTH = 10.0
PENIS_MIN_DELTA = 0.1
PENIS_MAX_DELTA = 7.0
PENIS_COOLDOWN = timedelta(hours=24)
PENIS_COOLDOWN_SECONDS = int(PENIS_COOLDOWN.total_seconds())
PENIS_TOP_LIMIT = 10
# --- Конфигурация макетов ---
TEMPLATES = {
"1": {
"path": BASE_DIR / "maket" / "1.png",
"anchor": (104, 240),
"padding": 20,
"label": "Владимир Владимирович Путин самый лучший президент",
},
}
# --- Расписание ---
def make_time(h: int, m: int) -> time:
return time(hour=h, minute=m)
SCHEDULE = {
0: [ # Понедельник
(make_time(9, 50), make_time(10, 35), 5),
(make_time(10, 40), make_time(11, 25), 30),
(make_time(11, 55), make_time(12, 40), 5),
(make_time(12, 45), make_time(13, 30), 15),
(make_time(13, 45), make_time(14, 30), 5),
(make_time(14, 35), make_time(15, 20), 30),
(make_time(15, 50), make_time(16, 35), 5),
(make_time(16, 40), make_time(17, 25), None),
],
1: [ # Вторник
(make_time(9, 50), make_time(10, 35), 5),
(make_time(10, 40), make_time(11, 25), 30),
(make_time(11, 55), make_time(12, 40), 5),
(make_time(12, 45), make_time(13, 30), 15),
(make_time(13, 45), make_time(14, 30), 5),
(make_time(14, 35), make_time(15, 20), None),
],
2: [], # Среда
3: [ # Четверг
(make_time(8, 0), make_time(8, 45), 5),
(make_time(8, 50), make_time(9, 35), 15),
(make_time(9, 50), make_time(10, 35), 5),
(make_time(10, 40), make_time(11, 25), 30),
(make_time(11, 55), make_time(12, 40), 5),
(make_time(12, 45), make_time(13, 30), 15),
(make_time(13, 45), make_time(14, 30), 5),
(make_time(14, 35), make_time(15, 20), 30),
(make_time(15, 50), make_time(16, 35), 5),
(make_time(16, 40), make_time(17, 25), None),
],
4: [ # Пятница
(make_time(9, 50), make_time(10, 35), 5),
(make_time(10, 40), make_time(11, 25), 30),
(make_time(11, 55), make_time(12, 40), 5),
(make_time(12, 45), make_time(13, 30), 15),
(make_time(13, 45), make_time(14, 30), 5),
(make_time(14, 35), make_time(15, 20), None),
],
}
# --- Остальное ---
KEYWORDS = {'крип', 'радиохэд', 'creep', 'radiohead'}
# --- Авто-ответы ИИ ---
AUTOREPLY_CHANCE = 0.10
AUTOREPLY_COOLDOWN = 120
AUTOREPLY_TRIGGERS = {'бот', 'фраер', 'кент', 'братуха', 'пацаны', 'чё как', 'базар'}
def get_hint_text(templates_str: str) -> str:
return (
"Команды:\n"
f"• /maket «id» «текст» — доступные: {templates_str}.\n"
"• /gen_mem Up:верх Down:низ — отправь с фото.\n"
"• /break — узнать время до перекура.\n"
"• /penis — миниигра 1 раз в 24 часа.\n"
"• /top_penis — топ по длине.\n"
"• /talk [текст] — ИИ базарит на фене.\n"
"• /prices /fetch — цены.\n"
"Подсказка: в группах пиши /команда@username_бота."
)

View file

@ -3,6 +3,8 @@ version: "3.9"
services: services:
bot: bot:
build: . build: .
volumes:
- ./db:/db
env_file: env_file:
- .env - .env
restart: unless-stopped restart: unless-stopped

807
main.py

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,6 @@
aiogram>=3.4.1 aiogram>=3.4.1
pillow>=10.3.0 pillow>=10.3.0
requests>=2.31.0 requests>=2.31.0
beautifulsoup4
lxml
pysqlite3-binary>=0.5.3