diff --git a/.gitignore b/.gitignore index 3c3629e..8b8c4cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +uploads diff --git a/migration.js b/migration.js index 27944a9..963cce5 100644 --- a/migration.js +++ b/migration.js @@ -7,7 +7,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS zutat" + " schluessel text NOT NULL," + " name text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS einheit" + @@ -16,7 +16,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS einheit" + " schluessel text NOT NULL," + " name text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS geraet" + @@ -25,7 +25,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS geraet" + " schluessel text NOT NULL," + " name text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS kategorie" + @@ -34,7 +34,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS kategorie" + " schluessel text NOT NULL," + " name text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS wertungkategorie" + @@ -43,7 +43,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS wertungkategorie" + " schluessel text NOT NULL," + " name text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS schwierigkeit" + @@ -52,7 +52,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS schwierigkeit" + " schluessel text NOT NULL," + " name text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS rezept" + @@ -64,7 +64,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS rezept" + " 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" + @@ -75,7 +75,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS rezept_dauer" + " name text NOT NULL," + " sort INT NOT NULL DEFAULT 0," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS rezept_zutat" + @@ -86,7 +86,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS rezept_zutat" + " zutat bigint NOT NULL REFERENCES zutat(id)," + " menge NUMERIC," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS rezept_geraet" + @@ -97,7 +97,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS rezept_geraet" + " geraet bigint NOT NULL REFERENCES geraet(id)," + " menge NUMERIC," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS rezept_schritt" + @@ -107,7 +107,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS rezept_schritt" + " sort INT NOT NULL DEFAULT 0," + " name text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS rezept_kategorie" + @@ -117,7 +117,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS rezept_kategorie" + " kategorie bigint NOT NULL REFERENCES kategorie(id)," + " modifikator NUMERIC NOT NULL DEFAULT 1," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS nutzer" + @@ -127,7 +127,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS nutzer" + " email text NOT NULL," + " kennwort text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS rolle" + @@ -136,7 +136,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS rolle" + " schluessel text NOT NULL," + " name text NOT NULL," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_rolle" + @@ -145,7 +145,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_rolle" + " nutzer bigint NOT NULL REFERENCES nutzer(id)," + " rolle bigint NOT NULL REFERENCES rolle(id)," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_favorit" + @@ -154,7 +154,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_favorit" + " nutzer bigint NOT NULL REFERENCES nutzer(id)," + " rezept bigint NOT NULL REFERENCES rezept(id)," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS rezept_wertung" + @@ -165,7 +165,7 @@ db.run("CREATE TABLE" +" IF NOT EXISTS rezept_wertung" + " wertungkategorie bigint NOT NULL REFERENCES wertungkategorie(id)," + " wert INTEGER NOT NULL DEFAULT 5," + " beschreibung text" + -" );" + +" );" ); db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_kommentar" + @@ -175,17 +175,26 @@ db.run("CREATE TABLE" +" IF NOT EXISTS nutzer_kommentar" + " relation text NOT NULL," + " relation_id bigint NOT NULL," + " beschreibung text" + +" );" ); +db.run("CREATE TABLE" +" IF NOT EXISTS rezept_image" + + " (" + + " id bigserial PRIMARY KEY," + + " rezept bigint NOT NULL REFERENCES rezept(id)," + + " pfad text NOT NULL," + + " dateiname text NOT NULL," + + " lizenz text NOT NULL," + + " uploadtime timestamp NOT NULL default current_timestamp," + + " beschreibung text" + + " );" + ); + 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);")" - - - ); +db.run("CREATE UNIQUE INDEX idx_wertungkategorie_email ON wertungkategorie (schluessel);"); }; diff --git a/package-lock.json b/package-lock.json index 70edf2b..432803f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -120,6 +120,11 @@ "normalize-path": "^2.1.1" } }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -1822,6 +1827,11 @@ "isarray": "^1.0.0" } }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, "buffer-writer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", @@ -1844,6 +1854,38 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -2035,6 +2077,17 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "connect-pg-simple": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/connect-pg-simple/-/connect-pg-simple-5.0.0.tgz", @@ -2334,6 +2387,38 @@ "repeating": "^2.0.0" } }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "diffie-hellman": { "version": "5.0.3", "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -4484,6 +4569,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multer": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", + "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", + "requires": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + } + }, "nan": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", @@ -6055,6 +6155,11 @@ "xtend": "^4.0.0" } }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "string-width": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -6248,6 +6353,11 @@ "mime-types": "~2.1.18" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "ua-parser-js": { "version": "0.7.19", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", diff --git a/package.json b/package.json index 54abec8..2fb6eef 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "express-session": "^1.15.6", "http-errors": "~1.6.2", "morgan": "~1.9.0", + "multer": "^1.4.2", "node-sass-middleware": "0.11.0", "passport-local": "^1.0.0", "pg": "^7.7.1", diff --git a/routes/recepie.js b/routes/recepie.js index d154cb5..732feaf 100644 --- a/routes/recepie.js +++ b/routes/recepie.js @@ -11,6 +11,7 @@ const toolsRouter = require('./recepieTools'); const durationsRouter = require('./recepieDurations'); const stepsRouter = require('./recepieSteps'); const categoriesRouter = require('./recepieCategories'); +const voteRouter = require('./recepieVote'); const DEBUG = false; @@ -51,6 +52,7 @@ router.use('/:recepieId/tools/', toolsRouter); router.use('/:recepieId/durations/', durationsRouter); router.use('/:recepieId/steps/', stepsRouter); router.use('/:recepieId/categories/', categoriesRouter); +router.use('/:recepieId/votes/', voteRouter); /* GET recepies listing. */ diff --git a/routes/recepieImage.js b/routes/recepieImage.js new file mode 100644 index 0000000..db3db86 --- /dev/null +++ b/routes/recepieImage.js @@ -0,0 +1,125 @@ +const express = require('express'); +const router = express.Router({mergeParams:true}); +const multer = require('multer'); +const storage = multer.diskStorage({ + destination: function(req, file, cb) { + cb(null, './uploads/'); + }, + filename: function(req, file, cb) { + cb(null, file.filename); + } +}) +const fileFilter = (req, file, cb) => { + if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') { + cb(null, true); + } else { + cb(null, false); + } +} +const upload = multer({ + storage:storage, + limits: { + fileSize: 1024 * 1024 * 2 + }, + fileFilter:fileFilter +}) + +const bcrypt = require('bcrypt'); +const randToken = require('rand-token'); + +const DEBUG = false; + +router.param('categorieId', function(req, res, next, id) { + req.categorieId = id; + let query = " Select rezept_kategorie.id, kategorie, kategorie.name as kategoriename, modifikator, rezept_kategorie.beschreibung "+ + " FROM rezept_kategorie "+ + " JOIN kategorie on kategorie = kategorie.id"+ + " WHERE rezept =$1 AND rezept_kategorie.id = $2"; + if(DEBUG) console.log(query); + req.db.query(query, [req.recepieId, req.categorieId], (err, rs) => { + if (err) { + return next(err) + } + req.recepieCategorie = rs.rows[0]; + next(); + }) +}); + +/* GET recepieCategories listing. */ +router.get('/', function(req, res, next) { + let query = " Select rezept_kategorie.id, kategorie, kategorie.name as kategoriename, modifikator, rezept_kategorie.beschreibung "+ + " FROM rezept_kategorie "+ + " JOIN kategorie on kategorie = kategorie.id"+ + " WHERE rezept =$1"+ + " ORDER BY modifikator"; + if(DEBUG) console.log(query); + req.db.query(query,[req.recepieId], (err, rs) => { + if (err){ + next(err); + } else { + let result = {}; + result['recepieCategories'] = rs.rows; + if (DEBUG) console.log(result); + res.status(200).json(result); + } + }); +}); + +router.post('/', function(req, res, next) { + let recepieCategorie = req.body.recepieCategories[0]; + if(!recepieCategorie.kategorie) { + return res.status(400).send("Wrong Params") + } + + if (!recepieCategorie.modifikator) recepieCategorie.modifikator = 1; + let query = "INSERT INTO rezept_kategorie (rezept, kategorie, modifikator, beschreibung) "+ + " VALUES ($1, $2, $3, $4)" + + " returning *"; + let values = [req.recepieId, recepieCategorie.kategorie, recepieCategorie.modifikator, recepieCategorie.beschreibung]; + + if(DEBUG) console.log(query); + + req.db.query(query, values, (err, rs) => { + if (err){ + next(err); + } else { + let result = {}; + result['recepieCategories'] = rs.rows[0]; + res.status(200).json(result); + } + }); +}); + +/* Methods with id */ +router.get('/:categorieId', function(req, res, next) { + res.status(200).json(req.recepieCategorie); +}); + +router.put('/:categorieId', function(req, res, next) { + let recepieCategorie = req.body.recepieCategories[0]; + let query = "UPDATE rezept_kategorie set kategorie = $1, modifikator =$2, beschreibung =$3"+ + " WHERE id = "+req.categorieId + + " returning *"; + let values = [recepieCategorie.kategorie, recepieCategorie.modifikator, recepieCategorie.beschreibung]; + + if(DEBUG) console.log(query); + req.db.query(query, values, (err, rs) => { + if (err){ + next(err); + } else { + let result = {}; + result['recepieCategories'] = rs.rows[0]; + res.status(200).json(result); + } + }); +}); + +router.delete('/:categorieId', function(req, res, next) { + let query = "DELETE FROM rezept_kategorie where id = $1;"; + req.db.query(query, [req.categorieId], (err, rs) => { + if (err) next(err) + }); + res.status(204).send(); +}); + +module.exports = router; diff --git a/routes/recepieVote.js b/routes/recepieVote.js new file mode 100644 index 0000000..46ad272 --- /dev/null +++ b/routes/recepieVote.js @@ -0,0 +1,60 @@ +const express = require('express'); +const router = express.Router({mergeParams:true}); + +const bcrypt = require('bcrypt'); +const randToken = require('rand-token'); + +const DEBUG = true; + + +/* GET recepieVotes listing. */ +router.get('/', function(req, res, next) { + let query = "SELECT avg(wert) as wertung FROM rezept_wertung WHERE rezept = $1"; + let values = [req.recepieId]; + + + req.db.query(query, values, (err, rs) => { + if (err){ + next(err); + } else { + let result = {}; + result['recepieVotes'] = rs.rows[0]; + res.status(200).json(result); + } + }); +}); + +router.post('/', function(req, res, next) { + let recepieVote = req.body.recepieVote[0]; + if(!recepieVote.wert) { + return res.status(400).send("Wrong Params") + } + + if (!recepieVote.nutzer) recepieVote.nutzer = 0; + let query = "INSERT INTO rezept_wertung (rezept, wertungkategorie, nutzer, wert, beschreibung) "+ + " VALUES ($1, (SELECT id from wertungkategorie where schluessel = 'sum'), $2, $3, $4)"; + let values = [req.recepieId, recepieVote.nutzer, recepieVote.wert, recepieVote.beschreibung]; + if(DEBUG) console.log(query); +req.db.query(query, values, (err, rs) => { + if (err) { + next(err); + } else { + query = "SELECT avg(wert) as wertung FROM rezept_wertung WHERE rezept = $1"; + values = [req.recepieId]; + + + req.db.query(query, values, (err, rs) => { + if (err){ + next(err); + } else { + let result = {}; + result['recepieVotes'] = rs.rows[0]; + res.status(200).json(result); + } + }); + } +}); + +}); + +module.exports = router; diff --git a/routes/valuelist.js b/routes/valuelist.js index 14462ef..3345319 100644 --- a/routes/valuelist.js +++ b/routes/valuelist.js @@ -1,6 +1,7 @@ var express = require('express'); var router = express.Router(); +const DEBUG = true; const { selectAllFromTable, selectAllFromTableByFieldValue,