mirror of
https://github.com/lnbits/lnbits.git
synced 2025-09-20 04:21:20 +02:00
black/prettier
This commit is contained in:
@@ -5,7 +5,6 @@ The TwitchAlerts extension allows you to integrate Bitcoin Lightning (and on-cha
|
||||
Try to include an image
|
||||
<img src="https://i.imgur.com/9i4xcQB.png">
|
||||
|
||||
|
||||
<h2>If your extension has API endpoints, include useful ones here</h2>
|
||||
|
||||
<code>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"</code>
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
);
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
@@ -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
|
||||
|
@@ -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!<br />
|
||||
For detailed setup instructions, check out <a href="https://github.com/Fittiboy/bitcoin-on-twitch">
|
||||
this guide!</a><br />
|
||||
For detailed setup instructions, check out
|
||||
<a href="https://github.com/Fittiboy/bitcoin-on-twitch"> this guide!</a
|
||||
><br />
|
||||
<small>
|
||||
Created by, <a href="https://github.com/Fittiboy">Fitti</a></small
|
||||
>
|
||||
|
@@ -18,8 +18,8 @@
|
||||
dense
|
||||
v-model.number="donationDialog.data.sats"
|
||||
type="number"
|
||||
min=1
|
||||
suffix=sats
|
||||
min="1"
|
||||
suffix="sats"
|
||||
:rules="[val => val > 0 || 'Choose a positive number of sats!']"
|
||||
label="Amount of sats"
|
||||
></q-input>
|
||||
|
@@ -151,9 +151,7 @@
|
||||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
LNbits Twitch Alerts extension
|
||||
</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">LNbits Twitch Alerts extension</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
@@ -231,21 +229,21 @@
|
||||
</div>
|
||||
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||
<script>
|
||||
var mapTwitchAlerts = function(obj) {
|
||||
var mapTwitchAlerts = function (obj) {
|
||||
obj.date = Quasar.utils.date.formatDate(
|
||||
new Date(obj.time * 1000),
|
||||
'YYYY-MM-DD HH:mm'
|
||||
)
|
||||
obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount)
|
||||
obj.authUrl = ['/twitchalerts/api/v1/getaccess/', obj.id].join('')
|
||||
obj.displayUrl = ['/twitchalerts/', obj.state].join('')
|
||||
obj.displayUrl = ['/twitchalerts/', obj.state].join('')
|
||||
return obj
|
||||
}
|
||||
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [windowMixin],
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
servicenames: ['Streamlabs'],
|
||||
services: [],
|
||||
@@ -253,7 +251,12 @@
|
||||
servicesTable: {
|
||||
columns: [
|
||||
{name: 'id', align: 'left', label: 'ID', field: 'id'},
|
||||
{name: 'twitchuser', align: 'left', label: 'Twitch Username', field: 'twitchuser'},
|
||||
{
|
||||
name: 'twitchuser',
|
||||
align: 'left',
|
||||
label: 'Twitch Username',
|
||||
field: 'twitchuser'
|
||||
},
|
||||
{name: 'wallet', align: 'left', label: 'Wallet', field: 'wallet'},
|
||||
{
|
||||
name: 'servicename',
|
||||
@@ -286,7 +289,12 @@
|
||||
},
|
||||
donationsTable: {
|
||||
columns: [
|
||||
{name: 'service', align: 'left', label: 'Service', field: 'service'},
|
||||
{
|
||||
name: 'service',
|
||||
align: 'left',
|
||||
label: 'Service',
|
||||
field: 'service'
|
||||
},
|
||||
{name: 'donor', align: 'left', label: 'Donor', field: 'donor'},
|
||||
{name: 'ltext', align: 'left', label: 'Message', field: 'ltext'},
|
||||
{name: 'sats', align: 'left', label: 'Sats', field: 'sats'}
|
||||
@@ -302,7 +310,7 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDonations: function() {
|
||||
getDonations: function () {
|
||||
var self = this
|
||||
|
||||
LNbits.api
|
||||
@@ -311,40 +319,40 @@
|
||||
'/twitchalerts/api/v1/donations',
|
||||
this.g.user.wallets[0].inkey
|
||||
)
|
||||
.then(function(response) {
|
||||
self.donations = response.data.map(function(obj) {
|
||||
.then(function (response) {
|
||||
self.donations = response.data.map(function (obj) {
|
||||
return mapTwitchAlerts(obj)
|
||||
})
|
||||
})
|
||||
},
|
||||
deleteDonation: function(donationId) {
|
||||
deleteDonation: function (donationId) {
|
||||
var self = this
|
||||
var donations = _.findWhere(this.donations, {id: donationId})
|
||||
|
||||
LNbits.utils
|
||||
.confirmDialog('Are you sure you want to delete this donation?')
|
||||
.onOk(function() {
|
||||
.onOk(function () {
|
||||
LNbits.api
|
||||
.request(
|
||||
'DELETE',
|
||||
'/twitchalerts/api/v1/donations/' + donationId,
|
||||
_.findWhere(self.g.user.wallets, {id: donations.wallet}).inkey
|
||||
)
|
||||
.then(function(response) {
|
||||
self.donations = _.reject(self.donations, function(obj) {
|
||||
.then(function (response) {
|
||||
self.donations = _.reject(self.donations, function (obj) {
|
||||
return obj.id == ticketId
|
||||
})
|
||||
})
|
||||
.catch(function(error) {
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
exportdonationsCSV: function() {
|
||||
exportdonationsCSV: function () {
|
||||
LNbits.utils.exportCSV(this.donationsTable.columns, this.donations)
|
||||
},
|
||||
|
||||
getServices: function() {
|
||||
getServices: function () {
|
||||
var self = this
|
||||
|
||||
LNbits.api
|
||||
@@ -353,13 +361,13 @@
|
||||
'/twitchalerts/api/v1/services',
|
||||
this.g.user.wallets[0].inkey
|
||||
)
|
||||
.then(function(response) {
|
||||
self.services = response.data.map(function(obj) {
|
||||
.then(function (response) {
|
||||
self.services = response.data.map(function (obj) {
|
||||
return mapTwitchAlerts(obj)
|
||||
})
|
||||
})
|
||||
},
|
||||
sendServiceData: function() {
|
||||
sendServiceData: function () {
|
||||
var wallet = _.findWhere(this.g.user.wallets, {
|
||||
id: this.serviceDialog.data.wallet
|
||||
})
|
||||
@@ -368,20 +376,20 @@
|
||||
this.createService(wallet, data)
|
||||
},
|
||||
|
||||
createService: function(wallet, data) {
|
||||
createService: function (wallet, data) {
|
||||
var self = this
|
||||
LNbits.api
|
||||
.request('POST', '/twitchalerts/api/v1/services', wallet.inkey, data)
|
||||
.then(function(response) {
|
||||
.then(function (response) {
|
||||
self.services.push(mapTwitchAlerts(response.data))
|
||||
self.serviceDialog.show = false
|
||||
self.serviceDialog.data = {}
|
||||
})
|
||||
.catch(function(error) {
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
})
|
||||
},
|
||||
updateserviceDialog: function(serviceId) {
|
||||
updateserviceDialog: function (serviceId) {
|
||||
var link = _.findWhere(this.services, {id: serviceId})
|
||||
console.log(link.id)
|
||||
this.serviceDialog.data.id = link.id
|
||||
@@ -392,35 +400,35 @@
|
||||
this.serviceDialog.data.client_secret = link.client_secret
|
||||
this.serviceDialog.show = true
|
||||
},
|
||||
deleteService: function(servicesId) {
|
||||
deleteService: function (servicesId) {
|
||||
var self = this
|
||||
var services = _.findWhere(this.services, {id: servicesId})
|
||||
|
||||
LNbits.utils
|
||||
.confirmDialog('Are you sure you want to delete this service link?')
|
||||
.onOk(function() {
|
||||
.onOk(function () {
|
||||
LNbits.api
|
||||
.request(
|
||||
'DELETE',
|
||||
'/twitchalerts/api/v1/services/' + servicesId,
|
||||
_.findWhere(self.g.user.wallets, {id: services.wallet}).inkey
|
||||
)
|
||||
.then(function(response) {
|
||||
self.services = _.reject(self.services, function(obj) {
|
||||
.then(function (response) {
|
||||
self.services = _.reject(self.services, function (obj) {
|
||||
return obj.id == servicesId
|
||||
})
|
||||
})
|
||||
.catch(function(error) {
|
||||
.catch(function (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
exportservicesCSV: function() {
|
||||
exportservicesCSV: function () {
|
||||
LNbits.utils.exportCSV(this.servicesTable.columns, this.services)
|
||||
}
|
||||
},
|
||||
|
||||
created: function() {
|
||||
created: function () {
|
||||
if (this.g.user.wallets.length) {
|
||||
this.getDonations()
|
||||
this.getServices()
|
||||
|
@@ -21,6 +21,6 @@ async def donation(state):
|
||||
service = await get_service(0, by_state=state)
|
||||
if not service:
|
||||
abort(HTTPStatus.NOT_FOUND, "Service does not exist.")
|
||||
return await render_template("twitchalerts/display.html",
|
||||
twitchuser=service.twitchuser,
|
||||
service=service.id)
|
||||
return await render_template(
|
||||
"twitchalerts/display.html", twitchuser=service.twitchuser, service=service.id
|
||||
)
|
||||
|
@@ -6,11 +6,22 @@ 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
|
||||
|
||||
|
||||
@@ -18,30 +29,14 @@ 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)
|
||||
@@ -65,16 +60,14 @@ async def api_get_access(service_id):
|
||||
"client_id": service.client_id,
|
||||
"redirect_uri": redirect_uri,
|
||||
"scope": "donations.create",
|
||||
"state": service.state
|
||||
"state": service.state,
|
||||
}
|
||||
endpoint_url = "https://streamlabs.com/api/v1.0/authorize/?"
|
||||
querystring = "&".join(
|
||||
[f"{key}={value}" for key, value in params.items()])
|
||||
querystring = "&".join([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"])
|
||||
@@ -84,40 +77,32 @@ async def api_authenticate_service(service_id):
|
||||
If successful, an API access token will be added to the service, and
|
||||
the user will be redirected to index.html.
|
||||
"""
|
||||
code = request.args.get('code')
|
||||
state = request.args.get('state')
|
||||
code = request.args.get("code")
|
||||
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
|
||||
@@ -126,7 +111,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)
|
||||
@@ -139,7 +124,8 @@ async def api_create_donation():
|
||||
completelinktext="Back to Stream!",
|
||||
webhook=webhook_base + "/twitchalerts/api/v1/postdonation",
|
||||
description=description,
|
||||
**charge_details)
|
||||
**charge_details,
|
||||
)
|
||||
await create_donation(
|
||||
id=charge.id,
|
||||
wallet=service.wallet,
|
||||
@@ -154,12 +140,11 @@ async def api_create_donation():
|
||||
|
||||
|
||||
@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.
|
||||
|
||||
@@ -170,8 +155,7 @@ 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"])
|
||||
@@ -184,8 +168,7 @@ 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,
|
||||
)
|
||||
|
||||
@@ -202,8 +185,7 @@ 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,
|
||||
)
|
||||
|
||||
@@ -216,17 +198,20 @@ 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
|
||||
|
||||
|
||||
@@ -238,17 +223,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
|
||||
|
||||
|
||||
@@ -258,11 +243,12 @@ 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
|
||||
@@ -274,11 +260,12 @@ 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
|
||||
|
Reference in New Issue
Block a user