Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ----------------------------------------
# NPM
# ----------------------------------------
node_modules/
npm-debug.log
22 changes: 22 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
### Title:
Make a Maddie Lib Story

### URL:
`/api/v1`

### Endpoints:
POST: `/maddie_libs?access_token=${token}`
GET: `/nouns?access_token=${token}&count=x` (x being any number, default is 5)
GET: `/nouns?access_token=${token}`
GET: `/verbs?access_token=${token}&count=x` (x being any number, default is 5)
GET: `/verbs?access_token=${token}`
GET: `/adjectives?access_token=${token}&count=x` (x being any number, default is 5)
GET: `/adjectives?access_token=${token}`
GET: `/adverbs?access_token=${token}&count=x` (x being any number, default is 5)
GET: `/adverbs?access_token=${token}`

### Success Response:
Code: 200
Content: array of words or a text string (story)

### Error Code: 500
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,42 @@
# assignment_mad_lib_api
Serving up the madness with a Mad Lib API!

## Maddie Rajavasireddy

### Assignment Description:
To build an API that serves parts of English speech and provides a Mad Lib creation service. While interacting with the API, a client should be able to ask the API for nouns, verbs, adverbs and adjectives. The user will then be able to submit words and their own "story" to the API and get back a resulting Mad Lib.

User Login and Registration:
----
The first step to creating the API will be allowing users to register. This requires creation of a sign up form that will take the user's first name, last name, email and password.
Now create a login form that creates a signed session ID and logins in the user when submitted. Use session and token authentication.
Once the user is successfully logged in, show them their information and token. This means you'll need to generate that token during the user creation process.

Designing the API:
----
The application should provide the ability to get lists of each of the following parts of speech:
Nouns
Verbs
Adverbs
Adjectives
The API should also allow the user (client) the ability to specify a number of each part of speech they'd like back in the response. So submitting a request without that parameter should default to say 5 words, but allow the user to specify a parameter to change the count of words returned.
The API should take a story (text in the format that Sentencer expects to create a Mad Lib) and a list of words to be plugged into the placeholders of that text. Then the API should respond with the generated Mad Lib from the provided data.

### Testing the app:
`npm test`

### Seeding with a user:
`npm run seed`

### Starting the app:
`npm start` (runs on localhost://3000)
Login (foobar@gmail.com, password) or Register new user
After logging in, play with the maddie lib api from drop down menu item Play with Maddie Libs


#### Packages used:
Express, Mongoose, Passport, Sentencer, Wordpos, md5, bcrypt, uuid, qs, lodash


### API Reference:
See the [API](/API.md/) page for details
239 changes: 239 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
const express = require('express');
const app = express();


// ----------------------------------------
// App Locals
// ----------------------------------------
app.use((req, res, next) => {
res.locals.siteTitle = "Maddie Libs API";
res.locals.author = "Maddie Rajavasireddy";
next();
});


// ----------------------------------------
// Body Parser
// ----------------------------------------
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));


// ----------------------------------------
// Sessions/Cookies
// ----------------------------------------
const cookieSession = require('cookie-session');

app.use(cookieSession({
name: 'session',
keys: [
process.env.SESSION_SECRET || 'asdf1234567890qwer'
]
}));

app.use((req, res, next) => {
app.locals.session = req.session;
next();
});


// ----------------------------------------
// Flash Messages
// ----------------------------------------
const flash = require('express-flash-messages');
app.use(flash());


// ----------------------------------------
// Method Override
// ----------------------------------------
const methodOverride = require('method-override');
const getPostSupport = require('express-method-override-get-post-support');

app.use(methodOverride(
getPostSupport.callback,
getPostSupport.options // GET POST
));


// ----------------------------------------
// Referrer
// ----------------------------------------
app.use((req, res, next) => {
req.session.backUrl = req.header('Referer') || '/';
next();
});


// ----------------------------------------
// Public
// ----------------------------------------
app.use(express.static(`${ __dirname }/public`));


// ----------------------------------------
// Logging
// ----------------------------------------
const morgan = require('morgan');
const morganToolkit = require('morgan-toolkit')(morgan);

// Use morgan middleware with
// custom format
if (process.env.NODE_ENV !== 'test') {
app.use(morganToolkit());
}


// ----------------------------------------
// Mongoose
// ----------------------------------------
const mongoose = require('mongoose');
app.use((req, res, next) => {
if (mongoose.connection.readyState) {
next();
} else {
require('./mongo')().then(() => next());
}
});


// ----------------------------------------
// Services
// ----------------------------------------

// Require passport, strategies and User model
const passport = require('passport');
const localStrategy = require("./strategies/local");
const bearerStrategy = require("./strategies/bearer");
const User = require('./models').User;


// Initialize passport
app.use(passport.initialize());
app.use(passport.session());

// Use the strategy middlewares
passport.use(localStrategy);
passport.use(bearerStrategy);

// Use the strategy middlewares
passport.use(localStrategy);
passport.use(bearerStrategy);

// Serialize and deserialize the user
// with the user ID
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => {

// Find the user in the database
User.findById(id)
.then(user => done(null, user))
.catch(e => done(null, false));
});


// ----------------------------------------
// Routes
// ----------------------------------------

// Pass logged in/out middlewares to users router
const usersRouter = require('./routers/users');
app.use('/', usersRouter);

// Setup API router
const maddieLibsRouter = require('./routers/maddie_libs');
app.use('/api/v1', maddieLibsRouter);

const storyRouter = require("./routers/stories");
app.use('/makeStory', storyRouter);


// ----------------------------------------
// Template Engine
// ----------------------------------------
const expressHandlebars = require('express-handlebars');
const helpers = require('./helpers');


const hbs = expressHandlebars.create({
helpers: helpers,
partialsDir: 'views/',
defaultLayout: 'application'
});


app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');


// ----------------------------------------
// Server
// ----------------------------------------
const port = process.env.PORT ||
process.argv[2] ||
3000;
const host = 'localhost';


let args;
process.env.NODE_ENV === 'production' ?
args = [port] :
args = [port, host];

args.push(() => {
console.log(`Listening: http://${ host }:${ port }\n`);
});


// If we're running this file directly
// start up the server
if (require.main === module) {
app.listen.apply(app, args);
}


// ----------------------------------------
// Error Handling
// ----------------------------------------
app.use('/api', (err, req, res, next) => {
if (res.headersSent) {
return next(err);
}

if (err.stack) {
err = err.stack;
}
res.status(500).json({ error: err });
});


app.use((err, req, res, next) => {
if (res.headersSent) {
return next(err);
}

if (err.stack) {
err = err.stack;
}
res.status(500).render('errors/500', { error: err });
});


module.exports = app;

















28 changes: 28 additions & 0 deletions config/mongoose.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"development": {
"database": "assignment_mad_lib_api_development",
"host": "localhost"
},
"test": {
"database": "assignment_mad_lib_api_test",
"host": "localhost"
},
"production": {
"use_env_variable": "MONGO_URL"
}
}















23 changes: 23 additions & 0 deletions helpers/debug_helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@


const DebugHelper = {};


DebugHelper.debug = (arg) => {
return `<pre>${ JSON.stringify(arg, null, 2) }</pre>`;
};


module.exports = DebugHelper;












21 changes: 21 additions & 0 deletions helpers/flash_helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@


const FlashHelper = {};


FlashHelper.bootstrapAlertClassFor = function(key) {
return {
"error": "danger",
"alert": "danger",
"notice": "info"
}[key] || key;
};


module.exports = FlashHelper;






9 changes: 9 additions & 0 deletions helpers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const LoadHelpers = require('load-helpers');
const helperLoader = new LoadHelpers();
const helpers = helperLoader.load('helpers/*_helper.js').cache;

module.exports = helpers;




Loading