Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
8 changed files
with
433 additions
and
82 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"plugins": ["jsdoc-route-plugin"], | ||
"recurseDepth": 10, | ||
"source": { | ||
"include": [ "." ], | ||
"exclude": [ "node_modules" ], | ||
"includePattern": ".+\\.js(doc|x)?$", | ||
"excludePattern": "(^|\\/|\\\\)_" | ||
}, | ||
"sourceType": "module", | ||
"tags": { | ||
"allowUnknownTags": true, | ||
"dictionaries": ["jsdoc","closure"] | ||
}, | ||
"templates": { | ||
"cleverLinks": false, | ||
"monospaceLinks": false | ||
}, | ||
"opts": { | ||
"encoding": "utf8", | ||
"destination": "./docs/jsdoc", | ||
"recurse": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
|
||
'use strict' | ||
|
||
const request = require('request') | ||
const readline = require('readline-sync') | ||
const fs = require('fs') | ||
|
||
const baseURL = 'https://api.exchangeratesapi.io/latest' | ||
|
||
async function main() { | ||
try { | ||
const base = await getInput('enter base currency') | ||
await checkValidCurrencyCode(base) | ||
const data = await getData(`${baseURL}?base=${base}`) | ||
const rates = JSON.parse(data).rates | ||
await printObject(data) | ||
const to = await getInput('convert to') | ||
await checkValidCurrencyCode(to) | ||
console.log(to) | ||
const amount = await getInput('enter exchange amount') | ||
const decoder = await readObjectFromFile('currencies.json') | ||
console.log(`${amount} ${decoder[base]} (${base}) is worth ${ | ||
(rates[to] * amount).toFixed(4)} ${decoder[to]} (${to})`) | ||
process.exit() | ||
} catch (err) { | ||
console.log(`error: ${err.message}`) | ||
} | ||
} | ||
|
||
const getInput = async prompt => readline.question(`${prompt}: `) | ||
|
||
const checkValidCurrencyCode = code => new Promise( (resolve, reject) => { | ||
code = code.trim() | ||
request(baseURL, (err, res, body) => { | ||
if (err) reject(new Error('invalid API call')) | ||
const rates = JSON.parse(body).rates | ||
if (!rates.hasOwnProperty(code)) throw new Error(`invalid currency code ${code}`) | ||
resolve() | ||
}) | ||
}) | ||
|
||
const getData = url => new Promise( (resolve, reject) => { | ||
request(url, (err, res, body) => { | ||
if (err) reject(new Error('invalid API call')) | ||
resolve(body) | ||
}) | ||
}) | ||
|
||
const printObject = async data => { | ||
const indent = 2 | ||
data = await JSON.parse(data) | ||
const str = JSON.stringify(data, null, indent) | ||
await new Promise( resolve => { | ||
console.log(str) | ||
resolve() | ||
}) | ||
|
||
} | ||
|
||
const readObjectFromFile = fileName => new Promise( (resolve, reject) => { | ||
fs.readFile(fileName, 'utf-8', (err, content) => { | ||
if (err) reject(new Error(err)) | ||
return resolve(JSON.parse(content)) | ||
}) | ||
}) | ||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#!/usr/bin/env node | ||
|
||
/* eslint max-lines-per-function: 0 */ | ||
|
||
'use strict' | ||
|
||
const request = require('request') | ||
const readline = require('readline') | ||
const fs = require('fs') | ||
|
||
const io = { input: process.stdin, output: process.stdout } | ||
|
||
const read = readline.createInterface(io) | ||
read.question('input base currency: ', base => { | ||
console.log(`You entered ${base}`) | ||
read.close() | ||
base = base.trim() | ||
// now we need to check the code is valid | ||
request('https://api.exchangeratesapi.io/latest', (err, res, body) => { | ||
if (err) { | ||
console.error(err.message) | ||
process.exit() | ||
} | ||
const rates = JSON.parse(body).rates | ||
if (!rates.hasOwnProperty(base)) { | ||
console.error(`invalid currency code ${base}`) | ||
process.exit() | ||
} | ||
// now we can get the currency rates | ||
request(`https://api.exchangeratesapi.io/latest?base=${base}`, (err, res, body) => { | ||
if (err) { | ||
console.error(err.message) | ||
process.exit() | ||
} | ||
body = JSON.parse(body) | ||
console.log(body) | ||
// lets ask another question | ||
const read = readline.createInterface(io) | ||
read.question('convert to: ', convertTo => { | ||
read.question('amount to convert: ', amount => { | ||
read.close() | ||
fs.readFile('currencies.json', 'utf8', (err, content) => { | ||
if(err) console.error(error.message) | ||
const decoder = JSON.parse(content) | ||
console.log(`${amount} ${decoder[base]} (${base}) is worth ${ | ||
(body.rates[convertTo] * amount).toFixed(4)} ${decoder[convertTo]} (${convertTo})`) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
|
||
'use strict' | ||
|
||
const request = require('request') | ||
const readline = require('readline') | ||
const fs = require('fs') | ||
|
||
const baseURL = 'https://api.exchangeratesapi.io/latest' | ||
|
||
const getInput = prompt => new Promise(resolve => { | ||
const read = readline.createInterface({ input: process.stdin, output: process.stdout }) | ||
read.question(`${prompt}: `, value => { | ||
console.log(`You entered ${value}`) | ||
read.close() | ||
return resolve(value) | ||
}) | ||
}) | ||
|
||
const checkValidCurrencyCode = code => new Promise( (resolve, reject) => { | ||
code = code.trim() | ||
request(baseURL, (err, res, body) => { | ||
if (err) reject(new Error('invalid API call')) | ||
const rates = JSON.parse(body).rates | ||
if (!rates.hasOwnProperty(code)) reject(new Error(`invalid currency code ${code}`)) | ||
return resolve(code) | ||
}) | ||
}) | ||
|
||
const getData = code => new Promise( (resolve, reject) => { | ||
request(`${baseURL}?base=${code}`, (err, res, body) => { | ||
if (err) reject(new Error('invalid API call')) | ||
return resolve(body) | ||
}) | ||
}) | ||
|
||
const printObject = data => new Promise( resolve => { | ||
const indent = 2 | ||
data = JSON.parse(data) | ||
const str = JSON.stringify(data, null, indent) | ||
console.log(str) | ||
return resolve() | ||
}) | ||
|
||
const exit = () => new Promise( () => { | ||
process.exit() | ||
}) | ||
|
||
const readObjectFromFile = fileName => new Promise( (resolve, reject) => { | ||
fs.readFile(fileName, 'utf-8', (err, content) => { | ||
if (err) reject(new Error(err)) | ||
return resolve(JSON.parse(content)) | ||
}) | ||
}) | ||
|
||
getInput('enter base currency') | ||
.then(checkValidCurrencyCode) | ||
.then(code => this.base = code) | ||
.then( () => getData(this.base)) | ||
.then( body => this.rates = JSON.parse(body).rates) | ||
.then( () => getInput('convert to')) | ||
.then(checkValidCurrencyCode) | ||
.then( code => this.convertTo = code) | ||
.then( () => readObjectFromFile('currencies.json')) | ||
.then(fileObject => this.decoder = fileObject) | ||
.then( () => getInput('enter exchange amount')) | ||
.then( amount => console.log(`${amount} ${this.decoder[this.base]} (${this.base}) is worth ${ | ||
(this.rates[this.convertTo] * amount).toFixed(4)} ${this.decoder[this.convertTo]} (${this.convertTo})`)) | ||
.then(exit) | ||
.catch(err => console.error(`error: ${err.message}`)) | ||
.then(exit) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/usr/bin/env node | ||
|
||
/** | ||
* Server index module | ||
* @module index | ||
*/ | ||
|
||
const Koa = require('koa') | ||
const Router = require('koa-router') | ||
const stat = require('koa-static') | ||
const bodyParser = require('koa-bodyparser') | ||
const handlebars = require('koa-hbs-renderer') | ||
|
||
const app = new Koa() | ||
const router = new Router() | ||
app.use(stat('public')) | ||
app.use(bodyParser()) | ||
app.use(handlebars({ paths: { views: `${__dirname}/views` } })) | ||
app.use(router.routes()) | ||
|
||
// The through which the server will communicate | ||
const port = 8080 | ||
|
||
const List = require('./modules/list').List | ||
const list = new List() | ||
|
||
/** | ||
* Get the home page | ||
* @name Home | ||
* @route {GET} / | ||
*/ | ||
router.get('/', ctx => { | ||
try { | ||
const items = list.getAll() | ||
console.log(items) | ||
const data = {items} | ||
ctx.render('home', data) | ||
} catch(err) { | ||
console.log(err.message) | ||
ctx.render('home', {msg: err.message}) | ||
} | ||
}) | ||
|
||
/** | ||
* Add an item to the list | ||
* @name Add item | ||
* @route {POST} / | ||
*/ | ||
router.post('/', ctx => { | ||
try { | ||
const body = ctx.request.body | ||
console.log(body) | ||
list.add(body.item, body.qty) | ||
ctx.redirect('/') | ||
} catch(err) { | ||
console.log(err.message) | ||
ctx.redirect(`/?msg=${err.message}`) | ||
} | ||
}) | ||
|
||
/** | ||
* Delete an item from the list | ||
* @name Delete item | ||
* @route {get} /delete/:key | ||
*/ | ||
router.get('/delete/:key', ctx => { | ||
try { | ||
const key = ctx.params.key | ||
console.log(`key: ${key}`) | ||
list.delete(key) | ||
ctx.redirect('/?msg=item deleted') | ||
} catch(err) { | ||
console.log(err.message) | ||
ctx.redirect(`/${err.message}`) | ||
} | ||
}) | ||
|
||
module.exports = app.listen(port, () => { | ||
console.log(`listening on port ${port}`) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
|
||
/** | ||
* Class representing a list of items. | ||
* */ | ||
class List { | ||
|
||
/** | ||
* Create a list. | ||
*/ | ||
constructor() { | ||
this.items = [] | ||
} | ||
|
||
/** | ||
* Add an item to the list. | ||
* @param {String} item - The name of the eitem. | ||
* @param {Number} qty - The number of items to add. | ||
*/ | ||
add(item, qty) { | ||
const data = {item: item, qty: qty} | ||
this.items.push(data) | ||
} | ||
|
||
/** | ||
* Return the list of items. | ||
* @return {Array.<{item: String, qty: Number}>} An array containing the items. | ||
*/ | ||
getAll() { | ||
return this.items.map( (element, index) => ({key: index, item: element.item, qty: element.qty})) | ||
} | ||
|
||
/** | ||
* Delete an item from the list. | ||
* @param {Number} id - The index of the deletable item | ||
*/ | ||
delete(id) { | ||
this.items.splice(id, 1) | ||
} | ||
|
||
/** | ||
* Return the number of items in the list | ||
* @return {Number} The number of items in the list | ||
*/ | ||
count() { | ||
return this.items.count | ||
} | ||
|
||
} | ||
|
||
// exporting the class by name adds the name to the documentation | ||
module.exports = { | ||
List | ||
} |