diff options
| author | hc <hc@email.ch> | 2024-09-12 11:46:51 +0800 |
|---|---|---|
| committer | hc <hc@email.ch> | 2024-09-12 11:46:51 +0800 |
| commit | fabefacd8da4932c9a5e8b4aec33d196c290d33b (patch) | |
| tree | 58f775cff291903a091ed3d4a63265ad44705614 /btcdashboard | |
Diffstat (limited to 'btcdashboard')
| -rw-r--r-- | btcdashboard/App.js | 81 | ||||
| -rw-r--r-- | btcdashboard/DOCS/react1 | 21 | ||||
| -rw-r--r-- | btcdashboard/pulltoredis.py | 56 | ||||
| -rw-r--r-- | btcdashboard/server3.js | 43 |
4 files changed, 201 insertions, 0 deletions
diff --git a/btcdashboard/App.js b/btcdashboard/App.js new file mode 100644 index 0000000..838ab4f --- /dev/null +++ b/btcdashboard/App.js @@ -0,0 +1,81 @@ +import React, { useState, useEffect } from 'react'; +import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'; + +const App = () => { + const [prices, setPrices] = useState([]); + const [rawData, setRawData] = useState(''); + const [error, setError] = useState(null); + + const testingString = "hiiii"; + + useEffect(() => { + const fetchPrices = async () => { + try { + console.log('Fetching prices...'); + const response = await fetch('/api/prices', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + console.log('Response status:', response.status); + console.log('Response headers:', response.headers); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + console.log('Fetched data:', data); + setPrices(data); + setRawData(JSON.stringify(data, null, 2)); + setError(null); + } catch (error) { + console.error('Failed to fetch prices:', error); + setError(error.toString()); + setRawData(''); + } + }; + fetchPrices(); + const interval = setInterval(fetchPrices, 5000); + return () => clearInterval(interval); + }, []); + + // prep data + const chartData = prices.map(item => { + const parsedItem = JSON.parse(item); + return { + price: parsedItem.price, + time: new Date(parsedItem.timestamp * 1000).toLocaleTimeString() + }; + }).reverse(); // show oldest data first + + return ( + <div> + <h1>price</h1> + <p>test stuff: {testingString}</p> + {error && <p>Error: {error}</p>} + <pre>{rawData}</pre> + + <h2>Price Graph</h2> + <ResponsiveContainer width="100%" height={400}> + <LineChart + data={chartData} + margin={{ + top: 5, + right: 30, + left: 20, + bottom: 5, + }} + > + <CartesianGrid strokeDasharray="3 3" /> + <XAxis dataKey="time" /> + <YAxis domain={['auto', 'auto']} /> + <Tooltip /> + <Legend /> + <Line type="monotone" dataKey="price" stroke="#8884d8" activeDot={{ r: 8 }} /> + </LineChart> + </ResponsiveContainer> + </div> + ); +}; + +export default App; diff --git a/btcdashboard/DOCS/react1 b/btcdashboard/DOCS/react1 new file mode 100644 index 0000000..9f8da04 --- /dev/null +++ b/btcdashboard/DOCS/react1 @@ -0,0 +1,21 @@ + +sudo dnf update -y +sudo dnf install nodejs npm -y +mkdir prices && cd prices + +npx create-react-app client +cd client +cd .. +npm install axios recharts + +mkdir server +cd server +npm init -y +cd .. +npm install express redis cors + +sudo dnf install -y redis +sudo systemctl start redis +sudo systemctl enable redis +sudo systemctl status redis + diff --git a/btcdashboard/pulltoredis.py b/btcdashboard/pulltoredis.py new file mode 100644 index 0000000..0a82fa7 --- /dev/null +++ b/btcdashboard/pulltoredis.py @@ -0,0 +1,56 @@ +import asyncio +import aiohttp +import redis +import json +import logging +import time + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# redis default port +redis_client = redis.Redis(host='localhost', port=6379, db=0) + +URL = 'https://api.kraken.com/0/public/Ticker?pair=BTCUSD' +HEADERS = {'Accept': 'application/json'} + +MAX_PRICES = 10 +UPDATE_INTERVAL = 3 # seconds + +async def fetch_btc_price(session): + try: + async with session.get(URL, headers=HEADERS, ssl=False) as response: + data = await response.json() + return float(data['result']['XXBTZUSD']['c'][0]) + except Exception as e: + logger.error(f"error getting price: {e}") + return None + +async def update_price(): + async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session: + while True: + price = await fetch_btc_price(session) + if price: + timestamp = int(time.time()) # this is unix + price_data = json.dumps({"price": price, "timestamp": timestamp}) + + redis_client.lpush('btc_prices', price_data) + + redis_client.ltrim('btc_prices', 0, MAX_PRICES - 1) + + logger.info(f"updated btc price: ${price}") + + all_prices = redis_client.lrange('btc_prices', 0, -1) + logger.info("prices:") + for i, p in enumerate(all_prices, 1): + p_data = json.loads(p) + logger.info(f"{i}. ${p_data['price']} at {p_data['timestamp']}") + + await asyncio.sleep(UPDATE_INTERVAL) + +async def main(): + logger.info("btc price update") + await update_price() + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/btcdashboard/server3.js b/btcdashboard/server3.js new file mode 100644 index 0000000..72bfb8d --- /dev/null +++ b/btcdashboard/server3.js @@ -0,0 +1,43 @@ +const express = require('express'); +const cors = require('cors'); +const redis = require('redis'); + +const app = express(); +const PORT = 3001; + +const redisClient = redis.createClient({ + url: 'redis://localhost:6379' // this is default port +}); + +// CORS +app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); + res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); + next(); +}); + +app.get('/api/prices', async (req, res) => { + try { + const prices = await redisClient.lRange('btc_prices', 0, -1); + + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); + res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); + + res.json(prices); + } catch (error) { + console.error('Error fetching prices:', error); + res.status(500).json({ error: 'Internal Server Error' }); + } +}); + +async function startServer() { + await redisClient.connect(); + + app.listen(PORT, () => { + console.log(`Server running on http://localhost:${PORT}`); + }); +} + +startServer().catch(console.error); |
