From 061892fa04da5dad3c21f51445c5f7b30d4ba6d7 Mon Sep 17 00:00:00 2001 From: Kumi Date: Thu, 8 Aug 2024 14:55:47 +0200 Subject: [PATCH] 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`. --- coingecko.php | 87 ++++++++++++++++++++++++++-------------------- index.php | 8 +++-- src/css/custom.css | 1 + src/js/main.js | 73 ++++++++++++++++++++++++++++++++------ 4 files changed, 118 insertions(+), 51 deletions(-) diff --git a/coingecko.php b/coingecko.php index 8fcebb9..878e9f3 100644 --- a/coingecko.php +++ b/coingecko.php @@ -15,7 +15,22 @@ $currentTime = time(); // Check if five seconds have passed since the last update if (($currentTime - $previousData['time']) >= 5) { // 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 $availableCurrencies = array_diff($availableCurrencies, $excludedCurrencies); @@ -29,44 +44,42 @@ if (($currentTime - $previousData['time']) >= 5) { curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $json = curl_exec($ch); - if (curl_errno($ch)) { - echo 'Curl error: ' . curl_error($ch); - curl_close($ch); - exit; - } - + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); - - // Decode the fetched data - $fetchedData = json_decode($json, true); - $moneroData = $fetchedData['monero']; - - // Initialize new data array - $newData = ['time' => $currentTime]; - - // Update the data for each currency - foreach ($currencies as $currency) { - $currencyLower = strtolower($currency); - if (isset($moneroData[$currencyLower])) { - $newData[$currencyLower] = [ - 'lastValue' => $moneroData[$currencyLower], - 'lastDate' => $currentTime - ]; - } else { - $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)); - - $output = $newData; + + // If the request worked and was not rate-limited + if ($httpCode == 200) { + // Decode the fetched data + $fetchedData = json_decode($json, true); + $moneroData = $fetchedData['monero']; + + // Initialize new data array + $newData = ['time' => $currentTime]; + + // Update the data for each currency + foreach ($currencies as $currency) { + $currencyLower = strtolower($currency); + if (isset($moneroData[$currencyLower])) { + $newData[$currencyLower] = [ + 'lastValue' => $moneroData[$currencyLower], + 'lastDate' => $currentTime + ]; + } else { + $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)); + + $output = $newData; + } } // Output the data header('Content-Type: application/json'); -echo json_encode($newData, JSON_PRETTY_PRINT); \ No newline at end of file +echo json_encode($output, JSON_PRETTY_PRINT); \ No newline at end of file diff --git a/index.php b/index.php index 7f2b76c..144d33c 100644 --- a/index.php +++ b/index.php @@ -59,8 +59,10 @@ $xmr_in_fiat = strtr($xmr_in_fiat, ",", " "); - - + + + + @@ -161,7 +163,7 @@ $xmr_in_fiat = strtr($xmr_in_fiat, ",", " "); diff --git a/src/css/custom.css b/src/css/custom.css index 603af42..597f08d 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -34,6 +34,7 @@ a.fiat-tooltip { table.table { max-width: 472px; margin: auto; + --bs-table-bg: transparent; } .input-group-text { diff --git a/src/js/main.js b/src/js/main.js index 3b1ba1d..eee2701 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -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"; var tooltipTriggerList = [].slice.call( document.querySelectorAll('[data-toggle="tooltip"]') @@ -7,8 +12,54 @@ var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { }); console.log(tooltipList); -import 'bootstrap/dist/css/bootstrap.min.css'; -import '../css/custom.css'; +let lastModifiedField = 'xmr'; + +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() { var content = document.getElementById('xmrInput'); @@ -23,14 +74,14 @@ function copyToClipBoardFiat() { } function fiatConvert(value) { - let fiatAmount = document.getElementById("fiatInput").value; - let xmrValue = document.getElementById("xmrInput"); - let selectBox = document.getElementById("selectBox").value; + let fiatAmount = document.getElementById("fiatInput").value; + let xmrValue = document.getElementById("xmrInput"); + let selectBox = document.getElementById("selectBox").value; - if (exchangeRates[selectBox]) { - let value = fiatAmount / exchangeRates[selectBox]; - xmrValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2); - } + if (exchangeRates[selectBox]) { + let value = fiatAmount / exchangeRates[selectBox]; + xmrValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2); + } } function xmrConvert(value) { @@ -39,8 +90,8 @@ function xmrConvert(value) { let selectBox = document.getElementById("selectBox").value; if (exchangeRates[selectBox]) { - let value = xmrAmount * exchangeRates[selectBox]; - fiatValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2); + let value = xmrAmount * exchangeRates[selectBox]; + fiatValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2); } }