mirror of
https://github.com/EDeev/y.calendarkin.git
synced 2026-06-15 19:01:00 +03:00
Add docker compose support. Migrate to new version of tools call
This commit is contained in:
parent
a7eeff23c1
commit
f951b4b7f3
11 changed files with 1675 additions and 586 deletions
63
.dockerignore
Normal file
63
.dockerignore
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.dockerignore
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.*
|
||||
env.example
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# Virtual environments
|
||||
venv/
|
||||
env/
|
||||
ENV/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
*.md
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
6
.env
Normal file
6
.env
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Telegram Bot Token
|
||||
# Получите токен у @BotFather в Telegram
|
||||
TELEGRAM_BOT_TOKEN=8263227899:AAESDG7RgctgI0a2oKHgM_2WeriiBcd3OZA
|
||||
|
||||
# Часовой пояс (опционально)
|
||||
TZ=Europe/Moscow
|
||||
33
Dockerfile
Normal file
33
Dockerfile
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Используем официальный Python образ
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Устанавливаем рабочую директорию
|
||||
WORKDIR /app
|
||||
|
||||
# Устанавливаем системные зависимости
|
||||
RUN apt-get update && apt-get install -y \
|
||||
wget \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Копируем файл зависимостей
|
||||
COPY requirements.txt .
|
||||
|
||||
# Устанавливаем Python зависимости
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Копируем код приложения
|
||||
COPY code/ ./code/
|
||||
COPY data/ ./data/
|
||||
|
||||
# Создаем директории для базы данных
|
||||
RUN mkdir -p db
|
||||
|
||||
# Устанавливаем рабочую директорию для запуска
|
||||
WORKDIR /app/code
|
||||
|
||||
# Открываем порт (если потребуется для мониторинга)
|
||||
EXPOSE 8000
|
||||
|
||||
# Команда запуска
|
||||
CMD ["python", "bot.py"]
|
||||
|
||||
54
README.md
54
README.md
|
|
@ -30,13 +30,47 @@ Y.Calendarkin — некоммерческий проект, предназна
|
|||
|
||||
## 🚀 Установка и запуск
|
||||
|
||||
### Предварительные требования
|
||||
### 🐳 Запуск с Docker (Рекомендуется)
|
||||
|
||||
1. **Клонируйте репозиторий:**
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd y.calendarkin
|
||||
```
|
||||
|
||||
2. **Создайте файл с переменными окружения:**
|
||||
```bash
|
||||
cp env.example .env
|
||||
```
|
||||
|
||||
3. **Настройте переменные окружения:**
|
||||
- Откройте файл `.env`
|
||||
- Замените `your_bot_token_here` на токен вашего бота от [@BotFather](https://t.me/BotFather)
|
||||
|
||||
4. **Запустите бота:**
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
5. **Проверьте логи:**
|
||||
```bash
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
6. **Остановите бота:**
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
### 📦 Локальная установка
|
||||
|
||||
#### Предварительные требования
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Настройка
|
||||
#### Настройка
|
||||
|
||||
1. Создайте нового бота через [@BotFather](https://t.me/BotFather)
|
||||
2. Получите токен и добавьте его в `config.py`:
|
||||
|
|
@ -51,7 +85,7 @@ TOKEN = "your_bot_token_here"
|
|||
mkdir -p data/icals db
|
||||
```
|
||||
|
||||
### Запуск
|
||||
#### Запуск
|
||||
|
||||
```bash
|
||||
cd code
|
||||
|
|
@ -100,9 +134,23 @@ y.calendarkin/
|
|||
│ ├── icals/ # Загруженные календари
|
||||
│ └── photo_edit_alarm.jpg
|
||||
├── db/ # База данных SQLite
|
||||
├── Dockerfile # Docker образ
|
||||
├── docker-compose.yml # Docker Compose конфигурация
|
||||
├── .dockerignore # Исключения для Docker
|
||||
├── env.example # Пример переменных окружения
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
### Управление данными
|
||||
|
||||
```bash
|
||||
# Создание резервной копии базы данных
|
||||
docker cp y-calendarkin-bot:/app/db ./backup/
|
||||
|
||||
# Восстановление базы данных
|
||||
docker cp ./backup/db y-calendarkin-bot:/app/
|
||||
```
|
||||
|
||||
## 📊 База данных
|
||||
|
||||
Проект использует две основные таблицы:
|
||||
|
|
|
|||
53
code/bot.py
53
code/bot.py
|
|
@ -1,7 +1,8 @@
|
|||
import logging, config, sql, asyncio, wget, os
|
||||
|
||||
from aiogram import Bot, Dispatcher, executor, types
|
||||
from aiogram.types import ParseMode
|
||||
from aiogram import Bot, Dispatcher, types, F
|
||||
from aiogram.enums import ParseMode
|
||||
from aiogram.filters import Command, or_f
|
||||
|
||||
from datetime import datetime, time
|
||||
from script import text_ical, message_form, dt_now, delta_time
|
||||
|
|
@ -10,7 +11,7 @@ from script import text_ical, message_form, dt_now, delta_time
|
|||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
bot = Bot(token=config.TOKEN)
|
||||
dp = Dispatcher(bot)
|
||||
dp = Dispatcher()
|
||||
|
||||
# инициализируем соединение с БД
|
||||
du = sql.Users('../db/users.db')
|
||||
|
|
@ -18,17 +19,16 @@ dc = sql.Clock('../db/clock.db')
|
|||
|
||||
|
||||
# ПРИВЕТСТВЕННОЕ СООБЩЕНИЕ
|
||||
@dp.message_handler(commands=['start', 'help'])
|
||||
@dp.message(or_f(Command('start'), Command('help')))
|
||||
async def helps(message: types.Message):
|
||||
tg_id = int(message.chat.id)
|
||||
if not du.user_exists(tg_id):
|
||||
du.add_user(tg_id)
|
||||
|
||||
buttons = [types.InlineKeyboardButton(text="КОМАНДЫ", callback_data="com"),
|
||||
types.InlineKeyboardButton(text="АВТОР", callback_data="auth")]
|
||||
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=2)
|
||||
keyboard.add(*buttons)
|
||||
keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
|
||||
[types.InlineKeyboardButton(text="КОМАНДЫ", callback_data="com"),
|
||||
types.InlineKeyboardButton(text="АВТОР", callback_data="auth")]
|
||||
])
|
||||
|
||||
await message.answer(text="<b>Я.Календаркин</b> - бот для оповещения о событиях из <b>Яндекс.Календаря</b>. "
|
||||
"Для начала работы вам нужно всего лишь прислать в чат ссылку экспорта календаря в "
|
||||
|
|
@ -38,7 +38,7 @@ async def helps(message: types.Message):
|
|||
parse_mode=ParseMode.HTML, reply_markup=keyboard)
|
||||
|
||||
|
||||
@dp.callback_query_handler(text="auth")
|
||||
@dp.callback_query(F.data == "auth")
|
||||
async def author(call: types.CallbackQuery):
|
||||
await call.message.answer(text='*| АВТОР |*\n\n*>>* Этот бот не коммерческий проект, для упрощенного получения '
|
||||
'уведомлений о событиях в Яндекс.Календаре. Не многим этот бот будет полезен, но '
|
||||
|
|
@ -48,7 +48,7 @@ async def author(call: types.CallbackQuery):
|
|||
parse_mode=ParseMode.MARKDOWN)
|
||||
|
||||
|
||||
@dp.callback_query_handler(text="com")
|
||||
@dp.callback_query(F.data == "com")
|
||||
async def commands(call: types.CallbackQuery):
|
||||
await call.message.answer(text='<b>| КОМАНДЫ |</b>\n\n'
|
||||
'<b>/help</b> - вспомогательная функция для уточнения работы команд\n'
|
||||
|
|
@ -59,11 +59,11 @@ async def commands(call: types.CallbackQuery):
|
|||
'<b>/get_alarm</b> - информация о времени на которое настроены оповещения\n'
|
||||
'<b>/edit_alarm</b> - изменение времени оповещений\n'
|
||||
'<b>/stop_alarm</b> - команда, отключающая второе оповещение о событии',
|
||||
parse_mode=types.ParseMode.HTML)
|
||||
parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
# КОМАНДЫ
|
||||
@dp.message_handler(commands=['list'])
|
||||
@dp.message(Command('list'))
|
||||
async def check_list(message: types.Message):
|
||||
user_id = du.get_user_id(int(message.chat.id))
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ async def check_list(message: types.Message):
|
|||
await message.answer("Для отображения событий вы должны прислать ical-ссылку на календарь!")
|
||||
|
||||
|
||||
@dp.message_handler(commands=['notif'])
|
||||
@dp.message(Command('notif'))
|
||||
async def notif_up(message: types.Message):
|
||||
user_id = du.get_user_id(int(message.chat.id))
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ async def notif_up(message: types.Message):
|
|||
await message.answer("Для взаимодействия с событиями вы должны прислать ical-ссылку на календарь!")
|
||||
|
||||
|
||||
@dp.message_handler(commands=['daily'])
|
||||
@dp.message(Command('daily'))
|
||||
async def daily_up(message: types.Message):
|
||||
user_id = du.get_user_id(int(message.chat.id))
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ async def daily_up(message: types.Message):
|
|||
await message.answer("Для взаимодействия с событиями вы должны прислать ical-ссылку на календарь!")
|
||||
|
||||
|
||||
@dp.message_handler(commands=['moment'])
|
||||
@dp.message(Command('moment'))
|
||||
async def start_up(message: types.Message):
|
||||
user_id = du.get_user_id(int(message.chat.id))
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ async def start_up(message: types.Message):
|
|||
await message.answer("Для взаимодействия с событиями вы должны прислать ical-ссылку на календарь!")
|
||||
|
||||
|
||||
@dp.message_handler(commands=['get_alarm'])
|
||||
@dp.message(Command('get_alarm'))
|
||||
async def start_up(message: types.Message):
|
||||
user_id = du.get_user_id(int(message.chat.id))
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ async def start_up(message: types.Message):
|
|||
await message.answer("Для того, чтобы получить таймеры, вы должны прислать ical-ссылку на свой календарь!")
|
||||
|
||||
|
||||
@dp.message_handler(commands=['edit_alarm'])
|
||||
@dp.message(Command('edit_alarm'))
|
||||
async def start_up(message: types.Message):
|
||||
user_id = du.get_user_id(int(message.chat.id))
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ async def start_up(message: types.Message):
|
|||
await message.answer("Для того, чтобы изменить таймеры, вы должны прислать ical-ссылку на свой календарь!")
|
||||
|
||||
|
||||
@dp.message_handler(commands=['stop_alarm'])
|
||||
@dp.message(Command('stop_alarm'))
|
||||
async def daily_up(message: types.Message):
|
||||
user_id = du.get_user_id(int(message.chat.id))
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ async def daily_up(message: types.Message):
|
|||
|
||||
|
||||
# ЗАГРУЗКА ССЫЛКИ
|
||||
@dp.message_handler(content_types=['text'])
|
||||
@dp.message(F.text)
|
||||
async def downloading_file_ics(message: types.Message):
|
||||
user_id = du.get_user_id(int(message.chat.id))
|
||||
|
||||
|
|
@ -314,8 +314,13 @@ async def update(wait_for):
|
|||
os.rename(f'../data/icals/{str(user_id)}_new.ics', f'../data/icals/{str(user_id)}.ics')
|
||||
|
||||
|
||||
async def main():
|
||||
# Создаем задачи для фоновых процессов
|
||||
asyncio.create_task(alarm(60)) # ПРОВЕРКА КАЖДУЮ 1 МИНУТУ
|
||||
asyncio.create_task(update(780)) # ПРОВЕРКА КАЖДУЮ 13 МИНУТУ
|
||||
|
||||
# Запускаем бота
|
||||
await dp.start_polling(bot, skip_updates=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(alarm(60)) # ПРОВЕРКА КАЖДУЮ 1 МИНУТУ
|
||||
loop.create_task(update(780)) # ПРОВЕРКА КАЖДУЮ 13 МИНУТУ
|
||||
executor.start_polling(dp, skip_updates=True)
|
||||
asyncio.run(main())
|
||||
|
|
|
|||
|
|
@ -1 +1,7 @@
|
|||
TOKEN = "**********:***************************"
|
||||
import os
|
||||
|
||||
# Получаем токен из переменной окружения
|
||||
TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
|
||||
|
||||
if not TOKEN:
|
||||
raise ValueError("TELEGRAM_BOT_TOKEN environment variable is required")
|
||||
|
|
|
|||
1406
data/icals/1.ics
1406
data/icals/1.ics
File diff suppressed because it is too large
Load diff
BIN
db/clock.db
BIN
db/clock.db
Binary file not shown.
BIN
db/users.db
BIN
db/users.db
Binary file not shown.
37
docker-compose.yml
Normal file
37
docker-compose.yml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
services:
|
||||
calendarkin-bot:
|
||||
build: .
|
||||
container_name: y-calendarkin-bot
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
# Токен Telegram бота (обязательно)
|
||||
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
|
||||
|
||||
# Дополнительные переменные окружения (опционально)
|
||||
- TZ=Europe/Moscow
|
||||
|
||||
volumes:
|
||||
# Монтируем директорию с базами данных для сохранения данных
|
||||
- ./db:/app/db
|
||||
# Монтируем директорию с календарями
|
||||
- ./data:/app/data
|
||||
|
||||
# Логирование
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
# Ограничения ресурсов
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 256M
|
||||
|
||||
# Создаем именованные тома для данных (опционально)
|
||||
volumes:
|
||||
db_data:
|
||||
ical_data:
|
||||
7
env.example
Normal file
7
env.example
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Telegram Bot Token
|
||||
# Получите токен у @BotFather в Telegram
|
||||
TELEGRAM_BOT_TOKEN=your_bot_token_here
|
||||
|
||||
# Часовой пояс (опционально)
|
||||
TZ=Europe/Moscow
|
||||
|
||||
Loading…
Add table
Reference in a new issue