summaryrefslogtreecommitdiff
path: root/btcdashboard
diff options
context:
space:
mode:
authorhc <hc@email.ch>2024-09-12 11:46:51 +0800
committerhc <hc@email.ch>2024-09-12 11:46:51 +0800
commitfabefacd8da4932c9a5e8b4aec33d196c290d33b (patch)
tree58f775cff291903a091ed3d4a63265ad44705614 /btcdashboard
archive of tuffy and btcdashboardHEADmain
Diffstat (limited to 'btcdashboard')
-rw-r--r--btcdashboard/App.js81
-rw-r--r--btcdashboard/DOCS/react121
-rw-r--r--btcdashboard/pulltoredis.py56
-rw-r--r--btcdashboard/server3.js43
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 @@
1import React, { useState, useEffect } from 'react';
2import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
3
4const App = () => {
5 const [prices, setPrices] = useState([]);
6 const [rawData, setRawData] = useState('');
7 const [error, setError] = useState(null);
8
9 const testingString = "hiiii";
10
11 useEffect(() => {
12 const fetchPrices = async () => {
13 try {
14 console.log('Fetching prices...');
15 const response = await fetch('/api/prices', {
16 method: 'GET',
17 headers: {
18 'Content-Type': 'application/json',
19 },
20 });
21 console.log('Response status:', response.status);
22 console.log('Response headers:', response.headers);
23 if (!response.ok) {
24 throw new Error(`HTTP error! status: ${response.status}`);
25 }
26 const data = await response.json();
27 console.log('Fetched data:', data);
28 setPrices(data);
29 setRawData(JSON.stringify(data, null, 2));
30 setError(null);
31 } catch (error) {
32 console.error('Failed to fetch prices:', error);
33 setError(error.toString());
34 setRawData('');
35 }
36 };
37 fetchPrices();
38 const interval = setInterval(fetchPrices, 5000);
39 return () => clearInterval(interval);
40 }, []);
41
42 // prep data
43 const chartData = prices.map(item => {
44 const parsedItem = JSON.parse(item);
45 return {
46 price: parsedItem.price,
47 time: new Date(parsedItem.timestamp * 1000).toLocaleTimeString()
48 };
49 }).reverse(); // show oldest data first
50
51 return (
52 <div>
53 <h1>price</h1>
54 <p>test stuff: {testingString}</p>
55 {error && <p>Error: {error}</p>}
56 <pre>{rawData}</pre>
57
58 <h2>Price Graph</h2>
59 <ResponsiveContainer width="100%" height={400}>
60 <LineChart
61 data={chartData}
62 margin={{
63 top: 5,
64 right: 30,
65 left: 20,
66 bottom: 5,
67 }}
68 >
69 <CartesianGrid strokeDasharray="3 3" />
70 <XAxis dataKey="time" />
71 <YAxis domain={['auto', 'auto']} />
72 <Tooltip />
73 <Legend />
74 <Line type="monotone" dataKey="price" stroke="#8884d8" activeDot={{ r: 8 }} />
75 </LineChart>
76 </ResponsiveContainer>
77 </div>
78 );
79};
80
81export 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 @@
1
2sudo dnf update -y
3sudo dnf install nodejs npm -y
4mkdir prices && cd prices
5
6npx create-react-app client
7cd client
8cd ..
9npm install axios recharts
10
11mkdir server
12cd server
13npm init -y
14cd ..
15npm install express redis cors
16
17sudo dnf install -y redis
18sudo systemctl start redis
19sudo systemctl enable redis
20sudo systemctl status redis
21
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 @@
1import asyncio
2import aiohttp
3import redis
4import json
5import logging
6import time
7
8logging.basicConfig(level=logging.INFO)
9logger = logging.getLogger(__name__)
10
11# redis default port
12redis_client = redis.Redis(host='localhost', port=6379, db=0)
13
14URL = 'https://api.kraken.com/0/public/Ticker?pair=BTCUSD'
15HEADERS = {'Accept': 'application/json'}
16
17MAX_PRICES = 10
18UPDATE_INTERVAL = 3 # seconds
19
20async def fetch_btc_price(session):
21 try:
22 async with session.get(URL, headers=HEADERS, ssl=False) as response:
23 data = await response.json()
24 return float(data['result']['XXBTZUSD']['c'][0])
25 except Exception as e:
26 logger.error(f"error getting price: {e}")
27 return None
28
29async def update_price():
30 async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session:
31 while True:
32 price = await fetch_btc_price(session)
33 if price:
34 timestamp = int(time.time()) # this is unix
35 price_data = json.dumps({"price": price, "timestamp": timestamp})
36
37 redis_client.lpush('btc_prices', price_data)
38
39 redis_client.ltrim('btc_prices', 0, MAX_PRICES - 1)
40
41 logger.info(f"updated btc price: ${price}")
42
43 all_prices = redis_client.lrange('btc_prices', 0, -1)
44 logger.info("prices:")
45 for i, p in enumerate(all_prices, 1):
46 p_data = json.loads(p)
47 logger.info(f"{i}. ${p_data['price']} at {p_data['timestamp']}")
48
49 await asyncio.sleep(UPDATE_INTERVAL)
50
51async def main():
52 logger.info("btc price update")
53 await update_price()
54
55if __name__ == "__main__":
56 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 @@
1const express = require('express');
2const cors = require('cors');
3const redis = require('redis');
4
5const app = express();
6const PORT = 3001;
7
8const redisClient = redis.createClient({
9 url: 'redis://localhost:6379' // this is default port
10});
11
12// CORS
13app.use((req, res, next) => {
14 res.header('Access-Control-Allow-Origin', '*');
15 res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
16 res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
17 next();
18});
19
20app.get('/api/prices', async (req, res) => {
21 try {
22 const prices = await redisClient.lRange('btc_prices', 0, -1);
23
24 res.header('Access-Control-Allow-Origin', '*');
25 res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
26 res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
27
28 res.json(prices);
29 } catch (error) {
30 console.error('Error fetching prices:', error);
31 res.status(500).json({ error: 'Internal Server Error' });
32 }
33});
34
35async function startServer() {
36 await redisClient.connect();
37
38 app.listen(PORT, () => {
39 console.log(`Server running on http://localhost:${PORT}`);
40 });
41}
42
43startServer().catch(console.error);