File size: 4,202 Bytes
e9a414a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import gradio as gr
import requests
import time
import datetime
import threading

# Function to fetch cryptocurrency prices from CoinGecko
def get_crypto_prices(crypto_ids, vs_currency="usd"):
    try:
        ids = ",".join(crypto_ids)
        url = f"https://api.coingecko.com/api/v3/simple/price?ids={ids}&vs_currencies={vs_currency}"
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()
        prices = {}
        for crypto_id in crypto_ids:
            if crypto_id in data:
                prices[crypto_id] = data[crypto_id][vs_currency]
            else:
                prices[crypto_id] = "N/A"  # Indicate if price is not available
        return prices
    except requests.exceptions.RequestException as e:
        return {crypto_id: f"Error: {e}" for crypto_id in crypto_ids}
    except Exception as e:
        return {crypto_id: f"Error: {e}" for crypto_id in crypto_ids}

# Function to get the current time as a string
def get_current_time():
    now = datetime.datetime.now()
    return now.strftime("%Y-%m-%d %H:%M:%S")

# Function to calculate the countdown to the next minute
def get_countdown():
    now = datetime.datetime.now()
    seconds_to_next_minute = 60 - now.second
    return f"Next Update in: {seconds_to_next_minute} seconds"

# Shared data (prices)
shared_prices = {} # This is the "Prices" that is shown to the GUI.

def scheduled_update(): # schedule a thread to trigger every minute.
    global shared_prices # import the global shared prices so we can apply changes.
    crypto_ids = ["bitcoin", "ethereum", "binancecoin", "ripple", "litecoin", "dash"]
    shared_prices = get_crypto_prices(crypto_ids) # Apply the new prices

    now = datetime.datetime.now()
    seconds_to_next_minute = 60 - now.second # get correct timing, it triggers in 1 minute.
    threading.Timer(seconds_to_next_minute, scheduled_update).start()  # Schedule the next update

# Gradio Interface
def update_all(): # runs the GUI clock.
    global shared_prices
    crypto_ids = ["bitcoin", "ethereum", "binancecoin", "ripple", "litecoin", "dash"] # we want it as one function.
    price_strings = []
    for crypto_id in crypto_ids:
        if crypto_id not in shared_prices: # when it loads the price might not be there, show some error message instead, make it more user friendy.
            price_strings.append("Loading, Please wait.") # give a warning state that something is going on.
            continue

        price = shared_prices[crypto_id] # it might come as error
        if isinstance(price, str): # means an error string.
            price_strings.append(f"Current {crypto_id.upper()} Price: {price}")
        else:
            price_strings.append(f"Current {crypto_id.upper()} Price: ${price:.2f}") # apply it to the UI.

    return get_current_time(), get_countdown(), *price_strings

with gr.Blocks() as demo:
    clock_output = gr.Textbox(label="Current Time") # put it before the row.
    countdown_output = gr.Textbox(label="Next Update")

    with gr.Row(): # prices are in these objects now.
        with gr.Column():
            output_btc = gr.Textbox(label="BTC Price")
            output_eth = gr.Textbox(label="ETH Price")
            output_bnb = gr.Textbox(label="BNB Price")
        with gr.Column():
            output_xrp = gr.Textbox(label="XRP Price")
            output_ltc = gr.Textbox(label="LTC Price")
            output_dash = gr.Textbox(label="DASH Price")

    demo.load(update_all, None, [clock_output, countdown_output, output_btc, output_eth, output_bnb, output_xrp, output_ltc, output_dash], every=1) # Update clock every second, the timer runs every second.  Might be bad, as it updates more frequent.

# Start the scheduled updates and fetch the initial data
now = datetime.datetime.now() # so it can run for a bit before setting.
seconds_to_next_minute = 60 - now.second
time.sleep(seconds_to_next_minute) # wait for start, you may want to do this to display what you want in the GUI so you can debug.
scheduled_update() # start it, get new results

if __name__ == "__main__":
    demo.launch()