Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Weather-App by Zakkarat #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions submissions/Zakkarat/Weather-app/dataFetcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const axios = require('axios');

const { appIds, currents } = require('./dictionary.json');

const fetcher = async (
l = process.argv[2],
units = 'metric',
range = 'weather',
{ type } = appIds[0],
{ APPID } = appIds[0]
) => {
if (!currents.some(elem => elem === range)) {
type = appIds[1].type;
APPID = appIds[1].APPID;
}
const data = await axios(
`https://api.openweathermap.org/data/2.5/${type}?${
Array.isArray(l) ? `lat=${l[0]}&lon=${l[1]}` : `q=${l}`
}&units=${units}&APPID=${APPID}`
).then(response => {
return response.data;
});
return data;
};

module.exports = fetcher;
10 changes: 10 additions & 0 deletions submissions/Zakkarat/Weather-app/dictionary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"celsium": ["c", "celsium"],
"currents": ["today", "current", "curr", "day"],
"appIds": [
{ "type": "weather", "APPID": "9b56af47f5baa2ff8c03fde75ad1993a" },
{ "type": "forecast", "APPID": "e1403e6bd9381734b9ef1b0163cf00f7" }
],
"days": ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
}

35 changes: 35 additions & 0 deletions submissions/Zakkarat/Weather-app/favourites.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const fs = require('fs');

const writeToFav = location => {
fs.writeFile('./favourites.txt', location.join('\n'), err => {
if (err) {
return console.log(err);
}
});
};

const readFav = () => {
try {
return fs.readFileSync('./favourites.txt', (err, data) => {
if (err) throw err;
return data;
});
} catch {
return '';
}
};

const toggleFav = loc => {
const data = readFav()
.toString()
.split('\n')
.map(elem => elem.toLowerCase());
if (!data.includes(loc)) {
data.push(loc);
} else {
data.splice(data.indexOf(loc), 1);
}
writeToFav(data);
};

module.exports = { toggleFav, readFav };
2 changes: 2 additions & 0 deletions submissions/Zakkarat/Weather-app/favourites.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
kiev
odessa
22 changes: 22 additions & 0 deletions submissions/Zakkarat/Weather-app/history.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const fs = require('fs');

const writeToHistory = location => {
fs.appendFile('./history.txt', location, err => {
if (err) {
return console.log(err);
}
});
};

const readHistory = () => {
try {
return fs.readFileSync('./history.txt', (err, data) => {
if (err) throw err;
return data.toString();
});
} catch {
console.log('No history yet.');
}
};

module.exports = { writeToHistory, readHistory };
14 changes: 14 additions & 0 deletions submissions/Zakkarat/Weather-app/history.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
odessa
odessa
kiev
kiev
kiev
kiev
kiev
kiev
kiev
kiev
odessa
odessa
odessakiev
kiev
105 changes: 105 additions & 0 deletions submissions/Zakkarat/Weather-app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
const fetcher = require('./dataFetcher');
const { celsium, days } = require('./dictionary.json');
const { writeToHistory, readHistory } = require('./history');
const { toggleFav, readFav } = require('./favourites');

const help = `
This is simple CLI Weather App, which can show current weather or forecast for 5 days.
There are parameters and values, to specify value for the parameter you should split them up
with '='.
For example: --l=Kiev
As a parameters, it takes:
--l: Used to specify a location for a weather forecast. (Last successful request by default)
--units: Used to specify units in which temperature will be given.
Units for example: 'c', 'f'. (Faranheit by default)
--r: Used to specify, whether you need a forecast or current weather.
Example for current weather: 'current', 'curr' 'today'. (Forecast by default)
--h: Used to show the history of requests.
--f: To add location to your favourites list, you should use this parameter with a request.
To remove location from the list, you should do exact same thing.
To see the list, you should use parameter without request.
--help: Shows this text.
`;

const main = async () => {
const args = toFetchArgs(argsToObject());
const argsKeys = Object.keys(args);
const history = readHistory().toString();
if (argsKeys.includes('h')) {
console.log(history);
return 0;
}
if (argsKeys.length === 2 && argsKeys.includes('f')) {
console.log(readFav().toString());
return 0;
}
if (argsKeys.includes('help')) {
console.log(help);
return 0;
}
if (!args.l) {
args.l = history.split('\n')[history.split('\n').length - 1];
}
const data = await fetcher(args.l, args.units, args.r);
data.list ? toConsoleSpec(data, args.l) : toConsoleCurr(data);
if (argsKeys.includes('f')) {
toggleFav(args.l);
}
if (argsKeys.includes('l')) {
writeToHistory(args.l + '\n');
}
return data;
};

const argsToObject = () => {
const args = process.argv
.slice(2, process.argv.length)
.map(elem => elem.split('='));
return args.reduce((acc, curr) => {
acc[curr[0].slice(2, curr[0].length)] = curr[1];
return acc;
}, {});
};

const toFetchArgs = args => {
if (celsium.some(str => str === args.units)) {
args.units = 'metric';
} else {
args.units = 'imperial';
}
if (args.l && args.l.includes(',')) {
args.l = args.l.split(',');
}
return args;
};

const toConsoleCurr = data => {
const { name, weather, main, wind, sys, dt } = data;
const status = weather[0].main;
const { temp } = main;
const { speed } = wind;
const { country } = sys;
const date = new Date(dt * 1000);
console.log(`${name} ${country} ${date.toDateString()}`);
console.log(`Status: ${status}`);
console.log(`Temperature: ${temp}`);
console.log(`Wind speed: ${speed}`);
};

const toConsoleSpec = ({ list }, location) => {
list.forEach(elem => (elem.dt = new Date(elem.dt * 1000)));
list = list.filter(elem => !(list.indexOf(elem) % 9));
console.log('------------------------');
console.log('Day | Temp | Wind Speed ');
console.log('------------------------');
list.forEach(elem =>
console.log(
`${days[elem.dt.getDay()].slice(0, 3)} | ${Math.floor(
elem.main.temp
)} | ${Math.floor(elem.wind.speed)}`
)
);
console.log('------------------------');
};

main();