initial working code

This commit is contained in:
Jan Scheiper 2019-07-15 23:31:05 +02:00
parent 60c5d4888c
commit 46368c841a
16 changed files with 295 additions and 4 deletions

View File

@ -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
View 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
View File

@ -0,0 +1,5 @@
module.exports = {
bitcoin: require('./bitcoinData'),
monero: require('./xmrData'),
weather: require('./weatherData'),
};

40
lib/weatherData.js Normal file
View 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
View 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
View File

@ -249,6 +249,11 @@
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
"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": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",

View File

@ -11,6 +11,7 @@
"dependencies": {
"axios": "^0.19.0",
"dotenv": "^8.0.0",
"express": "^4.17.1"
"express": "^4.17.1",
"loglevel": "^1.6.3"
}
}

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
page/img/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
page/img/shapeshift.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
page/img/weather.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
page/img/xmrto.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,20 +1,109 @@
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<title>Widget Display</title>
<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="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>
body {
color: white;
background-color: black;
margin: 0px;
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>
<script src="jquery-1.12.4.min.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
</head>
<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>
</html>

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
View 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]);
}
}
});
}