Добавил функцию переписи населения
This commit is contained in:
parent
2dd292ed4a
commit
e08116ae07
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/.idea/
|
||||||
|
users.txt
|
||||||
14
.idea/.gitignore
generated
vendored
14
.idea/.gitignore
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
||||||
.idea/
|
|
||||||
/.env
|
|
||||||
/misc.xml
|
|
||||||
/vcs.xml
|
|
||||||
/tgo-bot.iml
|
|
||||||
/modules.xml
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
# Используем официальный Python образ в качестве базового
|
# Используем официальный Python образ в качестве базового
|
||||||
FROM python:3.11-slim
|
FROM python:3.13.1-slim
|
||||||
|
|
||||||
LABEL authors="UdoChudo"
|
LABEL authors="UdoChudo"
|
||||||
|
|
||||||
@ -11,12 +11,13 @@ COPY requirements.txt .
|
|||||||
|
|
||||||
# Устанавливаем зависимости
|
# Устанавливаем зависимости
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
RUN mkdir /app/data
|
||||||
# Копируем все файлы проекта в рабочую директорию
|
# Копируем все файлы проекта в рабочую директорию
|
||||||
COPY main.py .
|
COPY main.py .
|
||||||
|
|
||||||
# Устанавливаем переменную окружения для токена API
|
# Устанавливаем переменную окружения для токена API
|
||||||
ENV BOT_TOKEN=your_api_token_here
|
ENV BOT_TOKEN=your_api_token_here
|
||||||
|
ENV CAT_TOKEN=your_cat_token_here
|
||||||
|
ENV DOG_TOKEN=your_dog_token_here
|
||||||
# Команда для запуска бота
|
# Команда для запуска бота
|
||||||
CMD ["python", "main.py"]
|
CMD ["python", "main.py"]
|
||||||
|
|||||||
118
main.py
118
main.py
@ -1,30 +1,59 @@
|
|||||||
|
import os
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
from aiogram import Bot, Dispatcher, types
|
from aiogram import Bot, Dispatcher, types, BaseMiddleware
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message, InputFile, FSInputFile
|
||||||
|
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import os
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
# Загрузка переменных окружения из .env файла
|
# Загрузка переменных окружения из .env файла
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
# Получение токена из переменной окружения
|
# Получение токена из переменной окружения
|
||||||
BOT_TOKEN = os.getenv("BOT_TOKEN")
|
BOT_TOKEN = os.getenv('BOT_TOKEN')
|
||||||
LOG_LEVEL = os.getenv("LOG_LEVEL")
|
LOG_LEVEL = os.getenv("LOG_LEVEL")
|
||||||
API_TOKEN_CATS = os.getenv("CATS_TOKEN")
|
CAT_API = os.getenv('CAT_TOKEN')
|
||||||
API_TOKEN_DOGS = os.getenv("DOGS_TOKEN")
|
DOG_API = os.getenv('DOG_TOKEN')
|
||||||
if not BOT_TOKEN:
|
BOT_OWNER_ID = os.getenv('BOT_OWNER')
|
||||||
raise ValueError("No BOT_TOKEN provided. Please set the API_TOKEN environment variable.")
|
if not API_TOKEN:
|
||||||
|
raise ValueError("No API_TOKEN provided. Please set the API_TOKEN environment variable.")
|
||||||
|
if not CAT_API:
|
||||||
|
raise ValueError("No CAT_TOKEN provided. Please set the CAT_TOKEN environment variable.")
|
||||||
|
if not DOG_API:
|
||||||
|
raise ValueError("No DOG_TOKEN provided. Please set the DOG_TOKEN environment variable.")
|
||||||
|
if not BOT_OWNER_ID:
|
||||||
|
raise ValueError("No BOT_OWNER_ID provided. Please set the BOT_OWNER_ID environment variable.")
|
||||||
|
FILE_PATH = "/app/data/users.txt"
|
||||||
|
FILE_PATH_WINDOWS = "./users.txt"
|
||||||
# Настраиваем логирование
|
# Настраиваем логирование
|
||||||
logging.basicConfig(level=logging.ERROR)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
# Инициализация бота
|
# Инициализация бота
|
||||||
bot = Bot(token=BOT_TOKEN)
|
bot = Bot(token=BOT_TOKEN)
|
||||||
dp = Dispatcher()
|
dp = Dispatcher()
|
||||||
|
|
||||||
|
# Middleware для ограничения частоты запросов
|
||||||
|
class ThrottlingMiddleware(BaseMiddleware):
|
||||||
|
def __init__(self, rate_limit=1.0):
|
||||||
|
self.rate_limit = rate_limit
|
||||||
|
self.last_time = {}
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
async def __call__(self, handler, event, data):
|
||||||
|
if isinstance(event, types.Message):
|
||||||
|
user_id = event.from_user.id
|
||||||
|
now = asyncio.get_event_loop().time()
|
||||||
|
if user_id in self.last_time and now - self.last_time[user_id] < self.rate_limit:
|
||||||
|
await event.answer("Подождите немного перед повторным нажатием!")
|
||||||
|
return
|
||||||
|
self.last_time[user_id] = now
|
||||||
|
return await handler(event, data)
|
||||||
|
|
||||||
|
# Регистрируем middleware
|
||||||
|
dp.message.middleware(ThrottlingMiddleware())
|
||||||
|
|
||||||
|
|
||||||
# Обработчик команды /boobs
|
# Обработчик команды /boobs
|
||||||
@dp.message(Command(commands=['boobs'], prefix="!/"))
|
@dp.message(Command(commands=['boobs'], prefix="!/"))
|
||||||
async def send_boobs(message: Message):
|
async def send_boobs(message: Message):
|
||||||
@ -83,7 +112,7 @@ async def send_butts(message: Message):
|
|||||||
|
|
||||||
@dp.message(Command(commands=['cats'], prefix="!/"))
|
@dp.message(Command(commands=['cats'], prefix="!/"))
|
||||||
async def send_cats(message: Message):
|
async def send_cats(message: Message):
|
||||||
response = requests.get('https://api.thecatapi.com/api/images/get?api_key=API_TOKEN_CATS&format=json')
|
response = requests.get('https://api.thecatapi.com/api/images/get?api_key=' + CAT_API + '&format=json')
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
data = response.json()
|
data = response.json()
|
||||||
if data:
|
if data:
|
||||||
@ -101,7 +130,7 @@ async def send_cats(message: Message):
|
|||||||
|
|
||||||
@dp.message(Command(commands=['dogs'], prefix="!/"))
|
@dp.message(Command(commands=['dogs'], prefix="!/"))
|
||||||
async def send_dogs(message: Message):
|
async def send_dogs(message: Message):
|
||||||
response = requests.get('https://api.thedogapi.com/api/images/get?api_key=API_TOKEN_DOGS&format=json')
|
response = requests.get('https://api.thedogapi.com/api/images/get?api_key=' + DOG_API + '&format=json')
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
data = response.json()
|
data = response.json()
|
||||||
if data:
|
if data:
|
||||||
@ -116,17 +145,68 @@ async def send_dogs(message: Message):
|
|||||||
await message.answer("Не удалось получить данные с сервера.")
|
await message.answer("Не удалось получить данные с сервера.")
|
||||||
else:
|
else:
|
||||||
await message.answer("Ошибка при выполнении запроса к API.")
|
await message.answer("Ошибка при выполнении запроса к API.")
|
||||||
|
|
||||||
|
@dp.message(Command("census"))
|
||||||
|
async def start_census(message: types.Message):
|
||||||
|
if message.from_user.id != int(BOT_OWNER_ID): # Убедитесь, что BOT_OWNER_ID это строка, конвертируем в int
|
||||||
|
await message.answer("Только владелец бота может запускать перепись!")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Исправленное создание клавиатуры
|
||||||
|
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||||
|
[InlineKeyboardButton(text="Принять участие", callback_data="census_join")]
|
||||||
|
])
|
||||||
|
|
||||||
|
await message.answer("Перепись участников начата! Нажмите кнопку ниже, чтобы участвовать.", reply_markup=keyboard)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@dp.callback_query(lambda c: c.data == "census_join")
|
||||||
|
async def register_user(callback_query: types.CallbackQuery):
|
||||||
|
user = callback_query.from_user
|
||||||
|
chat_id = callback_query.message.chat.id
|
||||||
|
username = user.username or user.full_name
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open("/app/data/users.txt", "r", encoding="utf-8") as file:
|
||||||
|
existing_users = file.readlines()
|
||||||
|
except FileNotFoundError:
|
||||||
|
existing_users = []
|
||||||
|
|
||||||
|
user_entry = f"{user.id}, @{username}\n"
|
||||||
|
if user_entry in existing_users:
|
||||||
|
await callback_query.answer("Вы уже записаны в перепись!")
|
||||||
|
return
|
||||||
|
|
||||||
|
with open("/app/data/users.txt", "a", encoding="utf-8") as file:
|
||||||
|
file.write(user_entry)
|
||||||
|
|
||||||
|
await callback_query.answer("Вы записаны в перепись!")
|
||||||
|
|
||||||
|
# Обработчик команды /sendfile
|
||||||
|
@dp.message(Command(commands=["sendfile"]))
|
||||||
|
async def send_file(message: Message):
|
||||||
|
document = ""
|
||||||
|
# Проверка, является ли отправитель владельцем бота
|
||||||
|
if message.from_user.id != int(BOT_OWNER_ID):
|
||||||
|
await message.answer("Только владелец бота может отправить файл!")
|
||||||
|
return
|
||||||
|
if os.path.exists(FILE_PATH):
|
||||||
|
document = FSInputFile(FILE_PATH)
|
||||||
|
elif os.path.exists(FILE_PATH_WINDOWS):
|
||||||
|
document = FSInputFile(FILE_PATH_WINDOWS)
|
||||||
|
else:
|
||||||
|
await message.answer("Файл не найден на сервере")
|
||||||
|
await bot.send_document(message.chat.id, document, caption="Вот ваш файл!")
|
||||||
|
|
||||||
|
|
||||||
@dp.message()
|
@dp.message()
|
||||||
async def default_message(message: types.Message):
|
async def default_message(message: types.Message):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def main():
|
|
||||||
# Регистрация обработчиков
|
|
||||||
dp.message.register(send_boobs)
|
|
||||||
dp.message.register(send_butts)
|
|
||||||
dp.message.register(send_cats)
|
|
||||||
dp.message.register(send_dogs)
|
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
# Запуск polling
|
# Запуск polling
|
||||||
await dp.start_polling(bot)
|
await dp.start_polling(bot)
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,25 @@
|
|||||||
aiofiles==23.2.1
|
aio-pika==9.5.4
|
||||||
aiogram==3.12.0
|
aiofiles==24.1.0
|
||||||
|
aiogram==3.17.0
|
||||||
aiohappyeyeballs==2.4.0
|
aiohappyeyeballs==2.4.0
|
||||||
aiohttp==3.10.5
|
aiohttp==3.11.11
|
||||||
|
aiormq==6.8.1
|
||||||
aiosignal==1.3.1
|
aiosignal==1.3.1
|
||||||
annotated-types==0.7.0
|
annotated-types==0.7.0
|
||||||
attrs==24.2.0
|
attrs==24.2.0
|
||||||
certifi==2024.8.30
|
certifi==2024.8.30
|
||||||
charset-normalizer==3.3.2
|
charset-normalizer==3.3.2
|
||||||
|
exceptiongroup==1.2.2
|
||||||
frozenlist==1.4.1
|
frozenlist==1.4.1
|
||||||
idna==3.8
|
idna==3.8
|
||||||
magic-filter==1.0.12
|
magic-filter==1.0.12
|
||||||
multidict==6.0.5
|
multidict==6.0.5
|
||||||
pydantic==2.8.2
|
pamqp==3.3.0
|
||||||
pydantic_core==2.20.1
|
propcache==0.2.1
|
||||||
|
pydantic==2.10.6
|
||||||
|
pydantic_core==2.27.2
|
||||||
python-dotenv==1.0.1
|
python-dotenv==1.0.1
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
typing_extensions==4.12.2
|
typing_extensions==4.12.2
|
||||||
urllib3==2.2.2
|
urllib3==2.2.2
|
||||||
yarl==1.9.7
|
yarl==1.18.3
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user