1
Fork 0
mirror of https://github.com/Steffo99/greed.git synced 2024-12-04 19:34:19 +00:00

I found this on my pc, I have no idea of what I was trying to do

This commit is contained in:
Steffo 2020-02-05 02:10:52 +01:00
parent 087eb0d594
commit dd686a4456
4 changed files with 138 additions and 117 deletions

View file

@ -2,39 +2,44 @@ import sys
import os import os
import configparser import configparser
# Check if the config file exists, and create one if it doesn't
if not os.path.isfile("config/config.ini"): def load_config(template_filename="config/template_config.ini",
config_filename="config/config.ini") -> configparser.ConfigParser:
# Check if the config file exists, and create one if it doesn't
if not os.path.isfile(config_filename):
# Open the template file and create the config file # Open the template file and create the config file
with open("config/template_config.ini") as template_file, open("config/config.ini", "w") as config_file: with open(template_filename) as template_file, open(config_filename, "w") as config_file:
# Copy the template file to the config file # Copy the template file to the config file
config_file.write(template_file.read()) config_file.write(template_file.read())
with open("config/template_config.ini") as template_file: with open(template_filename) as template_file:
# Find the template version number # Find the template version number
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read_file(template_file) config.read_file(template_file)
template_version = int(config["Config"]["version"]) template_version = int(config["Config"]["version"])
# Overwrite the template config with the values in the config # Overwrite the template config with the values in the config
with open("config/config.ini") as config_file: with open(config_filename) as config_file:
config.read_file(config_file) config.read_file(config_file)
# Check if the file has been edited # Check if the file has been edited
if config["Config"]["is_template"] == "yes": if config["Config"]["is_template"] == "yes":
print("A config file has been created in config/config.ini.\n" print("A config file has been created in config/config.ini.\n"
"Edit it with your configuration, set the is_template flag to false and restart this script.") "Edit it with your configuration, set the is_template flag to false and restart this script.")
sys.exit(1) sys.exit(1)
# Check if the version has changed from the template # Check if the version has changed from the template
if template_version > int(config["Config"]["version"]): if template_version > int(config["Config"]["version"]):
# Reset the is_template flag # Reset the is_template flag
config["Config"]["is_template"] = "yes" config["Config"]["is_template"] = "yes"
# Update the config version # Update the config version
config["Config"]["version"] = str(template_version) config["Config"]["version"] = str(template_version)
# Save the file # Save the file
with open("config/config.ini", "w") as config_file: with open(config_filename, "w") as config_file:
config.write(config_file) config.write(config_file)
# Notify the user and quit # Notify the user and quit
print("The config file in config/config.ini has been updated.\n" print("The config file in config/config.ini has been updated.\n"
"Edit it with the new required data, set the is_template flag to true and restart this script.") "Edit it with the new required data, set the is_template flag to true and restart this script.")
sys.exit(1) sys.exit(1)
return config

View file

@ -13,8 +13,11 @@ def main():
# Rename the main thread for presentation purposes # Rename the main thread for presentation purposes
threading.current_thread().name = "Core" threading.current_thread().name = "Core"
# Load the config
config = configloader.load_config()
# Create a bot instance # Create a bot instance
bot = utils.DuckBot(configloader.config["Telegram"]["token"]) bot = utils.DuckBot(config["Telegram"]["token"])
# Test the specified token # Test the specified token
try: try:
@ -38,7 +41,7 @@ def main():
while True: while True:
# Get a new batch of 100 updates and mark the last 100 parsed as read # Get a new batch of 100 updates and mark the last 100 parsed as read
updates = bot.get_updates(offset=next_update, updates = bot.get_updates(offset=next_update,
timeout=int(configloader.config["Telegram"]["long_polling_timeout"])) timeout=int(config["Telegram"]["long_polling_timeout"]))
# Parse all the updates # Parse all the updates
for update in updates: for update in updates:
# If the update is a message... # If the update is a message...
@ -57,7 +60,7 @@ def main():
if old_worker: if old_worker:
old_worker.stop("request") old_worker.stop("request")
# Initialize a new worker for the chat # Initialize a new worker for the chat
new_worker = worker.ChatWorker(bot, update.message.chat) new_worker = worker.ChatWorker(bot=bot, chat=update.message.chat, config=config)
# Start the worker # Start the worker
new_worker.start() new_worker.start()
# Store the worker in the dictionary # Store the worker in the dictionary

View file

@ -1,40 +1,31 @@
import telegram import telegram
import telegram.error import telegram.error
import time import time
from configloader import config
from strings import currency_format_string, currency_symbol from strings import currency_format_string, currency_symbol
import typing import typing
import os
import sys import sys
import strings import strings
if config["Error Reporting"]["sentry_token"] != \
"https://00000000000000000000000000000000:00000000000000000000000000000000@sentry.io/0000000":
import raven
sentry_client = raven.Client(config["Error Reporting"]["sentry_token"],
release=raven.fetch_git_sha(os.path.dirname(__file__)),
environment="Dev" if __debug__ else "Prod")
else:
sentry_client = None
class Price: class Price:
"""The base class for the prices in greed. """The base class for the prices in greed.
Its int value is in minimum units, while its float and str values are in decimal format.int(""" Its int value is in minimum units, while its float and str values are in decimal format.int("""
def __init__(self, value: typing.Union[int, float, str, "Price"]=0): def __init__(self, value: typing.Union[int, float, str, "Price"], exp: int):
if isinstance(value, int): if isinstance(value, int):
# Keep the value as it is # Keep the value as it is
self.value = int(value) self.value = int(value)
elif isinstance(value, float): elif isinstance(value, float):
# Convert the value to minimum units # Convert the value to minimum units
self.value = int(value * (10 ** int(config["Payments"]["currency_exp"]))) self.value = int(value * (10 ** exp))
elif isinstance(value, str): elif isinstance(value, str):
# Remove decimal points, then cast to int # Remove decimal points, then cast to int
self.value = int(float(value.replace(",", ".")) * (10 ** int(config["Payments"]["currency_exp"]))) self.value = int(float(value.replace(",", ".")) * (10 ** exp))
elif isinstance(value, Price): elif isinstance(value, Price):
# Copy self # Copy self
self.value = value.value self.value = value.value
else:
raise TypeError("Value is of an unsupported type")
self.exp: int = exp
def __repr__(self): def __repr__(self):
return f"<Price of value {self.value}>" return f"<Price of value {self.value}>"
@ -42,57 +33,69 @@ class Price:
def __str__(self): def __str__(self):
return currency_format_string.format(symbol=currency_symbol, return currency_format_string.format(symbol=currency_symbol,
value="{0:.2f}".format( value="{0:.2f}".format(
self.value / (10 ** int(config["Payments"]["currency_exp"])))) self.value / (10 ** self.exp)))
def __int__(self): def __int__(self):
return self.value return self.value
def __float__(self): def __float__(self):
return self.value / (10 ** int(config["Payments"]["currency_exp"])) return self.value / (10 ** self.exp)
def __ge__(self, other): def __ge__(self, other):
return self.value >= Price(other).value # Assuming currency exp is the same for the compared prices
return self.value >= Price(other, self.exp).value
def __le__(self, other): def __le__(self, other):
return self.value <= Price(other).value # Assuming currency exp is the same for the compared prices
return self.value <= Price(other, self.exp).value
def __eq__(self, other): def __eq__(self, other):
return self.value == Price(other).value # Assuming currency exp is the same for the compared prices
return self.value == Price(other, self.exp).value
def __gt__(self, other): def __gt__(self, other):
return self.value > Price(other).value # Assuming currency exp is the same for the compared prices
return self.value > Price(other, self.exp).value
def __lt__(self, other): def __lt__(self, other):
return self.value < Price(other).value # Assuming currency exp is the same for the compared prices
return self.value < Price(other, self.exp).value
def __add__(self, other): def __add__(self, other):
return Price(self.value + Price(other).value) # Assuming currency exp is the same for the compared prices
return Price(self.value + Price(other, self.exp).value, self.exp)
def __sub__(self, other): def __sub__(self, other):
return Price(self.value - Price(other).value) # Assuming currency exp is the same for the compared prices
return Price(self.value - Price(other, self.exp).value, self.exp)
def __mul__(self, other): def __mul__(self, other):
return Price(int(self.value * other)) # Assuming currency exp is the same for the compared prices
return Price(int(self.value * other), self.exp)
def __floordiv__(self, other): def __floordiv__(self, other):
return Price(int(self.value // other)) # Assuming currency exp is the same for the compared prices
return Price(int(self.value // other), self.exp)
def __radd__(self, other): def __radd__(self, other):
return self.__add__(other) return self.__add__(other)
def __rsub__(self, other): def __rsub__(self, other):
return Price(Price(other).value - self.value) # Assuming currency exp is the same for the compared prices
return Price(Price(other, self.exp).value - self.value, self.exp)
def __rmul__(self, other): def __rmul__(self, other):
return self.__mul__(other) return self.__mul__(other)
def __iadd__(self, other): def __iadd__(self, other):
self.value += Price(other).value # Assuming currency exp is the same for the compared prices
self.value += Price(other, self.exp).value
return self return self
def __isub__(self, other): def __isub__(self, other):
self.value -= Price(other).value # Assuming currency exp is the same for the compared prices
self.value -= Price(other, self.exp).value
return self return self
def __imul__(self, other): def __imul__(self, other):

112
worker.py
View file

@ -4,7 +4,7 @@ import uuid
import datetime import datetime
import telegram import telegram
import strings import strings
import configloader import configparser
import sys import sys
import queue as queuem import queue as queuem
import database as db import database as db
@ -18,7 +18,7 @@ import requests
class StopSignal: class StopSignal:
"""A data class that should be sent to the worker when the conversation has to be stopped abnormally.""" """A data class that should be sent to the worker when the conversation has to be stopped abnormally."""
def __init__(self, reason: str=""): def __init__(self, reason: str = ""):
self.reason = reason self.reason = reason
@ -30,12 +30,20 @@ class CancelSignal:
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."""
def __init__(self, bot: utils.DuckBot, chat: telegram.Chat, *args, **kwargs): def __init__(self,
bot: utils.DuckBot,
chat: telegram.Chat,
config: configparser.ConfigParser,
*args,
**kwargs):
# Initialize the thread # Initialize the thread
super().__init__(name=f"Worker {chat.id}", *args, **kwargs) super().__init__(name=f"Worker {chat.id}", *args, **kwargs)
# Store the bot and chat info inside the class # Store the bot, chat info and config inside the class
self.bot: utils.DuckBot = bot self.bot: utils.DuckBot = bot
self.chat: telegram.Chat = chat self.chat: telegram.Chat = chat
self.config: configparser.ConfigParser = config
# A shortcut to currency_exp
self._exp: int = int(config["Payments"]["currency_exp"])
# Open a new database session # Open a new database session
self.session = db.Session() self.session = db.Session()
# Get the user db data from the users and admin tables # Get the user db data from the users and admin tables
@ -46,10 +54,10 @@ class ChatWorker(threading.Thread):
# The current active invoice payload; reject all invoices with a different payload # The current active invoice payload; reject all invoices with a different payload
self.invoice_payload = None self.invoice_payload = None
# The Sentry client for reporting errors encountered by the user # The Sentry client for reporting errors encountered by the user
if configloader.config["Error Reporting"]["sentry_token"] != \ if self.config["Error Reporting"]["sentry_token"] != \
"https://00000000000000000000000000000000:00000000000000000000000000000000@sentry.io/0000000": "https://00000000000000000000000000000000:00000000000000000000000000000000@sentry.io/0000000":
import raven import raven
self.sentry_client = raven.Client(configloader.config["Error Reporting"]["sentry_token"], self.sentry_client = raven.Client(self.config["Error Reporting"]["sentry_token"],
release=raven.fetch_git_sha(os.path.dirname(__file__)), release=raven.fetch_git_sha(os.path.dirname(__file__)),
environment="Dev" if __debug__ else "Prod") environment="Dev" if __debug__ else "Prod")
else: else:
@ -110,7 +118,7 @@ class ChatWorker(threading.Thread):
if self.sentry_client is not None: if self.sentry_client is not None:
self.sentry_client.captureException() self.sentry_client.captureException()
def stop(self, reason: str=""): def stop(self, reason: str = ""):
"""Gracefully stop the worker process""" """Gracefully stop the worker process"""
# Send a stop message to the thread # Send a stop message to the thread
self.queue.put(StopSignal(reason)) self.queue.put(StopSignal(reason))
@ -130,7 +138,7 @@ class ChatWorker(threading.Thread):
If a stop signal is sent, try to gracefully stop the thread.""" If a stop signal is sent, try to gracefully stop the thread."""
# Pop data from the queue # Pop data from the queue
try: try:
data = self.queue.get(timeout=int(configloader.config["Telegram"]["conversation_timeout"])) data = self.queue.get(timeout=int(self.config["Telegram"]["conversation_timeout"]))
except queuem.Empty: except queuem.Empty:
# If the conversation times out, gracefully stop the thread # If the conversation times out, gracefully stop the thread
self.__graceful_stop(StopSignal("timeout")) self.__graceful_stop(StopSignal("timeout"))
@ -143,7 +151,7 @@ class ChatWorker(threading.Thread):
def __wait_for_specific_message(self, def __wait_for_specific_message(self,
items: typing.List[str], items: typing.List[str],
cancellable: bool=False) -> typing.Union[str, CancelSignal]: 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
@ -168,7 +176,7 @@ 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, cancellable: bool=False) -> typing.Union[str, CancelSignal]: 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
@ -192,7 +200,7 @@ class ChatWorker(threading.Thread):
return match.group(1) return match.group(1)
def __wait_for_precheckoutquery(self, def __wait_for_precheckoutquery(self,
cancellable: bool=False) -> typing.Union[telegram.PreCheckoutQuery, CancelSignal]: 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:
@ -222,7 +230,8 @@ 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, cancellable: bool=False) -> typing.Union[typing.List[telegram.PhotoSize], CancelSignal]: def __wait_for_photo(self, cancellable: bool = False) -> typing.Union[
typing.List[telegram.PhotoSize], CancelSignal]:
"""Continue getting updates until a photo is received, then return it.""" """Continue getting updates until a photo is received, then return it."""
while True: while True:
# Get the next update # Get the next update
@ -240,7 +249,7 @@ class ChatWorker(threading.Thread):
# Return the photo array # Return the photo array
return update.message.photo return update.message.photo
def __wait_for_inlinekeyboard_callback(self, cancellable: bool=True) \ def __wait_for_inlinekeyboard_callback(self, cancellable: bool = True) \
-> typing.Union[telegram.CallbackQuery, CancelSignal]: -> typing.Union[telegram.CallbackQuery, CancelSignal]:
"""Continue getting updates until an inline keyboard callback is received, then return it.""" """Continue getting updates until an inline keyboard callback is received, then return it."""
while True: while True:
@ -298,7 +307,8 @@ class ChatWorker(threading.Thread):
[telegram.KeyboardButton(strings.menu_help), telegram.KeyboardButton(strings.menu_bot_info)]] [telegram.KeyboardButton(strings.menu_help), telegram.KeyboardButton(strings.menu_bot_info)]]
# 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)
self.bot.send_message(self.chat.id, self.bot.send_message(self.chat.id,
strings.conversation_open_user_menu.format(credit=utils.Price(self.user.credit)), strings.conversation_open_user_menu.format(credit=utils.Price(self.user.credit,
self._exp)),
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([strings.menu_order, strings.menu_order_status, selection = self.__wait_for_specific_message([strings.menu_order, strings.menu_order_status,
@ -404,7 +414,7 @@ class ChatWorker(threading.Thread):
reply_markup=product_inline_keyboard) reply_markup=product_inline_keyboard)
# Create the cart summary # Create the cart summary
product_list = "" product_list = ""
total_cost = utils.Price(0) total_cost = utils.Price(0, self._exp)
for product_id in cart: for product_id in cart:
if cart[product_id][1] > 0: if cart[product_id][1] > 0:
product_list += cart[product_id][0].text(style="short", cart_qty=cart[product_id][1]) + "\n" product_list += cart[product_id][0].text(style="short", cart_qty=cart[product_id][1]) + "\n"
@ -452,7 +462,7 @@ class ChatWorker(threading.Thread):
reply_markup=product_inline_keyboard) reply_markup=product_inline_keyboard)
# Create the cart summary # Create the cart summary
product_list = "" product_list = ""
total_cost = utils.Price(0) total_cost = utils.Price(0, self._exp)
for product_id in cart: for product_id in cart:
if cart[product_id][1] > 0: if cart[product_id][1] > 0:
product_list += cart[product_id][0].text(style="short", cart_qty=cart[product_id][1]) + "\n" product_list += cart[product_id][0].text(style="short", cart_qty=cart[product_id][1]) + "\n"
@ -524,10 +534,10 @@ class ChatWorker(threading.Thread):
def __order_status(self): def __order_status(self):
"""Display the status of the sent orders.""" """Display the status of the sent orders."""
# Find the latest orders # Find the latest orders
orders = self.session.query(db.Order)\ orders = self.session.query(db.Order) \
.filter(db.Order.user == self.user)\ .filter(db.Order.user == self.user) \
.order_by(db.Order.creation_date.desc())\ .order_by(db.Order.creation_date.desc()) \
.limit(20)\ .limit(20) \
.all() .all()
# Ensure there is at least one order to display # Ensure there is at least one order to display
if len(orders) == 0: if len(orders) == 0:
@ -545,7 +555,7 @@ class ChatWorker(threading.Thread):
# Cash # Cash
keyboard.append([telegram.KeyboardButton(strings.menu_cash)]) keyboard.append([telegram.KeyboardButton(strings.menu_cash)])
# Telegram Payments # Telegram Payments
if configloader.config["Credit Card"]["credit_card_token"] != "": if self.config["Credit Card"]["credit_card_token"] != "":
keyboard.append([telegram.KeyboardButton(strings.menu_credit_card)]) keyboard.append([telegram.KeyboardButton(strings.menu_credit_card)])
# Keyboard: go back to the previous menu # Keyboard: go back to the previous menu
keyboard.append([telegram.KeyboardButton(strings.menu_cancel)]) keyboard.append([telegram.KeyboardButton(strings.menu_cancel)])
@ -571,10 +581,10 @@ class ChatWorker(threading.Thread):
def __add_credit_cc(self): def __add_credit_cc(self):
"""Add money to the wallet through a credit card payment.""" """Add money to the wallet through a credit card payment."""
# Create a keyboard to be sent later # Create a keyboard to be sent later
keyboard = [[telegram.KeyboardButton(str(utils.Price("10.00")))], keyboard = [[telegram.KeyboardButton(str(utils.Price("10.00", self._exp)))],
[telegram.KeyboardButton(str(utils.Price("25.00")))], [telegram.KeyboardButton(str(utils.Price("25.00", self._exp)))],
[telegram.KeyboardButton(str(utils.Price("50.00")))], [telegram.KeyboardButton(str(utils.Price("50.00", self._exp)))],
[telegram.KeyboardButton(str(utils.Price("100.00")))], [telegram.KeyboardButton(str(utils.Price("100.00", self._exp)))],
[telegram.KeyboardButton(strings.menu_cancel)]] [telegram.KeyboardButton(strings.menu_cancel)]]
# Boolean variable to check if the user has cancelled the action # Boolean variable to check if the user has cancelled the action
cancelled = False cancelled = False
@ -592,17 +602,17 @@ class ChatWorker(threading.Thread):
cancelled = True cancelled = True
continue continue
# Convert the amount to an integer # Convert the amount to an integer
value = utils.Price(selection) value = utils.Price(selection, self._exp)
# Ensure the amount is within the range # Ensure the amount is within the range
if value > utils.Price(int(configloader.config["Credit Card"]["max_amount"])): if value > utils.Price(int(self.config["Credit Card"]["max_amount"]), self._exp):
self.bot.send_message(self.chat.id, self.bot.send_message(self.chat.id,
strings.error_payment_amount_over_max.format( strings.error_payment_amount_over_max.format(
max_amount=utils.Price(configloader.config["Payments"]["max_amount"]))) max_amount=utils.Price(self.config["Payments"]["max_amount"], self._exp)))
continue continue
elif value < utils.Price(int(configloader.config["Credit Card"]["min_amount"])): elif value < utils.Price(int(self.config["Credit Card"]["min_amount"]), self._exp):
self.bot.send_message(self.chat.id, self.bot.send_message(self.chat.id,
strings.error_payment_amount_under_min.format( strings.error_payment_amount_under_min.format(
min_amount=utils.Price(configloader.config["Payments"]["min_amount"]))) min_amount=utils.Price(self.config["Payments"]["min_amount"], self._exp)))
continue continue
break break
# If the user cancelled the action... # If the user cancelled the action...
@ -614,8 +624,8 @@ class ChatWorker(threading.Thread):
# Create the price array # Create the price array
prices = [telegram.LabeledPrice(label=strings.payment_invoice_label, amount=int(value))] prices = [telegram.LabeledPrice(label=strings.payment_invoice_label, amount=int(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(self.config["Credit Card"]["fee_percentage"]) / 100
fee_fixed = int(configloader.config["Credit Card"]["fee_fixed"]) fee_fixed = int(self.config["Credit Card"]["fee_fixed"])
total_fee = value * fee_percentage + fee_fixed total_fee = 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)))
@ -631,13 +641,13 @@ class ChatWorker(threading.Thread):
title=strings.payment_invoice_title, title=strings.payment_invoice_title,
description=strings.payment_invoice_description.format(amount=str(value)), description=strings.payment_invoice_description.format(amount=str(value)),
payload=self.invoice_payload, payload=self.invoice_payload,
provider_token=configloader.config["Credit Card"]["credit_card_token"], provider_token=self.config["Credit Card"]["credit_card_token"],
start_parameter="tempdeeplink", start_parameter="tempdeeplink",
currency=configloader.config["Payments"]["currency"], currency=self.config["Payments"]["currency"],
prices=prices, prices=prices,
need_name=configloader.config["Credit Card"]["name_required"] == "yes", need_name=self.config["Credit Card"]["name_required"] == "yes",
need_email=configloader.config["Credit Card"]["email_required"] == "yes", need_email=self.config["Credit Card"]["email_required"] == "yes",
need_phone_number=configloader.config["Credit Card"]["phone_required"] == "yes", need_phone_number=self.config["Credit Card"]["phone_required"] == "yes",
reply_markup=inline_keyboard) reply_markup=inline_keyboard)
# Wait for the invoice # Wait for the invoice
precheckoutquery = self.__wait_for_precheckoutquery(cancellable=True) precheckoutquery = self.__wait_for_precheckoutquery(cancellable=True)
@ -762,7 +772,7 @@ class ChatWorker(threading.Thread):
# Open the edit menu for that specific product # Open the edit menu for that specific product
self.__edit_product_menu(product=product) self.__edit_product_menu(product=product)
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 # Create an inline keyboard with a single skip button
cancel = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.menu_skip, cancel = telegram.InlineKeyboardMarkup([[telegram.InlineKeyboardButton(strings.menu_skip,
@ -778,7 +788,7 @@ class ChatWorker(threading.Thread):
# Wait for an answer # Wait for an answer
name = self.__wait_for_regex(r"(.*)", cancellable=bool(product)) 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 (product and isinstance(name, CancelSignal)) or\ if (product and isinstance(name, CancelSignal)) or \
self.session.query(db.Product).filter_by(name=name, deleted=False).one_or_none() in [None, product]: self.session.query(db.Product).filter_by(name=name, deleted=False).one_or_none() in [None, product]:
# Exit the loop # Exit the loop
break break
@ -799,7 +809,7 @@ class ChatWorker(threading.Thread):
if product: if product:
self.bot.send_message(self.chat.id, self.bot.send_message(self.chat.id,
strings.edit_current_value.format( strings.edit_current_value.format(
value=(str(utils.Price(product.price)) value=(str(utils.Price(product.price, self._exp))
if product.price is not None else 'Non in vendita')), if product.price is not None else 'Non in vendita')),
reply_markup=cancel) reply_markup=cancel)
# Wait for an answer # Wait for an answer
@ -811,7 +821,7 @@ class ChatWorker(threading.Thread):
elif price.lower() == "x": elif price.lower() == "x":
price = None price = None
else: else:
price = utils.Price(price) price = utils.Price(price, self._exp)
# Ask for the product image # Ask for the product image
self.bot.send_message(self.chat.id, strings.ask_product_image, reply_markup=cancel) self.bot.send_message(self.chat.id, strings.ask_product_image, reply_markup=cancel)
# Wait for an answer # Wait for an answer
@ -892,10 +902,10 @@ class ChatWorker(threading.Thread):
[telegram.InlineKeyboardButton(strings.menu_refund, [telegram.InlineKeyboardButton(strings.menu_refund,
callback_data="order_refund")]]) callback_data="order_refund")]])
# Display the past pending orders # Display the past pending orders
orders = self.session.query(db.Order)\ orders = self.session.query(db.Order) \
.filter_by(delivery_date=None, refund_date=None)\ .filter_by(delivery_date=None, refund_date=None) \
.join(db.Transaction)\ .join(db.Transaction) \
.join(db.User)\ .join(db.User) \
.all() .all()
# Create a message for every one of them # Create a message for every one of them
for order in orders: for order in orders:
@ -1043,10 +1053,10 @@ class ChatWorker(threading.Thread):
# Loop used to move between pages # Loop used to move between pages
while True: while True:
# Retrieve the 10 transactions in that page # Retrieve the 10 transactions in that page
transactions = self.session.query(db.Transaction)\ transactions = self.session.query(db.Transaction) \
.order_by(db.Transaction.transaction_id.desc())\ .order_by(db.Transaction.transaction_id.desc()) \
.limit(10)\ .limit(10) \
.offset(10 * page)\ .offset(10 * page) \
.all() .all()
# Create a list to be converted in inline keyboard markup # Create a list to be converted in inline keyboard markup
inline_keyboard_list = [[]] inline_keyboard_list = [[]]
@ -1068,7 +1078,7 @@ class ChatWorker(threading.Thread):
inline_keyboard = telegram.InlineKeyboardMarkup(inline_keyboard_list) inline_keyboard = telegram.InlineKeyboardMarkup(inline_keyboard_list)
# Create the message text # Create the message text
transactions_string = "\n".join([str(transaction) for transaction in transactions]) transactions_string = "\n".join([str(transaction) for transaction in transactions])
text = strings.transactions_page.format(page=page+1, text = strings.transactions_page.format(page=page + 1,
transactions=transactions_string) transactions=transactions_string)
# Update the previously sent message # Update the previously sent message
self.bot.edit_message_text(chat_id=self.chat.id, message_id=message.message_id, text=text, self.bot.edit_message_text(chat_id=self.chat.id, message_id=message.message_id, text=text,
@ -1126,7 +1136,7 @@ class ChatWorker(threading.Thread):
# Reopen the file for reading # Reopen the file for reading
with open(f"transactions_{self.chat.id}.csv") as file: with open(f"transactions_{self.chat.id}.csv") as file:
# Send the file via a manual request to Telegram # Send the file via a manual request to Telegram
requests.post(f"https://api.telegram.org/bot{configloader.config['Telegram']['token']}/sendDocument", requests.post(f"https://api.telegram.org/bot{self.config['Telegram']['token']}/sendDocument",
files={"document": file}, files={"document": file},
params={"chat_id": self.chat.id, params={"chat_id": self.chat.id,
"parse_mode": "HTML"}) "parse_mode": "HTML"})