From 08ed86fb189cbda734674a47588428c0477547f9 Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 8 Dec 2022 10:24:37 +0000 Subject: [PATCH] Shuffling UI, trying to ditch variables --- lnbits/extensions/gerty/crud.py | 35 +- lnbits/extensions/gerty/helpers.py | 493 +++-- lnbits/extensions/gerty/migrations.py | 3 + lnbits/extensions/gerty/models.py | 5 +- .../gerty/templates/gerty/index.html | 1594 +++++++++-------- lnbits/extensions/gerty/views_api.py | 24 +- 6 files changed, 1240 insertions(+), 914 deletions(-) diff --git a/lnbits/extensions/gerty/crud.py b/lnbits/extensions/gerty/crud.py index ec1e2f68..e4a1713a 100644 --- a/lnbits/extensions/gerty/crud.py +++ b/lnbits/extensions/gerty/crud.py @@ -10,6 +10,7 @@ from loguru import logger from . import db from .models import Gerty, Mempool, MempoolEndpoint + async def create_gerty(wallet_id: str, data: Gerty) -> Gerty: gerty_id = urlsafe_short_hash() await db.execute( @@ -78,34 +79,52 @@ async def delete_gerty(gerty_id: str) -> None: #############MEMPOOL########### + async def get_mempool_info(endPoint: str, gerty) -> Optional[Mempool]: endpoints = MempoolEndpoint() url = "" for endpoint in endpoints: if endPoint == endpoint[0]: url = endpoint[1] - row = await db.fetchone("SELECT * FROM gerty.mempool WHERE endpoint = ?", (endPoint,)) + row = await db.fetchone( + "SELECT * FROM gerty.mempool WHERE endpoint = ? AND mempool_endpoint = ?", + ( + endPoint, + gerty.mempool_endpoint, + ), + ) if not row: async with httpx.AsyncClient() as client: response = await client.get(gerty.mempool_endpoint + url) await db.execute( - """ + """ INSERT INTO gerty.mempool ( data, endpoint, - time + time, + mempool_endpoint ) - VALUES (?, ?, ?) + VALUES (?, ?, ?, ?) """, - (json.dumps(response.json()), endPoint, int(time.time())), + ( + json.dumps(response.json()), + endPoint, + int(time.time()), + gerty.mempool_endpoint, + ), ) return response.json() if int(time.time()) - row.time > 20: async with httpx.AsyncClient() as client: response = await client.get(gerty.mempool_endpoint + url) await db.execute( - "UPDATE gerty.mempool SET data = ?, time = ? WHERE endpoint = ?", - (json.dumps(response.json()), int(time.time()), endPoint), + "UPDATE gerty.mempool SET data = ?, time = ? WHERE endpoint = ? AND mempool_endpoint = ?", + ( + json.dumps(response.json()), + int(time.time()), + endPoint, + gerty.mempool_endpoint, + ), ) return response.json() - return json.loads(row.data) \ No newline at end of file + return json.loads(row.data) diff --git a/lnbits/extensions/gerty/helpers.py b/lnbits/extensions/gerty/helpers.py index a3ecdbb7..1f8c1caf 100644 --- a/lnbits/extensions/gerty/helpers.py +++ b/lnbits/extensions/gerty/helpers.py @@ -12,13 +12,20 @@ from .number_prefixer import * from ...settings import LNBITS_PATH from lnbits.utils.exchange_rates import satoshis_amount_as_fiat + def get_percent_difference(current, previous, precision=3): difference = (current - previous) / current * 100 return "{0}{1}%".format("+" if difference > 0 else "", round(difference, precision)) # A helper function get a nicely formated dict for the text -def get_text_item_dict(text: str, font_size: int, x_pos: int = None, y_pos: int = None, gerty_type: str = 'Gerty'): +def get_text_item_dict( + text: str, + font_size: int, + x_pos: int = None, + y_pos: int = None, + gerty_type: str = "Gerty", +): # Get line size by font size line_width = 20 if font_size <= 12: @@ -31,7 +38,7 @@ def get_text_item_dict(text: str, font_size: int, x_pos: int = None, y_pos: int line_width = 25 # Get font sizes for Gerty mini - if(gerty_type.lower() == 'mini gerty'): + if gerty_type.lower() == "mini gerty": if font_size <= 12: font_size = 1 if font_size <= 15: @@ -43,8 +50,6 @@ def get_text_item_dict(text: str, font_size: int, x_pos: int = None, y_pos: int else: font_size = 5 - - # wrap the text wrapper = textwrap.TextWrapper(width=line_width) word_list = wrapper.wrap(text=text) @@ -81,10 +86,16 @@ async def get_mining_dashboard(gerty): hashrateOneWeekAgo = data["hashrates"][6]["avgHashrate"] text = [] - text.append(get_text_item_dict(text="Current mining hashrate", font_size=12,gerty_type=gerty.type)) text.append( get_text_item_dict( - text="{0}hash".format(si_format(hashrateNow, 6, True, " ")), font_size=20,gerty_type=gerty.type + text="Current mining hashrate", font_size=12, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict( + text="{0}hash".format(si_format(hashrateNow, 6, True, " ")), + font_size=20, + gerty_type=gerty.type, ) ) text.append( @@ -92,7 +103,8 @@ async def get_mining_dashboard(gerty): text="{0} vs 7 days ago".format( get_percent_difference(hashrateNow, hashrateOneWeekAgo, 3) ), - font_size=12,gerty_type=gerty.type + font_size=12, + gerty_type=gerty.type, ) ) areas.append(text) @@ -102,27 +114,54 @@ async def get_mining_dashboard(gerty): # timeAvg text = [] progress = "{0}%".format(round(r["progressPercent"], 2)) - text.append(get_text_item_dict(text="Progress through current epoch", font_size=12,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=progress, font_size=60,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Progress through current epoch", + font_size=12, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict(text=progress, font_size=60, gerty_type=gerty.type) + ) areas.append(text) # difficulty adjustment text = [] stat = r["remainingTime"] - text.append(get_text_item_dict(text="Time to next difficulty adjustment", font_size=12,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=get_time_remaining(stat / 1000, 3), font_size=12,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Time to next difficulty adjustment", + font_size=12, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict( + text=get_time_remaining(stat / 1000, 3), + font_size=12, + gerty_type=gerty.type, + ) + ) areas.append(text) # difficultyChange text = [] difficultyChange = round(r["difficultyChange"], 2) - text.append(get_text_item_dict(text="Estimated difficulty change", font_size=12,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Estimated difficulty change", + font_size=12, + gerty_type=gerty.type, + ) + ) text.append( get_text_item_dict( text="{0}{1}%".format( "+" if difficultyChange > 0 else "", round(difficultyChange, 2) ), - font_size=60,gerty_type=gerty.type + font_size=60, + gerty_type=gerty.type, ) ) areas.append(text) @@ -137,55 +176,106 @@ async def get_mining_dashboard(gerty): return areas - async def get_lightning_stats(gerty): data = await get_mempool_info("statistics", gerty) areas = [] text = [] - text.append(get_text_item_dict(text="Channel Count", font_size=12, gerty_type=gerty.type)) - text.append(get_text_item_dict(text=format_number(data["latest"]["channel_count"]), font_size=20, gerty_type=gerty.type)) + text.append( + get_text_item_dict(text="Channel Count", font_size=12, gerty_type=gerty.type) + ) + text.append( + get_text_item_dict( + text=format_number(data["latest"]["channel_count"]), + font_size=20, + gerty_type=gerty.type, + ) + ) difference = get_percent_difference( current=data["latest"]["channel_count"], previous=data["previous"]["channel_count"], ) - text.append(get_text_item_dict(text="{0} in last 7 days".format(difference), font_size=12, gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="{0} in last 7 days".format(difference), + font_size=12, + gerty_type=gerty.type, + ) + ) areas.append(text) text = [] - text.append(get_text_item_dict(text="Number of Nodes", font_size=12,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=format_number(data["latest"]["node_count"]), font_size=20,gerty_type=gerty.type)) + text.append( + get_text_item_dict(text="Number of Nodes", font_size=12, gerty_type=gerty.type) + ) + text.append( + get_text_item_dict( + text=format_number(data["latest"]["node_count"]), + font_size=20, + gerty_type=gerty.type, + ) + ) difference = get_percent_difference( current=data["latest"]["node_count"], previous=data["previous"]["node_count"] ) - text.append(get_text_item_dict(text="{0} in last 7 days".format(difference), font_size=12,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="{0} in last 7 days".format(difference), + font_size=12, + gerty_type=gerty.type, + ) + ) areas.append(text) text = [] - text.append(get_text_item_dict(text="Total Capacity", font_size=12,gerty_type=gerty.type)) + text.append( + get_text_item_dict(text="Total Capacity", font_size=12, gerty_type=gerty.type) + ) avg_capacity = float(data["latest"]["total_capacity"]) / float(100000000) text.append( - get_text_item_dict(text="{0} BTC".format(format_number(avg_capacity, 2)), font_size=20,gerty_type=gerty.type) + get_text_item_dict( + text="{0} BTC".format(format_number(avg_capacity, 2)), + font_size=20, + gerty_type=gerty.type, + ) ) difference = get_percent_difference( current=data["latest"]["total_capacity"], previous=data["previous"]["total_capacity"], ) - text.append(get_text_item_dict(text="{0} in last 7 days".format(difference), font_size=12,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="{0} in last 7 days".format(difference), + font_size=12, + gerty_type=gerty.type, + ) + ) areas.append(text) text = [] - text.append(get_text_item_dict(text="Average Channel Capacity", font_size=12,gerty_type=gerty.type)) text.append( get_text_item_dict( - text="{0} sats".format(format_number(data["latest"]["avg_capacity"])), font_size=20,gerty_type=gerty.type + text="Average Channel Capacity", font_size=12, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict( + text="{0} sats".format(format_number(data["latest"]["avg_capacity"])), + font_size=20, + gerty_type=gerty.type, ) ) difference = get_percent_difference( current=data["latest"]["avg_capacity"], previous=data["previous"]["avg_capacity"], ) - text.append(get_text_item_dict(text="{0} in last 7 days".format(difference), font_size=12, gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="{0} in last 7 days".format(difference), + font_size=12, + gerty_type=gerty.type, + ) + ) areas.append(text) return areas @@ -244,21 +334,52 @@ async def get_mining_stat(stat_slug: str, gerty): text = [] if stat_slug == "mining_current_hash_rate": stat = await api_get_mining_stat(stat_slug, gerty) - current = "{0}hash".format(si_format(stat['current'], 6, True, " ")) - text.append(get_text_item_dict(text="Current Mining Hashrate", font_size=20,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=current, font_size=40,gerty_type=gerty.type)) + current = "{0}hash".format(si_format(stat["current"], 6, True, " ")) + text.append( + get_text_item_dict( + text="Current Mining Hashrate", font_size=20, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict(text=current, font_size=40, gerty_type=gerty.type) + ) # compare vs previous time period - difference = get_percent_difference(current=stat['current'], previous=stat['1w']) - text.append(get_text_item_dict(text="{0} in last 7 days".format(difference), font_size=12,gerty_type=gerty.type)) + difference = get_percent_difference( + current=stat["current"], previous=stat["1w"] + ) + text.append( + get_text_item_dict( + text="{0} in last 7 days".format(difference), + font_size=12, + gerty_type=gerty.type, + ) + ) elif stat_slug == "mining_current_difficulty": stat = await api_get_mining_stat(stat_slug, gerty) - text.append(get_text_item_dict(text="Current Mining Difficulty", font_size=20,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=format_number(stat['current']), font_size=40,gerty_type=gerty.type)) - difference = get_percent_difference(current=stat['current'], previous=stat['previous']) - text.append(get_text_item_dict(text="{0} since last adjustment".format(difference), font_size=12,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Current Mining Difficulty", font_size=20, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict( + text=format_number(stat["current"]), font_size=40, gerty_type=gerty.type + ) + ) + difference = get_percent_difference( + current=stat["current"], previous=stat["previous"] + ) + text.append( + get_text_item_dict( + text="{0} since last adjustment".format(difference), + font_size=12, + gerty_type=gerty.type, + ) + ) # text.append(get_text_item_dict("Required threshold for mining proof-of-work", 12)) return text + async def api_get_mining_stat(stat_slug: str, gerty): stat = "" if stat_slug == "mining_current_hash_rate": @@ -266,20 +387,23 @@ async def api_get_mining_stat(stat_slug: str, gerty): r = await get_mempool_info("hashrate_1m", gerty) data = r stat = {} - stat['current'] = data['currentHashrate'] - stat['1w'] = data['hashrates'][len(data['hashrates']) - 7]['avgHashrate'] + stat["current"] = data["currentHashrate"] + stat["1w"] = data["hashrates"][len(data["hashrates"]) - 7]["avgHashrate"] elif stat_slug == "mining_current_difficulty": async with httpx.AsyncClient() as client: r = await get_mempool_info("hashrate_1m", gerty) data = r stat = {} - stat['current'] = data['currentDifficulty'] - stat['previous'] = data['difficulty'][len(data['difficulty']) - 2]['difficulty'] + stat["current"] = data["currentDifficulty"] + stat["previous"] = data["difficulty"][len(data["difficulty"]) - 2][ + "difficulty" + ] return stat ########################################### + async def get_satoshi(): maxQuoteLength = 186 with open(os.path.join(LNBITS_PATH, "extensions/gerty/static/satoshi.json")) as fd: @@ -292,6 +416,7 @@ async def get_satoshi(): else: return quote + # Get a screen slug by its position in the screens_list def get_screen_slug_by_index(index: int, screens_list): if index <= len(screens_list) - 1: @@ -314,36 +439,54 @@ async def get_screen_data(screen_num: int, screens_list: dict, gerty): wallets = await get_lnbits_wallet_balances(gerty) text = [] for wallet in wallets: - text.append(get_text_item_dict(text="{0}'s Wallet".format(wallet['name']), font_size=20,gerty_type=gerty.type)) - text.append(get_text_item_dict(text="{0} sats".format(format_number(wallet['balance'])), font_size=40,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="{0}'s Wallet".format(wallet["name"]), + font_size=20, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict( + text="{0} sats".format(format_number(wallet["balance"])), + font_size=40, + gerty_type=gerty.type, + ) + ) areas.append(text) elif screen_slug == "fun_satoshi_quotes": areas.append(await get_satoshi_quotes(gerty)) elif screen_slug == "fun_exchange_market_rate": areas.append(await get_exchange_rate(gerty)) elif screen_slug == "onchain_difficulty_epoch_progress": - areas.append(await get_onchain_stat(screen_slug, gerty)) + areas.append(await get_onchain_stat(screen_slug, gerty)) elif screen_slug == "onchain_block_height": text = [] - text.append(get_text_item_dict(text=format_number(await get_mempool_info("tip_height", gerty)), font_size=80, gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text=format_number(await get_mempool_info("tip_height", gerty)), + font_size=80, + gerty_type=gerty.type, + ) + ) areas.append(text) elif screen_slug == "onchain_difficulty_retarget_date": - areas.append(await get_onchain_stat(screen_slug, gerty)) + areas.append(await get_onchain_stat(screen_slug, gerty)) elif screen_slug == "onchain_difficulty_blocks_remaining": - areas.append(await get_onchain_stat(screen_slug, gerty)) + areas.append(await get_onchain_stat(screen_slug, gerty)) elif screen_slug == "onchain_difficulty_epoch_time_remaining": - areas.append(await get_onchain_stat(screen_slug, gerty)) + areas.append(await get_onchain_stat(screen_slug, gerty)) elif screen_slug == "dashboard_onchain": title = "Onchain Data" areas = await get_onchain_dashboard(gerty) elif screen_slug == "mempool_recommended_fees": areas.append(await get_mempool_stat(screen_slug, gerty)) elif screen_slug == "mempool_tx_count": - areas.append(await get_mempool_stat(screen_slug, gerty)) + areas.append(await get_mempool_stat(screen_slug, gerty)) elif screen_slug == "mining_current_hash_rate": - areas.append(await get_mining_stat(screen_slug, gerty)) + areas.append(await get_mining_stat(screen_slug, gerty)) elif screen_slug == "mining_current_difficulty": - areas.append(await get_mining_stat(screen_slug, gerty)) + areas.append(await get_mining_stat(screen_slug, gerty)) elif screen_slug == "dashboard_mining": title = "Mining Data" areas = await get_mining_dashboard(gerty) @@ -364,34 +507,68 @@ async def get_dashboard(gerty): # XC rate text = [] amount = await satoshis_amount_as_fiat(100000000, gerty.exchange) - text.append(get_text_item_dict(text=format_number(amount), font_size=40,gerty_type=gerty.type)) - text.append(get_text_item_dict(text="BTC{0} price".format(gerty.exchange), font_size=15,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text=format_number(amount), font_size=40, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict( + text="BTC{0} price".format(gerty.exchange), + font_size=15, + gerty_type=gerty.type, + ) + ) areas.append(text) # balance text = [] wallets = await get_lnbits_wallet_balances(gerty) text = [] for wallet in wallets: - text.append(get_text_item_dict(text="{0}".format(wallet["name"]), font_size=15,gerty_type=gerty.type)) text.append( - get_text_item_dict(text="{0} sats".format(format_number(wallet["balance"])), font_size=20,gerty_type=gerty.type) + get_text_item_dict( + text="{0}".format(wallet["name"]), font_size=15, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict( + text="{0} sats".format(format_number(wallet["balance"])), + font_size=20, + gerty_type=gerty.type, + ) ) areas.append(text) # Mempool fees text = [] - text.append(get_text_item_dict(text=format_number(await get_mempool_info("tip_height", gerty)), font_size=40,gerty_type=gerty.type)) - text.append(get_text_item_dict(text="Current block height", font_size=15,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text=format_number(await get_mempool_info("tip_height", gerty)), + font_size=40, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict( + text="Current block height", font_size=15, gerty_type=gerty.type + ) + ) areas.append(text) # difficulty adjustment time text = [] text.append( get_text_item_dict( - text=await get_time_remaining_next_difficulty_adjustment(gerty), font_size=15,gerty_type=gerty.type + text=await get_time_remaining_next_difficulty_adjustment(gerty), + font_size=15, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict( + text="until next difficulty adjustment", font_size=12, gerty_type=gerty.type ) ) - text.append(get_text_item_dict(text="until next difficulty adjustment", font_size=12,gerty_type=gerty.type)) areas.append(text) return areas @@ -416,8 +593,20 @@ async def get_lnbits_wallet_balances(gerty): async def get_placeholder_text(): return [ - get_text_item_dict(text="Some placeholder text", x_pos=15, y_pos=10, font_size=50,gerty_type=gerty.type), - get_text_item_dict(text="Some placeholder text", x_pos=15, y_pos=10, font_size=50,gerty_type=gerty.type), + get_text_item_dict( + text="Some placeholder text", + x_pos=15, + y_pos=10, + font_size=50, + gerty_type=gerty.type, + ), + get_text_item_dict( + text="Some placeholder text", + x_pos=15, + y_pos=10, + font_size=50, + gerty_type=gerty.type, + ), ] @@ -427,10 +616,18 @@ async def get_satoshi_quotes(gerty): quote = await get_satoshi() if quote: if quote["text"]: - text.append(get_text_item_dict(text=quote["text"], font_size=15,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text=quote["text"], font_size=15, gerty_type=gerty.type + ) + ) if quote["date"]: text.append( - get_text_item_dict(text="Satoshi Nakamoto - {0}".format(quote["date"]), font_size=15,gerty_type=gerty.type) + get_text_item_dict( + text="Satoshi Nakamoto - {0}".format(quote["date"]), + font_size=15, + gerty_type=gerty.type, + ) ) return text @@ -445,44 +642,91 @@ async def get_exchange_rate(gerty): price = format_number(amount) text.append( get_text_item_dict( - text="Current {0}/BTC price".format(gerty.exchange), font_size=15,gerty_type=gerty.type + text="Current {0}/BTC price".format(gerty.exchange), + font_size=15, + gerty_type=gerty.type, ) ) - text.append(get_text_item_dict(text=price, font_size=80,gerty_type=gerty.type)) + text.append( + get_text_item_dict(text=price, font_size=80, gerty_type=gerty.type) + ) except: pass return text + async def get_onchain_stat(stat_slug: str, gerty): text = [] if ( - stat_slug == "onchain_difficulty_epoch_progress" or - stat_slug == "onchain_difficulty_retarget_date" or - stat_slug == "onchain_difficulty_blocks_remaining" or - stat_slug == "onchain_difficulty_epoch_time_remaining" - + stat_slug == "onchain_difficulty_epoch_progress" + or stat_slug == "onchain_difficulty_retarget_date" + or stat_slug == "onchain_difficulty_blocks_remaining" + or stat_slug == "onchain_difficulty_epoch_time_remaining" ): async with httpx.AsyncClient() as client: r = await get_mempool_info("difficulty_adjustment", gerty) if stat_slug == "onchain_difficulty_epoch_progress": - stat = round(r['progressPercent']) - text.append(get_text_item_dict(text="Progress through current difficulty epoch", font_size=15,gerty_type=gerty.type)) - text.append(get_text_item_dict(text="{0}%".format(stat), font_size=80,gerty_type=gerty.type)) + stat = round(r["progressPercent"]) + text.append( + get_text_item_dict( + text="Progress through current difficulty epoch", + font_size=15, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict( + text="{0}%".format(stat), font_size=80, gerty_type=gerty.type + ) + ) elif stat_slug == "onchain_difficulty_retarget_date": - stat = r['estimatedRetargetDate'] + stat = r["estimatedRetargetDate"] dt = datetime.fromtimestamp(stat / 1000).strftime("%e %b %Y at %H:%M") - text.append(get_text_item_dict(text="Date of next difficulty adjustment", font_size=15,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=dt, font_size=40,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Date of next difficulty adjustment", + font_size=15, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict(text=dt, font_size=40, gerty_type=gerty.type) + ) elif stat_slug == "onchain_difficulty_blocks_remaining": - stat = r['remainingBlocks'] - text.append(get_text_item_dict(text="Blocks until next difficulty adjustment", font_size=15,gerty_type=gerty.type)) - text.append(get_text_item_dict(text="{0}".format(format_number(stat)), font_size=80,gerty_type=gerty.type)) + stat = r["remainingBlocks"] + text.append( + get_text_item_dict( + text="Blocks until next difficulty adjustment", + font_size=15, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict( + text="{0}".format(format_number(stat)), + font_size=80, + gerty_type=gerty.type, + ) + ) elif stat_slug == "onchain_difficulty_epoch_time_remaining": - stat = r['remainingTime'] - text.append(get_text_item_dict(text="Time until next difficulty adjustment", font_size=15,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=get_time_remaining(stat / 1000, 4), font_size=20,gerty_type=gerty.type)) + stat = r["remainingTime"] + text.append( + get_text_item_dict( + text="Time until next difficulty adjustment", + font_size=15, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict( + text=get_time_remaining(stat / 1000, 4), + font_size=20, + gerty_type=gerty.type, + ) + ) return text + async def get_onchain_dashboard(gerty): areas = [] if isinstance(gerty.mempool_endpoint, str): @@ -490,27 +734,61 @@ async def get_onchain_dashboard(gerty): r = await get_mempool_info("difficulty_adjustment", gerty) text = [] stat = round(r["progressPercent"]) - text.append(get_text_item_dict(text="Progress through epoch", font_size=12,gerty_type=gerty.type)) - text.append(get_text_item_dict(text="{0}%".format(stat), font_size=60,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Progress through epoch", font_size=12, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict( + text="{0}%".format(stat), font_size=60, gerty_type=gerty.type + ) + ) areas.append(text) text = [] stat = r["estimatedRetargetDate"] dt = datetime.fromtimestamp(stat / 1000).strftime("%e %b %Y at %H:%M") - text.append(get_text_item_dict(text="Date of next adjustment", font_size=12,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=dt, font_size=20,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Date of next adjustment", font_size=12, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict(text=dt, font_size=20, gerty_type=gerty.type) + ) areas.append(text) text = [] stat = r["remainingBlocks"] - text.append(get_text_item_dict(text="Blocks until adjustment", font_size=12,gerty_type=gerty.type)) - text.append(get_text_item_dict(text="{0}".format(format_number(stat)), font_size=60,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Blocks until adjustment", font_size=12, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict( + text="{0}".format(format_number(stat)), + font_size=60, + gerty_type=gerty.type, + ) + ) areas.append(text) text = [] stat = r["remainingTime"] - text.append(get_text_item_dict(text="Time until adjustment", font_size=12,gerty_type=gerty.type)) - text.append(get_text_item_dict(text=get_time_remaining(stat / 1000, 4), font_size=20,gerty_type=gerty.type)) + text.append( + get_text_item_dict( + text="Time until adjustment", font_size=12, gerty_type=gerty.type + ) + ) + text.append( + get_text_item_dict( + text=get_time_remaining(stat / 1000, 4), + font_size=20, + gerty_type=gerty.type, + ) + ) areas.append(text) return areas @@ -531,9 +809,19 @@ async def get_mempool_stat(stat_slug: str, gerty): r = get_mempool_info("mempool", gerty) if stat_slug == "mempool_tx_count": stat = round(r["count"]) - text.append(get_text_item_dict(text="Transactions in the mempool", font_size=15,gerty_type=gerty.type)) text.append( - get_text_item_dict(text="{0}".format(format_number(stat)), font_size=80,gerty_type=gerty.type) + get_text_item_dict( + text="Transactions in the mempool", + font_size=15, + gerty_type=gerty.type, + ) + ) + text.append( + get_text_item_dict( + text="{0}".format(format_number(stat)), + font_size=80, + gerty_type=gerty.type, + ) ) elif stat_slug == "mempool_recommended_fees": y_offset = 60 @@ -541,7 +829,9 @@ async def get_mempool_stat(stat_slug: str, gerty): pos_y = 80 + y_offset text.append(get_text_item_dict("mempool.space", 40, 160, pos_y, gerty.type)) pos_y = 180 + y_offset - text.append(get_text_item_dict("Recommended Tx Fees", 20, 240, pos_y, gerty.type)) + text.append( + get_text_item_dict("Recommended Tx Fees", 20, 240, pos_y, gerty.type) + ) pos_y = 280 + y_offset text.append( @@ -571,7 +861,7 @@ async def get_mempool_stat(stat_slug: str, gerty): font_size=font_size, x_pos=30, y_pos=pos_y, - gerty_type=gerty.type + gerty_type=gerty.type, ) ) @@ -586,7 +876,7 @@ async def get_mempool_stat(stat_slug: str, gerty): font_size=font_size, x_pos=235, y_pos=pos_y, - gerty_type=gerty.type + gerty_type=gerty.type, ) ) @@ -601,7 +891,7 @@ async def get_mempool_stat(stat_slug: str, gerty): font_size=font_size, x_pos=460, y_pos=pos_y, - gerty_type=gerty.type + gerty_type=gerty.type, ) ) @@ -616,7 +906,7 @@ async def get_mempool_stat(stat_slug: str, gerty): font_size=font_size, x_pos=750, y_pos=pos_y, - gerty_type=gerty.type + gerty_type=gerty.type, ) ) return text @@ -628,13 +918,14 @@ def get_date_suffix(dayNumber): else: return ["st", "nd", "rd"][dayNumber % 10 - 1] + def get_time_remaining(seconds, granularity=2): intervals = ( # ('weeks', 604800), # 60 * 60 * 24 * 7 - ('days', 86400), # 60 * 60 * 24 - ('hours', 3600), # 60 * 60 - ('minutes', 60), - ('seconds', 1), + ("days", 86400), # 60 * 60 * 24 + ("hours", 3600), # 60 * 60 + ("minutes", 60), + ("seconds", 1), ) result = [] @@ -644,6 +935,6 @@ def get_time_remaining(seconds, granularity=2): if value: seconds -= value * count if value == 1: - name = name.rstrip('s') + name = name.rstrip("s") result.append("{} {}".format(round(value), name)) - return ', '.join(result[:granularity]) \ No newline at end of file + return ", ".join(result[:granularity]) diff --git a/lnbits/extensions/gerty/migrations.py b/lnbits/extensions/gerty/migrations.py index b2a9d1e1..830b8cfd 100644 --- a/lnbits/extensions/gerty/migrations.py +++ b/lnbits/extensions/gerty/migrations.py @@ -24,6 +24,7 @@ async def m002_add_utc_offset_col(db): """ await db.execute("ALTER TABLE gerty.gertys ADD COLUMN utc_offset INT;") + async def m003_add_gerty_model_col(db): """ support for Gerty model col @@ -33,6 +34,7 @@ async def m003_add_gerty_model_col(db): #########MEMPOOL MIGRATIONS######## + async def m004_initial(db): """ Initial Gertys table. @@ -40,6 +42,7 @@ async def m004_initial(db): await db.execute( """ CREATE TABLE gerty.mempool ( + mempool_endpoint TEXT PRIMARY KEY, endpoint TEXT NOT NULL, data TEXT NOT NULL, time TIMESTAMP diff --git a/lnbits/extensions/gerty/models.py b/lnbits/extensions/gerty/models.py index fddf886c..4bb82d74 100644 --- a/lnbits/extensions/gerty/models.py +++ b/lnbits/extensions/gerty/models.py @@ -27,6 +27,7 @@ class Gerty(BaseModel): #########MEMPOOL MODELS########### + class MempoolEndpoint(BaseModel): fees_recommended: str = "/api/v1/fees/recommended" hashrate_1w: str = "/api/v1/mining/hashrate/1w" @@ -36,7 +37,9 @@ class MempoolEndpoint(BaseModel): tip_height: str = "/api/blocks/tip/height" mempool: str = "/api/mempool" + class Mempool(BaseModel): + mempool_endpoint: str = Query(None) endpoint: str = Query(None) data: str = Query(None) - time: int = Query(None) \ No newline at end of file + time: int = Query(None) diff --git a/lnbits/extensions/gerty/templates/gerty/index.html b/lnbits/extensions/gerty/templates/gerty/index.html index bb4f9a32..83d821ea 100644 --- a/lnbits/extensions/gerty/templates/gerty/index.html +++ b/lnbits/extensions/gerty/templates/gerty/index.html @@ -1,808 +1,810 @@ -{% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} {% block page %} -
-
- - - New Gerty - - - - - -
-
-
Gerty
-
-
- Export to CSV -
-
- - {% raw %} - +{% extends "base.html" %} {% from "macros.jinja" import window_vars with context +%} {% block page %} +
+
+ + + New Gerty + + + + + +
+
+
Gerty
+
+
+ Export to CSV +
+
+ + {% raw %} + - - {% endraw %} - -
-
+ + {% endraw %} + + + +
+ +
+ + +
+ {{ SITE_TITLE }} Gerty extension +
+
+ + + {% include "gerty/_api_docs.html" %} + +
+
+ + + + + + +

Use the toggles below to control what your Gerty will display

+ +
+
+ + Displays random quotes from Satoshi + +
+ +
+ + +
+
+ + + Hit enter to add values + +
+
+ + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+ +
+ + +
+ + The amount of time in seconds between screen updates + + +
-
- - -
- {{ SITE_TITLE }} Gerty extension -
-
- - - {% include "gerty/_api_docs.html" %} - -
+
+ Create Gerty + + Update Gerty + + Cancel +
- - - - - - - - Hit enter to add values - - - - Used for getting onchain/ln stats - - - - The amount of time in seconds between screen updates - - - - - Enter a UTC time offset value (e.g. -1) - - -

Use the toggles below to control what your Gerty will display

- - - - - - - - - - - - - - - - - - - Displays random quotes from Satoshi - - - - - - - - - - Toggle all - -
- - - - - - - - -
- - - Toggle all - -
- - - - -
- - - - Toggle all - -
- - - -
- -
- - -
- Create Gerty - - Update Gerty - - Cancel - -
-
-
-
-
+
+
+
+
{% endblock %} {% block scripts %} {{ window_vars(user) }} - + } + // This is a weird hack we have to use to get VueJS to persist the previous toggle state between + // watches. VueJS passes the old and new values by reference so when comparing objects they + // will have the same values unless we do this + this.oldToggleStates = JSON.parse(JSON.stringify(toggleStatesValue)) + }, + deep: true + } + } + }) + {% endblock %} {% block styles %} - + {% endblock %} diff --git a/lnbits/extensions/gerty/views_api.py b/lnbits/extensions/gerty/views_api.py index eda95e96..b50e7802 100644 --- a/lnbits/extensions/gerty/views_api.py +++ b/lnbits/extensions/gerty/views_api.py @@ -23,17 +23,18 @@ from lnbits.utils.exchange_rates import satoshis_amount_as_fiat from ...settings import LNBITS_PATH from . import gerty_ext from .crud import ( - create_gerty, - delete_gerty, - get_gerty, - get_gertys, + create_gerty, + delete_gerty, + get_gerty, + get_gertys, update_gerty, - get_mempool_info - ) + get_mempool_info, +) from .helpers import * from .models import Gerty, MempoolEndpoint + @gerty_ext.get("/api/v1/gerty", status_code=HTTPStatus.OK) async def api_gertys( all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type) @@ -145,40 +146,47 @@ async def api_gerty_json(gerty_id: str, p: int = None): # page number }, } + ###########CACHED MEMPOOL############## + @gerty_ext.get("/api/v1/gerty/fees-recommended/{gerty_id}") async def api_gerty_get_fees_recommended(gerty_id): - gerty = await get_gerty(gerty_id) return await get_mempool_info("fees_recommended", gerty) + @gerty_ext.get("/api/v1/gerty/hashrate-1w/{gerty_id}") async def api_gerty_get_hashrate_1w(gerty_id): gerty = await get_gerty(gerty_id) return await get_mempool_info("hashrate_1w", gerty) + @gerty_ext.get("/api/v1/gerty/hashrate-1m/{gerty_id}") async def api_gerty_get_hashrate_1m(gerty_id): gerty = await get_gerty(gerty_id) return await get_mempool_info("hashrate_1m", gerty) + @gerty_ext.get("/api/v1/gerty/statistics/{gerty_id}") async def api_gerty_get_statistics(gerty_id): gerty = await get_gerty(gerty_id) return await get_mempool_info("statistics", gerty) + @gerty_ext.get("/api/v1/gerty/difficulty-adjustment/{gerty_id}") async def api_gerty_get_difficulty_adjustment(gerty_id): gerty = await get_gerty(gerty_id) return await get_mempool_info("difficulty_adjustment", gerty) + @gerty_ext.get("/api/v1/gerty/tip-height/{gerty_id}") async def api_gerty_get_tip_height(gerty_id): gerty = await get_gerty(gerty_id) return await get_mempool_info("tip_height", gerty) + @gerty_ext.get("/api/v1/gerty/mempool/{gerty_id}") async def api_gerty_get_mempool(gerty_id): gerty = await get_gerty(gerty_id) - return await get_mempool_info("mempool", gerty) \ No newline at end of file + return await get_mempool_info("mempool", gerty)