1
Fork 0
mirror of https://github.com/Steffo99/greed.git synced 2024-11-22 05:54:18 +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 # greed
A framework for shops on Telegram A customizable Telegram shop bot

15
core.py
View file

@ -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

View file

@ -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

View file

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

View file

@ -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

View file

@ -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),