1
Fork 0
mirror of https://github.com/Steffo99/greed.git synced 2024-11-25 15:24:17 +00:00

Recover from corrupt repo

This commit is contained in:
Steffo 2018-01-10 11:29:02 +01:00
parent cf896a8549
commit c26621223d
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: C27544372FBB445D
5 changed files with 86 additions and 37 deletions

View file

@ -3,7 +3,7 @@
# Config file parameters # Config file parameters
[Config] [Config]
; Config file version. DO NOT EDIT THIS! ; Config file version. DO NOT EDIT THIS!
version = 7 version = 8
; Set this to no when you are done editing the file ; Set this to no when you are done editing the file
is_template = yes is_template = yes
@ -22,19 +22,24 @@ long_polling_timeout = 30
; The database engine you want to use. Refer to http://docs.sqlalchemy.org/en/latest/core/engines.html for the possible settings. ; The database engine you want to use. Refer to http://docs.sqlalchemy.org/en/latest/core/engines.html for the possible settings.
engine = sqlite:// engine = sqlite://
# Enabled payment methods # General payment settings
# To disable, leave the row empty
[Payment Methods]
# Cash payment is always enabled
# Credit card: get the token at @BotFather
credit_card_token = 123456789:YOUR_TOKEN_HERE_
[Payments] [Payments]
# Minimum wallet payment accepted
min_amount = 10
# Maximum wallet payment accepted
max_amount = 100
# ISO currency code # ISO currency code
currency = EUR currency = EUR
# Currency exp parameter. You can find that on https://core.telegram.org/bots/payments/currencies.json # Currency exp parameter. You can find that on https://core.telegram.org/bots/payments/currencies.json
currency_exp = 2 currency_exp = 2
# Credit card payment settings
[Credit Card]
# Provider token: get the token at @BotFather
credit_card_token = 123456789:YOUR_TOKEN_HERE_
# Minimum wallet payment accepted
min_amount = 10
# Maximum wallet payment accepted
max_amount = 100
# Require the name of the credit card owner
name_required = yes
# Require the email of the credit card owner
email_required = yes
# Require the phone number of the credit card owner
phone_required = yes

View file

@ -116,7 +116,7 @@ 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.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)

View file

@ -1,6 +1,6 @@
from sqlalchemy import create_engine, Column, ForeignKey, UniqueConstraint, CheckConstraint from sqlalchemy import create_engine, Column, ForeignKey, UniqueConstraint, CheckConstraint
from sqlalchemy import Integer, BigInteger, String, Numeric, Text from sqlalchemy import Integer, BigInteger, String, Numeric, Text
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
import configloader import configloader
import telegram import telegram
@ -28,7 +28,7 @@ class User(TableDeclarativeBase):
username = Column(String) username = Column(String)
# Current wallet credit # Current wallet credit
credit = Column(Numeric, nullable=False) credit = Column(Integer, nullable=False)
# Extra table parameters # Extra table parameters
__tablename__ = "users" __tablename__ = "users"
@ -65,7 +65,7 @@ class Product(TableDeclarativeBase):
# Product description # Product description
description = Column(Text) description = Column(Text)
# Product price, if null product is not for sale # Product price, if null product is not for sale
price = Column(Numeric) price = Column(Integer)
# Image filename # Image filename
image = Column(String) image = Column(String)
# Stock quantity, if null product has infinite stock # Stock quantity, if null product has infinite stock
@ -94,26 +94,32 @@ class Transaction(TableDeclarativeBase):
Wallet credit ISN'T calculated from these, but they can be used to recalculate it.""" Wallet credit ISN'T calculated from these, but they can be used to recalculate it."""
# The internal transaction ID # The internal transaction ID
transaction_id = Column(BigInteger, primary_key=True) transaction_id = Column(Integer, primary_key=True)
# The user whose credit is affected by this transaction # The user whose credit is affected by this transaction
user_id = Column(BigInteger, ForeignKey("users.user_id"), nullable=False) user_id = Column(BigInteger, ForeignKey("users.user_id"), nullable=False)
user = relationship("User")
# The value of this transaction. Can be both negative and positive. # The value of this transaction. Can be both negative and positive.
value = Column(Numeric, nullable=False) value = Column(Integer, nullable=False)
# Extra notes on the transaction # Extra notes on the transaction
notes = Column(Text) notes = Column(Text)
# Payment provider # Payment provider
provider = Column(String) provider = Column(String)
# Transaction ID supplied by Telegram
telegram_charge_id = Column(String)
# Transaction ID supplied by the payment provider # Transaction ID supplied by the payment provider
provider_id = Column(BigInteger) provider_charge_id = Column(String)
# Extra transaction data, may be required by the payment provider in case of a dispute # Extra transaction data, may be required by the payment provider in case of a dispute
payment_name = Column(String) payment_name = Column(String)
payment_address = Column(String) payment_phone = Column(String)
payment_email = Column(String) payment_email = Column(String)
# Order ID
order_id = Column(Integer)
# Extra table parameters # Extra table parameters
__tablename__ = "transactions" __tablename__ = "transactions"
__table_args__ = (UniqueConstraint("provider", "provider_id"),) __table_args__ = (UniqueConstraint("provider", "provider_charge_id"),)
def __str__(self): def __str__(self):
"""Return the correctly formatted transaction value""" """Return the correctly formatted transaction value"""
@ -128,17 +134,12 @@ class Transaction(TableDeclarativeBase):
return f"<Transaction {self.transaction_id} - User {self.user_id} {str(self)}>" return f"<Transaction {self.transaction_id} - User {self.user_id} {str(self)}>"
# TODO
# class Order(TableDeclarativeBase):
# """A product order."""
# pass
class Admin(TableDeclarativeBase): class Admin(TableDeclarativeBase):
"""A greed administrator with his permissions.""" """A greed administrator with his permissions."""
# The telegram id # The telegram id
user_id = Column(BigInteger, ForeignKey("users.user_id"), primary_key=True) user_id = Column(BigInteger, ForeignKey("users.user_id"), primary_key=True)
user = relationship("User")
# Permissions # Permissions
# TODO: unfinished # TODO: unfinished

View file

@ -31,7 +31,6 @@ conversation_expired = "🕐 Il bot non ha ricevuto messaggi per un po' di tempo
# User menu: order # User menu: order
menu_order = "🛍 Ordina" menu_order = "🛍 Ordina"
# User menu: order status # User menu: order status
menu_order_status = "❓ Stato ordini" menu_order_status = "❓ Stato ordini"

View file

@ -1,5 +1,7 @@
import threading import threading
import typing import typing
import uuid
import telegram import telegram
import strings import strings
import configloader import configloader
@ -28,8 +30,8 @@ class ChatWorker(threading.Thread):
# 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
self.user = self.session.query(db.User).filter(db.User.user_id == self.chat.id).one_or_none() self.user = None
self.admin = self.session.query(db.Admin).filter(db.Admin.user_id == self.chat.id).one_or_none() self.admin = None
# The sending pipe is stored in the ChatWorker class, allowing the forwarding of messages to the chat process # The sending pipe is stored in the ChatWorker class, allowing the forwarding of messages to the chat process
self.queue = queuem.Queue() self.queue = queuem.Queue()
# The current active invoice payload; reject all invoices with a different payload # The current active invoice payload; reject all invoices with a different payload
@ -40,6 +42,9 @@ class ChatWorker(threading.Thread):
# TODO: catch all the possible exceptions # TODO: catch all the possible exceptions
# Welcome the user to the bot # Welcome the user to the bot
self.bot.send_message(self.chat.id, strings.conversation_after_start) self.bot.send_message(self.chat.id, strings.conversation_after_start)
# Get the user db data from the users and admin tables
self.user = self.session.query(db.User).filter(db.User.user_id == self.chat.id).one_or_none()
self.admin = self.session.query(db.Admin).filter(db.Admin.user_id == self.chat.id).one_or_none()
# If the user isn't registered, create a new record and add it to the db # If the user isn't registered, create a new record and add it to the db
if self.user is None: if self.user is None:
# Create the new record # Create the new record
@ -116,17 +121,31 @@ class ChatWorker(threading.Thread):
return match.group(1) return match.group(1)
def __wait_for_precheckoutquery(self) -> telegram.PreCheckoutQuery: def __wait_for_precheckoutquery(self) -> telegram.PreCheckoutQuery:
"""Continue getting updates until a precheckoutquery is received.""" """Continue getting updates until a precheckoutquery is received.
The payload is checked by the core before forwarding the message."""
while True: while True:
# Get the next update # Get the next update
update = self.__receive_next_update() update = self.__receive_next_update()
# Ensure the update contains a precheckoutquery # Ensure the update contains a precheckoutquery
if update.pre_checkout_query is None: if update.pre_checkout_query is None:
continue continue
# TODO: something payload
# Return the precheckoutquery # Return the precheckoutquery
return update.pre_checkout_query return update.pre_checkout_query
def __wait_for_successfulpayment(self) -> telegram.SuccessfulPayment:
"""Continue getting updates until a successfulpayment is received."""
while True:
# Get the next update
update = self.__receive_next_update()
# Ensure the update contains a message
if update.message is None:
continue
# Ensure the message is a successfulpayment
if update.message.successful_payment is None:
continue
# Return the successfulpayment
return update.message.successful_payment
def __user_menu(self): def __user_menu(self):
"""Function called from the run method when the user is not an administrator. """Function called from the run method when the user is not an administrator.
Normal bot actions should be placed here.""" Normal bot actions should be placed here."""
@ -175,7 +194,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["Payment Methods"]["credit_card_token"] != "": if configloader.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)])
@ -224,17 +243,42 @@ class ChatWorker(threading.Thread):
self.bot.send_message(self.chat.id, strings.error_payment_amount_under_min.format(min_amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=configloader.config["Payments"]["min_amount"]))) self.bot.send_message(self.chat.id, strings.error_payment_amount_under_min.format(min_amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=configloader.config["Payments"]["min_amount"])))
continue continue
break break
# Set the invoice active invoice payload
self.invoice_payload = str(uuid.uuid4())
# The amount is valid, send the invoice # The amount is valid, send the invoice
self.bot.send_invoice(self.chat.id, self.bot.send_invoice(self.chat.id,
title=strings.payment_invoice_title, title=strings.payment_invoice_title,
description=strings.payment_invoice_description.format(amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=selection)), description=strings.payment_invoice_description.format(amount=strings.currency_format_string.format(symbol=strings.currency_symbol, value=selection)),
payload="temppayload", # TODO: how should I use the payload? payload=self.invoice_payload,
provider_token=configloader.config["Payment Methods"]["credit_card_token"], provider_token=configloader.config["Credit Card"]["credit_card_token"],
start_parameter="tempdeeplink", # TODO: no idea on how deeplinks should work start_parameter="tempdeeplink", # TODO: no idea on how deeplinks should work
currency=configloader.config["Payments"]["currency"], currency=configloader.config["Payments"]["currency"],
prices=[telegram.LabeledPrice(label=strings.payment_invoice_label, amount=int(selection * (10 ** int(configloader.config["Payments"]["currency_exp"]))))]) prices=[telegram.LabeledPrice(label=strings.payment_invoice_label, amount=int(selection * (10 ** int(configloader.config["Payments"]["currency_exp"]))))],
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")
# Wait for the invoice # Wait for the invoice
precheckoutquery = self.__wait_for_precheckoutquery() precheckoutquery = self.__wait_for_precheckoutquery()
# TODO: ensure the bot doesn't die here!
# Accept the checkout
self.bot.answer_pre_checkout_query(precheckoutquery.id, ok=True)
# Wait for the payment
successfulpayment = self.__wait_for_successfulpayment()
# Create a new database transaction
transaction = db.Transaction(user=self.user,
value=successfulpayment.total_amount,
provider="Credit Card",
telegram_charge_id=successfulpayment.telegram_payment_charge_id,
provider_charge_id=successfulpayment.provider_payment_charge_id)
if successfulpayment.order_info is not None:
transaction.payment_name = successfulpayment.order_info.name
transaction.payment_email = successfulpayment.order_info.email
transaction.payment_phone = successfulpayment.order_info.phone_number
# Add the credit to the user account
self.user.credit += successfulpayment.total_amount
# Add and commit the transaction
self.session.add(transaction)
self.session.commit()
def __bot_info(self): def __bot_info(self):
"""Send information about the bot.""" """Send information about the bot."""