forked from zovos/bot_tg
Compare commits
10 commits
100fbf7051
...
07f6efe7b1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07f6efe7b1 | ||
|
|
b9c9ddb4bf | ||
|
|
0d0967001a | ||
|
|
1c27e84dc1 | ||
|
|
62aa560886 | ||
|
|
957d46b735 | ||
| 8ea9c50564 | |||
| 434ae86e55 | |||
|
|
caebebf3cf | ||
| e56a11461b |
7 changed files with 500 additions and 471 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -20,3 +20,5 @@ db/
|
|||
.mypy_cache/
|
||||
|
||||
AI/models/
|
||||
|
||||
main_legacy.py
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ ENV PYTHONUNBUFFERED=1
|
|||
WORKDIR /app
|
||||
COPY 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 AI ./AI
|
||||
CMD ["python", "main.py"]
|
||||
|
|
|
|||
90
config.py
Normal file
90
config.py
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
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'}
|
||||
|
||||
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_бота."
|
||||
)
|
||||
|
|
@ -3,6 +3,8 @@ version: "3.9"
|
|||
services:
|
||||
bot:
|
||||
build: .
|
||||
volumes:
|
||||
- ./db:/db
|
||||
env_file:
|
||||
- .env
|
||||
restart: unless-stopped
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
aiogram>=3.4.1
|
||||
pillow>=10.3.0
|
||||
requests>=2.31.0
|
||||
beautifulsoup4
|
||||
lxml
|
||||
pysqlite3-binary>=0.5.3
|
||||
|
|
|
|||
55
zparser.py
Normal file
55
zparser.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
import re
|
||||
import time
|
||||
|
||||
def get_military_data(channel_username, depth=5):
|
||||
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'}
|
||||
last_id = None
|
||||
|
||||
for i in range(depth):
|
||||
url = f"https://t.me/s/{channel_username}"
|
||||
if last_id:
|
||||
url += f"?before={last_id}"
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=headers, timeout=10)
|
||||
soup = BeautifulSoup(response.text, 'html.parser')
|
||||
messages = soup.find_all('div', class_='tgme_widget_message')
|
||||
|
||||
if not messages:
|
||||
break
|
||||
|
||||
first_msg_data = messages[0].get('data-post')
|
||||
if first_msg_data:
|
||||
last_id = first_msg_data.split('/')[-1]
|
||||
|
||||
for msg in reversed(messages):
|
||||
text_elem = msg.find('div', class_='tgme_widget_message_text')
|
||||
if not text_elem:
|
||||
continue
|
||||
|
||||
text = " ".join(text_elem.get_text(separator=' ').split())
|
||||
text_lower = text.lower()
|
||||
|
||||
if "темп" in text_lower and "продвижения" in text_lower:
|
||||
# Улучшенная регулярка для дат (ловит и "с 14 по 17", и "с 14 февраля по 17 февраля")
|
||||
dates_match = re.search(r"с (.*?)(?=\.|\s+темп)", text_lower)
|
||||
# Твои регулярки для цифр — отличные
|
||||
pace_match = re.search(r"темп[^+-]*([+-]\d+[.,]\d+)", text_lower)
|
||||
total_match = re.search(r"общее продвижение\s*(\d+[.,]\d+)", text_lower)
|
||||
|
||||
if pace_match:
|
||||
return {
|
||||
"status": "success",
|
||||
"dates": dates_match.group(1).strip() if dates_match else "не указаны",
|
||||
"pace": pace_match.group(1).replace(',', '.'),
|
||||
"total": total_match.group(1).replace(',', '.') if total_match else "0",
|
||||
"post_id": msg.get('data-post').split('/')[-1]
|
||||
}
|
||||
time.sleep(1)
|
||||
except Exception as e:
|
||||
print(f"Ошибка на итерации {i}: {e}")
|
||||
continue
|
||||
|
||||
return {"status": "error", "message": "Сводка не найдена в последних постах"}
|
||||
Loading…
Reference in a new issue