Seems to be working

This commit is contained in:
ben 2022-12-13 20:01:05 +00:00
parent d69c2e9170
commit 2e69ebe080
7 changed files with 105 additions and 43 deletions

View file

@ -2,6 +2,7 @@ from typing import List
from . import db from . import db
from .models import Target from .models import Target
from loguru import logger
async def get_targets(source_wallet: str) -> List[Target]: async def get_targets(source_wallet: str) -> List[Target]:
@ -12,6 +13,7 @@ async def get_targets(source_wallet: str) -> List[Target]:
async def set_targets(source_wallet: str, targets: List[Target]): async def set_targets(source_wallet: str, targets: List[Target]):
logger.debug(targets)
async with db.connect() as conn: async with db.connect() as conn:
await conn.execute( await conn.execute(
"DELETE FROM splitpayments.targets WHERE source = ?", (source_wallet,) "DELETE FROM splitpayments.targets WHERE source = ?", (source_wallet,)
@ -20,8 +22,8 @@ async def set_targets(source_wallet: str, targets: List[Target]):
await conn.execute( await conn.execute(
""" """
INSERT INTO splitpayments.targets INSERT INTO splitpayments.targets
(source, wallet, percent, alias) (source, wallet, percent, tag, alias)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""", """,
(source_wallet, target.wallet, target.percent, target.alias), (source_wallet, target.wallet, target.percent, target.tag, target.alias),
) )

View file

@ -1,3 +1,5 @@
from lnbits.helpers import urlsafe_short_hash
async def m001_initial(db): async def m001_initial(db):
""" """
Initial split payment table. Initial split payment table.
@ -52,3 +54,43 @@ async def m002_float_percent(db):
) )
await db.execute("DROP TABLE splitpayments.splitpayments_old") await db.execute("DROP TABLE splitpayments.splitpayments_old")
async def m003_float_percent(db):
"""
Add float percent and migrates the existing data.
"""
await db.execute("ALTER TABLE splitpayments.targets RENAME TO splitpayments_old")
await db.execute(
"""
CREATE TABLE splitpayments.targets (
wallet TEXT NOT NULL,
source TEXT NOT NULL,
percent INT,
alias TEXT,
UNIQUE (source, wallet)
);
"""
)
for row in [
list(row)
for row in await db.fetchall("SELECT * FROM splitpayments.splitpayments_old")
]:
await db.execute(
"""
INSERT INTO splitpayments.targets (
id
wallet,
source,
percent,
tag,
alias
)
VALUES (?, ?, ?, ?)
""",
(urlsafe_short_hash(), row[0], row[1], row[2], '', row[3]),
)
await db.execute("DROP TABLE splitpayments.splitpayments_old")

View file

@ -8,13 +8,15 @@ class Target(BaseModel):
wallet: str wallet: str
source: str source: str
percent: float percent: float
tag: str
alias: Optional[str] alias: Optional[str]
class TargetPutList(BaseModel): class TargetPutList(BaseModel):
wallet: str = Query(...) wallet: str = Query(...)
alias: str = Query("") alias: str = Query("")
percent: float = Query(..., ge=0.01, lt=100) percent: float = Query(..., ge=0, lt=100)
tag: str = Query("")
class TargetPut(BaseModel): class TargetPut(BaseModel):

View file

@ -10,7 +10,7 @@ function hashTargets(targets) {
} }
function isTargetComplete(target) { function isTargetComplete(target) {
return target.wallet && target.wallet.trim() !== '' && target.percent > 0 return target.wallet && target.wallet.trim() !== '' && (target.percent > 0 || target.tag != '')
} }
new Vue({ new Vue({
@ -52,33 +52,15 @@ new Vue({
.then(response => { .then(response => {
this.currentHash = hashTargets(response.data) this.currentHash = hashTargets(response.data)
this.targets = response.data.concat({}) this.targets = response.data.concat({})
for (let i = 0; i < this.targets.length; i++) {
if(this.targets[i].tag !=
}
}) })
}, },
changedWallet(wallet) { changedWallet(wallet) {
this.selectedWallet = wallet this.selectedWallet = wallet
this.getTargets() this.getTargets()
}, },
tagChanged(isTag, index) {
// fix percent min and max range
if (isTag) {
this.targets[index].percent = null
this.targets[index].tag.trim()
}
// remove empty lines (except last)
if (this.targets.length >= 2) {
for (let i = this.targets.length - 2; i >= 0; i--) {
let target = this.targets[i]
if (
(!target.wallet || target.wallet.trim() === '') &&
(!target.alias || target.alias.trim() === '') &&
!target.percent
) {
this.targets.splice(i, 1)
}
}
}
},
clearChanged(index) { clearChanged(index) {
if(this.targets[index].method == 'split'){ if(this.targets[index].method == 'split'){
this.targets[index].tag = null this.targets[index].tag = null
@ -87,13 +69,19 @@ new Vue({
this.targets[index].percent = null this.targets[index].percent = null
} }
}, },
percentageChanged(isPercent, index) { targetChanged(index) {
// fix percent min and max range // fix percent min and max range
if (isPercent) { console.log(this.targets)
if (this.targets[index].percent) {
if (this.targets[index].percent > 100) this.targets[index].percent = 100 if (this.targets[index].percent > 100) this.targets[index].percent = 100
if (this.targets[index].percent < 0) this.targets[index].percent = 0 if (this.targets[index].percent < 0) this.targets[index].percent = 0
} }
// not percentage
if (!this.targets[index].percent) {
this.targets[index].percent = 0
}
// remove empty lines (except last) // remove empty lines (except last)
if (this.targets.length >= 2) { if (this.targets.length >= 2) {
for (let i = this.targets.length - 2; i >= 0; i--) { for (let i = this.targets.length - 2; i >= 0; i--) {
@ -101,6 +89,7 @@ new Vue({
if ( if (
(!target.wallet || target.wallet.trim() === '') && (!target.wallet || target.wallet.trim() === '') &&
(!target.alias || target.alias.trim() === '') && (!target.alias || target.alias.trim() === '') &&
(!target.tag || target.tag.trim() === '') &&
!target.percent !target.percent
) { ) {
this.targets.splice(i, 1) this.targets.splice(i, 1)
@ -145,6 +134,15 @@ new Vue({
console.log(this.targets) console.log(this.targets)
}, },
saveTargets() { saveTargets() {
console.log(this.targets)
for (let i = 0; i < this.targets.length; i++) {
if (this.targets[i].tag){
this.targets[i].percent = 0
}
else{
this.targets[i].tag = ''
}
}
LNbits.api LNbits.api
.request( .request(
'PUT', 'PUT',
@ -153,7 +151,7 @@ new Vue({
{ {
targets: this.targets targets: this.targets
.filter(isTargetComplete) .filter(isTargetComplete)
.map(({wallet, percent, alias}) => ({wallet, percent, alias})) .map(({wallet, percent, tag, alias}) => ({wallet, percent, tag, alias}))
} }
) )
.then(response => { .then(response => {

View file

@ -37,7 +37,14 @@ async def on_invoice_paid(payment: Payment) -> None:
logger.debug(f"performing split payments to {len(targets)} targets") logger.debug(f"performing split payments to {len(targets)} targets")
for target in targets: for target in targets:
amount = int(payment.amount * target.percent / 100) # msats
if target.tag and payment.extra.get("tag") == target.tag:
amount = int(payment.amount)
elif target.percent:
amount = int(payment.amount * target.percent / 100) # msats
else:
return
payment_hash, payment_request = await create_invoice( payment_hash, payment_request = await create_invoice(
wallet_id=target.wallet, wallet_id=target.wallet,
amount=int(amount / 1000), # sats amount=int(amount / 1000), # sats

View file

@ -59,6 +59,7 @@
:true-value="'tag'" :true-value="'tag'"
color="primary" color="primary"
label="" label=""
value="True"
style="width: 180px" style="width: 180px"
v-model="target.method" v-model="target.method"
:label="`${target.method}` === 'tag' ? 'Send funds by tag' : `${target.method}` === 'split' ? 'Split funds by %' : 'Split/tag?'" :label="`${target.method}` === 'tag' ? 'Send funds by tag' : `${target.method}` === 'split' ? 'Split funds by %' : 'Split/tag?'"
@ -66,14 +67,13 @@
></q-toggle> ></q-toggle>
<q-input <q-input
v-if="target.method == 'tag' || target.tag != null" v-if="target.method == 'tag' || target.tag != ''"
style="width: 150px" style="width: 150px"
dense dense
outlined outlined
v-model.number="target.tag" v-model="target.tag"
label="Tag name" label="Tag name"
suffix="#" suffix="#"
@input="tagChanged(true, t)"
></q-input> ></q-input>
<q-input <q-input
@ -84,11 +84,20 @@
v-model.number="target.percent" v-model.number="target.percent"
label="split" label="split"
suffix="%" suffix="%"
@input="percentageChanged(true, t)"
></q-input> ></q-input>
<q-btn
v-if="t == targets.length - 1 && (target.method == 'tag' || target.method == 'split')"
round
size="sm"
icon="add"
unelevated
color="primary"
@click="targetChanged(t)"
>
<q-tooltip>Add more</q-tooltip>
</q-btn>
</div> </div>
<div class="row justify-evenly q-pa-lg"> <div class="row justify-evenly q-pa-lg">
<div> <div>
<q-btn unelevated outline color="secondary" @click="clearTargets"> <q-btn unelevated outline color="secondary" @click="clearTargets">
@ -101,7 +110,7 @@
unelevated unelevated
color="primary" color="primary"
type="submit" type="submit"
:disabled="!isDirty" :disabled="targets.length < 2"
> >
Save Targets Save Targets
</q-btn> </q-btn>

View file

@ -11,6 +11,8 @@ from . import splitpayments_ext
from .crud import get_targets, set_targets from .crud import get_targets, set_targets
from .models import Target, TargetPut from .models import Target, TargetPut
from loguru import logger
@splitpayments_ext.get("/api/v1/targets") @splitpayments_ext.get("/api/v1/targets")
async def api_targets_get(wallet: WalletTypeInfo = Depends(require_admin_key)): async def api_targets_get(wallet: WalletTypeInfo = Depends(require_admin_key)):
@ -25,6 +27,7 @@ async def api_targets_set(
body = await req.json() body = await req.json()
targets = [] targets = []
data = TargetPut.parse_obj(body["targets"]) data = TargetPut.parse_obj(body["targets"])
logger.debug(data)
for entry in data.__root__: for entry in data.__root__:
wallet = await get_wallet(entry.wallet) wallet = await get_wallet(entry.wallet)
if not wallet: if not wallet:
@ -50,16 +53,15 @@ async def api_targets_set(
Target( Target(
wallet=wallet.id, wallet=wallet.id,
source=wal.wallet.id, source=wal.wallet.id,
tag=entry.tag,
percent=entry.percent, percent=entry.percent,
alias=entry.alias, alias=entry.alias,
) )
) )
percent_sum = sum([target.percent for target in targets])
percent_sum = sum([target.percent for target in targets]) if percent_sum > 100:
if percent_sum > 100: raise HTTPException(
raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail="Splitting over 100%."
status_code=HTTPStatus.BAD_REQUEST, detail="Splitting over 100%." )
)
await set_targets(wal.wallet.id, targets) await set_targets(wal.wallet.id, targets)
return "" return ""