Browse Source

version 1.0.0

this commit contains version 1 of the notes app and api.

the functionality contained within this version includes:
html of all notes in the notes table, formatted and served over the / (index) route
json output containing all notes in the notes table, served over the /api/notes route

there is not yet functionality to post notes via the api, but is planned.
master
Blaine Motsinger 1 year ago
parent
commit
1056028969

+ 9
- 0
.gitignore View File

@@ -0,0 +1,9 @@
/.well-known
/cgi-bin
scratch
package-lock.json
node_modules/
*.swp
*.back
backup/
.notesrc

+ 34
- 0
bin/add_note View File

@@ -0,0 +1,34 @@
#!/usr/bin/env nodejs

"use strict";

const program = require( 'commander' );
const path = require( 'path' );
const dbPath = path.resolve( __dirname, './../db/notes.db' );
const sqlite3 = require( 'sqlite3' ).verbose();
const dbh = new sqlite3.Database( dbPath );

program
.version( '1.0.0' )
.arguments( '<note>' )
.usage( '<note>' )
.parse( process.argv );

// display help if note isn't set
if ( program.args.length === 0 ) {
program.help();
}

// squash down the note if it wasn't wrapped in quotes from the commandline
let note = program.args.join( ' ' );

dbh.run( 'INSERT into notes ( note ) VALUES ( ? )', note, function( err ) {
if ( err ) {
console.log( 'error: ' + err );
process.exit( 1 );
}

console.log( 'note id ' + this.lastID + ' was inserted correctly' );
process.exit( 0 );
});


+ 25
- 0
bin/backup_db.bash View File

@@ -0,0 +1,25 @@
#!/bin/bash

SCRIPT_DIR=$(dirname "$0")
BACKUP_DIR="$SCRIPT_DIR/../db/backup"
DATABASE_NAME='notes.db'
BACKUP_NAME="$DATABASE_NAME.$(date '+%m%d%y').back"

echo "# SCRIPT_DIR ----- $SCRIPT_DIR"
echo "# BACKUP_DIR ----- $BACKUP_DIR"
echo "# DATABASE_NAME -- $DATABASE_NAME"
echo "# BACKUP_NAME ---- $BACKUP_NAME"

echo
echo -n "# backing up database into $BACKUP_DIR - "

CP_RESULT=$(cp ../db/$DATABASE_NAME $BACKUP_DIR/$BACKUP_NAME)

if [ ! "CP_RESULT" ]; then
echo "error"
echo $CP_RESULT
exit 1
else
echo "done"
exit 0
fi

+ 7
- 0
bin/package.json View File

@@ -0,0 +1,7 @@
{
"dependencies": {
"commander": "^2.17.1",
"path": "^0.12.7",
"sqlite3": "^4.0.2"
}
}

+ 8
- 0
config/application.js View File

@@ -0,0 +1,8 @@
// notes application settings

const fs = require( 'fs' );
const path = require( 'path' );

let config = JSON.parse( fs.readFileSync( path.resolve( __dirname, './../.notesrc' ), 'utf8' ) );

module.exports = config;

+ 5
- 0
config/services/.htaccess View File

@@ -0,0 +1,5 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

+ 7
- 0
config/services/httpd.conf View File

@@ -0,0 +1,7 @@
# add the following include entry to the notes virtualhost section for 443:
# To customize this VirtualHost use an include file at the following location
Include "/etc/apache2/conf.d/userdata/ssl/2_4/notes/notes.tld/*.conf"

# then, within the include dir above, create the nodejs.conf file and add the following:
ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/

+ 16
- 0
config/services/notes.service View File

@@ -0,0 +1,16 @@
[Service]
ExecStart=/usr/local/bin/node /home/notes/git/notes/notes.js
Restart=always

StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=notes

Type=simple
User=notes
Group=notes

Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

+ 2
- 0
config/services/robots.txt View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: /

BIN
db/notes.db View File


+ 5
- 0
db/schema.sql View File

@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
note TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)

+ 9
- 0
lib/dbh.js View File

@@ -0,0 +1,9 @@
// notes
// dbh connection initialization

const path = require( 'path' );
const dbPath = path.resolve( __dirname, './../db/notes.db' );
const sqlite3 = require( 'sqlite3' ).verbose();
const dbh = new sqlite3.Database( dbPath );

module.exports = dbh;

+ 66
- 0
notes.js View File

@@ -0,0 +1,66 @@
// notes
// app and api in nodejs

"use strict";

const version = '1.0.0';

const express = require( 'express' );
const moment = require( 'moment' );
const config = require( './config/application' );
const app = express();
const path = require( 'path' );

const logger = function ( req, res, next ) {
console.log(
timestamp() + ' ' +
req.connection.remoteAddress + ' ' +
req.method + ' ' +
req.url + ' '
);

next();
};

// disable unused headers
app.disable( 'etag' );
app.disable( 'x-powered-by' );

// set template engine and views location
app.set( 'view engine', 'pug' );
app.set( 'views', path.resolve( __dirname, './views' ) );

// routes
const notes = require( './routes/api/notes' );
const index = require( './routes/index' );

// load the middleware for each route
app.use( logger );

// load the routes
app.use( '/api/notes', notes );
app.use( '/', index );

// default route
app.get( '*', function( req, res ) {
res.status( 404 )
.header( 'Content-Type', 'text/plain' )
.send( 'Not Found' );
});

function timestamp () {
const timestamp = moment().format( 'MMDDYYYY-HHmmss' );

return '[' + timestamp + ']';
}

// before starting the server, display the initial startup message
console.log( timestamp() + ' [info] notes - version ' + version );

// now start the server, listening on the configured port and address
app.listen( config.app.port, config.app.address, () => {
console.log(
timestamp() + ' [info] server started\n' +
timestamp() + ' [info] serving: ' + config.app.address + ':' + config.app.port
);
});

+ 9
- 0
package.json View File

@@ -0,0 +1,9 @@
{
"dependencies": {
"express": "^4.16.3",
"moment": "^2.22.2",
"path": "^0.12.7",
"pug": "^2.0.3",
"sqlite3": "^4.0.2"
}
}

+ 20
- 0
routes/api/notes.js View File

@@ -0,0 +1,20 @@
// notes
// notes route

const express = require( 'express' );
const router = express.Router();
const dbh = require( './../../lib/dbh' );

// GET /notes
router.get( '/', function ( req, res ) {

// get all of the notes
dbh.all( 'SELECT * from notes', function( err, rows ) {

res.status( 200 )
.header( 'Content-Type', 'application/json' )
.send( JSON.stringify( rows || [] ) );
});
});

module.exports = router;

+ 20
- 0
routes/index.js View File

@@ -0,0 +1,20 @@
// notes
// index route

const express = require( 'express' );
const router = express.Router();
const dbh = require( './../lib/dbh' );

// GET /
router.get( '/', function ( req, res ) {

// get all of the notes
dbh.all( 'SELECT * from notes', function( err, rows ) {

// send to the index.pug view
res.render( 'index', { rows: rows } );
});

});

module.exports = router;

+ 11
- 0
views/index.pug View File

@@ -0,0 +1,11 @@
doctype html
html(lang="en")
head
title Notes
body
#notes
if rows
each row in rows
p.note #{row.created_at} - #{row.note}
else
p.note There are no notes to be displayed.

Loading…
Cancel
Save