mirror of
https://github.com/Steffo99/greed.git
synced 2024-11-21 21:44:19 +00:00
PEP8 and PyCharm fixes
This commit is contained in:
parent
c15ddabfd1
commit
e8250cd64d
7 changed files with 50 additions and 25 deletions
|
@ -1,2 +1,2 @@
|
||||||
# greed
|
# greed
|
||||||
A framework for shops on Telegram
|
A customizable Telegram shop bot
|
||||||
|
|
|
@ -36,4 +36,4 @@ if template_version > int(config["Config"]["version"]):
|
||||||
# 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)
|
||||||
|
|
17
core.py
17
core.py
|
@ -1,11 +1,11 @@
|
||||||
import sys
|
import sys
|
||||||
import telegram
|
import telegram
|
||||||
import time
|
|
||||||
import strings
|
import strings
|
||||||
import worker
|
import worker
|
||||||
import configloader
|
import configloader
|
||||||
import utils
|
import utils
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""The core code of the program. Should be run only in the main process!"""
|
"""The core code of the program. Should be run only in the main process!"""
|
||||||
|
|
||||||
|
@ -27,9 +27,6 @@ def main():
|
||||||
# Current update offset; if None it will get the last 100 unparsed messages
|
# Current update offset; if None it will get the last 100 unparsed messages
|
||||||
next_update = None
|
next_update = None
|
||||||
|
|
||||||
# TimedOut / NetworkError counter, increases by 1 every time get_updates fails and resets to 0 when it succedes
|
|
||||||
timed_out_counter = 0
|
|
||||||
|
|
||||||
# Notify on the console that the bot is starting
|
# Notify on the console that the bot is starting
|
||||||
print("greed-bot is now starting!")
|
print("greed-bot is now starting!")
|
||||||
|
|
||||||
|
@ -68,7 +65,8 @@ def main():
|
||||||
# Ensure a worker exists for the chat and is alive
|
# Ensure a worker exists for the chat and is alive
|
||||||
if receiving_worker is None or not receiving_worker.is_alive():
|
if receiving_worker is None or not receiving_worker.is_alive():
|
||||||
# Suggest that the user restarts the chat with /start
|
# Suggest that the user restarts the chat with /start
|
||||||
bot.send_message(update.message.chat.id, strings.error_no_worker_for_chat, reply_markup=telegram.ReplyKeyboardRemove())
|
bot.send_message(update.message.chat.id, strings.error_no_worker_for_chat,
|
||||||
|
reply_markup=telegram.ReplyKeyboardRemove())
|
||||||
# Skip the update
|
# Skip the update
|
||||||
continue
|
continue
|
||||||
# Forward the update to the worker
|
# Forward the update to the worker
|
||||||
|
@ -97,10 +95,13 @@ def main():
|
||||||
# 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
|
||||||
if receiving_worker is None or update.pre_checkout_query.invoice_payload != receiving_worker.invoice_payload:
|
if receiving_worker is None or\
|
||||||
|
update.pre_checkout_query.invoice_payload != receiving_worker.invoice_payload:
|
||||||
# Notify the user that the invoice has expired
|
# Notify the user that the invoice has expired
|
||||||
try:
|
try:
|
||||||
bot.answer_pre_checkout_query(update.pre_checkout_query.id, ok=False, error_message=strings.error_invoice_expired)
|
bot.answer_pre_checkout_query(update.pre_checkout_query.id,
|
||||||
|
ok=False,
|
||||||
|
error_message=strings.error_invoice_expired)
|
||||||
except telegram.error.BadRequest:
|
except telegram.error.BadRequest:
|
||||||
print(f"ERROR: pre_checkout_query expired before an answer could be sent")
|
print(f"ERROR: pre_checkout_query expired before an answer could be sent")
|
||||||
# Go to the next update
|
# Go to the next update
|
||||||
|
@ -115,4 +116,4 @@ def main():
|
||||||
|
|
||||||
# Run the main function only in the main process
|
# Run the main function only in the main process
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
34
database.py
34
database.py
|
@ -1,3 +1,5 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
from sqlalchemy import create_engine, Column, ForeignKey, UniqueConstraint
|
from sqlalchemy import create_engine, Column, ForeignKey, UniqueConstraint
|
||||||
from sqlalchemy import Integer, BigInteger, String, Text, LargeBinary, DateTime, Boolean
|
from sqlalchemy import Integer, BigInteger, String, Text, LargeBinary, DateTime, Boolean
|
||||||
from sqlalchemy.orm import sessionmaker, relationship
|
from sqlalchemy.orm import sessionmaker, relationship
|
||||||
|
@ -18,6 +20,7 @@ TableDeclarativeBase = declarative_base(bind=engine)
|
||||||
# Create a Session class able to initialize database sessions
|
# Create a Session class able to initialize database sessions
|
||||||
Session = sessionmaker()
|
Session = sessionmaker()
|
||||||
|
|
||||||
|
|
||||||
# Define all the database tables using the sqlalchemy declarative base
|
# Define all the database tables using the sqlalchemy declarative base
|
||||||
class User(TableDeclarativeBase):
|
class User(TableDeclarativeBase):
|
||||||
"""A Telegram user who used the bot at least once."""
|
"""A Telegram user who used the bot at least once."""
|
||||||
|
@ -91,17 +94,26 @@ class Product(TableDeclarativeBase):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.text()
|
return self.text()
|
||||||
|
|
||||||
def text(self, style:str="full", cart_qty:int=None):
|
def text(self, style: str="full", cart_qty: int=None):
|
||||||
"""Return the product details formatted with Telegram HTML. The image is omitted."""
|
"""Return the product details formatted with Telegram HTML. The image is omitted."""
|
||||||
if style == "short":
|
if style == "short":
|
||||||
return f"{cart_qty}x {escape(self.name)} - {str(Price(self.price) * cart_qty)}"
|
return f"{cart_qty}x {escape(self.name)} - {str(Price(self.price) * cart_qty)}"
|
||||||
elif style == "full":
|
elif style == "full":
|
||||||
return f"<b>{escape(self.name)}</b>\n" \
|
if self.stock is not None:
|
||||||
f"{escape(self.description)}\n" \
|
stock = strings.in_stock_format_string.format(quantity=self.stock)
|
||||||
f"<i>{strings.in_stock_format_string.format(quantity=self.stock) if self.stock is not None else ''}</i>\n" \
|
else:
|
||||||
f"{str(Price(self.price))}\n" \
|
stock = ''
|
||||||
f"<b>{strings.in_cart_format_string.format(quantity=cart_qty) if cart_qty is not None else ''}</b>"
|
if cart_qty is not None:
|
||||||
|
cart = strings.in_cart_format_string.format(quantity=cart_qty)
|
||||||
|
else:
|
||||||
|
cart = ''
|
||||||
|
return strings.order_format_string.format(name=escape(self.name),
|
||||||
|
description=escape(self.description),
|
||||||
|
stock=stock,
|
||||||
|
price=str(Price(self.price)),
|
||||||
|
cart=cart)
|
||||||
elif style == "image":
|
elif style == "image":
|
||||||
|
print("WARNING: image text is obsolete and shouldn't be used anymore")
|
||||||
return f"{escape(self.name)}\n" \
|
return f"{escape(self.name)}\n" \
|
||||||
f"{escape(self.description)}\n" \
|
f"{escape(self.description)}\n" \
|
||||||
f"{strings.in_stock_format_string.format(quantity=self.stock) if self.stock is not None else ''}\n" \
|
f"{strings.in_stock_format_string.format(quantity=self.stock) if self.stock is not None else ''}\n" \
|
||||||
|
@ -117,9 +129,9 @@ class Product(TableDeclarativeBase):
|
||||||
"""Send a message containing the product data."""
|
"""Send a message containing the product data."""
|
||||||
if self.image is None:
|
if self.image is None:
|
||||||
r = requests.get(f"https://api.telegram.org/bot{configloader.config['Telegram']['token']}/sendMessage",
|
r = requests.get(f"https://api.telegram.org/bot{configloader.config['Telegram']['token']}/sendMessage",
|
||||||
params={"chat_id": chat_id,
|
params={"chat_id": chat_id,
|
||||||
"text": self.text(),
|
"text": self.text(),
|
||||||
"parse_mode": "HTML"})
|
"parse_mode": "HTML"})
|
||||||
else:
|
else:
|
||||||
r = requests.post(f"https://api.telegram.org/bot{configloader.config['Telegram']['token']}/sendPhoto",
|
r = requests.post(f"https://api.telegram.org/bot{configloader.config['Telegram']['token']}/sendPhoto",
|
||||||
files={"photo": self.image},
|
files={"photo": self.image},
|
||||||
|
@ -224,7 +236,7 @@ class Order(TableDeclarativeBase):
|
||||||
# Refund reason: if null, product hasn't been refunded
|
# Refund reason: if null, product hasn't been refunded
|
||||||
refund_reason = Column(Text)
|
refund_reason = Column(Text)
|
||||||
# List of items in the order
|
# List of items in the order
|
||||||
items = relationship("OrderItem")
|
items: typing.List["OrderItem"] = relationship("OrderItem")
|
||||||
# Extra details specified by the purchasing user
|
# Extra details specified by the purchasing user
|
||||||
notes = Column(Text)
|
notes = Column(Text)
|
||||||
# Linked transaction
|
# Linked transaction
|
||||||
|
@ -280,4 +292,4 @@ class OrderItem(TableDeclarativeBase):
|
||||||
|
|
||||||
# If this script is ran as main, try to create all the tables in the database
|
# If this script is ran as main, try to create all the tables in the database
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
TableDeclarativeBase.metadata.create_all()
|
TableDeclarativeBase.metadata.create_all()
|
||||||
|
|
|
@ -14,6 +14,13 @@ in_stock_format_string = "{quantity} disponibili"
|
||||||
# Copies of a product in cart
|
# Copies of a product in cart
|
||||||
in_cart_format_string = "{quantity} nel carrello"
|
in_cart_format_string = "{quantity} nel carrello"
|
||||||
|
|
||||||
|
# Product information
|
||||||
|
product_format_string = "<b>{name}</b>\n" \
|
||||||
|
"{description}\n" \
|
||||||
|
"{stock}\n" \
|
||||||
|
"{price}\n" \
|
||||||
|
"<b>{cart}</b>"
|
||||||
|
|
||||||
# Order number, displayed in the order info
|
# Order number, displayed in the order info
|
||||||
order_number = "Ordine #{id}"
|
order_number = "Ordine #{id}"
|
||||||
|
|
||||||
|
|
6
utils.py
6
utils.py
|
@ -7,7 +7,7 @@ import typing
|
||||||
|
|
||||||
|
|
||||||
class Price:
|
class Price:
|
||||||
def __init__(self, value:typing.Union[int, float, str, "Price"]=0):
|
def __init__(self, value: typing.Union[int, float, str, "Price"]=0):
|
||||||
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)
|
||||||
|
@ -25,7 +25,9 @@ class Price:
|
||||||
return f"<Price of value {self.value}>"
|
return f"<Price of value {self.value}>"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return currency_format_string.format(symbol=currency_symbol, value="{0:.2f}".format(self.value / (10 ** int(config["Payments"]["currency_exp"]))))
|
return currency_format_string.format(symbol=currency_symbol,
|
||||||
|
value="{0:.2f}".format(
|
||||||
|
self.value / (10 ** int(config["Payments"]["currency_exp"]))))
|
||||||
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
|
@ -684,13 +684,15 @@ 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)),
|
self.bot.send_message(self.chat.id,
|
||||||
|
strings.edit_current_value.format(value=escape(product.description)),
|
||||||
parse_mode="HTML",
|
parse_mode="HTML",
|
||||||
reply_markup=cancel)
|
reply_markup=cancel)
|
||||||
# Wait for an answer
|
# Wait for an answer
|
||||||
description = self.__wait_for_regex(r"(.*)", cancellable=bool(product))
|
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,
|
||||||
parse_mode="HTML")
|
parse_mode="HTML")
|
||||||
# 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:
|
||||||
|
@ -717,6 +719,7 @@ class ChatWorker(threading.Thread):
|
||||||
# If a new product is being added...
|
# If a new product is being added...
|
||||||
if not product:
|
if not product:
|
||||||
# Create the db record for the product
|
# Create the db record for the product
|
||||||
|
# noinspection PyTypeChecker
|
||||||
product = db.Product(name=name,
|
product = db.Product(name=name,
|
||||||
description=description,
|
description=description,
|
||||||
price=int(price),
|
price=int(price),
|
||||||
|
|
Loading…
Reference in a new issue