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:
parent
087eb0d594
commit
dd686a4456
4 changed files with 138 additions and 117 deletions
|
@ -2,21 +2,24 @@ import sys
|
|||
import os
|
||||
import configparser
|
||||
|
||||
|
||||
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/config.ini"):
|
||||
if not os.path.isfile(config_filename):
|
||||
# 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
|
||||
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
|
||||
config = configparser.ConfigParser()
|
||||
config.read_file(template_file)
|
||||
template_version = int(config["Config"]["version"])
|
||||
|
||||
# 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)
|
||||
|
||||
# Check if the file has been edited
|
||||
|
@ -32,9 +35,11 @@ if template_version > int(config["Config"]["version"]):
|
|||
# Update the config version
|
||||
config["Config"]["version"] = str(template_version)
|
||||
# Save the file
|
||||
with open("config/config.ini", "w") as config_file:
|
||||
with open(config_filename, "w") as config_file:
|
||||
config.write(config_file)
|
||||
# Notify the user and quit
|
||||
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.")
|
||||
sys.exit(1)
|
||||
|
||||
return config
|
||||
|
|
9
core.py
9
core.py
|
@ -13,8 +13,11 @@ def main():
|
|||
# Rename the main thread for presentation purposes
|
||||
threading.current_thread().name = "Core"
|
||||
|
||||
# Load the config
|
||||
config = configloader.load_config()
|
||||
|
||||
# Create a bot instance
|
||||
bot = utils.DuckBot(configloader.config["Telegram"]["token"])
|
||||
bot = utils.DuckBot(config["Telegram"]["token"])
|
||||
|
||||
# Test the specified token
|
||||
try:
|
||||
|
@ -38,7 +41,7 @@ def main():
|
|||
while True:
|
||||
# Get a new batch of 100 updates and mark the last 100 parsed as read
|
||||
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
|
||||
for update in updates:
|
||||
# If the update is a message...
|
||||
|
@ -57,7 +60,7 @@ def main():
|
|||
if old_worker:
|
||||
old_worker.stop("request")
|
||||
# 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
|
||||
new_worker.start()
|
||||
# Store the worker in the dictionary
|
||||
|
|
61
utils.py
61
utils.py
|
@ -1,40 +1,31 @@
|
|||
import telegram
|
||||
import telegram.error
|
||||
import time
|
||||
from configloader import config
|
||||
from strings import currency_format_string, currency_symbol
|
||||
import typing
|
||||
import os
|
||||
import sys
|
||||
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:
|
||||
"""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("""
|
||||
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):
|
||||
# Keep the value as it is
|
||||
self.value = int(value)
|
||||
elif isinstance(value, float):
|
||||
# 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):
|
||||
# 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):
|
||||
# Copy self
|
||||
self.value = value.value
|
||||
else:
|
||||
raise TypeError("Value is of an unsupported type")
|
||||
self.exp: int = exp
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Price of value {self.value}>"
|
||||
|
@ -42,57 +33,69 @@ class Price:
|
|||
def __str__(self):
|
||||
return currency_format_string.format(symbol=currency_symbol,
|
||||
value="{0:.2f}".format(
|
||||
self.value / (10 ** int(config["Payments"]["currency_exp"]))))
|
||||
self.value / (10 ** self.exp)))
|
||||
|
||||
def __int__(self):
|
||||
return self.value
|
||||
|
||||
def __float__(self):
|
||||
return self.value / (10 ** int(config["Payments"]["currency_exp"]))
|
||||
return self.value / (10 ** self.exp)
|
||||
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
return self.__add__(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):
|
||||
|
||||
return self.__mul__(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
|
||||
|
||||
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
|
||||
|
||||
def __imul__(self, other):
|
||||
|
|
70
worker.py
70
worker.py
|
@ -4,7 +4,7 @@ import uuid
|
|||
import datetime
|
||||
import telegram
|
||||
import strings
|
||||
import configloader
|
||||
import configparser
|
||||
import sys
|
||||
import queue as queuem
|
||||
import database as db
|
||||
|
@ -30,12 +30,20 @@ class CancelSignal:
|
|||
class ChatWorker(threading.Thread):
|
||||
"""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
|
||||
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.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
|
||||
self.session = db.Session()
|
||||
# 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
|
||||
self.invoice_payload = None
|
||||
# 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":
|
||||
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__)),
|
||||
environment="Dev" if __debug__ else "Prod")
|
||||
else:
|
||||
|
@ -130,7 +138,7 @@ class ChatWorker(threading.Thread):
|
|||
If a stop signal is sent, try to gracefully stop the thread."""
|
||||
# Pop data from the queue
|
||||
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:
|
||||
# If the conversation times out, gracefully stop the thread
|
||||
self.__graceful_stop(StopSignal("timeout"))
|
||||
|
@ -222,7 +230,8 @@ class ChatWorker(threading.Thread):
|
|||
# Return the successfulpayment
|
||||
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."""
|
||||
while True:
|
||||
# Get the next update
|
||||
|
@ -298,7 +307,8 @@ class ChatWorker(threading.Thread):
|
|||
[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)
|
||||
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))
|
||||
# Wait for a reply from the user
|
||||
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)
|
||||
# Create the cart summary
|
||||
product_list = ""
|
||||
total_cost = utils.Price(0)
|
||||
total_cost = utils.Price(0, self._exp)
|
||||
for product_id in cart:
|
||||
if cart[product_id][1] > 0:
|
||||
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)
|
||||
# Create the cart summary
|
||||
product_list = ""
|
||||
total_cost = utils.Price(0)
|
||||
total_cost = utils.Price(0, self._exp)
|
||||
for product_id in cart:
|
||||
if cart[product_id][1] > 0:
|
||||
product_list += cart[product_id][0].text(style="short", cart_qty=cart[product_id][1]) + "\n"
|
||||
|
@ -545,7 +555,7 @@ class ChatWorker(threading.Thread):
|
|||
# Cash
|
||||
keyboard.append([telegram.KeyboardButton(strings.menu_cash)])
|
||||
# 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: go back to the previous menu
|
||||
keyboard.append([telegram.KeyboardButton(strings.menu_cancel)])
|
||||
|
@ -571,10 +581,10 @@ class ChatWorker(threading.Thread):
|
|||
def __add_credit_cc(self):
|
||||
"""Add money to the wallet through a credit card payment."""
|
||||
# Create a keyboard to be sent later
|
||||
keyboard = [[telegram.KeyboardButton(str(utils.Price("10.00")))],
|
||||
[telegram.KeyboardButton(str(utils.Price("25.00")))],
|
||||
[telegram.KeyboardButton(str(utils.Price("50.00")))],
|
||||
[telegram.KeyboardButton(str(utils.Price("100.00")))],
|
||||
keyboard = [[telegram.KeyboardButton(str(utils.Price("10.00", self._exp)))],
|
||||
[telegram.KeyboardButton(str(utils.Price("25.00", self._exp)))],
|
||||
[telegram.KeyboardButton(str(utils.Price("50.00", self._exp)))],
|
||||
[telegram.KeyboardButton(str(utils.Price("100.00", self._exp)))],
|
||||
[telegram.KeyboardButton(strings.menu_cancel)]]
|
||||
# Boolean variable to check if the user has cancelled the action
|
||||
cancelled = False
|
||||
|
@ -592,17 +602,17 @@ class ChatWorker(threading.Thread):
|
|||
cancelled = True
|
||||
continue
|
||||
# Convert the amount to an integer
|
||||
value = utils.Price(selection)
|
||||
value = utils.Price(selection, self._exp)
|
||||
# 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,
|
||||
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
|
||||
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,
|
||||
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
|
||||
break
|
||||
# If the user cancelled the action...
|
||||
|
@ -614,8 +624,8 @@ class ChatWorker(threading.Thread):
|
|||
# Create the price array
|
||||
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
|
||||
fee_percentage = float(configloader.config["Credit Card"]["fee_percentage"]) / 100
|
||||
fee_fixed = int(configloader.config["Credit Card"]["fee_fixed"])
|
||||
fee_percentage = float(self.config["Credit Card"]["fee_percentage"]) / 100
|
||||
fee_fixed = int(self.config["Credit Card"]["fee_fixed"])
|
||||
total_fee = value * fee_percentage + fee_fixed
|
||||
if total_fee > 0:
|
||||
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,
|
||||
description=strings.payment_invoice_description.format(amount=str(value)),
|
||||
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",
|
||||
currency=configloader.config["Payments"]["currency"],
|
||||
currency=self.config["Payments"]["currency"],
|
||||
prices=prices,
|
||||
need_name=configloader.config["Credit Card"]["name_required"] == "yes",
|
||||
need_email=configloader.config["Credit Card"]["email_required"] == "yes",
|
||||
need_phone_number=configloader.config["Credit Card"]["phone_required"] == "yes",
|
||||
need_name=self.config["Credit Card"]["name_required"] == "yes",
|
||||
need_email=self.config["Credit Card"]["email_required"] == "yes",
|
||||
need_phone_number=self.config["Credit Card"]["phone_required"] == "yes",
|
||||
reply_markup=inline_keyboard)
|
||||
# Wait for the invoice
|
||||
precheckoutquery = self.__wait_for_precheckoutquery(cancellable=True)
|
||||
|
@ -799,7 +809,7 @@ class ChatWorker(threading.Thread):
|
|||
if product:
|
||||
self.bot.send_message(self.chat.id,
|
||||
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')),
|
||||
reply_markup=cancel)
|
||||
# Wait for an answer
|
||||
|
@ -811,7 +821,7 @@ class ChatWorker(threading.Thread):
|
|||
elif price.lower() == "x":
|
||||
price = None
|
||||
else:
|
||||
price = utils.Price(price)
|
||||
price = utils.Price(price, self._exp)
|
||||
# Ask for the product image
|
||||
self.bot.send_message(self.chat.id, strings.ask_product_image, reply_markup=cancel)
|
||||
# Wait for an answer
|
||||
|
@ -1126,7 +1136,7 @@ class ChatWorker(threading.Thread):
|
|||
# Reopen the file for reading
|
||||
with open(f"transactions_{self.chat.id}.csv") as file:
|
||||
# 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},
|
||||
params={"chat_id": self.chat.id,
|
||||
"parse_mode": "HTML"})
|
||||
|
|
Loading…
Reference in a new issue