-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbot.py
236 lines (192 loc) · 10.7 KB
/
bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
import asyncio
from cgitb import text
from ctypes import resize
from email import message
from itertools import count
from lib2to3.pgen2 import token
import logging
from pydoc import describe
from re import sub
from unicodedata import name
from aiogram import Bot, Dispatcher, executor, types
from aiohttp import request
import DataBase
from EduBot_States import CreateandAdd_states
from aiogram.dispatcher import FSMContext
from aiogram.contrib.fsm_storage.mongo import MongoStorage
import schedule
import calendar,datetime
import aioschedule
import os
from aiogram.utils.callback_data import CallbackData
TelegramBot_token = os.environ.get("TELEGRAMBOT_TOKEN")
MongoDB_token = os.environ.get('MONGODB_URI')
# Объект бота
bot = Bot(token=TelegramBot_token)
#Подключение БД
storage = MongoStorage(uri=MongoDB_token)
# Диспетчер для бота
dp = Dispatcher(bot,storage=storage)
# Включаем логирование, чтобы не пропустить важные сообщения
logging.basicConfig(level=logging.INFO)
#фабрика CallBack'ов
CallbackData_my_notification= CallbackData("my_notification", "InlineButtonNumber")
#функция для создане кнопки
def new_sub_button():
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True,one_time_keyboard=True)
button1 =types.KeyboardButton("Создать новое напоминание")
button2 =types.KeyboardButton("Мои напоминания")
keyboard.add(button1,button2)
return keyboard
#конвертация дней недели с англ на рус
def weekday_eng_to_rus(weekday):
week = {
"Monday":0,
"Tuesday":1,
"Wednesday":2,
"Thursday":3 ,
"Friday":4,
"Saturday":5,
"Sunday":6
}
week_ru=["Понедельник","Вторник","Среда","Четверг","Пятница","Суббота","Воскресенье"]
return week_ru[week.get(weekday)]
#создане кнопок дней недели
def new_weekday_buttons():
keyboard = types.InlineKeyboardMarkup()
button1 = types.InlineKeyboardButton(text="Понедельник",callback_data="Monday")
button2 = types.InlineKeyboardButton(text="Вторник",callback_data="Tuesday")
button3 = types.InlineKeyboardButton(text="Среда",callback_data="Wednesday")
button4 = types.InlineKeyboardButton(text="Четверг",callback_data="Thursday")
button5 = types.InlineKeyboardButton(text="Пятница",callback_data="Friday")
button6 = types.InlineKeyboardButton(text="Суббота",callback_data="Saturday")
button7 = types.InlineKeyboardButton(text="Воскресенье",callback_data="Sunday")
keyboard.add(button1,button2,button3,button4,button5,button6,button7)
return keyboard
# Хэндлер на команду /help /start
@dp.message_handler(commands=["help","start"])
async def helper(message: types.Message):
print(1)
DataBase.set(message.chat.id,message.chat)
keyboard = new_sub_button()
await message.answer("Привет!!\nЯ умею создавть текстовые заметки с напоминнием \nЧтобы создать новое напоминание необходимо:\n 1)Создать новое занятие \n 2)Записать что необходимо сделать ",reply_markup=keyboard)
@dp.message_handler(state = CreateandAdd_states.waiting_sub_for_note)
async def waiting_sub_for_note(message : types.Message,state:FSMContext):
print(3)
await message.answer("Введите что надо сделать")
await CreateandAdd_states.waiting_note.set()
await state.set_data({"subject":message.text})
@dp.message_handler(state = CreateandAdd_states.waiting_note)
async def waiting_note_name(message : types.Message,state:FSMContext):
print(4)
await state.update_data({"Description":message.text})
await state.update_data(count = 0)#счетчик введенных дней недели
keyboard = new_weekday_buttons()
await message.answer("Когда напомнить?",reply_markup=keyboard)
await time_request(message)
await CreateandAdd_states.waiting_time.set()
async def time_request(message):
keybord = types.ReplyKeyboardMarkup(resize_keyboard=True,one_time_keyboard=True)
keybord.add(types.KeyboardButton("17:00"),types.KeyboardButton("08:00"),types.KeyboardButton("12:00"))
await message.answer("Во сколько? Выберите из предложенных вариантов или введите свой в формате ЧЧ:ММ",reply_markup=keybord)
@dp.callback_query_handler(text = ["Monday","Tuesday","Wednesday", "Thursday" ,"Friday", "Saturday","Sunday"],state= CreateandAdd_states.waiting_time)
async def weekday_handler(call: types.CallbackQuery,state:FSMContext):
count = await state.get_data()#счетчик введенных дней недели
count=count.get("count")
count = int(count)
await state.update_data({f"weekday{count}": call.data})
count+=1
await state.update_data({"count":count})
await call.message.answer("Добавлен новый день напоминания: "+weekday_eng_to_rus(call.data))
@dp.callback_query_handler(CallbackData_my_notification.filter())
async def callbacks(call: types.CallbackQuery, callback_data: dict,state:FSMContext):
my_notification = await state.get_data()
my_notification = my_notification.get(callback_data.get("InlineButtonNumber"))
DataBase.delete_notification(my_notification)
await call.message.answer("Напоминание удалено")
@dp.message_handler(state = CreateandAdd_states.waiting_time)
async def waiting_time(message : types.Message,state:FSMContext):
print(6)
user_data = await state.get_data()
user_data = user_data.get("count")
if user_data == 0:
await message.answer("Введите день недели.")
keyboard = new_weekday_buttons()
await message.answer("Когда напомнить?",reply_markup=keyboard)
await time_request(message)
else:
try:
datetime.datetime.strptime(message.text, '%H:%M')
except:
await message.answer("Некоректно введено время.Пример: 05:24(ЧЧ:ММ)")
await CreateandAdd_states.waiting_time.set()
return
for i in range(0,user_data):
user_data = await state.get_data()
DataBase.set_note(message.chat.id,user_data.get("subject"),user_data.get("Description"),user_data.get(f"weekday{i}"),message.text)
keybord = new_sub_button()
await message.answer("Заметка успешно создана!",reply_markup= keybord)
#await state.reset_state()
#await dp.storage.wait_closed()
await state.finish()
@dp.message_handler()
async def new_sub(message:types.Message, state:FSMContext):
DataBase.set(message.chat.id,message.chat)
if message.text == "Создать новое напоминание":
print(2)
await state.reset_data()
await message.answer("Введите название занятия")
await CreateandAdd_states.waiting_sub_for_note.set()
elif message.text == "Мои напоминания":
my_notification = DataBase.get_many({"chat_id":message.from_user.id})
a = len([x for x in my_notification])
print(a)
if a == 0:
keyboard = new_sub_button()
await message.answer("У вас еще нет напоминаний",reply_markup=keyboard)
else:
for i,my_notification in enumerate(DataBase.get_many({"chat_id":message.from_user.id}),1): #для просмотра имеющихся напоминаний
keyboard = types.InlineKeyboardMarkup()
#button = types.InlineKeyboardButton(text="Удалить",callback_data=CallbackData_my_notification.new( my_notification.get("chat_id"),my_notification.get("subject"), my_notification.get("Description"),my_notification.get("weekday"),my_notification.get("time").replace(':'," ") ))
button = types.InlineKeyboardButton(text="Удалить",callback_data=CallbackData_my_notification.new(f"InlineButton{i}"))
keyboard.add(button)
await state.update_data({f"InlineButton{i}":{"chat_id":my_notification.get("chat_id"),
"subject":my_notification.get("subject"),
"Description":my_notification.get("Description"),
"weekday":my_notification.get("weekday"),
"time":my_notification.get("time")}})
if my_notification.get("weekday") == "Tuesday":
await message.answer("Занятие:\n "+my_notification.get("subject")+"\nЧто необходимо сделать:\n "+my_notification.get("Description")+" во "+weekday_eng_to_rus(my_notification.get("weekday"))+" в "+my_notification.get("time"),reply_markup=keyboard)
else:
await message.answer("Занятие:\n "+my_notification.get("subject")+"\nЧто необходимо сделать:\n "+my_notification.get("Description")+" в "+weekday_eng_to_rus(my_notification.get("weekday"))+" в "+my_notification.get("time"),reply_markup=keyboard)
else:
await message.answer("Сообщенеи не распознано!")
await helper(message)
#########################################################
#проверка напоминаний
async def Notification_checker():
offset = datetime.timedelta(hours=3)
tz = datetime.timezone(offset,"МСК")
now = datetime.datetime.now(tz=tz)
print(now.time())
data = DataBase.get({"weekday":calendar.day_name[now.weekday()],"time":now.time().isoformat(timespec="minutes")})
if data == None:
print("Джонни,у нас проблемы")
else:
print("Notific sended")
msg = data.get("subject")+"\n"+data.get("Description")
await bot.send_message(data.get("chat_id"),msg)
if data.get("chat_id") != 639454374:
DataBase.delete_notification(data)
#Отправление напоминаний
async def scheduler():
aioschedule.every().second.do(Notification_checker)
while True:
await aioschedule.run_pending()
await asyncio.sleep(1)
async def on_startup(_):
asyncio.create_task(scheduler())
##########################################################
if __name__ == "__main__":
# Запуск бота
executor.start_polling(dp, skip_updates=True,on_startup=on_startup)