lnbits-legend/lnbits/extensions/twitchalerts/crud.py

268 lines
7.2 KiB
Python
Raw Normal View History

2021-06-22 13:19:22 +02:00
from . import db
2021-06-22 16:42:50 +02:00
from .models import Donation, Service
2021-06-22 13:19:22 +02:00
from ..satspay.crud import delete_charge
import httpx
2021-06-24 09:59:11 +02:00
from http import HTTPStatus
from quart import jsonify
2021-06-22 13:19:22 +02:00
from typing import Optional
2021-06-22 18:05:07 +02:00
from lnbits.helpers import urlsafe_short_hash
2021-06-22 13:19:22 +02:00
from lnbits.core.crud import get_wallet
async def get_charge_details(service_id):
details = {
"time": 1440,
2021-06-22 13:19:22 +02:00
}
2021-06-24 10:20:38 +02:00
service = await get_service(service_id)
2021-06-22 13:19:22 +02:00
wallet_id = service.wallet
wallet = await get_wallet(wallet_id)
user = wallet.user
details["user"] = user
details["lnbitswallet"] = wallet_id
details["onchainwallet"] = service.onchain
return details
2021-06-22 13:19:22 +02:00
async def create_donation(
id: str,
2021-06-28 17:18:35 +02:00
wallet: str,
2021-06-22 13:19:22 +02:00
cur_code: str,
sats: int,
amount: float,
service: int,
2021-06-24 09:59:11 +02:00
name: str = "Anonymous",
message: str = "",
2021-06-22 13:19:22 +02:00
posted: bool = False,
2021-06-22 16:42:50 +02:00
) -> Donation:
2021-06-22 13:19:22 +02:00
await db.execute(
"""
INSERT INTO Donations (
id,
2021-06-28 17:18:35 +02:00
wallet,
2021-06-22 13:19:22 +02:00
name,
2021-06-24 09:59:11 +02:00
message,
2021-06-22 13:19:22 +02:00
cur_code,
sats,
amount,
service,
posted
)
2021-06-28 17:18:35 +02:00
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
2021-06-22 13:19:22 +02:00
""",
(
id,
2021-06-28 17:18:35 +02:00
wallet,
2021-06-22 13:19:22 +02:00
name,
2021-06-24 09:59:11 +02:00
message,
2021-06-22 13:19:22 +02:00
cur_code,
sats,
amount,
service,
posted
),
)
return await get_donation(id)
2021-06-24 09:59:11 +02:00
async def post_donation(donation_id: str) -> tuple:
2021-06-22 13:19:22 +02:00
donation = await get_donation(donation_id)
2021-06-24 09:59:11 +02:00
if not donation:
return (
jsonify({"message": "Donation not found!"}),
HTTPStatus.BAD_REQUEST
)
2021-06-22 13:19:22 +02:00
if donation.posted:
2021-06-24 09:59:11 +02:00
return (
jsonify({"message": "Donation has already been posted!"}),
HTTPStatus.BAD_REQUEST
)
2021-06-22 13:19:22 +02:00
service = await get_service(donation.service)
2021-06-24 09:59:11 +02:00
if service.servicename == "Streamlabs":
url = "https://streamlabs.com/api/v1.0/donations"
data = {
"name": donation.name,
"message": donation.message,
"identifier": "LNbits",
"amount": donation.amount,
"currency": donation.cur_code.upper(),
"access_token": service.token,
}
async with httpx.AsyncClient() as client:
response = await client.post(url, data=data)
print(response.json())
status = [s for s in list(HTTPStatus) if s == response.status_code][0]
elif service.servicename == "StreamElements":
return (
jsonify({"message": "StreamElements not yet supported!"}),
HTTPStatus.BAD_REQUEST
)
else:
return (
jsonify({"message": "Unsopported servicename"}),
HTTPStatus.BAD_REQUEST
)
2021-06-22 13:19:22 +02:00
await db.execute(
"UPDATE Donations SET posted = 1 WHERE id = ?",
(donation_id,)
)
2021-06-24 09:59:11 +02:00
return (
jsonify(response.json()),
status
)
2021-06-22 13:19:22 +02:00
async def create_service(
twitchuser: str,
client_id: str,
client_secret: str,
wallet: str,
servicename: str,
2021-06-22 18:05:07 +02:00
state: str = None,
2021-06-22 13:19:22 +02:00
onchain: str = None,
2021-06-22 16:42:50 +02:00
) -> Service:
2021-06-22 13:19:22 +02:00
result = await db.execute(
"""
INSERT INTO Services (
twitchuser,
client_id,
client_secret,
wallet,
servicename,
authenticated,
2021-06-22 18:05:07 +02:00
state,
2021-06-22 13:19:22 +02:00
onchain
)
2021-06-22 18:05:07 +02:00
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
2021-06-22 13:19:22 +02:00
""",
(
twitchuser,
client_id,
client_secret,
wallet,
servicename,
False,
2021-06-22 18:05:07 +02:00
urlsafe_short_hash(),
2021-06-22 13:19:22 +02:00
onchain,
),
)
service_id = result._result_proxy.lastrowid
service = await get_service(service_id)
return service
2021-06-28 19:02:47 +02:00
async def get_service(service_id: int,
by_state: str = None) -> Optional[Service]:
if by_state:
row = await db.fetchone(
"SELECT * FROM Services WHERE state = ?",
(by_state,)
)
else:
row = await db.fetchone(
"SELECT * FROM Services WHERE id = ?",
(service_id,)
)
2021-06-22 16:42:50 +02:00
return Service.from_row(row) if row else None
2021-06-22 13:19:22 +02:00
2021-06-28 09:06:13 +02:00
async def get_services(wallet_id: str) -> Optional[list]:
rows = await db.fetchall(
"SELECT * FROM Services WHERE wallet = ?",
(wallet_id,)
)
return [Service.from_row(row) for row in rows] if rows else None
2021-06-22 13:19:22 +02:00
async def authenticate_service(service_id, code, redirect_uri):
# The API token is passed in the querystring as 'code'
service = await get_service(service_id)
wallet = await get_wallet(service.wallet)
user = wallet.user
url = "https://streamlabs.com/api/v1.0/token"
data = {
"grant_type": "authorization_code",
"code": code,
"client_id": service.client_id,
"client_secret": service.client_secret,
"redirect_uri": redirect_uri,
}
print(data)
async with httpx.AsyncClient() as client:
response = (await client.post(url, data=data)).json()
print(response)
token = response['access_token']
2021-06-23 09:53:10 +02:00
success = await service_add_token(service_id, token)
return f"/twitchalerts/?usr={user}", success
2021-06-22 13:19:22 +02:00
async def service_add_token(service_id, token):
2021-06-23 09:53:10 +02:00
if (await get_service(service_id)).authenticated:
return False
2021-06-24 10:20:38 +02:00
await db.execute(
2021-06-23 09:53:10 +02:00
"UPDATE Services SET authenticated = 1, token = ? where id = ?",
2021-06-22 13:19:22 +02:00
(token, service_id,),
)
2021-06-23 09:53:10 +02:00
return True
2021-06-22 13:19:22 +02:00
async def delete_service(service_id: int) -> None:
await db.execute(
"DELETE FROM Services WHERE id = ?",
(service_id,)
)
rows = await db.fetchall(
"SELECT * FROM Donations WHERE service = ?",
(service_id,)
)
for row in rows:
await delete_donation(row["id"])
2021-06-22 16:42:50 +02:00
async def get_donation(donation_id: str) -> Optional[Donation]:
2021-06-22 13:19:22 +02:00
row = await db.fetchone(
"SELECT * FROM Donations WHERE id = ?",
(donation_id,)
)
2021-06-22 16:42:50 +02:00
return Donation.from_row(row) if row else None
2021-06-22 13:19:22 +02:00
2021-06-28 09:06:13 +02:00
async def get_donations(wallet_id: str) -> Optional[list]:
2021-06-28 17:18:35 +02:00
rows = await db.fetchall(
"SELECT * FROM Donations WHERE wallet = ?",
(wallet_id,)
)
2021-06-28 09:06:13 +02:00
return [Donation.from_row(row) for row in rows] if rows else None
2021-06-22 13:19:22 +02:00
async def delete_donation(donation_id: str) -> None:
await db.execute(
2021-06-22 16:42:50 +02:00
"DELETE FROM Donations WHERE id = ?",
2021-06-22 13:19:22 +02:00
(donation_id,)
)
await delete_charge(donation_id)
2021-06-28 17:18:35 +02:00
async def update_donation(donation_id: str, **kwargs) -> Donation:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
2021-06-28 18:18:52 +02:00
await db.execute(f"UPDATE Donations SET {q} WHERE id = ?",
(*kwargs.values(), donation_id))
2021-06-28 17:18:35 +02:00
row = await db.fetchone("SELECT * FROM Donations WHERE id = ?",
(donation_id,))
assert row, "Newly updated donation couldn't be retrieved"
return Donation(**row)
async def update_service(service_id: str, **kwargs) -> Donation:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
2021-06-28 18:18:52 +02:00
await db.execute(f"UPDATE Services SET {q} WHERE id = ?",
(*kwargs.values(), service_id))
2021-06-28 17:18:35 +02:00
row = await db.fetchone("SELECT * FROM Services WHERE id = ?",
(service_id,))
assert row, "Newly updated service couldn't be retrieved"
return Service(**row)