├── .gitignore ├── LICENSE ├── README.md ├── Unit 1 - Welcome ├── U1-M2-helloworld │ └── helloworld.js └── U1-M5-randomnumber │ ├── index.js │ ├── package-lock.json │ └── package.json ├── Unit 2 - Nodejs On The Command Line ├── U2-M1-helloyou │ ├── index.js │ ├── numbers.js │ └── package.json ├── U2-M2-files │ ├── create.js │ ├── createanddelete-1.js │ ├── createanddelete-2.js │ ├── createanddeletesync.js │ ├── delete.js │ ├── index.js │ ├── package.json │ └── readdir.js ├── U2-M3-files │ ├── hellofile-1.js │ ├── hellofile-2.js │ └── hellofile-3.js ├── U2-M4-chuck │ ├── chuck.txt │ ├── chuck1.js │ ├── chuck2.js │ └── chuck3.js ├── U2-M5-chuck │ ├── chuck.txt │ ├── chuck3.js │ └── runchuck.js ├── U2-M6-weather │ ├── index.js │ └── package.json ├── U2-M7-weather │ ├── index.js │ ├── package-lock.json │ └── package.json └── U2-M8-async │ ├── 1.txt │ ├── 2.txt │ ├── 3.txt │ ├── 4.txt │ ├── 5.txt │ ├── readfiles1.js │ ├── readfiles2.js │ ├── readfiles3-1.js │ └── readfiles3-2.js ├── Unit 3 - Building Web Applications With Node ├── U3-M1-httpserver │ ├── index.js │ ├── package-lock.json │ └── package.json ├── U3-M2-httpfileserver │ ├── files │ │ ├── cat1.jpg │ │ ├── cat2.jpg │ │ ├── cat3.jpg │ │ ├── cat4.jpg │ │ ├── cat5.jpg │ │ └── index.html │ ├── httpfileserver.js │ ├── package-lock.json │ └── package.json ├── U3-M3-M4-numbers │ ├── form.html │ ├── index-1.js │ ├── index-2.js │ ├── index-3.js │ ├── index.js │ ├── package-lock.json │ ├── package.json │ └── results.html ├── U3-M5-numbers │ ├── form.html │ ├── index-1.js │ ├── index.js │ ├── package-lock.json │ ├── package.json │ └── results.ejs ├── U3-M7-pugplay │ ├── index.js │ ├── package-lock.json │ ├── package.json │ └── templates │ │ ├── body.pug │ │ ├── index.pug │ │ └── layout.pug ├── U3-M7-trypug │ ├── form.html │ ├── form.pug │ ├── index.js │ ├── package-lock.json │ ├── package.json │ ├── page.html │ └── page.pug └── U3-M8-helloworld │ ├── chuck.js │ ├── chuck.txt │ ├── index-1.js │ ├── index-1.pug │ ├── index-2.js │ ├── index.js │ ├── index.pug │ ├── layout.pug │ ├── package-lock.json │ ├── package.json │ └── style.css ├── Unit 4 - Databases ├── U4-M1-trysqlite │ ├── index.js │ ├── package-lock.json │ ├── package.json │ └── seed.js ├── U4-M2-crud │ ├── delete.js │ ├── index.js │ ├── migrate.js │ ├── migration.js │ ├── package-lock.json │ ├── package.json │ └── update.js ├── U4-M3-trysequelize │ ├── delete.js │ ├── index.js │ ├── migration.js │ ├── package-lock.json │ ├── package.json │ ├── update.js │ └── users.sqlite ├── U4-M4-trymongodb │ ├── delete.js │ ├── index.js │ ├── migration.js │ ├── package-lock.json │ ├── package.json │ └── update.js ├── U4-M5-moresequelize │ ├── config │ │ └── config.json │ ├── index.js │ ├── migrations │ │ └── 20171121112949-create-users.js │ ├── models │ │ ├── index.js │ │ └── users.js │ ├── package-lock.json │ ├── package.json │ └── seeders │ │ └── 20171121113025-users.js └── U4-M6-helloworld │ ├── config │ └── config.json │ ├── index.js │ ├── migrations │ ├── create_Fonts.js │ ├── create_Translations.js │ └── create_Users.js │ ├── models │ ├── Font.js │ ├── Translation.js │ ├── User.js │ └── index.js │ ├── package-lock.json │ ├── package.json │ └── seeders │ ├── seed_Fonts.js │ ├── seed_Translations.js │ └── seed_Users.js ├── Unit 5 - Building Better Web Apps With Express ├── U5-M1-cheese │ ├── config │ │ └── config.json │ ├── db │ │ └── cheese.sqlite │ ├── index.js │ ├── migrations │ │ ├── 20171212112506-create-cheese.js │ │ └── 20171212132234-create-cheese.js │ ├── models │ │ ├── cheese.js │ │ └── index.js │ ├── package-lock.json │ ├── package.json │ └── seeders │ │ └── 20171212121213-cheese.js ├── U5-M10-helloworld │ ├── app.js │ ├── bin │ │ └── www │ ├── config │ │ ├── config.json │ │ └── helloworld.json │ ├── db │ │ └── hello_world.sqlite │ ├── index.js │ ├── migrations │ │ ├── 20171122120413-create-users.js │ │ ├── 20171122123812-create-fonts.js │ │ └── 20171122123855-create-translations.js │ ├── models │ │ ├── fonts.js │ │ ├── index.js │ │ ├── translations.js │ │ └── users.js │ ├── my_modules │ │ └── chuck │ │ │ ├── chuck.js │ │ │ ├── chuck.txt │ │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── images │ │ │ └── favicon.png │ │ ├── javascripts │ │ │ └── script.js │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ ├── seeders │ │ ├── seed_Fonts.js │ │ ├── seed_Translations.js │ │ └── seed_Users.js │ ├── test.js │ └── views │ │ ├── error.pug │ │ ├── index.pug │ │ ├── layout.pug │ │ ├── login.pug │ │ ├── logout.pug │ │ └── users │ │ ├── create.pug │ │ ├── form.pug │ │ ├── index.pug │ │ └── update.pug ├── U5-M11-helloworld │ ├── app.js │ ├── bin │ │ └── www │ ├── config │ │ ├── config.json │ │ └── helloworld.json │ ├── db │ │ └── hello_world.sqlite │ ├── index.js │ ├── migrations │ │ ├── 20171122120413-create-users.js │ │ ├── 20171122123812-create-fonts.js │ │ └── 20171122123855-create-translations.js │ ├── models │ │ ├── fonts.js │ │ ├── index.js │ │ ├── translations.js │ │ └── users.js │ ├── my_modules │ │ └── chuck │ │ │ ├── chuck.js │ │ │ ├── chuck.txt │ │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── images │ │ │ └── favicon.png │ │ ├── javascripts │ │ │ └── script.js │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── api.js │ │ ├── index.js │ │ └── users.js │ ├── seeders │ │ ├── seed_Fonts.js │ │ ├── seed_Translations.js │ │ └── seed_Users.js │ ├── test.js │ └── views │ │ ├── error.pug │ │ ├── index.pug │ │ ├── layout.pug │ │ ├── login.pug │ │ ├── logout.pug │ │ └── users │ │ ├── create.pug │ │ ├── form.pug │ │ ├── index.pug │ │ └── update.pug ├── U5-M2-tryexpress │ ├── app.js │ ├── bin │ │ └── www │ ├── package.json │ ├── public │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ ├── tryexpress │ │ ├── app.js │ │ ├── bin │ │ │ └── www │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ │ └── stylesheets │ │ │ │ └── style.css │ │ ├── routes │ │ │ ├── index.js │ │ │ └── users.js │ │ └── views │ │ │ ├── error.pug │ │ │ ├── index.pug │ │ │ └── layout.pug │ └── views │ │ ├── error.jade │ │ ├── index.jade │ │ └── layout.jade ├── U5-M3-helloworld │ ├── app.js │ ├── bin │ │ └── www │ ├── config │ │ └── config.json │ ├── db │ │ └── hello_world.sqlite │ ├── migrations │ │ ├── 20171122120413-create-users.js │ │ ├── 20171122123812-create-fonts.js │ │ └── 20171122123855-create-translations.js │ ├── models │ │ ├── fonts.js │ │ ├── index.js │ │ ├── translations.js │ │ └── users.js │ ├── my_modules │ │ └── chuck │ │ │ ├── chuck.js │ │ │ ├── chuck.txt │ │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ ├── seeders │ │ ├── seed_Fonts.js │ │ ├── seed_Translations.js │ │ └── seed_Users.js │ ├── test.js │ └── views │ │ ├── error.pug │ │ ├── index.pug │ │ └── layout.pug ├── U5-M4-helloworld │ ├── app.js │ ├── bin │ │ └── www │ ├── config │ │ └── config.json │ ├── db │ │ └── hello_world.sqlite │ ├── migrations │ │ ├── 20171122120413-create-users.js │ │ ├── 20171122123812-create-fonts.js │ │ └── 20171122123855-create-translations.js │ ├── models │ │ ├── fonts.js │ │ ├── index.js │ │ ├── translations.js │ │ └── users.js │ ├── my_modules │ │ └── chuck │ │ │ ├── chuck.js │ │ │ ├── chuck.txt │ │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ ├── seeders │ │ ├── seed_Fonts.js │ │ ├── seed_Translations.js │ │ └── seed_Users.js │ └── views │ │ ├── error.pug │ │ ├── index.pug │ │ └── layout.pug ├── U5-M5-helloworld │ ├── app.js │ ├── bin │ │ └── www │ ├── config │ │ ├── config.json │ │ └── helloworld.json │ ├── db │ │ └── hello_world.sqlite │ ├── migrations │ │ ├── 20171122120413-create-users.js │ │ ├── 20171122123812-create-fonts.js │ │ └── 20171122123855-create-translations.js │ ├── models │ │ ├── fonts.js │ │ ├── index.js │ │ ├── translations.js │ │ └── users.js │ ├── my_modules │ │ └── chuck │ │ │ ├── chuck.js │ │ │ ├── chuck.txt │ │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ ├── seeders │ │ ├── seed_Fonts.js │ │ ├── seed_Translations.js │ │ └── seed_Users.js │ └── views │ │ ├── error.pug │ │ ├── index.pug │ │ └── layout.pug ├── U5-M6-helloworld │ ├── app.js │ ├── bin │ │ └── www │ ├── config │ │ ├── config.json │ │ └── helloworld.json │ ├── db │ │ └── hello_world.sqlite │ ├── index.js │ ├── migrations │ │ ├── 20171122120413-create-users.js │ │ ├── 20171122123812-create-fonts.js │ │ └── 20171122123855-create-translations.js │ ├── models │ │ ├── fonts.js │ │ ├── index.js │ │ ├── translations.js │ │ └── users.js │ ├── my_modules │ │ └── chuck │ │ │ ├── chuck.js │ │ │ ├── chuck.txt │ │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.png │ │ ├── javascripts │ │ │ └── script.js │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ ├── seeders │ │ ├── seed_Fonts.js │ │ ├── seed_Translations.js │ │ └── seed_Users.js │ ├── test.js │ └── views │ │ ├── error.pug │ │ ├── index.pug │ │ └── layout.pug ├── U5-M7-helloworld │ ├── app.js │ ├── bin │ │ └── www │ ├── config │ │ ├── config.json │ │ └── helloworld.json │ ├── db │ │ └── hello_world.sqlite │ ├── index.js │ ├── migrations │ │ ├── 20171122120413-create-users.js │ │ ├── 20171122123812-create-fonts.js │ │ └── 20171122123855-create-translations.js │ ├── models │ │ ├── fonts.js │ │ ├── index.js │ │ ├── translations.js │ │ └── users.js │ ├── my_modules │ │ └── chuck │ │ │ ├── chuck.js │ │ │ ├── chuck.txt │ │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── javascripts │ │ │ └── script.js │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ ├── seeders │ │ ├── seed_Fonts.js │ │ ├── seed_Translations.js │ │ └── seed_Users.js │ └── views │ │ ├── error.pug │ │ ├── index.pug │ │ ├── layout.pug │ │ ├── login.pug │ │ └── logout.pug └── U5-M8-M9-helloworld │ ├── app.js │ ├── bin │ └── www │ ├── config │ ├── config.json │ └── helloworld.json │ ├── db │ └── hello_world.sqlite │ ├── index.js │ ├── migrations │ ├── 20171122120413-create-users.js │ ├── 20171122123812-create-fonts.js │ └── 20171122123855-create-translations.js │ ├── models │ ├── fonts.js │ ├── index.js │ ├── translations.js │ └── users.js │ ├── my_modules │ └── chuck │ │ ├── chuck.js │ │ ├── chuck.txt │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── images │ │ └── favicon.png │ ├── javascripts │ │ └── script.js │ └── stylesheets │ │ └── style.css │ ├── routes │ ├── index.js │ └── users.js │ ├── seeders │ ├── seed_Fonts.js │ ├── seed_Translations.js │ └── seed_Users.js │ ├── test.js │ └── views │ ├── error.pug │ ├── index.pug │ ├── layout.pug │ ├── login.pug │ ├── logout.pug │ └── users │ ├── create.pug │ ├── form.pug │ ├── index.pug │ └── update.pug ├── Unit 6 - WebSockets ├── U6-M2-qchat │ ├── app.js │ ├── bin │ │ └── www │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── javascripts │ │ │ └── script.js │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ ├── views │ │ ├── error.pug │ │ ├── index.pug │ │ └── layout.pug │ └── websockets.js ├── U6-M3-helloworld │ ├── app.js │ ├── bin │ │ └── www │ ├── config │ │ ├── config.json │ │ └── helloworld.json │ ├── db │ │ └── hello_world.sqlite │ ├── index.js │ ├── migrations │ │ ├── 20171122120413-create-users.js │ │ ├── 20171122123812-create-fonts.js │ │ └── 20171122123855-create-translations.js │ ├── models │ │ ├── fonts.js │ │ ├── index.js │ │ ├── translations.js │ │ └── users.js │ ├── my_modules │ │ └── chuck │ │ │ ├── chuck.js │ │ │ ├── chuck.txt │ │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── javascripts │ │ │ └── script.js │ │ └── stylesheets │ │ │ └── style.css │ ├── routes │ │ ├── api.js │ │ ├── index.js │ │ └── users.js │ ├── seeders │ │ ├── seed_Fonts.js │ │ ├── seed_Translations.js │ │ └── seed_Users.js │ ├── views │ │ ├── error.pug │ │ ├── index.pug │ │ ├── layout.pug │ │ ├── login.pug │ │ ├── logout.pug │ │ └── users │ │ │ ├── create.pug │ │ │ ├── form.pug │ │ │ ├── index.pug │ │ │ └── update.pug │ └── websockets.js └── U6-M4-helloworld │ ├── app.js │ ├── bin │ └── www │ ├── config │ ├── config.json │ └── helloworld.json │ ├── db │ └── hello_world.sqlite │ ├── index.js │ ├── migrations │ ├── 20171122120413-create-users.js │ ├── 20171122123812-create-fonts.js │ └── 20171122123855-create-translations.js │ ├── models │ ├── fonts.js │ ├── index.js │ ├── translations.js │ └── users.js │ ├── my_modules │ └── chuck │ │ ├── chuck.js │ │ ├── chuck.txt │ │ └── package.json │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── images │ │ ├── admin.png │ │ ├── jane.png │ │ ├── john.png │ │ ├── patrick.png │ │ ├── pj.png │ │ └── trish.png │ ├── javascripts │ │ └── script.js │ └── stylesheets │ │ └── style.css │ ├── routes │ ├── api.js │ ├── index.js │ └── users.js │ ├── seeders │ ├── seed_Fonts.js │ ├── seed_Translations.js │ └── seed_Users.js │ ├── views │ ├── error.pug │ ├── index.pug │ ├── layout.pug │ ├── login.pug │ ├── logout.pug │ └── users │ │ ├── create.pug │ │ ├── form.pug │ │ ├── index.pug │ │ └── update.pug │ └── websockets.js ├── Unit 7 - Node In The Real World └── U7-M5-chuckfact │ ├── chuck.js │ ├── chuck.txt │ └── index.js └── helloworld ├── app.js ├── bin └── www ├── config ├── config.json └── helloworld.json ├── db └── hello_world.sqlite ├── migrations ├── 20171122120413-create-users.js ├── 20171122123812-create-fonts.js └── 20171122123855-create-translations.js ├── models ├── fonts.js ├── index.js ├── translations.js └── users.js ├── my_modules └── chuck │ ├── chuck.js │ ├── chuck.txt │ └── package.json ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── images │ ├── admin.png │ ├── jane.png │ ├── john.png │ ├── patrick.png │ ├── pj.png │ └── trish.png ├── javascripts │ └── script.js └── stylesheets │ └── style.css ├── routes ├── api.js ├── index.js └── users.js ├── seeders ├── seed_Fonts.js ├── seed_Translations.js └── seed_Users.js ├── views ├── error.pug ├── index.pug ├── layout.pug ├── login.pug ├── logout.pug ├── ousers │ ├── create.pug │ ├── form.pug │ ├── index.pug │ └── update.pug └── users │ ├── create.pug │ ├── form.pug │ ├── index.pug │ └── update.pug └── websockets.js /README.md: -------------------------------------------------------------------------------- 1 | # Node.js-In-Action 2 | Supporting files for the Node.js In Action livevideo course from Manning 3 | 4 | ## Important 5 | To save space, dependancies are not included. Before running each project, from the code's root directory, run npm install to download required modules. For example: 6 | 7 | `$ cd "Unit 4 - Databases/U4-M1-trysqlite"` 8 | 9 | `$ npm install` 10 | 11 | 12 | ## Update: Security Vulnerability Warnings 13 | 14 | When installing modules using *npm install*, you may receive warnings about security vulnerabilities. These warnings will not stop your code working but do highlight issues 15 | that have emerged since the publication of this course. None of the code provided here is intended to be used in a production environment in any way. These vunerabilities 16 | only come in to play if others have access to the running server and/or code. 17 | -------------------------------------------------------------------------------- /Unit 1 - Welcome/U1-M2-helloworld/helloworld.js: -------------------------------------------------------------------------------- 1 | console.log('Hello, world!'); -------------------------------------------------------------------------------- /Unit 1 - Welcome/U1-M5-randomnumber/index.js: -------------------------------------------------------------------------------- 1 | // Script to pick a number between one and ten 2 | 3 | // Require the seedrandom module 4 | const seedrandom = require('seedrandom'); 5 | 6 | // Create a random number 7 | let rng = seedrandom(); 8 | 9 | let myRandomNumber = Math.ceil((rng() * 10)); 10 | 11 | console.log(myRandomNumber); 12 | -------------------------------------------------------------------------------- /Unit 1 - Welcome/U1-M5-randomnumber/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "randomnumber", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "seedrandom": { 8 | "version": "2.4.3", 9 | "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz", 10 | "integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Unit 1 - Welcome/U1-M5-randomnumber/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "randomnumber", 3 | "version": "1.0.0", 4 | "description": "Generates a random number between 1 and 10", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "seedrandom": "^2.4.3" 13 | }, 14 | "devDependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M1-helloyou/index.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | 4 | const rl = readline.createInterface({ 5 | input: process.stdin, 6 | output: process.stdout 7 | }); 8 | 9 | rl.question("What's your name? ", (answer) => { 10 | 11 | console.log(`Well hello there ${answer}`); 12 | 13 | rl.close(); 14 | 15 | }); -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M1-helloyou/numbers.js: -------------------------------------------------------------------------------- 1 | const readline = require('readline'); 2 | 3 | const rl = readline.createInterface({ 4 | input: process.stdin, 5 | output: process.stdout 6 | }); 7 | 8 | rl.question("Pick a number: ", (number1) => { 9 | 10 | console.log(`You chose ${number1}`); 11 | 12 | rl.question("Pick a second number: ", (number2) => { 13 | 14 | const product = parseInt(number1) + parseInt(number2); 15 | console.log(`${number1} + ${number2} = ${product}`); 16 | 17 | rl.close(); 18 | 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M1-helloyou/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloyou", 3 | "version": "1.0.0", 4 | "description": "Say hello", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M2-files/create.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | fs.writeFile('message.txt', 'Node.js In Motion', (err) => { 4 | if (err) throw err; 5 | console.log('The file has been saved!'); 6 | }); 7 | 8 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M2-files/createanddelete-1.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs'); 3 | 4 | fs.writeFile('message.txt', 'Node.js In Motion', (err) => { 5 | if (err) throw err; 6 | console.log('The file has been saved!'); 7 | }); 8 | 9 | fs.unlink('message.txt', (err) => { 10 | if (err) throw err; 11 | console.log('The file has been deleted!'); 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M2-files/createanddelete-2.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs'); 3 | 4 | fs.writeFile('message.txt', 'Node.js In Motion', (err) => { 5 | if (err) throw err; 6 | console.log('The file has been saved!'); 7 | 8 | fs.unlink('message.txt', (err) => { 9 | if (err) throw err; 10 | console.log('The file has been deleted!'); 11 | }); 12 | 13 | }); 14 | 15 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M2-files/createanddeletesync.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs'); 3 | 4 | fs.writeFileSync('message.txt', 'Node.js In Motion'); 5 | console.log('The file has been saved!'); 6 | 7 | fs.unlinkSync('message.txt'); 8 | console.log('The file has been deleted!'); 9 | 10 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M2-files/delete.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | fs.unlink('message.txt', (err) => { 4 | if (err) throw err; 5 | console.log('The file has been deleted!'); 6 | }); 7 | 8 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M2-files/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | fs.writeFile('message.txt', 'Node.js In Motion', (err) => { 4 | if (err) throw err; 5 | console.log('The file has been saved!'); 6 | }); 7 | 8 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M2-files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "files", 3 | "version": "1.0.0", 4 | "description": "Examples of the File API", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M2-files/readdir.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs'); 3 | 4 | fs.readdir(__dirname, (err, files) => { 5 | 6 | console.log(files); 7 | 8 | }); -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M3-files/hellofile-1.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const readline = require('readline'); 3 | 4 | const rl = readline.createInterface({ 5 | input: process.stdin, 6 | output: process.stdout 7 | }); 8 | 9 | // A default greeting 10 | let lastGreeting = 'None'; 11 | 12 | // Check whether the file exists 13 | fs.stat('message.txt', (err, stats) => { 14 | 15 | if(typeof stats != 'undefined') { 16 | 17 | // It does, so read in the contents 18 | fs.readFile('message.txt', (err, data) => { 19 | if (err) throw err; 20 | lastGreeting = data; 21 | 22 | 23 | 24 | }); 25 | 26 | } 27 | 28 | console.log(`My last greeting was to ${lastGreeting}`); 29 | 30 | rl.question("What's your name? ", (answer) => { 31 | 32 | console.log(`Well hello there ${answer}`); 33 | 34 | // Write the response out so we show it next time 35 | fs.writeFile('message.txt', answer, (err) => { 36 | if (err) throw err; 37 | rl.close(); 38 | }); 39 | 40 | }); 41 | 42 | }); 43 | 44 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M3-files/hellofile-3.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const readline = require('readline'); 3 | 4 | const rl = readline.createInterface({ 5 | input: process.stdin, 6 | output: process.stdout 7 | }); 8 | 9 | // Check whether the file exists 10 | fs.stat('message.txt', (err, stats) => { 11 | 12 | // It does, so read in the contents 13 | if(typeof stats != undefined) { 14 | 15 | fs.readFile('message.txt', (err, data) => { 16 | handleGreeting(data); 17 | }); 18 | 19 | } else { 20 | 21 | handleGreeting('None'); 22 | 23 | } 24 | 25 | }); 26 | 27 | function handleGreeting(lastGreeting) { 28 | 29 | console.log(`My last greeting was to ${lastGreeting}`); 30 | 31 | rl.question("What's your name? ", (answer) => { 32 | 33 | console.log(`Well hello there, ${answer}`); 34 | 35 | // Write the response out so we show it next time 36 | fs.writeFile('message.txt', answer, (err) => { 37 | if (err) throw err; 38 | rl.close(); 39 | }); 40 | 41 | }); 42 | 43 | } -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M4-chuck/chuck1.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | // A message of the day 6 | const rl = readline.createInterface({ 7 | input: fs.createReadStream('chuck.txt') 8 | }); 9 | 10 | rl.on('line', (line) => { 11 | console.log(line); 12 | }) 13 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M4-chuck/chuck2.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | let chuckCounter = 0; 6 | let chuckLine = 0; 7 | const chuckLines = 85; 8 | 9 | if(fs.existsSync('chuckcounter.txt')) { 10 | chuckLine = parseInt(fs.readFileSync('chuckcounter.txt')); 11 | chuckLine++; 12 | if(chuckLine > chuckLines) chuckLine = 0; 13 | } 14 | 15 | // A message of the day 16 | const rl = readline.createInterface({ 17 | input: fs.createReadStream('chuck.txt') 18 | }); 19 | 20 | rl.on('line', (line) => { 21 | 22 | if(chuckCounter == chuckLine) { 23 | fs.writeFileSync('chuckcounter.txt', chuckLine); 24 | console.log(line); 25 | } 26 | 27 | chuckCounter++; 28 | 29 | }) 30 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M4-chuck/chuck3.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | // A message of the day 6 | let chuckCounter = 0; 7 | 8 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 9 | 10 | const rl = readline.createInterface({ 11 | input: fs.createReadStream('chuck.txt') 12 | }); 13 | 14 | rl.on('line', (line) => { 15 | 16 | if(chuckCounter == chuckLine) { 17 | console.log(line); 18 | } 19 | 20 | chuckCounter++; 21 | 22 | }) 23 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M5-chuck/chuck3.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = (cb) => { 6 | 7 | // A message of the day 8 | let chuckCounter = 0; 9 | 10 | const chuckLine = Math.floor(Math.random() * 86); 11 | 12 | const rl = readline.createInterface({ 13 | input: fs.createReadStream('chuck.txt') 14 | }); 15 | 16 | rl.on('line', (line) => { 17 | 18 | if(chuckCounter == chuckLine) { 19 | cb(line); 20 | } 21 | 22 | chuckCounter++; 23 | 24 | }) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M5-chuck/runchuck.js: -------------------------------------------------------------------------------- 1 | 2 | const chuck = require('./chuck3.js'); 3 | 4 | chuck.getChuckNorrisFact((line) => { 5 | console.log(line); 6 | }); 7 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M6-weather/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weather", 3 | "version": "1.0.0", 4 | "description": "Example code to display the current weather", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M7-weather/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Fancy script to tell me the weather 4 | */ 5 | 6 | // Requirements 7 | const req = require('request'); 8 | 9 | // Settings 10 | const country = "London,uk"; 11 | const url = "http://api.openweathermap.org/data/2.5/weather"; 12 | const apiKey = "REPLACE_ME_WITH_YOUR_API_KEY"; 13 | 14 | // Build the full query string 15 | const getString = `${url}?q=${country}&appid=${apiKey}&units=metric`; 16 | 17 | // Make the request 18 | req.get({uri: getString, json: true}, (error, response, body) => { 19 | 20 | if(response.statusCode != 200) { 21 | console.log(`Something bad happened: ${response.statusCode}`); 22 | } else { 23 | console.log(`${body.main.temp}C, ${body.weather[0].description}`); 24 | } 25 | 26 | }); 27 | 28 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M7-weather/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weather", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "request": "^2.83.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/1.txt: -------------------------------------------------------------------------------- 1 | A programmer started to cuss 2 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/2.txt: -------------------------------------------------------------------------------- 1 | Cos getting to sleep was a fuss 2 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/3.txt: -------------------------------------------------------------------------------- 1 | As he lay in his bed 2 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/4.txt: -------------------------------------------------------------------------------- 1 | Going round in his head 2 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/5.txt: -------------------------------------------------------------------------------- 1 | Was while (!asleep) sheep++ -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/readfiles1.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs'); 3 | let myText = ""; 4 | 5 | fs.readFile('1.txt', (err, data) => { 6 | if(err) throw(err); 7 | myText += data; 8 | fs.readFile('2.txt', (err, data) => { 9 | if(err) throw(err); 10 | myText += data; 11 | fs.readFile('3.txt', (err, data) => { 12 | if(err) throw(err); 13 | myText += data; 14 | fs.readFile('4.txt', (err, data) => { 15 | if(err) throw(err); 16 | myText += data; 17 | fs.readFile('5.txt', (err, data) => { 18 | if(err) throw(err); 19 | myText += data; 20 | console.log(myText); 21 | }); 22 | }); 23 | }); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/readfiles2.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs'); 3 | let myText = ""; 4 | 5 | function readFilePromise(fileName) { 6 | return new Promise((resolve, reject) => { 7 | fs.readFile(fileName, (err, data) => { 8 | if(err) { 9 | reject(err); 10 | } else { 11 | resolve(data); 12 | } 13 | }); 14 | }); 15 | } 16 | 17 | 18 | readFilePromise('1.txt').then((data) => { 19 | myText = data; 20 | return readFilePromise('2.txt'); 21 | }).then((data) => { 22 | myText += data; 23 | return readFilePromise('3.txt'); 24 | }).then((data) => { 25 | myText += data; 26 | return readFilePromise('4.txt'); 27 | }).then((data) => { 28 | myText += data; 29 | return readFilePromise('5.txt'); 30 | }).then((data) => { 31 | myText += data; 32 | console.log(myText); 33 | }).catch((err) => { 34 | console.log(`Error! ${err}`); 35 | }); 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/readfiles3-1.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs'); 3 | 4 | function readFilePromise(fileName) { 5 | return new Promise((resolve, reject) => { 6 | fs.readFile(fileName, (err, data) => { 7 | if(err) { 8 | reject(err); 9 | } else { 10 | resolve(data); 11 | } 12 | }); 13 | }); 14 | } 15 | 16 | const readAllFiles = async () => { 17 | 18 | let myText = ""; 19 | try { 20 | myText = await readFilePromise('1.txt'); 21 | myText += await readFilePromise('2.txt'); 22 | myText += await readFilePromise('3.txt'); 23 | myText += await readFilePromise('4.txt'); 24 | myText += await readFilePromise('5.txt'); 25 | console.log(myText); 26 | } catch(err) { 27 | console.log(`Error! ${err.message}`); 28 | } 29 | 30 | } 31 | 32 | const main = async () => { 33 | await readAllFiles(); 34 | console.log('Complete!'); 35 | } 36 | 37 | main(); -------------------------------------------------------------------------------- /Unit 2 - Nodejs On The Command Line/U2-M8-async/readfiles3-2.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs-extra'); 3 | 4 | const readAllFiles = async () => { 5 | 6 | let myText = ""; 7 | try { 8 | myText = await fs.readFile('1.txt'); 9 | myText += await fs.readFile('2.txt'); 10 | myText += await fs.readFile('3.txt'); 11 | myText += await fs.readFile('4.txt'); 12 | myText += await fs.readFile('5.txt'); 13 | console.log(myText); 14 | } catch(err) { 15 | console.log(`Error! ${err.message}`); 16 | } 17 | 18 | } 19 | readAllFiles(); 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M1-httpserver/index.js: -------------------------------------------------------------------------------- 1 | 2 | const http = require('http'); 3 | 4 | http.createServer((req, res) => { 5 | console.log(req.url); 6 | res.write('
Thank you. The results are as follows:
8 |15 | Return To The Form 16 |
17 | 18 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M5-numbers/form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |Thank you. The results are as follows:
8 |15 | Return To The Form 16 |
17 | 18 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M7-pugplay/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | 5 | // Handle every GET 6 | app.get('*', (req, res) => { 7 | 8 | let myTemplate = req.url; 9 | if(myTemplate == '/') { 10 | myTemplate = 'index'; 11 | } 12 | 13 | const data = { 14 | theTime: new Date(), 15 | aList: ['One', 'Two', 'Three', 'Four'] 16 | }; 17 | 18 | console.log(`Serving ${myTemplate}`); 19 | 20 | res.render(`${__dirname}/templates/${myTemplate}.pug`, data ); 21 | 22 | }); 23 | 24 | // Start the server 25 | app.listen(8080, (err) => { 26 | console.log('Express running at http://127.0.0.1:8080/'); 27 | }); 28 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M7-pugplay/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pugplay", 3 | "version": "1.0.0", 4 | "description": "App for playing around with Pug templates", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "express": "^4.16.2", 13 | "pug": "^2.0.0-rc.4" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M7-pugplay/templates/body.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | p Hello! This is a template within a template! -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M7-pugplay/templates/index.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | body 4 | h1 Hello 5 | p This is some text 6 | p= theTime 7 | p The time is #{theTime} 8 | p Here's a list 9 | ul 10 | each val in aList 11 | if val == 'Three' 12 | li The Magic Number 13 | else 14 | li= val -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M7-trypug/form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |Some text goes here.
10 | 11 | 12 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M7-trypug/page.pug: -------------------------------------------------------------------------------- 1 | 2 | DOCTYPE html 3 | html 4 | head 5 | title My Cool Webpage 6 | body 7 | h1 Hello, World! 8 | p Some text goes here. 9 | 10 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M8-helloworld/index-1.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | 5 | // Handle every GET 6 | app.get('/', (req, res) => { 7 | 8 | // Render the template 9 | res.render(__dirname + '/index.pug'); 10 | 11 | }); 12 | 13 | // Start the server 14 | app.listen(8080, (err) => { 15 | console.log('Express running at http://127.0.0.1:8080/'); 16 | }); 17 | 18 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M8-helloworld/index-1.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld Hello, world! 8 | hr 9 | 10 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M8-helloworld/index-2.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const chuck = require('./chuck'); 3 | const app = express(); 4 | 5 | // Handle every GET 6 | app.get('/', (req, res) => { 7 | 8 | // Get a random Chuck Norris fact 9 | chuck.getChuckNorrisFact((chuckFact) => { 10 | 11 | // Render the template 12 | res.render(__dirname + '/index.pug', {'chuck': chuckFact}); 13 | 14 | }); 15 | 16 | }); 17 | 18 | // Serve the stylesheet 19 | app.get('/style.css', (req, res) => { 20 | res.sendFile(__dirname + '/style.css'); 21 | }); 22 | 23 | // Start the server 24 | app.listen(8080, (err) => { 25 | console.log('Express running at http://127.0.0.1:8080/'); 26 | }); 27 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M8-helloworld/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const chuck = require('./chuck'); 3 | const app = express(); 4 | 5 | // Handle every GET 6 | app.get('/', (req, res) => { 7 | 8 | // Immediately Invoked Function Expressions (IIFE) so we can use async 9 | (async () => { 10 | 11 | // Get a random Chuck Norris fact 12 | const chuckFact = await chuck.getChuckNorrisFactPromise(); 13 | 14 | // Render the template 15 | res.render(__dirname + '/index.pug', {'chuck': chuckFact}); 16 | 17 | })(); 18 | 19 | }); 20 | 21 | // Serve the stylesheet 22 | app.get('/style.css', (req, res) => { 23 | res.sendFile(__dirname + '/style.css'); 24 | }); 25 | 26 | // Start the server 27 | app.listen(8080, (err) => { 28 | console.log('Express running at http://127.0.0.1:8080/'); 29 | }); 30 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M8-helloworld/index.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | 5 | // A nice, friendly welcome 6 | h1.heroHelloWorld Hello, world! 7 | hr 8 | 9 | // Chuck Norris 10 | .row 11 | .col-md-12 12 | .well.chuck= chuck 13 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M8-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloworld", 3 | "version": "1.0.0", 4 | "description": "The ultimate 'Hello, world!' application", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "express": "^4.16.2", 13 | "pug": "^2.0.0-rc.4" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Unit 3 - Building Web Applications With Node/U3-M8-helloworld/style.css: -------------------------------------------------------------------------------- 1 | .heroHelloWorld { 2 | text-align: center; 3 | font-size: 100px; 4 | } 5 | 6 | .chuck { 7 | text-align: center; 8 | } -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M1-trysqlite/index.js: -------------------------------------------------------------------------------- 1 | 2 | const sqlite3 = require('sqlite3'); 3 | const db = new sqlite3.Database('example.sqlite'); 4 | 5 | db.each("SELECT rowid AS id, name FROM cheeses", (err, row) => { 6 | 7 | console.log(`${row.id}: ${row.name}`); 8 | 9 | }); 10 | 11 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M1-trysqlite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trysqlite", 3 | "version": "1.0.0", 4 | "description": "Example connection to SQLite database", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "sqlite3": "^3.1.13" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M1-trysqlite/seed.js: -------------------------------------------------------------------------------- 1 | 2 | const sqlite3 = require('sqlite3'); 3 | const db = new sqlite3.Database('example.sqlite'); 4 | 5 | db.serialize(() => { 6 | 7 | db.run("CREATE TABLE cheeses (name TEXT)"); 8 | 9 | const stmt = db.prepare("INSERT INTO cheeses VALUES (?)"); 10 | 11 | stmt.run("Cheddar"); 12 | stmt.run("Wensleydale"); 13 | stmt.run("Red Leicester"); 14 | stmt.run("Stilton"); 15 | stmt.run("Yarg"); 16 | stmt.run("Oxford Blue"); 17 | stmt.run("Brie"); 18 | stmt.run("Cheshire"); 19 | 20 | stmt.finalize(); 21 | 22 | db.each("SELECT rowid AS id, name FROM cheeses", (err, row) => { 23 | console.log(row.id + ": " + row.name); 24 | }); 25 | 26 | }); 27 | 28 | db.close(); 29 | 30 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M2-crud/delete.js: -------------------------------------------------------------------------------- 1 | 2 | const sqlite3 = require('sqlite3'); 3 | const db = new sqlite3.Database('users.sqlite'); 4 | 5 | db.run("DELETE FROM users WHERE name = 'Bob'", (err, row) => { 6 | 7 | if (err) { 8 | console.log(`Oops! ${err}`); 9 | } else { 10 | console.log('Row deleted'); 11 | } 12 | 13 | }); 14 | 15 | db.close(); 16 | 17 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M2-crud/index.js: -------------------------------------------------------------------------------- 1 | 2 | const sqlite3 = require('sqlite3'); 3 | const db = new sqlite3.Database('users.sqlite'); 4 | 5 | db.each("SELECT rowid as id, * FROM users", (err, row) => { 6 | 7 | console.log(`${row.name} (${row.email}): Pizza - ${row.fav_pizza}, Space Invaders - ${row.space_invaders}`); 8 | 9 | }); 10 | 11 | db.close(); 12 | 13 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M2-crud/migrate.js: -------------------------------------------------------------------------------- 1 | 2 | const sqlite3 = require('sqlite3'); 3 | const db = new sqlite3.Database('users.sqlite'); 4 | 5 | db.serialize(() => { 6 | 7 | // Create our table (dropping if it's already there) 8 | db.run('DROP TABLE IF EXISTS users'); 9 | db.run('CREATE TABLE users (name TEXT, email TEXT, fav_pizza TEXT, space_invaders INT)'); 10 | 11 | // Populate 12 | const stmt = db.prepare('INSERT INTO users VALUES (?,?,?,?)'); 13 | stmt.run('PJ', 'pj@company.org', 'Pepperoni', 826488); 14 | stmt.run('Trish','trish@company.org', 'Spicy Veg', 674588); 15 | stmt.run('Paddy', 'paddy@company.org', 'Ham', 998988); 16 | stmt.run('Bob', 'bob@company.org', 'Onion', 6577); 17 | stmt.run('Alice', 'alice@company.org', 'Everything', 929848); 18 | 19 | // We're done here 20 | stmt.finalize(); 21 | 22 | }); 23 | 24 | db.close(); 25 | 26 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M2-crud/migration.js: -------------------------------------------------------------------------------- 1 | 2 | const sqlite3 = require('sqlite3'); 3 | const db = new sqlite3.Database('users.sqlite'); 4 | 5 | db.serialize(() => { 6 | 7 | // Create our table (dropping if it's already there) 8 | db.run('DROP TABLE IF EXISTS users'); 9 | db.run('CREATE TABLE users (name TEXT, email TEXT, fav_pizza TEXT, space_invaders INT)'); 10 | 11 | // Populate 12 | const stmt = db.prepare('INSERT INTO users VALUES (?,?,?,?)'); 13 | stmt.run('PJ', 'pj@company.org', 'Pepperoni', 826488); 14 | stmt.run('Trish','trish@company.org', 'Spicy Veg', 674588); 15 | stmt.run('Paddy', 'paddy@company.org', 'Ham', 998988); 16 | stmt.run('Bob', 'bob@company.org', 'Onion', 6577); 17 | stmt.run('Alice', 'alice@company.org', 'Everything', 929848); 18 | 19 | // We're done here 20 | stmt.finalize(); 21 | 22 | }); 23 | 24 | db.close(); 25 | 26 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M2-crud/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "crud", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "sqlite3": "^3.1.13" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M2-crud/update.js: -------------------------------------------------------------------------------- 1 | 2 | const sqlite3 = require('sqlite3'); 3 | const db = new sqlite3.Database('users.sqlite'); 4 | 5 | db.run("UPDATE users SET space_invaders = 999999999 WHERE name = 'PJ'", (err, row) => { 6 | 7 | if (err) { 8 | console.log(`Oops! ${err}`); 9 | } else { 10 | console.log('Row updated'); 11 | } 12 | 13 | }); 14 | 15 | db.close(); 16 | 17 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M3-trysequelize/delete.js: -------------------------------------------------------------------------------- 1 | 2 | const Sequelize = require('sequelize'); 3 | 4 | // Initialise connection 5 | const sequelize = new Sequelize({ 6 | dialect: 'sqlite', 7 | storage: 'users.sqlite', 8 | operatorsAliases: false 9 | }); 10 | 11 | // Define our Model 12 | const User = sequelize.define('users', { 13 | name: Sequelize.STRING, 14 | email: Sequelize.STRING, 15 | fav_pizza: Sequelize.STRING, 16 | space_invaders: Sequelize.INTEGER 17 | }); 18 | 19 | // Or using async... 20 | (async () => { 21 | 22 | // Bye Bob! 23 | await User.destroy({ 24 | where: { 25 | name: 'Bob' 26 | } 27 | }); 28 | 29 | })(); 30 | 31 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M3-trysequelize/index.js: -------------------------------------------------------------------------------- 1 | 2 | const Sequelize = require('sequelize'); 3 | 4 | // Initialise connection 5 | const sequelize = new Sequelize({ 6 | dialect: 'sqlite', 7 | storage: 'users.sqlite', 8 | operatorsAliases: false, 9 | logging: false 10 | }); 11 | 12 | // Define our Model 13 | const User = sequelize.define('users', { 14 | name: Sequelize.STRING, 15 | email: Sequelize.STRING, 16 | fav_pizza: Sequelize.STRING, 17 | space_invaders: Sequelize.INTEGER 18 | }); 19 | 20 | // Get some data 21 | (async () => { 22 | const rows = await User.findAll(); 23 | rows.forEach((row) => { 24 | console.log(`${row.name} (${row.email}): Pizza - ${row.fav_pizza}, Space Invaders - ${row.space_invaders}`); 25 | }); 26 | })(); 27 | 28 | 29 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M3-trysequelize/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trysequelize", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "sequelize": "^4.22.6", 13 | "sqlite3": "^3.1.13" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M3-trysequelize/update.js: -------------------------------------------------------------------------------- 1 | 2 | const Sequelize = require('sequelize'); 3 | 4 | // Initialise connection 5 | const sequelize = new Sequelize({ 6 | dialect: 'sqlite', 7 | storage: 'users.sqlite', 8 | operatorsAliases: false 9 | }); 10 | 11 | // Define our Model 12 | const User = sequelize.define('users', { 13 | name: Sequelize.STRING, 14 | email: Sequelize.STRING, 15 | fav_pizza: Sequelize.STRING, 16 | space_invaders: Sequelize.INTEGER 17 | }); 18 | 19 | (async () => { 20 | 21 | // I Win! 22 | await User.update({ 23 | space_invaders: 9999999 24 | }, { 25 | where: { 26 | name: 'PJ' 27 | } 28 | }); 29 | 30 | })(); 31 | 32 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M3-trysequelize/users.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 4 - Databases/U4-M3-trysequelize/users.sqlite -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M4-trymongodb/delete.js: -------------------------------------------------------------------------------- 1 | 2 | const mongoClient = require('mongodb').MongoClient; 3 | const url = 'mongodb://localhost:27017/users'; 4 | 5 | (async () => { 6 | 7 | // Connect 8 | const db = await mongoClient.connect(url); 9 | const users = await db.collection('users'); 10 | 11 | // Delete 12 | await users.deleteOne({ name: 'Bob' }); 13 | 14 | console.log('Document deleted'); 15 | 16 | db.close(); 17 | 18 | })(); 19 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M4-trymongodb/index.js: -------------------------------------------------------------------------------- 1 | 2 | const mongoClient = require('mongodb').MongoClient; 3 | const url = 'mongodb://localhost:27017/users'; 4 | 5 | (async () => { 6 | 7 | // Connect 8 | const db = await mongoClient.connect(url); 9 | const users = await db.collection('users'); 10 | 11 | // Get every document 12 | const docs = await users.find().toArray(); 13 | 14 | console.log(docs); 15 | 16 | db.close(); 17 | 18 | })(); 19 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M4-trymongodb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trymongodb", 3 | "version": "1.0.0", 4 | "description": "Have a play with NoSQL", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "mongodb": "^2.2.33" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M4-trymongodb/update.js: -------------------------------------------------------------------------------- 1 | 2 | const mongoClient = require('mongodb').MongoClient; 3 | const url = 'mongodb://localhost:27017/users'; 4 | 5 | (async () => { 6 | 7 | // Connect 8 | const db = await mongoClient.connect(url); 9 | const users = await db.collection('users'); 10 | 11 | // Update 12 | await users.updateOne( 13 | { name: 'PJ' }, 14 | {'space_invaders': 9999999} 15 | ); 16 | 17 | })(); 18 | 19 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M5-moresequelize/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false 12 | }, 13 | "production": { 14 | "dialect": "sqlite", 15 | "storage": "db/hello_world.sqlite", 16 | "operatorsAliases": false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M5-moresequelize/index.js: -------------------------------------------------------------------------------- 1 | 2 | const db = require('./models'); 3 | 4 | (async () => { 5 | 6 | rows = await db.users.findAll(); 7 | rows.forEach((row) => { 8 | console.log(`${row.name} (${row.email}): Pizza - ${row.fav_pizza}, Space Invaders - ${row.space_invaders}`); 9 | }); 10 | 11 | })(); 12 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M5-moresequelize/migrations/20171121112949-create-users.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('users', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | email: { 15 | type: Sequelize.STRING 16 | }, 17 | fav_pizza: { 18 | type: Sequelize.STRING 19 | }, 20 | space_invaders: { 21 | type: Sequelize.INTEGER 22 | }, 23 | createdAt: { 24 | allowNull: false, 25 | type: Sequelize.DATE 26 | }, 27 | updatedAt: { 28 | allowNull: false, 29 | type: Sequelize.DATE 30 | } 31 | }); 32 | }, 33 | down: function(queryInterface, Sequelize) { 34 | return queryInterface.dropTable('users'); 35 | } 36 | }; -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M5-moresequelize/models/users.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | module.exports = function(sequelize, DataTypes) { 4 | var users = sequelize.define('users', { 5 | name: DataTypes.STRING, 6 | email: DataTypes.STRING, 7 | fav_pizza: DataTypes.STRING, 8 | space_invaders: DataTypes.INTEGER 9 | }, { 10 | classMethods: { 11 | associate: function(models) { 12 | // associations can be defined here 13 | } 14 | } 15 | }); 16 | return users; 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M5-moresequelize/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moresequelize", 3 | "version": "1.0.0", 4 | "description": "Fun with Sequelize on the command line", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "sequelize": "^4.22.11", 13 | "sqlite3": "^3.1.13" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M6-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false 6 | }, 7 | "test": { 8 | "dialect": "sqlite", 9 | "storage": "db/hello_world.sqlite", 10 | "operatorsAliases": false 11 | }, 12 | "production": { 13 | "dialect": "sqlite", 14 | "storage": "db/hello_world.sqlite", 15 | "operatorsAliases": false 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M6-helloworld/index.js: -------------------------------------------------------------------------------- 1 | const Sequelize = require('sequelize'); 2 | const db = require('./models'); 3 | 4 | //const users = new db.users(); 5 | 6 | (async () => { 7 | 8 | const translation = db.Translation; 9 | 10 | const transModel = await translation.findOne({ 11 | order: [ 12 | Sequelize.fn('RANDOM') 13 | ] 14 | }); 15 | console.log(transModel.language); 16 | 17 | })(); 18 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M6-helloworld/migrations/create_Fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | up: function (queryInterface, Sequelize) { 5 | queryInterface.createTable( 6 | 'Fonts', 7 | { 8 | id: { 9 | type: Sequelize.INTEGER, 10 | primaryKey: true, 11 | autoIncrement: true 12 | }, 13 | name: { 14 | type: Sequelize.STRING, 15 | allowNull: false 16 | }, 17 | link: { 18 | type: Sequelize.STRING, 19 | allowNull: false 20 | }, 21 | css: { 22 | type: Sequelize.STRING, 23 | allowNull: false 24 | } 25 | } 26 | ); 27 | }, 28 | 29 | down: function (queryInterface) { 30 | queryInterface.dropTable('Fonts'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M6-helloworld/migrations/create_Translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | up: function (queryInterface, Sequelize) { 5 | queryInterface.createTable( 6 | 'Translations', 7 | { 8 | id: { 9 | type: Sequelize.INTEGER, 10 | primaryKey: true, 11 | autoIncrement: true 12 | }, 13 | language: { 14 | type: Sequelize.STRING, 15 | allowNull: false 16 | }, 17 | languageCode: { 18 | type: Sequelize.STRING, 19 | allowNull: false 20 | }, 21 | translation: { 22 | type: Sequelize.STRING, 23 | } 24 | } 25 | ); 26 | }, 27 | 28 | down: function (queryInterface) { 29 | queryInterface.dropTable('Translations'); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M6-helloworld/models/Font.js: -------------------------------------------------------------------------------- 1 | // Model for the Fonts table 2 | module.exports = (sequelize, DataTypes) => { 3 | const Font = sequelize.define( 4 | 'Font', 5 | { 6 | id: { 7 | type: DataTypes.INTEGER, 8 | primaryKey: true, 9 | autoIncrement: true 10 | }, 11 | name: { 12 | type: DataTypes.STRING, 13 | allowNull: false 14 | }, 15 | link: { 16 | type: DataTypes.STRING, 17 | allowNull: false 18 | }, 19 | css: { 20 | type: DataTypes.STRING, 21 | allowNull: false 22 | } 23 | }, { 24 | timestamps: false 25 | }); 26 | return Font; 27 | }; 28 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M6-helloworld/models/Translation.js: -------------------------------------------------------------------------------- 1 | module.exports = (sequelize, DataTypes) => { 2 | const Translation = sequelize.define( 3 | 'Translation', 4 | { 5 | id: { 6 | type: DataTypes.INTEGER, 7 | primaryKey: true, 8 | autoIncrement: true 9 | }, 10 | language: { 11 | type: DataTypes.STRING, 12 | allowNull: false 13 | }, 14 | languageCode: { 15 | type: DataTypes.STRING, 16 | allowNull: false 17 | }, 18 | translation: { 19 | type: DataTypes.STRING, 20 | } 21 | }, { 22 | timestamps: false 23 | }); 24 | return Translation; 25 | }; 26 | -------------------------------------------------------------------------------- /Unit 4 - Databases/U4-M6-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloworld", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT", 11 | "dependencies": { 12 | "bcrypt": "^1.0.3", 13 | "sequelize": "^4.22.5", 14 | "sqlite3": "^3.1.13" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M1-cheese/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/cheese.sqlite", 5 | "operatorsAliases": false 6 | }, 7 | "test": { 8 | "dialect": "sqlite", 9 | "storage": "db/cheese.sqlite", 10 | "operatorsAliases": false 11 | }, 12 | "production": { 13 | "dialect": "sqlite", 14 | "storage": "db/cheese.sqlite", 15 | "operatorsAliases": false 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M1-cheese/db/cheese.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M1-cheese/db/cheese.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M1-cheese/index.js: -------------------------------------------------------------------------------- 1 | const Sequelize = require('sequelize'); 2 | const db = require('./models'); 3 | 4 | (async () => { 5 | 6 | const cheese = db.cheese; 7 | console.log(await cheese.uniqueCountries()); 8 | 9 | })(); 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M1-cheese/migrations/20171212112506-create-cheese.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('cheeses', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | origin: { 15 | type: Sequelize.STRING 16 | }, 17 | createdAt: { 18 | allowNull: false, 19 | type: Sequelize.DATE 20 | }, 21 | updatedAt: { 22 | allowNull: false, 23 | type: Sequelize.DATE 24 | } 25 | }); 26 | }, 27 | down: function(queryInterface, Sequelize) { 28 | return queryInterface.dropTable('cheeses'); 29 | } 30 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M1-cheese/migrations/20171212132234-create-cheese.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('cheeses', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | origin: { 15 | type: Sequelize.STRING 16 | }, 17 | createdAt: { 18 | allowNull: false, 19 | type: Sequelize.DATE 20 | }, 21 | updatedAt: { 22 | allowNull: false, 23 | type: Sequelize.DATE 24 | } 25 | }); 26 | }, 27 | down: function(queryInterface, Sequelize) { 28 | return queryInterface.dropTable('cheeses'); 29 | } 30 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M1-cheese/models/cheese.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var cheese = sequelize.define('cheese', { 4 | name: DataTypes.STRING, 5 | origin: DataTypes.STRING 6 | }, { 7 | classMethods: { 8 | associate: function(models) { 9 | // associations can be defined here 10 | } 11 | } 12 | }); 13 | 14 | // Here we extend the model at add our business logic 15 | cheese.uniqueCountries = () => { 16 | return cheese.aggregate('origin', 'DISTINCT', { plain: false }); 17 | }; 18 | 19 | return cheese; 20 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M1-cheese/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modelexample", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "sequelize": "^4.28.0", 8 | "sqlite3": "^3.1.13" 9 | }, 10 | "devDependencies": {}, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "author": "PJ Evans", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | const chuck = require('./chuck'); 5 | 6 | // Handle every GET 7 | app.get('/', (req, res) => { 8 | 9 | // Immediately Invoked Function Expressions (IIFE) so we can use async 10 | (async () => { 11 | 12 | // Get a random Chuck Norris fact 13 | const chuckFact = await chuck.getChuckNorrisFact(); 14 | 15 | // Render the template 16 | res.render(__dirname + '/index.pug', {chuck: chuckFact}); 17 | 18 | })(); 19 | 20 | }); 21 | 22 | // Serve the stylesheet 23 | app.get('/style.css', (req, res) => { 24 | res.sendFile(__dirname + '/style.css'); 25 | }); 26 | 27 | 28 | // Start the server 29 | app.listen(8080, (err) => { 30 | console.log('Express running at http://127.0.0.1:8080/'); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Fonts = sequelize.define('Fonts', { 4 | name: DataTypes.STRING, 5 | link: DataTypes.STRING, 6 | css: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | 15 | Fonts.getRandomFont = async () => { 16 | const fontResult = await Fonts.findOne({ 17 | order: [ 18 | sequelize.fn('RANDOM') 19 | ] 20 | }); 21 | return fontResult.toJSON(); 22 | } 23 | 24 | return Fonts; 25 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "Chuck Norris facts", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "chuck", 11 | "norris", 12 | "awesome" 13 | ], 14 | "author": "PJ Evans", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "u5m3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "bcrypt": "^1.0.3", 10 | "bcrypt-promise": "^2.0.0", 11 | "body-parser": "~1.18.2", 12 | "cookie-parser": "~1.4.3", 13 | "cookie-session": "^2.0.0-beta.3", 14 | "csurf": "^1.9.0", 15 | "debug": "~2.6.9", 16 | "express": "~4.15.5", 17 | "morgan": "~1.9.0", 18 | "nodemailer": "^4.4.1", 19 | "pug": "2.0.0-beta11", 20 | "request": "^2.83.0", 21 | "request-promise-native": "^1.0.5", 22 | "sequelize": "^4.28.0", 23 | "serve-favicon": "~2.4.5", 24 | "sqlite3": "^3.1.13" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/public/images/favicon.png -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/public/javascripts/script.js: -------------------------------------------------------------------------------- 1 | $(() => { 2 | 3 | // Populate the weather 4 | $.getJSON('/weather', (data) => { 5 | $('.mypanel-weather').html(`${data.current_observation.weather}
${data.current_observation.temperature_string}
`); 6 | }); 7 | 8 | }) 9 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .heroHelloWorld { 3 | text-align: center; 4 | font-size: 100px; 5 | } 6 | 7 | .chuck { 8 | text-align: center; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/test.js: -------------------------------------------------------------------------------- 1 | 2 | const Sequelize = require('sequelize'); 3 | const db = require('./models'); 4 | 5 | (async () => { 6 | 7 | const translation = db.Translations; 8 | 9 | const transModel = await translation.findOne({ 10 | order: [ 11 | Sequelize.fn('RANDOM') 12 | ] 13 | }); 14 | console.log(transModel.language); 15 | 16 | })(); 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld= greeting.translation 8 | p.text-center That's #{greeting.language} for 'Hello, World' in the #{font.name} font 9 | 10 | hr 11 | 12 | // Chuck Norris 13 | .row 14 | .col-md-12 15 | .well.chuck= chuck 16 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/views/login.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Login 5 | if authFailure 6 | div.alert.alert-danger Username or password incorrect 7 | 8 | form(action='login',method='POST') 9 | 10 | input(type="hidden", name="_csrf", value=csrf) 11 | 12 | div.form-group 13 | label.control-label(for="username") Username 14 | input#username.form-control(type="text",name="username",value=username) 15 | 16 | div.form-group 17 | label.control-label(for="password") Password 18 | input#password.form-control(type="password",name="password") 19 | 20 | button.btn.btn-primary Log In 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/views/logout.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Logout 5 | p You have been logged out - thanks for playing! 6 | p 7 | a.btn.btn-default(href='login') Log In Again -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/views/users/create.pug: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | h1 Create a New User 5 | if alert 6 | if alert.type == 'success' 7 | div.alert.alert-success User created successfully 8 | else if alert.type == 'validation' 9 | div.alert.alert-warning Please check the form 10 | 11 | form(action='create',method='POST') 12 | 13 | include form.pug 14 | 15 | button.btn.btn-primary Create 16 | | 17 | a.btn.btn-default(href="/users/") Cancel -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/views/users/index.pug: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | h1 Users 5 | if alert 6 | case alert.type 7 | when 'deleted' 8 | div.alert.alert-success User deleted successfully 9 | when 'self' 10 | div.alert.alert-warning You cannot delete yourself 11 | table.table.table-hover 12 | thead 13 | th Username 14 | th Name 15 | th Email 16 | th Role 17 | th Status 18 | tbody 19 | each user in users 20 | tr(onclick="window.location = '/users/" + user.username + "/'") 21 | td= user.username 22 | td= user.name 23 | td= user.email 24 | td= user.role 25 | td= user.status 26 | a.btn.btn-primary(href='/users/create') Add New User 27 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M10-helloworld/views/users/update.pug: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | h1 Update User 5 | if alert 6 | if alert.type == 'success' 7 | div.alert.alert-success User modified successfully 8 | else if alert.type == 'validation' 9 | div.alert.alert-warning Please check the form 10 | 11 | form(action='.',method="POST") 12 | input(type='hidden',name='id',value=fields.id) 13 | 14 | include form.pug 15 | 16 | button.btn.btn-primary Update 17 | | 18 | a.btn.btn-default(href="/users/") Cancel 19 | button#delete.btn.btn-danger.pull-right Delete 20 | 21 | script. 22 | $('#delete').on('click',function(){ 23 | if(confirm('Are you sure?')) { 24 | $('form').attr('action','delete').submit(); 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | const chuck = require('./chuck'); 5 | 6 | // Handle every GET 7 | app.get('/', (req, res) => { 8 | 9 | // Immediately Invoked Function Expressions (IIFE) so we can use async 10 | (async () => { 11 | 12 | // Get a random Chuck Norris fact 13 | const chuckFact = await chuck.getChuckNorrisFact(); 14 | 15 | // Render the template 16 | res.render(__dirname + '/index.pug', {chuck: chuckFact}); 17 | 18 | })(); 19 | 20 | }); 21 | 22 | // Serve the stylesheet 23 | app.get('/style.css', (req, res) => { 24 | res.sendFile(__dirname + '/style.css'); 25 | }); 26 | 27 | 28 | // Start the server 29 | app.listen(8080, (err) => { 30 | console.log('Express running at http://127.0.0.1:8080/'); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Fonts = sequelize.define('Fonts', { 4 | name: DataTypes.STRING, 5 | link: DataTypes.STRING, 6 | css: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | 15 | Fonts.getRandomFont = async () => { 16 | const fontResult = await Fonts.findOne({ 17 | order: [ 18 | sequelize.fn('RANDOM') 19 | ] 20 | }); 21 | return fontResult.toJSON(); 22 | } 23 | 24 | return Fonts; 25 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "Chuck Norris facts", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "chuck", 11 | "norris", 12 | "awesome" 13 | ], 14 | "author": "PJ Evans", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "u5m3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "bcrypt": "^1.0.3", 10 | "bcrypt-promise": "^2.0.0", 11 | "body-parser": "~1.18.2", 12 | "cookie-parser": "~1.4.3", 13 | "cookie-session": "^2.0.0-beta.3", 14 | "csurf": "^1.9.0", 15 | "debug": "~2.6.9", 16 | "express": "~4.15.5", 17 | "morgan": "~1.9.0", 18 | "nodemailer": "^4.4.1", 19 | "pug": "2.0.0-beta11", 20 | "request": "^2.83.0", 21 | "request-promise-native": "^1.0.5", 22 | "sequelize": "^4.28.0", 23 | "serve-favicon": "~2.4.5", 24 | "sqlite3": "^3.1.13" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/public/images/favicon.png -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/public/javascripts/script.js: -------------------------------------------------------------------------------- 1 | $(() => { 2 | 3 | // Populate the weather 4 | $.getJSON('/weather', (data) => { 5 | $('.mypanel-weather').html(`${data.current_observation.weather}
${data.current_observation.temperature_string}
`); 6 | }); 7 | 8 | }) 9 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .heroHelloWorld { 3 | text-align: center; 4 | font-size: 100px; 5 | } 6 | 7 | .chuck { 8 | text-align: center; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/routes/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const chuck = require('../my_modules/chuck'); 4 | const db = require('../models'); 5 | const config = require('../config/helloworld'); 6 | 7 | /* GET a Chuck Norris fact */ 8 | router.get('/chuck', async (req, res, next) => { 9 | 10 | // Get a random Chuck Norris fact 11 | const chuckFact = await chuck.getChuckNorrisFact(); 12 | 13 | // Render the template 14 | res.json({chuck: chuckFact}); 15 | 16 | }); 17 | 18 | /* GET a Hello World */ 19 | router.get('/hello', async (req, res, next) => { 20 | 21 | // Translation 22 | const trans = await db.Translations.getRandomTranslation(config); 23 | 24 | // Render the template 25 | res.json(trans); 26 | 27 | }); 28 | 29 | module.exports = router; 30 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/test.js: -------------------------------------------------------------------------------- 1 | 2 | const Sequelize = require('sequelize'); 3 | const db = require('./models'); 4 | 5 | (async () => { 6 | 7 | const translation = db.Translations; 8 | 9 | const transModel = await translation.findOne({ 10 | order: [ 11 | Sequelize.fn('RANDOM') 12 | ] 13 | }); 14 | console.log(transModel.language); 15 | 16 | })(); 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld= greeting.translation 8 | p.text-center That's #{greeting.language} for 'Hello, World' in the #{font.name} font 9 | 10 | hr 11 | 12 | // Chuck Norris 13 | .row 14 | .col-md-12 15 | .well.chuck= chuck 16 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/views/login.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Login 5 | if authFailure 6 | div.alert.alert-danger Username or password incorrect 7 | 8 | form(action='login',method='POST') 9 | 10 | input(type="hidden", name="_csrf", value=csrf) 11 | 12 | div.form-group 13 | label.control-label(for="username") Username 14 | input#username.form-control(type="text",name="username",value=username) 15 | 16 | div.form-group 17 | label.control-label(for="password") Password 18 | input#password.form-control(type="password",name="password") 19 | 20 | button.btn.btn-primary Log In 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/views/logout.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Logout 5 | p You have been logged out - thanks for playing! 6 | p 7 | a.btn.btn-default(href='login') Log In Again -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/views/users/create.pug: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | h1 Create a New User 5 | if alert 6 | if alert.type == 'success' 7 | div.alert.alert-success User created successfully 8 | else if alert.type == 'validation' 9 | div.alert.alert-warning Please check the form 10 | 11 | form(action='create',method='POST') 12 | 13 | include form.pug 14 | 15 | button.btn.btn-primary Create 16 | | 17 | a.btn.btn-default(href="/users/") Cancel -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/views/users/index.pug: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | h1 Users 5 | if alert 6 | case alert.type 7 | when 'deleted' 8 | div.alert.alert-success User deleted successfully 9 | when 'self' 10 | div.alert.alert-warning You cannot delete yourself 11 | table.table.table-hover 12 | thead 13 | th Username 14 | th Name 15 | th Email 16 | th Role 17 | th Status 18 | tbody 19 | each user in users 20 | tr(onclick="window.location = '/users/" + user.username + "/'") 21 | td= user.username 22 | td= user.name 23 | td= user.email 24 | td= user.role 25 | td= user.status 26 | a.btn.btn-primary(href='/users/create') Add New User 27 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M11-helloworld/views/users/update.pug: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | h1 Update User 5 | if alert 6 | if alert.type == 'success' 7 | div.alert.alert-success User modified successfully 8 | else if alert.type == 'validation' 9 | div.alert.alert-warning Please check the form 10 | 11 | form(action='.',method="POST") 12 | input(type='hidden',name='id',value=fields.id) 13 | 14 | include form.pug 15 | 16 | button.btn.btn-primary Update 17 | | 18 | a.btn.btn-default(href="/users/") Cancel 19 | button#delete.btn.btn-danger.pull-right Delete 20 | 21 | script. 22 | $('#delete').on('click',function(){ 23 | if(confirm('Are you sure?')) { 24 | $('form').attr('action','delete').submit(); 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tryexpress", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.2", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.9", 12 | "express": "~4.15.5", 13 | "jade": "~1.11.0", 14 | "morgan": "~1.9.0", 15 | "serve-favicon": "~2.4.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/tryexpress/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tryexpress", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.2", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.9", 12 | "express": "~4.15.5", 13 | "morgan": "~1.9.0", 14 | "pug": "2.0.0-beta11", 15 | "serve-favicon": "~2.4.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/tryexpress/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/tryexpress/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/tryexpress/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/tryexpress/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/tryexpress/views/index.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p Welcome to #{title} 6 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/tryexpress/views/layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content 8 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p Welcome to #{title} 6 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M2-tryexpress/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content 8 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Fonts = sequelize.define('Fonts', { 4 | name: DataTypes.STRING, 5 | link: DataTypes.STRING, 6 | css: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | return Fonts; 15 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/models/translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Translations = sequelize.define('Translations', { 4 | language: DataTypes.STRING, 5 | languageCode: DataTypes.STRING, 6 | translation: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | return Translations; 15 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/models/users.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Users = sequelize.define('Users', { 4 | username: DataTypes.STRING, 5 | password_digest: DataTypes.STRING, 6 | name: DataTypes.STRING, 7 | email: DataTypes.STRING, 8 | role: DataTypes.ENUM('Admin','User'), 9 | status: DataTypes.ENUM('In','Out','Busy') 10 | }, { 11 | classMethods: { 12 | associate: function(models) { 13 | // associations can be defined here 14 | } 15 | } 16 | }); 17 | return Users; 18 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "Chuck Norris facts", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "chuck", 11 | "norris", 12 | "awesome" 13 | ], 14 | "author": "PJ Evans", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "u5m3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.2", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.9", 12 | "express": "~4.15.5", 13 | "morgan": "~1.9.0", 14 | "pug": "2.0.0-beta11", 15 | "serve-favicon": "~2.4.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .heroHelloWorld { 3 | text-align: center; 4 | font-size: 100px; 5 | } 6 | 7 | .chuck { 8 | text-align: center; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const chuck = require('../my_modules/chuck'); 4 | 5 | /* GET home page. */ 6 | router.get('/', async (req, res, next) => { 7 | 8 | // Get a random Chuck Norris fact 9 | const chuckFact = await chuck.getChuckNorrisFact(); 10 | 11 | // Render the template 12 | res.render('index', {chuck: chuckFact}); 13 | 14 | }); 15 | 16 | module.exports = router; 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/test.js: -------------------------------------------------------------------------------- 1 | 2 | const Sequelize = require('sequelize'); 3 | const db = require('./models'); 4 | 5 | (async () => { 6 | 7 | const translation = db.Translations; 8 | 9 | const transModel = await translation.findOne({ 10 | order: [ 11 | Sequelize.fn('RANDOM') 12 | ] 13 | }); 14 | console.log(transModel.language); 15 | 16 | })(); 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M3-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld Hello, world! 8 | hr 9 | 10 | // Chuck Norris 11 | .row 12 | .col-md-12 13 | .well.chuck= chuck 14 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Fonts = sequelize.define('Fonts', { 4 | name: DataTypes.STRING, 5 | link: DataTypes.STRING, 6 | css: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | 15 | Fonts.getRandomFont = async () => { 16 | const fontResult = await Fonts.findOne({ 17 | order: [ 18 | sequelize.fn('RANDOM') 19 | ] 20 | }); 21 | return fontResult.toJSON(); 22 | } 23 | 24 | return Fonts; 25 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/models/translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Translations = sequelize.define('Translations', { 4 | language: DataTypes.STRING, 5 | languageCode: DataTypes.STRING, 6 | translation: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | return Translations; 15 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/models/users.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Users = sequelize.define('Users', { 4 | username: DataTypes.STRING, 5 | password_digest: DataTypes.STRING, 6 | name: DataTypes.STRING, 7 | email: DataTypes.STRING, 8 | role: DataTypes.ENUM('Admin','User'), 9 | status: DataTypes.ENUM('In','Out','Busy') 10 | }, { 11 | classMethods: { 12 | associate: function(models) { 13 | // associations can be defined here 14 | } 15 | } 16 | }); 17 | return Users; 18 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "Chuck Norris facts", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "chuck", 11 | "norris", 12 | "awesome" 13 | ], 14 | "author": "PJ Evans", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "u5m3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.2", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.9", 12 | "express": "~4.15.5", 13 | "morgan": "~1.9.0", 14 | "pug": "2.0.0-beta11", 15 | "sequelize": "^4.28.0", 16 | "serve-favicon": "~2.4.5", 17 | "sqlite3": "^3.1.13" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .heroHelloWorld { 3 | text-align: center; 4 | font-size: 100px; 5 | } 6 | 7 | .chuck { 8 | text-align: center; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const chuck = require('../my_modules/chuck'); 4 | const db = require('../models'); 5 | 6 | /* GET home page. */ 7 | router.get('/', async (req, res, next) => { 8 | 9 | // Get a random Chuck Norris fact 10 | const chuckFact = await chuck.getChuckNorrisFact(); 11 | 12 | // Random Font 13 | const font = await db.Fonts.getRandomFont(); 14 | 15 | // Render the template 16 | res.render('index', {chuck: chuckFact, font}); 17 | 18 | }); 19 | 20 | module.exports = router; 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M4-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld Hello, world! 8 | hr 9 | 10 | // Chuck Norris 11 | .row 12 | .col-md-12 13 | .well.chuck= chuck 14 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Fonts = sequelize.define('Fonts', { 4 | name: DataTypes.STRING, 5 | link: DataTypes.STRING, 6 | css: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | 15 | Fonts.getRandomFont = async () => { 16 | const fontResult = await Fonts.findOne({ 17 | order: [ 18 | sequelize.fn('RANDOM') 19 | ] 20 | }); 21 | return fontResult.toJSON(); 22 | } 23 | 24 | return Fonts; 25 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/models/users.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Users = sequelize.define('Users', { 4 | username: DataTypes.STRING, 5 | password_digest: DataTypes.STRING, 6 | name: DataTypes.STRING, 7 | email: DataTypes.STRING, 8 | role: DataTypes.ENUM('Admin','User'), 9 | status: DataTypes.ENUM('In','Out','Busy') 10 | }, { 11 | classMethods: { 12 | associate: function(models) { 13 | // associations can be defined here 14 | } 15 | } 16 | }); 17 | return Users; 18 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "Chuck Norris facts", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "chuck", 11 | "norris", 12 | "awesome" 13 | ], 14 | "author": "PJ Evans", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "u5m3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.2", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.9", 12 | "express": "~4.15.5", 13 | "morgan": "~1.9.0", 14 | "pug": "2.0.0-beta11", 15 | "request": "^2.83.0", 16 | "request-promise-native": "^1.0.5", 17 | "sequelize": "^4.28.0", 18 | "serve-favicon": "~2.4.5", 19 | "sqlite3": "^3.1.13" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .heroHelloWorld { 3 | text-align: center; 4 | font-size: 100px; 5 | } 6 | 7 | .chuck { 8 | text-align: center; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const chuck = require('../my_modules/chuck'); 4 | const db = require('../models'); 5 | const config = require('../config/helloworld'); 6 | 7 | /* GET home page. */ 8 | router.get('/', async (req, res, next) => { 9 | 10 | // Get a random Chuck Norris fact 11 | const chuckFact = await chuck.getChuckNorrisFact(); 12 | 13 | // Random Font 14 | const font = await db.Fonts.getRandomFont(); 15 | 16 | // Translation 17 | const trans = await db.Translations.getRandomTranslation(config); 18 | 19 | // Render the template 20 | res.render('index', {chuck: chuckFact, font, greeting: trans}); 21 | 22 | }); 23 | 24 | module.exports = router; 25 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M5-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld= greeting.translation 8 | p.text-center That's #{greeting.language} for 'Hello, World' in the #{font.name} font 9 | 10 | hr 11 | 12 | // Chuck Norris 13 | .row 14 | .col-md-12 15 | .well.chuck= chuck 16 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | const chuck = require('./chuck'); 5 | 6 | // Handle every GET 7 | app.get('/', (req, res) => { 8 | 9 | // Immediately Invoked Function Expressions (IIFE) so we can use async 10 | (async () => { 11 | 12 | // Get a random Chuck Norris fact 13 | const chuckFact = await chuck.getChuckNorrisFact(); 14 | 15 | // Render the template 16 | res.render(__dirname + '/index.pug', {chuck: chuckFact}); 17 | 18 | })(); 19 | 20 | }); 21 | 22 | // Serve the stylesheet 23 | app.get('/style.css', (req, res) => { 24 | res.sendFile(__dirname + '/style.css'); 25 | }); 26 | 27 | 28 | // Start the server 29 | app.listen(8080, (err) => { 30 | console.log('Express running at http://127.0.0.1:8080/'); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Fonts = sequelize.define('Fonts', { 4 | name: DataTypes.STRING, 5 | link: DataTypes.STRING, 6 | css: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | 15 | Fonts.getRandomFont = async () => { 16 | const fontResult = await Fonts.findOne({ 17 | order: [ 18 | sequelize.fn('RANDOM') 19 | ] 20 | }); 21 | return fontResult.toJSON(); 22 | } 23 | 24 | return Fonts; 25 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/models/users.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Users = sequelize.define('Users', { 4 | username: DataTypes.STRING, 5 | password_digest: DataTypes.STRING, 6 | name: DataTypes.STRING, 7 | email: DataTypes.STRING, 8 | role: DataTypes.ENUM('Admin','User'), 9 | status: DataTypes.ENUM('In','Out','Busy') 10 | }, { 11 | classMethods: { 12 | associate: function(models) { 13 | // associations can be defined here 14 | } 15 | } 16 | }); 17 | return Users; 18 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "Chuck Norris facts", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "chuck", 11 | "norris", 12 | "awesome" 13 | ], 14 | "author": "PJ Evans", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "u5m3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.2", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.9", 12 | "express": "~4.15.5", 13 | "morgan": "~1.9.0", 14 | "pug": "2.0.0-beta11", 15 | "request": "^2.83.0", 16 | "request-promise-native": "^1.0.5", 17 | "sequelize": "^4.28.0", 18 | "serve-favicon": "~2.4.5", 19 | "sqlite3": "^3.1.13" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/public/favicon.png -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/public/javascripts/script.js: -------------------------------------------------------------------------------- 1 | 2 | $(() => { 3 | 4 | // Populate the weather 5 | $.getJSON('/weather', (data) => { 6 | $('.mypanel-weather').html(`${data.weather[0].main}
${data.main.temp}C
`); 7 | }); 8 | 9 | }) 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .heroHelloWorld { 3 | text-align: center; 4 | font-size: 100px; 5 | } 6 | 7 | .chuck { 8 | text-align: center; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/test.js: -------------------------------------------------------------------------------- 1 | 2 | const Sequelize = require('sequelize'); 3 | const db = require('./models'); 4 | 5 | (async () => { 6 | 7 | const translation = db.Translations; 8 | 9 | const transModel = await translation.findOne({ 10 | order: [ 11 | Sequelize.fn('RANDOM') 12 | ] 13 | }); 14 | console.log(transModel.language); 15 | 16 | })(); 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M6-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld= greeting.translation 8 | p.text-center That's #{greeting.language} for 'Hello, World' in the #{font.name} font 9 | 10 | hr 11 | 12 | // Panels 13 | .mypanel-weather= weather.weather[0].main 14 | 15 | // Chuck Norris 16 | .row 17 | .col-md-12 18 | .well.chuck= chuck 19 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | const chuck = require('./chuck'); 5 | 6 | // Handle every GET 7 | app.get('/', (req, res) => { 8 | 9 | // Immediately Invoked Function Expressions (IIFE) so we can use async 10 | (async () => { 11 | 12 | // Get a random Chuck Norris fact 13 | const chuckFact = await chuck.getChuckNorrisFact(); 14 | 15 | // Render the template 16 | res.render(__dirname + '/index.pug', {chuck: chuckFact}); 17 | 18 | })(); 19 | 20 | }); 21 | 22 | // Serve the stylesheet 23 | app.get('/style.css', (req, res) => { 24 | res.sendFile(__dirname + '/style.css'); 25 | }); 26 | 27 | 28 | // Start the server 29 | app.listen(8080, (err) => { 30 | console.log('Express running at http://127.0.0.1:8080/'); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | module.exports = function(sequelize, DataTypes) { 4 | var Fonts = sequelize.define('Fonts', { 5 | name: DataTypes.STRING, 6 | link: DataTypes.STRING, 7 | css: DataTypes.STRING 8 | }, { 9 | classMethods: { 10 | associate: function(models) { 11 | // associations can be defined here 12 | } 13 | } 14 | }); 15 | 16 | Fonts.getRandomFont = async () => { 17 | const fontResult = await Fonts.findOne({ 18 | order: [ 19 | sequelize.fn('RANDOM') 20 | ] 21 | }); 22 | return fontResult.toJSON(); 23 | }; 24 | 25 | return Fonts; 26 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloworld", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "bcrypt": "^1.0.3", 10 | "bcrypt-promise": "^2.0.0", 11 | "body-parser": "~1.18.2", 12 | "cookie-parser": "~1.4.3", 13 | "cookie-session": "^2.0.0-beta.3", 14 | "csurf": "^1.9.0", 15 | "debug": "~2.6.9", 16 | "express": "~4.15.5", 17 | "morgan": "~1.9.0", 18 | "pug": "2.0.0-beta11", 19 | "request": "^2.83.0", 20 | "request-promise-native": "^1.0.5", 21 | "sequelize": "^4.31.2", 22 | "serve-favicon": "~2.4.5", 23 | "sqlite3": "^3.1.13" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/public/favicon.ico -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/public/javascripts/script.js: -------------------------------------------------------------------------------- 1 | 2 | $(() => { 3 | 4 | // Populate the weather 5 | $.getJSON('/weather', (data) => { 6 | $('.mypanel-weather').html(`${data.weather[0].main}
${data.main.temp}C
`); 7 | }); 8 | 9 | }) 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .heroHelloWorld { 3 | text-align: center; 4 | font-size: 100px; 5 | } 6 | 7 | .chuck { 8 | text-align: center; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld= greeting.translation 8 | p.text-center That's #{greeting.language} for 'Hello, World!' in the #{font.name} font 9 | 10 | hr 11 | 12 | // Panels 13 | .mypanel-weather 14 | 15 | // Chuck Norris 16 | .row 17 | .col-md-12 18 | .well.chuck= chuck 19 | 20 | script(src="javascripts/script.js") -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/views/login.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Login 5 | if authFailure 6 | div.alert.alert-danger Username or password incorrect 7 | 8 | form(action='login',method='POST') 9 | 10 | input(type="hidden", name="_csrf", value=csrf) 11 | 12 | div.form-group 13 | label.control-label(for="username") Username 14 | input#username.form-control(type="text",name="username",value=username) 15 | 16 | div.form-group 17 | label.control-label(for="password") Password 18 | input#password.form-control(type="password",name="password") 19 | 20 | button.btn.btn-primary Log In 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M7-helloworld/views/logout.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Logout 5 | p You have been logged out - thanks for playing! 6 | p 7 | a.btn.btn-default(href='login') Log In Again -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | const chuck = require('./chuck'); 5 | 6 | // Handle every GET 7 | app.get('/', (req, res) => { 8 | 9 | // Immediately Invoked Function Expressions (IIFE) so we can use async 10 | (async () => { 11 | 12 | // Get a random Chuck Norris fact 13 | const chuckFact = await chuck.getChuckNorrisFact(); 14 | 15 | // Render the template 16 | res.render(__dirname + '/index.pug', {chuck: chuckFact}); 17 | 18 | })(); 19 | 20 | }); 21 | 22 | // Serve the stylesheet 23 | app.get('/style.css', (req, res) => { 24 | res.sendFile(__dirname + '/style.css'); 25 | }); 26 | 27 | 28 | // Start the server 29 | app.listen(8080, (err) => { 30 | console.log('Express running at http://127.0.0.1:8080/'); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function(sequelize, DataTypes) { 3 | var Fonts = sequelize.define('Fonts', { 4 | name: DataTypes.STRING, 5 | link: DataTypes.STRING, 6 | css: DataTypes.STRING 7 | }, { 8 | classMethods: { 9 | associate: function(models) { 10 | // associations can be defined here 11 | } 12 | } 13 | }); 14 | 15 | Fonts.getRandomFont = async () => { 16 | const fontResult = await Fonts.findOne({ 17 | order: [ 18 | sequelize.fn('RANDOM') 19 | ] 20 | }); 21 | return fontResult.toJSON(); 22 | } 23 | 24 | return Fonts; 25 | }; -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "Chuck Norris facts", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "chuck", 11 | "norris", 12 | "awesome" 13 | ], 14 | "author": "PJ Evans", 15 | "license": "MIT" 16 | } 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "u5m3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "bcrypt": "^1.0.3", 10 | "bcrypt-promise": "^2.0.0", 11 | "body-parser": "~1.18.2", 12 | "cookie-parser": "~1.4.3", 13 | "cookie-session": "^2.0.0-beta.3", 14 | "csurf": "^1.9.0", 15 | "debug": "~2.6.9", 16 | "express": "~4.15.5", 17 | "morgan": "~1.9.0", 18 | "pug": "2.0.0-beta11", 19 | "request": "^2.83.0", 20 | "request-promise-native": "^1.0.5", 21 | "sequelize": "^4.28.0", 22 | "serve-favicon": "~2.4.5", 23 | "sqlite3": "^3.1.13" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/public/images/favicon.png -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/public/javascripts/script.js: -------------------------------------------------------------------------------- 1 | $(() => { 2 | 3 | // Populate the weather 4 | $.getJSON('/weather', (data) => { 5 | $('.mypanel-weather').html(`${data.current_observation.weather}
${data.current_observation.temperature_string}
`); 6 | }); 7 | 8 | }) 9 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | .heroHelloWorld { 3 | text-align: center; 4 | font-size: 100px; 5 | } 6 | 7 | .chuck { 8 | text-align: center; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/test.js: -------------------------------------------------------------------------------- 1 | 2 | const Sequelize = require('sequelize'); 3 | const db = require('./models'); 4 | 5 | (async () => { 6 | 7 | const translation = db.Translations; 8 | 9 | const transModel = await translation.findOne({ 10 | order: [ 11 | Sequelize.fn('RANDOM') 12 | ] 13 | }); 14 | console.log(transModel.language); 15 | 16 | })(); 17 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld= greeting.translation 8 | p.text-center That's #{greeting.language} for 'Hello, World' in the #{font.name} font 9 | 10 | hr 11 | 12 | // Chuck Norris 13 | .row 14 | .col-md-12 15 | .well.chuck= chuck 16 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/views/login.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Login 5 | if authFailure 6 | div.alert.alert-danger Username or password incorrect 7 | 8 | form(action='login',method='POST') 9 | 10 | input(type="hidden", name="_csrf", value=csrf) 11 | 12 | div.form-group 13 | label.control-label(for="username") Username 14 | input#username.form-control(type="text",name="username",value=username) 15 | 16 | div.form-group 17 | label.control-label(for="password") Password 18 | input#password.form-control(type="password",name="password") 19 | 20 | button.btn.btn-primary Log In 21 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/views/logout.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Logout 5 | p You have been logged out - thanks for playing! 6 | p 7 | a.btn.btn-default(href='login') Log In Again -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/views/users/create.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Create a New User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User created successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='create',method='POST') 13 | 14 | include form.pug 15 | 16 | button.btn.btn-primary Create 17 | | 18 | a.btn.btn-default(href="/users/") Cancel -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/views/users/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Users 6 | if alert 7 | case alert.type 8 | when 'deleted' 9 | div.alert.alert-success User deleted successfully 10 | when 'self' 11 | div.alert.alert-warning You cannot delete yourself 12 | table.table.table-hover 13 | thead 14 | th Username 15 | th Name 16 | th Email 17 | th Role 18 | th Status 19 | tbody 20 | each user in users 21 | tr(onclick="window.location = '/users/" + user.username + "/'") 22 | td= user.username 23 | td= user.name 24 | td= user.email 25 | td= user.role 26 | td= user.status 27 | a.btn.btn-primary(href='/users/create') Add New User 28 | -------------------------------------------------------------------------------- /Unit 5 - Building Better Web Apps With Express/U5-M8-M9-helloworld/views/users/update.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Update User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User modified successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='.',method="POST") 13 | input(type='hidden',name='id',value=fields.id) 14 | 15 | include form.pug 16 | 17 | button.btn.btn-primary Update 18 | | 19 | a.btn.btn-default(href="/users/") Cancel 20 | button#delete.btn.btn-danger.pull-right Delete 21 | 22 | script. 23 | $('#delete').on('click',function(){ 24 | if(confirm('Are you sure?')) { 25 | $('form').attr('action','delete').submit(); 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qchat", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.2", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.9", 12 | "express": "~4.15.5", 13 | "morgan": "~1.9.0", 14 | "pug": "2.0.0-beta11", 15 | "serve-favicon": "~2.4.5", 16 | "socket.io": "^2.0.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/public/javascripts/script.js: -------------------------------------------------------------------------------- 1 | 2 | var socket; 3 | 4 | // Connect socket when the document has loaded 5 | $(() => { 6 | 7 | socket = io.connect(); 8 | 9 | // On receiving a status change message, update the relevant user's status 10 | socket.on('update', (data) => { 11 | console.log(data); 12 | $('textarea').append(`${data.handle}: ${data.update}` + "\r\n"); 13 | }); 14 | 15 | }); 16 | 17 | // Send an update 18 | function sendUpdate() { 19 | 20 | const handle = $('INPUT[name=handle]').val(); 21 | const update = $('INPUT[name=update]').val(); 22 | const payload = {'handle': handle, 'update': update}; 23 | socket.emit('update', payload); 24 | $('INPUT[name=update]').val(''); 25 | 26 | return false; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | padding: 50px; 4 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 5 | } 6 | 7 | a { 8 | color: #00B7FF; 9 | } 10 | 11 | textarea { 12 | width: 400px; 13 | height: 200px; 14 | } 15 | 16 | input { 17 | width: 400px; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/views/index.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Quick Chat 5 | form(onsubmit='return(sendUpdate())') 6 | p 7 | | Your Username 8 | br 9 | input(type='text',name='handle',required) 10 | p: textarea(name='chatwindow',disabled) 11 | p 12 | | Update Status 13 | br 14 | input(type='text',name='update',required) 15 | button Send 16 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/views/layout.pug: -------------------------------------------------------------------------------- 1 | 2 | doctype html 3 | html 4 | head 5 | title Let's Chat 6 | 7 | link(rel='stylesheet', href='/stylesheets/style.css') 8 | 9 | // JQuery 10 | script(src='https://code.jquery.com/jquery-3.2.1.min.js') 11 | 12 | // Socket.io client 13 | script(src='https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.slim.js') 14 | 15 | // Our code 16 | script(src="/javascripts/script.js") 17 | 18 | body 19 | block content 20 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M2-qchat/websockets.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = (server) => { 3 | 4 | // Create a socket instance 5 | var io = require('socket.io')(server); 6 | 7 | // Set up events 8 | io.on('connection', (socket) => { 9 | 10 | // Handle an incoming status change 11 | socket.on('update', function (data) { 12 | 13 | // Broadcast to everyone (including self) 14 | console.log(data); 15 | io.emit('update', data); 16 | 17 | }); 18 | 19 | }); 20 | 21 | }; 22 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M3-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | const chuck = require('./chuck'); 5 | 6 | // Handle every GET 7 | app.get('/', (req, res) => { 8 | 9 | // Immediately Invoked Function Expressions (IIFE) so we can use async 10 | (async () => { 11 | 12 | // Get a random Chuck Norris fact 13 | const chuckFact = await chuck.getChuckNorrisFact(); 14 | 15 | // Render the template 16 | res.render(__dirname + '/index.pug', {chuck: chuckFact}); 17 | 18 | })(); 19 | 20 | }); 21 | 22 | // Serve the stylesheet 23 | app.get('/style.css', (req, res) => { 24 | res.sendFile(__dirname + '/style.css'); 25 | }); 26 | 27 | 28 | // Start the server 29 | app.listen(8080, (err) => { 30 | console.log('Express running at http://127.0.0.1:8080/'); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | module.exports = function(sequelize, DataTypes) { 4 | var Fonts = sequelize.define('Fonts', { 5 | name: DataTypes.STRING, 6 | link: DataTypes.STRING, 7 | css: DataTypes.STRING 8 | }, { 9 | classMethods: { 10 | associate: function(models) { 11 | // associations can be defined here 12 | } 13 | } 14 | }); 15 | 16 | Fonts.getRandomFont = async () => { 17 | const fontResult = await Fonts.findOne({ 18 | order: [ 19 | sequelize.fn('RANDOM') 20 | ] 21 | }); 22 | return fontResult.toJSON(); 23 | }; 24 | 25 | return Fonts; 26 | }; -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloworld", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "bcrypt": "^1.0.3", 10 | "bcrypt-promise": "^2.0.0", 11 | "body-parser": "~1.18.2", 12 | "cookie-parser": "~1.4.3", 13 | "cookie-session": "^2.0.0-beta.3", 14 | "csurf": "^1.9.0", 15 | "debug": "~2.6.9", 16 | "express": "~4.15.5", 17 | "morgan": "~1.9.0", 18 | "nodemailer": "^4.4.2", 19 | "pug": "2.0.0-beta11", 20 | "request": "^2.83.0", 21 | "request-promise-native": "^1.0.5", 22 | "sequelize": "^4.31.2", 23 | "serve-favicon": "~2.4.5", 24 | "socket.io": "^2.0.4", 25 | "sqlite3": "^3.1.13" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M3-helloworld/public/favicon.ico -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/public/javascripts/script.js: -------------------------------------------------------------------------------- 1 | 2 | var socket; 3 | 4 | $(() => { 5 | 6 | socket = io.connect(); 7 | 8 | // On receiving a time broadcast, update the clock and date 9 | socket.on('time', (data) => { 10 | $('.mypanel-clock').html(data.time); 11 | $('.date-date').html(data.date); 12 | $('.date-month').html(data.month); 13 | }); 14 | 15 | // Populate the weather 16 | $.getJSON('/weather', (data) => { 17 | $('.mypanel-weather').html(`${data.weather[0].main}
${data.main.temp}C
`); 18 | }); 19 | 20 | }) 21 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | .table-hover { 2 | cursor: pointer; 3 | } 4 | 5 | .heroHelloWorld { 6 | text-align: center; 7 | font-size: 100px; 8 | } 9 | 10 | .fixed-ratio-resize { 11 | max-width: 100%; 12 | height: auto; 13 | width: auto; 14 | } 15 | 16 | .mypanel { 17 | height:150px; 18 | } 19 | 20 | .panel-body { 21 | display: flex; 22 | align-items: center; 23 | justify-content: center; 24 | } 25 | 26 | .mypanel-clock { 27 | font-size: 60px; 28 | font-weight: bold; 29 | } 30 | 31 | .mypanel-date { 32 | font-size: 50px; 33 | font-weight: bold; 34 | } 35 | 36 | .mypanel-weather { 37 | display: block; 38 | text-align: center; 39 | font-size: 20px; 40 | font-weight: bold; 41 | } 42 | 43 | .status-button { 44 | padding:0; 45 | } 46 | 47 | .chuck { 48 | text-align: center; 49 | } -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/routes/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const chuck = require('../my_modules/chuck'); 4 | const db = require('../models'); 5 | const config = require('../config/helloworld'); 6 | 7 | /* GET a Chuck Norris fact */ 8 | router.get('/chuck', async (req, res, next) => { 9 | 10 | // Get a random Chuck Norris fact 11 | const chuckFact = await chuck.getChuckNorrisFact(); 12 | 13 | // Render the template 14 | res.json({chuck: chuckFact}); 15 | 16 | }); 17 | 18 | /* GET a Hello World */ 19 | router.get('/hello', async (req, res, next) => { 20 | 21 | // Translation 22 | const trans = await db.Translations.getRandomTranslation(config); 23 | 24 | // Render the template 25 | res.json(trans); 26 | 27 | }); 28 | 29 | 30 | module.exports = router; 31 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/views/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | 6 | // A nice, friendly welcome 7 | h1.heroHelloWorld= greeting.translation 8 | p.text-center That's #{greeting.language} for 'Hello, World!' in the #{font.name} font 9 | 10 | hr 11 | 12 | // Panels 13 | .row 14 | .col-md-4 15 | .panel.panel-default 16 | .panel-body.mypanel 17 | .mypanel-clock 18 | .panel-footer.text-center 19 | | Server Time 20 | 21 | .col-md-4 22 | .panel.panel-default 23 | .panel-body.mypanel 24 | .mypanel-date 25 | span.date-month 26 | span 27 | span.date-date 28 | .panel-footer.text-center 29 | | Server Date 30 | 31 | .col-md-4 32 | .panel.panel-default 33 | .panel-body.mypanel 34 | .mypanel-weather 35 | .panel-footer.text-center 36 | | Weather 37 | 38 | // Chuck Norris 39 | .row 40 | .col-md-12 41 | .well.chuck= chuck 42 | 43 | script(src="javascripts/script.js") -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/views/login.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Login 5 | if authFailure 6 | div.alert.alert-danger Username or password incorrect 7 | 8 | form(action='login',method='POST') 9 | 10 | input(type="hidden", name="_csrf", value=csrf) 11 | 12 | div.form-group 13 | label.control-label(for="username") Username 14 | input#username.form-control(type="text",name="username",value=username) 15 | 16 | div.form-group 17 | label.control-label(for="password") Password 18 | input#password.form-control(type="password",name="password") 19 | 20 | button.btn.btn-primary Log In 21 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/views/logout.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Logout 5 | p You have been logged out - thanks for playing! 6 | p 7 | a.btn.btn-default(href='login') Log In Again -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/views/users/create.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Create a New User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User created successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='create',method='POST') 13 | 14 | include form.pug 15 | 16 | button.btn.btn-primary Create 17 | | 18 | a.btn.btn-default(href="/users/") Cancel -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/views/users/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Users 6 | if alert 7 | case alert.type 8 | when 'deleted' 9 | div.alert.alert-success User deleted successfully 10 | when 'self' 11 | div.alert.alert-warning You cannot delete yourself 12 | table.table.table-hover 13 | thead 14 | th Username 15 | th Name 16 | th Email 17 | th Role 18 | th Status 19 | tbody 20 | each user in users 21 | tr(onclick="window.location = '/users/" + user.username + "/'") 22 | td= user.username 23 | td= user.name 24 | td= user.email 25 | td= user.role 26 | td= user.status 27 | a.btn.btn-primary(href='/users/create') Add New User 28 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M3-helloworld/views/users/update.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Update User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User modified successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='.',method="POST") 13 | input(type='hidden',name='id',value=fields.id) 14 | 15 | include form.pug 16 | 17 | button.btn.btn-primary Update 18 | | 19 | a.btn.btn-default(href="/users/") Cancel 20 | button#delete.btn.btn-danger.pull-right Delete 21 | 22 | script. 23 | $('#delete').on('click',function(){ 24 | if(confirm('Are you sure?')) { 25 | $('form').attr('action','delete').submit(); 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "db/hello_world.sqlite", 5 | "operatorsAliases": false, 6 | "logging": false 7 | }, 8 | "test": { 9 | "dialect": "sqlite", 10 | "storage": "db/hello_world.sqlite", 11 | "operatorsAliases": false, 12 | "logging": false 13 | }, 14 | "production": { 15 | "dialect": "sqlite", 16 | "storage": "db/hello_world.sqlite", 17 | "operatorsAliases": false, 18 | "logging": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M4-helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/index.js: -------------------------------------------------------------------------------- 1 | 2 | const express = require('express'); 3 | const app = express(); 4 | const chuck = require('./chuck'); 5 | 6 | // Handle every GET 7 | app.get('/', (req, res) => { 8 | 9 | // Immediately Invoked Function Expressions (IIFE) so we can use async 10 | (async () => { 11 | 12 | // Get a random Chuck Norris fact 13 | const chuckFact = await chuck.getChuckNorrisFact(); 14 | 15 | // Render the template 16 | res.render(__dirname + '/index.pug', {chuck: chuckFact}); 17 | 18 | })(); 19 | 20 | }); 21 | 22 | // Serve the stylesheet 23 | app.get('/style.css', (req, res) => { 24 | res.sendFile(__dirname + '/style.css'); 25 | }); 26 | 27 | 28 | // Start the server 29 | app.listen(8080, (err) => { 30 | console.log('Express running at http://127.0.0.1:8080/'); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | module.exports = function(sequelize, DataTypes) { 4 | var Fonts = sequelize.define('Fonts', { 5 | name: DataTypes.STRING, 6 | link: DataTypes.STRING, 7 | css: DataTypes.STRING 8 | }, { 9 | classMethods: { 10 | associate: function(models) { 11 | // associations can be defined here 12 | } 13 | } 14 | }); 15 | 16 | Fonts.getRandomFont = async () => { 17 | const fontResult = await Fonts.findOne({ 18 | order: [ 19 | sequelize.fn('RANDOM') 20 | ] 21 | }); 22 | return fontResult.toJSON(); 23 | }; 24 | 25 | return Fonts; 26 | }; -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloworld", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "bcrypt": "^1.0.3", 10 | "bcrypt-promise": "^2.0.0", 11 | "body-parser": "~1.18.2", 12 | "cookie-parser": "~1.4.3", 13 | "cookie-session": "^2.0.0-beta.3", 14 | "csurf": "^1.9.0", 15 | "debug": "~2.6.9", 16 | "express": "~4.15.5", 17 | "morgan": "~1.9.0", 18 | "nodemailer": "^4.4.2", 19 | "pug": "2.0.0-beta11", 20 | "request": "^2.83.0", 21 | "request-promise-native": "^1.0.5", 22 | "sequelize": "^4.31.2", 23 | "serve-favicon": "~2.4.5", 24 | "socket.io": "^2.0.4", 25 | "sqlite3": "^3.1.13" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M4-helloworld/public/favicon.ico -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/public/images/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M4-helloworld/public/images/admin.png -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/public/images/jane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M4-helloworld/public/images/jane.png -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/public/images/john.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M4-helloworld/public/images/john.png -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/public/images/patrick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M4-helloworld/public/images/patrick.png -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/public/images/pj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M4-helloworld/public/images/pj.png -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/public/images/trish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/Unit 6 - WebSockets/U6-M4-helloworld/public/images/trish.png -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | .table-hover { 2 | cursor: pointer; 3 | } 4 | 5 | .heroHelloWorld { 6 | text-align: center; 7 | font-size: 100px; 8 | } 9 | 10 | .fixed-ratio-resize { 11 | max-width: 100%; 12 | height: auto; 13 | width: auto; 14 | } 15 | 16 | .mypanel { 17 | height:150px; 18 | } 19 | 20 | .panel-body { 21 | display: flex; 22 | align-items: center; 23 | justify-content: center; 24 | } 25 | 26 | .mypanel-clock { 27 | font-size: 60px; 28 | font-weight: bold; 29 | } 30 | 31 | .mypanel-date { 32 | font-size: 50px; 33 | font-weight: bold; 34 | } 35 | 36 | .mypanel-weather { 37 | display: block; 38 | text-align: center; 39 | font-size: 20px; 40 | font-weight: bold; 41 | } 42 | 43 | .status-button { 44 | padding:0; 45 | } 46 | 47 | .chuck { 48 | text-align: center; 49 | } -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/routes/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const chuck = require('../my_modules/chuck'); 4 | const db = require('../models'); 5 | const config = require('../config/helloworld'); 6 | 7 | /* GET a Chuck Norris fact */ 8 | router.get('/chuck', async (req, res, next) => { 9 | 10 | // Get a random Chuck Norris fact 11 | const chuckFact = await chuck.getChuckNorrisFact(); 12 | 13 | // Render the template 14 | res.json({chuck: chuckFact}); 15 | 16 | }); 17 | 18 | /* GET a Hello World */ 19 | router.get('/hello', async (req, res, next) => { 20 | 21 | // Translation 22 | const trans = await db.Translations.getRandomTranslation(config); 23 | 24 | // Render the template 25 | res.json(trans); 26 | 27 | }); 28 | 29 | 30 | module.exports = router; 31 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/views/login.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Login 5 | if authFailure 6 | div.alert.alert-danger Username or password incorrect 7 | 8 | form(action='login',method='POST') 9 | 10 | input(type="hidden", name="_csrf", value=csrf) 11 | 12 | div.form-group 13 | label.control-label(for="username") Username 14 | input#username.form-control(type="text",name="username",value=username) 15 | 16 | div.form-group 17 | label.control-label(for="password") Password 18 | input#password.form-control(type="password",name="password") 19 | 20 | button.btn.btn-primary Log In 21 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/views/logout.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Logout 5 | p You have been logged out - thanks for playing! 6 | p 7 | a.btn.btn-default(href='login') Log In Again -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/views/users/create.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Create a New User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User created successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='create',method='POST') 13 | 14 | include form.pug 15 | 16 | button.btn.btn-primary Create 17 | | 18 | a.btn.btn-default(href="/users/") Cancel -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/views/users/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Users 6 | if alert 7 | case alert.type 8 | when 'deleted' 9 | div.alert.alert-success User deleted successfully 10 | when 'self' 11 | div.alert.alert-warning You cannot delete yourself 12 | table.table.table-hover 13 | thead 14 | th Username 15 | th Name 16 | th Email 17 | th Role 18 | th Status 19 | tbody 20 | each user in users 21 | tr(onclick="window.location = '/users/" + user.username + "/'") 22 | td= user.username 23 | td= user.name 24 | td= user.email 25 | td= user.role 26 | td= user.status 27 | a.btn.btn-primary(href='/users/create') Add New User 28 | -------------------------------------------------------------------------------- /Unit 6 - WebSockets/U6-M4-helloworld/views/users/update.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Update User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User modified successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='.',method="POST") 13 | input(type='hidden',name='id',value=fields.id) 14 | 15 | include form.pug 16 | 17 | button.btn.btn-primary Update 18 | | 19 | a.btn.btn-default(href="/users/") Cancel 20 | button#delete.btn.btn-danger.pull-right Delete 21 | 22 | script. 23 | $('#delete').on('click',function(){ 24 | if(confirm('Are you sure?')) { 25 | $('form').attr('action','delete').submit(); 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /Unit 7 - Node In The Real World/U7-M5-chuckfact/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = (cb) => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname . '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }); 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Unit 7 - Node In The Real World/U7-M5-chuckfact/index.js: -------------------------------------------------------------------------------- 1 | 2 | const chuck = require('./chuck.js'); 3 | 4 | (async () => { 5 | 6 | const line = await chuck.getChuckNorrisFact(); 7 | console.log(line); 8 | 9 | })(); 10 | -------------------------------------------------------------------------------- /helloworld/config/config.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "development": { 4 | "dialect": "sqlite", 5 | "storage": "db/hello_world.sqlite", 6 | "operatorsAliases": false, 7 | "logging": false 8 | }, 9 | "test": { 10 | "dialect": "sqlite", 11 | "storage": "db/hello_world.sqlite", 12 | "operatorsAliases": false, 13 | "logging": false 14 | }, 15 | "production": { 16 | "dialect": "sqlite", 17 | "storage": "db/hello_world.sqlite", 18 | "operatorsAliases": false, 19 | "logging": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /helloworld/config/helloworld.json: -------------------------------------------------------------------------------- 1 | { 2 | "yandex": { 3 | "apikey": "YANDEX API KEY GOES HERE", 4 | "uri": "https://translate.yandex.net/api/v1.5/tr.json/translate" 5 | }, 6 | "wunderground": { 7 | "apikey": "WUNDERGROUND API KEY GOES HERE", 8 | "uri": "http://api.wunderground.com/api/", 9 | "city": "UK/London" 10 | } 11 | } -------------------------------------------------------------------------------- /helloworld/db/hello_world.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/helloworld/db/hello_world.sqlite -------------------------------------------------------------------------------- /helloworld/migrations/20171122123812-create-fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Fonts', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | name: { 12 | type: Sequelize.STRING 13 | }, 14 | link: { 15 | type: Sequelize.STRING 16 | }, 17 | css: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Fonts'); 32 | } 33 | }; -------------------------------------------------------------------------------- /helloworld/migrations/20171122123855-create-translations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: function(queryInterface, Sequelize) { 4 | return queryInterface.createTable('Translations', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | language: { 12 | type: Sequelize.STRING 13 | }, 14 | languageCode: { 15 | type: Sequelize.STRING 16 | }, 17 | translation: { 18 | type: Sequelize.STRING 19 | }, 20 | createdAt: { 21 | allowNull: false, 22 | type: Sequelize.DATE 23 | }, 24 | updatedAt: { 25 | allowNull: false, 26 | type: Sequelize.DATE 27 | } 28 | }); 29 | }, 30 | down: function(queryInterface, Sequelize) { 31 | return queryInterface.dropTable('Translations'); 32 | } 33 | }; -------------------------------------------------------------------------------- /helloworld/models/fonts.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | module.exports = function(sequelize, DataTypes) { 4 | var Fonts = sequelize.define('Fonts', { 5 | name: DataTypes.STRING, 6 | link: DataTypes.STRING, 7 | css: DataTypes.STRING 8 | }, { 9 | classMethods: { 10 | associate: function(models) { 11 | // associations can be defined here 12 | } 13 | } 14 | }); 15 | 16 | Fonts.getRandomFont = async () => { 17 | const fontResult = await Fonts.findOne({ 18 | order: [ 19 | sequelize.fn('RANDOM') 20 | ] 21 | }); 22 | return fontResult.toJSON(); 23 | }; 24 | 25 | return Fonts; 26 | }; -------------------------------------------------------------------------------- /helloworld/my_modules/chuck/chuck.js: -------------------------------------------------------------------------------- 1 | 2 | const readline = require('readline'); 3 | const fs = require('fs'); 4 | 5 | exports.getChuckNorrisFact = () => { 6 | 7 | return new Promise((resolve) => { 8 | 9 | // A message of the day 10 | let chuckCounter = 0; 11 | 12 | const chuckLine = Math.floor(Math.random() * (86)) + 1; 13 | 14 | const rl = readline.createInterface({ 15 | input: fs.createReadStream(__dirname + '/chuck.txt') 16 | }); 17 | 18 | rl.on('line', (line) => { 19 | 20 | if(chuckCounter == chuckLine) { 21 | resolve(line); 22 | } 23 | 24 | chuckCounter++; 25 | 26 | }) 27 | 28 | }); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /helloworld/my_modules/chuck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chuck", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "chuck.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "PJ Evans", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /helloworld/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helloworld", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "bcrypt": "^1.0.3", 10 | "bcrypt-promise": "^2.0.0", 11 | "body-parser": "~1.18.2", 12 | "cookie-parser": "~1.4.3", 13 | "cookie-session": "^2.0.0-beta.3", 14 | "csurf": "^1.9.0", 15 | "debug": "~2.6.9", 16 | "express": "~4.15.5", 17 | "morgan": "~1.9.0", 18 | "nodemailer": "^4.4.2", 19 | "pug": "2.0.0-beta11", 20 | "request": "^2.83.0", 21 | "request-promise-native": "^1.0.5", 22 | "sequelize": "^4.31.2", 23 | "serve-favicon": "~2.4.5", 24 | "socketio": "^1.0.0", 25 | "sqlite3": "^3.1.13" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /helloworld/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/helloworld/public/favicon.ico -------------------------------------------------------------------------------- /helloworld/public/images/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/helloworld/public/images/admin.png -------------------------------------------------------------------------------- /helloworld/public/images/jane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/helloworld/public/images/jane.png -------------------------------------------------------------------------------- /helloworld/public/images/john.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/helloworld/public/images/john.png -------------------------------------------------------------------------------- /helloworld/public/images/patrick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/helloworld/public/images/patrick.png -------------------------------------------------------------------------------- /helloworld/public/images/pj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/helloworld/public/images/pj.png -------------------------------------------------------------------------------- /helloworld/public/images/trish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrpjevans/Node.js-In-Motion/5ce56a27af0478e62f8c833d824cc30c2cb58ff9/helloworld/public/images/trish.png -------------------------------------------------------------------------------- /helloworld/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | .table-hover { 2 | cursor: pointer; 3 | } 4 | 5 | .heroHelloWorld { 6 | text-align: center; 7 | font-size: 100px; 8 | } 9 | 10 | .fixed-ratio-resize { 11 | max-width: 100%; 12 | height: auto; 13 | width: auto; 14 | } 15 | 16 | .mypanel { 17 | height:150px; 18 | } 19 | 20 | .panel-body { 21 | display: flex; 22 | align-items: center; 23 | justify-content: center; 24 | } 25 | 26 | .mypanel-clock { 27 | font-size: 60px; 28 | font-weight: bold; 29 | } 30 | 31 | .mypanel-date { 32 | font-size: 50px; 33 | font-weight: bold; 34 | } 35 | 36 | .mypanel-weather { 37 | display: block; 38 | text-align: center; 39 | font-size: 20px; 40 | font-weight: bold; 41 | } 42 | 43 | .status-button { 44 | padding:0; 45 | } 46 | 47 | .chuck { 48 | text-align: center; 49 | } -------------------------------------------------------------------------------- /helloworld/routes/api.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const chuck = require('../my_modules/chuck'); 4 | const db = require('../models'); 5 | const config = require('../config/helloworld'); 6 | 7 | /* GET a Chuck Norris fact */ 8 | router.get('/chuck', async (req, res, next) => { 9 | 10 | // Get a random Chuck Norris fact 11 | const chuckFact = await chuck.getChuckNorrisFact(); 12 | 13 | // Render the template 14 | res.json({chuck: chuckFact}); 15 | 16 | }); 17 | 18 | /* GET a Hello World */ 19 | router.get('/hello', async (req, res, next) => { 20 | 21 | // Translation 22 | const trans = await db.Translations.getRandomTranslation(config); 23 | 24 | // Render the template 25 | res.json(trans); 26 | 27 | }); 28 | 29 | 30 | module.exports = router; 31 | -------------------------------------------------------------------------------- /helloworld/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /helloworld/views/login.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Login 5 | if authFailure 6 | div.alert.alert-danger Username or password incorrect 7 | 8 | form(action='login',method='POST') 9 | 10 | input(type="hidden", name="_csrf", value=csrf) 11 | 12 | div.form-group 13 | label.control-label(for="username") Username 14 | input#username.form-control(type="text",name="username",value=username) 15 | 16 | div.form-group 17 | label.control-label(for="password") Password 18 | input#password.form-control(type="password",name="password") 19 | 20 | button.btn.btn-primary Log In 21 | -------------------------------------------------------------------------------- /helloworld/views/logout.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Logout 5 | p You have been logged out - thanks for playing! 6 | p 7 | a.btn.btn-default(href='login') Log In Again -------------------------------------------------------------------------------- /helloworld/views/ousers/create.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Create a New User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User created successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='create',method='POST') 13 | 14 | include form.pug 15 | 16 | button.btn.btn-primary Create 17 | | 18 | a.btn.btn-default(href="/users/") Cancel -------------------------------------------------------------------------------- /helloworld/views/ousers/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Users 6 | if alert 7 | case alert.type 8 | when 'deleted' 9 | div.alert.alert-success User deleted successfully 10 | when 'self' 11 | div.alert.alert-warning You cannot delete yourself 12 | table.table.table-hover 13 | thead 14 | th Username 15 | th Name 16 | th Email 17 | th Role 18 | th Status 19 | tbody 20 | each user in users 21 | tr(onclick="window.location = '/users/" + user.username + "/'") 22 | td= user.username 23 | td= user.name 24 | td= user.email 25 | td= user.role 26 | td= user.status 27 | a.btn.btn-primary(href='/users/create') Add New User 28 | -------------------------------------------------------------------------------- /helloworld/views/ousers/update.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Update User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User modified successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='.',method="POST") 13 | input(type='hidden',name='id',value=fields.id) 14 | 15 | include form.pug 16 | 17 | button.btn.btn-primary Update 18 | | 19 | a.btn.btn-default(href="/users/") Cancel 20 | button#delete.btn.btn-danger.pull-right Delete 21 | 22 | script. 23 | $('#delete').on('click',function(){ 24 | if(confirm('Are you sure?')) { 25 | $('form').attr('action','delete').submit(); 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /helloworld/views/users/create.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Create a New User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User created successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='create',method='POST') 13 | 14 | include form.pug 15 | 16 | button.btn.btn-primary Create 17 | | 18 | a.btn.btn-default(href="/users/") Cancel -------------------------------------------------------------------------------- /helloworld/views/users/index.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Users 6 | if alert 7 | case alert.type 8 | when 'deleted' 9 | div.alert.alert-success User deleted successfully 10 | when 'self' 11 | div.alert.alert-warning You cannot delete yourself 12 | table.table.table-hover 13 | thead 14 | th Username 15 | th Name 16 | th Email 17 | th Role 18 | th Status 19 | tbody 20 | each user in users 21 | tr(onclick="window.location = '/users/" + user.username + "/'") 22 | td= user.username 23 | td= user.name 24 | td= user.email 25 | td= user.role 26 | td= user.status 27 | a.btn.btn-primary(href='/users/create') Add New User 28 | -------------------------------------------------------------------------------- /helloworld/views/users/update.pug: -------------------------------------------------------------------------------- 1 | 2 | extends ../layout 3 | 4 | block content 5 | h1 Update User 6 | if alert 7 | if alert.type == 'success' 8 | div.alert.alert-success User modified successfully 9 | else if alert.type == 'validation' 10 | div.alert.alert-warning Please check the form 11 | 12 | form(action='.',method="POST") 13 | input(type='hidden',name='id',value=fields.id) 14 | 15 | include form.pug 16 | 17 | button.btn.btn-primary Update 18 | | 19 | a.btn.btn-default(href="/users/") Cancel 20 | button#delete.btn.btn-danger.pull-right Delete 21 | 22 | script. 23 | $('#delete').on('click',function(){ 24 | if(confirm('Are you sure?')) { 25 | $('form').attr('action','delete').submit(); 26 | } 27 | }) 28 | --------------------------------------------------------------------------------