diff --git a/submissions/Zakkarat/Weather-app/dataFetcher.js b/submissions/Zakkarat/Weather-app/dataFetcher.js new file mode 100644 index 0000000..c7c26ad --- /dev/null +++ b/submissions/Zakkarat/Weather-app/dataFetcher.js @@ -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; diff --git a/submissions/Zakkarat/Weather-app/dictionary.json b/submissions/Zakkarat/Weather-app/dictionary.json new file mode 100644 index 0000000..8ba931d --- /dev/null +++ b/submissions/Zakkarat/Weather-app/dictionary.json @@ -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"] +} + diff --git a/submissions/Zakkarat/Weather-app/favourites.js b/submissions/Zakkarat/Weather-app/favourites.js new file mode 100644 index 0000000..8b50ac6 --- /dev/null +++ b/submissions/Zakkarat/Weather-app/favourites.js @@ -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 }; diff --git a/submissions/Zakkarat/Weather-app/favourites.txt b/submissions/Zakkarat/Weather-app/favourites.txt new file mode 100644 index 0000000..fd1b15b --- /dev/null +++ b/submissions/Zakkarat/Weather-app/favourites.txt @@ -0,0 +1,2 @@ +kiev +odessa \ No newline at end of file diff --git a/submissions/Zakkarat/Weather-app/history.js b/submissions/Zakkarat/Weather-app/history.js new file mode 100644 index 0000000..97f3091 --- /dev/null +++ b/submissions/Zakkarat/Weather-app/history.js @@ -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 }; diff --git a/submissions/Zakkarat/Weather-app/history.txt b/submissions/Zakkarat/Weather-app/history.txt new file mode 100644 index 0000000..f8cf0f7 --- /dev/null +++ b/submissions/Zakkarat/Weather-app/history.txt @@ -0,0 +1,14 @@ +odessa +odessa +kiev +kiev +kiev +kiev +kiev +kiev +kiev +kiev +odessa +odessa +odessakiev +kiev diff --git a/submissions/Zakkarat/Weather-app/index.js b/submissions/Zakkarat/Weather-app/index.js new file mode 100644 index 0000000..99d660d --- /dev/null +++ b/submissions/Zakkarat/Weather-app/index.js @@ -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();