feat: improve API error handling & add exchange rate updates

- Switched to using cURL for fetching data from CoinGecko API, with added error handling for failed requests. This reduces the chances of runtime errors and ensures fallback to previous data.
- Implemented periodic updates to exchange rates every 5 seconds in `main.js` to keep the rates current.
- Added OpenGraph meta tags on `index.php` for better social media integration.
- Minor CSS adjustments for better table rendering.
- Moved `import` statements for Bootstrap CSS and JS to the top in `main.js`.
This commit is contained in:
Kumi 2024-08-08 14:55:47 +02:00
parent 91dd6df3dd
commit 061892fa04
Signed by: kumi
GPG key ID: ECBCC9082395383F
4 changed files with 118 additions and 51 deletions

View file

@ -15,7 +15,22 @@ $currentTime = time();
// Check if five seconds have passed since the last update // Check if five seconds have passed since the last update
if (($currentTime - $previousData['time']) >= 5) { if (($currentTime - $previousData['time']) >= 5) {
// Fetch the available currencies from CoinGecko API // Fetch the available currencies from CoinGecko API
$availableCurrencies = json_decode(file_get_contents("https://api.coingecko.com/api/v3/simple/supported_vs_currencies"), true); $availableCurrenciesApi = "https://api.coingecko.com/api/v3/simple/supported_vs_currencies";
$currenciesCh = curl_init($availableCurrenciesApi);
curl_setopt($currenciesCh, CURLOPT_RETURNTRANSFER, true);
$availableCurrenciesJson = curl_exec($currenciesCh);
$currenciesHttpCode = curl_getinfo($currenciesCh, CURLINFO_HTTP_CODE);
curl_close($currenciesCh);
if ($currenciesHttpCode == 200) {
$availableCurrencies = json_decode($availableCurrenciesJson, true);
} else {
$availableCurrencies = array_keys($previousData);
unset($availableCurrencies[array_search('time', $availableCurrencies)]);
}
// Remove excluded currencies // Remove excluded currencies
$availableCurrencies = array_diff($availableCurrencies, $excludedCurrencies); $availableCurrencies = array_diff($availableCurrencies, $excludedCurrencies);
@ -29,44 +44,42 @@ if (($currentTime - $previousData['time']) >= 5) {
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$json = curl_exec($ch); $json = curl_exec($ch);
if (curl_errno($ch)) { $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo 'Curl error: ' . curl_error($ch);
curl_close($ch);
exit;
}
curl_close($ch); curl_close($ch);
// Decode the fetched data // If the request worked and was not rate-limited
$fetchedData = json_decode($json, true); if ($httpCode == 200) {
$moneroData = $fetchedData['monero']; // Decode the fetched data
$fetchedData = json_decode($json, true);
// Initialize new data array $moneroData = $fetchedData['monero'];
$newData = ['time' => $currentTime];
// Initialize new data array
// Update the data for each currency $newData = ['time' => $currentTime];
foreach ($currencies as $currency) {
$currencyLower = strtolower($currency); // Update the data for each currency
if (isset($moneroData[$currencyLower])) { foreach ($currencies as $currency) {
$newData[$currencyLower] = [ $currencyLower = strtolower($currency);
'lastValue' => $moneroData[$currencyLower], if (isset($moneroData[$currencyLower])) {
'lastDate' => $currentTime $newData[$currencyLower] = [
]; 'lastValue' => $moneroData[$currencyLower],
} else { 'lastDate' => $currentTime
$newData[$currencyLower] = [ ];
'lastValue' => $previousData[$currencyLower]['lastValue'] ?? null, } else {
'lastDate' => $previousData[$currencyLower]['lastDate'] ?? null $newData[$currencyLower] = [
]; 'lastValue' => $previousData[$currencyLower]['lastValue'] ?? null,
} 'lastDate' => $previousData[$currencyLower]['lastDate'] ?? null
} ];
}
// Save the new data to JSON files }
file_put_contents("coingecko.json", json_encode($newData, JSON_PRETTY_PRINT));
file_put_contents("coingecko-original.json", json_encode($moneroData, JSON_PRETTY_PRINT)); // Save the new data to JSON files
file_put_contents("coingecko.json", json_encode($newData, JSON_PRETTY_PRINT));
$output = $newData; file_put_contents("coingecko-original.json", json_encode($moneroData, JSON_PRETTY_PRINT));
$output = $newData;
}
} }
// Output the data // Output the data
header('Content-Type: application/json'); header('Content-Type: application/json');
echo json_encode($newData, JSON_PRETTY_PRINT); echo json_encode($output, JSON_PRETTY_PRINT);

View file

@ -59,8 +59,10 @@ $xmr_in_fiat = strtr($xmr_in_fiat, ",", " ");
<meta name="description" lang="<?php echo $lang_meta; ?>" content="<?php echo $meta_description; ?>" /> <meta name="description" lang="<?php echo $lang_meta; ?>" content="<?php echo $meta_description; ?>" />
<meta name="keywords" lang="<?php echo $lang_meta; ?>" content="<?php echo $meta_keywords; ?>" /> <meta name="keywords" lang="<?php echo $lang_meta; ?>" content="<?php echo $meta_keywords; ?>" />
<meta property="og:title" content="<?php echo $page_title; ?>" />
<!-- TODO: Add corresponding OpenGraph tags --> <meta property="og:description" content="<?php echo $meta_description; ?>" />
<meta property="og:image" content="img/mstile-310x150.png" />
<meta property="og:type" content="website" />
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="img/apple-touch-icon-57x57.png" /> <link rel="apple-touch-icon-precomposed" sizes="57x57" href="img/apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/apple-touch-icon-114x114.png" /> <link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/apple-touch-icon-114x114.png" />
@ -161,7 +163,7 @@ $xmr_in_fiat = strtr($xmr_in_fiat, ",", " ");
</div> </div>
<script> <script>
const exchangeRates = <?php echo json_encode($exchangeRates); ?>; var exchangeRates = <?php echo json_encode($exchangeRates); ?>;
</script> </script>
<script src="js/main.js"></script> <script src="js/main.js"></script>

View file

@ -34,6 +34,7 @@ a.fiat-tooltip {
table.table { table.table {
max-width: 472px; max-width: 472px;
margin: auto; margin: auto;
--bs-table-bg: transparent;
} }
.input-group-text { .input-group-text {

View file

@ -1,3 +1,8 @@
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min';
import '../css/custom.css';
import Tooltip from "bootstrap/js/dist/tooltip"; import Tooltip from "bootstrap/js/dist/tooltip";
var tooltipTriggerList = [].slice.call( var tooltipTriggerList = [].slice.call(
document.querySelectorAll('[data-toggle="tooltip"]') document.querySelectorAll('[data-toggle="tooltip"]')
@ -7,8 +12,54 @@ var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
}); });
console.log(tooltipList); console.log(tooltipList);
import 'bootstrap/dist/css/bootstrap.min.css'; let lastModifiedField = 'xmr';
import '../css/custom.css';
document.addEventListener('DOMContentLoaded', function () {
// Add event listeners to track the last modified input field
document.getElementById("xmrInput").addEventListener('input', function () {
lastModifiedField = 'xmr';
});
document.getElementById("fiatInput").addEventListener('input', function () {
lastModifiedField = 'fiat';
});
// Fetch updated exchange rates every 5 seconds
setInterval(fetchUpdatedExchangeRates, 5000);
});
function fetchUpdatedExchangeRates() {
fetch('/coingecko.php')
.then(response => response.json())
.then(data => {
// Update the exchangeRates object with the new values
for (const [currency, value] of Object.entries(data)) {
exchangeRates[currency.toUpperCase()] = value.lastValue;
}
updateTimeElement(data.time);
// Re-execute the appropriate conversion function
if (lastModifiedField === 'xmr') {
xmrConvert();
} else {
fiatConvert();
}
})
.catch(error => console.error('Error fetching exchange rates:', error));
}
function updateTimeElement(unixTimestamp) {
const date = new Date(unixTimestamp * 1000);
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const formattedTime = `${hours}:${minutes}:${seconds}`;
const u = document.querySelector('u');
u.textContent = formattedTime;
u.parentElement.innerHTML = u.parentElement.innerHTML.replace('Europe/Berlin', Intl.DateTimeFormat().resolvedOptions().timeZone);
}
function copyToClipBoardXMR() { function copyToClipBoardXMR() {
var content = document.getElementById('xmrInput'); var content = document.getElementById('xmrInput');
@ -23,14 +74,14 @@ function copyToClipBoardFiat() {
} }
function fiatConvert(value) { function fiatConvert(value) {
let fiatAmount = document.getElementById("fiatInput").value; let fiatAmount = document.getElementById("fiatInput").value;
let xmrValue = document.getElementById("xmrInput"); let xmrValue = document.getElementById("xmrInput");
let selectBox = document.getElementById("selectBox").value; let selectBox = document.getElementById("selectBox").value;
if (exchangeRates[selectBox]) { if (exchangeRates[selectBox]) {
let value = fiatAmount / exchangeRates[selectBox]; let value = fiatAmount / exchangeRates[selectBox];
xmrValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2); xmrValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2);
} }
} }
function xmrConvert(value) { function xmrConvert(value) {
@ -39,8 +90,8 @@ function xmrConvert(value) {
let selectBox = document.getElementById("selectBox").value; let selectBox = document.getElementById("selectBox").value;
if (exchangeRates[selectBox]) { if (exchangeRates[selectBox]) {
let value = xmrAmount * exchangeRates[selectBox]; let value = xmrAmount * exchangeRates[selectBox];
fiatValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2); fiatValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2);
} }
} }