-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtelegramcalendar.py
125 lines (111 loc) · 5.2 KB
/
telegramcalendar.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
#!/usr/bin/env python3
#
# A library that allows to create an inline calendar keyboard.
# grcanosa https://github.com/grcanosa
#
"""
Base methods for calendar keyboard creation and processing.
"""
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
import datetime
import calendar
import json
def create_callback_data(action, year, month, day):
""" Create the callback data associated to each button"""
return ";".join([action, str(year), str(month), str(day)])
def separate_callback_data(data):
""" Separate the callback data"""
return data.split(";")
def create_calendar(year=None, month=None, callback_info=None):
"""
Create an inline keyboard with the provided year and month
:param str callback_info: additional callback_info
:param int year: Year to use in the calendar, if None the current year is used.
:param int month: Month to use in the calendar, if None the current month is used.
:return: Returns the InlineKeyboardMarkup object with the calendar.
"""
now = datetime.datetime.now()
year = now.year if year is None else year
month = now.month if month is None else month
data_ignore = create_callback_data("IGNORE", year, month, 0)
keyboard = []
# First row - Month and Year
row = []
row.append(InlineKeyboardButton(calendar.month_name[month] + " " + str(year), callback_data=data_ignore))
keyboard.append(row)
# Second row - Week Days
row = []
for day in ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]:
row.append(InlineKeyboardButton(day, callback_data=data_ignore))
keyboard.append(row)
my_calendar = calendar.monthcalendar(year, month)
for week in my_calendar:
row = []
for day in week:
if day == 0:
row.append(InlineKeyboardButton(" ", callback_data=data_ignore))
else:
row.append(InlineKeyboardButton(str(day), callback_data=create_callback_data(callback_info + "-DAY", year, month, day)))
keyboard.append(row)
# Last row - Buttons
row = []
row.append(InlineKeyboardButton("<", callback_data=create_callback_data(callback_info + "-PREV-MONTH", year, month, day)))
row.append(InlineKeyboardButton(" ", callback_data=data_ignore))
row.append(InlineKeyboardButton(">", callback_data=create_callback_data(callback_info + "-NEXT-MONTH", year, month, day)))
keyboard.append(row)
return json.dumps(InlineKeyboardMarkup(keyboard).to_dict())
def create_month(year=None, month=None):
now = datetime.datetime.now()
year = now.year if year is None else year
month = now.month if month is None else month
data_ignore = create_callback_data("IGNORE", year, month, 0)
keyboard = []
my_calendar = calendar.monthcalendar(year, month)
for week in my_calendar:
row = []
for day in week:
if day == 0:
row.append(InlineKeyboardButton(" ", callback_data=data_ignore))
else:
row.append(InlineKeyboardButton(str(day), callback_data="DATE;" + str(day) + ';0'))
keyboard.append(row)
keyboard.append([InlineKeyboardButton('Подтвердить', callback_data="DATE;A;0")])
keyboard.append([InlineKeyboardButton('Назад', callback_data="DATE;B;0")])
return InlineKeyboardMarkup(keyboard).to_dict()
def process_calendar_selection(bot, update):
"""
Process the callback_query. This method generates a new calendar if forward or
backward is pressed. This method should be called inside a CallbackQueryHandler.
:param telegram.Bot bot: The bot, as provided by the CallbackQueryHandler
:param telegram.Update update: The update, as provided by the CallbackQueryHandler
:return: Returns a tuple (Boolean,datetime.datetime), indicating if a date is selected
and returning the date if so.
"""
ret_data = (False, None)
query = update.callback_query
(action, year, month, day) = separate_callback_data(query.data)
curr = datetime.datetime(int(year), int(month), 1)
if action == "IGNORE":
bot.answer_callback_query(callback_query_id=query.id)
elif action == "DAY":
bot.edit_message_text(text=query.message.text,
chat_id=query.message.chat_id,
message_id=query.message.message_id
)
ret_data = True, datetime.datetime(int(year), int(month), int(day))
elif action == "PREV-MONTH":
pre = curr - datetime.timedelta(days=1)
bot.edit_message_text(text=query.message.text,
chat_id=query.message.chat_id,
message_id=query.message.message_id,
reply_markup=create_calendar(int(pre.year), int(pre.month)))
elif action == "NEXT-MONTH":
ne = curr + datetime.timedelta(days=31)
bot.edit_message_text(text=query.message.text,
chat_id=query.message.chat_id,
message_id=query.message.message_id,
reply_markup=create_calendar(int(ne.year), int(ne.month)))
else:
bot.answer_callback_query(callback_query_id=query.id, text="Something went wrong!")
# UNKNOWN
return ret_data