adding redis, tasks, api calls

This commit is contained in:
José Conde 2023-01-06 19:12:43 +01:00
parent 8b557d3c76
commit 34ed6355c9
12 changed files with 4147 additions and 15 deletions

View File

@ -1,6 +1,7 @@
const moment = require('moment');
const { getUserFromReferenceTable } = require('../db/mongo/mongoPilots');
const { getSessions } = require('../db/mongo/mongoSessions');
const { RedisClient } = require('../db/redis/redis');
const { getHistoricalSessions } = require('../requests/ivao/session');
async function getTodaySessionsFromIvao(callsign, incompletes) {
@ -19,10 +20,21 @@ async function getTodaySessionsFromIvao(callsign, incompletes) {
}
async function checkUsername(user, key) {
async function checkUsername(user, key, usersList) {
const u = {...user };
if (!u.name) {
const ref = await getUserFromReferenceTable(key);
const ref1 = await getUserFromReferenceTable(key) || {};
const ref2 = usersList.find(d => key === d.vid) || {};
let ref;
if (ref2.name) {
ref = ref2;
if (!ref1.name) {
// TODO: update mongo
}
} else if (ref1.name) {
ref = ref1
}
if (ref) {
u.name = ref.name;
} else {
@ -32,12 +44,19 @@ async function checkUsername(user, key) {
return u;
}
async function getWhitelist() {
const redisUsers = await RedisClient.getPair('users_whitelist');
return redisUsers.sort((a, b) => b.flightTime - a.flightTime);
}
async function getList(callsign) {
const from = moment().utc().startOf('month');
const to = moment().subtract(1, 'day').utc().endOf('day');
const todayData = await getTodaySessionsFromIvao(callsign);
const monthData = await getSessions(from, to);
const allData = [...todayData, ...monthData];
const redisUsers = await RedisClient.getPair('users');
const totalsByUserId = allData.reduce((acc, d) => {
const userId = d.userId;
@ -72,7 +91,7 @@ async function getList(callsign) {
const array = [];
for (const key in totalsByUserId) {
if (Object.hasOwnProperty.call(totalsByUserId, key)) {
const user = await checkUsername(totalsByUserId[key], key);
const user = await checkUsername(totalsByUserId[key], key, redisUsers);
user.vid = key;
array.push(user);
}
@ -83,4 +102,5 @@ async function getList(callsign) {
module.exports = {
getList,
getWhitelist,
};

View File

@ -72,4 +72,4 @@ module.exports = {
getSessions,
};
//http://localhost:3001/api/v1/ivao/init-sessions?callsign=LTS&from=2022-01-01T00:00:00&to=2023-01-04T23:59:59
//http://localhost:3001/api/v1/ivao/init-sessions?callsign=LTS&from=2023-01-05T00:00:00&to=2023-01-05T23:59:59

29
app/db/mysql/lsaUsers.js Normal file
View File

@ -0,0 +1,29 @@
const { query } = require("./mysqlPool");
async function getUsers() {
const sql = `SELECT u.name,
u.country, u.flights, u.flight_time AS flightTime, ufv.value as vid, u.email
FROM users AS u
INNER JOIN user_field_values AS ufv
ON u.id = ufv.user_id
WHERE ufv.user_field_id = 1`;
const result = await query(sql);
return result;
}
async function getUsersWhitelist() {
const sql = `SELECT ufv.value as vid, u.name, u.flights, u.flight_time AS flightTime
FROM users AS u
INNER JOIN user_field_values AS ufv
ON u.id = ufv.user_id
WHERE ufv.user_field_id = 1 AND u.flight_time > 60 * 200 AND u.state = 1`;
const result = await query(sql);
return result;
}
module.exports = {
getUsers,
getUsersWhitelist,
}

47
app/db/mysql/mysqlPool.js Normal file
View File

@ -0,0 +1,47 @@
const mysql = require('promise-mysql');
const {
LSA_MYSQL_HOST,
LSA_MYSQL_PORT,
LSA_MYSQL_USER,
LSA_MYSQL_PASS,
LSA_MYSQL_DB,
LSA_MYSQL_CONN_LIMIT,
} = process.env;
const config = {
connectionLimit: LSA_MYSQL_CONN_LIMIT,
host: LSA_MYSQL_HOST,
port: LSA_MYSQL_PORT,
user: LSA_MYSQL_USER,
password: LSA_MYSQL_PASS,
database: LSA_MYSQL_DB
};
let pool; //bunyan for logger
async function getMysqlPool() {
try {
if (!pool) {
pool = await mysql.createPool(config);
}
return pool;
} catch (err) {
console.log(err);
}
}
const query = async(sql) => {
try {
const pool = await getMysqlPool();
return pool.query(sql);
} catch (err) {
console.log(err);
}
}
module.exports = {
getMysqlPool,
query
};

82
app/db/redis/redis.js Normal file
View File

@ -0,0 +1,82 @@
const { createClient } = require('redis');
class RedisClient {
constructor(host) {
this._host = host;
}
get client() {
return this._client;
}
async connect() {
const client = createClient({
socket: {
host: this._host,
},
});
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();
this._client = client;
return client;
}
async set(key, value) {
await this._client.set(key, value);
return value;
}
async get(key) {
const value = await this._client.get(key);
return value;
}
async disconnect() {
await this._client.disconnect();
}
}
RedisClient.setPair = async function(key, value) {
const redis = new RedisClient(process.env.REDIS_HOST);
await redis.connect();
await redis.set(key, JSON.stringify(value));
await redis.disconnect();
}
RedisClient.getPair = async function(key) {
const redis = new RedisClient(process.env.REDIS_HOST);
await redis.connect();
const value = await redis.get(key);
await redis.disconnect();
return JSON.parse(value);
}
RedisClient.setCollection = async function(array) {
const redis = new RedisClient(process.env.REDIS_HOST);
await redis.connect();
if (Array.isArray(array)) {
for (let index = 0; index < array.length; index++) {
const pair = array[index];
if (Array.isArray(pair)) {
await redis.set(pair[0], JSON.stringify(pair[1]));
} else {
await redis.set(pair.key, JSON.stringify(pair.value));
}
}
} else {
for (const key in array) {
if (Object.hasOwnProperty.call(array, key)) {
const value = array[key];
await redis.set(key, JSON.stringify(value));
}
}
}
await redis.disconnect();
}
module.exports = {
RedisClient,
};

View File

@ -30,7 +30,6 @@ const getHistoricalSessions = async({ callsign, userId, from, to }) => {
};
async function _requestHistoricalRecursive(data, url, options) {
console.log('options :>> ', options);
const { page, pages, items } = await request(url, options);
data = [...data, ...items];

View File

@ -1,5 +1,5 @@
const express = require('express');
const { getList } = require('../controllers/sessionsController');
const { getList, getWhitelist } = require('../controllers/sessionsController');
const { insertSessions, getSessions } = require('../db/mongo/mongoSessions');
const { getHistoricalSessions } = require('../requests/ivao/session');
const router = express.Router();
@ -33,6 +33,15 @@ router.get('/list/today', async(req, res) => {
}
})
router.get('/whitelist', async(req, res) => {
try {
const data = await getWhitelist();
res.status(200).json(data);
} catch (err) {
console.log(err);
}
})
router.get('/init-sessions', async(req, res) => {
try {
const data = await getHistoricalSessions(req.query);

22
app/tasks/sync.js Normal file
View File

@ -0,0 +1,22 @@
const cron = require('node-cron');
const moment = require('moment');
const { getUsersWhitelist, getUsers } = require('../db/mysql/lsaUsers');
const { RedisClient } = require('../db/redis/redis');
async function task() {
console.log('Running task', moment().format('HH:mm:ss'));
const users = await getUsers();
const whitelist = await getUsersWhitelist();
RedisClient.setCollection([
['users', users],
['users_whitelist', whitelist],
]);
}
module.exports = function() {
task();
cron.schedule('*/15 * * * *', async() => {
task();
});
}

View File

@ -1,5 +1,7 @@
require('dotenv').config();
require('./app/tasks/sync')();
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
@ -8,6 +10,8 @@ const ivaoRoutes = require('./app/routes/ivao');
const app = express();
const whitelist = process.env.HOSTS_WHITELIST ? process.env.HOSTS_WHITELIST.split(',') : [];
// parse application/json
app.use(bodyParser.json());
@ -15,15 +19,18 @@ app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
var corsOptions = {
origin: 'http://localhost:3000'
origin: function(origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
};
// use cors options
app.use(cors(corsOptions));
app.use(express.static('assets'));
// routes
app.use('/api/v1/ivao', ivaoRoutes);

3905
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,10 @@
"express": "^4.18.2",
"moment": "^2.29.4",
"mongodb": "^4.13.0",
"node": "^19.3.0"
"node": "^19.3.0",
"node-cron": "^3.0.2",
"promise-mysql": "^5.2.0",
"redis": "^4.5.1"
},
"devDependencies": {
"eslint": "^8.31.0",

17
test.js Normal file
View File

@ -0,0 +1,17 @@
require('dotenv').config();
const { getUsers } = require('./app/db/mysql/lsaUsers');
const { RedisClient } = require('./app/db/redis/redis');
async function f() {
const users = await getUsers();
const redis = new RedisClient(process.env.REDIS_HOST);
await redis.connect()
await redis.set('users', JSON.stringify(users))
await redis.disconnect();
}
// f();
require('./app/tasks/sync')();