diff --git a/lnbits/extensions/twitchalerts/README.md b/lnbits/extensions/twitchalerts/README.md
index 5bc1369d6..a55ed4a9e 100644
--- a/lnbits/extensions/twitchalerts/README.md
+++ b/lnbits/extensions/twitchalerts/README.md
@@ -5,7 +5,6 @@ The TwitchAlerts extension allows you to integrate Bitcoin Lightning (and on-cha
Try to include an image
-
curl -H "Content-type: application/json" -X POST https://YOUR-LNBITS/YOUR-EXTENSION/api/v1/EXAMPLE -d '{"amount":"100","memo":"TwitchAlerts"}' -H "X-Api-Key: YOUR_WALLET-ADMIN/INVOICE-KEY"
diff --git a/lnbits/extensions/twitchalerts/__init__.py b/lnbits/extensions/twitchalerts/__init__.py
index e8ab01455..e8ba90e1e 100644
--- a/lnbits/extensions/twitchalerts/__init__.py
+++ b/lnbits/extensions/twitchalerts/__init__.py
@@ -3,10 +3,9 @@ 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
diff --git a/lnbits/extensions/twitchalerts/crud.py b/lnbits/extensions/twitchalerts/crud.py
index 250185c68..e59d5696b 100644
--- a/lnbits/extensions/twitchalerts/crud.py
+++ b/lnbits/extensions/twitchalerts/crud.py
@@ -79,11 +79,12 @@ 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"
@@ -100,13 +101,13 @@ async def post_donation(donation_id: str) -> tuple:
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({"message": "Unsopported servicename"}), HTTPStatus.BAD_REQUEST)
+ await db.execute("UPDATE Donations SET posted = 1 WHERE id = ?", (donation_id,))
return (jsonify(response.json()), status)
@@ -150,8 +151,7 @@ async def create_service(
return service
-async def get_service(service_id: int,
- by_state: str = None) -> Optional[Service]:
+async def get_service(service_id: int, by_state: str = None) -> Optional[Service]:
"""Return a service either by ID or, available, by state
Each Service's donation page is reached through its "state" hash
@@ -159,18 +159,15 @@ 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
@@ -192,7 +189,7 @@ async def authenticate_service(service_id, code, redirect_uri):
async with httpx.AsyncClient() as client:
response = (await client.post(url, data=data)).json()
print(response)
- token = response['access_token']
+ token = response["access_token"]
success = await service_add_token(service_id, token)
return f"/twitchalerts/?usr={user}", success
@@ -218,40 +215,37 @@ async def service_add_token(service_id, token):
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)
async def update_donation(donation_id: str, **kwargs) -> Donation:
"""Update a Donation"""
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
- 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, ))
+ 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,))
assert row, "Newly updated donation couldn't be retrieved"
return Donation(**row)
@@ -259,9 +253,9 @@ async def update_donation(donation_id: str, **kwargs) -> Donation:
async def update_service(service_id: str, **kwargs) -> Donation:
"""Update a service"""
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
- 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, ))
+ 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,))
assert row, "Newly updated service couldn't be retrieved"
return Service(**row)
diff --git a/lnbits/extensions/twitchalerts/migrations.py b/lnbits/extensions/twitchalerts/migrations.py
index a70b81bf0..64d75a8d4 100644
--- a/lnbits/extensions/twitchalerts/migrations.py
+++ b/lnbits/extensions/twitchalerts/migrations.py
@@ -1,6 +1,7 @@
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,
@@ -13,9 +14,11 @@ 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,
@@ -28,4 +31,5 @@ async def m001_initial(db):
posted BOOLEAN NOT NULL,
FOREIGN KEY(service) REFERENCES Services(id)
);
- """)
+ """
+ )
diff --git a/lnbits/extensions/twitchalerts/models.py b/lnbits/extensions/twitchalerts/models.py
index 0467e6aca..20923ebbe 100644
--- a/lnbits/extensions/twitchalerts/models.py
+++ b/lnbits/extensions/twitchalerts/models.py
@@ -6,6 +6,7 @@ class Donation(NamedTuple):
"""A Donation simply contains all the necessary information about a
user's donation to a streamer
"""
+
id: str # This ID always corresponds to a satspay charge ID
wallet: str
name: str # Name of the donor
@@ -26,6 +27,7 @@ class Service(NamedTuple):
Currently, Streamlabs is the only supported Service.
"""
+
id: int
state: str # A random hash used during authentication
twitchuser: str # The Twitch streamer's username
diff --git a/lnbits/extensions/twitchalerts/templates/twitchalerts/_api_docs.html b/lnbits/extensions/twitchalerts/templates/twitchalerts/_api_docs.html
index d062589fe..540fcaee3 100644
--- a/lnbits/extensions/twitchalerts/templates/twitchalerts/_api_docs.html
+++ b/lnbits/extensions/twitchalerts/templates/twitchalerts/_api_docs.html
@@ -7,8 +7,9 @@
Accept Bitcoin donations on Twitch, and integrate them into your alerts.
Present your viewers with a simple donation page, and add those donations
to Streamlabs to play alerts on your stream!