Default Project Structure

This commit is contained in:
Thomas Mack 2018-12-28 11:23:19 +01:00
parent 64e665869f
commit 77c1c089d5
25 changed files with 4697 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

66
app.js Normal file
View File

@ -0,0 +1,66 @@
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var logger = require('morgan');
var sassMiddleware = require('node-sass-middleware');
const db = require('./db')
const PORT = process.env.PORT || 4000;
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var valuelistRouter = require('./routes/valuelist');
var recepieRouter = require('./routes/recepie');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(sassMiddleware({
src: path.join(__dirname, 'public'),
dest: path.join(__dirname, 'public'),
indentedSyntax: true, // true = .sass and false = .scss
sourceMap: true
}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', (req, res, next ) => {
req.db = db;
next();
})
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/wl', valuelistRouter);
app.use('/recepies', recepieRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
app.listen(PORT, ()=> {
console.log('Server listening on PORT '+PORT);
})
module.exports = app;

90
bin/www Executable file
View File

@ -0,0 +1,90 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('myrezeptapp:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

182
db/index.js Normal file
View File

@ -0,0 +1,182 @@
// SQL-Class
// Author: Thomas Mack
const DEBUG = true;
const { Pool } = require('pg');
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'bidat_cookbook',
password: 'postgres',
port: 5432
});
const query = function (text, params, callback) {
const start = Date.now()
return pool.query(text, params, (err, res) => {
const duration = Date.now() - start;
//if(res)
console.log('executed query', { text, duration})
callback(err, res)
})
}
const getClient = function (callback) {
pool.connect((err, client, done) => {
callback(err, client, done)
})
}
const dataStructure = {
categories: {
tableName: "kategorie",
jsonName: "categories"
},
units: {
tableName: "einheit",
jsonName: "units"
},
tools: {
tableName: "geraet",
jsonName: "tools"
},
difficulties: {
tableName: "schwierigkeit",
jsonName: "difficulties"
},
ingredients: {
tableName: "zutat",
jsonName: "ingredients"
},
ratingcategories: {
tableName: "wertungkategorie",
jsonName: "ratingcategories"
}
}
const selectAllFromTable = (table) => {
return "SELECT * FROM "+table+";";
}
const selectAllFromTableByFieldValue = (table, field, value) => {
return "SELECT * FROM "+table+" WHERE "+field+"="+value+";";
}
const selectItemFromTable = function (table, id) {
return "SELECT * FROM "+table+" WHERE id = "+id+";";
}
const deleteItemFromTable = function (table, id) {
return "DELETE FROM "+table+" WHERE id = "+id+";";
}
const deleteNameKeyObject = function(req, res, next) {
if(DEBUG) console.log("Delte Valuelist");
let structure = getStructure(req);
let obj = req.body[structure.jsonName][0];
let query = "DELETE FROM "+structure.tableName+
" WHERE id = "+req.itemId;
query(query, (err, rs) => {
if(err) {
console.log(query);
next(err)
} else {
res.status(204).send();
}
});
}
const updateNameKeyObject = function(req, res, next) {
if(DEBUG) console.log("Update Valuelist");
let structure = getStructure(req);
if(DEBUG) console.log(req.body[structure.jsonName]);
let obj = req.body[structure.jsonName][0];
let query = "UPDATE "+structure.tableName+
" set schluessel = '"+obj.schluessel+
"', name = '"+obj.name+
"', beschreibung = '"+obj.beschreibung+
"' WHERE id = "+req.itemId+" returning *";
query(query, (err, rs) => {
if(err) {
console.log(query);
next(err)
} else {
let result = {};
result[structure['jsonName']] = rs.rows;
res.status(200).json(result);
}
});
}
const insertNameKeyObject = function(req, res, next) {
if(DEBUG) console.log("Insert Valuelist");
let structure = getStructure(req);
if(DEBUG) console.log(req.body[structure.jsonName]);
let obj = req.body[structure.jsonName][0];
let query = "INSERT INTO "+structure.tableName+" (schluessel, name, beschreibung) "+
" VALUES ('"+obj.schluessel+"','"+obj.name+"','"+obj.beschreibung+"')" +
" returning *";
if(DEBUG) console.log(query);
query(query, (err, rs) => {
if(err) {
console.log(query);
next(err)
} else {
let result = {};
result[structure['jsonName']] = rs.rows;
console.log(result);
res.status(200).json(result);
}
});
}
const getStructure = function(req) {
let path = req.pathCall;
let structure = dataStructure[path];
return structure;
}
const getAllFromTable = function(req, res, next) {
let structure = getStructure(req);
if(DEBUG) {
console.log("Found Structure-Object: ");
console.log(structure);
}
if(structure === undefined) return res.status(404).send();
query(selectAllFromTable(structure.tableName), (err, rs) => {
if(err) next(err)
else {
if(DEBUG) console.log(res);
let result = {};
result[structure['jsonName']] = rs.rows;
console.log(result);
res.status(200).json(result);
}
})
}
module.exports = {
query,
selectAllFromTable,
selectAllFromTableByFieldValue,
deleteItemFromTable,
updateNameKeyObject,
insertNameKeyObject,
deleteNameKeyObject,
getAllFromTable,
getStructure
};

116
index.js Normal file
View File

@ -0,0 +1,116 @@
const express = require('express');
const router = express.Router();
const pg = require('pg');
const path = require('path');
const { Pool } = require('pg');
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'hogwarts',
password: 'postgres',
port: 5432
});
pool.on('error', (err, client) => {
console.error('Unexpected error on idle client', err)
process.exit(-1)
});
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/api/v1/person', function(req, res, next) {
const results = [];
pool.connect((err, client, done) => {
if (err) throw err
client.query('SELECT * FROM v_person ORDER BY name ASC;', (err, rs) => {
for(var i= 0; i<rs.rows.length; i++) {
results.push(rs.rows[i]);
}
console.log(err, rs);
done();
return res.json(results);
});
//done();
})
});
router.get('/api/v1/person/:person_id', function(req, res, next) {
const results = [];
const id = req.params.person_id;
pool.connect((err, client, done) => {
if (err) throw err
client.query('SELECT * FROM v_person WHERE id = $1;',[id], (err, rs) => {
for(var i= 0; i<rs.rows.length; i++) {
results.push(rs.rows[i]);
}
console.log(err, rs);
done();
return res.json(results);
});
})
});
router.get('/api/v1/schuljahr', function(req, res, next) {
const results = [];
pool.connect((err, client, done) => {
if (err) throw err
client.query('SELECT * FROM schuljahr ORDER BY von ASC;', (err, rs) => {
for(var i= 0; i<rs.rows.length; i++) {
results.push(rs.rows[i]);
}
console.log(err, rs);
done();
return res.json(results);
});
//done();
})
});
router.get('/api/v1/punkte/:schuljahr', function(req, res, next) {
const results = [];
const id = req.params.schuljahr;
const group = req.query.group;
var queryString = 'SELECT * FROM v_hauspunkte_small WHERE schuljahr = $1;';
if(group==1) queryString = 'SELECT schuljahr, haus, sum(punkte) FROM v_hauspunkte WHERE schuljahr = $1 GROUP BY schuljahr, haus;'
pool.connect((err, client, done) => {
if (err) throw err
client.query(queryString,[id], (err, rs) => {
for(var i= 0; i<rs.rows.length; i++) {
results.push(rs.rows[i]);
}
console.log(err, rs);
done();
return res.json(results);
});
})
});
module.exports = router;

191
migration.js Normal file
View File

@ -0,0 +1,191 @@
// Todo Implement Database Connection
db.serialize(function() {
db.run("CREATE TABLE" +" IF NOT EXISTS zutat" +
" (" +
" id bigserial PRIMARY KEY," +
" schluessel text NOT NULL," +
" name text NOT NULL," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS einheit" +
" (" +
" id bigserial PRIMARY KEY," +
" schluessel text NOT NULL," +
" name text NOT NULL," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS geraet" +
" (" +
" id bigserial PRIMARY KEY," +
" schluessel text NOT NULL," +
" name text NOT NULL," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS kategorie" +
" (" +
" id bigserial PRIMARY KEY," +
" schluessel text NOT NULL," +
" name text NOT NULL," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS wertungkategorie" +
" (" +
" id bigserial PRIMARY KEY," +
" schluessel text NOT NULL," +
" name text NOT NULL," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS schwierigkeit" +
" (" +
" id bigserial PRIMARY KEY," +
" schluessel text NOT NULL," +
" name text NOT NULL," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS rezept" +
" (" +
" id bigserial PRIMARY KEY," +
" schluessel text NOT NULL," +
" schwierigkeit bigint NOT NULL REFERENCES schwierigkeit(id)," +
" name text NOT NULL," +
" portionen NUMERIC NOT NULL DEFAULT 4.0," +
" nutzer bigint NOT NULL REFERENCES nutzer(id)," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS rezept_dauer" +
" (" +
" id bigserial PRIMARY KEY," +
" rezept bigint NOT NULL REFERENCES rezept(id)," +
" dauer interval NOT NULL," +
" name text NOT NULL," +
" sort INT NOT NULL DEFAULT 0," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS rezept_zutat" +
" (" +
" id bigserial PRIMARY KEY," +
" rezept bigint NOT NULL REFERENCES rezept(id)," +
" einheit bigint NOT NULL REFERENCES einheit(id)," +
" zutat bigint NOT NULL REFERENCES zutat(id)," +
" menge NUMERIC," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS rezept_geraet" +
" (" +
" id bigserial PRIMARY KEY," +
" rezept bigint NOT NULL REFERENCES rezept(id)," +
" einheit bigint NOT NULL REFERENCES einheit(id)," +
" geraet bigint NOT NULL REFERENCES geraet(id)," +
" menge NUMERIC," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS rezept_schritt" +
" (" +
" id bigserial PRIMARY KEY," +
" rezept bigint NOT NULL REFERENCES rezept(id)," +
" sort INT NOT NULL DEFAULT 0," +
" name text NOT NULL," +
" beschreibung text NOT NULL" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS rezept_kategorie" +
" (" +
" id bigserial PRIMARY KEY," +
" rezept bigint NOT NULL REFERENCES rezept(id)," +
" kategorie bigint NOT NULL REFERENCES kategorie(id)," +
" modifikator NUMERIC NOT NULL DEFAULT 1," +
" beschreibung text NOT NULL" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS nutzer" +
" (" +
" id bigserial PRIMARY KEY," +
" name text NOT NULL," +
" email text NOT NULL," +
" kennwort text NOT NULL," +
" beschreibung text NOT NULL" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS rolle" +
" (" +
" id bigserial PRIMARY KEY," +
" schluessel text NOT NULL," +
" name text NOT NULL," +
" beschreibung text" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_rolle" +
" (" +
" id bigserial PRIMARY KEY," +
" nutzer bigint NOT NULL REFERENCES nutzer(id)," +
" rolle bigint NOT NULL REFERENCES rolle(id)," +
" beschreibung text NOT NULL" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_favorit" +
" (" +
" id bigserial PRIMARY KEY," +
" nutzer bigint NOT NULL REFERENCES nutzer(id)," +
" rezept bigint NOT NULL REFERENCES rezept(id)," +
" beschreibung text NOT NULL" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS rezept_wertung" +
" (" +
" id bigserial PRIMARY KEY," +
" nutzer bigint NOT NULL REFERENCES nutzer(id)," +
" rezept bigint NOT NULL REFERENCES rezept(id)," +
" wertungkategorie bigint NOT NULL REFERENCES wertungkategorie(id)," +
" wert INTEGER NOT NULL DEFAULT 5," +
" beschreibung text NOT NULL" +
" );" +
);
db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_kommentar" +
" (" +
" id bigserial PRIMARY KEY," +
" nutzer bigint NOT NULL REFERENCES nutzer(id)," +
" relation text NOT NULL," +
" relation_id bigint NOT NULL," +
" beschreibung text NOT NULL" +
);
db.run("CREATE UNIQUE INDEX idx_geraet_schluessel ON geraet (schluessel);");
db.run("CREATE UNIQUE INDEX idx_einheit_schluessel ON einheit (schluessel);");
db.run("CREATE UNIQUE INDEX idx_kategorie_schluessel ON kategorie (schluessel);");
db.run("CREATE UNIQUE INDEX idx_schwierigket_schluessel ON schwierigkeit (schluessel);");
db.run("CREATE UNIQUE INDEX idx_zutat_schluessel ON zutat (schluessel);");
db.run("CREATE UNIQUE INDEX idx_rezept_schluessel ON rezept (schluessel);");
db.run("CREATE UNIQUE INDEX idx_nutzer_email ON nutzer (email);");
db.run("CREATE UNIQUE INDEX idx_wertungkategorie_email ON wertungkategorie (schluessel);")"
);
};

2930
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

28
package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "bidatCookbook",
"version": "0.5.0",
"description": "Cookbook app for Families to share their recipies",
"main": "app.js",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"bcrypt": "^3.0.3",
"body-parser": "^1.18.3",
"cors": "^2.8.5",
"debug": "~2.6.9",
"express": "~4.16.0",
"express-session": "^1.15.6",
"http-errors": "~1.6.2",
"morgan": "~1.9.0",
"node-sass-middleware": "0.11.0",
"passport-local": "^1.0.0",
"pg": "^7.7.1",
"pug": "2.0.0-beta11",
"rand-token": "^0.4.0",
"react": "^16.7.0",
"react-dom": "^15.6.1",
"react-router-dom": "^4.2.2"
}
}

View File

@ -0,0 +1,8 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; }
a {
color: #00B7FF; }
/*# sourceMappingURL=style.css.map */

View File

@ -0,0 +1,9 @@
{
"version": 3,
"file": "style.css",
"sources": [
"style.sass"
],
"names": [],
"mappings": "AAAA,AAAA,IAAI,CAAC;EACH,OAAO,EAAE,IAAI;EACb,IAAI,EAAE,kDAAkD,GAAG;;AAE7D,AAAA,CAAC,CAAC;EACA,KAAK,EAAE,OAAO,GAAG"
}

View File

@ -0,0 +1,6 @@
body
padding: 50px
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif
a
color: #00B7FF

9
routes/index.js Normal file
View File

@ -0,0 +1,9 @@
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;

165
routes/recepie.js Normal file
View File

@ -0,0 +1,165 @@
const express = require('express');
const router = express.Router();
const bcrypt = require('bcrypt');
const randToken = require('rand-token');
const ingredientsRouter = require('./recepieIngredients');
const toolsRouter = require('./recepieTools');
const durationsRouter = require('./recepieDurations');
const DEBUG = false;
router.param('recepieId', function(req, res, next, id) {
req.recepieId = id;
let query = " Select id, schluessel, schwierigkeit, name, portionen, nutzer, beschreibung, "+
" (SELECT sum(dauer) FROM rezept_dauer WHERE rezept = $1) as overall_duration "+
" FROM rezept ";
if(isNaN(req.recepieId)) {
query += " WHERE schluessel ilike '$1'";
} else {
query += " WHERE id = $1";
}
if(DEBUG) console.log(query);
req.db.query(query, [req.recepieId], (err, rs) => {
if (err) {
return next(err)
}
req.recepie = rs.rows[0];
next();
})
});
router.use('/:recepieId/ingredients/', ingredientsRouter);
router.use('/:recepieId/tools/', toolsRouter);
router.use('/:recepieId/durations/', durationsRouter);
/* GET recepies listing. */
router.get('/', function(req, res, next) {
let query = "Select * FROM rezept ";
if(DEBUG) console.log(query);
req.db.query(query, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepies'] = rs.rows;
console.log(result);
res.status(200).json(result);
}
});
});
router.post('/', function(req, res, next) {
let recepie = req.body.recepies[0];
if(!recepie.schluessel) recepie.schluessel = randToken.uid(8);
if(!recepie.schwierigkeit || !recepie.name || !recepie.nutzer) {
return res.status(400).send("Wrong Params")
}
let query = "INSERT INTO rezept (nutzer, name, schluessel, schwierigkeit, portionen, beschreibung) "+
" VALUES ($1, $2, $3, $4, $5, $6)" +
" returning *";
let values = [recepie.nutzer, recepie.name, recepie.schluessel, recepie.schwierigkeit, recepie.portionen, recepie.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if(err && err.constraint && err.constraint ==='idx_rezept_email') {
return res.status(409).send("Email-adress already in use");
} else if (err){
next(err);
} else {
let result = {};
result['recepies'] = rs.rows[0];
res.status(200).json(result);
}
});
});
/* Methods with id */
router.get('/:recepieId', function(req, res, next) {
res.status(200).json(req.recepie);
});
router.put('/:recepieId', function(req, res, next) {
let recepie = req.body.recepies[0];
let query = "UPDATE rezept set name = '"+recepie.name+"', email='"+recepie.email+"', beschreibung = '"+recepie.beschreibung+"' "+
" WHERE id = "+req.recepieId +
" returning *";
if(DEBUG) console.log(query);
req.db.query(query, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepies'] = rs.rows[0];
res.status(200).json(result);
}
});
});
router.put('/:recepieId/changepasswd', function(req, res, next) {
let recepie = req.body.recepies[0];
let oldPasswd = req.body.recepies[0]['oldPasswd'];
let newPasswd = req.body.recepies[0]['newPasswd'];
if(!oldPasswd || !newPasswd) {
return res.status(400).send("Wrong Params");
}
bcrypt.compare(oldPasswd, req.recepie.kennwort, function(err, checkResult) {
console.log("Compare: "+oldPasswd+" WITH "+req.recepie.kennwort+" Result:");
console.log(checkResult);
if(checkResult) {
bcrypt.hash('myPassword', 10, function(err, hash) {
let query = "UPDATE rezept set kennwort = '"+hash+"'"+
" WHERE id = "+req.recepieId +
" returning *";
req.db.query(query, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
let recepie = {};
recepie['name'] = rs.rows[0].name;
recepie['email'] = rs.rows[0].email;
recepie['id'] = rs.rows[0].id;
recepie['beschreibung'] = rs.rows[0].beschreibung;
result['recepies'] = recepie;
console.log(result);
res.status(200).json(result);
}
});
});
} else {
console.log(err);
res.status(409).send("Old Passwd didn't match");
}
});
});
router.delete('/:recepieId', function(req, res, next) {
let query = [
"DELETE FROM rezept_favorit where rezept = $1;",
"DELETE FROM rezept_kommentar where rezept = $1;",
"DELETE FROM rezept_rolle where rezept = $1;",
"DELETE FROM rezept where id = $1;"
];
for(let i = 0; i< query.length; i++) {
req.db.query(query[i], [req.recepieId], (err, rs) => {
if (err) next(err)
});
}
res.status(204).send();
});
module.exports = router;

View File

@ -0,0 +1,97 @@
const express = require('express');
const router = express.Router({mergeParams:true});
const bcrypt = require('bcrypt');
const randToken = require('rand-token');
const DEBUG = false;
router.param('durationId', function(req, res, next, id) {
req.durationId = id;
let query = " Select rezept_dauer.id, dauer, name, sort, beschreibung "+
" FROM rezept_dauer "+
" WHERE rezept =$1 AND rezept_dauer.id = $2";
if(DEBUG) console.log(query);
req.db.query(query, [req.recepieId, req.durationId], (err, rs) => {
if (err) {
return next(err)
}
req.recepieDuration = rs.rows[0];
next();
})
});
/* GET recepieDurations listing. */
router.get('/', function(req, res, next) {
let query = " Select rezept_dauer.id, dauer, name, sort, beschreibung "+
" FROM rezept_dauer "+
" WHERE rezept =$1";
if(DEBUG) console.log(query);
req.db.query(query,[req.recepieId], (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieDurations'] = rs.rows;
console.log(result);
res.status(200).json(result);
}
});
});
router.post('/', function(req, res, next) {
let recepieDuration = req.body.recepieDurations[0];
if(!recepieDuration.dauer || !recepieDuration.name || !recepieDuration.sort) {
return res.status(400).send("Wrong Params")
}
let query = "INSERT INTO rezept_dauer (rezept, dauer, name, sort, beschreibung) "+
" VALUES ($1, $2, $3, $4, $5)" +
" returning *";
let values = [req.recepieId, recepieDuration.dauer, recepieDuration.name, recepieDuration.sort, recepieDuration.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieDurations'] = rs.rows[0];
res.status(200).json(result);
}
});
});
/* Methods with id */
router.get('/:durationId', function(req, res, next) {
res.status(200).json(req.recepieDuration);
});
router.put('/:durationId', function(req, res, next) {
let recepieDuration = req.body.recepieDurations[0];
let query = "UPDATE rezept_dauer set name = $1, dauer = $2, sort =$3, beschreibung =$4"+
" WHERE id = "+req.durationId +
" returning *";
let values = [recepieDuration.name, recepieDuration.dauer, recepieDuration.sort, recepieDuration.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieDurations'] = rs.rows[0];
res.status(200).json(result);
}
});
});
router.delete('/:durationId', function(req, res, next) {
let query = "DELETE FROM rezept_dauer where id = $1;";
req.db.query(query, [req.durationId], (err, rs) => {
if (err) next(err)
});
res.status(204).send();
});
module.exports = router;

View File

@ -0,0 +1,101 @@
const express = require('express');
const router = express.Router({mergeParams:true});
const bcrypt = require('bcrypt');
const randToken = require('rand-token');
const DEBUG = false;
router.param('ingredientId', function(req, res, next, id) {
req.ingredientId = id;
let query = " Select rezept_zutat.id, rezept, einheit, einheit.name as einheitname, einheit.schluessel as einheitschluessel , zutat, zutat.name as zutatname, menge "+
" FROM rezept_zutat "+
" JOIN zutat on zutat.id = zutat "+
" JOIN einheit on einheit.id = einheit "+
" WHERE rezept =$1 AND rezept_zutat.id = $2";
if(DEBUG) console.log(query);
req.db.query(query, [req.recepieId, req.ingredientId], (err, rs) => {
if (err) {
return next(err)
}
req.recepieIngredient = rs.rows[0];
next();
})
});
/* GET recepieIngredients listing. */
router.get('/', function(req, res, next) {
let query = " Select rezept_zutat.id, rezept, einheit, einheit.name as einheitname, einheit.schluessel as einheitschluessel , zutat, zutat.name as zutatname, menge "+
" FROM rezept_zutat "+
" JOIN zutat on zutat.id = zutat "+
" JOIN einheit on einheit.id = einheit "+
" WHERE rezept =$1";
if(DEBUG) console.log(query);
req.db.query(query,[req.recepieId], (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieIngredients'] = rs.rows;
console.log(result);
res.status(200).json(result);
}
});
});
router.post('/', function(req, res, next) {
let recepieIngredient = req.body.recepieIngredients[0];
if(!recepieIngredient.zutat || !recepieIngredient.einheit || !recepieIngredient.menge) {
return res.status(400).send("Wrong Params")
}
let query = "INSERT INTO rezept_zutat (rezept, menge, einheit, zutat, beschreibung) "+
" VALUES ($1, $2, $3, $4, $5)" +
" returning *";
let values = [req.recepieId, recepieIngredient.menge, recepieIngredient.einheit, recepieIngredient.zutat, recepieIngredient.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieIngredients'] = rs.rows[0];
res.status(200).json(result);
}
});
});
/* Methods with id */
router.get('/:ingredientId', function(req, res, next) {
res.status(200).json(req.recepieIngredient);
});
router.put('/:ingredientId', function(req, res, next) {
let recepieIngredient = req.body.recepieIngredients[0];
let query = "UPDATE rezept_zutat set menge = $1, einheit = $2, zutat =$3, beschreibung =$4"+
" WHERE id = "+req.ingredientId +
" returning *";
let values = [recepieIngredient.menge, recepieIngredient.einheit, recepieIngredient.zutat, recepieIngredient.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieIngredients'] = rs.rows[0];
res.status(200).json(result);
}
});
});
router.delete('/:ingredientId', function(req, res, next) {
let query = "DELETE FROM rezept_zutat where id = $1;";
req.db.query(query, [req.ingredientId], (err, rs) => {
if (err) next(err)
});
res.status(204).send();
});
module.exports = router;

97
routes/recepieStep.js Normal file
View File

@ -0,0 +1,97 @@
const express = require('express');
const router = express.Router({mergeParams:true});
const bcrypt = require('bcrypt');
const randToken = require('rand-token');
const DEBUG = false;
router.param('stepId', function(req, res, next, id) {
req.stepId = id;
let query = " Select rezept_schritt.id, dauer, name, sort, beschreibung "+
" FROM rezept_schritt "+
" WHERE rezept =$1 AND rezept_schritt.id = $2";
if(DEBUG) console.log(query);
req.db.query(query, [req.recepieId, req.stepId], (err, rs) => {
if (err) {
return next(err)
}
req.recepieStep = rs.rows[0];
next();
})
});
/* GET recepieSteps listing. */
router.get('/', function(req, res, next) {
let query = " Select rezept_schritt.id, dauer, name, sort, beschreibung "+
" FROM rezept_schritt "+
" WHERE rezept =$1";
if(DEBUG) console.log(query);
req.db.query(query,[req.recepieId], (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieSteps'] = rs.rows;
console.log(result);
res.status(200).json(result);
}
});
});
router.post('/', function(req, res, next) {
let recepieStep = req.body.recepieSteps[0];
if(!recepieStep.dauer || !recepieStep.name || !recepieStep.sort) {
return res.status(400).send("Wrong Params")
}
let query = "INSERT INTO rezept_schritt (rezept, dauer, name, sort, beschreibung) "+
" VALUES ($1, $2, $3, $4, $5)" +
" returning *";
let values = [req.recepieId, recepieStep.dauer, recepieStep.name, recepieStep.sort, recepieStep.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieSteps'] = rs.rows[0];
res.status(200).json(result);
}
});
});
/* Methods with id */
router.get('/:stepId', function(req, res, next) {
res.status(200).json(req.recepieStep);
});
router.put('/:stepId', function(req, res, next) {
let recepieStep = req.body.recepieSteps[0];
let query = "UPDATE rezept_schritt set name = $1, dauer = $2, sort =$3, beschreibung =$4"+
" WHERE id = "+req.stepId +
" returning *";
let values = [recepieStep.name, recepieStep.dauer, recepieStep.sort, recepieStep.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieSteps'] = rs.rows[0];
res.status(200).json(result);
}
});
});
router.delete('/:stepId', function(req, res, next) {
let query = "DELETE FROM rezept_schritt where id = $1;";
req.db.query(query, [req.stepId], (err, rs) => {
if (err) next(err)
});
res.status(204).send();
});
module.exports = router;

103
routes/recepieTools.js Normal file
View File

@ -0,0 +1,103 @@
const express = require('express');
const router = express.Router({mergeParams:true});
const bcrypt = require('bcrypt');
const randToken = require('rand-token');
const DEBUG = false;
router.param('toolId', function(req, res, next, id) {
req.toolId = id;
let query = " Select rezept_geraet.id, rezept, einheit, einheit.name as einheitname, einheit.schluessel as einheitschluessel ,"+
" geraet, geraet.name as geraetname, menge, rezept_geraet.beschreibung "+
" FROM rezept_geraet "+
" JOIN geraet on geraet.id = geraet "+
" JOIN einheit on einheit.id = einheit "+
" WHERE rezept =$1 AND rezept_geraet.id = $2";
if(DEBUG) console.log(query);
req.db.query(query, [req.recepieId, req.toolId], (err, rs) => {
if (err) {
return next(err)
}
req.recepieTool = rs.rows[0];
next();
})
});
/* GET recepieTools listing. */
router.get('/', function(req, res, next) {
let query = " Select rezept_geraet.id, rezept, einheit, einheit.name as einheitname, einheit.schluessel as einheitschluessel , "+
" geraet, geraet.name as geraetname, menge, rezept_geraet.beschreibung "+
" FROM rezept_geraet "+
" JOIN geraet on geraet.id = geraet "+
" JOIN einheit on einheit.id = einheit "+
" WHERE rezept =$1";
if(DEBUG) console.log(query);
req.db.query(query,[req.recepieId], (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieTools'] = rs.rows;
console.log(result);
res.status(200).json(result);
}
});
});
router.post('/', function(req, res, next) {
let recepieTool = req.body.recepieTools[0];
if(!recepieTool.geraet || !recepieTool.einheit || !recepieTool.menge) {
return res.status(400).send("Wrong Params")
}
let query = "INSERT INTO rezept_geraet (rezept, menge, einheit, geraet, beschreibung) "+
" VALUES ($1, $2, $3, $4, $5)" +
" returning *";
let values = [req.recepieId, recepieTool.menge, recepieTool.einheit, recepieTool.geraet, recepieTool.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieTools'] = rs.rows[0];
res.status(200).json(result);
}
});
});
/* Methods with id */
router.get('/:toolId', function(req, res, next) {
res.status(200).json(req.recepieTool);
});
router.put('/:toolId', function(req, res, next) {
let recepieTool = req.body.recepieTools[0];
let query = "UPDATE rezept_geraet set menge = $1, einheit = $2, geraet =$3, beschreibung =$4"+
" WHERE id = "+req.toolId +
" returning *";
let values = [recepieTool.menge, recepieTool.einheit, recepieTool.geraet, recepieTool.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['recepieTools'] = rs.rows[0];
res.status(200).json(result);
}
});
});
router.delete('/:toolId', function(req, res, next) {
let query = "DELETE FROM rezept_geraet where id = $1;";
req.db.query(query, [req.toolId], (err, rs) => {
if (err) next(err)
});
res.status(204).send();
});
module.exports = router;

162
routes/users.js Normal file
View File

@ -0,0 +1,162 @@
const express = require('express');
const router = express.Router();
const bcrypt = require('bcrypt');
const DEBUG = false;
router.param('userId', function(req, res, next, id) {
req.userId = id;
let query = "Select id, name, email, kennwort, beschreibung FROM nutzer WHERE id ="+req.userId;
if(isNaN(req.userId)) query = "Select id, name, email, kennwort, beschreibung FROM nutzer WHERE email ilike '"+req.userId+"'";
if(DEBUG) console.log(query);
req.db.query(query, (err, rs) => {
if (err) {
return next(err)
}
req.user = rs.rows[0];
next();
})
});
/* GET users listing. */
router.get('/', function(req, res, next) {
let query = "Select id, name, email, beschreibung FROM nutzer ";
if(DEBUG) console.log(query);
req.db.query(query, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
result['users'] = rs.rows;
console.log(result);
res.status(200).json(result);
}
});
});
router.post('/', function(req, res, next) {
let user = req.body.users[0];
bcrypt.hash(user.kennwort, 10, function(err, hash) {
let query = "INSERT INTO nutzer ( name, email, kennwort, beschreibung) "+
" VALUES ('"+user.name+"','"+user.email+"','"+hash+"','"+user.beschreibung+"')" +
" returning *";
if(DEBUG) console.log(query);
req.db.query(query, (err, rs) => {
if(err && err.constraint && err.constraint ==='idx_nutzer_email') {
return res.status(409).send("Email-adress already in use");
} else if (err){
next(err);
} else {
let result = {};
let user = {};
user['name'] = rs.rows[0].name;
user['email'] = rs.rows[0].email;
user['id'] = rs.rows[0].id;
user['beschreibung'] = rs.rows[0].beschreibung;
result['users'] = user;
res.status(200).json(result);
}
});
});
});
/* Methods with id */
router.get('/:userId', function(req, res, next) {
let user = {};
let result = {};
user['name'] = req.user.name;
user['email'] = req.user.email;
user['id'] = req.user.id;
user['beschreibung'] = req.user.beschreibung;
result['users'] = user;
res.status(200).json(result);
});
router.put('/:userId', function(req, res, next) {
let user = req.body.users[0];
let query = "UPDATE nutzer set name = '"+user.name+"', email='"+user.email+"', beschreibung = '"+user.beschreibung+"' "+
" WHERE id = "+req.userId +
" returning *";
if(DEBUG) console.log(query);
req.db.query(query, (err, rs) => {
if(err && err.constraint && err.constraint ==='idx_nutzer_email') {
return res.status(409).send("Email-adress already in use");
} else if (err){
next(err);
} else {
let result = {};
let user = {};
user['name'] = rs.rows[0].name;
user['email'] = rs.rows[0].email;
user['id'] = rs.rows[0].id;
user['beschreibung'] = rs.rows[0].beschreibung;
result['users'] = user;
res.status(200).json(result);
}
});
});
router.put('/:userId/changepasswd', function(req, res, next) {
let user = req.body.users[0];
let oldPasswd = req.body.users[0]['oldPasswd'];
let newPasswd = req.body.users[0]['newPasswd'];
if(!oldPasswd || !newPasswd) {
return res.status(400).send("Wrong Params");
}
bcrypt.compare(oldPasswd, req.user.kennwort, function(err, checkResult) {
console.log("Compare: "+oldPasswd+" WITH "+req.user.kennwort+" Result:");
console.log(checkResult);
if(checkResult) {
bcrypt.hash('myPassword', 10, function(err, hash) {
let query = "UPDATE nutzer set kennwort = '"+hash+"'"+
" WHERE id = "+req.userId +
" returning *";
req.db.query(query, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
let user = {};
user['name'] = rs.rows[0].name;
user['email'] = rs.rows[0].email;
user['id'] = rs.rows[0].id;
user['beschreibung'] = rs.rows[0].beschreibung;
result['users'] = user;
console.log(result);
res.status(200).json(result);
}
});
});
} else {
console.log(err);
res.status(409).send("Old Passwd didn't match");
}
});
});
router.delete('/:userId', function(req, res, next) {
let query = [
"DELETE FROM nutzer_favorit where nutzer = $1;",
"DELETE FROM nutzer_kommentar where nutzer = $1;",
"DELETE FROM nutzer_rolle where nutzer = $1;",
"DELETE FROM nutzer where id = $1;"
];
for(let i = 0; i< query.length; i++) {
req.db.query(query[i], [req.userId], (err, rs) => {
if (err) next(err)
});
}
res.status(204).send();
});
module.exports = router;

68
routes/valuelist.js Normal file
View File

@ -0,0 +1,68 @@
var express = require('express');
var router = express.Router();
const { selectAllFromTable,
selectAllFromTableByFieldValue,
deleteItemFromTable,
updateNameKeyObject,
insertNameKeyObject,
deleteNameKeyObject,
getAllFromTable,
getStructure} = require('./../db/');
router.param('id', function(req, res, next, id) {
req.itemId = id;
console.log(req.body);
let structure = getStructure(req);
req[structure.jsonName] = req.body;
next();
});
router.param('path', function(req, res, next, id) {
let test = id;
req.pathCall = test.replace(/\//g,"");
next();
});
/* GET users listing. */
router.get('/:path', function(req, res, next) {
getAllFromTable(req, res, next)
});
router.put('/:path/:id', function(req, res, next) {
console.log("Update WL");
updateNameKeyObject(req, res, next)
});
router.post('/:path', function(req, res, next) {
console.log("Insert WL");
insertNameKeyObject(req, res, next)
});
router.delete('/:path/:id', function(req, res, next) {
console.log("Delete WL");
deleteNameKeyObject(req, res, next)
});
router.post('/', function(req, res, next) {
res.send('CreateUser');
});
/* Methods with id */
router.get('/:userId', function(req, res, next) {
res.send(req.user);
});
router.put('/:userId', function(req, res, next) {
res.send('Update a User');
});
router.delete('/:userId', function(req, res, next) {
res.send('Delete User');
});
module.exports = router;

144
seed.js Normal file
View File

@ -0,0 +1,144 @@
const db = require('./db')
let defaultZutaten = [
"Mehl",
"Zucker",
"Milch",
"Wasser",
"Rotwein",
"Weißwein",
"Gemüsebrühe",
"Puderzucker",
"Vanillezucker",
"Salz",
"Pfeffer",
"Paprika",
"Kräuter der Provence",
"Basilikum",
"Weißbrot",
"Kartoffeln",
"Kartoffeln (mehlig)",
"Kartoffeln (festkochend)",
"Reis",
"Nudeln",
"Kroketten",
"Spätzle",
"Hähnchenbrustfilet",
"Putenschnitzel",
"Rindfleisch",
"Kalbfleisch",
"Rindersteak",
"Rinderhackfleisch",
"Hackfleisch gemischt",
"Schweineschnitzel",
"Schweinekotelett",
"Ente",
"Gans",
"Käse",
"Frischkäse",
"Kräuterquark",
"Quark",
"Mozzarella",
"Parmesan",
"Speisequark (40 % Fett)",
"Camembert",
"Gouda",
"Edamer",
"Raclette",
"Mascarpone",
"Schinken (gekocht)",
"Schinken (roh)",
"Schinken (geräuchert)",
"Salami",
"Oliven schwarz",
"Butter",
"Butterschmalz",
"Olivenöl",
"Rapsöl",
"Sonnenblumenöl",
"Margarine",
"Honig",
"Marmelade",
"Konfitüre",
"Nussnougatcreme",
"Eier",
"Joghurt, 1,5 % Fett",
"Joghurt, 3,5 % Fett",
"Seelachs",
"Zander",
"Kabeljau",
"Garnelen",
"Krabben",
"Forelle",
"Makrele",
"Lachs",
"Lachs (geräuchert)",
"Heringsfilet",
"passierte Tomaten",
"Saure Sahne",
"Pesto (rot)",
"Pesto (grün)",
"Mayonnaise",
"Sahne",
"Crème fraiche",
"Nüsse",
"Mandeln",
"Apfelmus",
"Preiselbeeren",
"Schokolade (Vollmilch)",
"Schokolade (Zartbitter)",
"Kuvertüre (Vollmilch)",
"Kuvertüre (Zartbitter)",
"Marzipan",
"Hefe"
];
let defaultSchwierigkeiten = [
"leicht",
"mittel",
"anspruchsvoll"
];
let defaultWertungskategorien = [
{ "name":"Gesamtwertung",
"schluessel":"sum"},
{ "name":"Kosten",
"schluessel":"kosten"}
];
const makeKey = (input) => {
let result = input.toLowerCase();
result = result.replace(/[\(\)]/g,"");
result = result.replace(/[%,. ]/g,"_");
return result;
//console.log(result);
}
for(let i = 0; i<defaultSchwierigkeiten.length; i++) {
let query = "INSERT INTO schwierigkeit (name, schluessel) "+
"VALUES ($1, $2) returning *";
db.query(query, [defaultSchwierigkeiten[i], makeKey(defaultSchwierigkeiten[i])], (err, rs) => {
console.log(err);
})
}
for(let i = 0; i<defaultWertungskategorien.length; i++) {
let query = "INSERT INTO wertungkategorie (name, schluessel) "+
"VALUES ($1, $2) returning *";
db.query(query, [defaultWertungskategorien[i]['name'], makeKey(defaultWertungskategorien[i]['schluessel'])], (err, rs) => {
console.log(err);
})
}
for(let i = 0; i<defaultZutaten.length; i++) {
let query = "INSERT INTO zutat (name, schluessel) "+
"VALUES ($1, $2) returning *";
db.query(query, [defaultZutaten[i], makeKey(defaultZutaten[i])], (err, rs) => {
console.log(err);
})
}

30
server.js Normal file
View File

@ -0,0 +1,30 @@
// codecademy Project Cap2
const express = require('express');
const morgan = require('morgan');
const cors = require('cors');
const sqlite3 = require('sqlite3');
const errorhandler = require('errorhandler');
const bodyParser = require('body-parser');
const apiRouter = require('./api/api');
const DEBUG = true;
const PORT = process.env.PORT || 4000;
const app = express();
app.use(bodyParser.json());
app.use(morgan('tiny'));
app.use(cors());
app.use('/api', apiRouter);
app.use(errorhandler());
// INIT server
app.listen(PORT, ()=> {
console.log('Server listening on PORT '+PORT);
})
module.exports = app;

6
views/error.pug Normal file
View File

@ -0,0 +1,6 @@
extends layout
block content
h1= message
h2= error.status
pre #{error.stack}

5
views/index.pug Normal file
View File

@ -0,0 +1,5 @@
extends layout
block content
h1= title
p Welcome to #{title}

7
views/layout.pug Normal file
View File

@ -0,0 +1,7 @@
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content

76
zutatenliste.sql Normal file
View File

@ -0,0 +1,76 @@
Weißbrot
Kartoffeln
Kartoffeln (mehlig)
Kartofflen (festkochend)
Reis
Nudeln
Kroketten
Spätzle
Hähnchenbrustfilet
Putenschnitzel
Rindfleisch
Kalbfleisch
Rindersteak
Rinderhackfleisch
Hackfleisch gemischt
Schweineschnitzel
Schweinekotelett
Ente
Gans
Käse
Frischkäse
Kräuterquark
Quark
Mozzarella
Parmesan
Speisequark (40 % Fett)
Camembert
Gouda
Edamer
Raclette
Mascarpone
Schinken (gekocht)
Schinken (roh)
Schinken (geräuchert)
Salami
Oliven schwarz
Butter
Butterschmalz
Olivenöl
Rapsöl
Sonnenblumenöl
Margarine
Honig
Marmelade
Konfitüre
Nussnougatcreme
Eier
Joghurt, 1,5 % Fett
Joghurt, 3,5 % Fett
Seelachs
Zander
Kabeljau
Garnelen
Krabben
Forelle
Makrele
Lachs
Lachs (geräuchert)
Heringsfilet
passierte Tomaten
Saure Sahne
Pesto (rot)
Pesto (grün)
Mayonnaise
Sahne
Crème fraiche
Nüsse
Mandeln
Apfelmus
Preiselbeeren
Schokolade (Vollmilch)
Schokolade (Zartbitter)
Kuvertüre (Vollmilch)
Kuvertüre (Zartbitter)
Marzipan
Hefe