From fabefacd8da4932c9a5e8b4aec33d196c290d33b Mon Sep 17 00:00:00 2001 From: hc Date: Thu, 12 Sep 2024 11:46:51 +0800 Subject: archive of tuffy and btcdashboard --- btcdashboard/App.js | 81 +++++++++++++++++++++++++++++++++++++++++++++ btcdashboard/DOCS/react1 | 21 ++++++++++++ btcdashboard/pulltoredis.py | 56 +++++++++++++++++++++++++++++++ btcdashboard/server3.js | 43 ++++++++++++++++++++++++ 4 files changed, 201 insertions(+) create mode 100644 btcdashboard/App.js create mode 100644 btcdashboard/DOCS/react1 create mode 100644 btcdashboard/pulltoredis.py create mode 100644 btcdashboard/server3.js (limited to 'btcdashboard') 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 ( +
+

price

+

test stuff: {testingString}

+ {error &&

Error: {error}

} +
{rawData}
+ +

Price Graph

+ + + + + + + + + + +
+ ); +}; + +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); -- cgit v1.2.3-70-g09d2