mirror of
https://github.com/Redume/Kekkai.git
synced 2025-03-12 11:34:38 +03:00
Merge pull request #6 from Redume/chore/migrating-to-hjson
Some checks failed
Create and publish a Docker image / build-and-push-chart (push) Has been cancelled
Create and publish a Docker image / detect what files changed (push) Has been cancelled
Create and publish a Docker image / build-and-push-server (push) Has been cancelled
Create and publish a Docker image / build-and-push-CR (push) Has been cancelled
Create and publish a Docker image / build-and-push-web (push) Has been cancelled
Some checks failed
Create and publish a Docker image / build-and-push-chart (push) Has been cancelled
Create and publish a Docker image / detect what files changed (push) Has been cancelled
Create and publish a Docker image / build-and-push-server (push) Has been cancelled
Create and publish a Docker image / build-and-push-CR (push) Has been cancelled
Create and publish a Docker image / build-and-push-web (push) Has been cancelled
Chore/migrating to hjson
This commit is contained in:
commit
5387a91a2f
18 changed files with 278 additions and 201 deletions
|
@ -17,7 +17,8 @@ module.exports = {
|
||||||
'error', {
|
'error', {
|
||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
parser: "flow",
|
parser: "flow",
|
||||||
tabWidth: 4
|
tabWidth: 4,
|
||||||
|
endOfLine: 'lf'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,12 +1,20 @@
|
||||||
|
# IDE & text redactors files
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# Project
|
||||||
CertSSL/
|
CertSSL/
|
||||||
charts/
|
charts/
|
||||||
|
|
||||||
|
# Depends
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
# Docker compose
|
||||||
postgres-data/
|
postgres-data/
|
||||||
|
|
||||||
config.yaml
|
# Config
|
||||||
|
config.hjson
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
# Other
|
||||||
.DS_Store
|
.DS_Store
|
|
@ -9,7 +9,7 @@ import asyncpg
|
||||||
|
|
||||||
from utils.load_config import load_config
|
from utils.load_config import load_config
|
||||||
|
|
||||||
config = load_config('config.yaml')
|
config = load_config('config.hjson')
|
||||||
|
|
||||||
async def create_pool() -> asyncpg.pool.Pool:
|
async def create_pool() -> asyncpg.pool.Pool:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -16,7 +16,7 @@ from routes import get_chart, get_chart_period
|
||||||
from utils.load_config import load_config
|
from utils.load_config import load_config
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
config = load_config('config.yaml')
|
config = load_config('config.hjson')
|
||||||
|
|
||||||
if not os.path.exists('../charts'):
|
if not os.path.exists('../charts'):
|
||||||
os.mkdir('../charts')
|
os.mkdir('../charts')
|
||||||
|
@ -35,10 +35,10 @@ if __name__ == '__main__':
|
||||||
port=3030,
|
port=3030,
|
||||||
ssl_keyfile=
|
ssl_keyfile=
|
||||||
config['server']['ssl']['private_key']
|
config['server']['ssl']['private_key']
|
||||||
if config['server']['ssl']['work']
|
if config['server']['ssl']['enabled']
|
||||||
else None,
|
else None,
|
||||||
ssl_certfile=
|
ssl_certfile=
|
||||||
config['server']['ssl']['cert']
|
config['server']['ssl']['cert']
|
||||||
if config['server']['ssl']['work']
|
if config['server']['ssl']['enabled']
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from user_agents import parse as ua_parse
|
||||||
|
|
||||||
from utils.load_config import load_config
|
from utils.load_config import load_config
|
||||||
|
|
||||||
config = load_config('config.yaml')
|
config = load_config('config.hjson')
|
||||||
|
|
||||||
# pylint: disable=too-few-public-methods
|
# pylint: disable=too-few-public-methods
|
||||||
class PlausibleAnalytics:
|
class PlausibleAnalytics:
|
||||||
|
@ -23,7 +23,7 @@ class PlausibleAnalytics:
|
||||||
async def __call__(self, request, call_next):
|
async def __call__(self, request, call_next):
|
||||||
response = await call_next(request)
|
response = await call_next(request)
|
||||||
|
|
||||||
if HTTPStatus(response.status_code).is_client_error or not config['analytics']['work']:
|
if HTTPStatus(response.status_code).is_client_error or not config['analytics']['enabled']:
|
||||||
return response
|
return response
|
||||||
|
|
||||||
user_agent = request.headers.get('user-agent', 'unknown')
|
user_agent = request.headers.get('user-agent', 'unknown')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
matplotlib~=3.9.1
|
matplotlib~=3.9.1
|
||||||
PyYAML~=6.0.1
|
hjson~=3.1.0
|
||||||
uvicorn~=0.29.0
|
uvicorn~=0.29.0
|
||||||
fastapi[standard]~=0.115.2
|
fastapi[standard]~=0.115.2
|
||||||
starlette~=0.40.0
|
starlette~=0.40.0
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
# pylint: disable=R0801
|
|
||||||
"""
|
"""
|
||||||
This module provides a function for loading a YAML configuration file.
|
Parsing and converting HJSON config to JSON
|
||||||
The function reads the file content and returns it as a Python dictionary.
|
|
||||||
"""
|
"""
|
||||||
import yaml
|
import hjson
|
||||||
|
import json
|
||||||
|
|
||||||
def load_config(file_path: str) -> dict:
|
def load_config(file_path: str) -> dict:
|
||||||
"""
|
"""
|
||||||
Loads a YAML configuration file and returns its contents as a dictionary.
|
Load an HJSON file, convert it to a JSON string with indentation,
|
||||||
|
and return it.
|
||||||
|
|
||||||
This function opens the specified YAML file, parses its content, and
|
params: file_path (str): The path to the HJSON file.
|
||||||
returns it in dictionary format, making it accessible for use in
|
|
||||||
the application.
|
|
||||||
|
|
||||||
:param file_path: The path to the YAML configuration file to be loaded.
|
returns str: The JSON string formatted with indentation.
|
||||||
:return: A dictionary containing the parsed content of the YAML file.
|
|
||||||
"""
|
"""
|
||||||
with open(file_path, 'r', encoding='utf-8') as file:
|
with open(file_path, 'r', encoding='utf-8') as file:
|
||||||
return yaml.safe_load(file)
|
hjson_data = hjson.load(file)
|
||||||
|
return json.loads(
|
||||||
|
json.dumps(hjson_data, indent=4)
|
||||||
|
)
|
||||||
|
|
|
@ -13,7 +13,7 @@ async function validateSchedule(schedule) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initialize() {
|
async function initialize() {
|
||||||
await require('../shared/database/src/create_table')();
|
//await require('../shared/database/src/create_table')();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runTasks() {
|
async function runTasks() {
|
||||||
|
@ -21,6 +21,7 @@ async function runTasks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
console.log(config['currency']['collecting']['schedule'])
|
||||||
await initialize();
|
await initialize();
|
||||||
await validateSchedule(config['currency']['collecting']['schedule']);
|
await validateSchedule(config['currency']['collecting']['schedule']);
|
||||||
|
|
||||||
|
@ -32,8 +33,6 @@ async function main() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch((err) => {
|
main();
|
||||||
logger.error('Error in main execution:', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = { main };
|
module.exports = { main };
|
||||||
|
|
57
config.example.hjson
Normal file
57
config.example.hjson
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
database:
|
||||||
|
{
|
||||||
|
user: DATABASE_USERNAME
|
||||||
|
password: DATABASE_PASSWORD
|
||||||
|
host: localhost
|
||||||
|
name: kekkai
|
||||||
|
port: 5432
|
||||||
|
}
|
||||||
|
server:
|
||||||
|
{
|
||||||
|
host: 0.0.0.0
|
||||||
|
ssl:
|
||||||
|
{
|
||||||
|
private_key: /CertSSL/privkey.pem
|
||||||
|
cert: /CertSSL/fullchain.pem
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
log:
|
||||||
|
{
|
||||||
|
level: info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
analytics:
|
||||||
|
{
|
||||||
|
plausible_domain: plausible.io
|
||||||
|
plausible_token: TOKEN
|
||||||
|
plausiblee_api: https://plausible.io//api/event/
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
currency:
|
||||||
|
{
|
||||||
|
collecting:
|
||||||
|
{
|
||||||
|
fiat: true
|
||||||
|
crypto: false
|
||||||
|
schedule: 30 8 * * *
|
||||||
|
crypto_apikey: TOKEN
|
||||||
|
}
|
||||||
|
fiat:
|
||||||
|
[
|
||||||
|
USD
|
||||||
|
RUB
|
||||||
|
EUR
|
||||||
|
UAH
|
||||||
|
TRY
|
||||||
|
KZT
|
||||||
|
]
|
||||||
|
crypto:
|
||||||
|
[
|
||||||
|
ETH
|
||||||
|
TON
|
||||||
|
USDT
|
||||||
|
BTC
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +0,0 @@
|
||||||
# For more information, see the documentation
|
|
||||||
# https://kekkai-docs.redume.su/
|
|
||||||
|
|
||||||
database: # Postgresql database data, for connection
|
|
||||||
user: 'DATABASE_USERNAME'
|
|
||||||
password: 'DATABASE_PASSWORD'
|
|
||||||
host: 'DATABASE_HOST'
|
|
||||||
name: 'DATABASE_NAME'
|
|
||||||
port: 5432
|
|
||||||
server:
|
|
||||||
host: '0.0.0.0'
|
|
||||||
ssl:
|
|
||||||
private_key: '/CertSSL/privkey.pem' # The path to the private SSL key file (String)
|
|
||||||
cert: '/CertSSL/fullchain.pem' # The path to the SSL certificate (String)
|
|
||||||
work: false # Enable or disable SSL support [Boolean]
|
|
||||||
log:
|
|
||||||
print: true # Enable or disable logging [Boolean]
|
|
||||||
level: 'info' # Log level (Fatal/Error/Warn/Log/Debug) [String]
|
|
||||||
analytics:
|
|
||||||
plausible_api: 'https://plausible.io/api/event/'
|
|
||||||
plausible_domain: 'PLAUSIBLE_DOMAIN'
|
|
||||||
plausible_token: 'PLAUSIBLE_TOKEN'
|
|
||||||
work: false
|
|
||||||
currency:
|
|
||||||
chart:
|
|
||||||
save: false # Enable or disable saving graphs to an image (Boolean)
|
|
||||||
collecting:
|
|
||||||
fiat: true # Turn off or turn on the collection of the fiat currency rate [Boolean]
|
|
||||||
crypto: false
|
|
||||||
schedule: '30 8 * * *' # Currency collection schedule in crontab format [String]
|
|
||||||
crypto_apikey: 'APIKEY'
|
|
||||||
fiat: # List of fiat currency to save the exchange rate [Array]
|
|
||||||
- USD
|
|
||||||
- RUB
|
|
||||||
- EUR
|
|
||||||
- UAH
|
|
||||||
- TRY
|
|
||||||
- KZT
|
|
||||||
crypto:
|
|
||||||
- ETH
|
|
||||||
- TON
|
|
||||||
- USDT
|
|
|
@ -24,7 +24,7 @@ services:
|
||||||
- '3000:3000'
|
- '3000:3000'
|
||||||
volumes:
|
volumes:
|
||||||
- './CertSSL:/CertSSL'
|
- './CertSSL:/CertSSL'
|
||||||
- './config.yaml:/config.yaml'
|
- './config.hjson:/config.hjson'
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ services:
|
||||||
- '3030:3030'
|
- '3030:3030'
|
||||||
volumes:
|
volumes:
|
||||||
- './CertSSL:/CertSSL'
|
- './CertSSL:/CertSSL'
|
||||||
- './config.yaml:/config.yaml'
|
- './config.hjson:/config.hjson'
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
@ -50,7 +50,7 @@ services:
|
||||||
- '3050:3050'
|
- '3050:3050'
|
||||||
volumes:
|
volumes:
|
||||||
- './CertSSL:/CertSSL'
|
- './CertSSL:/CertSSL'
|
||||||
- './config.yaml:/config.yaml'
|
- './config.hjson:/config.hjson'
|
||||||
|
|
||||||
docs:
|
docs:
|
||||||
build:
|
build:
|
||||||
|
@ -63,7 +63,7 @@ services:
|
||||||
dockerfile: Dockerfile-collect-currency
|
dockerfile: Dockerfile-collect-currency
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- './config.yaml:/config.yaml'
|
- './config.hjson:/config.hjson'
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,8 @@ export default defineConfig({
|
||||||
slug: 'docs/config/config-env'
|
slug: 'docs/config/config-env'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Configure config.yaml',
|
label: 'Configure config.hjson',
|
||||||
slug: 'docs/config/config-yaml'
|
slug: 'docs/config/config-hjson'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Configure Nginx',
|
label: 'Configure Nginx',
|
||||||
|
|
|
@ -1,66 +1,93 @@
|
||||||
---
|
---
|
||||||
title: Configure config.yaml
|
title: Configure config.hjson
|
||||||
---
|
---
|
||||||
|
|
||||||
import { Aside } from '@astrojs/starlight/components';
|
import { Aside } from '@astrojs/starlight/components';
|
||||||
|
|
||||||
Kekkai can be configured using the `config.yaml` file in the working directory.
|
Kekkai can be configured using the `config.hjson` file in the working directory.
|
||||||
`config.example.yaml`.
|
`config.example.hjson`.
|
||||||
|
|
||||||
```yaml
|
```hjson
|
||||||
# For more information, see the documentation
|
# For more information, see the documentation
|
||||||
# https://kekkai-docs.redume.su/
|
# https://kekkai-docs.redume.su/
|
||||||
|
|
||||||
database:
|
{
|
||||||
user: 'DATABASE_USERNAME'
|
database:
|
||||||
password: 'DATABASE_PASSWORD'
|
{
|
||||||
host: 'DATABASE_HOST'
|
user: DATABASE_USERNAME
|
||||||
name: 'DATABASE_NAME'
|
password: DATABASE_PASSWORD
|
||||||
port: 5432
|
host: localhost
|
||||||
server:
|
name: kekkai
|
||||||
host: '0.0.0.0'
|
port: 5432
|
||||||
ssl:
|
}
|
||||||
private_key: '/CertSSL/privkey.pem'
|
server:
|
||||||
cert: '/CertSSL/fullchain.pem'
|
{
|
||||||
work: true
|
host: 0.0.0.0
|
||||||
log:
|
ssl:
|
||||||
print: true
|
{
|
||||||
level: 'info'
|
private_key: /CertSSL/privkey.pem
|
||||||
analytics:
|
cert: /CertSSL/fullchain.pem
|
||||||
plausible_api: 'https://plausible.io/api/event/'
|
enabled: false
|
||||||
plausible_domain: 'PLAUSIBLE_DOMAIN'
|
}
|
||||||
plausible_token: 'PLAUSIBLE_TOKEN'
|
log:
|
||||||
work: false
|
{
|
||||||
currency:
|
level: info
|
||||||
chart:
|
}
|
||||||
save: false
|
}
|
||||||
collecting:
|
analytics:
|
||||||
|
{
|
||||||
|
plausible_domain: plausible.io
|
||||||
|
plausible_token: TOKEN
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
currency:
|
||||||
|
{
|
||||||
|
collecting:
|
||||||
|
{
|
||||||
fiat: true
|
fiat: true
|
||||||
schedule: '30 8 * * *'
|
crypto: false
|
||||||
fiat:
|
schedule: 30 8 * * *
|
||||||
- USD
|
crypto_apikey: TOKEN
|
||||||
- RUB
|
}
|
||||||
- EUR
|
fiat:
|
||||||
- UAH
|
[
|
||||||
- TRY
|
USD
|
||||||
- KZT
|
RUB
|
||||||
|
EUR
|
||||||
|
UAH
|
||||||
|
TRY
|
||||||
|
KZT
|
||||||
|
]
|
||||||
|
crypto:
|
||||||
|
[
|
||||||
|
ETH
|
||||||
|
TON
|
||||||
|
USDT
|
||||||
|
BTC
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
Kekkai is used as a `PostgreSQL` database.
|
Kekkai is used as a `PostgreSQL` database.
|
||||||
|
|
||||||
<Aside>
|
<Aside>
|
||||||
If you installed Kekkai via Docker Compose,
|
If you installed Kekkai via `Docker Compose`,
|
||||||
then install it in the `database.host` value of `postgres`.
|
set it to `database.host` for postgres.
|
||||||
The rest of the data does not have to be filled in.
|
The password (database.password) should be the same as in `.env`,
|
||||||
They need to be filled in `.env`.
|
the rest of the data doesn't need to be filled in,
|
||||||
|
it should be in `.env`
|
||||||
|
|
||||||
What should it look like:
|
What should it look like:
|
||||||
```yaml
|
```hjson
|
||||||
database:
|
database:
|
||||||
...
|
{
|
||||||
host: 'postgres'
|
...
|
||||||
...
|
password: PASSWORD_FROM_ENV
|
||||||
|
host: postgres
|
||||||
|
...
|
||||||
|
}
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
</Aside>
|
</Aside>
|
||||||
|
@ -96,7 +123,7 @@ analytics:
|
||||||
plausible_api: 'https://plausible.io/api/event/'
|
plausible_api: 'https://plausible.io/api/event/'
|
||||||
plausible_domain: 'PLAUSIBLE_DOMAIN'
|
plausible_domain: 'PLAUSIBLE_DOMAIN'
|
||||||
plausible_token: 'PLAUSIBLE_TOKEN'
|
plausible_token: 'PLAUSIBLE_TOKEN'
|
||||||
work: true
|
enabled: true
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -107,7 +134,7 @@ analytics:
|
||||||
You can add the domain [here](https://plausible.io/sites/new?flow=provisioning).
|
You can add the domain [here](https://plausible.io/sites/new?flow=provisioning).
|
||||||
- `plausible_token`: Api token for authorization and sending requests.
|
- `plausible_token`: Api token for authorization and sending requests.
|
||||||
You can create it [here](https://plausible.io/settings/api-keys).
|
You can create it [here](https://plausible.io/settings/api-keys).
|
||||||
- `work`: Enable or disable analytics.
|
- `enabled`: Enable or disable analytics.
|
||||||
|
|
||||||
## Currency
|
## Currency
|
||||||
`DuckDuckGo` (fiat currency collection) and `CoinMarketCap` (cryptocurrency collection)
|
`DuckDuckGo` (fiat currency collection) and `CoinMarketCap` (cryptocurrency collection)
|
||||||
|
@ -116,25 +143,32 @@ are used to collect currency rates.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
...
|
...
|
||||||
currency:
|
currency:
|
||||||
chart:
|
{
|
||||||
save: false # Enable or disable saving graphs to an image (Boolean)
|
collecting:
|
||||||
collecting:
|
{
|
||||||
fiat: true # Turn off or turn on the collection of the fiat currency rate [Boolean]
|
fiat: true
|
||||||
crypto: false
|
crypto: false
|
||||||
schedule: '30 8 * * *' # Currency collection schedule in crontab format [String]
|
schedule: 30 8 * * *
|
||||||
crypto_apikey: 'APIKEY'
|
crypto_apikey: TOKEN
|
||||||
fiat: # List of fiat currency to save the exchange rate [Array]
|
}
|
||||||
- USD
|
fiat:
|
||||||
- RUB
|
[
|
||||||
- EUR
|
USD
|
||||||
- UAH
|
RUB
|
||||||
- TRY
|
EUR
|
||||||
- KZT
|
UAH
|
||||||
crypto:
|
TRY
|
||||||
- ETH
|
KZT
|
||||||
- TON
|
]
|
||||||
- USDT
|
crypto:
|
||||||
|
[
|
||||||
|
ETH
|
||||||
|
TON
|
||||||
|
USDT
|
||||||
|
BTC
|
||||||
|
]
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `currency.chart.save`: Enable or disable saving graphs.
|
- `currency.chart.save`: Enable or disable saving graphs.
|
|
@ -1,26 +1,32 @@
|
||||||
const logger = require("../shared/logger/src/main.js");
|
const logger = require('../shared/logger/src/main.js');
|
||||||
const config = require("../shared/config/src/main.js")();
|
const config = require('../shared/config/src/main.js')();
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require('fs');
|
||||||
const axios = require("axios");
|
const axios = require('axios');
|
||||||
const UAParser = require("ua-parser-js");
|
const UAParser = require('ua-parser-js');
|
||||||
|
|
||||||
require("../shared/database/src/create_table.js")();
|
require('../shared/database/src/create_table.js')();
|
||||||
|
|
||||||
const fastify = require("fastify")({
|
const fastify = require('fastify')({
|
||||||
logger: config["server"]["log"]["print"] ? logger : false,
|
logger: config['server']['log']['level'] !== 'none' ? logger : false,
|
||||||
...(config["server"]["ssl"]["work"]
|
...(config['server']['ssl']['enabled']
|
||||||
? {
|
? {
|
||||||
https: {
|
https: {
|
||||||
key: fs.readFileSync(config["server"]["ssl"]["private_key"], "utf8"),
|
key: fs.readFileSync(
|
||||||
cert: fs.readFileSync(config["server"]["ssl"]["cert"], "utf8"),
|
config['server']['ssl']['private_key'],
|
||||||
},
|
'utf8',
|
||||||
}
|
),
|
||||||
|
cert: fs.readFileSync(
|
||||||
|
config['server']['ssl']['cert'],
|
||||||
|
'utf8',
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
: false),
|
: false),
|
||||||
});
|
});
|
||||||
|
|
||||||
const getRateRoute = require("./routes/getRate.js");
|
const getRateRoute = require('./routes/getRate.js');
|
||||||
const getMetadata = require("./routes/metadata.js");
|
const getMetadata = require('./routes/metadata.js');
|
||||||
|
|
||||||
fastify.register(getRateRoute);
|
fastify.register(getRateRoute);
|
||||||
fastify.register(getMetadata);
|
fastify.register(getMetadata);
|
||||||
|
@ -28,69 +34,81 @@ fastify.register(getMetadata);
|
||||||
fastify.setNotFoundHandler(function (res, reply) {
|
fastify.setNotFoundHandler(function (res, reply) {
|
||||||
return reply.status(404).send({
|
return reply.status(404).send({
|
||||||
status: 404,
|
status: 404,
|
||||||
message: "Page not found!",
|
message: 'Page not found!',
|
||||||
documentation: "https://kekkai-docs.redume.su/",
|
documentation: 'https://kekkai-docs.redume.su/',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
fastify.addHook("onResponse", async (request, reply) => {
|
fastify.addHook('onResponse', async (request, reply) => {
|
||||||
const routePart = request.raw.url.split("/");
|
const routePart = request.raw.url.split('/');
|
||||||
const routePartFiltered = routePart
|
const routePartFiltered = routePart
|
||||||
.filter((part) => part !== "")
|
.filter((part) => part !== '')
|
||||||
.map((part) => `${part}/`);
|
.map((part) => `${part}/`);
|
||||||
|
|
||||||
routePartFiltered.unshift("/");
|
routePartFiltered.unshift('/');
|
||||||
|
|
||||||
if (!config?.["analytics"]["work"] ? config?.["analytics"]["work"] : false)
|
if (!config?.['analytics']['work'] ? config?.['analytics']['work'] : false)
|
||||||
return;
|
return;
|
||||||
else if (!fastify.printRoutes().includes(routePartFiltered.at(-1))) return;
|
else if (!fastify.printRoutes().includes(routePartFiltered.at(-1))) return;
|
||||||
|
|
||||||
const userAgent = request.headers["user-agent"];
|
const userAgent = request.headers['user-agent'];
|
||||||
const parser = new UAParser(userAgent);
|
const parser = new UAParser(userAgent);
|
||||||
const browser = parser.getBrowser();
|
const browser = parser.getBrowser();
|
||||||
const os = parser.getOS();
|
const os = parser.getOS();
|
||||||
|
|
||||||
const formattedOS =
|
const formattedOS =
|
||||||
os.name && os.version ? `${os.name} ${os.version}` : "N/A";
|
os.name && os.version ? `${os.name} ${os.version}` : 'N/A';
|
||||||
const formattedBrowser =
|
const formattedBrowser =
|
||||||
browser.name && browser.version
|
browser.name && browser.version
|
||||||
? `${browser.name} ${browser.version}`
|
? `${browser.name} ${browser.version}`
|
||||||
: "N/A";
|
: 'N/A';
|
||||||
|
|
||||||
const event = {
|
const event = {
|
||||||
domain: config["analytics"]["plausible_domain"],
|
domain: config['analytics']['plausible_domain'],
|
||||||
name: request.routeOptions.url
|
name: request.routeOptions.url
|
||||||
? request.routeOptions.url
|
? request.routeOptions.url
|
||||||
: "404 - Not Found",
|
: '404 - Not Found',
|
||||||
url: request.raw.url,
|
url: request.raw.url,
|
||||||
props: {
|
props: {
|
||||||
method: request.method,
|
method: request.method,
|
||||||
statusCode: reply.statusCode,
|
statusCode: reply.statusCode,
|
||||||
browser: formattedBrowser,
|
browser: formattedBrowser,
|
||||||
os: formattedOS,
|
os: formattedOS,
|
||||||
source: request.headers["referer"]
|
source: request.headers['referer']
|
||||||
? request.headers["referer"]
|
? request.headers['referer']
|
||||||
: "direct",
|
: 'direct',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await axios.post(config["analytics"]["plausible_api"], event, {
|
<<<<<<< HEAD
|
||||||
|
await axios.post(
|
||||||
|
`https://${config['analytics']['plausible_domain']}/api/event/`,
|
||||||
|
event,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${config['analytics']['plausible_token']}`,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'User-Agent': userAgent,
|
||||||
|
},
|
||||||
|
=======
|
||||||
|
await axios.post(config['analytics']['plausible_api'], event, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${config["analytics"]["plausible_token"]}`,
|
Authorization: `Bearer ${config['analytics']['plausible_token']}`,
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
"User-Agent": userAgent,
|
'User-Agent': userAgent,
|
||||||
|
>>>>>>> parent of da7134f (chore(server): Changed the name of the keys. Made it easier to change the domain)
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
fastify.log.error("Error sending event to Plausible:", error.message);
|
fastify.log.error('Error sending event to Plausible:', error.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fastify.listen(
|
fastify.listen(
|
||||||
{
|
{
|
||||||
port: 3000,
|
port: 3000,
|
||||||
host: config["server"]["host"] ? config["server"]["host"] : "localhost",
|
host: config['server']['host'] ? config['server']['host'] : 'localhost',
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
17
shared/config/package-lock.json
generated
17
shared/config/package-lock.json
generated
|
@ -9,19 +9,16 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yaml": "^2.5.0"
|
"hjson": "^3.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/yaml": {
|
"node_modules/hjson": {
|
||||||
"version": "2.5.0",
|
"version": "3.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/hjson/-/hjson-3.2.2.tgz",
|
||||||
"integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
|
"integrity": "sha512-MkUeB0cTIlppeSsndgESkfFD21T2nXPRaBStLtf3cAYA2bVEFdXlodZB0TukwZiobPD1Ksax5DK4RTZeaXCI3Q==",
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"yaml": "bin.mjs"
|
"hjson": "bin/hjson"
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,6 @@
|
||||||
"homepage": "https://github.com/Redume/Kekkai#readme",
|
"homepage": "https://github.com/Redume/Kekkai#readme",
|
||||||
"description": "Config management service",
|
"description": "Config management service",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yaml": "^2.5.0"
|
"hjson": "^3.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const yaml = require('yaml');
|
const hjson = require('hjson');
|
||||||
|
|
||||||
const config = () => {
|
const config = () => {
|
||||||
if (!fs.existsSync('../config.yaml')) return;
|
if (!fs.existsSync('../config.hjson')) throw new Error('Config not found');
|
||||||
|
|
||||||
return yaml.parse(fs.readFileSync('../config.yaml', 'utf-8'));
|
return hjson.parse(fs.readFileSync('../config.hjson', 'utf-8'));
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
|
33
web/main.js
33
web/main.js
|
@ -1,18 +1,24 @@
|
||||||
const logger = require("../shared/logger");
|
const logger = require('../shared/logger');
|
||||||
const config = require("../shared/config/src/main.js")();
|
const config = require('../shared/config/src/main.js')();
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require('fs');
|
||||||
const path = require("node:path");
|
const path = require('node:path');
|
||||||
|
|
||||||
const fastify = require("fastify")({
|
const fastify = require('fastify')({
|
||||||
logger: config["server"]["log"]["print"] ? logger : false,
|
logger: config['server']['log']['level'] !== 'none' ? logger : false,
|
||||||
...(config["server"]["ssl"]["work"]
|
...(config['server']['ssl']['enabled']
|
||||||
? {
|
? {
|
||||||
https: {
|
https: {
|
||||||
key: fs.readFileSync(config["server"]["ssl"]["private_key"], "utf8"),
|
key: fs.readFileSync(
|
||||||
cert: fs.readFileSync(config["server"]["ssl"]["cert"], "utf8"),
|
config['server']['ssl']['private_key'],
|
||||||
},
|
'utf8',
|
||||||
}
|
),
|
||||||
|
cert: fs.readFileSync(
|
||||||
|
config['server']['ssl']['cert'],
|
||||||
|
'utf8',
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
: false),
|
: false),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,11 +29,10 @@ fastify.register(require('@fastify/static'), {
|
||||||
|
|
||||||
fastify.register(require('./routes/home.js'));
|
fastify.register(require('./routes/home.js'));
|
||||||
|
|
||||||
|
|
||||||
fastify.listen(
|
fastify.listen(
|
||||||
{
|
{
|
||||||
port: 3050,
|
port: 3050,
|
||||||
host: config["server"]["host"] ? config["server"]["host"] : "localhost",
|
host: config['server']['host'] ? config['server']['host'] : 'localhost',
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue