mirror of
https://github.com/Steffo99/greed.git
synced 2024-11-22 05:54:18 +00:00
Add cancel button
This commit is contained in:
parent
af1757050b
commit
9017680044
3 changed files with 118 additions and 51 deletions
21
core.py
21
core.py
|
@ -75,7 +75,7 @@ def main():
|
||||||
# Skip the update
|
# Skip the update
|
||||||
continue
|
continue
|
||||||
# If the message is a start command...
|
# If the message is a start command...
|
||||||
if update.message.text is not None and update.message.text == "/start":
|
if isinstance(update.message.text, str) and update.message.text == "/start":
|
||||||
# Check if a worker already exists for that chat
|
# Check if a worker already exists for that chat
|
||||||
old_worker = chat_workers.get(update.message.chat.id)
|
old_worker = chat_workers.get(update.message.chat.id)
|
||||||
# If it exists, gracefully stop the worker
|
# If it exists, gracefully stop the worker
|
||||||
|
@ -100,19 +100,26 @@ def main():
|
||||||
# Forward the update to the worker
|
# Forward the update to the worker
|
||||||
receiving_worker.queue.put(update)
|
receiving_worker.queue.put(update)
|
||||||
# If the update is a inline keyboard press...
|
# If the update is a inline keyboard press...
|
||||||
if update.callback_query is not None:
|
if isinstance(update.callback_query, telegram.CallbackQuery):
|
||||||
# Forward the update to the corresponding worker
|
# Forward the update to the corresponding worker
|
||||||
receiving_worker = chat_workers.get(update.callback_query.chat.id)
|
receiving_worker = chat_workers.get(update.callback_query.from_user.id)
|
||||||
# Ensure a worker exists for the chat
|
# Ensure a worker exists for the chat
|
||||||
if receiving_worker is None:
|
if receiving_worker is None:
|
||||||
# Suggest that the user restarts the chat with /start
|
# Suggest that the user restarts the chat with /start
|
||||||
bot.send_message(update.callback_query.chat.id, strings.error_no_worker_for_chat)
|
bot.send_message(update.callback_query.from_user.id, strings.error_no_worker_for_chat)
|
||||||
# Skip the update
|
# Skip the update
|
||||||
continue
|
continue
|
||||||
# Forward the update to the worker
|
# Check if the pressed inline key is a cancel button
|
||||||
receiving_worker.queue.put(update)
|
if update.callback_query.data == "cmd_cancel":
|
||||||
|
# Forward a CancelSignal to the worker
|
||||||
|
receiving_worker.queue.put(worker.CancelSignal())
|
||||||
|
# Notify the Telegram client that the inline keyboard press has been received
|
||||||
|
bot.answer_callback_query(update.callback_query.id)
|
||||||
|
else:
|
||||||
|
# Forward the update to the worker
|
||||||
|
receiving_worker.queue.put(update)
|
||||||
# If the update is a precheckoutquery, ensure it hasn't expired before forwarding it
|
# If the update is a precheckoutquery, ensure it hasn't expired before forwarding it
|
||||||
if update.pre_checkout_query is not None:
|
if isinstance(update.pre_checkout_query, telegram.PreCheckoutQuery):
|
||||||
# Forward the update to the corresponding worker
|
# Forward the update to the corresponding worker
|
||||||
receiving_worker = chat_workers.get(update.pre_checkout_query.from_user.id)
|
receiving_worker = chat_workers.get(update.pre_checkout_query.from_user.id)
|
||||||
# Check if it's the active invoice for this chat
|
# Check if it's the active invoice for this chat
|
||||||
|
|
|
@ -78,9 +78,15 @@ menu_add_product = "✨ Nuovo prodotto"
|
||||||
# Menu: cancel
|
# Menu: cancel
|
||||||
menu_cancel = "🔙 Annulla"
|
menu_cancel = "🔙 Annulla"
|
||||||
|
|
||||||
|
# Menu: skip
|
||||||
|
menu_skip = "⏭ Salta"
|
||||||
|
|
||||||
# Menu: done
|
# Menu: done
|
||||||
menu_done = "✅️ Fatto"
|
menu_done = "✅️ Fatto"
|
||||||
|
|
||||||
|
# Menu: pay invoice
|
||||||
|
menu_pay = "💳 Paga"
|
||||||
|
|
||||||
# Add product: name?
|
# Add product: name?
|
||||||
ask_product_name = "Come si deve chiamare il prodotto?"
|
ask_product_name = "Come si deve chiamare il prodotto?"
|
||||||
|
|
||||||
|
|
142
worker.py
142
worker.py
|
@ -17,6 +17,11 @@ class StopSignal:
|
||||||
self.reason = reason
|
self.reason = reason
|
||||||
|
|
||||||
|
|
||||||
|
class CancelSignal:
|
||||||
|
"""An empty class that is added to the queue whenever the user presses a cancel inline button."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ChatWorker(threading.Thread):
|
class ChatWorker(threading.Thread):
|
||||||
"""A worker for a single conversation. A new one is created every time the /start command is sent."""
|
"""A worker for a single conversation. A new one is created every time the /start command is sent."""
|
||||||
|
|
||||||
|
@ -83,11 +88,15 @@ class ChatWorker(threading.Thread):
|
||||||
# Return the received update
|
# Return the received update
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def __wait_for_specific_message(self, items:typing.List[str]) -> str:
|
def __wait_for_specific_message(self, items:typing.List[str], cancellable:bool=False) -> typing.Union[str, CancelSignal]:
|
||||||
"""Continue getting updates until until one of the strings contained in the list is received as a message."""
|
"""Continue getting updates until until one of the strings contained in the list is received as a message."""
|
||||||
while True:
|
while True:
|
||||||
# Get the next update
|
# Get the next update
|
||||||
update = self.__receive_next_update()
|
update = self.__receive_next_update()
|
||||||
|
# Ensure the update isn't a CancelSignal
|
||||||
|
if cancellable and isinstance(update, CancelSignal):
|
||||||
|
# Return the CancelSignal
|
||||||
|
return update
|
||||||
# Ensure the update contains a message
|
# Ensure the update contains a message
|
||||||
if update.message is None:
|
if update.message is None:
|
||||||
continue
|
continue
|
||||||
|
@ -100,11 +109,15 @@ class ChatWorker(threading.Thread):
|
||||||
# Return the message text
|
# Return the message text
|
||||||
return update.message.text
|
return update.message.text
|
||||||
|
|
||||||
def __wait_for_regex(self, regex:str) -> str:
|
def __wait_for_regex(self, regex:str, cancellable:bool=False) -> typing.Union[str, CancelSignal]:
|
||||||
"""Continue getting updates until the regex finds a match in a message, then return the first capture group."""
|
"""Continue getting updates until the regex finds a match in a message, then return the first capture group."""
|
||||||
while True:
|
while True:
|
||||||
# Get the next update
|
# Get the next update
|
||||||
update = self.__receive_next_update()
|
update = self.__receive_next_update()
|
||||||
|
# Ensure the update isn't a CancelSignal
|
||||||
|
if cancellable and isinstance(update, CancelSignal):
|
||||||
|
# Return the CancelSignal
|
||||||
|
return update
|
||||||
# Ensure the update contains a message
|
# Ensure the update contains a message
|
||||||
if update.message is None:
|
if update.message is None:
|
||||||
continue
|
continue
|
||||||
|
@ -119,12 +132,16 @@ class ChatWorker(threading.Thread):
|
||||||
# Return the first capture group
|
# Return the first capture group
|
||||||
return match.group(1)
|
return match.group(1)
|
||||||
|
|
||||||
def __wait_for_precheckoutquery(self) -> telegram.PreCheckoutQuery:
|
def __wait_for_precheckoutquery(self, cancellable:bool=False) -> typing.Union[telegram.PreCheckoutQuery, CancelSignal]:
|
||||||
"""Continue getting updates until a precheckoutquery is received.
|
"""Continue getting updates until a precheckoutquery is received.
|
||||||
The payload is checked by the core before forwarding the message."""
|
The payload is checked by the core before forwarding the message."""
|
||||||
while True:
|
while True:
|
||||||
# Get the next update
|
# Get the next update
|
||||||
update = self.__receive_next_update()
|
update = self.__receive_next_update()
|
||||||
|
# Ensure the update isn't a CancelSignal
|
||||||
|
if cancellable and isinstance(update, CancelSignal):
|
||||||
|
# Return the CancelSignal
|
||||||
|
return update
|
||||||
# Ensure the update contains a precheckoutquery
|
# Ensure the update contains a precheckoutquery
|
||||||
if update.pre_checkout_query is None:
|
if update.pre_checkout_query is None:
|
||||||
continue
|
continue
|
||||||
|
@ -145,11 +162,15 @@ class ChatWorker(threading.Thread):
|
||||||
# Return the successfulpayment
|
# Return the successfulpayment
|
||||||
return update.message.successful_payment
|
return update.message.successful_payment
|
||||||
|
|
||||||
def __wait_for_photo(self) -> typing.List[telegram.PhotoSize]:
|
def __wait_for_photo(self, cancellable:bool=False) -> typing.Union[typing.List[telegram.PhotoSize], CancelSignal]:
|
||||||
"""Continue getting updates until a photo is received, then download and return it."""
|
"""Continue getting updates until a photo is received, then download and return it."""
|
||||||
while True:
|
while True:
|
||||||
# Get the next update
|
# Get the next update
|
||||||
update = self.__receive_next_update()
|
update = self.__receive_next_update()
|
||||||
|
# Ensure the update isn't a CancelSignal
|
||||||
|
if cancellable and isinstance(update, CancelSignal):
|
||||||
|
# Return the CancelSignal
|
||||||
|
return update
|
||||||
# Ensure the update contains a message
|
# Ensure the update contains a message
|
||||||
if update.message is None:
|
if update.message is None:
|
||||||
continue
|
continue
|
||||||
|
@ -294,7 +315,7 @@ class ChatWorker(threading.Thread):
|
||||||
# Go to the pay with credit card function
|
# Go to the pay with credit card function
|
||||||
self.__add_credit_cc()
|
self.__add_credit_cc()
|
||||||
# If the user has selected the Cancel option...
|
# If the user has selected the Cancel option...
|
||||||
elif selection == strings.menu_add_credit:
|
elif selection == strings.menu_cancel:
|
||||||
# Send him back to the previous menu
|
# Send him back to the previous menu
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -308,40 +329,57 @@ class ChatWorker(threading.Thread):
|
||||||
keyboard = [[telegram.KeyboardButton(strings.currency_format_string.format(symbol=strings.currency_symbol, value="10"))],
|
keyboard = [[telegram.KeyboardButton(strings.currency_format_string.format(symbol=strings.currency_symbol, value="10"))],
|
||||||
[telegram.KeyboardButton(strings.currency_format_string.format(symbol=strings.currency_symbol, value="25"))],
|
[telegram.KeyboardButton(strings.currency_format_string.format(symbol=strings.currency_symbol, value="25"))],
|
||||||
[telegram.KeyboardButton(strings.currency_format_string.format(symbol=strings.currency_symbol, value="50"))],
|
[telegram.KeyboardButton(strings.currency_format_string.format(symbol=strings.currency_symbol, value="50"))],
|
||||||
[telegram.KeyboardButton(strings.currency_format_string.format(symbol=strings.currency_symbol, value="100"))]]
|
[telegram.KeyboardButton(strings.currency_format_string.format(symbol=strings.currency_symbol, value="100"))],
|
||||||
|
[telegram.KeyboardButton(strings.menu_cancel)]]
|
||||||
|
# Boolean variable to check if the user has cancelled the action
|
||||||
|
cancelled = False
|
||||||
# Loop used to continue asking if there's an error during the input
|
# Loop used to continue asking if there's an error during the input
|
||||||
while True:
|
while not cancelled:
|
||||||
# Send the message and the keyboard
|
# Send the message and the keyboard
|
||||||
self.bot.send_message(self.chat.id, strings.payment_cc_amount,
|
self.bot.send_message(self.chat.id, strings.payment_cc_amount,
|
||||||
reply_markup=telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=True))
|
reply_markup=telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=True))
|
||||||
# Wait until a valid amount is sent
|
# Wait until a valid amount is sent
|
||||||
# TODO: check and debug the regex
|
# TODO: check and debug the regex
|
||||||
selection = int(self.__wait_for_regex(r"([0-9]{1,3}(?:[.,][0-9]{1,2})?)").replace(".", "").replace(",", "")) * (10 ** int(configloader.config["Payments"]["currency_exp"]))
|
selection = self.__wait_for_regex(r"([0-9]{1,3}(?:[.,][0-9]{1,2})?|" + strings.menu_cancel + r")")
|
||||||
|
# If the user cancelled the action
|
||||||
|
if selection == strings.menu_cancel:
|
||||||
|
# Exit the loop
|
||||||
|
cancelled = True
|
||||||
|
continue
|
||||||
|
# Convert the amount to an integer
|
||||||
|
value = int(selection.replace(".", "").replace(",", "")) * (10 ** int(configloader.config["Payments"]["currency_exp"]))
|
||||||
# Ensure the amount is within the range
|
# Ensure the amount is within the range
|
||||||
if selection > int(configloader.config["Payments"]["max_amount"]):
|
if value > int(configloader.config["Payments"]["max_amount"]):
|
||||||
self.bot.send_message(self.chat.id, strings.error_payment_amount_over_max.format(max_amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=configloader.config["Payments"]["max_amount"])))
|
self.bot.send_message(self.chat.id, strings.error_payment_amount_over_max.format(max_amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=configloader.config["Payments"]["max_amount"])))
|
||||||
continue
|
continue
|
||||||
elif selection < int(configloader.config["Payments"]["min_amount"]):
|
elif value < int(configloader.config["Payments"]["min_amount"]):
|
||||||
self.bot.send_message(self.chat.id, strings.error_payment_amount_under_min.format(min_amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=configloader.config["Payments"]["min_amount"])))
|
self.bot.send_message(self.chat.id, strings.error_payment_amount_under_min.format(min_amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=configloader.config["Payments"]["min_amount"])))
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
|
# If the user cancelled the action...
|
||||||
|
else:
|
||||||
|
# Exit the function
|
||||||
|
return
|
||||||
# Set the invoice active invoice payload
|
# Set the invoice active invoice payload
|
||||||
self.invoice_payload = str(uuid.uuid4())
|
self.invoice_payload = str(uuid.uuid4())
|
||||||
# Create the price array
|
# Create the price array
|
||||||
prices = [telegram.LabeledPrice(label=strings.payment_invoice_label, amount=selection)]
|
prices = [telegram.LabeledPrice(label=strings.payment_invoice_label, amount=value)]
|
||||||
# If the user has to pay a fee when using the credit card, add it to the prices list
|
# If the user has to pay a fee when using the credit card, add it to the prices list
|
||||||
fee_percentage = float(configloader.config["Credit Card"]["fee_percentage"]) / 100
|
fee_percentage = float(configloader.config["Credit Card"]["fee_percentage"]) / 100
|
||||||
fee_fixed = int(configloader.config["Credit Card"]["fee_fixed"])
|
fee_fixed = int(configloader.config["Credit Card"]["fee_fixed"])
|
||||||
total_fee = int(selection * fee_percentage) + fee_fixed
|
total_fee = int(value * fee_percentage) + fee_fixed
|
||||||
if total_fee > 0:
|
if total_fee > 0:
|
||||||
prices.append(telegram.LabeledPrice(label=strings.payment_invoice_fee_label, amount=int(total_fee)))
|
prices.append(telegram.LabeledPrice(label=strings.payment_invoice_fee_label, amount=int(total_fee)))
|
||||||
else:
|
else:
|
||||||
# Otherwise, set the fee to 0 to ensure no accidental discounts are applied
|
# Otherwise, set the fee to 0 to ensure no accidental discounts are applied
|
||||||
total_fee = 0
|
total_fee = 0
|
||||||
|
# Create the invoice keyboard
|
||||||
|
inline_keyboard = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.menu_pay)],
|
||||||
|
[telegram.InlineKeyboardButton(strings.menu_cancel, callback_data="cmd_cancel")]])
|
||||||
# The amount is valid, send the invoice
|
# The amount is valid, send the invoice
|
||||||
self.bot.send_invoice(self.chat.id,
|
self.bot.send_invoice(self.chat.id,
|
||||||
title=strings.payment_invoice_title,
|
title=strings.payment_invoice_title,
|
||||||
description=strings.payment_invoice_description.format(amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=selection / (10 ** int(configloader.config["Payments"]["currency_exp"])))),
|
description=strings.payment_invoice_description.format(amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=value / (10 ** int(configloader.config["Payments"]["currency_exp"])))),
|
||||||
payload=self.invoice_payload,
|
payload=self.invoice_payload,
|
||||||
provider_token=configloader.config["Credit Card"]["credit_card_token"],
|
provider_token=configloader.config["Credit Card"]["credit_card_token"],
|
||||||
start_parameter="tempdeeplink", # TODO: no idea on how deeplinks should work
|
start_parameter="tempdeeplink", # TODO: no idea on how deeplinks should work
|
||||||
|
@ -349,10 +387,14 @@ class ChatWorker(threading.Thread):
|
||||||
prices=prices,
|
prices=prices,
|
||||||
need_name=configloader.config["Credit Card"]["name_required"] == "yes",
|
need_name=configloader.config["Credit Card"]["name_required"] == "yes",
|
||||||
need_email=configloader.config["Credit Card"]["email_required"] == "yes",
|
need_email=configloader.config["Credit Card"]["email_required"] == "yes",
|
||||||
need_phone_number=configloader.config["Credit Card"]["phone_required"] == "yes")
|
need_phone_number=configloader.config["Credit Card"]["phone_required"] == "yes",
|
||||||
|
reply_markup=inline_keyboard)
|
||||||
# Wait for the invoice
|
# Wait for the invoice
|
||||||
precheckoutquery = self.__wait_for_precheckoutquery()
|
precheckoutquery = self.__wait_for_precheckoutquery(cancellable=True)
|
||||||
# TODO: ensure the bot doesn't die here!
|
# Check if the user has cancelled the invoice
|
||||||
|
if isinstance(precheckoutquery, CancelSignal):
|
||||||
|
# Exit the function
|
||||||
|
return
|
||||||
# Accept the checkout
|
# Accept the checkout
|
||||||
self.bot.answer_pre_checkout_query(precheckoutquery.id, ok=True)
|
self.bot.answer_pre_checkout_query(precheckoutquery.id, ok=True)
|
||||||
# Wait for the payment
|
# Wait for the payment
|
||||||
|
@ -411,8 +453,9 @@ class ChatWorker(threading.Thread):
|
||||||
products = self.session.query(db.Product).all()
|
products = self.session.query(db.Product).all()
|
||||||
# Create a list of product names
|
# Create a list of product names
|
||||||
product_names = [product.name for product in products]
|
product_names = [product.name for product in products]
|
||||||
# Insert at the start of the list the add product option
|
# Insert at the start of the list the add product option and the Cancel option
|
||||||
product_names.insert(0, strings.menu_add_product)
|
product_names.insert(0, strings.menu_cancel)
|
||||||
|
product_names.insert(1, strings.menu_add_product)
|
||||||
# Create a keyboard using the product names
|
# Create a keyboard using the product names
|
||||||
keyboard = [[telegram.KeyboardButton(product_name)] for product_name in product_names]
|
keyboard = [[telegram.KeyboardButton(product_name)] for product_name in product_names]
|
||||||
# Send the previously created keyboard to the user (ensuring it can be clicked only 1 time)
|
# Send the previously created keyboard to the user (ensuring it can be clicked only 1 time)
|
||||||
|
@ -420,8 +463,12 @@ class ChatWorker(threading.Thread):
|
||||||
reply_markup=telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=True))
|
reply_markup=telegram.ReplyKeyboardMarkup(keyboard, one_time_keyboard=True))
|
||||||
# Wait for a reply from the user
|
# Wait for a reply from the user
|
||||||
selection = self.__wait_for_specific_message(product_names)
|
selection = self.__wait_for_specific_message(product_names)
|
||||||
|
# If the user has selected the Cancel option...
|
||||||
|
if selection == strings.menu_cancel:
|
||||||
|
# Exit the menu
|
||||||
|
return
|
||||||
# If the user has selected the Add Product option...
|
# If the user has selected the Add Product option...
|
||||||
if selection == strings.menu_add_product:
|
elif selection == strings.menu_add_product:
|
||||||
# Open the add product menu
|
# Open the add product menu
|
||||||
self.__edit_product_menu()
|
self.__edit_product_menu()
|
||||||
# If the user has selected a product
|
# If the user has selected a product
|
||||||
|
@ -433,17 +480,19 @@ class ChatWorker(threading.Thread):
|
||||||
|
|
||||||
def __edit_product_menu(self, product: typing.Optional[db.Product]=None):
|
def __edit_product_menu(self, product: typing.Optional[db.Product]=None):
|
||||||
"""Add a product to the database or edit an existing one."""
|
"""Add a product to the database or edit an existing one."""
|
||||||
|
# Create an inline keyboard with a single skip button
|
||||||
|
cancel = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.menu_skip, callback_data="cmd_cancel")]])
|
||||||
# Ask for the product name until a valid product name is specified
|
# Ask for the product name until a valid product name is specified
|
||||||
while True:
|
while True:
|
||||||
# Ask the question to the user
|
# Ask the question to the user
|
||||||
self.bot.send_message(self.chat.id, strings.ask_product_name)
|
self.bot.send_message(self.chat.id, strings.ask_product_name)
|
||||||
# Display the current name if you're editing an existing product
|
# Display the current name if you're editing an existing product
|
||||||
if product:
|
if product:
|
||||||
self.bot.send_message(self.chat.id, strings.edit_current_value.format(value=escape(product.name)), parse_mode="HTML")
|
self.bot.send_message(self.chat.id, strings.edit_current_value.format(value=escape(product.name)), parse_mode="HTML", reply_markup=cancel)
|
||||||
# Wait for an answer
|
# Wait for an answer
|
||||||
name = self.__wait_for_regex(r"(.*)")
|
name = self.__wait_for_regex(r"(.*)", cancellable=bool(product))
|
||||||
# Ensure a product with that name doesn't already exist
|
# Ensure a product with that name doesn't already exist
|
||||||
if self.session.query(db.Product).filter_by(name=name).one_or_none() in [None, product]:
|
if (product and isinstance(name, CancelSignal)) or self.session.query(db.Product).filter_by(name=name).one_or_none() in [None, product]:
|
||||||
# Exit the loop
|
# Exit the loop
|
||||||
break
|
break
|
||||||
self.bot.send_message(self.chat.id, strings.error_duplicate_name)
|
self.bot.send_message(self.chat.id, strings.error_duplicate_name)
|
||||||
|
@ -451,25 +500,27 @@ class ChatWorker(threading.Thread):
|
||||||
self.bot.send_message(self.chat.id, strings.ask_product_description)
|
self.bot.send_message(self.chat.id, strings.ask_product_description)
|
||||||
# Display the current description if you're editing an existing product
|
# Display the current description if you're editing an existing product
|
||||||
if product:
|
if product:
|
||||||
self.bot.send_message(self.chat.id, strings.edit_current_value.format(value=escape(product.description)), parse_mode="HTML")
|
self.bot.send_message(self.chat.id, strings.edit_current_value.format(value=escape(product.description)), parse_mode="HTML", reply_markup=cancel)
|
||||||
# Wait for an answer
|
# Wait for an answer
|
||||||
description = self.__wait_for_regex(r"(.*)")
|
description = self.__wait_for_regex(r"(.*)", cancellable=bool(product))
|
||||||
# Ask for the product price
|
# Ask for the product price
|
||||||
self.bot.send_message(self.chat.id, strings.ask_product_price)
|
self.bot.send_message(self.chat.id, strings.ask_product_price)
|
||||||
# Display the current name if you're editing an existing product
|
# Display the current name if you're editing an existing product
|
||||||
if product:
|
if product:
|
||||||
self.bot.send_message(self.chat.id, strings.edit_current_value.format(value=(strings.currency_format_string.format(symbol=strings.currency_symbol, value=(product.price / (10 ** int(configloader.config["Payments"]["currency_exp"]))))) if product.price is not None else 'Non in vendita'), parse_mode="HTML")
|
self.bot.send_message(self.chat.id, strings.edit_current_value.format(value=(strings.currency_format_string.format(symbol=strings.currency_symbol, value=(product.price / (10 ** int(configloader.config["Payments"]["currency_exp"]))))) if product.price is not None else 'Non in vendita'), parse_mode="HTML", reply_markup=cancel)
|
||||||
# Wait for an answer
|
# Wait for an answer
|
||||||
price = self.__wait_for_regex(r"([0-9]{1,3}(?:[.,][0-9]{1,2})?|[Ss][Kk][Ii][Pp])")
|
price = self.__wait_for_regex(r"([0-9]{1,3}(?:[.,][0-9]{1,2})?|[Xx])", cancellable=True)
|
||||||
# If the price is skipped
|
# If the price is skipped
|
||||||
if price.lower() == "skip":
|
if isinstance(price, CancelSignal):
|
||||||
|
pass
|
||||||
|
elif price.lower() == "x":
|
||||||
price = None
|
price = None
|
||||||
else:
|
else:
|
||||||
price = int(price.replace(".", "").replace(",", "")) * (10 ** int(configloader.config["Payments"]["currency_exp"]))
|
price = int(price.replace(".", "").replace(",", "")) * (10 ** int(configloader.config["Payments"]["currency_exp"]))
|
||||||
# Ask for the product image
|
# Ask for the product image
|
||||||
self.bot.send_message(self.chat.id, strings.ask_product_image)
|
self.bot.send_message(self.chat.id, strings.ask_product_image, reply_markup=cancel)
|
||||||
# Wait for an answer
|
# Wait for an answer
|
||||||
photo_list = self.__wait_for_photo()
|
photo_list = self.__wait_for_photo(cancellable=True)
|
||||||
# TODO: ask for boolean status
|
# TODO: ask for boolean status
|
||||||
# If a new product is being added...
|
# If a new product is being added...
|
||||||
if not product:
|
if not product:
|
||||||
|
@ -484,21 +535,24 @@ class ChatWorker(threading.Thread):
|
||||||
# If a product is being edited...
|
# If a product is being edited...
|
||||||
else:
|
else:
|
||||||
# Edit the record with the new values
|
# Edit the record with the new values
|
||||||
product.name = name
|
product.name = name if not isinstance(name, CancelSignal) else product.name
|
||||||
product.description = description
|
product.description = description if not isinstance(description, CancelSignal) else product.description
|
||||||
product.price = price
|
product.price = price if not isinstance(price, CancelSignal) else product.price
|
||||||
# Find the largest photo id
|
# If a photo has been sent...
|
||||||
largest_photo = photo_list[0]
|
if not isinstance(photo_list, CancelSignal):
|
||||||
for photo in photo_list[1:]:
|
# Find the largest photo id
|
||||||
if photo.width > largest_photo.width:
|
largest_photo = photo_list[0]
|
||||||
largest_photo = photo
|
for photo in photo_list[1:]:
|
||||||
# Get the file object associated with the photo
|
if photo.width > largest_photo.width:
|
||||||
photo_file = self.bot.get_file(largest_photo.file_id)
|
largest_photo = photo
|
||||||
# Notify the user that the bot is downloading the image and might be inactive for a while
|
# Get the file object associated with the photo
|
||||||
self.bot.send_message(self.chat.id, strings.downloading_image)
|
photo_file = self.bot.get_file(largest_photo.file_id)
|
||||||
self.bot.send_chat_action(self.chat.id, action="upload_photo")
|
# Notify the user that the bot is downloading the image and might be inactive for a while
|
||||||
# Set the image for that product
|
self.bot.send_message(self.chat.id, strings.downloading_image)
|
||||||
product.set_image(photo_file)
|
self.bot.send_chat_action(self.chat.id, action="upload_photo")
|
||||||
|
# Set the image for that product
|
||||||
|
product.set_image(photo_file)
|
||||||
|
# Commit the session changes
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
# Notify the user
|
# Notify the user
|
||||||
if product:
|
if product:
|
||||||
|
|
Loading…
Reference in a new issue