Format with yapf
This commit is contained in:
parent
435787ad93
commit
7c1ff1ff37
4 changed files with 131 additions and 195 deletions
|
|
@ -3,13 +3,10 @@ from lnbits.db import Database
|
|||
|
||||
db = Database("ext_twitchalerts")
|
||||
|
||||
twitchalerts_ext: Blueprint = Blueprint(
|
||||
"twitchalerts",
|
||||
__name__,
|
||||
static_folder="static",
|
||||
template_folder="templates"
|
||||
)
|
||||
|
||||
twitchalerts_ext: Blueprint = Blueprint("twitchalerts",
|
||||
__name__,
|
||||
static_folder="static",
|
||||
template_folder="templates")
|
||||
|
||||
from .views_api import * # noqa
|
||||
from .views import * # noqa
|
||||
|
|
|
|||
|
|
@ -67,17 +67,7 @@ async def create_donation(
|
|||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(
|
||||
id,
|
||||
wallet,
|
||||
name,
|
||||
message,
|
||||
cur_code,
|
||||
sats,
|
||||
amount,
|
||||
service,
|
||||
posted
|
||||
),
|
||||
(id, wallet, name, message, cur_code, sats, amount, service, posted),
|
||||
)
|
||||
return await get_donation(id)
|
||||
|
||||
|
|
@ -89,48 +79,35 @@ async def post_donation(donation_id: str) -> tuple:
|
|||
"""
|
||||
donation = await get_donation(donation_id)
|
||||
if not donation:
|
||||
return (
|
||||
jsonify({"message": "Donation not found!"}),
|
||||
HTTPStatus.BAD_REQUEST
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"Donation not found!"}), HTTPStatus.BAD_REQUEST)
|
||||
if donation.posted:
|
||||
return (
|
||||
jsonify({"message": "Donation has already been posted!"}),
|
||||
HTTPStatus.BAD_REQUEST
|
||||
)
|
||||
return (jsonify({"message": "Donation has already been posted!"}),
|
||||
HTTPStatus.BAD_REQUEST)
|
||||
service = await get_service(donation.service)
|
||||
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,
|
||||
"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
|
||||
)
|
||||
return (jsonify({"message": "StreamElements not yet supported!"}),
|
||||
HTTPStatus.BAD_REQUEST)
|
||||
else:
|
||||
return (
|
||||
jsonify({"message": "Unsopported servicename"}),
|
||||
HTTPStatus.BAD_REQUEST
|
||||
)
|
||||
await db.execute(
|
||||
"UPDATE Donations SET posted = 1 WHERE id = ?",
|
||||
(donation_id,)
|
||||
)
|
||||
return (
|
||||
jsonify(response.json()),
|
||||
status
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"Unsopported servicename"}), HTTPStatus.BAD_REQUEST)
|
||||
await db.execute("UPDATE Donations SET posted = 1 WHERE id = ?",
|
||||
(donation_id, ))
|
||||
return (jsonify(response.json()), status)
|
||||
|
||||
|
||||
async def create_service(
|
||||
|
|
@ -182,24 +159,18 @@ async def get_service(service_id: int,
|
|||
streamer via typos like 2 -> 3.
|
||||
"""
|
||||
if by_state:
|
||||
row = await db.fetchone(
|
||||
"SELECT * FROM Services WHERE state = ?",
|
||||
(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,)
|
||||
)
|
||||
row = await db.fetchone("SELECT * FROM Services WHERE id = ?",
|
||||
(service_id, ))
|
||||
return Service.from_row(row) if row else None
|
||||
|
||||
|
||||
async def get_services(wallet_id: str) -> Optional[list]:
|
||||
"""Return all services belonging assigned to the wallet_id"""
|
||||
rows = await db.fetchall(
|
||||
"SELECT * FROM Services WHERE wallet = ?",
|
||||
(wallet_id,)
|
||||
)
|
||||
rows = await db.fetchall("SELECT * FROM Services WHERE wallet = ?",
|
||||
(wallet_id, ))
|
||||
return [Service.from_row(row) for row in rows] if rows else None
|
||||
|
||||
|
||||
|
|
@ -237,49 +208,40 @@ async def service_add_token(service_id, token):
|
|||
return False
|
||||
await db.execute(
|
||||
"UPDATE Services SET authenticated = 1, token = ? where id = ?",
|
||||
(token, service_id,),
|
||||
(
|
||||
token,
|
||||
service_id,
|
||||
),
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
async def delete_service(service_id: int) -> None:
|
||||
"""Delete a Service and all corresponding Donations"""
|
||||
await db.execute(
|
||||
"DELETE FROM Services WHERE id = ?",
|
||||
(service_id,)
|
||||
)
|
||||
rows = await db.fetchall(
|
||||
"SELECT * FROM Donations WHERE service = ?",
|
||||
(service_id,)
|
||||
)
|
||||
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"])
|
||||
|
||||
|
||||
async def get_donation(donation_id: str) -> Optional[Donation]:
|
||||
"""Return a Donation"""
|
||||
row = await db.fetchone(
|
||||
"SELECT * FROM Donations WHERE id = ?",
|
||||
(donation_id,)
|
||||
)
|
||||
row = await db.fetchone("SELECT * FROM Donations WHERE id = ?",
|
||||
(donation_id, ))
|
||||
return Donation.from_row(row) if row else None
|
||||
|
||||
|
||||
async def get_donations(wallet_id: str) -> Optional[list]:
|
||||
"""Return all Donations assigned to wallet_id"""
|
||||
rows = await db.fetchall(
|
||||
"SELECT * FROM Donations WHERE wallet = ?",
|
||||
(wallet_id,)
|
||||
)
|
||||
rows = await db.fetchall("SELECT * FROM Donations WHERE wallet = ?",
|
||||
(wallet_id, ))
|
||||
return [Donation.from_row(row) for row in rows] if rows else None
|
||||
|
||||
|
||||
async def delete_donation(donation_id: str) -> None:
|
||||
"""Delete a Donation and its corresponding statspay charge"""
|
||||
await db.execute(
|
||||
"DELETE FROM Donations WHERE id = ?",
|
||||
(donation_id,)
|
||||
)
|
||||
await db.execute("DELETE FROM Donations WHERE id = ?", (donation_id, ))
|
||||
await delete_charge(donation_id)
|
||||
|
||||
|
||||
|
|
@ -289,7 +251,7 @@ async def update_donation(donation_id: str, **kwargs) -> Donation:
|
|||
await db.execute(f"UPDATE Donations SET {q} WHERE id = ?",
|
||||
(*kwargs.values(), donation_id))
|
||||
row = await db.fetchone("SELECT * FROM Donations WHERE id = ?",
|
||||
(donation_id,))
|
||||
(donation_id, ))
|
||||
assert row, "Newly updated donation couldn't be retrieved"
|
||||
return Donation(**row)
|
||||
|
||||
|
|
@ -300,6 +262,6 @@ async def update_service(service_id: str, **kwargs) -> Donation:
|
|||
await db.execute(f"UPDATE Services SET {q} WHERE id = ?",
|
||||
(*kwargs.values(), service_id))
|
||||
row = await db.fetchone("SELECT * FROM Services WHERE id = ?",
|
||||
(service_id,))
|
||||
(service_id, ))
|
||||
assert row, "Newly updated service couldn't be retrieved"
|
||||
return Service(**row)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
async def m001_initial(db):
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
await db.execute("""
|
||||
CREATE TABLE IF NOT EXISTS Services (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
state TEXT NOT NULL,
|
||||
|
|
@ -14,11 +13,9 @@ async def m001_initial(db):
|
|||
authenticated BOOLEAN NOT NULL,
|
||||
token TEXT
|
||||
);
|
||||
"""
|
||||
)
|
||||
""")
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
await db.execute("""
|
||||
CREATE TABLE IF NOT EXISTS Donations (
|
||||
id TEXT PRIMARY KEY,
|
||||
wallet TEXT NOT NULL,
|
||||
|
|
@ -31,5 +28,4 @@ async def m001_initial(db):
|
|||
posted BOOLEAN NOT NULL,
|
||||
FOREIGN KEY(service) REFERENCES Services(id)
|
||||
);
|
||||
"""
|
||||
)
|
||||
""")
|
||||
|
|
|
|||
|
|
@ -6,22 +6,11 @@ from lnbits.core.crud import get_wallet, get_user
|
|||
from lnbits.utils.exchange_rates import btc_price
|
||||
|
||||
from . import twitchalerts_ext
|
||||
from .crud import (
|
||||
get_charge_details,
|
||||
get_service_redirect_uri,
|
||||
create_donation,
|
||||
post_donation,
|
||||
get_donation,
|
||||
get_donations,
|
||||
delete_donation,
|
||||
create_service,
|
||||
get_service,
|
||||
get_services,
|
||||
authenticate_service,
|
||||
update_donation,
|
||||
update_service,
|
||||
delete_service
|
||||
)
|
||||
from .crud import (get_charge_details, get_service_redirect_uri,
|
||||
create_donation, post_donation, get_donation, get_donations,
|
||||
delete_donation, create_service, get_service, get_services,
|
||||
authenticate_service, update_donation, update_service,
|
||||
delete_service)
|
||||
from ..satspay.crud import create_charge, get_charge
|
||||
|
||||
|
||||
|
|
@ -29,14 +18,30 @@ from ..satspay.crud import create_charge, get_charge
|
|||
@api_check_wallet_key("invoice")
|
||||
@api_validate_post_request(
|
||||
schema={
|
||||
"twitchuser": {"type": "string", "required": True},
|
||||
"client_id": {"type": "string", "required": True},
|
||||
"client_secret": {"type": "string", "required": True},
|
||||
"wallet": {"type": "string", "required": True},
|
||||
"servicename": {"type": "string", "required": True},
|
||||
"onchain": {"type": "string"}
|
||||
}
|
||||
)
|
||||
"twitchuser": {
|
||||
"type": "string",
|
||||
"required": True
|
||||
},
|
||||
"client_id": {
|
||||
"type": "string",
|
||||
"required": True
|
||||
},
|
||||
"client_secret": {
|
||||
"type": "string",
|
||||
"required": True
|
||||
},
|
||||
"wallet": {
|
||||
"type": "string",
|
||||
"required": True
|
||||
},
|
||||
"servicename": {
|
||||
"type": "string",
|
||||
"required": True
|
||||
},
|
||||
"onchain": {
|
||||
"type": "string"
|
||||
}
|
||||
})
|
||||
async def api_create_service():
|
||||
"""Create a service, which holds data about how/where to post donations"""
|
||||
service = await create_service(**g.data)
|
||||
|
|
@ -64,15 +69,12 @@ async def api_get_access(service_id):
|
|||
}
|
||||
endpoint_url = "https://streamlabs.com/api/v1.0/authorize/?"
|
||||
querystring = "&".join(
|
||||
[f"{key}={value}" for key, value in params.items()]
|
||||
)
|
||||
[f"{key}={value}" for key, value in params.items()])
|
||||
redirect_url = endpoint_url + querystring
|
||||
return redirect(redirect_url)
|
||||
else:
|
||||
return (
|
||||
jsonify({"message": "Service does not exist!"}),
|
||||
HTTPStatus.BAD_REQUEST
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"Service does not exist!"}), HTTPStatus.BAD_REQUEST)
|
||||
|
||||
|
||||
@twitchalerts_ext.route("/api/v1/authenticate/<service_id>", methods=["GET"])
|
||||
|
|
@ -86,31 +88,36 @@ async def api_authenticate_service(service_id):
|
|||
state = request.args.get('state')
|
||||
service = await get_service(service_id)
|
||||
if service.state != state:
|
||||
return (
|
||||
jsonify({"message": "State doesn't match!"}),
|
||||
HTTPStatus.BAD_Request
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"State doesn't match!"}), HTTPStatus.BAD_Request)
|
||||
redirect_uri = request.scheme + "://" + request.headers["Host"]
|
||||
redirect_uri += f"/twitchalerts/api/v1/authenticate/{service_id}"
|
||||
url, success = await authenticate_service(service_id, code, redirect_uri)
|
||||
if success:
|
||||
return redirect(url)
|
||||
else:
|
||||
return (
|
||||
jsonify({"message": "Service already authenticated!"}),
|
||||
HTTPStatus.BAD_REQUEST
|
||||
)
|
||||
return (jsonify({"message": "Service already authenticated!"}),
|
||||
HTTPStatus.BAD_REQUEST)
|
||||
|
||||
|
||||
@twitchalerts_ext.route("/api/v1/donations", methods=["POST"])
|
||||
@api_validate_post_request(
|
||||
schema={
|
||||
"name": {"type": "string"},
|
||||
"sats": {"type": "integer", "required": True},
|
||||
"service": {"type": "integer", "required": True},
|
||||
"message": {"type": "string"}
|
||||
}
|
||||
)
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"sats": {
|
||||
"type": "integer",
|
||||
"required": True
|
||||
},
|
||||
"service": {
|
||||
"type": "integer",
|
||||
"required": True
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
})
|
||||
async def api_create_donation():
|
||||
"""Take data from donation form and return satspay charge"""
|
||||
# Currency is hardcoded while frotnend is limited
|
||||
|
|
@ -119,7 +126,7 @@ async def api_create_donation():
|
|||
message = g.data.get("message", "")
|
||||
# Fiat amount is calculated here while frontend is limited
|
||||
price = await btc_price(cur_code)
|
||||
amount = sats * (10 ** (-8)) * price
|
||||
amount = sats * (10**(-8)) * price
|
||||
webhook_base = request.scheme + "://" + request.headers["Host"]
|
||||
service_id = g.data["service"]
|
||||
service = await get_service(service_id)
|
||||
|
|
@ -143,18 +150,16 @@ async def api_create_donation():
|
|||
amount=amount,
|
||||
service=g.data["service"],
|
||||
)
|
||||
return (
|
||||
jsonify({"redirect_url": f"/satspay/{charge.id}"}),
|
||||
HTTPStatus.OK
|
||||
)
|
||||
return (jsonify({"redirect_url": f"/satspay/{charge.id}"}), HTTPStatus.OK)
|
||||
|
||||
|
||||
@twitchalerts_ext.route("/api/v1/postdonation", methods=["POST"])
|
||||
@api_validate_post_request(
|
||||
schema={
|
||||
"id": {"type": "string", "required": True},
|
||||
}
|
||||
)
|
||||
@api_validate_post_request(schema={
|
||||
"id": {
|
||||
"type": "string",
|
||||
"required": True
|
||||
},
|
||||
})
|
||||
async def api_post_donation():
|
||||
"""Post a paid donation to Stremalabs/StreamElements.
|
||||
|
||||
|
|
@ -165,10 +170,8 @@ async def api_post_donation():
|
|||
if charge and charge.paid:
|
||||
return await post_donation(donation_id)
|
||||
else:
|
||||
return (
|
||||
jsonify({"message": "Not a paid charge!"}),
|
||||
HTTPStatus.BAD_REQUEST
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"Not a paid charge!"}), HTTPStatus.BAD_REQUEST)
|
||||
|
||||
|
||||
@twitchalerts_ext.route("/api/v1/services", methods=["GET"])
|
||||
|
|
@ -181,9 +184,8 @@ async def api_get_services():
|
|||
new_services = await get_services(wallet_id)
|
||||
services += new_services if new_services else []
|
||||
return (
|
||||
jsonify([
|
||||
service._asdict() for service in services
|
||||
] if services else []),
|
||||
jsonify([service._asdict()
|
||||
for service in services] if services else []),
|
||||
HTTPStatus.OK,
|
||||
)
|
||||
|
||||
|
|
@ -200,9 +202,8 @@ async def api_get_donations():
|
|||
new_donations = await get_donations(wallet_id)
|
||||
donations += new_donations if new_donations else []
|
||||
return (
|
||||
jsonify([
|
||||
donation._asdict() for donation in donations
|
||||
] if donations else []),
|
||||
jsonify([donation._asdict()
|
||||
for donation in donations] if donations else []),
|
||||
HTTPStatus.OK,
|
||||
)
|
||||
|
||||
|
|
@ -215,23 +216,17 @@ async def api_update_donation(donation_id=None):
|
|||
donation = await get_donation(donation_id)
|
||||
|
||||
if not donation:
|
||||
return (
|
||||
jsonify({"message": "Donation does not exist."}),
|
||||
HTTPStatus.NOT_FOUND
|
||||
)
|
||||
return (jsonify({"message": "Donation does not exist."}),
|
||||
HTTPStatus.NOT_FOUND)
|
||||
|
||||
if donation.wallet != g.wallet.id:
|
||||
return (
|
||||
jsonify({"message": "Not your donation."}),
|
||||
HTTPStatus.FORBIDDEN
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"Not your donation."}), HTTPStatus.FORBIDDEN)
|
||||
|
||||
donation = await update_donation(donation_id, **g.data)
|
||||
else:
|
||||
return (
|
||||
jsonify({"message": "No donation ID specified"}),
|
||||
HTTPStatus.BAD_REQUEST
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"No donation ID specified"}), HTTPStatus.BAD_REQUEST)
|
||||
return jsonify(donation._asdict()), HTTPStatus.CREATED
|
||||
|
||||
|
||||
|
|
@ -243,23 +238,17 @@ async def api_update_service(service_id=None):
|
|||
service = await get_service(service_id)
|
||||
|
||||
if not service:
|
||||
return (
|
||||
jsonify({"message": "Service does not exist."}),
|
||||
HTTPStatus.NOT_FOUND
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"Service does not exist."}), HTTPStatus.NOT_FOUND)
|
||||
|
||||
if service.wallet != g.wallet.id:
|
||||
return (
|
||||
jsonify({"message": "Not your service."}),
|
||||
HTTPStatus.FORBIDDEN
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"Not your service."}), HTTPStatus.FORBIDDEN)
|
||||
|
||||
service = await update_service(service_id, **g.data)
|
||||
else:
|
||||
return (
|
||||
jsonify({"message": "No service ID specified"}),
|
||||
HTTPStatus.BAD_REQUEST
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"No service ID specified"}), HTTPStatus.BAD_REQUEST)
|
||||
return jsonify(service._asdict()), HTTPStatus.CREATED
|
||||
|
||||
|
||||
|
|
@ -269,15 +258,11 @@ async def api_delete_donation(donation_id):
|
|||
"""Delete the donation with the given donation_id"""
|
||||
donation = await get_donation(donation_id)
|
||||
if not donation:
|
||||
return (
|
||||
jsonify({"message": "No donation with this ID!"}),
|
||||
HTTPStatus.NOT_FOUND
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"No donation with this ID!"}), HTTPStatus.NOT_FOUND)
|
||||
if donation.wallet != g.wallet.id:
|
||||
return (
|
||||
jsonify({"message": "Not authorized to delete this donation!"}),
|
||||
HTTPStatus.FORBIDDEN
|
||||
)
|
||||
return (jsonify({"message": "Not authorized to delete this donation!"
|
||||
}), HTTPStatus.FORBIDDEN)
|
||||
await delete_donation(donation_id)
|
||||
|
||||
return "", HTTPStatus.NO_CONTENT
|
||||
|
|
@ -289,15 +274,11 @@ async def api_delete_service(service_id):
|
|||
"""Delete the service with the given service_id"""
|
||||
service = await get_service(service_id)
|
||||
if not service:
|
||||
return (
|
||||
jsonify({"message": "No service with this ID!"}),
|
||||
HTTPStatus.NOT_FOUND
|
||||
)
|
||||
return (jsonify({"message":
|
||||
"No service with this ID!"}), HTTPStatus.NOT_FOUND)
|
||||
if service.wallet != g.wallet.id:
|
||||
return (
|
||||
jsonify({"message": "Not authorized to delete this service!"}),
|
||||
HTTPStatus.FORBIDDEN
|
||||
)
|
||||
return (jsonify({"message": "Not authorized to delete this service!"}),
|
||||
HTTPStatus.FORBIDDEN)
|
||||
await delete_service(service_id)
|
||||
|
||||
return "", HTTPStatus.NO_CONTENT
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue