pip install aiogram-datepicker --upgrade
import logging
import os
from datetime import datetime
from aiogram import Bot, Dispatcher
from aiogram.types import Message, CallbackQuery
from aiogram.utils import executor
from aiogram_datepicker import Datepicker, DatepickerSettings
logging.basicConfig(level=logging.INFO)
bot = Bot(token=os.environ['API_TOKEN'])
dp = Dispatcher(bot, run_tasks_by_default=True)
def _get_datepicker_settings():
return DatepickerSettings() #some settings
@dp.message_handler(state='*')
async def _main(message: Message):
datepicker = Datepicker(_get_datepicker_settings())
markup = datepicker.start_calendar()
await message.answer('Select a date: ', reply_markup=markup)
@dp.callback_query_handler(Datepicker.datepicker_callback.filter())
async def _process_datepicker(callback_query: CallbackQuery, callback_data: dict):
datepicker = Datepicker(_get_datepicker_settings())
date = await datepicker.process(callback_query, callback_data)
if date:
await callback_query.message.answer(date.strftime('%d/%m/%Y'))
await callback_query.answer()
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
DatepickerSettings(
initial_view='day', #available views -> day, month, year
initial_date=datetime.now().date(), #default date
views={
'day': {
'show_weekdays': True,
'weekdays_labels': ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
'header': ['prev-year', 'days-title', 'next-year'],
'footer': ['prev-month', 'select', 'next-month'], #if you don't need select action, you can remove it and the date will return automatically without waiting for the button select
#available actions -> prev-year, days-title, next-year, prev-month, select, next-month, ignore
},
'month': {
'months_labels': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
'header': [
'prev-year',
['year', 'select'], #you can separate buttons into groups
'next-year'
],
'footer': ['select'],
#available actions -> prev-year, year, next-year, select, ignore
},
'year': {
'header': [],
'footer': ['prev-years', 'next-years'],
#available actions -> prev-years, ignore, next-years
}
},
labels={
'prev-year': '<<',
'next-year': '>>',
'prev-years': '<<',
'next-years': '>>',
'days-title': '{month} {year}',
'selected-day': '{day} *',
'selected-month': '{month} *',
'present-day': '• {day} •',
'prev-month': '<',
'select': 'Select',
'next-month': '>',
'ignore': ''
},
custom_actions=[] #some custom actions
)
from aiogram_datepicker import Datepicker, DatepickerSettings, DatepickerCustomAction
class TodayAction(DatepickerCustomAction):
action: str = 'today'
label: str = 'Today'
def get_action(self, view: str, year: int, month: int, day: int) -> InlineKeyboardButton:
"""
Required function
"""
return InlineKeyboardButton(self.label,
callback_data=self._get_callback(view, self.action, year, month, day))
async def process(self, query: CallbackQuery, view: str, _date: date) -> bool:
"""
Required function
"""
if view == 'day':
await self.set_view(query, 'day', datetime.now().date())
return False
elif view == 'month':
await self.set_view(query, 'month', date(_date.year, datetime.now().date().month, _date.day))
return False
elif view == 'year':
await self.set_view(query, 'month', date(datetime.now().date().year, _date.month, _date.day))
return False
settings = DatepickerSettings(
views={
'day': {
'footer': ['prev-month', 'today', 'next-month', ['cancel']],
},
'month': {
'footer': ['today']
},
'year': {
'header': ['today'],
}
},
custom_actions=[TodayAction]
)