Added update
This commit is contained in:
parent
69c7cdb49f
commit
08ce55e29e
7 changed files with 171 additions and 37 deletions
|
|
@ -20,7 +20,7 @@ async def create_gerty(wallet_id: str, data: Gerty) -> Gerty:
|
||||||
data.lnbits_wallets,
|
data.lnbits_wallets,
|
||||||
data.sats_quote,
|
data.sats_quote,
|
||||||
data.exchange,
|
data.exchange,
|
||||||
data.onchain_sats,
|
data.onchain_stats,
|
||||||
data.ln_stats,
|
data.ln_stats,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -28,7 +28,13 @@ async def create_gerty(wallet_id: str, data: Gerty) -> Gerty:
|
||||||
gerty = await get_gerty(gerty_id)
|
gerty = await get_gerty(gerty_id)
|
||||||
assert gerty, "Newly created gerty couldn't be retrieved"
|
assert gerty, "Newly created gerty couldn't be retrieved"
|
||||||
return gerty
|
return gerty
|
||||||
|
|
||||||
|
async def update_gerty(gerty_id: str, **kwargs) -> Gerty:
|
||||||
|
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
|
||||||
|
await db.execute(
|
||||||
|
f"UPDATE gerty.gertys SET {q} WHERE id = ?", (*kwargs.values(), gerty_id)
|
||||||
|
)
|
||||||
|
return await get_gerty(gerty_id)
|
||||||
|
|
||||||
async def get_gerty(gerty_id: str) -> Optional[Gerty]:
|
async def get_gerty(gerty_id: str) -> Optional[Gerty]:
|
||||||
row = await db.fetchone("SELECT * FROM gerty.gertys WHERE id = ?", (gerty_id,))
|
row = await db.fetchone("SELECT * FROM gerty.gertys WHERE id = ?", (gerty_id,))
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ async def m001_initial(db):
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
wallet TEXT NOT NULL,
|
wallet TEXT NOT NULL,
|
||||||
lnbits_wallets TEXT,
|
lnbits_wallets TEXT,
|
||||||
|
mempool_endpoint TEXT,
|
||||||
sats_quote BOOL,
|
sats_quote BOOL,
|
||||||
exchange TEXT,
|
exchange TEXT,
|
||||||
onchain_stats BOOL,
|
onchain_stats BOOL,
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,10 @@ class Gerty(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
wallet: str
|
wallet: str
|
||||||
lnbits_wallets: str = Query(None) # Wallets to keep an eye on, {"wallet-id": "wallet-read-key, etc"}
|
lnbits_wallets: str = Query(None) # Wallets to keep an eye on, {"wallet-id": "wallet-read-key, etc"}
|
||||||
|
mempool_endpoint: str = Query("https://mempool.space") # Mempool endpoint to use
|
||||||
sats_quote: bool = Query(False) # Fetch Satoshi quotes
|
sats_quote: bool = Query(False) # Fetch Satoshi quotes
|
||||||
exchange: str = Query(None) # BTC <-> Fiat exchange rate to pull ie "USD", in 0.0001 and sats
|
exchange: str = Query(None) # BTC <-> Fiat exchange rate to pull ie "USD", in 0.0001 and sats
|
||||||
onchain_sats: bool = Query(False) # Onchain stats
|
onchain_stats: bool = Query(False) # Onchain stats
|
||||||
ln_stats: bool = Query(False) # ln Sats
|
ln_stats: bool = Query(False) # ln Sats
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,23 @@
|
||||||
{% extends "public.html" %} {% block page %}
|
{% extends "public.html" %} {% block toolbar_title %} {{ gerty.name }}{% endblock %}{% block page %}
|
||||||
<div class="row q-col-gutter-md justify-center">
|
<div class="q-pa-md">
|
||||||
|
<div class="row q-col-gutter-md" >{% raw %}
|
||||||
|
<div class="col q-pr-sm" v-for="gertywallet in gertywallets" style="max-width:400px">
|
||||||
|
<div class="q-item q-item-type row no-wrap q-pa-none" :style="`background-color: ${walletColors[0].first}`">
|
||||||
|
<div class="q-item__section column q-pa-lg q-mr-none text-white q-item__section--side justify-center" :style="`background-color: ${walletColors[0].second}`" >
|
||||||
|
<i aria-hidden="true" role="presentation" class="material-icons q-icon notranslate text-white" style="font-size: 50px;">sentiment_satisfied</i></div>
|
||||||
|
<div class="q-item__section column q-pa-md q-ml-none text-white q-item__section--main justify-center" style="min-width:200px;">
|
||||||
|
<div class="q-item__label text-white text-h6 text-weight-bolder">{{gertywallet.amount}}</div><div class="q-item__label">Wallet: <b>{{gertywallet.name}}</b></div>
|
||||||
|
</div>{% endraw %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row q-col-gutter-md justify-center">
|
||||||
|
|
||||||
|
|
||||||
<div class="col-12 col-sm-6 col-md-5 col-lg-4">
|
<div class="col-12 col-sm-6 col-md-5 col-lg-4">
|
||||||
<q-card class="q-pa-lg">
|
<q-card class="q-pa-lg">
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
<div class="text-center">
|
|
||||||
<a href="lightning:{{ lnurl }}">
|
|
||||||
<q-responsive :ratio="1" class="q-mx-md">
|
|
||||||
<qrcode
|
|
||||||
value="{{ lnurl }}"
|
|
||||||
:options="{width: 800}"
|
|
||||||
class="rounded-borders"
|
|
||||||
></qrcode>
|
|
||||||
</q-responsive>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="row q-mt-lg q-gutter-sm">
|
<div class="row q-mt-lg q-gutter-sm">
|
||||||
<q-btn outline color="grey" @click="copyText('{{ lnurl }}')"
|
<q-btn outline color="grey" @click="copyText('{{ lnurl }}')"
|
||||||
>Copy LNURL</q-btn
|
>Copy LNURL</q-btn
|
||||||
|
|
@ -37,7 +41,6 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
<q-separator></q-separator>
|
<q-separator></q-separator>
|
||||||
<q-list> {% include "lnurlp/_lnurl.html" %} </q-list>
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -48,7 +51,45 @@
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
mixins: [windowMixin]
|
mixins: [windowMixin],
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
gertyName: '{{gerty.name}}',
|
||||||
|
walletColors: [
|
||||||
|
{first: "#3f51b5",
|
||||||
|
second: "#1a237e"},
|
||||||
|
{first: "#9c27b0",
|
||||||
|
second: "#4a148c"},
|
||||||
|
{first: "#e91e63",
|
||||||
|
second: "#880e4f"},
|
||||||
|
{first: "#009688",
|
||||||
|
second: "#004d40"},
|
||||||
|
{first: "#ff9800",
|
||||||
|
second: "#e65100"},
|
||||||
|
{first: "#2196f3",
|
||||||
|
second: "#0d47a1"},
|
||||||
|
{first: "#4caf50",
|
||||||
|
second: "#1b5e20"}
|
||||||
|
],
|
||||||
|
gertywallets: [{
|
||||||
|
name:"poo",
|
||||||
|
amount:"200"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:"poo",
|
||||||
|
amount:"200"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
},
|
||||||
|
created: function () {
|
||||||
|
console.log(this.gerty)
|
||||||
|
// if(){
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
{{ col.label }}
|
{{ col.label }}
|
||||||
</q-th>
|
</q-th>
|
||||||
<q-th auto-width></q-th>
|
<q-th auto-width></q-th>
|
||||||
|
<q-th auto-width></q-th>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -45,17 +46,27 @@
|
||||||
unelevated
|
unelevated
|
||||||
dense
|
dense
|
||||||
size="xs"
|
size="xs"
|
||||||
icon="launch"
|
icon="sentiment_satisfied"
|
||||||
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
|
||||||
type="a"
|
type="a"
|
||||||
:href="props.row.gerty"
|
:href="props.row.gerty"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
></q-btn>
|
><q-tooltip>Launch software Gerty</q-tooltip></q-btn>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
{{ (col.name == 'tip_options' && col.value ?
|
{{ (col.name == 'tip_options' && col.value ?
|
||||||
JSON.parse(col.value).join(", ") : col.value) }}
|
JSON.parse(col.value).join(", ") : col.value) }}
|
||||||
</q-td>
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="updateformDialog(props.row.id)"
|
||||||
|
icon="edit"
|
||||||
|
color="light-blue"
|
||||||
|
></q-btn>
|
||||||
|
</q-td>
|
||||||
<q-td auto-width>
|
<q-td auto-width>
|
||||||
<q-btn
|
<q-btn
|
||||||
flat
|
flat
|
||||||
|
|
@ -90,7 +101,7 @@
|
||||||
|
|
||||||
<q-dialog v-model="formDialog.show" position="top" @hide="closeFormDialog">
|
<q-dialog v-model="formDialog.show" position="top" @hide="closeFormDialog">
|
||||||
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
|
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
|
||||||
<q-form @submit="createGerty" class="q-gutter-md">
|
<q-form @submit="sendFormDataGerty" class="q-gutter-md">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
|
|
@ -106,12 +117,19 @@
|
||||||
:options="g.user.walletOptions"
|
:options="g.user.walletOptions"
|
||||||
label="Wallet *"
|
label="Wallet *"
|
||||||
></q-select>
|
></q-select>
|
||||||
<q-input
|
<q-select
|
||||||
filled
|
filled
|
||||||
|
multiple
|
||||||
dense
|
dense
|
||||||
v-model.trim="formDialog.data.lnbits_wallets"
|
emit-value
|
||||||
label="Wallets to watch (invoice keys, seperated by comma)"
|
v-model="formDialog.data.lnbits_wallets"
|
||||||
></q-input>
|
use-input
|
||||||
|
use-chips
|
||||||
|
multiple
|
||||||
|
hide-dropdown-icon
|
||||||
|
new-value-mode="add-unique"
|
||||||
|
label="Wallets to watch"
|
||||||
|
><q-tooltip>Hit enter to add values</q-tooltip></q-select>
|
||||||
<q-select
|
<q-select
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
|
|
@ -138,8 +156,17 @@
|
||||||
color="primary"
|
color="primary"
|
||||||
:disable="formDialog.data.wallet == null || formDialog.data.name == null"
|
:disable="formDialog.data.wallet == null || formDialog.data.name == null"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
class="q-mr-md"
|
||||||
>Create Gerty</q-btn
|
>Create Gerty</q-btn
|
||||||
>
|
>
|
||||||
|
<q-btn
|
||||||
|
v-if="formDialog.data.id"
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
:disable="formDialog.data.wallet == null || formDialog.data.name == null"
|
||||||
|
type="submit"
|
||||||
|
>Update Gerty</q-btn
|
||||||
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||||
>Cancel</q-btn
|
>Cancel</q-btn
|
||||||
>
|
>
|
||||||
|
|
@ -383,15 +410,17 @@
|
||||||
show: false,
|
show: false,
|
||||||
data: {sats_quote: false,
|
data: {sats_quote: false,
|
||||||
onchain_stats: false,
|
onchain_stats: false,
|
||||||
ln_stats: false}
|
ln_stats: false,
|
||||||
|
lnbits_wallets:[]}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeFormDialog: function () {
|
closeFormDialog: function () {
|
||||||
this.formDialog.data = {sats_quote: false,
|
this.formDialog.data = {sats_quote: false,
|
||||||
onchain_sats: false,
|
onchain_stats: false,
|
||||||
ln_stats: false}
|
ln_stats: false,
|
||||||
|
lnbits_wallets:[]}
|
||||||
},
|
},
|
||||||
getGertys: function () {
|
getGertys: function () {
|
||||||
var self = this
|
var self = this
|
||||||
|
|
@ -407,14 +436,40 @@
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
updateformDialog: function (formId) {
|
||||||
|
var gerty = _.findWhere(this.gertys, {id: formId})
|
||||||
|
this.formDialog.data.id = gerty.id
|
||||||
|
this.formDialog.data.name = gerty.name
|
||||||
|
this.formDialog.data.wallet = gerty.wallet
|
||||||
|
this.formDialog.data.lnbits_wallets = JSON.parse(gerty.lnbits_wallets)
|
||||||
|
this.formDialog.data.exchange = gerty.exchange,
|
||||||
|
this.formDialog.data.sats_quote = Boolean(gerty.sats_quote)
|
||||||
|
this.formDialog.data.onchain_stats = Boolean(gerty.onchain_stats)
|
||||||
|
this.formDialog.data.ln_stats = Boolean(gerty.ln_stats)
|
||||||
|
this.formDialog.show = true
|
||||||
|
},
|
||||||
|
sendFormDataGerty: function () {
|
||||||
|
var self = this
|
||||||
|
if (self.formDialog.data.id) {
|
||||||
|
this.updateGerty(
|
||||||
|
self.g.user.wallets[0].adminkey,
|
||||||
|
self.formDialog.data
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
this.createGerty(
|
||||||
|
self.g.user.wallets[0].adminkey,
|
||||||
|
self.formDialog.data
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
createGerty: function () {
|
createGerty: function () {
|
||||||
var data = {
|
var data = {
|
||||||
name: this.formDialog.data.name,
|
name: this.formDialog.data.name,
|
||||||
wallet: this.formDialog.data.wallet,
|
wallet: this.formDialog.data.wallet,
|
||||||
lnbits_wallets: this.formDialog.data.lnbits_wallets,
|
lnbits_wallets: JSON.stringify(this.formDialog.data.lnbits_wallets),
|
||||||
sats_quote: this.formDialog.data.sats_quote,
|
sats_quote: this.formDialog.data.sats_quote,
|
||||||
exchange: this.formDialog.data.exchange,
|
exchange: this.formDialog.data.exchange,
|
||||||
onchain_sats: this.formDialog.data.onchain_sats,
|
onchain_stats: this.formDialog.data.onchain_stats,
|
||||||
ln_stats: this.formDialog.data.ln_stats
|
ln_stats: this.formDialog.data.ln_stats
|
||||||
}
|
}
|
||||||
var self = this
|
var self = this
|
||||||
|
|
@ -435,6 +490,27 @@
|
||||||
LNbits.utils.notifyApiError(error)
|
LNbits.utils.notifyApiError(error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
updateGerty: function (wallet, data) {
|
||||||
|
var self = this
|
||||||
|
data.lnbits_wallets = JSON.stringify(this.formDialog.data.lnbits_wallets)
|
||||||
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
'PUT',
|
||||||
|
'/gerty/api/v1/gerty/' + data.id,
|
||||||
|
wallet,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
.then(function (response) {
|
||||||
|
self.gertys = _.reject(self.gertys, function (obj) {
|
||||||
|
return obj.id == data.id
|
||||||
|
})
|
||||||
|
self.gertys.push(mapGerty(response.data))
|
||||||
|
self.formDialog.show = false
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
deleteGerty: function (gertyId) {
|
deleteGerty: function (gertyId) {
|
||||||
var self = this
|
var self = this
|
||||||
var gerty = _.findWhere(this.gertys, {id: gertyId})
|
var gerty = _.findWhere(this.gertys, {id: gertyId})
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ from lnbits.settings import LNBITS_CUSTOM_LOGO, LNBITS_SITE_TITLE
|
||||||
|
|
||||||
from . import gerty_ext, gerty_renderer
|
from . import gerty_ext, gerty_renderer
|
||||||
from .crud import get_gerty
|
from .crud import get_gerty
|
||||||
|
from .views_api import api_gerty_json
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
|
||||||
|
|
@ -28,4 +31,5 @@ async def display(request: Request, gerty_id):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.NOT_FOUND, detail="Gerty does not exist."
|
status_code=HTTPStatus.NOT_FOUND, detail="Gerty does not exist."
|
||||||
)
|
)
|
||||||
return lnurlp_renderer().TemplateResponse("gerty/gerty.html", ctx)
|
gertyData = await api_gerty_json(gerty_id)
|
||||||
|
return gerty_renderer().TemplateResponse("gerty/gerty.html", {"request": request, "gerty": gertyData})
|
||||||
|
|
@ -12,12 +12,12 @@ from starlette.exceptions import HTTPException
|
||||||
|
|
||||||
from lnbits.core.crud import get_user
|
from lnbits.core.crud import get_user
|
||||||
from lnbits.core.services import create_invoice
|
from lnbits.core.services import create_invoice
|
||||||
from lnbits.core.views.api import api_payment
|
from lnbits.core.views.api import api_payment, api_wallet
|
||||||
from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key
|
from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
from . import gerty_ext
|
from . import gerty_ext
|
||||||
from .crud import create_gerty, delete_gerty, get_gerty, get_gertys
|
from .crud import create_gerty, update_gerty, delete_gerty, get_gerty, get_gertys
|
||||||
from .models import Gerty
|
from .models import Gerty
|
||||||
|
|
||||||
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
|
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
|
||||||
|
|
@ -101,8 +101,13 @@ async def api_gerty_json(
|
||||||
)
|
)
|
||||||
gertyReturn = []
|
gertyReturn = []
|
||||||
if gerty.lnbits_wallets != "":
|
if gerty.lnbits_wallets != "":
|
||||||
gertyReturn.append(gerty.lnbitsWallets)
|
for lnbits_wallet in json.loads(gerty.lnbits_wallets):
|
||||||
|
logger.debug(lnbits_wallet)
|
||||||
|
walletPrint = await api_wallet(wallet=lnbits_wallet)
|
||||||
|
gertyReturn.wallets.append(walletPrint)
|
||||||
|
#logger.debug(walletPrint)
|
||||||
|
logger.debug(gertyReturn)
|
||||||
|
|
||||||
if gerty.sats_quote:
|
if gerty.sats_quote:
|
||||||
gertyReturn.append(await api_gerty_satoshi())
|
gertyReturn.append(await api_gerty_satoshi())
|
||||||
|
|
||||||
|
|
@ -111,7 +116,7 @@ async def api_gerty_json(
|
||||||
gertyReturn.append(await fiat_amount_as_satoshis(1, gerty.exchange))
|
gertyReturn.append(await fiat_amount_as_satoshis(1, gerty.exchange))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if gerty.onchain_sats:
|
if gerty.onchain_stats:
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
r = await client.get(gerty.mempool_endpoint + "/api/v1/difficulty-adjustment")
|
r = await client.get(gerty.mempool_endpoint + "/api/v1/difficulty-adjustment")
|
||||||
gertyReturn.append({"difficulty-adjustment": json.dumps(r)})
|
gertyReturn.append({"difficulty-adjustment": json.dumps(r)})
|
||||||
|
|
@ -124,7 +129,7 @@ async def api_gerty_json(
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
r = await client.get(gerty.mempool_endpoint + "/api/v1/lightning/statistics/latest")
|
r = await client.get(gerty.mempool_endpoint + "/api/v1/lightning/statistics/latest")
|
||||||
gertyReturn.append({"latest": json.dumps(r)})
|
gertyReturn.append({"latest": json.dumps(r)})
|
||||||
|
logger.debug(gertyReturn)
|
||||||
return gertyReturn
|
return gertyReturn
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue