1
Fork 0
mirror of https://github.com/Steffo99/greed.git synced 2024-10-16 13:47:27 +00:00

PEP8 and PyCharm fixes

This commit is contained in:
Steffo 2018-04-09 12:24:55 +02:00
parent c15ddabfd1
commit e8250cd64d
7 changed files with 50 additions and 25 deletions

View file

@ -1,2 +1,2 @@
# greed
A framework for shops on Telegram
A customizable Telegram shop bot

View file

@ -36,4 +36,4 @@ if template_version > int(config["Config"]["version"]):
# 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)
sys.exit(1)

17
core.py
View file

@ -1,11 +1,11 @@
import sys
import telegram
import time
import strings
import worker
import configloader
import utils
def main():
"""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
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
print("greed-bot is now starting!")
@ -68,7 +65,8 @@ def main():
# Ensure a worker exists for the chat and is alive
if receiving_worker is None or not receiving_worker.is_alive():
# 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
continue
# Forward the update to the worker
@ -97,10 +95,13 @@ def main():
# Forward the update to the corresponding worker
receiving_worker = chat_workers.get(update.pre_checkout_query.from_user.id)
# 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
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:
print(f"ERROR: pre_checkout_query expired before an answer could be sent")
# Go to the next update
@ -115,4 +116,4 @@ def main():
# Run the main function only in the main process
if __name__ == "__main__":
main()
main()

View file

@ -1,3 +1,5 @@
import typing
from sqlalchemy import create_engine, Column, ForeignKey, UniqueConstraint
from sqlalchemy import Integer, BigInteger, String, Text, LargeBinary, DateTime, Boolean
from sqlalchemy.orm import sessionmaker, relationship
@ -18,6 +20,7 @@ TableDeclarativeBase = declarative_base(bind=engine)
# Create a Session class able to initialize database sessions
Session = sessionmaker()
# Define all the database tables using the sqlalchemy declarative base
class User(TableDeclarativeBase):
"""A Telegram user who used the bot at least once."""
@ -91,17 +94,26 @@ class Product(TableDeclarativeBase):
def __str__(self):
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."""
if style == "short":
return f"{cart_qty}x {escape(self.name)} - {str(Price(self.price) * cart_qty)}"
elif style == "full":
return f"<b>{escape(self.name)}</b>\n" \
f"{escape(self.description)}\n" \
f"<i>{strings.in_stock_format_string.format(quantity=self.stock) if self.stock is not None else ''}</i>\n" \
f"{str(Price(self.price))}\n" \
f"<b>{strings.in_cart_format_string.format(quantity=cart_qty) if cart_qty is not None else ''}</b>"
if self.stock is not None:
stock = strings.in_stock_format_string.format(quantity=self.stock)
else:
stock = ''
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":
print("WARNING: image text is obsolete and shouldn't be used anymore")
return f"{escape(self.name)}\n" \
f"{escape(self.description)}\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."""
if self.image is None:
r = requests.get(f"https://api.telegram.org/bot{configloader.config['Telegram']['token']}/sendMessage",
params={"chat_id": chat_id,
"text": self.text(),
"parse_mode": "HTML"})
params={"chat_id": chat_id,
"text": self.text(),
"parse_mode": "HTML"})
else:
r = requests.post(f"https://api.telegram.org/bot{configloader.config['Telegram']['token']}/sendPhoto",
files={"photo": self.image},
@ -224,7 +236,7 @@ class Order(TableDeclarativeBase):
# Refund reason: if null, product hasn't been refunded
refund_reason = Column(Text)
# List of items in the order
items = relationship("OrderItem")
items: typing.List["OrderItem"] = relationship("OrderItem")
# Extra details specified by the purchasing user
notes = Column(Text)
# 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 __name__ == "__main__":
TableDeclarativeBase.metadata.create_all()
TableDeclarativeBase.metadata.create_all()

View file

@ -14,6 +14,13 @@ in_stock_format_string = "{quantity} disponibili"
# Copies of a product in cart
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 = "Ordine #{id}"

View file

@ -7,7 +7,7 @@ import typing
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):
# Keep the value as it is
self.value = int(value)
@ -25,7 +25,9 @@ class Price:
return f"<Price of value {self.value}>"
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):
return self.value

View file

@ -684,13 +684,15 @@ class ChatWorker(threading.Thread):
self.bot.send_message(self.chat.id, strings.ask_product_description)
# Display the current description if you're editing an existing 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",
reply_markup=cancel)
# Wait for an answer
description = self.__wait_for_regex(r"(.*)", cancellable=bool(product))
# 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")
# Display the current name if you're editing an existing product
if product:
@ -717,6 +719,7 @@ class ChatWorker(threading.Thread):
# If a new product is being added...
if not product:
# Create the db record for the product
# noinspection PyTypeChecker
product = db.Product(name=name,
description=description,
price=int(price),