mirror of
https://github.com/pawelmalak/flame.git
synced 2025-08-05 02:45:18 +02:00
Merge branch 'master' of https://github.com/pawelmalak/flame into merge_upstream_2020-12-06
This commit is contained in:
commit
021bd4e85a
266 changed files with 13470 additions and 7067 deletions
|
@ -1,8 +1,8 @@
|
|||
class ErrorResponse extends Error {
|
||||
constructor(message, statusCode) {
|
||||
super(message);
|
||||
this.statusCode = statusCode
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ErrorResponse;
|
||||
module.exports = ErrorResponse;
|
||||
|
|
10
utils/checkFileExists.js
Normal file
10
utils/checkFileExists.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const fs = require('fs');
|
||||
|
||||
const checkFileExists = (path) => {
|
||||
return fs.promises
|
||||
.access(path, fs.constants.F_OK)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
};
|
||||
|
||||
module.exports = checkFileExists;
|
|
@ -1,24 +1,20 @@
|
|||
const { Op } = require('sequelize');
|
||||
const Weather = require('../models/Weather');
|
||||
const Logger = require('./Logger');
|
||||
const logger = new Logger();
|
||||
|
||||
const clearWeatherData = async () => {
|
||||
const weather = await Weather.findOne({
|
||||
order: [[ 'createdAt', 'DESC' ]]
|
||||
order: [['createdAt', 'DESC']],
|
||||
});
|
||||
|
||||
if (weather) {
|
||||
await Weather.destroy({
|
||||
where: {
|
||||
id: {
|
||||
[Op.lt]: weather.id
|
||||
}
|
||||
}
|
||||
})
|
||||
[Op.lt]: weather.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
logger.log('Old weather data was deleted');
|
||||
}
|
||||
|
||||
module.exports = clearWeatherData;
|
||||
module.exports = clearWeatherData;
|
||||
|
|
|
@ -1,27 +1,15 @@
|
|||
const Config = require('../models/Config');
|
||||
const Weather = require('../models/Weather');
|
||||
const axios = require('axios');
|
||||
const loadConfig = require('./loadConfig');
|
||||
|
||||
const getExternalWeather = async () => {
|
||||
// Get config from database
|
||||
const config = await Config.findAll();
|
||||
|
||||
// Find and check values
|
||||
const secret = config.find(pair => pair.key === 'WEATHER_API_KEY');
|
||||
const lat = config.find(pair => pair.key === 'lat');
|
||||
const long = config.find(pair => pair.key === 'long');
|
||||
|
||||
if (!secret) {
|
||||
throw new Error('API key was not found. Weather updated failed');
|
||||
}
|
||||
|
||||
if (!lat || !long) {
|
||||
throw new Error('Location was not found. Weather updated failed');
|
||||
}
|
||||
const { WEATHER_API_KEY: secret, lat, long } = await loadConfig();
|
||||
|
||||
// Fetch data from external API
|
||||
try {
|
||||
const res = await axios.get(`http://api.weatherapi.com/v1/current.json?key=${secret.value}&q=${lat.value},${long.value}`);
|
||||
const res = await axios.get(
|
||||
`http://api.weatherapi.com/v1/current.json?key=${secret}&q=${lat},${long}`
|
||||
);
|
||||
|
||||
// Save weather data
|
||||
const cursor = res.data.current;
|
||||
|
@ -32,12 +20,15 @@ const getExternalWeather = async () => {
|
|||
isDay: cursor.is_day,
|
||||
cloud: cursor.cloud,
|
||||
conditionText: cursor.condition.text,
|
||||
conditionCode: cursor.condition.code
|
||||
conditionCode: cursor.condition.code,
|
||||
humidity: cursor.humidity,
|
||||
windK: cursor.wind_kph,
|
||||
windM: cursor.wind_mph,
|
||||
});
|
||||
return weatherData;
|
||||
} catch (err) {
|
||||
throw new Error('External API request failed');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = getExternalWeather;
|
||||
module.exports = getExternalWeather;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
const initConfig = require('./initConfig');
|
||||
const initFiles = require('./initFiles');
|
||||
const initDockerSecrets = require('./initDockerSecrets');
|
||||
|
||||
const initApp = async () => {
|
||||
await initConfig();
|
||||
initDockerSecrets();
|
||||
await initFiles();
|
||||
await initConfig();
|
||||
};
|
||||
|
||||
module.exports = initApp;
|
||||
|
|
|
@ -1,39 +1,25 @@
|
|||
const { Op } = require('sequelize');
|
||||
const Config = require('../../models/Config');
|
||||
const { config } = require('./initialConfig.json');
|
||||
|
||||
const Logger = require('../Logger');
|
||||
const logger = new Logger();
|
||||
const { copyFile, readFile, writeFile } = require('fs/promises');
|
||||
const checkFileExists = require('../checkFileExists');
|
||||
const initialConfig = require('./initialConfig.json');
|
||||
|
||||
const initConfig = async () => {
|
||||
// Get config values
|
||||
const configPairs = await Config.findAll({
|
||||
where: {
|
||||
key: {
|
||||
[Op.or]: config.map((pair) => pair.key),
|
||||
},
|
||||
},
|
||||
});
|
||||
const configExists = await checkFileExists('data/config.json');
|
||||
|
||||
// Get key from each pair
|
||||
const configKeys = configPairs.map((pair) => pair.key);
|
||||
|
||||
// Create missing pairs
|
||||
config.forEach(async ({ key, value }) => {
|
||||
if (!configKeys.includes(key)) {
|
||||
await Config.create({
|
||||
key,
|
||||
value,
|
||||
valueType: typeof value,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV == 'development') {
|
||||
logger.log('Initial config created');
|
||||
if (!configExists) {
|
||||
await copyFile('utils/init/initialConfig.json', 'data/config.json');
|
||||
}
|
||||
|
||||
return;
|
||||
const existingConfig = await readFile('data/config.json', 'utf-8');
|
||||
const parsedConfig = JSON.parse(existingConfig);
|
||||
|
||||
// Add new config pairs if necessary
|
||||
for (let key in initialConfig) {
|
||||
if (!Object.keys(parsedConfig).includes(key)) {
|
||||
parsedConfig[key] = initialConfig[key];
|
||||
}
|
||||
}
|
||||
|
||||
await writeFile('data/config.json', JSON.stringify(parsedConfig));
|
||||
};
|
||||
|
||||
module.exports = initConfig;
|
||||
|
|
17
utils/init/initDockerSecrets.js
Normal file
17
utils/init/initDockerSecrets.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
const { getSecrets } = require('docker-secret');
|
||||
const Logger = require('../Logger');
|
||||
const logger = new Logger();
|
||||
|
||||
const initDockerSecrets = () => {
|
||||
const secrets = getSecrets();
|
||||
|
||||
for (const property in secrets) {
|
||||
const upperProperty = property.toUpperCase();
|
||||
|
||||
process.env[upperProperty] = secrets[property];
|
||||
|
||||
logger.log(`${upperProperty} was overwritten with docker secret value`);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = initDockerSecrets;
|
|
@ -1,88 +1,33 @@
|
|||
{
|
||||
"config": [
|
||||
{
|
||||
"key": "WEATHER_API_KEY",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"key": "lat",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "long",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "isCelsius",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"key": "customTitle",
|
||||
"value": "Flame"
|
||||
},
|
||||
{
|
||||
"key": "pinAppsByDefault",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"key": "pinBookmarksByDefault",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"key": "pinCategoriesByDefault",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"key": "hideHeader",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "useOrdering",
|
||||
"value": "createdAt"
|
||||
},
|
||||
{
|
||||
"key": "appsSameTab",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "bookmarksSameTab",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "searchSameTab",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "hideApps",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "hideBookmarks",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "hideSearch",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "defaultSearchProvider",
|
||||
"value": "l"
|
||||
},
|
||||
{
|
||||
"key": "dockerApps",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "dockerHost",
|
||||
"value": "localhost"
|
||||
},
|
||||
{
|
||||
"key": "kubernetesApps",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "unpinStoppedApps",
|
||||
"value": false
|
||||
}
|
||||
]
|
||||
"WEATHER_API_KEY": "",
|
||||
"lat": 0,
|
||||
"long": 0,
|
||||
"isCelsius": true,
|
||||
"customTitle": "Flame",
|
||||
"pinAppsByDefault": true,
|
||||
"pinBookmarksByDefault": true,
|
||||
"pinCategoriesByDefault": true,
|
||||
"hideHeader": false,
|
||||
"useOrdering": "createdAt",
|
||||
"appsSameTab": false,
|
||||
"bookmarksSameTab": false,
|
||||
"searchSameTab": false,
|
||||
"hideApps": false,
|
||||
"hideBookmarks": false,
|
||||
"hideSearch": false,
|
||||
"defaultSearchProvider": "l",
|
||||
"dockerApps": false,
|
||||
"dockerHost": "localhost",
|
||||
"kubernetesApps": false,
|
||||
"unpinStoppedApps": false,
|
||||
"useAmericanDate": false,
|
||||
"disableAutofocus": false,
|
||||
"greetingsSchema": "Good evening!;Good afternoon!;Good morning!;Good night!",
|
||||
"daySchema": "Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday",
|
||||
"monthSchema": "January;February;March;April;May;June;July;August;September;October;November;December",
|
||||
"showTime": false,
|
||||
"defaultTheme": "tron",
|
||||
"isKilometer": true,
|
||||
"weatherData": "cloud",
|
||||
"hideDate": false
|
||||
}
|
||||
|
|
|
@ -3,20 +3,33 @@ const getExternalWeather = require('./getExternalWeather');
|
|||
const clearWeatherData = require('./clearWeatherData');
|
||||
const Sockets = require('../Sockets');
|
||||
const Logger = require('./Logger');
|
||||
const loadConfig = require('./loadConfig');
|
||||
const logger = new Logger();
|
||||
|
||||
// Update weather data every 15 minutes
|
||||
const weatherJob = schedule.scheduleJob('updateWeather', '0 */15 * * * *', async () => {
|
||||
try {
|
||||
const weatherData = await getExternalWeather();
|
||||
logger.log('Weather updated');
|
||||
Sockets.getSocket('weather').socket.send(JSON.stringify(weatherData));
|
||||
} catch (err) {
|
||||
logger.log(err.message, 'ERROR');
|
||||
const weatherJob = schedule.scheduleJob(
|
||||
'updateWeather',
|
||||
'0 */15 * * * *',
|
||||
async () => {
|
||||
const { WEATHER_API_KEY: secret } = await loadConfig();
|
||||
|
||||
try {
|
||||
const weatherData = await getExternalWeather();
|
||||
|
||||
Sockets.getSocket('weather').socket.send(JSON.stringify(weatherData));
|
||||
} catch (err) {
|
||||
if (secret) {
|
||||
logger.log(err.message, 'ERROR');
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// Clear old weather data every 4 hours
|
||||
const weatherCleanerJob = schedule.scheduleJob('clearWeather', '0 5 */4 * * *', async () => {
|
||||
clearWeatherData();
|
||||
})
|
||||
const weatherCleanerJob = schedule.scheduleJob(
|
||||
'clearWeather',
|
||||
'0 5 */4 * * *',
|
||||
async () => {
|
||||
clearWeatherData();
|
||||
}
|
||||
);
|
||||
|
|
18
utils/loadConfig.js
Normal file
18
utils/loadConfig.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
const { readFile } = require('fs/promises');
|
||||
const checkFileExists = require('../utils/checkFileExists');
|
||||
const initConfig = require('../utils/init/initConfig');
|
||||
|
||||
const loadConfig = async () => {
|
||||
const configExists = await checkFileExists('data/config.json');
|
||||
|
||||
if (!configExists) {
|
||||
await initConfig();
|
||||
}
|
||||
|
||||
const config = await readFile('data/config.json', 'utf-8');
|
||||
const parsedConfig = JSON.parse(config);
|
||||
|
||||
return parsedConfig;
|
||||
};
|
||||
|
||||
module.exports = loadConfig;
|
8
utils/signToken.js
Normal file
8
utils/signToken.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
const jwt = require('jsonwebtoken');
|
||||
|
||||
const signToken = (expiresIn) => {
|
||||
const token = jwt.sign({ app: 'flame' }, process.env.SECRET, { expiresIn });
|
||||
return token;
|
||||
};
|
||||
|
||||
module.exports = signToken;
|
Loading…
Add table
Add a link
Reference in a new issue