initial working code
This commit is contained in:
parent
60c5d4888c
commit
46368c841a
36
index.js
36
index.js
@ -0,0 +1,36 @@
|
|||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const log = require('loglevel');
|
||||||
|
|
||||||
|
const dataLoaders = require('./lib/dataLoaders');
|
||||||
|
|
||||||
|
if (process.env.LOG != undefined) {
|
||||||
|
log.setLevel(process.env.LOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
const widgetData = { };
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
app.get("/api/data", function(req, res) {
|
||||||
|
res.json(widgetData);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use("/", express.static(path.join(__dirname, "page")));
|
||||||
|
|
||||||
|
app.listen(process.env.PORT, process.env.ADDRESS, () => {
|
||||||
|
log.info(`Server is listening on ${process.env.ADDRESS}:${process.env.PORT}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
for(let id in dataLoaders) {
|
||||||
|
dataLoaders[id].on("data", data => {
|
||||||
|
widgetData[id] = data;
|
||||||
|
});
|
||||||
|
|
||||||
|
widgetData[id] = dataLoaders[id].initial;
|
||||||
|
|
||||||
|
dataLoaders[id].start();
|
||||||
|
}
|
||||||
42
lib/bitcoinData.js
Normal file
42
lib/bitcoinData.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
const { EventEmitter } = require('events');
|
||||||
|
const axios = require('axios');
|
||||||
|
const log = require('loglevel');
|
||||||
|
|
||||||
|
class BitcoinData extends EventEmitter {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
get initial() {
|
||||||
|
return { bitpay: null, coinbase: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.fetch();
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
this.fetch();
|
||||||
|
}, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch() {
|
||||||
|
Promise.all([
|
||||||
|
axios.get("https://bitpay.com/api/rates/eur").catch(err => log.error(err.config.url, err.message)),
|
||||||
|
axios.get("https://api.coinbase.com/v2/prices/spot?currency=EUR").catch(err => log.error(err.config.url, err.message)),
|
||||||
|
]).then(resp => {
|
||||||
|
let bitpay = null, coinbase = null;
|
||||||
|
|
||||||
|
if (resp[0] != undefined) {
|
||||||
|
bitpay = (Math.round(resp[0].data.rate * 100) / 100) + "€";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp[1] != undefined) {
|
||||||
|
coinbase = (Math.round(resp[1].data.data.amount * 100) / 100) + "€";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.emit("data", { bitpay, coinbase });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new BitcoinData();
|
||||||
5
lib/dataLoaders.js
Normal file
5
lib/dataLoaders.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
bitcoin: require('./bitcoinData'),
|
||||||
|
monero: require('./xmrData'),
|
||||||
|
weather: require('./weatherData'),
|
||||||
|
};
|
||||||
40
lib/weatherData.js
Normal file
40
lib/weatherData.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const { EventEmitter } = require('events');
|
||||||
|
const axios = require('axios');
|
||||||
|
const log = require('loglevel');
|
||||||
|
|
||||||
|
const AACHEN = 3247449;
|
||||||
|
const STEINFURT = 2828105;
|
||||||
|
|
||||||
|
class WeatherData extends EventEmitter {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
get initial() {
|
||||||
|
return { aachen: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.fetch();
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
this.fetch();
|
||||||
|
}, 5*60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch() {
|
||||||
|
Promise.all([
|
||||||
|
axios.get(`https://api.openweathermap.org/data/2.5/weather?id=${AACHEN}&units=metric&appid=f16fb438a43a12fb3347ca17937649be`).catch(err => log.error(err.config.url, err.message)),
|
||||||
|
]).then(resp => {
|
||||||
|
let aachen = null;
|
||||||
|
|
||||||
|
if (resp[0] != undefined) {
|
||||||
|
aachen = resp[0].data.main.temp + "°C";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.emit("data", { aachen });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new WeatherData();
|
||||||
47
lib/xmrData.js
Normal file
47
lib/xmrData.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
const { EventEmitter } = require('events');
|
||||||
|
const axios = require('axios');
|
||||||
|
const log = require('loglevel');
|
||||||
|
|
||||||
|
class XMRData extends EventEmitter {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
get initial() {
|
||||||
|
return { shapeshift: null, xmrto: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.fetch();
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
this.fetch();
|
||||||
|
}, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch() {
|
||||||
|
Promise.all([
|
||||||
|
axios.get("https://bitpay.com/api/rates/eur").catch(err => log.error(err.config.url, err.message)),
|
||||||
|
axios.get("https://shapeshift.io/marketinfo/btc_xmr").catch(err => log.error(err.config.url, err.message)),
|
||||||
|
axios.get("https://xmr.to/api/v2/xmr2btc/order_parameter_query/").catch(err => log.error(err.config.url, err.message)),
|
||||||
|
]).then(resp => {
|
||||||
|
let bitpay = null, shapeshift = null, xmrto = null;
|
||||||
|
|
||||||
|
if (resp[0] != undefined) {
|
||||||
|
bitpay = resp[0].data.rate;
|
||||||
|
|
||||||
|
if (resp[1] != undefined) {
|
||||||
|
shapeshift = (Math.round((bitpay / resp[1].data.rate) * 100) / 100) + "€";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp[2] != undefined) {
|
||||||
|
xmrto = (Math.round((bitpay * resp[2].data.price) * 100) / 100) + "€";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.emit("data", { shapeshift, xmrto });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new XMRData();
|
||||||
5
package-lock.json
generated
5
package-lock.json
generated
@ -249,6 +249,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
|
||||||
"integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw=="
|
"integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw=="
|
||||||
},
|
},
|
||||||
|
"loglevel": {
|
||||||
|
"version": "1.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.3.tgz",
|
||||||
|
"integrity": "sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA=="
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.19.0",
|
"axios": "^0.19.0",
|
||||||
"dotenv": "^8.0.0",
|
"dotenv": "^8.0.0",
|
||||||
"express": "^4.17.1"
|
"express": "^4.17.1",
|
||||||
|
"loglevel": "^1.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
page/img/bitpay.png
Normal file
BIN
page/img/bitpay.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
BIN
page/img/coinbase.png
Normal file
BIN
page/img/coinbase.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
page/img/icon.png
Normal file
BIN
page/img/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
BIN
page/img/shapeshift.png
Normal file
BIN
page/img/shapeshift.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
BIN
page/img/weather.png
Normal file
BIN
page/img/weather.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
page/img/xmrto.png
Normal file
BIN
page/img/xmrto.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@ -1,20 +1,109 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Test</title>
|
<title>Widget Display</title>
|
||||||
|
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
|
|
||||||
|
<link rel="shortcut icon" type="image/png" href="img/icon.png"/>
|
||||||
|
<link rel="apple-touch-icon" href="img/icon.png">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
|
color: white;
|
||||||
|
background-color: black;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.inverted {
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget {
|
||||||
|
display: inline-block;
|
||||||
|
padding-top: 20px;
|
||||||
|
height: 50px;
|
||||||
|
position: relative;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget .title {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.databox {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.databox img {
|
||||||
|
display: inline-block;
|
||||||
|
height: 30px;
|
||||||
|
margin: 10px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.databox .data {
|
||||||
|
display: inline-block;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
vertical-align: top;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay {
|
||||||
|
z-index: 1000;
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script src="jquery-1.12.4.min.js" type="text/javascript"></script>
|
||||||
|
<script src="main.js" type="text/javascript"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Test</h1>
|
<div id="overlay"></div>
|
||||||
|
|
||||||
|
<div class="widget">
|
||||||
|
<div class="title">Bitcoin</div>
|
||||||
|
|
||||||
|
<div class="databox">
|
||||||
|
<img class="icon" src="img/bitpay.png"><div class="data d-bitcoin-bitpay">---</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="databox">
|
||||||
|
<img class="icon" src="img/coinbase.png"><div class="data d-bitcoin-coinbase">---</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="widget">
|
||||||
|
<div class="title">Monero</div>
|
||||||
|
|
||||||
|
<div class="databox">
|
||||||
|
<img class="icon" src="img/shapeshift.png"><div class="data d-monero-shapeshift">---</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="databox">
|
||||||
|
<img class="icon" src="img/xmrto.png"><div class="data d-monero-xmrto">---</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="widget">
|
||||||
|
<div class="title">Weather</div>
|
||||||
|
|
||||||
|
<div class="databox">
|
||||||
|
<img class="icon" src="img/weather.png"><div class="data">Aachen:</div> <div class="data d-weather-aachen">---</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
5
page/jquery-1.12.4.min.js
vendored
Normal file
5
page/jquery-1.12.4.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
21
page/main.js
Normal file
21
page/main.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
$(document).ready(function() {
|
||||||
|
$("#overlay").click(function() {
|
||||||
|
$("body").toggleClass("inverted");
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch();
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
fetch();
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
|
||||||
|
function fetch() {
|
||||||
|
$.get("/api/data", function(data) {
|
||||||
|
for(var widget in data) {
|
||||||
|
for(var id in data[widget]) {
|
||||||
|
$(".d-" + widget + "-" + id).text(data[widget][id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user