More refactor for dynamic apps

This commit is contained in:
Taylor Helsper 2021-04-25 14:25:49 -05:00
parent cbbdf5d31c
commit aceab30cec
18 changed files with 429 additions and 887 deletions

View File

@ -6,8 +6,6 @@ from bitcoin_info import *
from lightning_info import * from lightning_info import *
from electrum_info import * from electrum_info import *
from device_info import * from device_info import *
from dojo import get_dojo_status
from whirlpool import get_whirlpool_status
from thread_functions import * from thread_functions import *
from systemctl_info import * from systemctl_info import *
from application_info import * from application_info import *
@ -68,61 +66,14 @@ def api_get_service_status():
data = {} data = {}
data["status"] = "gray" data["status"] = "gray"
data["color"] = "" data["color"] = ""
data["ready"] = None data["sso_token"] = ""
service = request.args.get('service') service = request.args.get('service')
if service == "electrs":
data["status"], data["color"] = get_electrs_status_and_color()
elif service == "bitcoin":
data["status"], data["color"] = get_bitcoin_status_and_color()
elif service == "lnd":
data["status"], data["color"] = get_lnd_status_and_color()
elif service == "loop":
data["status"], data["color"] = get_loop_status_and_color()
elif service == "pool":
data["status"], data["color"] = get_pool_status_and_color()
elif service == "lit":
data["status"], data["color"] = get_lit_status_and_color()
elif service == "dojo":
data["status"], data["color"], dojo_initialized = get_dojo_status()
elif service == "rtl":
data["status"], data["color"] = get_rtl_status_and_color()
elif service == "mempool":
data["status"], data["color"] = get_mempool_status_and_color()
elif service == "whirlpool":
data["status"], data["color"], whirlpool_initialized = get_whirlpool_status()
elif service == "btcpayserver":
data["status"], data["color"] = get_btcpayserver_status_and_color()
elif service == "lndhub":
data["status"], data["color"] = get_lndhub_status_and_color()
elif service == "lndconnect":
data["status"], data["color"] = get_lndconnect_status_and_color()
elif service == "btcrpcexplorer":
data["status"], data["color"], data["ready"] = get_btcrpcexplorer_status_and_color_and_ready()
data["sso_token"] = get_btcrpcexplorer_sso_token()
elif service == "caravan":
data["status"], data["color"] = get_caravan_status_and_color()
elif service == "specter":
data["status"], data["color"] = get_specter_status_and_color()
elif service == "lnbits":
data["status"], data["color"] = get_lnbits_status_and_color()
elif service == "thunderhub":
data["status"], data["color"] = get_thunderhub_status_and_color()
data["sso_token"] = get_thunderhub_sso_token()
elif service == "ckbunker":
data["status"], data["color"] = get_ckbunker_status_and_color()
elif service == "sphinxrelay":
data["status"], data["color"] = get_sphinxrelay_status_and_color()
elif service == "tor":
data["status"] = "Private Connections"
data["color"] = get_service_status_color("tor@default")
elif service == "vpn":
data["status"], data["color"] = get_vpn_status_and_color()
elif service == "webssh2":
data["status"], data["color"] = get_webssh2_status_and_color()
else:
data["status"] = "unknown service"
# Try standard status API
data["status"] = get_application_status(service)
data["color"] = get_application_status_color(service)
data["sso_token"] = get_application_sso_token(service)
return jsonify(data) return jsonify(data)
@mynode_api.route("/api/get_device_info") @mynode_api.route("/api/get_device_info")
@ -135,6 +86,7 @@ def api_get_device_info():
data["ram"] = get_ram_usage() data["ram"] = get_ram_usage()
data["temp"] = get_device_temp() data["temp"] = get_device_temp()
data["is_installing_docker_images"] = is_installing_docker_images() data["is_installing_docker_images"] = is_installing_docker_images()
data["is_electrs_active"] = is_electrs_active()
return jsonify(data) return jsonify(data)

View File

@ -18,34 +18,68 @@ def is_installed(current_version):
def create_application(name="NAME", def create_application(name="NAME",
short_name="SHORT_NAME", short_name="SHORT_NAME",
app_tile_name=None,
is_premium=False, is_premium=False,
can_reinstall=True, can_reinstall=True,
can_uninstall=False, can_uninstall=False,
requires_lightning=False,
requires_electrs=False,
requires_bitcoin=False,
requires_docker_image_installation=False,
supports_testnet=False,
show_on_homepage=False, show_on_homepage=False,
show_on_application_page=True, show_on_application_page=True,
can_enable_disable=True, can_enable_disable=True,
icon="TODO", homepage_order=9999,
homepage_section="",
app_tile_button_text=None,
app_tile_default_status_text="",
app_tile_running_status_text="",
app_tile_button_href="#",
status="UNKNOWN", status="UNKNOWN",
log_file=None, log_file=None,
journalctl_log_name=None): journalctl_log_name=None,
):
app = {} app = {}
app["name"] = name app["name"] = name
app["short_name"] = short_name app["short_name"] = short_name
if app_tile_name != None:
app["app_tile_name"] = app_tile_name
else:
app["app_tile_name"] = name
app["is_premium"] = is_premium app["is_premium"] = is_premium
app["current_version"] = get_app_current_version(short_name) app["current_version"] = get_app_current_version(short_name)
app["latest_version"] = get_app_latest_version(short_name) app["latest_version"] = get_app_latest_version(short_name)
app["is_installed"] = is_installed(app["current_version"]) app["is_installed"] = is_installed(app["current_version"])
app["can_reinstall"] = can_reinstall app["can_reinstall"] = can_reinstall
app["can_uninstall"] = can_uninstall app["can_uninstall"] = can_uninstall
app["requires_lightning"] = requires_lightning
app["requires_electrs"] = requires_electrs
app["requires_bitcoin"] = requires_bitcoin
app["requires_docker_image_installation"] = requires_docker_image_installation
app["supports_testnet"] = supports_testnet
app["show_on_homepage"] = show_on_homepage app["show_on_homepage"] = show_on_homepage
app["show_on_application_page"] = show_on_application_page app["show_on_application_page"] = show_on_application_page
app["can_enable_disable"] = can_enable_disable app["can_enable_disable"] = can_enable_disable
app["is_enabled"] = is_service_enabled(short_name) app["is_enabled"] = is_service_enabled(short_name)
app["icon"] = icon
#app["status"] = status # Should status be optional to include? Takes lots of time. #app["status"] = status # Should status be optional to include? Takes lots of time.
#app["status_color"] = get_service_status_color(short_name) #app["status_color"] = get_service_status_color(short_name)
app["log_file"] = log_file app["log_file"] = log_file
app["journalctl_log_name"] = journalctl_log_name app["journalctl_log_name"] = journalctl_log_name
app["homepage_order"] = homepage_order
app["homepage_section"] = homepage_section
if app["homepage_section"] == "" and app["show_on_homepage"]:
app["homepage_section"] = "apps"
if app_tile_button_text != None:
app["app_tile_button_text"] = app_tile_button_text
else:
app["app_tile_button_text"] = app["app_tile_name"]
app["app_tile_default_status_text"] = app_tile_default_status_text
if app_tile_running_status_text != "":
app["app_tile_running_status_text"] = app_tile_running_status_text
else:
app["app_tile_running_status_text"] = app_tile_default_status_text
app["app_tile_button_href"] = app_tile_button_href
return app return app
def update_application(app): def update_application(app):
@ -61,34 +95,75 @@ def initialize_applications():
apps.append(create_application( apps.append(create_application(
name="Bitcoin", name="Bitcoin",
short_name="bitcoin", short_name="bitcoin",
app_tile_running_status_text="Running",
log_file=get_bitcoin_log_file() log_file=get_bitcoin_log_file()
)) ))
apps.append(create_application( apps.append(create_application(
name="LND", name="LND",
short_name="lnd", short_name="lnd",
app_tile_running_status_text="Running",
)) ))
apps.append(create_application( apps.append(create_application(
name="Loop", name="Loop",
short_name="loop", short_name="loop",
requires_lightning=True,
)) ))
apps.append(create_application( apps.append(create_application(
name="Pool", name="Pool",
short_name="pool", short_name="pool",
requires_lightning=True,
)) ))
apps.append(create_application( apps.append(create_application(
name="Lightning Terminal", name="Lightning Terminal",
short_name="lit", short_name="lit",
requires_lightning=True,
))
apps.append(create_application(
name="Ride the Lightning",
short_name="rtl",
app_tile_name="RTL",
app_tile_default_status_text="Lightning Wallet",
show_on_homepage=True,
requires_lightning=True,
supports_testnet=True,
homepage_order=11
)) ))
apps.append(create_application( apps.append(create_application(
name="Electrum Server", name="Electrum Server",
short_name="electrs", short_name="electrs",
app_tile_button_text="Info",
app_tile_button_href="/electrum-server",
app_tile_default_status_text="",
app_tile_running_status_text="Running",
can_reinstall=False, can_reinstall=False,
show_on_homepage=True show_on_homepage=True,
supports_testnet=True,
homepage_order=12
)) ))
apps.append(create_application( apps.append(create_application(
name="BTC RPC Explorer", name="BTCPay Server",
short_name="btcrpcexplorer", short_name="btcpayserver",
show_on_homepage=True app_tile_default_status_text="Merchant Tool",
requires_lightning=True,
show_on_homepage=True,
homepage_order=13
))
apps.append(create_application(
name="Mempool",
short_name="mempool",
app_tile_default_status_text="Mempool Viewer",
show_on_homepage=True,
supports_testnet=True,
requires_docker_image_installation=True,
homepage_order=14
))
apps.append(create_application(
name="LND Hub",
short_name="lndhub",
app_tile_default_status_text="BlueWallet Backend",
requires_lightning=True,
show_on_homepage=True,
homepage_order=15
)) ))
apps.append(create_application( apps.append(create_application(
name="Corsproxy", name="Corsproxy",
@ -101,88 +176,118 @@ def initialize_applications():
short_name="lndconnect", short_name="lndconnect",
)) ))
apps.append(create_application( apps.append(create_application(
name="LND Hub", name="BTC RPC Explorer",
short_name="lndhub", short_name="btcrpcexplorer",
show_on_homepage=True app_tile_name="Explorer",
)) app_tile_default_status_text="BTC RPC Explorer",
apps.append(create_application( requires_bitcoin=True,
name="Ride the Lightning", show_on_homepage=True,
short_name="rtl", supports_testnet=True,
show_on_homepage=True requires_electrs=True,
)) homepage_order=21
apps.append(create_application(
name="BTCPay Server",
short_name="btcpayserver",
show_on_homepage=True
))
apps.append(create_application(
name="Mempool",
short_name="mempool",
show_on_homepage=True
))
apps.append(create_application(
name="Whirlpool",
short_name="whirlpool",
show_on_homepage=True
)) ))
apps.append(create_application( apps.append(create_application(
name="Dojo", name="Dojo",
short_name="dojo", short_name="dojo",
app_tile_button_text="Info",
app_tile_button_href="/dojo",
app_tile_default_status_text="Mixing Tool",
show_on_application_page=True, show_on_application_page=True,
show_on_homepage=True show_on_homepage=True,
requires_electrs=True,
requires_docker_image_installation=True,
homepage_order=22
)) ))
apps.append(create_application( apps.append(create_application(
name="Joinmarket", name="Whirlpool",
short_name="joinmarket", short_name="whirlpool",
app_tile_button_text="Info",
app_tile_button_href="/whirlpool",
app_tile_default_status_text="Mixing Tool",
show_on_homepage=True, show_on_homepage=True,
is_premium=True homepage_order=23
)) ))
apps.append(create_application( apps.append(create_application(
name="JoininBox", name="JoininBox",
short_name="joininbox", short_name="joininbox",
app_tile_button_text="Info",
app_tile_button_href="/joininbox",
app_tile_default_status_text="JoinMarket Mixing",
show_on_homepage=True, show_on_homepage=True,
homepage_order=24,
can_enable_disable=False, can_enable_disable=False,
is_premium=True, is_premium=True,
)) ))
apps.append(create_application( apps.append(create_application(
name="Thunderhub", name="Joinmarket",
short_name="thunderhub", short_name="joinmarket",
show_on_homepage=True,
is_premium=True is_premium=True
)) ))
apps.append(create_application( apps.append(create_application(
name="LNbits", name="Thunderhub",
short_name="lnbits", short_name="thunderhub",
app_tile_default_status_text="Lightning Wallet",
requires_lightning=True,
supports_testnet=True,
show_on_homepage=True, show_on_homepage=True,
homepage_order=25,
is_premium=True is_premium=True
)) ))
apps.append(create_application( apps.append(create_application(
name="Caravan", name="Caravan",
short_name="caravan", short_name="caravan",
requires_bitcoin=True,
app_tile_button_text="Info",
app_tile_button_href="/caravan",
app_tile_default_status_text="Multisig Tool",
show_on_homepage=True, show_on_homepage=True,
homepage_order=31,
supports_testnet=True,
is_premium=True is_premium=True
)) ))
apps.append(create_application( apps.append(create_application(
name="Specter", name="Specter",
short_name="specter", short_name="specter",
requires_bitcoin=True,
app_tile_default_status_text="Multisig Tool",
show_on_homepage=True, show_on_homepage=True,
homepage_order=32,
supports_testnet=True,
is_premium=True is_premium=True
)) ))
apps.append(create_application( apps.append(create_application(
name="CKBunker", name="CKBunker",
short_name="ckbunker", short_name="ckbunker",
requires_bitcoin=True,
app_tile_default_status_text="Coldcard Signing Tool",
show_on_homepage=True, show_on_homepage=True,
homepage_order=33,
supports_testnet=True,
is_premium=True is_premium=True
)) ))
apps.append(create_application( apps.append(create_application(
name="Sphinx Relay", name="Sphinx Relay",
short_name="sphinxrelay", short_name="sphinxrelay",
app_tile_button_text="Info",
app_tile_button_href="/sphinxrelay",
app_tile_default_status_text="Chat",
requires_lightning=True,
show_on_homepage=True, show_on_homepage=True,
homepage_order=34,
is_premium=True
))
apps.append(create_application(
name="LNbits",
short_name="lnbits",
requires_lightning=True,
app_tile_default_status_text="Lightning Wallet",
show_on_homepage=True,
homepage_order=35,
is_premium=True is_premium=True
)) ))
apps.append(create_application( apps.append(create_application(
name="Web SSH", name="Web SSH",
short_name="webssh2" short_name="webssh2",
)) ))
apps.append(create_application( apps.append(create_application(
name="Netdata", name="Netdata",
@ -192,15 +297,28 @@ def initialize_applications():
apps.append(create_application( apps.append(create_application(
name="Tor", name="Tor",
short_name="tor", short_name="tor",
can_enable_disable=False,
app_tile_button_text="Tor Services",
app_tile_default_status_text="Private Connections",
app_tile_button_href="/tor",
show_on_homepage=True,
show_on_application_page=False, show_on_application_page=False,
journalctl_log_name="tor@default" journalctl_log_name="tor@default",
homepage_section="remote_services",
supports_testnet=True,
is_premium=True,
)) ))
apps.append(create_application( apps.append(create_application(
name="VPN", name="VPN",
short_name="vpn", short_name="vpn",
show_on_homepage=True,
can_reinstall=False, can_reinstall=False,
show_on_application_page=False app_tile_button_text="Info",
app_tile_button_href="/vpn-info",
show_on_homepage=True,
show_on_application_page=False,
homepage_section="remote_services",
supports_testnet=True,
is_premium=True,
)) ))
apps.append(create_application( apps.append(create_application(
name="NGINX", name="NGINX",
@ -232,6 +350,8 @@ def get_all_applications(order_by="none"):
apps = copy.deepcopy(mynode_applications) apps = copy.deepcopy(mynode_applications)
if order_by == "alphabetic": if order_by == "alphabetic":
apps.sort(key=lambda x: x["name"]) apps.sort(key=lambda x: x["name"])
elif order_by == "homepage":
apps.sort(key=lambda x: x["homepage_order"])
return apps return apps
@ -272,6 +392,118 @@ def get_application_log(short_name):
else: else:
return "ERROR: App or log not found ({})".format(short_name) return "ERROR: App or log not found ({})".format(short_name)
def get_application_status_special(short_name):
if short_name == "bitcoin":
return get_bitcoin_status()
elif short_name == "lnd":
return get_lnd_status()
elif short_name == "vpn":
if os.path.isfile("/home/pivpn/ovpns/mynode_vpn.ovpn"):
return "Running"
else:
return "Setting up..."
elif short_name == "electrs":
return get_electrs_status()
elif short_name == "whirlpool":
if not os.path.isfile("/mnt/hdd/mynode/whirlpool/whirlpool-cli-config.properties"):
return "Waiting for initialization..."
elif short_name == "dojo":
try:
dojo_initialized = subprocess.check_output("docker inspect --format={{.State.Running}} db", shell=True).strip()
except:
dojo_initialized = ""
if dojo_initialized != "true":
return "Error"
return ""
def get_application_status(short_name):
# Make sure app is valid
if not is_application_valid(short_name):
return "APP NOT FOUND"
# Get application
app = get_application(short_name)
# Check Disabled, Testnet, Lightning, Electrum requirements...
if is_testnet_enabled() and not app["supports_testnet"]:
return "Requires Mainnet"
if app["requires_docker_image_installation"] and is_installing_docker_images():
return "Installing..."
if not app["is_enabled"]:
return app["app_tile_default_status_text"]
if app["requires_bitcoin"] and not is_bitcoin_synced():
return "Waiting on Bitcoin"
if app["requires_lightning"] and not is_lnd_ready():
return "Waiting on Lightning"
if app["requires_electrs"] and not is_electrs_active():
return "Waiting on Electrum"
# Check special cases
special_status = get_application_status_special(short_name)
if special_status != "":
return special_status
# Return
return app["app_tile_running_status_text"]
def get_application_status_color_special(short_name):
if short_name == "lnd":
return get_lnd_status_color()
elif short_name == "joininbox":
return "clear"
elif short_name == "whirlpool":
if not os.path.isfile("/mnt/hdd/mynode/whirlpool/whirlpool-cli-config.properties"):
return "yellow"
elif short_name == "dojo":
try:
dojo_initialized = subprocess.check_output("docker inspect --format={{.State.Running}} db", shell=True).strip()
except:
dojo_initialized = ""
if dojo_initialized != "true":
return "red"
return ""
def get_application_status_color(short_name):
# Make sure app is valid
if not is_application_valid(short_name):
return "gray"
# Get application
app = get_application(short_name)
# Check Disabled, Testnet, Lightning, Electrum requirements...
if is_testnet_enabled() and not app["supports_testnet"]:
return "gray"
if app["requires_docker_image_installation"] and is_installing_docker_images():
return "yellow"
if app["can_enable_disable"] and not app["is_enabled"]:
return "gray"
if app["requires_bitcoin"] and not is_bitcoin_synced():
return "yellow"
if app["requires_lightning"] and not is_lnd_ready():
return "yellow"
if app["requires_electrs"] and not is_electrs_active():
return "yellow"
# Check special cases
special_status_color = get_application_status_color_special(short_name)
if special_status_color != "":
return special_status_color
# Return service operational status
return get_service_status_color(short_name)
def get_application_sso_token(short_name):
# Make sure app is valid
if not is_application_valid(short_name):
return "APP NOT FOUND"
if short_name == "btcrpcexplorer":
return get_btcrpcexplorer_sso_token()
if short_name == "thunderhub":
return get_thunderhub_sso_token()
return ""
def restart_application(short_name): def restart_application(short_name):
try: try:
subprocess.check_output('systemctl restart {}'.format(short_name), shell=True) subprocess.check_output('systemctl restart {}'.format(short_name), shell=True)

View File

@ -1,13 +1,13 @@
from config import * from config import *
from threading import Timer from threading import Timer
from werkzeug.routing import RequestRedirect from werkzeug.routing import RequestRedirect
from flask import flash from flask import flash, redirect
from utilities import * from utilities import *
from enable_disable_functions import * from enable_disable_functions import *
from lightning_info import is_lnd_ready, get_lnd_status, get_lnd_status_color from lightning_info import is_lnd_ready
from systemctl_info import * from systemctl_info import *
from electrum_info import get_electrs_status, is_electrs_active from electrum_info import get_electrs_status, is_electrs_active
from bitcoin_info import get_bitcoin_status, is_bitcoin_synced from bitcoin_info import is_bitcoin_synced
from datetime import timedelta from datetime import timedelta
import time import time
import json import json
@ -460,227 +460,6 @@ def get_drive_info(drive):
return data return data
#==================================
# Specific Service Status / Colors
#==================================
def get_bitcoin_status_and_color():
status = ""
color = "gray"
if get_service_status_code("bitcoin") == 0:
status = get_bitcoin_status()
color = "green"
else:
status = "Error"
color = "red"
return status,color
def get_lnd_status_and_color():
status = get_lnd_status()
color = get_lnd_status_color()
return status,color
def get_loop_status_and_color():
status = "Not Displayed"
color = "gray"
if is_lnd_ready():
color = get_service_status_color("loop")
return status,color
def get_pool_status_and_color():
status = "Not Displayed"
color = "gray"
if is_lnd_ready():
color = get_service_status_color("loop")
return status,color
def get_lit_status_and_color():
status = "Not Displayed"
color = "gray"
if is_lnd_ready():
color = get_service_status_color("loop")
return status,color
def get_lndconnect_status_and_color():
status = "Not Displayed"
color = get_service_status_color("lndconnect")
return status,color
def get_vpn_status_and_color():
status = ""
color = "gray"
if is_service_enabled("vpn"):
color = get_service_status_color("vpn")
status_code = get_service_status_code("vpn")
if status_code != 0:
status = "Unknown"
else:
if os.path.isfile("/home/pivpn/ovpns/mynode_vpn.ovpn"):
status = "Running"
else:
status = "Setting up..."
return status,color
def get_rtl_status_and_color():
status = "Lightning Wallet"
color = "gray"
if is_lnd_ready():
if is_service_enabled("rtl"):
status_code = get_service_status_code("rtl")
if status_code != 0:
color = "red"
else:
color = "green"
else:
status = "Waiting on Lightning"
return status,color
def get_lnbits_status_and_color():
color = "gray"
status = "Lightning Wallet"
if is_testnet_enabled():
return "Requires Mainnet", "gray"
if is_lnd_ready():
if is_service_enabled("lnbits"):
status_code = get_service_status_code("lnbits")
if status_code != 0:
color = "red"
else:
color = "green"
else:
status = "Waiting on Lightning"
return status,color
def get_thunderhub_status_and_color():
color = "gray"
status = "Lightning Wallet"
if is_lnd_ready():
if is_service_enabled("thunderhub"):
status_code = get_service_status_code("thunderhub")
if status_code != 0:
color = "red"
else:
color = "green"
else:
status = "Waiting on Lightning"
return status,color
def get_ckbunker_status_and_color():
status = "Coldcard Signing Tool"
color = "gray"
if is_bitcoin_synced():
if is_service_enabled("ckbunker"):
color = get_service_status_color("ckbunker")
else:
status = "Waiting on Bitcoin"
return status,color
def get_sphinxrelay_status_and_color():
color = "gray"
status = "Chat"
if is_testnet_enabled():
return "Requires Mainnet", "gray"
if is_lnd_ready():
if is_service_enabled("sphinxrelay"):
status_code = get_service_status_code("sphinxrelay")
if status_code != 0:
color = "red"
else:
color = "green"
else:
status = "Waiting on Lightning"
return status,color
def get_lndhub_status_and_color():
status = "BlueWallet Backend"
color = "gray"
if is_testnet_enabled():
return "Requires Mainnet", "gray"
if is_lnd_ready():
if is_service_enabled("lndhub"):
color = get_service_status_color("lndhub")
else:
status = "Waiting on Lightning"
return status,color
def get_btcpayserver_status_and_color():
status = "Merchant Tool"
color = "gray"
if is_testnet_enabled():
return "Requires Mainnet", "gray"
if is_lnd_ready():
color = get_service_status_color("btcpayserver")
else:
status = "Waiting on Lightning"
return status,color
def get_electrs_status_and_color():
status = ""
color = "gray"
if is_service_enabled("electrs"):
status_code = get_service_status_code("electrs")
color = get_service_status_color("electrs")
if status_code == 0:
status = get_electrs_status()
return status,color
def get_btcrpcexplorer_status_and_color_and_ready():
status = "BTC RPC Explorer"
color = "gray"
ready = False
if is_service_enabled("btcrpcexplorer"):
if is_bitcoin_synced():
if is_electrs_active():
color = get_service_status_color("btcrpcexplorer")
status_code = get_service_status_code("btcrpcexplorer")
if status_code == 0:
ready = True
else:
color = "yellow"
status = "Waiting on Electrum"
else:
color = "yellow"
status = "Waiting on Bitcoin"
return status,color,ready
def get_caravan_status_and_color():
status = ""
color = "gray"
if is_service_enabled("caravan"):
color = get_service_status_color("caravan")
status = "Running"
return status,color
def get_specter_status_and_color():
status = ""
color = "gray"
if is_service_enabled("specter"):
color = get_service_status_color("specter")
status = "Running"
return status,color
def get_mempool_status_and_color():
status = "Mempool Viewer"
color = "gray"
if is_service_enabled("mempool"):
if is_installing_docker_images():
color = "yellow"
status = "Installing..."
else:
color = get_service_status_color("mempool")
return status,color
def get_webssh2_status_and_color():
status = "Web SSH"
color = "gray"
if is_service_enabled("webssh2"):
if is_installing_docker_images():
color = "yellow"
status = "Installing..."
else:
color = get_service_status_color("webssh2")
return status,color
#================================== #==================================
# UI Functions # UI Functions
#================================== #==================================

View File

@ -5,6 +5,7 @@ from user_management import check_logged_in
from enable_disable_functions import * from enable_disable_functions import *
from bitcoin_info import get_mynode_block_height from bitcoin_info import get_mynode_block_height
from electrum_info import get_electrs_status, is_electrs_active from electrum_info import get_electrs_status, is_electrs_active
from application_info import *
import subprocess import subprocess
import re import re
import os import os
@ -12,6 +13,15 @@ import os
mynode_dojo = Blueprint('mynode_dojo',__name__) mynode_dojo = Blueprint('mynode_dojo',__name__)
## Status and color ## Status and color
def is_dojo_initialized():
try:
dojo_initialized = subprocess.check_output("docker inspect --format={{.State.Running}} db", shell=True)
dojo_initialized = dojo_initialized.strip()
except:
dojo_initialized = ""
return dojo_initialized == "true"
def get_dojo_status(): def get_dojo_status():
# Find dojo status # Find dojo status
dojo_status = "Disabled" dojo_status = "Disabled"
@ -20,22 +30,17 @@ def get_dojo_status():
if is_installing_docker_images(): if is_installing_docker_images():
dojo_status = "Installing..." dojo_status = "Installing..."
dojo_status_color = "yellow" dojo_status_color = "yellow"
dojo_initialized = "" return dojo_status, dojo_status_color
return dojo_status, dojo_status_color, dojo_initialized
if is_testnet_enabled(): if is_testnet_enabled():
dojo_status = "Requires Mainnet" dojo_status = "Requires Mainnet"
dojo_status_color = "gray" dojo_status_color = "gray"
dojo_initialized = "" return dojo_status, dojo_status_color
return dojo_status, dojo_status_color, dojo_initialized
init = is_dojo_initialized()
try:
dojo_initialized = subprocess.check_output("docker inspect --format={{.State.Running}} db", shell=True)
dojo_initialized = dojo_initialized.strip()
except:
dojo_initialized = ""
if is_service_enabled("dojo"): if is_service_enabled("dojo"):
if dojo_initialized != "false": if init:
if is_electrs_active(): if is_electrs_active():
dojo_status = "Running" dojo_status = "Running"
dojo_status_color = "green" dojo_status_color = "green"
@ -45,9 +50,8 @@ def get_dojo_status():
else: else:
dojo_status = "Issue Starting" dojo_status = "Issue Starting"
dojo_status_color = "red" dojo_status_color = "red"
dojo_initialized = ""
return dojo_status, dojo_status_color, dojo_initialized return dojo_status, dojo_status_color
def get_dojo_tracker_status(): def get_dojo_tracker_status():
try: try:
@ -116,7 +120,12 @@ def dojo_page():
admin_key = get_dojo_admin_key() admin_key = get_dojo_admin_key()
dojo_v3_addr = get_dojo_addr() dojo_v3_addr = get_dojo_addr()
dojo_status, dojo_status_color, dojo_initialized = get_dojo_status() dojo_status = "Running"
dojo_status_code = get_service_status_code("dojo")
if not is_dojo_initialized():
dojo_status = "Issue Starting"
elif dojo_status_code != 0:
dojo_status = "Error"
# Load page # Load page
templateData = { templateData = {
@ -125,9 +134,7 @@ def dojo_page():
"is_dojo_installed": is_dojo_installed(), "is_dojo_installed": is_dojo_installed(),
"dojo_status": dojo_status, "dojo_status": dojo_status,
"dojo_version": get_dojo_version(), "dojo_version": get_dojo_version(),
"dojo_status_color": dojo_status_color,
"dojo_enabled": is_service_enabled("dojo"), "dojo_enabled": is_service_enabled("dojo"),
"dojo_initialized": dojo_initialized,
"dojo_tracker_status": get_dojo_tracker_status(), "dojo_tracker_status": get_dojo_tracker_status(),
"electrs_status": get_electrs_status(), "electrs_status": get_electrs_status(),
"NODE_ADMIN_KEY": admin_key, "NODE_ADMIN_KEY": admin_key,
@ -138,6 +145,5 @@ def dojo_page():
@mynode_dojo.route("/restart-dojo") @mynode_dojo.route("/restart-dojo")
def page_restart_dojo(): def page_restart_dojo():
check_logged_in() check_logged_in()
disable_dojo() restart_service("dojo")
enable_dojo()
return redirect("/dojo") return redirect("/dojo")

View File

@ -1,15 +1,16 @@
import os import os
import subprocess import subprocess
from werkzeug.routing import RequestRedirect
from config import * from config import *
from systemctl_info import * from systemctl_info import *
# Generic Enable / Disable Function # Generic Enable / Disable Function
def enable_service(short_name): def enable_service(short_name):
enable_actions(short_name)
os.system("systemctl enable {} --no-pager".format(short_name)) os.system("systemctl enable {} --no-pager".format(short_name))
os.system("systemctl start {} --no-pager".format(short_name)) os.system("systemctl start {} --no-pager".format(short_name))
open("/mnt/hdd/mynode/settings/{}_enabled".format(short_name), 'a').close() # touch file open("/mnt/hdd/mynode/settings/{}_enabled".format(short_name), 'a').close() # touch file
clear_service_enabled_cache() clear_service_enabled_cache()
enable_actions(short_name)
def disable_service(short_name): def disable_service(short_name):
enabled_file = "/mnt/hdd/mynode/settings/{}_enabled".format(short_name) enabled_file = "/mnt/hdd/mynode/settings/{}_enabled".format(short_name)
@ -22,7 +23,10 @@ def disable_service(short_name):
# Functions to handle special enable/disable cases # Functions to handle special enable/disable cases
def enable_actions(short_name): def enable_actions(short_name):
pass if short_name == "dojo":
if not is_dojo_installed():
install_dojo()
raise RequestRedirect("/settings/reboot-device")
def disable_actions(short_name): def disable_actions(short_name):
if short_name == "electrs": if short_name == "electrs":
@ -33,7 +37,9 @@ def disable_actions(short_name):
os.system("systemctl stop openvpn --no-pager") os.system("systemctl stop openvpn --no-pager")
os.system("systemctl disable openvpn --no-pager") os.system("systemctl disable openvpn --no-pager")
# Function to restart service
def restart_service(short_name):
os.system("systemctl restart {} --no-pager".format(short_name))
# Dojo install / uninstall functions.... future work to abstract this # Dojo install / uninstall functions.... future work to abstract this
@ -47,6 +53,6 @@ def install_dojo():
def uninstall_dojo(): def uninstall_dojo():
os.system("rm -f " + DOJO_INSTALL_FILE) os.system("rm -f " + DOJO_INSTALL_FILE)
os.system("rf -f /mnt/hdd/mynode/settings/dojo_url") os.system("rf -f /mnt/hdd/mynode/settings/dojo_url")
disable_dojo() disable_service("dojo")
os.system("sync") os.system("sync")

View File

@ -4,8 +4,8 @@ from flask import Flask, render_template, Markup, send_from_directory, redirect,
from user_management import * from user_management import *
from api import mynode_api from api import mynode_api
from bitcoin import mynode_bitcoin from bitcoin import mynode_bitcoin
from whirlpool import mynode_whirlpool, get_whirlpool_status from whirlpool import mynode_whirlpool
from dojo import mynode_dojo, get_dojo_status from dojo import mynode_dojo
from joininbox import mynode_joininbox from joininbox import mynode_joininbox
from caravan import mynode_caravan from caravan import mynode_caravan
from sphinxrelay import mynode_sphinxrelay from sphinxrelay import mynode_sphinxrelay
@ -456,10 +456,6 @@ def index():
} }
return render_template('syncing.html', **templateData) return render_template('syncing.html', **templateData)
# Find tor status
tor_status_color = get_service_status_color("tor@default")
tor_status = "Private Connections"
# Find bitcoid status # Find bitcoid status
bitcoin_info = get_bitcoin_blockchain_info() bitcoin_info = get_bitcoin_blockchain_info()
bitcoin_peers = get_bitcoin_peers() bitcoin_peers = get_bitcoin_peers()
@ -480,52 +476,6 @@ def index():
if int(re.sub("[^0-9]", "", drive_usage)) > 95: if int(re.sub("[^0-9]", "", drive_usage)) > 95:
low_drive_space_error = True low_drive_space_error = True
# Find lndhub status
lndhub_status, lndhub_status_color = get_lndhub_status_and_color()
# Find RTL status
rtl_status, rtl_status_color = get_rtl_status_and_color()
# Find LNbits status
lnbits_status, lnbits_status_color = get_lnbits_status_and_color()
# Find Thunderhub status
thunderhub_status, thunderhub_status_color = get_thunderhub_status_and_color()
# Find CKBunker status
ckbunker_status, ckbunker_status_color = get_ckbunker_status_and_color()
# Find Sphinx Relay status
sphinxrelay_status, sphinxrelay_status_color = get_sphinxrelay_status_and_color()
# Find electrs status
electrs_status, electrs_status_color = get_electrs_status_and_color()
# Find btc-rpc-explorer status
btcrpcexplorer_status, btcrpcexplorer_status_color, btcrpcexplorer_ready = get_btcrpcexplorer_status_and_color_and_ready()
# Find mempool space status
mempool_status, mempool_status_color = get_mempool_status_and_color()
# Find btcpayserver status
btcpayserver_status, btcpayserver_status_color = get_btcpayserver_status_and_color()
# Find VPN status
vpn_status, vpn_status_color = get_vpn_status_and_color()
# Find whirlpool status
whirlpool_status, whirlpool_status_color, whirlpool_initialized = get_whirlpool_status()
# Find dojo status
dojo_status, dojo_status_color, dojo_initialized = get_dojo_status()
# Find caravan status
caravan_status, caravan_status_color = get_caravan_status_and_color()
# Find specter status
specter_status, specter_status_color = get_specter_status_and_color()
# Check for new version of software # Check for new version of software
upgrade_available = False upgrade_available = False
current = get_current_version() current = get_current_version()
@ -544,7 +494,7 @@ def index():
"title": "myNode Home", "title": "myNode Home",
"refresh_rate": refresh_rate, "refresh_rate": refresh_rate,
"config": CONFIG, "config": CONFIG,
"apps": get_all_applications(order_by="alphabetic"), "apps": get_all_applications(order_by="homepage"),
"bitcoin_status_color": bitcoin_status_color, "bitcoin_status_color": bitcoin_status_color,
"bitcoin_status": Markup(bitcoin_status), "bitcoin_status": Markup(bitcoin_status),
"current_block": current_block, "current_block": current_block,
@ -562,63 +512,10 @@ def index():
"lnd_version": get_lnd_version(), "lnd_version": get_lnd_version(),
"lnd_deposit_address": get_lnd_deposit_address(), "lnd_deposit_address": get_lnd_deposit_address(),
"lnd_channels": get_lightning_channels(), "lnd_channels": get_lightning_channels(),
"electrs_active": electrs_active,
"is_testnet_enabled": is_testnet_enabled(), "is_testnet_enabled": is_testnet_enabled(),
"tor_status_color": tor_status_color,
"tor_status": tor_status,
"is_installing_docker_images": is_installing_docker_images(), "is_installing_docker_images": is_installing_docker_images(),
"is_device_from_reseller": is_device_from_reseller(), "is_device_from_reseller": is_device_from_reseller(),
"electrs_status_color": electrs_status_color,
"electrs_status": Markup(electrs_status),
"electrs_enabled": is_service_enabled("electrs"),
"electrs_active": electrs_active,
"rtl_status_color": rtl_status_color,
"rtl_status": rtl_status,
"rtl_enabled": is_service_enabled("rtl"),
"lnbits_status_color": lnbits_status_color,
"lnbits_status": lnbits_status,
"lnbits_enabled": is_service_enabled("lnbits"),
"thunderhub_status_color": thunderhub_status_color,
"thunderhub_status": thunderhub_status,
"thunderhub_enabled": is_service_enabled("thunderhub"),
"thunderhub_sso_token": get_thunderhub_sso_token(),
"ckbunker_status_color": ckbunker_status_color,
"ckbunker_status": ckbunker_status,
"ckbunker_enabled": is_service_enabled("ckbunker"),
"sphinxrelay_status_color": sphinxrelay_status_color,
"sphinxrelay_status": sphinxrelay_status,
"sphinxrelay_enabled": is_service_enabled("sphinxrelay"),
"lndhub_status_color": lndhub_status_color,
"lndhub_status": lndhub_status,
"lndhub_enabled": is_service_enabled("lndhub"),
"btcrpcexplorer_ready": btcrpcexplorer_ready,
"btcrpcexplorer_status_color": btcrpcexplorer_status_color,
"btcrpcexplorer_status": btcrpcexplorer_status,
"btcrpcexplorer_enabled": is_service_enabled("btcrpcexplorer"),
"btcrpcexplorer_sso_token": get_btcrpcexplorer_sso_token(),
"caravan_status_color": caravan_status_color,
"caravan_status": caravan_status,
"caravan_enabled": is_service_enabled("caravan"),
"specter_status_color": specter_status_color,
"specter_status": specter_status,
"specter_enabled": is_service_enabled("specter"),
"mempool_status_color": mempool_status_color,
"mempool_status": mempool_status,
"mempool_enabled": is_service_enabled("mempool"),
"btcpayserver_enabled": is_service_enabled("btcpayserver"),
"btcpayserver_status_color": btcpayserver_status_color,
"btcpayserver_status": btcpayserver_status,
"vpn_status_color": vpn_status_color,
"vpn_status": vpn_status,
"vpn_enabled": is_service_enabled("vpn"),
"whirlpool_status": whirlpool_status,
"whirlpool_status_color": whirlpool_status_color,
"whirlpool_enabled": is_service_enabled("whirlpool"),
"whirlpool_initialized": whirlpool_initialized,
"is_dojo_installed": is_dojo_installed(),
"dojo_status": dojo_status,
"dojo_status_color": dojo_status_color,
"dojo_enabled": is_service_enabled("dojo"),
"dojo_initialized": dojo_initialized,
"product_key_skipped": pk_skipped, "product_key_skipped": pk_skipped,
"product_key_error": pk_error, "product_key_error": pk_error,
"fsck_error": has_fsck_error(), "fsck_error": has_fsck_error(),

View File

@ -383,6 +383,7 @@ table.bitcoin_table td {
.red { background-color: red; } .red { background-color: red; }
.gray { background-color: gray; } .gray { background-color: gray; }
.blue { background-color: blue; } .blue { background-color: blue; }
.clear { opacity: 100%; }
.green_text {color: green;} .green_text {color: green;}
.yellow_text {color: yellow;} .yellow_text {color: yellow;}

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -49,7 +49,7 @@
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/toggle-dojo-install">Uninstall</a> <a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/toggle-dojo-install">Uninstall</a>
</td> </td>
</tr> </tr>
{% if dojo_enabled and dojo_initialized and electrs_status == "Running" %} {% if dojo_enabled and electrs_status == "Running" %}
<tr> <tr>
<th>Dojo V3 Onion Address</th> <th>Dojo V3 Onion Address</th>
<td style="font-size: 12px;">{{DOJO_V3_ADDR}}</td> <td style="font-size: 12px;">{{DOJO_V3_ADDR}}</td>

View File

@ -102,7 +102,7 @@
<div class="app_tile_row"> <div class="app_tile_row">
<div class="app_tile_short"> <div class="app_tile_short">
<div class="app_status_icon"></div> <div class="app_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/electrum_logo.png")}}"/></div> <div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/electrs.png")}}"/></div>
<div class="app_title">Local<br/>PC Wallet</div> <div class="app_title">Local<br/>PC Wallet</div>
<div class="app_status"></div> <div class="app_status"></div>
<div class="app_contents"> <div class="app_contents">
@ -112,7 +112,7 @@
<div class="app_tile_short"> <div class="app_tile_short">
<div class="app_status_icon"></div> <div class="app_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/electrum_logo.png")}}"/></div> <div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/electrs.png")}}"/></div>
<div class="app_title">Local<br/>Mobile Wallets</div> <div class="app_title">Local<br/>Mobile Wallets</div>
<div class="app_status"></div> <div class="app_status"></div>
<div class="app_contents"> <div class="app_contents">

View File

@ -1,286 +1,39 @@
<div class="main_header">Apps</div> <div class="main_header">Apps</div>
<!-- ROW 1 -->
<div class="app_tile_grid_container"> <div class="app_tile_grid_container">
<!-- Dynamic App Display -->
{% for app in apps %}
{% if app.show_on_homepage and app.homepage_section == "apps" %}
<div class="app_tile"> <div class="app_tile">
<div class="app_status_icon {{ rtl_status_color }}" id="rtl_status_icon"></div> <div class="app_status_icon {% if app.can_enable_disable %}clear{% endif %}" id="{{app.short_name}}_status_icon"></div>
<!-- <div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/")}}{{app.short_name}}.png"/></div>
Sample Help Tooltip for each app <div class="app_title">{{app.app_tile_name}}</div>
<img class="app_tooltip" src="{{ url_for('static', filename="images/help_icon.png")}}" title="RTL is a web app for managing your lightning wallet"/> <div class="app_status"id="{{app.short_name}}_status"></div>
-->
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/rtl.png")}}"/></div>
<div class="app_title">RTL</div>
<div class="app_status"id="rtl_status">{{ rtl_status }}</div>
<div class="app_contents"> <div class="app_contents">
{% if lnd_ready %} {% if product_key_skipped and app.is_premium %}
{% if rtl_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="rtl">RTL</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('rtl')">
{% if rtl_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ electrs_status_color }}" id="electrs_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/electrum_logo.png")}}"/></div>
<div class="app_title">Electrum Server</div>
<div class="app_status" id="electrs_status">{{ electrs_status }}</div>
<div class="app_contents">
{% if electrs_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/electrum-server">Info</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('electrs')">
{% if electrs_enabled %}Disable{% else %}Enable{% endif %}
</a>
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ btcpayserver_status_color }}" id="btcpayserver_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/btcpayserver.png")}}"/></div>
<div class="app_title">BTCPay Server</div>
<div class="app_status" id="btcpayserver_status">{{ btcpayserver_status }}</div>
<div class="app_contents">
{% if product_key_skipped %}
Premium Feature Premium Feature
{% else %} {% else %}
{% if lnd_ready and not is_testnet_enabled %} {% if not is_testnet_enabled or is_testnet_enabled and app.supports_testnet %}
{% if btcpayserver_enabled %} {% if lnd_ready or ( not lnd_ready and not app.requires_lightning ) %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="btcpayserver">BTCPay Server</a> {% if electrs_active or ( not electrs_active and not app.requires_electrs ) %}
{% if not is_installing_docker_images or ( is_installing_docker_images and not app.requires_docker_image_installation ) %}
{% if app.is_enabled or not app.can_enable_disable %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="{{app.app_tile_button_href}}" id="{{app.short_name}}">{{app.app_tile_button_text}}</a>
{% endif %} {% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('btcpayserver')"> {% if app.can_enable_disable %}
{% if btcpayserver_enabled %}Disable{% else %}Enable{% endif %} <a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('{{app.short_name}}')">
{% if app.is_enabled %}Disable{% else %}Enable{% endif %}
</a> </a>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{mempool_status_color}}" id="mempool_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/mempool.png")}}"/></div>
<div class="app_title">Mempool</div>
<div class="app_status" id="mempool_status">{{ mempool_status }}</div>
<div class="app_contents">
{% if not is_installing_docker_images %}
{% if mempool_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="mempool">View</a>
{% endif %} {% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('mempool')">
{% if mempool_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %} {% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ lndhub_status_color }}" id="lndhub_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/lndhub.png")}}"/></div>
<div class="app_title">LND Hub</div>
<div class="app_status" id="lndhub_status">{{ lndhub_status }}</div>
<div class="app_contents">
{% if lnd_ready and not is_testnet_enabled %}
{% if lndhub_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="lndhub">LND Hub</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('lndhub')">
{% if lndhub_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ btcrpcexplorer_status_color }}" id="btcrpcexplorer_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/btcrpcexplorer.png")}}"/></div>
<div class="app_title">Explorer</div>
<div class="app_status">{{ btcrpcexplorer_status }}</div>
<div class="app_contents">
{% if btcrpcexplorer_enabled and btcrpcexplorer_ready %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="btcrpcexplorer">Explorer</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('btcrpcexplorer')">
{% if btcrpcexplorer_enabled %}Disable{% else %}Enable{% endif %}
</a>
</div>
</div>
{% if not is_device_from_reseller %}
<div class="app_tile">
<div class="app_status_icon {{ dojo_status_color }}" id="dojo_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/dojo.png")}}"/></div>
<div class="app_title">Dojo</div>
<div class="app_status" id="dojo_status">{{ dojo_status }}</div>
<div class="app_contents">
{% if not is_installing_docker_images and not is_testnet_enabled %}
{% if is_dojo_installed %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/dojo">Info</a>
{% if electrs_active %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('dojo')">
{% if dojo_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
{% else %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/toggle-dojo-install">Install</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div class="app_tile">
<div class="app_status_icon {{ whirlpool_status_color }}" id="whirlpool_status_icon"></div>
{% if ui_settings['darkmode'] %}
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/wp-white.png")}}"/></div>
{% else %}
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/wp-black.png")}}"/></div>
{% endif %} {% endif %}
<div class="app_title">Whirlpool</div> {% endfor %}
<div class="app_status" id="whirlpool_status">{{ whirlpool_status }}</div>
<div class="app_contents">
{% if not is_testnet_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/whirlpool">Info</a>
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('whirlpool')">
{% if whirlpool_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
</div>
</div>
{% endif %}
<div class="app_tile">
<!--<div class="app_status_icon green" id="joininbox_status_icon"></div>-->
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/joininbox.png")}}"/></div>
<div class="app_title">JoininBox</div>
<div class="app_status" id="joininbox_status">JoinMarket Mixing</div>
<div class="app_contents">
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/joininbox">Info</a>
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ thunderhub_status_color }}" id="thunderhub_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/thunderhub.png")}}"/></div>
<div class="app_title">Thunderhub</div>
<div class="app_status" id="thunderhub_status">{{ thunderhub_status }}</div>
<div class="app_contents">
{% if product_key_skipped %}
Premium Feature
{% else %}
{% if lnd_ready %}
{% if thunderhub_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="thunderhub">Thunderhub</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('thunderhub')">
{% if thunderhub_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ caravan_status_color }}" id="caravan_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/caravan.png")}}"/></div>
<div class="app_title">Caravan</div>
<div class="app_status" id="caravan_status">{{ caravan_status }}</div>
<div class="app_contents">
{% if product_key_skipped %}
Premium Feature
{% else %}
{% if caravan_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/caravan">Info</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('caravan')">
{% if caravan_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ specter_status_color }}" id="specter_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/specter.png")}}"/></div>
<div class="app_title">Specter</div>
<div class="app_status" id="specter_status">{{ specter_status }}</div>
<div class="app_contents">
{% if product_key_skipped %}
Premium Feature
{% else %}
{% if specter_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="specter">Specter</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('specter')">
{% if specter_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ ckbunker_status_color }}" id="ckbunker_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/ckbunker.png")}}"/></div>
<img class="app_beta_tag_image" src="{{ url_for('static', filename="images/beta.png")}}"/>
<div class="app_title">CKBunker</div>
<div class="app_status" id="ckbunker_status">{{ ckbunker_status }}</div>
<div class="app_contents">
{% if product_key_skipped %}
Premium Feature
{% else %}
{% if ckbunker_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="ckbunker">CKBunker</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('ckbunker')">
{% if ckbunker_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ sphinxrelay_status_color }}" id="sphinxrelay_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/sphinx.png")}}"/></div>
<div class="app_title">Sphinx Relay</div>
<div class="app_status" id="sphinxrelay_status">{{ sphinxrelay_status }}</div>
<div class="app_contents">
{% if product_key_skipped %}
Premium Feature
{% else %}
{% if lnd_ready and not is_testnet_enabled %}
{% if sphinxrelay_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/sphinxrelay">Info</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('sphinxrelay')">
{% if sphinxrelay_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ lnbits_status_color }}" id="lnbits_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/lnbits.png")}}"/></div>
<div class="app_title">LNbits</div>
<div class="app_status" id="lnbits_status">{{ lnbits_status }}</div>
<div class="app_contents">
{% if product_key_skipped %}
Premium Feature
{% else %}
{% if lnd_ready and not is_testnet_enabled %}
{% if lnbits_enabled %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="#" id="lnbits">LNbits</a>
{% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('lnbits')">
{% if lnbits_enabled %}Disable{% else %}Enable{% endif %}
</a>
{% endif %}
{% endif %}
</div>
</div>
</div> </div>
@ -289,37 +42,38 @@
<div> <div>
<div class="main_header">Remote Access Services</div> <div class="main_header">Remote Access Services</div>
<div class="app_tile_row_section"> <div class="app_tile_row_section">
{% for app in apps %}
{% if app.show_on_homepage and app.homepage_section == "remote_services" %}
<div class="app_tile"> <div class="app_tile">
<div class="app_status_icon {{ tor_status_color }}" id="tor_status_icon"></div> <div class="app_status_icon {% if app.can_enable_disable %}clear{% endif %}" id="{{app.short_name}}_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/tor.png")}}"/></div> <div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/")}}{{app.short_name}}.png"/></div>
<div class="app_title">Tor</div> <div class="app_title">{{app.app_tile_name}}</div>
<div class="app_status" id="tor_status">{{ tor_status }}</div> <div class="app_status"id="{{app.short_name}}_status"></div>
<div class="app_contents"> <div class="app_contents">
{% if product_key_skipped %} {% if product_key_skipped and app.is_premium %}
Remote Access Premium Feature
{% else %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/tor">Tor Services</a>
{% endif %}
</div>
</div>
<div class="app_tile">
<div class="app_status_icon {{ vpn_status_color }}" id="vpn_status_icon"></div>
<div class="app_logo"><img class="app_logo_icon" src="{{ url_for('static', filename="images/vpn.png")}}"/></div>
<div class="app_title">VPN</div>
<div class="app_status" id="vpn_status">{{ vpn_status }}</div>
<div class="app_contents">
{% if product_key_skipped %}
Premium Feature Premium Feature
{% else %} {% else %}
{% if vpn_enabled %} {% if not is_testnet_enabled or is_testnet_enabled and app.supports_testnet %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="/vpn-info">Info</a> {% if lnd_ready or ( not lnd_ready and not app.requires_lightning ) %}
{% if electrs_active or ( not electrs_active and not app.requires_electrs ) %}
{% if not is_installing_docker_images or ( is_installing_docker_images and not app.requires_docker_image_installation ) %}
{% if app.is_enabled or not app.can_enable_disable %}
<a class="ui-button ui-widget ui-corner-all mynode_button" href="{{app.app_tile_button_href}}" id="{{app.short_name}}">{{app.app_tile_button_text}}</a>
{% endif %} {% endif %}
<a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('vpn')"> {% if app.can_enable_disable %}
{% if vpn_enabled %}Disable{% else %}Enable{% endif %} <a class="ui-button ui-widget ui-corner-all mynode_button" onclick="toggleEnabled('{{app.short_name}}')">
{% if app.is_enabled %}Disable{% else %}Enable{% endif %}
</a> </a>
{% endif %} {% endif %}
</div> {% endif %}
</div> {% endif %}
{% endif %}
{% endif %}
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -13,6 +13,9 @@
application_data["{{app.short_name}}"]["short_name"] = "{{app.short_name}}"; application_data["{{app.short_name}}"]["short_name"] = "{{app.short_name}}";
application_data["{{app.short_name}}"]["is_enabled"] = {% if app.is_enabled %}true{% else %}false{% endif %}; application_data["{{app.short_name}}"]["is_enabled"] = {% if app.is_enabled %}true{% else %}false{% endif %};
{% endfor %} {% endfor %}
var electrs_active = {% if electrs_active %}1{% else %}0{% endif %};
var lnd_ready = {% if lnd_ready %}true{% else %}false{% endif %};
var is_installing_docker_images = {% if is_installing_docker_images %}true{% else %}false{% endif %};
// Toggle enable/disable functions // Toggle enable/disable functions
function get_custom_enable_message(short_name) { function get_custom_enable_message(short_name) {
@ -23,6 +26,8 @@
} else if (short_name == "vpn") { } else if (short_name == "vpn") {
message = "Enabling VPN will set your IP to a static IP rather than a dynamic one via DHCP. \ message = "Enabling VPN will set your IP to a static IP rather than a dynamic one via DHCP. \
The initial setup may take about an hour."; The initial setup may take about an hour.";
} else if (short_name == "dojo") {
message = "Enabling Dojo for the first time will reboot your device and install Dojo.";
} }
if (message != "") { if (message != "") {
message += "<br/><br/>"; message += "<br/><br/>";
@ -72,6 +77,7 @@
$("#"+status_icon_name).removeClass("green"); $("#"+status_icon_name).removeClass("green");
$("#"+status_icon_name).removeClass("gray"); $("#"+status_icon_name).removeClass("gray");
$("#"+status_icon_name).removeClass("blue"); $("#"+status_icon_name).removeClass("blue");
$("#"+status_icon_name).removeClass("clear");
$("#"+status_icon_name).addClass(data["color"]); $("#"+status_icon_name).addClass(data["color"]);
} }
} }
@ -83,10 +89,17 @@
$("#channel_status_icon_"+c["chan_id"]).removeClass("green"); $("#channel_status_icon_"+c["chan_id"]).removeClass("green");
$("#channel_status_icon_"+c["chan_id"]).removeClass("gray"); $("#channel_status_icon_"+c["chan_id"]).removeClass("gray");
$("#channel_status_icon_"+c["chan_id"]).removeClass("blue"); $("#channel_status_icon_"+c["chan_id"]).removeClass("blue");
$("#channel_status_icon_"+c["chan_id"]).removeClass("clear");
$("#channel_status_icon_"+c["chan_id"]).addClass(c["status_color"]); $("#channel_status_icon_"+c["chan_id"]).addClass(c["status_color"]);
} }
} }
function update_sso_token(short_name, data) {
if ("sso_token" in data && data["sso_token"] != null && data["sso_token"] != "") {
application_data[short_name]["sso_token"] = data["sso_token"]
}
}
function refresh_page() { function refresh_page() {
window.location.href=location.protocol+'//'+location.hostname+"/"; window.location.href=location.protocol+'//'+location.hostname+"/";
} }
@ -125,11 +138,6 @@
// Update page function // Update page function
var lnd_ready = {% if lnd_ready %}true{% else %}false{% endif %};
var btcrpcexplorer_ready = {% if btcrpcexplorer_ready %}true{% else %}false{% endif %};
var btcrpcexplorer_sso_token = "{{btcrpcexplorer_sso_token}}";
var thunderhub_sso_token = "{{thunderhub_sso_token}}";
var is_installing_docker_images = {% if is_installing_docker_images %}true{% else %}false{% endif %};
function update_page() { function update_page() {
// Update Bitcoin Info // Update Bitcoin Info
$.getJSON("/api/get_bitcoin_info", function( data ) { $.getJSON("/api/get_bitcoin_info", function( data ) {
@ -206,88 +214,15 @@
}); });
// Update app status // Update app status
$.getJSON("/api/get_service_status?service=bitcoin", function( data ) { {% for app in apps %}
update_status("bitcoin_status", data); {% if app.show_on_homepage %}
update_status_icon("bitcoin_status_icon", data); $.getJSON("/api/get_service_status?service={{app.short_name}}", function( data ) {
}); update_status("{{app.short_name}}_status", data);
$.getJSON("/api/get_service_status?service=lnd", function( data ) { update_status_icon("{{app.short_name}}_status_icon", data);
update_status("lnd_status", data); update_sso_token("{{app.short_name}}", data);
update_status_icon("lnd_status_icon", data);
});
$.getJSON("/api/get_service_status?service=electrs", function( data ) {
update_status("electrs_status", data);
update_status_icon("electrs_status_icon", data);
});
$.getJSON("/api/get_service_status?service=dojo", function( data ) {
update_status("dojo_status", data);
update_status_icon("dojo_status_icon", data);
});
$.getJSON("/api/get_service_status?service=rtl", function( data ) {
update_status("rtl_status", data);
update_status_icon("rtl_status_icon", data);
});
$.getJSON("/api/get_service_status?service=mempool", function( data ) {
update_status("mempool_status", data);
update_status_icon("mempool_status_icon", data);
});
$.getJSON("/api/get_service_status?service=whirlpool", function( data ) {
update_status("whirlpool_status", data);
update_status_icon("whirlpool_status_icon", data);
});
$.getJSON("/api/get_service_status?service=btcpayserver", function( data ) {
update_status("btcpayserver_status", data);
update_status_icon("btcpayserver_status_icon", data);
});
$.getJSON("/api/get_service_status?service=lndhub", function( data ) {
update_status("lndhub_status", data);
update_status_icon("lndhub_status_icon", data);
});
// BTC RPC Explorer // TODO: Refresh page if btcexplorerready changes
$.getJSON("/api/get_service_status?service=btcrpcexplorer", function( data ) {
update_status("btcrpcexplorer_status", data);
update_status_icon("btcrpcexplorer_status_icon", data);
if ("sso_token" in data && data["sso_token"] != null) {
btcrpcexplorer_sso_token = data["sso_token"]
}
if ("ready" in data && data["ready"] != null && btcrpcexplorer_ready != data["ready"]) {
refresh_page();
}
});
$.getJSON("/api/get_service_status?service=caravan", function( data ) {
update_status("caravan_status", data);
update_status_icon("caravan_status_icon", data);
});
$.getJSON("/api/get_service_status?service=specter", function( data ) {
update_status("specter_status", data);
update_status_icon("specter_status_icon", data);
});
$.getJSON("/api/get_service_status?service=lnbits", function( data ) {
update_status("lnbits_status", data);
update_status_icon("lnbits_status_icon", data);
});
$.getJSON("/api/get_service_status?service=thunderhub", function( data ) {
update_status("thunderhub_status", data);
update_status_icon("thunderhub_status_icon", data);
if ("sso_token" in data && data["sso_token"] != null) {
thunderhub_sso_token = data["sso_token"]
}
});
$.getJSON("/api/get_service_status?service=ckbunker", function( data ) {
update_status("ckbunker_status", data);
update_status_icon("ckbunker_status_icon", data);
});
$.getJSON("/api/get_service_status?service=sphinxrelay", function( data ) {
update_status("sphinxrelay_status", data);
update_status_icon("sphinxrelay_status_icon", data);
});
$.getJSON("/api/get_service_status?service=tor", function( data ) {
update_status("tor_status", data);
update_status_icon("tor_status_icon", data);
});
$.getJSON("/api/get_service_status?service=vpn", function( data ) {
update_status("vpn_status", data);
update_status_icon("vpn_status_icon", data);
}); });
{% endif %}
{% endfor %}
// Update device info // Update device info
$.getJSON("/api/get_device_info", function( data ) { $.getJSON("/api/get_device_info", function( data ) {
@ -312,6 +247,11 @@
refresh_page(); refresh_page();
} }
} }
if ("is_electrs_active" in data && data["is_electrs_active"] != null) {
if (electrs_active != data["is_electrs_active"]) {
refresh_page();
}
}
}); });
// Check if we need a full page refresh (errors, status changes, etc...) // Check if we need a full page refresh (errors, status changes, etc...)
@ -326,11 +266,6 @@
// Run when page ready // Run when page ready
$(document).ready(function() { $(document).ready(function() {
electrs_enabled = {% if electrs_enabled %}1{% else %}0{% endif %}
lndhub_enabled = {% if lndhub_enabled %}1{% else %}0{% endif %}
vpn_enabled = {% if vpn_enabled %}1{% else %}0{% endif %}
mempool_enabled = {% if mempool_enabled %}1{% else %}0{% endif %}
$( document ).tooltip(); $( document ).tooltip();
$("#lit").on("click", function() { $("#lit").on("click", function() {
@ -372,7 +307,7 @@
} }
// Swap to use SSO (make optional? - needing password is safer) // Swap to use SSO (make optional? - needing password is safer)
url = location.protocol+'//'+location.hostname+':'+port url = location.protocol+'//'+location.hostname+':'+port
//url = location.protocol+'//'+location.hostname+':'+port+'/sso?'+'token='+thunderhub_sso_token //url = location.protocol+'//'+location.hostname+':'+port+'/sso?'+'token='+application_data["thunderhub"]["sso_token"]
window.open(url,'_blank'); window.open(url,'_blank');
}) })
@ -385,16 +320,12 @@
window.open(url,'_blank'); window.open(url,'_blank');
}) })
$("#sphinxrelay").on("click", function() {
alert("TODO???")
})
$("#btcrpcexplorer").on("click", function() { $("#btcrpcexplorer").on("click", function() {
port="3002" port="3002"
if (location.protocol == "https:") { if (location.protocol == "https:") {
port="3003" port="3003"
} }
url = location.protocol+'//'+location.hostname+':'+port+'/?'+'token='+btcrpcexplorer_sso_token url = location.protocol+'//'+location.hostname+':'+port+'/?'+'token='+application_data["btcrpcexplorer"]["sso_token"]
window.open(url,'_blank'); window.open(url,'_blank');
}) })

View File

@ -30,7 +30,7 @@
<tr> <tr>
<th>Actions</th> <th>Actions</th>
<td> <td>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/toggle-whirlpool"> <a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/toggle-enabled?app=whirlpool">
{% if whirlpool_enabled %}Disable{% else %}Enable{% endif %} {% if whirlpool_enabled %}Disable{% else %}Enable{% endif %}
</a> </a>
{% if whirlpool_enabled %} {% if whirlpool_enabled %}

View File

@ -2,6 +2,7 @@ from flask import Blueprint, render_template, redirect
from user_management import check_logged_in from user_management import check_logged_in
from enable_disable_functions import * from enable_disable_functions import *
from device_info import read_ui_settings, is_testnet_enabled, get_local_ip from device_info import read_ui_settings, is_testnet_enabled, get_local_ip
from application_info import *
from systemctl_info import * from systemctl_info import *
import subprocess import subprocess
import os import os
@ -9,30 +10,9 @@ import os
mynode_whirlpool = Blueprint('mynode_whirlpool',__name__) mynode_whirlpool = Blueprint('mynode_whirlpool',__name__)
## Status and color ## Status and color
def get_whirlpool_status(): def is_whirlpool_initialized():
# Find whirlpool status return os.path.isfile("/mnt/hdd/mynode/whirlpool/whirlpool-cli-config.properties")
whirlpool_status = "Disabled"
whirlpool_status_color = "gray"
whirlpool_initialized = os.path.isfile("/mnt/hdd/mynode/whirlpool/whirlpool-cli-config.properties")
if is_testnet_enabled():
whirlpool_status = "Requires Mainnet"
whirlpool_status_color = "gray"
return whirlpool_status, whirlpool_status_color, whirlpool_initialized
if is_service_enabled("whirlpool"):
status_code = get_service_status_code("whirlpool")
if status_code != 0:
whirlpool_status = "Inactive"
whirlpool_status_color = "red"
else:
if whirlpool_initialized:
whirlpool_status = "Running"
whirlpool_status_color = "green"
else:
whirlpool_status = "Waiting for initialization..."
whirlpool_status_color = "yellow"
return whirlpool_status, whirlpool_status_color, whirlpool_initialized
### Page functions ### Page functions
@mynode_whirlpool.route("/whirlpool") @mynode_whirlpool.route("/whirlpool")
@ -45,7 +25,12 @@ def whirlpool_page():
except: except:
whirlpool_api_key = 'error' whirlpool_api_key = 'error'
whirlpool_status, whirlpool_status_color, whirlpool_initialized = get_whirlpool_status() whirlpool_status = "Running"
whirlpool_status_code = get_service_status_code("whirlpool")
if not is_whirlpool_initialized():
whirlpool_status = "Waiting on Initialization..."
elif whirlpool_status_code != 0:
whirlpool_status = "Inactive"
# Load page # Load page
templateData = { templateData = {
@ -53,9 +38,8 @@ def whirlpool_page():
"ui_settings": read_ui_settings(), "ui_settings": read_ui_settings(),
"local_ip": get_local_ip(), "local_ip": get_local_ip(),
"whirlpool_status": whirlpool_status, "whirlpool_status": whirlpool_status,
"whirlpool_status_color": whirlpool_status_color,
"whirlpool_enabled": is_service_enabled("whirlpool"), "whirlpool_enabled": is_service_enabled("whirlpool"),
"whirlpool_initialized": whirlpool_initialized, "whirlpool_initialized": is_whirlpool_initialized(),
"whirlpool_api_key": whirlpool_api_key "whirlpool_api_key": whirlpool_api_key
} }
return render_template('whirlpool.html', **templateData) return render_template('whirlpool.html', **templateData)