From 6df8494ed65030f647cc49552633e62681cf336a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Wed, 15 Feb 2023 10:58:36 +0100 Subject: [PATCH] remove livestream --- lnbits/extensions/livestream/README.md | 45 --- lnbits/extensions/livestream/__init__.py | 35 -- lnbits/extensions/livestream/config.json | 10 - lnbits/extensions/livestream/crud.py | 203 ----------- lnbits/extensions/livestream/lnurl.py | 118 ------- lnbits/extensions/livestream/migrations.py | 39 --- lnbits/extensions/livestream/models.py | 103 ------ .../livestream/static/image/livestream.png | Bin 68286 -> 0 bytes .../extensions/livestream/static/js/index.js | 216 ------------ lnbits/extensions/livestream/tasks.py | 70 ---- .../templates/livestream/_api_docs.html | 150 -------- .../templates/livestream/index.html | 323 ------------------ lnbits/extensions/livestream/views.py | 48 --- lnbits/extensions/livestream/views_api.py | 101 ------ 14 files changed, 1461 deletions(-) delete mode 100644 lnbits/extensions/livestream/README.md delete mode 100644 lnbits/extensions/livestream/__init__.py delete mode 100644 lnbits/extensions/livestream/config.json delete mode 100644 lnbits/extensions/livestream/crud.py delete mode 100644 lnbits/extensions/livestream/lnurl.py delete mode 100644 lnbits/extensions/livestream/migrations.py delete mode 100644 lnbits/extensions/livestream/models.py delete mode 100644 lnbits/extensions/livestream/static/image/livestream.png delete mode 100644 lnbits/extensions/livestream/static/js/index.js delete mode 100644 lnbits/extensions/livestream/tasks.py delete mode 100644 lnbits/extensions/livestream/templates/livestream/_api_docs.html delete mode 100644 lnbits/extensions/livestream/templates/livestream/index.html delete mode 100644 lnbits/extensions/livestream/views.py delete mode 100644 lnbits/extensions/livestream/views_api.py diff --git a/lnbits/extensions/livestream/README.md b/lnbits/extensions/livestream/README.md deleted file mode 100644 index b2cf41d6..00000000 --- a/lnbits/extensions/livestream/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# DJ Livestream - -## Help DJ's and music producers conduct music livestreams - -LNbits Livestream extension produces a static QR code that can be shown on screen while livestreaming a DJ set for example. If someone listening to the livestream likes a song and want to support the DJ and/or the producer he can scan the QR code with a LNURL-pay capable wallet. - -When scanned, the QR code sends up information about the song playing at the moment (name and the producer of that song). Also, if the user likes the song and would like to support the producer, he can send a tip and a message for that specific track. If the user sends an amount over a specific threshold they will be given a link to download it (optional). - -The revenue will be sent to a wallet created specifically for that producer, with optional revenue splitting between the DJ and the producer. - -[**Wallets supporting LNURL**](https://github.com/fiatjaf/awesome-lnurl#wallets) - -[![video tutorial livestream](http://img.youtube.com/vi/zDrSWShKz7k/0.jpg)](https://youtu.be/zDrSWShKz7k 'video tutorial offline shop') - -## Usage - -1. Start by adding a track\ - ![add new track](https://i.imgur.com/Cu0eGrW.jpg) - - set the producer, or choose an existing one - - set the track name - - define a minimum price where a user can download the track - - set the download URL, where user will be redirected if he tips the livestream and the tip is equal or above the set price\ - ![track settings](https://i.imgur.com/HTJYwcW.jpg) -2. Adjust the percentage of the pay you want to take from the user's tips. 10%, the default, means that the DJ will keep 10% of all the tips sent by users. The other 90% will go to an auto generated producer wallet\ - ![adjust percentage](https://i.imgur.com/9weHKAB.jpg) -3. For every different producer added, when adding tracks, a wallet is generated for them\ - ![producer wallet](https://i.imgur.com/YFIZ7Tm.jpg) -4. On the bottom of the LNbits DJ Livestream extension you'll find the static QR code ([LNURL-pay](https://github.com/lnbits/lnbits/blob/master/lnbits/extensions/lnurlp/README.md)) you can add to the livestream or if you're a street performer you can print it and have it displayed -5. After all tracks and producers are added, you can start "playing" songs\ - ![play tracks](https://i.imgur.com/7ytiBkq.jpg) -6. You'll see the current track playing and a green icon indicating active track also\ - ![active track](https://i.imgur.com/W1vBz54.jpg) -7. When a user scans the QR code, and sends a tip, you'll receive 10%, in the example case, in your wallet and the producer's wallet will get the rest. For example someone tips 100 sats, you'll get 10 sats and the producer will get 90 sats - - producer's wallet receiving 18 sats from 20 sats tips\ - ![producer wallet](https://i.imgur.com/OM9LawA.jpg) - -## Use cases - -You can print the QR code and display it on a live gig, a street performance, etc... OR you can use the QR as an overlay in an online stream of you playing music, doing a DJ set, making a podcast. - -You can use the extension's API to trigger updates for the current track, update fees, add tracks... - -## Sponsored by - -[![](https://cdn.shopify.com/s/files/1/0826/9235/files/cryptograffiti_logo_clear_background.png?v=1504730421)](https://cryptograffiti.com/) diff --git a/lnbits/extensions/livestream/__init__.py b/lnbits/extensions/livestream/__init__.py deleted file mode 100644 index accd61de..00000000 --- a/lnbits/extensions/livestream/__init__.py +++ /dev/null @@ -1,35 +0,0 @@ -import asyncio - -from fastapi import APIRouter -from fastapi.staticfiles import StaticFiles - -from lnbits.db import Database -from lnbits.helpers import template_renderer -from lnbits.tasks import catch_everything_and_restart - -db = Database("ext_livestream") - -livestream_static_files = [ - { - "path": "/livestream/static", - "app": StaticFiles(packages=[("lnbits", "extensions/livestream/static")]), - "name": "livestream_static", - } -] - -livestream_ext: APIRouter = APIRouter(prefix="/livestream", tags=["livestream"]) - - -def livestream_renderer(): - return template_renderer(["lnbits/extensions/livestream/templates"]) - - -from .lnurl import * # noqa: F401,F403 -from .tasks import wait_for_paid_invoices -from .views import * # noqa: F401,F403 -from .views_api import * # noqa: F401,F403 - - -def livestream_start(): - loop = asyncio.get_event_loop() - loop.create_task(catch_everything_and_restart(wait_for_paid_invoices)) diff --git a/lnbits/extensions/livestream/config.json b/lnbits/extensions/livestream/config.json deleted file mode 100644 index d2674e70..00000000 --- a/lnbits/extensions/livestream/config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "DJ Livestream", - "short_description": "Sell tracks and split revenue (lnurl-pay)", - "tile": "/livestream/static/image/livestream.png", - "contributors": [ - "fiatjaf", - "cryptograffiti" - ], - "hidden": false -} diff --git a/lnbits/extensions/livestream/crud.py b/lnbits/extensions/livestream/crud.py deleted file mode 100644 index 037851aa..00000000 --- a/lnbits/extensions/livestream/crud.py +++ /dev/null @@ -1,203 +0,0 @@ -from typing import List, Optional - -from lnbits.core.crud import create_account, create_wallet -from lnbits.db import SQLITE - -from . import db -from .models import Livestream, Producer, Track - - -async def create_livestream(*, wallet_id: str) -> int: - returning = "" if db.type == SQLITE else "RETURNING ID" - method = db.execute if db.type == SQLITE else db.fetchone - - result = await (method)( - f""" - INSERT INTO livestream.livestreams (wallet) - VALUES (?) - {returning} - """, - (wallet_id,), - ) - - if db.type == SQLITE: - return result._result_proxy.lastrowid - else: - return result[0] # type: ignore - - -async def get_livestream(ls_id: int) -> Optional[Livestream]: - row = await db.fetchone( - "SELECT * FROM livestream.livestreams WHERE id = ?", (ls_id,) - ) - return Livestream(**row) if row else None - - -async def get_livestream_by_track(track_id: int) -> Optional[Livestream]: - row = await db.fetchone( - """ - SELECT * FROM livestream.tracks WHERE tracks.id = ? - """, - (track_id,), - ) - row2 = await db.fetchone( - """ - SELECT * FROM livestream.livestreams WHERE livestreams.id = ? - """, - (row.livestream,), - ) - return Livestream(**row2) if row2 else None - - -async def get_or_create_livestream_by_wallet(wallet: str) -> Optional[Livestream]: - row = await db.fetchone( - "SELECT * FROM livestream.livestreams WHERE wallet = ?", (wallet,) - ) - - if not row: - # create on the fly - ls_id = await create_livestream(wallet_id=wallet) - return await get_livestream(ls_id) - - return Livestream(**row) if row else None - - -async def update_current_track(ls_id: int, track_id: Optional[int]): - await db.execute( - "UPDATE livestream.livestreams SET current_track = ? WHERE id = ?", - (track_id, ls_id), - ) - - -async def update_livestream_fee(ls_id: int, fee_pct: int): - await db.execute( - "UPDATE livestream.livestreams SET fee_pct = ? WHERE id = ?", (fee_pct, ls_id) - ) - - -async def add_track( - livestream: int, - name: str, - download_url: Optional[str], - price_msat: int, - producer: Optional[int], -) -> int: - result = await db.execute( - """ - INSERT INTO livestream.tracks (livestream, name, download_url, price_msat, producer) - VALUES (?, ?, ?, ?, ?) - """, - (livestream, name, download_url, price_msat, producer), - ) - return result._result_proxy.lastrowid - - -async def update_track( - livestream: int, - track_id: int, - name: str, - download_url: Optional[str], - price_msat: int, - producer: int, -) -> int: - result = await db.execute( - """ - UPDATE livestream.tracks SET - name = ?, - download_url = ?, - price_msat = ?, - producer = ? - WHERE livestream = ? AND id = ? - """, - (name, download_url, price_msat, producer, livestream, track_id), - ) - return result._result_proxy.lastrowid - - -async def get_track(track_id: Optional[int]) -> Optional[Track]: - if not track_id: - return None - - row = await db.fetchone( - """ - SELECT id, download_url, price_msat, name, producer - FROM livestream.tracks WHERE id = ? - """, - (track_id,), - ) - return Track(**row) if row else None - - -async def get_tracks(livestream: int) -> List[Track]: - rows = await db.fetchall( - """ - SELECT id, download_url, price_msat, name, producer - FROM livestream.tracks WHERE livestream = ? - """, - (livestream,), - ) - return [Track(**row) for row in rows] - - -async def delete_track_from_livestream(livestream: int, track_id: int): - await db.execute( - """ - DELETE FROM livestream.tracks WHERE livestream = ? AND id = ? - """, - (livestream, track_id), - ) - - -async def add_producer(livestream: int, name: str) -> int: - name = name.strip() - - existing = await db.fetchall( - """ - SELECT id FROM livestream.producers - WHERE livestream = ? AND lower(name) = ? - """, - (livestream, name.lower()), - ) - if existing: - return existing[0].id - - user = await create_account() - wallet = await create_wallet(user_id=user.id, wallet_name="livestream: " + name) - - returning = "" if db.type == SQLITE else "RETURNING ID" - method = db.execute if db.type == SQLITE else db.fetchone - - result = await method( - f""" - INSERT INTO livestream.producers (livestream, name, "user", wallet) - VALUES (?, ?, ?, ?) - {returning} - """, - (livestream, name, user.id, wallet.id), - ) - if db.type == SQLITE: - return result._result_proxy.lastrowid - else: - return result[0] # type: ignore - - -async def get_producer(producer_id: int) -> Optional[Producer]: - row = await db.fetchone( - """ - SELECT id, "user", wallet, name - FROM livestream.producers WHERE id = ? - """, - (producer_id,), - ) - return Producer(**row) if row else None - - -async def get_producers(livestream: int) -> List[Producer]: - rows = await db.fetchall( - """ - SELECT id, "user", wallet, name - FROM livestream.producers WHERE livestream = ? - """, - (livestream,), - ) - return [Producer(**row) for row in rows] diff --git a/lnbits/extensions/livestream/lnurl.py b/lnbits/extensions/livestream/lnurl.py deleted file mode 100644 index e3e1b1be..00000000 --- a/lnbits/extensions/livestream/lnurl.py +++ /dev/null @@ -1,118 +0,0 @@ -import math -from http import HTTPStatus - -from fastapi import HTTPException, Query, Request -from lnurl import LnurlErrorResponse, LnurlPayActionResponse, LnurlPayResponse -from lnurl.models import ClearnetUrl, LightningInvoice, MilliSatoshi - -from lnbits.core.services import create_invoice - -from . import livestream_ext -from .crud import get_livestream, get_livestream_by_track, get_track - - -@livestream_ext.get("/lnurl/{ls_id}", name="livestream.lnurl_livestream") -async def lnurl_livestream(ls_id, request: Request): - ls = await get_livestream(ls_id) - if not ls: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="Livestream not found." - ) - - track = await get_track(ls.current_track) - if not track: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="This livestream is offline." - ) - - resp = LnurlPayResponse( - callback=ClearnetUrl( - request.url_for("livestream.lnurl_callback", track_id=track.id), - scheme="https", - ), - minSendable=MilliSatoshi(track.min_sendable), - maxSendable=MilliSatoshi(track.max_sendable), - metadata=await track.lnurlpay_metadata(), - ) - - params = resp.dict() - params["commentAllowed"] = 300 - - return params - - -@livestream_ext.get("/lnurl/t/{track_id}", name="livestream.lnurl_track") -async def lnurl_track(track_id, request: Request): - track = await get_track(track_id) - if not track: - raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Track not found.") - - resp = LnurlPayResponse( - callback=ClearnetUrl( - request.url_for("livestream.lnurl_callback", track_id=track.id), - scheme="https", - ), - minSendable=MilliSatoshi(track.min_sendable), - maxSendable=MilliSatoshi(track.max_sendable), - metadata=await track.lnurlpay_metadata(), - ) - - params = resp.dict() - params["commentAllowed"] = 300 - - return params - - -@livestream_ext.get("/lnurl/cb/{track_id}", name="livestream.lnurl_callback") -async def lnurl_callback( - track_id, request: Request, amount: int = Query(...), comment: str = Query("") -): - track = await get_track(track_id) - if not track: - raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Track not found.") - - amount_received = int(amount or 0) - - if amount_received < track.min_sendable: - return LnurlErrorResponse( - reason=f"Amount {round(amount_received / 1000)} is smaller than minimum {math.floor(track.min_sendable)}." - ).dict() - elif track.max_sendable < amount_received: - return LnurlErrorResponse( - reason=f"Amount {round(amount_received / 1000)} is greater than maximum {math.floor(track.max_sendable)}." - ).dict() - - if len(comment or "") > 300: - return LnurlErrorResponse( - reason=f"Got a comment with {len(comment)} characters, but can only accept 300" - ).dict() - - ls = await get_livestream_by_track(track_id) - assert ls - - extra_amount = amount_received - int(amount_received * (100 - ls.fee_pct) / 100) - - payment_hash, payment_request = await create_invoice( - wallet_id=ls.wallet, - amount=int(amount_received / 1000), - memo=await track.fullname(), - unhashed_description=(await track.lnurlpay_metadata()).encode(), - extra={ - "tag": "livestream", - "track": track.id, - "comment": comment, - "amount": int(extra_amount / 1000), - }, - ) - - assert track.price_msat - if amount_received < track.price_msat: - success_action = None - else: - success_action = track.success_action(payment_hash, request=request) - - resp = LnurlPayActionResponse( - pr=LightningInvoice(payment_request), successAction=success_action, routes=[] - ) - - return resp.dict() diff --git a/lnbits/extensions/livestream/migrations.py b/lnbits/extensions/livestream/migrations.py deleted file mode 100644 index fb664ab1..00000000 --- a/lnbits/extensions/livestream/migrations.py +++ /dev/null @@ -1,39 +0,0 @@ -async def m001_initial(db): - """ - Initial livestream tables. - """ - await db.execute( - f""" - CREATE TABLE livestream.livestreams ( - id {db.serial_primary_key}, - wallet TEXT NOT NULL, - fee_pct INTEGER NOT NULL DEFAULT 10, - current_track INTEGER - ); - """ - ) - - await db.execute( - f""" - CREATE TABLE livestream.producers ( - livestream INTEGER NOT NULL REFERENCES {db.references_schema}livestreams (id), - id {db.serial_primary_key}, - "user" TEXT NOT NULL, - wallet TEXT NOT NULL, - name TEXT NOT NULL - ); - """ - ) - - await db.execute( - f""" - CREATE TABLE livestream.tracks ( - livestream INTEGER NOT NULL REFERENCES {db.references_schema}livestreams (id), - id {db.serial_primary_key}, - download_url TEXT, - price_msat INTEGER NOT NULL DEFAULT 0, - name TEXT, - producer INTEGER REFERENCES {db.references_schema}producers (id) NOT NULL - ); - """ - ) diff --git a/lnbits/extensions/livestream/models.py b/lnbits/extensions/livestream/models.py deleted file mode 100644 index 31d3f6eb..00000000 --- a/lnbits/extensions/livestream/models.py +++ /dev/null @@ -1,103 +0,0 @@ -import json -from sqlite3 import Row -from typing import Optional - -from fastapi import Query, Request -from lnurl import Lnurl -from lnurl import encode as lnurl_encode -from lnurl.models import ClearnetUrl, Max144Str, UrlAction -from lnurl.types import LnurlPayMetadata -from pydantic import BaseModel - - -class CreateTrack(BaseModel): - name: str = Query(...) - download_url: str = Query(None) - price_msat: int = Query(None, ge=0) - producer_id: str = Query(None) - producer_name: str = Query(None) - - -class Livestream(BaseModel): - id: int - wallet: str - fee_pct: int - current_track: Optional[int] - - def lnurl(self, request: Request) -> Lnurl: - url = request.url_for("livestream.lnurl_livestream", ls_id=self.id) - return lnurl_encode(url) - - @classmethod - def from_row(cls, row: Row): - return cls(**dict(row)) - - -class Track(BaseModel): - id: int - download_url: Optional[str] - price_msat: int = 0 - name: str - producer: int - - @classmethod - def from_row(cls, row: Row): - return cls(**dict(row)) - - @property - def min_sendable(self) -> int: - return min(100_000, self.price_msat or 100_000) - - @property - def max_sendable(self) -> int: - return max(50_000_000, self.price_msat * 5) - - def lnurl(self, request: Request) -> Lnurl: - url = request.url_for("livestream.lnurl_track", track_id=self.id) - return lnurl_encode(url) - - async def fullname(self) -> str: - from .crud import get_producer - - producer = await get_producer(self.producer) - if producer: - producer_name = producer.name - else: - producer_name = "unknown author" - - return f"'{self.name}', from {producer_name}." - - async def lnurlpay_metadata(self) -> LnurlPayMetadata: - description = ( - await self.fullname() - ) + " Like this track? Send some sats in appreciation." - - if self.download_url: - description += f" Send {round(self.price_msat/1000)} sats or more and you can download it." - - return LnurlPayMetadata(json.dumps([["text/plain", description]])) - - def success_action( - self, payment_hash: str, request: Request - ) -> Optional[UrlAction]: - if not self.download_url: - return None - - url = request.url_for("livestream.track_redirect_download", track_id=self.id) - url_with_query = f"{url}?p={payment_hash}" - - return UrlAction( - url=ClearnetUrl(url_with_query, scheme="https"), - description=Max144Str(f"Download the track {self.name}!"), - ) - - -class Producer(BaseModel): - id: int - user: str - wallet: str - name: str - - @classmethod - def from_row(cls, row: Row): - return cls(**dict(row)) diff --git a/lnbits/extensions/livestream/static/image/livestream.png b/lnbits/extensions/livestream/static/image/livestream.png deleted file mode 100644 index 7d53d5661eefda1c4ed0a187c29eda68a383b686..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68286 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

)Y&_kg~ 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 diff --git a/lnbits/extensions/livestream/static/js/index.js b/lnbits/extensions/livestream/static/js/index.js deleted file mode 100644 index c49befce..00000000 --- a/lnbits/extensions/livestream/static/js/index.js +++ /dev/null @@ -1,216 +0,0 @@ -/* globals Quasar, Vue, _, VueQrcode, windowMixin, LNbits, LOCALE */ - -Vue.component(VueQrcode.name, VueQrcode) - -new Vue({ - el: '#vue', - mixins: [windowMixin], - data() { - return { - cancelListener: () => {}, - selectedWallet: null, - nextCurrentTrack: null, - livestream: { - tracks: [], - producers: [] - }, - trackDialog: { - show: false, - data: {} - } - } - }, - computed: { - sortedTracks() { - return this.livestream.tracks.sort((a, b) => a.name - b.name) - }, - tracksMap() { - return Object.fromEntries( - this.livestream.tracks.map(track => [track.id, track]) - ) - }, - producersMap() { - return Object.fromEntries( - this.livestream.producers.map(prod => [prod.id, prod]) - ) - } - }, - methods: { - getTrackLabel(trackId) { - if (!trackId) return - let track = this.tracksMap[trackId] - return `${track.name}, ${this.producersMap[track.producer].name}` - }, - disabledAddTrackButton() { - return ( - !this.trackDialog.data.name || - this.trackDialog.data.name.length === 0 || - !this.trackDialog.data.producer || - this.trackDialog.data.producer.length === 0 - ) - }, - changedWallet(wallet) { - this.selectedWallet = wallet - this.loadLivestream() - this.startPaymentNotifier() - }, - loadLivestream() { - LNbits.api - .request( - 'GET', - '/livestream/api/v1/livestream', - this.selectedWallet.inkey - ) - .then(response => { - this.livestream = response.data - this.nextCurrentTrack = this.livestream.current_track - }) - .catch(err => { - LNbits.utils.notifyApiError(err) - }) - }, - startPaymentNotifier() { - this.cancelListener() - - this.cancelListener = LNbits.events.onInvoicePaid( - this.selectedWallet, - payment => { - let satoshiAmount = Math.round(payment.amount / 1000) - let trackName = ( - this.tracksMap[payment.extra.track] || {name: '[unknown]'} - ).name - - this.$q.notify({ - message: `Someone paid ${satoshiAmount} sat for the track ${trackName}.`, - caption: payment.extra.comment - ? `"${payment.extra.comment}"` - : undefined, - color: 'secondary', - html: true, - timeout: 0, - actions: [{label: 'Dismiss', color: 'white', handler: () => {}}] - }) - } - ) - }, - addTrack() { - let {id, name, producer, price_sat, download_url} = this.trackDialog.data - - const [method, path] = id - ? ['PUT', `/livestream/api/v1/livestream/tracks/${id}`] - : ['POST', '/livestream/api/v1/livestream/tracks'] - - LNbits.api - .request(method, path, this.selectedWallet.inkey, { - download_url: - download_url && download_url.length > 0 ? download_url : undefined, - name, - price_msat: price_sat * 1000 || 0, - producer_name: typeof producer === 'string' ? producer : undefined, - producer_id: typeof producer === 'object' ? producer.id : undefined - }) - .then(response => { - this.$q.notify({ - message: `Track '${this.trackDialog.data.name}' added.`, - timeout: 700 - }) - this.loadLivestream() - this.trackDialog.show = false - this.trackDialog.data = {} - }) - .catch(err => { - LNbits.utils.notifyApiError(err) - }) - }, - openAddTrackDialog() { - this.trackDialog.show = true - this.trackDialog.data = {} - }, - openUpdateDialog(itemId) { - this.trackDialog.show = true - let item = this.livestream.tracks.find(item => item.id === itemId) - this.trackDialog.data = { - ...item, - producer: this.livestream.producers.find( - prod => prod.id === item.producer - ), - price_sat: Math.round(item.price_msat / 1000) - } - }, - deleteTrack(trackId) { - LNbits.utils - .confirmDialog('Are you sure you want to delete this track?') - .onOk(() => { - LNbits.api - .request( - 'DELETE', - '/livestream/api/v1/livestream/tracks/' + trackId, - this.selectedWallet.inkey - ) - .then(response => { - this.$q.notify({ - message: `Track deleted`, - timeout: 700 - }) - this.livestream.tracks.splice( - this.livestream.tracks.findIndex(track => track.id === trackId), - 1 - ) - }) - .catch(err => { - LNbits.utils.notifyApiError(err) - }) - }) - }, - updateCurrentTrack(track) { - console.log(this.nextCurrentTrack, this.livestream) - if (this.livestream.current_track === track) { - // if clicking the same, stop it - track = 0 - } - - LNbits.api - .request( - 'PUT', - '/livestream/api/v1/livestream/track/' + track, - this.selectedWallet.inkey - ) - .then(() => { - this.livestream.current_track = track - this.nextCurrentTrack = track - this.$q.notify({ - message: `Current track updated.`, - timeout: 700 - }) - }) - .catch(err => { - LNbits.utils.notifyApiError(err) - }) - }, - updateFeePct() { - LNbits.api - .request( - 'PUT', - '/livestream/api/v1/livestream/fee/' + this.livestream.fee_pct, - this.selectedWallet.inkey - ) - .then(() => { - this.$q.notify({ - message: `Percentage updated.`, - timeout: 700 - }) - }) - .catch(err => { - LNbits.utils.notifyApiError(err) - }) - }, - producerAdded(added, cb) { - cb(added) - } - }, - created() { - this.selectedWallet = this.g.user.wallets[0] - this.loadLivestream() - this.startPaymentNotifier() - } -}) diff --git a/lnbits/extensions/livestream/tasks.py b/lnbits/extensions/livestream/tasks.py deleted file mode 100644 index 4489dad9..00000000 --- a/lnbits/extensions/livestream/tasks.py +++ /dev/null @@ -1,70 +0,0 @@ -import asyncio - -from loguru import logger - -from lnbits.core.models import Payment -from lnbits.core.services import create_invoice, pay_invoice -from lnbits.helpers import get_current_extension_name -from lnbits.tasks import register_invoice_listener - -from .crud import get_livestream_by_track, get_producer, get_track - - -async def wait_for_paid_invoices(): - invoice_queue = asyncio.Queue() - register_invoice_listener(invoice_queue, get_current_extension_name()) - - while True: - payment = await invoice_queue.get() - await on_invoice_paid(payment) - - -async def on_invoice_paid(payment: Payment) -> None: - - if payment.extra.get("tag") != "livestream": - # not a livestream invoice - return - - track = await get_track(payment.extra.get("track", -1)) - if not track: - logger.error("this should never happen", payment) - return - - if payment.extra.get("shared_with"): - logger.error("payment was shared already", payment) - return - - producer = await get_producer(track.producer) - assert producer, f"track {track.id} is not associated with a producer" - - ls = await get_livestream_by_track(track.id) - assert ls, f"track {track.id} is not associated with a livestream" - - amount = int(payment.amount * (100 - ls.fee_pct) / 100) - - payment_hash, payment_request = await create_invoice( - wallet_id=producer.wallet, - amount=int(amount / 1000), - internal=True, - memo=f"Revenue from '{track.name}'.", - ) - logger.debug( - f"livestream: producer invoice created: {payment_hash}, {amount} msats" - ) - - checking_id = await pay_invoice( - payment_request=payment_request, - wallet_id=payment.wallet_id, - extra={ - **payment.extra, - "shared_with": f"Producer ID: {producer.id}", - "received": payment.amount, - }, - ) - logger.debug(f"livestream: producer invoice paid: {checking_id}") - - # so the flow is the following: - # - we receive, say, 1000 satoshis - # - if the fee_pct is, say, 30%, the amount we will send is 700 - # - we change the amount of receiving payment on the database from 1000 to 300 - # - we create a new payment on the producer's wallet with amount 700 diff --git a/lnbits/extensions/livestream/templates/livestream/_api_docs.html b/lnbits/extensions/livestream/templates/livestream/_api_docs.html deleted file mode 100644 index 34b6518d..00000000 --- a/lnbits/extensions/livestream/templates/livestream/_api_docs.html +++ /dev/null @@ -1,150 +0,0 @@ - - - -

Add tracks, profit.

-
-
-
- - - - - - - - GET - /livestream/api/v1/livestream -
Headers
- {"X-Api-Key": <invoice_key>}
-
Body (application/json)
-
- Returns 200 OK (application/json) -
- [<livestream_object>, ...] -
Curl example
- curl -X GET {{ request.base_url }}livestream/api/v1/livestream -H - "X-Api-Key: {{ user.wallets[0].inkey }}" - -
-
-
- - - - PUT - /livestream/api/v1/livestream/track/<track_id> -
Headers
- {"X-Api-Key": <invoice_key>}
-
Body (application/json)
-
- Returns 201 CREATED (application/json) -
-
Curl example
- curl -X PUT {{ request.base_url }} - livestream/api/v1/livestream/track/<track_id> -H "X-Api-Key: {{ - user.wallets[0].inkey }}" - -
-
-
- - - - PUT - /livestream/api/v1/livestream/fee/<fee_pct> -
Headers
- {"X-Api-Key": <invoice_key>}
-
Body (application/json)
-
- Returns 201 CREATED (application/json) -
-
Curl example
- curl -X PUT {{ request.base_url }} - livestream/api/v1/livestream/fee/<fee_pct> -H "X-Api-Key: {{ - user.wallets[0].inkey }}" - -
-
-
- - - - - POST - /livestream/api/v1/livestream/tracks -
Headers
- {"X-Api-Key": <invoice_key>}
-
Body (application/json)
- {"name": <string>, "download_url": <string>, - "price_msat": <integer>, "producer_id": <integer>, - "producer_name": <string>} -
- Returns 201 CREATED (application/json) -
-
Curl example
- curl -X POST {{ request.base_url }} - livestream/api/v1/livestream/tracks -d '{"name": <string>, - "download_url": <string>, "price_msat": <integer>, - "producer_id": <integer>, "producer_name": <string>}' -H - "Content-type: application/json" -H "X-Api-Key: {{ - user.wallets[0].adminkey }}" - -
-
-
- - - - DELETE - /livestream/api/v1/livestream/tracks/<track_id> -
Headers
- {"X-Api-Key": <invoice_key>}
-
Returns 204 NO CONTENT
- -
Curl example
- curl -X DELETE {{ request.base_url }} - livestream/api/v1/livestream/tracks/<track_id> -H "X-Api-Key: {{ - user.wallets[0].inkey }}" - -
-
-
-
diff --git a/lnbits/extensions/livestream/templates/livestream/index.html b/lnbits/extensions/livestream/templates/livestream/index.html deleted file mode 100644 index 8749a9cf..00000000 --- a/lnbits/extensions/livestream/templates/livestream/index.html +++ /dev/null @@ -1,323 +0,0 @@ -{% extends "base.html" %} {% from "macros.jinja" import window_vars with context -%} {% block page %} -
- - -
- - -
- {{SITE_TITLE}} Livestream extension -
-
- - - {% include "livestream/_api_docs.html" %} - -
-
- - - - -

- Standalone QR Code for this track -

- - - - - - - Copy LNURL-pay code -
- - - - - - - -
-
- - Update track - Add track - -
-
- Cancel -
-
-
-
-
-
-
-{% endblock %} {% block scripts %} {{ window_vars(user) }} - -{% endblock %} diff --git a/lnbits/extensions/livestream/views.py b/lnbits/extensions/livestream/views.py deleted file mode 100644 index ca12f16b..00000000 --- a/lnbits/extensions/livestream/views.py +++ /dev/null @@ -1,48 +0,0 @@ -from http import HTTPStatus - -from fastapi import Depends, HTTPException, Query, Request -from starlette.datastructures import URL -from starlette.responses import HTMLResponse, RedirectResponse - -from lnbits.core.crud import get_wallet_payment -from lnbits.core.models import User -from lnbits.decorators import check_user_exists - -from . import livestream_ext, livestream_renderer -from .crud import get_livestream_by_track, get_track - - -@livestream_ext.get("/", response_class=HTMLResponse) -async def index(request: Request, user: User = Depends(check_user_exists)): - return livestream_renderer().TemplateResponse( - "livestream/index.html", {"request": request, "user": user.dict()} - ) - - -@livestream_ext.get("/track/{track_id}", name="livestream.track_redirect_download") -async def track_redirect_download(track_id, p: str = Query(...)): - payment_hash = p - track = await get_track(track_id) - ls = await get_livestream_by_track(track_id) - assert ls - payment = await get_wallet_payment(ls.wallet, payment_hash) - - if not payment: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, - detail=f"Couldn't find the payment {payment_hash}.", - ) - if not track: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, - detail=f"Couldn't find the track {track_id}.", - ) - - if payment.pending: - raise HTTPException( - status_code=HTTPStatus.PAYMENT_REQUIRED, - detail=f"Payment {payment_hash} wasn't received yet. Please try again in a minute.", - ) - - assert track.download_url - return RedirectResponse(url=URL(track.download_url)) diff --git a/lnbits/extensions/livestream/views_api.py b/lnbits/extensions/livestream/views_api.py deleted file mode 100644 index b346f353..00000000 --- a/lnbits/extensions/livestream/views_api.py +++ /dev/null @@ -1,101 +0,0 @@ -from http import HTTPStatus - -from fastapi import Depends, HTTPException, Request -from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl - -from lnbits.decorators import WalletTypeInfo, get_key_type - -from . import livestream_ext -from .crud import ( - add_producer, - add_track, - delete_track_from_livestream, - get_or_create_livestream_by_wallet, - get_producers, - get_tracks, - update_current_track, - update_livestream_fee, - update_track, -) -from .models import CreateTrack - - -@livestream_ext.get("/api/v1/livestream") -async def api_livestream_from_wallet( - req: Request, g: WalletTypeInfo = Depends(get_key_type) -): - ls = await get_or_create_livestream_by_wallet(g.wallet.id) - assert ls - tracks = await get_tracks(ls.id) - producers = await get_producers(ls.id) - - try: - return { - **ls.dict(), - **{ - "lnurl": ls.lnurl(request=req), - "tracks": [ - dict(lnurl=track.lnurl(request=req), **track.dict()) - for track in tracks - ], - "producers": [producer.dict() for producer in producers], - }, - } - except LnurlInvalidUrl: - raise HTTPException( - status_code=HTTPStatus.UPGRADE_REQUIRED, - detail="LNURLs need to be delivered over a publically accessible `https` domain or Tor.", - ) - - -@livestream_ext.put("/api/v1/livestream/track/{track_id}") -async def api_update_track(track_id, g: WalletTypeInfo = Depends(get_key_type)): - try: - id = int(track_id) - except ValueError: - id = 0 - - ls = await get_or_create_livestream_by_wallet(g.wallet.id) - assert ls - await update_current_track(ls.id, None if id <= 0 else id) - return "", HTTPStatus.NO_CONTENT - - -@livestream_ext.put("/api/v1/livestream/fee/{fee_pct}") -async def api_update_fee(fee_pct, g: WalletTypeInfo = Depends(get_key_type)): - ls = await get_or_create_livestream_by_wallet(g.wallet.id) - assert ls - await update_livestream_fee(ls.id, int(fee_pct)) - return "", HTTPStatus.NO_CONTENT - - -@livestream_ext.post("/api/v1/livestream/tracks") -@livestream_ext.put("/api/v1/livestream/tracks/{id}") -async def api_add_track( - data: CreateTrack, id=None, g: WalletTypeInfo = Depends(get_key_type) -): - ls = await get_or_create_livestream_by_wallet(g.wallet.id) - assert ls - - if data.producer_id: - p_id = int(data.producer_id) - elif data.producer_name: - p_id = await add_producer(ls.id, data.producer_name) - else: - raise TypeError("need either producer_id or producer_name arguments") - - if id: - await update_track( - ls.id, id, data.name, data.download_url, data.price_msat or 0, p_id - ) - else: - await add_track(ls.id, data.name, data.download_url, data.price_msat or 0, p_id) - return - - -@livestream_ext.delete("/api/v1/livestream/tracks/{track_id}") -async def api_delete_track(track_id, g: WalletTypeInfo = Depends(get_key_type)): - ls = await get_or_create_livestream_by_wallet(g.wallet.id) - assert ls - await delete_track_from_livestream(ls.id, track_id) - return "", HTTPStatus.NO_CONTENT