mirror of
https://github.com/rottenwheel/moner.ooo.git
synced 2024-12-21 15:50:25 +00:00
feat: improve cache, refactor code, add api key support
This commit is contained in:
parent
01365b4c51
commit
2025ef0a91
4 changed files with 118 additions and 54 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -7,6 +7,10 @@
|
|||
# Coingecko export data
|
||||
/coingecko.json
|
||||
/coingecko-original.json
|
||||
/coingecko-currencies.json
|
||||
|
||||
# Secret files
|
||||
/secrets.php
|
||||
|
||||
# Compiled files
|
||||
/js/
|
||||
|
|
12
README.md
12
README.md
|
@ -117,6 +117,18 @@ return [
|
|||
];
|
||||
```
|
||||
|
||||
Create a `secrets.php` file in the root directory to store CoinGecko API keys. Example:
|
||||
|
||||
```php
|
||||
<?php
|
||||
return [
|
||||
'coingecko_api_key' => 'CG-xxxx',
|
||||
'coingecko_key_is_demo' => true,
|
||||
];
|
||||
```
|
||||
|
||||
**Note:** The `secrets.dist.php` file should not be accessible from the web server.
|
||||
|
||||
### Fetching Exchange Rates
|
||||
|
||||
Exchange rates are fetched from the CoinGecko API. The `coingecko.php` file handles the API requests and attempts to update exchange rates every 5 seconds. Due to the rate limits of the CoinGecko API, actual update intervals may vary and are closer to 60 seconds.
|
||||
|
|
151
coingecko.php
151
coingecko.php
|
@ -6,78 +6,121 @@ date_default_timezone_set('Europe/Berlin');
|
|||
// Define currencies that should *not* be included in the list
|
||||
$excludedCurrencies = ['bits', 'sats'];
|
||||
|
||||
// Fetch the previously stored data
|
||||
$previousData = json_decode(file_get_contents("coingecko.json"), true);
|
||||
$output = $previousData;
|
||||
// Fetch JSON data from a file and decode it
|
||||
function fetchJson($filename) {
|
||||
return json_decode(file_get_contents($filename), true);
|
||||
}
|
||||
|
||||
// Make an API request and return the JSON response
|
||||
function makeApiRequest($url) {
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$json = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($httpCode == 200) {
|
||||
return json_decode($json, true);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get CoinGecko key URL parameter
|
||||
function getCoinGeckoApiUrl($path, $params = []) {
|
||||
$secrets = require_once 'secrets.php';
|
||||
$key = $secrets['coingecko_api_key'];
|
||||
$demo = $secrets['coingecko_key_is_demo'];
|
||||
|
||||
$paramName = $demo ? 'x_cg_demo_api_key' : 'x_cg_pro_api_key';
|
||||
$baseUrl = $demo ? "https://api.coingecko.com/api/v3/" : "https://pro-api.coingecko.com/api/v3/";
|
||||
|
||||
$params[$paramName] = $key;
|
||||
$url = $baseUrl . $path;
|
||||
|
||||
if (!empty($params)) {
|
||||
$url .= '?' . http_build_query($params);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
$currentTime = time();
|
||||
|
||||
// Check if five seconds have passed since the last update
|
||||
if (($currentTime - $previousData['time']) >= 5) {
|
||||
// Fetch the available currencies from CoinGecko API
|
||||
$availableCurrenciesApi = "https://api.coingecko.com/api/v3/simple/supported_vs_currencies";
|
||||
// Fetch list of available currencies from CoinGecko API
|
||||
// Available currencies are cached for 24 hours
|
||||
function fetchAvailableCurrencies() {
|
||||
$cacheFile = 'coingecko-currencies.json';
|
||||
$cacheTime = 86400;
|
||||
|
||||
$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)]);
|
||||
// Return cached data if it exists and is less than 24 hours old
|
||||
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheTime)) {
|
||||
return fetchJson($cacheFile);
|
||||
}
|
||||
|
||||
$apiUrl = getCoinGeckoApiUrl('simple/supported_vs_currencies');
|
||||
$data = makeApiRequest($apiUrl);
|
||||
|
||||
if ($data) {
|
||||
file_put_contents($cacheFile, json_encode($data, JSON_PRETTY_PRINT));
|
||||
return $data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fetch currency data from CoinGecko API
|
||||
function fetchCurrencyData($currencies) {
|
||||
$apiUrl = getCoinGeckoApiUrl('simple/price', ['ids' => 'monero', 'vs_currencies' => implode(',', array_map('strtolower', $currencies))]);
|
||||
return makeApiRequest($apiUrl);
|
||||
}
|
||||
|
||||
$currencyFile = 'coingecko.json';
|
||||
$originalFile = 'coingecko-original.json';
|
||||
|
||||
// Function to process currency data
|
||||
function processCurrencyData($availableCurrencies, $previousData, $currentTime, $excludedCurrencies) {
|
||||
// Remove excluded currencies
|
||||
$availableCurrencies = array_diff($availableCurrencies, $excludedCurrencies);
|
||||
|
||||
$currencies = array_map('strtoupper', $availableCurrencies);
|
||||
|
||||
// Fetch the latest data from CoinGecko API
|
||||
$apiUrl = 'https://api.coingecko.com/api/v3/simple/price?ids=monero&vs_currencies=' . implode('%2C', array_map('strtolower', $currencies)) . '&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true&include_last_updated_at=true';
|
||||
$fetchedData = fetchCurrencyData($currencies);
|
||||
|
||||
$ch = curl_init($apiUrl);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$json = curl_exec($ch);
|
||||
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
// If the request worked and was not rate-limited
|
||||
if ($httpCode == 200) {
|
||||
// Decode the fetched data
|
||||
$fetchedData = json_decode($json, true);
|
||||
if ($fetchedData) {
|
||||
$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
|
||||
];
|
||||
}
|
||||
$newData[$currencyLower] = [
|
||||
'lastValue' => $moneroData[$currencyLower] ?? $previousData[$currencyLower]['lastValue'] ?? null,
|
||||
'lastDate' => $currentTime
|
||||
];
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
return $newData;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$previousData = fetchJson($currencyFile);
|
||||
$output = $previousData;
|
||||
|
||||
// Check if five seconds have passed since the last update
|
||||
if (($currentTime - $previousData['time']) >= 5) {
|
||||
$availableCurrencies = fetchAvailableCurrencies();
|
||||
if ($availableCurrencies !== null) {
|
||||
$output = processCurrencyData($availableCurrencies, $previousData, $currentTime, $excludedCurrencies);
|
||||
|
||||
// Save the data if the API call was successful
|
||||
if ($output !== null) {
|
||||
file_put_contents($currencyFile, json_encode($output, JSON_PRETTY_PRINT));
|
||||
file_put_contents($originalFile, json_encode($output, JSON_PRETTY_PRINT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output the data
|
||||
|
|
5
secrets.dist.php
Normal file
5
secrets.dist.php
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
return [
|
||||
'coingecko_api_key' => 'CG-xxxx',
|
||||
'coingecko_key_is_demo' => true,
|
||||
];
|
Loading…
Reference in a new issue