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,21 +2,24 @@ import sys
import os import os
import configparser 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 # 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 # 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
@ -32,9 +35,11 @@ if template_version > int(config["Config"]["version"]):
# 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):

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
@ -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:
@ -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"))
@ -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
@ -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"
@ -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)
@ -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
@ -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"})