Browse Source

Unique withdraw printable

Working towards trying to make the unique withdraw links prinatble
WithdrawExt
benarc 5 years ago
parent
commit
da382c31ab
  1. 8
      lnbits/extensions/withdraw/config.json
  2. 18
      lnbits/extensions/withdraw/crud.py
  3. 77
      lnbits/extensions/withdraw/migrations.py
  4. 17
      lnbits/extensions/withdraw/models.py
  5. 1
      lnbits/extensions/withdraw/templates/withdraw/index.html
  6. 21
      lnbits/extensions/withdraw/templates/withdraw/print_qr.html
  7. 15
      lnbits/extensions/withdraw/views.py
  8. 16
      lnbits/extensions/withdraw/views_api.py

8
lnbits/extensions/withdraw/config.json

@ -1,6 +1,6 @@
{
"name": "LNURLw",
"short_description": "Make LNURL withdraw links",
"icon": "crop_free",
"contributors": ["arcbtc", "eillarra"]
"name": "LNURLw",
"short_description": "Vouchers/faucets/links",
"icon": "crop_free",
"contributors": ["arcbtc", "eillarra"]
}

18
lnbits/extensions/withdraw/crud.py

@ -51,14 +51,22 @@ def create_withdraw_link(
),
)
return get_withdraw_link(link_id)
return get_withdraw_link(link_id, 0)
def get_withdraw_link(link_id: str) -> Optional[WithdrawLink]:
def get_withdraw_link(link_id: str, unique_hash_int: int) -> Optional[WithdrawLink]:
with open_ext_db("withdraw") as db:
row = db.fetchone("SELECT * FROM withdraw_links WHERE id = ?", (link_id,))
return WithdrawLink.from_row(row) if row else None
withdraw = WithdrawLink.from_row(row) if row else None
if row["is_unique"] == 0:
return withdraw
if withdraw == None:
return withdraw
link = []
for item in row:
link.append(item)
link[12] = unique_hash_int
return WithdrawLink._make(link)
def get_withdraw_link_by_hash(unique_hash: str) -> Optional[WithdrawLink]:
@ -68,6 +76,7 @@ def get_withdraw_link_by_hash(unique_hash: str) -> Optional[WithdrawLink]:
return WithdrawLink.from_row(row) if row else None
def get_withdraw_links(wallet_ids: Union[str, List[str]]) -> List[WithdrawLink]:
if isinstance(wallet_ids, str):
wallet_ids = [wallet_ids]
@ -78,7 +87,6 @@ def get_withdraw_links(wallet_ids: Union[str, List[str]]) -> List[WithdrawLink]:
return [WithdrawLink.from_row(row) for row in rows]
def update_withdraw_link(link_id: str, **kwargs) -> Optional[WithdrawLink]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])

77
lnbits/extensions/withdraw/migrations.py

@ -5,34 +5,6 @@ from lnbits.helpers import urlsafe_short_hash
def m001_initial(db):
"""
Initial withdraw table.
"""
db.execute(
"""
CREATE TABLE IF NOT EXISTS withdraws (
key INTEGER PRIMARY KEY AUTOINCREMENT,
usr TEXT,
wal TEXT,
walnme TEXT,
adm INTEGER,
uni TEXT,
tit TEXT,
maxamt INTEGER,
minamt INTEGER,
spent INTEGER,
inc INTEGER,
tme INTEGER,
uniq INTEGER DEFAULT 0,
withdrawals TEXT,
tmestmp INTEGER,
rand TEXT
);
"""
)
def m002_change_withdraw_table(db):
"""
Creates an improved withdraw table and migrates the existing data.
"""
@ -50,52 +22,13 @@ def m002_change_withdraw_table(db):
unique_hash TEXT UNIQUE,
k1 TEXT,
open_time INTEGER,
used INTEGER DEFAULT 0
used INTEGER DEFAULT 0,
unique_hash_int INTEGER DEFAULT 0
);
"""
)
db.execute("CREATE INDEX IF NOT EXISTS wallet_idx ON withdraw_links (wallet)")
db.execute("CREATE UNIQUE INDEX IF NOT EXISTS unique_hash_idx ON withdraw_links (unique_hash)")
for row in [list(row) for row in db.fetchall("SELECT * FROM withdraws")]:
db.execute(
"""
INSERT INTO withdraw_links (
id,
wallet,
title,
min_withdrawable,
max_withdrawable,
uses,
wait_time,
is_unique,
unique_hash,
k1,
open_time,
used
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
row[5], # uni
row[2], # wal
row[6], # tit
row[8], # minamt
row[7], # maxamt
row[10], # inc
row[11], # tme
row[12], # uniq
urlsafe_short_hash(),
urlsafe_short_hash(),
int(datetime.now().timestamp()) + row[11],
row[9], # spent
),
)
db.execute("DROP TABLE withdraws")
""")
def migrate():
with open_ext_db("withdraw") as db:
m001_initial(db)
m002_change_withdraw_table(db)

17
lnbits/extensions/withdraw/models.py

@ -19,6 +19,7 @@ class WithdrawLink(NamedTuple):
k1: str
open_time: int
used: int
unique_hash_int: int
@classmethod
def from_row(cls, row: Row) -> "WithdrawLink":
@ -32,14 +33,24 @@ class WithdrawLink(NamedTuple):
@property
def lnurl(self) -> Lnurl:
scheme = "https" if FORCE_HTTPS else None
url = url_for("withdraw.api_lnurl_response", unique_hash=self.unique_hash, _external=True, _scheme=scheme)
scheme = "https" if FORCE_HTTPS else None
if self.is_unique == 1:
unique_hashs = self.unique_hash.split(",")
unique_hash = unique_hashs[- self.unique_hash_int]
else:
unique_hash = self.unique_hash
url = url_for("withdraw.api_lnurl_response", unique_hash=unique_hash, _external=True, _scheme=scheme)
return lnurl_encode(url)
@property
def lnurl_response(self) -> LnurlWithdrawResponse:
scheme = "https" if FORCE_HTTPS else None
url = url_for("withdraw.api_lnurl_callback", unique_hash=self.unique_hash, _external=True, _scheme=scheme)
if self.is_unique == 1:
unique_hashs = self.unique_hash.split(",")
unique_hash = unique_hashs[- self.unique_hash_int]
else:
unique_hash = self.unique_hash
url = url_for("withdraw.api_lnurl_callback", unique_hash=unique_hash, _external=True, _scheme=scheme)
return LnurlWithdrawResponse(
callback=url,

1
lnbits/extensions/withdraw/templates/withdraw/index.html

@ -274,7 +274,6 @@
>Shareable link</q-btn
>
<q-btn
v-if="!qrCodeDialog.data.is_unique"
outline
color="grey"
icon="print"

21
lnbits/extensions/withdraw/templates/withdraw/print_qr.html

@ -1,10 +1,11 @@
{% extends "print.html" %} {% block page %}
<div class="row justify-center">
<div class="col-12 col-sm-8 col-lg-6 text-center">
{% for i in range(link.uses) %}
{% if unique %} {% for i in range(links) %}
<div class="zimbabwe">
<div class="qr">
<qrcode value="{{ link.lnurl }}" :options="{width: 150}"></qrcode>
<qrcode value="{{ links[i].lnurl }}" :options="{width: 150}"></qrcode>
<br /><br />
<strong>{{ SITE_TITLE }}</strong><br />
<strong>{{ link.max_withdrawable }} FREE SATS</strong><br />
@ -12,7 +13,21 @@
</div>
<img src="{{ url_for('static', filename='images/note.jpg') }}" />
</div>
{% endfor %}
{% endfor %} {% elif not unique %} {% for i in range(link.uses) %}
<div class="zimbabwe">
<div class="qr">
<qrcode value="{{ links.lnurl }}" :options="{width: 150}"></qrcode>
<br /><br />
<strong>{{ SITE_TITLE }}</strong><br />
<strong>{{ link.max_withdrawable }} FREE SATS</strong><br />
<small>Scan and follow link<br />or use Lightning wallet</small>
</div>
<img src="{{ url_for('static', filename='images/note.jpg') }}" />
</div>
{% endfor %} {% endif %}
</div>
</div>
{% endblock %} {% block styles %}

15
lnbits/extensions/withdraw/views.py

@ -16,13 +16,20 @@ def index():
@withdraw_ext.route("/<link_id>")
def display(link_id):
link = get_withdraw_link(link_id) or abort(HTTPStatus.NOT_FOUND, "Withdraw link does not exist.")
link = get_withdraw_link(link_id, 0) or abort(HTTPStatus.NOT_FOUND, "Withdraw link does not exist.")
return render_template("withdraw/display.html", link=link)
@withdraw_ext.route("/print/<link_id>")
def print_qr(link_id):
link = get_withdraw_link(link_id) or abort(HTTPStatus.NOT_FOUND, "Withdraw link does not exist.")
return render_template("withdraw/print_qr.html", link=link)
links = []
link = get_withdraw_link(link_id, 0) or abort(HTTPStatus.NOT_FOUND, "Withdraw link does not exist.")
if link.is_unique == True:
unique_hashs = link.unique_hash.split(",")
count = 1
for item in unique_hashs:
links.append(get_withdraw_link(link_id, count))
count + 1
return render_template("withdraw/print_qr.html", link=link, unique=True, links=links)

16
lnbits/extensions/withdraw/views_api.py

@ -42,7 +42,7 @@ def api_links():
@withdraw_ext.route("/api/v1/links/<link_id>", methods=["GET"])
@api_check_wallet_key("invoice")
def api_link_retrieve(link_id):
link = get_withdraw_link(link_id)
link = get_withdraw_link(link_id, 0)
if not link:
return jsonify({"message": "Withdraw link does not exist."}), HTTPStatus.NOT_FOUND
@ -77,7 +77,7 @@ def api_link_create_or_update(link_id=None):
return jsonify({"message": "Insufficient balance."}), HTTPStatus.FORBIDDEN
if link_id:
link = get_withdraw_link(link_id)
link = get_withdraw_link(link_id, 0)
if not link:
return jsonify({"message": "Withdraw link does not exist."}), HTTPStatus.NOT_FOUND
@ -95,7 +95,7 @@ def api_link_create_or_update(link_id=None):
@withdraw_ext.route("/api/v1/links/<link_id>", methods=["DELETE"])
@api_check_wallet_key("admin")
def api_link_delete(link_id):
link = get_withdraw_link(link_id)
link = get_withdraw_link(link_id, 0)
if not link:
return jsonify({"message": "Withdraw link does not exist."}), HTTPStatus.NOT_FOUND
@ -120,9 +120,9 @@ def api_lnurl_response(unique_hash):
return jsonify(link.lnurl_response.dict()), HTTPStatus.OK
@withdraw_ext.route("/api/v1/lnurl/cb/<unique_hash>", methods=["GET"])
def api_lnurl_callback(unique_hash):
link = get_withdraw_link_by_hash(unique_hash)
@withdraw_ext.route("/api/v1/lnurl/cb/<link_id>", methods=["GET"])
def api_lnurl_callback(link_id):
link = get_withdraw_link_by_hash(link_id)
k1 = request.args.get("k1", type=str)
payment_request = request.args.get("pr", type=str)
now = int(datetime.now().timestamp())
@ -148,9 +148,9 @@ def api_lnurl_callback(unique_hash):
}
if link.is_unique:
changes["unique_hash"] = urlsafe_short_hash()
changes["unique_hash"] = link.unique_hash[:-1]
update_withdraw_link(link.id, **changes)
update_withdraw_link(link_id, **changes)
except ValueError as e:
return jsonify({"status": "ERROR", "reason": str(e)}), HTTPStatus.OK

Loading…
Cancel
Save