Skip to content

Commit 6445c68

Browse files
committed
Add full_server folder
1 parent daa0ff8 commit 6445c68

File tree

5 files changed

+161
-0
lines changed

5 files changed

+161
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Contains the route handlers.
3+
*
4+
*/
5+
class AppController {
6+
static getHomepage(request, response) {
7+
response.status(200).send('Hello Holberton School!');
8+
}
9+
}
10+
11+
export default AppController;
12+
module.exports = AppController;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import readDatabase from '../utils';
2+
3+
/**
4+
* The list of supported majors.
5+
*/
6+
const VALID_MAJORS = ['CS', 'SWE'];
7+
8+
/**
9+
* Contains the student-related route handlers.
10+
*
11+
*/
12+
class StudentsController {
13+
static getAllStudents(request, response) {
14+
const dataPath = process.argv.length > 2 ? process.argv[2] : '';
15+
16+
readDatabase(dataPath)
17+
.then((studentGroups) => {
18+
const responseParts = ['This is the list of our students'];
19+
const cmpFxn = (a, b) => {
20+
if (a[0].toLowerCase() < b[0].toLowerCase()) {
21+
return -1;
22+
}
23+
if (a[0].toLowerCase() > b[0].toLowerCase()) {
24+
return 1;
25+
}
26+
return 0;
27+
};
28+
29+
for (const [field, group] of Object.entries(studentGroups).sort(cmpFxn)) {
30+
responseParts.push(
31+
[
32+
`Number of students in ${field}: ${group.length}.`,
33+
'List:',
34+
group.map((student) => student.firstname).join(', '),
35+
].join(' ')
36+
);
37+
}
38+
response.status(200).send(responseParts.join('\n'));
39+
})
40+
.catch((err) => {
41+
response.status(500).send(err instanceof Error ? err.message : err.toString());
42+
});
43+
}
44+
45+
static getAllStudentsByMajor(request, response) {
46+
const dataPath = process.argv.length > 2 ? process.argv[2] : '';
47+
const { major } = request.params;
48+
49+
if (!VALID_MAJORS.includes(major)) {
50+
response.status(500).send('Major parameter must be CS or SWE');
51+
return;
52+
}
53+
readDatabase(dataPath)
54+
.then((studentGroups) => {
55+
let responseText = '';
56+
57+
if (Object.keys(studentGroups).includes(major)) {
58+
const group = studentGroups[major];
59+
responseText = `List: ${group.map((student) => student.firstname).join(', ')}`;
60+
}
61+
response.status(200).send(responseText);
62+
})
63+
.catch((err) => {
64+
response.status(500).send(err instanceof Error ? err.message : err.toString());
65+
});
66+
}
67+
}
68+
69+
export default StudentsController;
70+
module.exports = StudentsController;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import AppController from '../controllers/AppController';
2+
import StudentsController from '../controllers/StudentsController';
3+
4+
/**
5+
* Binds the routes to the appropriate handler in the
6+
* given Express application.
7+
* @param {Express} app The Express application.
8+
* @returns {void}
9+
*/
10+
const mapRoutes = (app) => {
11+
app.get('/', AppController.getHomepage);
12+
app.get('/students', StudentsController.getAllStudents);
13+
app.get('/students/:major', StudentsController.getAllStudentsByMajor);
14+
};
15+
16+
export default mapRoutes;
17+
module.exports = mapRoutes;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import express from 'express';
2+
import mapRoutes from './routes';
3+
4+
const app = express();
5+
const PORT = 1245;
6+
7+
mapRoutes(app);
8+
app.listen(PORT, () => {
9+
console.log(`Server listening on PORT ${PORT}`);
10+
});
11+
12+
export default app;
13+
module.exports = app;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import fs from 'fs';
2+
3+
/**
4+
* Reads the data of students in a CSV data file.
5+
* @param {String} dataPath The path to the CSV data file.
6+
* @author Bezaleel Olakunori <https://github.com/B3zaleel>
7+
* @returns {Promise<{
8+
* String: {firstname: String, lastname: String, age: number}[]
9+
* }>}
10+
*/
11+
const readDatabase = (dataPath) => new Promise((resolve, reject) => {
12+
if (!dataPath) {
13+
reject(new Error('Cannot load the database'));
14+
}
15+
if (dataPath) {
16+
fs.readFile(dataPath, (err, data) => {
17+
if (err) {
18+
reject(new Error('Cannot load the database'));
19+
}
20+
if (data) {
21+
const fileLines = data
22+
.toString('utf-8')
23+
.trim()
24+
.split('\n');
25+
const studentGroups = {};
26+
const dbFieldNames = fileLines[0].split(',');
27+
const studentPropNames = dbFieldNames
28+
.slice(0, dbFieldNames.length - 1);
29+
30+
for (const line of fileLines.slice(1)) {
31+
const studentRecord = line.split(',');
32+
const studentPropValues = studentRecord
33+
.slice(0, studentRecord.length - 1);
34+
const field = studentRecord[studentRecord.length - 1];
35+
if (!Object.keys(studentGroups).includes(field)) {
36+
studentGroups[field] = [];
37+
}
38+
const studentEntries = studentPropNames
39+
.map((propName, idx) => [propName, studentPropValues[idx]]);
40+
studentGroups[field].push(Object.fromEntries(studentEntries));
41+
}
42+
resolve(studentGroups);
43+
}
44+
});
45+
}
46+
});
47+
48+
export default readDatabase;
49+
module.exports = readDatabase;

0 commit comments

Comments
 (0)