import helper
import logging
from telebot import types
run(message, bot): This is the main function used to implement the budget add/update features. It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object from the main code.py function.
def run(message, bot):
chat_id = message.chat.id
if helper.isOverallBudgetAvailable(chat_id):
update_overall_budget(chat_id, bot)
elif helper.isCategoryBudgetAvailable(chat_id):
update_category_budget(message, bot)
else:
markup = types.ReplyKeyboardMarkup(one_time_keyboard=True)
options = helper.getBudgetTypes()
markup.row_width = 2
for c in options.values():
markup.add(c)
msg = bot.reply_to(message, 'Select Budget Type', reply_markup=markup)
bot.register_next_step_handler(msg, post_type_selection, bot)
post_type_selection(message, bot): It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object. This function takes input from the user, making them choose which type of budget they would like to create - category-wise or overall, and then calls the corresponding functions for further processing.
def post_type_selection(message, bot):
try:
chat_id = message.chat.id
op = message.text
options = helper.getBudgetTypes()
if op not in options.values():
bot.send_message(chat_id, 'Invalid',
reply_markup=types.ReplyKeyboardRemove())
raise Exception(
"Sorry I don't recognise this operation \"{}\"!".format(op))
if op == options['overall']:
update_overall_budget(chat_id, bot)
elif op == options['category']:
update_category_budget(message, bot)
except Exception as e:
helper.throw_exception(e, message, bot, logging)
update_overall_budget(message, bot): It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object. This function is called when the user wants to either create a new overall budget or update an existing one. It checks if there is an existing budget through the helper module’s isOverallBudgetAvailable function and if so, displays this along with the prompt for the new (to be updated) budget, or just asks for the new budget. It passes control to the post_overall_amount_input function in the same file.
def update_overall_budget(chat_id, bot):
if (helper.isOverallBudgetAvailable(chat_id)):
currentBudget = helper.getOverallBudget(chat_id)
msg_string = 'Current Budget is ${}\n\nHow much is your new monthly budget? \n(Enter numeric values only)'
message = bot.send_message(chat_id, msg_string.format(currentBudget))
else:
message = bot.send_message(
chat_id, 'How much is your monthly budget? \n(Enter numeric values only)')
bot.register_next_step_handler(message, post_overall_amount_input, bot)
update_overall_budget(message, bot): It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object. This function is called when the user wants to either create a new overall budget or update an existing one. It checks if there is an existing budget through the helper module’s isOverallBudgetAvailable function and if so, displays this along with the prompt for the new (to be updated) budget, or just asks for the new budget. It passes control to the post_overall_amount_input function in the same file.
def post_overall_amount_input(message, bot):
try:
chat_id = message.chat.id
amount_value = helper.validate_entered_amount(message.text)
if amount_value == 0:
raise Exception("Invalid amount.")
user_list = helper.read_json()
if str(chat_id) not in user_list:
user_list[str(chat_id)] = helper.createNewUserRecord()
user_list[str(chat_id)]['budget']['overall'] = amount_value
helper.write_json(user_list)
bot.send_message(chat_id, 'Budget Updated!')
return user_list
except Exception as e:
helper.throw_exception(e, message, bot, logging)
update_category_budget(message, bot): It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object. This function is called in case the user decides to choose category-wise budgest in the run or post_type_selection stages. It gets the spend categories from the helper module’s getSpendCategories and displays them to the user. It then passes control on to the post_category_selection function.
def update_category_budget(message, bot):
markup = types.ReplyKeyboardMarkup(one_time_keyboard=True)
categories = helper.getSpendCategories()
markup.row_width = 2
for c in categories:
markup.add(c)
msg = bot.reply_to(message, 'Select Category', reply_markup=markup)
bot.register_next_step_handler(msg, post_category_selection, bot)
post_category_selection(message, bot): It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object. Based on the category chosen by the user, the bot checks if these are part of the pre-defined categories in helper.getSpendCategories(), else it throws an exception. If there is a budget already existing for the category, it identifies this case through helper.isCategoryBudgetByCategoryAvailable and shares this information with the user. If not, it simply proceeds. In either case, it then asks for the new/updated budget amount. It passes control onto post_category_amount_input.
def post_category_selection(message, bot):
try:
chat_id = message.chat.id
selected_category = message.text
categories = helper.getSpendCategories()
if selected_category not in categories:
bot.send_message(chat_id, 'Invalid',
reply_markup=types.ReplyKeyboardRemove())
raise Exception(
"Sorry I don't recognise this category \"{}\"!".format(selected_category))
if helper.isCategoryBudgetByCategoryAvailable(chat_id, selected_category):
currentBudget = helper.getCategoryBudgetByCategory(
chat_id, selected_category)
msg_string = 'Current monthly budget for {} is {}\n\nEnter monthly budget for {}\n(Enter numeric values only)'
message = bot.send_message(chat_id, msg_string.format(
selected_category, currentBudget, selected_category))
else:
message = bot.send_message(
chat_id, 'Enter monthly budget for ' + selected_category + '\n(Enter numeric values only)')
bot.register_next_step_handler(
message, post_category_amount_input, bot, selected_category)
except Exception as e:
helper.throw_exception(e, message, bot, logging)
post_category_amount_input(message, bot, category): It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object, and the category chosen by the user.
def post_category_amount_input(message, bot, category):
try:
chat_id = message.chat.id
amount_value = helper.validate_entered_amount(message.text)
if amount_value == 0:
raise Exception("Invalid amount.")
user_list = helper.read_json()
if str(chat_id) not in user_list:
user_list[str(chat_id)] = helper.createNewUserRecord()
if user_list[str(chat_id)]['budget']['category'] is None:
user_list[str(chat_id)]['budget']['category'] = {}
user_list[str(chat_id)]['budget']['category'][category] = amount_value
helper.write_json(user_list)
message = bot.send_message(
chat_id, 'Budget for ' + category + ' Created!')
post_category_add(message, bot)
except Exception as e:
helper.throw_exception(e, message, bot, logging)
post_category_add(message, bot): It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object. This exists in case the user wants to add a category-wise budget to another category after adding it for one category. It prompts the user to choose an option from helper.getUpdateOptions().values() and passes control to post_option_selection to either continue or exit the add/update feature.
def post_category_add(message, bot):
markup = types.ReplyKeyboardMarkup(one_time_keyboard=True)
options = helper.getUpdateOptions().values()
markup.row_width = 2
for c in options:
markup.add(c)
msg = bot.reply_to(message, 'Select Option', reply_markup=markup)
bot.register_next_step_handler(msg, post_option_selection, bot)
post_option_selection(message, bot): It takes 2 arguments for processing - message which is the message from the user, and bot which is the telegram bot object. It takes the category chosen by the user from the message object. If the message is “continue”, then it runs update_category_budget (above) allowing the user to get into the add/update process again. Otherwise, it exits the feature.
def post_option_selection(message, bot):
print("here")
selected_option = message.text
options = helper.getUpdateOptions()
print("here")
if selected_option == options['continue']:
update_category_budget(message, bot)