diff --git a/.gitignore b/.gitignore index 0748bfb6..a0b28d67 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,5 @@ Pipfile.lock .env venv -database.sqlite3 -database.sqlite3* +*.sqlite3 .pyre* diff --git a/lnbits/__init__.py b/lnbits/__init__.py index d2cc7532..e2cfc219 100644 --- a/lnbits/__init__.py +++ b/lnbits/__init__.py @@ -1,5 +1,4 @@ import json -import os import requests import uuid @@ -9,26 +8,29 @@ from lnurl import Lnurl, LnurlWithdrawResponse from . import bolt11 from .core import core_app -from .db import open_db, open_ext_db +from .db import init_databases, open_db from .extensions.withdraw import withdraw_ext from .helpers import megajson -from .settings import LNBITS_PATH, WALLET, DEFAULT_USER_WALLET_NAME, FEE_RESERVE +from .settings import WALLET, DEFAULT_USER_WALLET_NAME, FEE_RESERVE app = Flask(__name__) -Talisman(app, content_security_policy={ - "default-src": [ - "'self'", - "'unsafe-eval'", - "'unsafe-inline'", - "cdnjs.cloudflare.com", - "code.ionicframework.com", - "code.jquery.com", - "fonts.googleapis.com", - "fonts.gstatic.com", - "maxcdn.bootstrapcdn.com", - ] -}) +Talisman( + app, + content_security_policy={ + "default-src": [ + "'self'", + "'unsafe-eval'", + "'unsafe-inline'", + "cdnjs.cloudflare.com", + "code.ionicframework.com", + "code.jquery.com", + "fonts.googleapis.com", + "fonts.gstatic.com", + "maxcdn.bootstrapcdn.com", + ] + }, +) # filters app.jinja_env.filters["megajson"] = megajson @@ -40,10 +42,7 @@ app.register_blueprint(withdraw_ext, url_prefix="/withdraw") @app.before_first_request def init(): - with open_db() as db: - with open(os.path.join(LNBITS_PATH, "data", "schema.sql")) as schemafile: - for stmt in schemafile.read().split(";\n\n"): - db.execute(stmt, []) + init_databases() @app.route("/deletewallet") @@ -447,38 +446,35 @@ def api_checkpending(): @app.route("/extensions") def extensions(): usr = request.args.get("usr") - lnevents = request.args.get("lnevents") - lnjoust = request.args.get("lnjoust") - withdraw = request.args.get("withdraw") - if usr: - if not len(usr) > 20: - return redirect(url_for("home")) + enable = request.args.get("enable") + disable = request.args.get("disable") + ext = None + + if usr and not len(usr) > 20: + return redirect(url_for("home")) + + if enable and disable: + # TODO: show some kind of error + return redirect(url_for("extensions")) with open_db() as db: user_wallets = db.fetchall("SELECT * FROM wallets WHERE user = ?", (usr,)) - with open_ext_db() as ext_db: - user_ext = ext_db.fetchall("SELECT * FROM overview WHERE user = ?", (usr,)) - if not user_ext: - ext_db.execute( - """ - INSERT OR IGNORE INTO overview (user) VALUES (?) - """, - (usr,), - ) - return redirect(url_for("extensions", usr=usr)) + if enable: + ext, value = enable, 1 + if disable: + ext, value = disable, 0 - if lnevents: - if int(lnevents) != user_ext[0][1] and int(lnevents) < 2: - ext_db.execute("UPDATE overview SET lnevents = ? WHERE user = ?", (int(lnevents), usr,)) - user_ext = ext_db.fetchall("SELECT * FROM overview WHERE user = ?", (usr,)) - if lnjoust: - if int(lnjoust) != user_ext[0][2] and int(lnjoust) < 2: - ext_db.execute("UPDATE overview SET lnjoust = ? WHERE user = ?", (int(lnjoust), usr,)) - user_ext = ext_db.fetchall("SELECT * FROM overview WHERE user = ?", (usr,)) - if withdraw: - if int(withdraw) != user_ext[0][3] and int(withdraw) < 2: - ext_db.execute("UPDATE overview SET withdraw = ? WHERE user = ?", (int(withdraw), usr,)) - user_ext = ext_db.fetchall("SELECT * FROM overview WHERE user = ?", (usr,)) + if ext: + db.execute( + """ + INSERT OR REPLACE INTO extensions (user, extension, active) + VALUES (?, ?, ?) + """, + (usr, ext, value), + ) + + user_ext = db.fetchall("SELECT extension FROM extensions WHERE user = ? AND active = 1", (usr,)) + user_ext = [v[0] for v in user_ext] return render_template("extensions.html", user_wallets=user_wallets, user=usr, user_ext=user_ext) diff --git a/lnbits/data/schema.sql b/lnbits/data/schema.sql index 2c9991d7..37fceb4d 100644 --- a/lnbits/data/schema.sql +++ b/lnbits/data/schema.sql @@ -1,39 +1,47 @@ CREATE TABLE IF NOT EXISTS accounts ( - id text PRIMARY KEY, - email text, - pass text + id TEXT PRIMARY KEY, + email TEXT, + pass TEXT +); + +CREATE TABLE IF NOT EXISTS extensions ( + user TEXT NOT NULL, + extension TEXT NOT NULL, + active BOOLEAN DEFAULT 0, + + UNIQUE (user, extension) ); CREATE TABLE IF NOT EXISTS wallets ( - id text PRIMARY KEY, - name text NOT NULL, - user text NOT NULL, - adminkey text NOT NULL, - inkey text + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + user TEXT NOT NULL, + adminkey TEXT NOT NULL, + inkey TEXT ); CREATE TABLE IF NOT EXISTS apipayments ( - payhash text NOT NULL, - amount integer NOT NULL, - fee integer NOT NULL DEFAULT 0, - wallet text NOT NULL, - pending boolean NOT NULL, - memo text, - time timestamp NOT NULL DEFAULT (strftime('%s', 'now')), + payhash TEXT NOT NULL, + amount INTEGER NOT NULL, + fee INTEGER NOT NULL DEFAULT 0, + wallet TEXT NOT NULL, + pending BOOLEAN NOT NULL, + memo TEXT, + time TIMESTAMP NOT NULL DEFAULT (strftime('%s', 'now')), UNIQUE (wallet, payhash) ); CREATE VIEW IF NOT EXISTS balances AS - SELECT wallet, coalesce(sum(s), 0) AS balance FROM ( - SELECT wallet, sum(amount) AS s -- incoming + SELECT wallet, COALESCE(SUM(s), 0) AS balance FROM ( + SELECT wallet, SUM(amount) AS s -- incoming FROM apipayments - WHERE amount > 0 AND pending = 0 -- don't sum pending + WHERE amount > 0 AND pending = 0 -- don't sum pending GROUP BY wallet UNION ALL - SELECT wallet, sum(amount + fee) AS s -- outgoing, sum fees + SELECT wallet, SUM(amount + fee) AS s -- outgoing, sum fees FROM apipayments - WHERE amount < 0 -- do sum pending + WHERE amount < 0 -- do sum pending GROUP BY wallet ) GROUP BY wallet; diff --git a/lnbits/db.py b/lnbits/db.py index fd7b21ca..a43c92c5 100644 --- a/lnbits/db.py +++ b/lnbits/db.py @@ -1,9 +1,7 @@ import os import sqlite3 -from typing import Optional - -from .settings import DATABASE_PATH, LNBITS_PATH +from .settings import LNBITS_PATH, LNBITS_DATA_FOLDER class Database: @@ -35,11 +33,28 @@ class Database: self.connection.commit() -def open_db(db_path: str = DATABASE_PATH) -> Database: +def open_db(db_name: str = "database") -> Database: + db_path = os.path.join(LNBITS_DATA_FOLDER, f"{db_name}.sqlite3") return Database(db_path=db_path) -def open_ext_db(extension: Optional[str] = None) -> Database: - if extension: - return open_db(os.path.join(LNBITS_PATH, "extensions", extension, "database.sqlite3")) - return open_db(os.path.join(LNBITS_PATH, "extensions", "overview.sqlite3")) +def open_ext_db(extension_name: str) -> Database: + return open_db(f"ext_{extension_name}") + + +def init_databases() -> None: + """Creates the necessary databases if they don't exist already.""" + """TODO: see how we can deal with migrations.""" + + schemas = [ + ("database", os.path.join(LNBITS_PATH, "data", "schema.sql")), + ] + + for extension in [x[1] for x in os.walk(os.path.join(LNBITS_PATH, "extensions"))][0]: + schemas.append((f"ext_{extension}", os.path.join(LNBITS_PATH, "extensions", extension, "schema.sql"))) + + for schema in [s for s in schemas if os.path.exists(s[1])]: + with open_db(schema[0]) as db: + with open(schema[1]) as schemafile: + for stmt in schemafile.read().split(";\n\n"): + db.execute(stmt, []) diff --git a/lnbits/extensions/overview.sqlite3 b/lnbits/extensions/overview.sqlite3 deleted file mode 100644 index b4957a1b..00000000 Binary files a/lnbits/extensions/overview.sqlite3 and /dev/null differ diff --git a/lnbits/extensions/withdraw/crud.py b/lnbits/extensions/withdraw/crud.py deleted file mode 100644 index e69de29b..00000000 diff --git a/lnbits/extensions/withdraw/database.sqlite3 b/lnbits/extensions/withdraw/database.sqlite3 deleted file mode 100644 index 1e84bb45..00000000 Binary files a/lnbits/extensions/withdraw/database.sqlite3 and /dev/null differ diff --git a/lnbits/extensions/withdraw/schema.sql b/lnbits/extensions/withdraw/schema.sql new file mode 100644 index 00000000..f0037fe3 --- /dev/null +++ b/lnbits/extensions/withdraw/schema.sql @@ -0,0 +1,18 @@ +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 +); diff --git a/lnbits/extensions/withdraw/templates/withdraw/index.html b/lnbits/extensions/withdraw/templates/withdraw/index.html index b334a2b8..c5ddc3e7 100644 --- a/lnbits/extensions/withdraw/templates/withdraw/index.html +++ b/lnbits/extensions/withdraw/templates/withdraw/index.html @@ -34,9 +34,9 @@