Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
2671c01
Generate express project
lortza Aug 14, 2017
9ca7606
Add name to readme
lortza Aug 14, 2017
e4a975a
Install handlebars package
lortza Aug 14, 2017
b112310
Install request package
lortza Aug 14, 2017
c399405
Install Express dependencies
lortza Aug 14, 2017
523ca9b
Set up basic API file
lortza Aug 14, 2017
1d19b0d
Fetch legslators by zip code
lortza Aug 16, 2017
b6f6d29
Add documentation to track all of the relevant data sources and docs
lortza Aug 17, 2017
07dd59f
Add Viking assignment links
lortza Aug 17, 2017
69def68
Prelminary function for getting bills
lortza Aug 17, 2017
447c114
Prelminary function for getting votes
lortza Aug 17, 2017
f00f1a1
WIP Legislator class
lortza Aug 17, 2017
11ac3d7
Temporarily comment out api require to work on front end
lortza Aug 17, 2017
b03a131
Add favicon
lortza Aug 17, 2017
03dd957
Create preliminary html & css for home page
lortza Aug 17, 2017
9b96703
Move site title to layout page
lortza Aug 17, 2017
f97025a
Add footer
lortza Aug 17, 2017
e032e16
Set up routes and html for legislators page
lortza Aug 17, 2017
d944e0c
Build out styles for legislator show page
lortza Aug 17, 2017
17c651a
Set up routes for legislator show page
lortza Aug 17, 2017
69a9984
Add styles for legislator show page
lortza Aug 17, 2017
bdcc84e
Add Heroku address
lortza Aug 17, 2017
5ff6c6e
Update api urls
lortza Aug 17, 2017
357fab1
Add heroku deployment info
lortza Aug 17, 2017
91f474e
WIP api code that goes nowhere
lortza Aug 17, 2017
8f1ed50
Set up legislator show page routes
lortza Aug 18, 2017
0a5b176
Clean up legislator data in the legislators model
lortza Aug 18, 2017
f23ffdf
Populate legislator show page with contact info data
lortza Aug 18, 2017
72f7564
Strip down api class to focus on just getting legislators by zip
lortza Aug 18, 2017
718bf4d
Update api uris for votes and bills
lortza Aug 18, 2017
891c80c
Rename routers
lortza Aug 18, 2017
02a4c79
Convert party initial to full word
lortza Aug 18, 2017
1aeadc1
Rename files to include purpose for clarity
lortza Aug 18, 2017
8dcf78f
Link from legislators index to legislator show page
lortza Aug 18, 2017
4c13ce8
Refactor link style on zip results index page
lortza Aug 18, 2017
c36fb5e
Make main header a link to root
lortza Aug 18, 2017
71b4d87
WIP feeling the struggle of not passing form params into the router c…
lortza Aug 18, 2017
4427194
Rename legislator routers
lortza Aug 22, 2017
4333217
Rename legislators index view
lortza Aug 22, 2017
aef53ab
Remove data from model and rebuild class constructor
lortza Aug 22, 2017
3984d97
Remove temp data holder file
lortza Aug 22, 2017
44b2b7c
Remove placeholder info
lortza Aug 22, 2017
e8271f4
Make call to api to get legislators by zip
lortza Aug 23, 2017
15dfe18
Make call to api to get info for a specific legislator
lortza Aug 23, 2017
37aba7b
Set up legislator show page to receive bill data
lortza Aug 23, 2017
8db4cf0
Retreive vote information for legislators
lortza Aug 23, 2017
f0bd76f
Separate members of house and senate on legislators index page
lortza Aug 23, 2017
a2ae993
Move legislator pics up a bit in the frame to show their faces better
lortza Aug 23, 2017
1f2f397
Redesign vote output display on legislator show page
lortza Aug 23, 2017
2a346bc
Standardize output vote results
lortza Aug 23, 2017
4eb6dea
Add build status to readme
lortza Sep 20, 2017
e1219f4
Update README.md
lortza Apr 28, 2019
f0f22fb
Update README.md
lortza Apr 28, 2019
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
sandbox.js
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
# project_what_have_you_done
Build an application to help track the legislative activities of your local representatives.

This build is not 100% complete as it lacks bill info integration.

by Anne Richardson

Hosted on heroku: https://frozen-brushlands-61850.herokuapp.com

_App is currently turned off_

65 changes: 65 additions & 0 deletions api/sunlight_api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// require the request library
const request = require('request');
const {Legislator} = require('../models/legislator_model')
const {Vote} = require('../models/vote_model')

// set up the base URI for the api from https://sunlightlabs.github.io/congress/
const baseUri = 'https://congress.api.sunlightfoundation.com';


// build class to organize api calls
class SunlightApi {

// Get a list of legislators based upon a given zip code.
// The callback is passed in directly in the router.
getLegislators(zip, callback) {
var url = `${baseUri}/legislators/locate?zip=${zip}`
var mapper = function(result){
// generate a new instance of legislator obj
return new Legislator(result)
}
this._sendRequest(url, mapper, callback);
}

// Get details on a specific legislator.
// The callback is passed in directly in the router.
getLegislator(bioguide_id, callback) {
var url = `${baseUri}/legislators?bioguide_id=${bioguide_id}`
var mapper = function(result){
// generate a new instance of legislator obj
return new Legislator(result)
}
this._sendRequest(url, mapper, callback);
}

// Get the list of votes a legislator has participated in
getLegislatorVotes(bioguide_id, callback) {
var url = `https://congress.api.sunlightfoundation.com/votes?fields=bill_id,vote_zipUri,year,result,voter_ids&vote_type=passage&voter_ids.${bioguide_id}__exists=true`;
var mapper = function(result){
// generate a new instance of legislator obj
return new Vote(result, bioguide_id)
}
this._sendRequest(url, mapper, callback);
};


// A method for making all of the api calls
_sendRequest(url, mapper, callback){
request(url, function(error, response, body){
if (!error & response.statusCode === 200) {
callback(
JSON.parse(body).results.map(function(api_result) {
// for each result, execute the passed mapper function
return mapper(api_result)
}
))
}
});
}

} // close SunlightApi

// return the class for use in other files
module.exports = {
SunlightApi
};
54 changes: 54 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// packages
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

// api
var request = require('request');

// require info from routes
var index = require('./routes/index');
var legislators_index_router = require('./routes/legislators_index_router');
var legislator_show_router = require('./routes/legislator_router');

// express app
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// set up route paths
app.use('/', index);
app.use('/legislators', legislators_index_router);
app.use('/legislator', legislator_show_router);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

module.exports = app;
90 changes: 90 additions & 0 deletions bin/www
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env node

/**
* Module dependencies.
*/

var app = require('../app');
var debug = require('debug')('project-what-have-you-done:server');
var http = require('http');

/**
* Get port from environment and store in Express.
*/

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
* Create HTTP server.
*/

var server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
*/

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

/**
* Event listener for HTTP server "listening" event.
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
53 changes: 53 additions & 0 deletions documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# What Have You Done Project
This project uses info from the Sunlight Foundation API in an app where you can look up members of the Senate and House by zip code and see how they voted on certain bills.

Demo:
https://what-have-you-done.herokuapp.com

Viking Assignment Page:
https://www.vikingcodeschool.com/dashboard#/professional-development-with-javascript/project-walkthrough-professional-javascript

Viking Repo:
https://github.com/vikingeducation/project_what_have_you_done

My Heroku Deployment:
https://frozen-brushlands-61850.herokuapp.com



## Sunlight Foundation API info
https://sunlightlabs.github.io/congress/index.html
Though the docs say we need an API key, this is no longer true


### Legislators
Documentation:
https://sunlightlabs.github.io/congress/legislators.html#fields

API Call:
https://congress.api.sunlightfoundation.com/legislators/locate?zip=${zip}

Images:
https://theunitedstates.io/images/congress/225x275/${legislator.bioguide_id}.jpg


### Bills
Documentation:
https://sunlightlabs.github.io/congress/bills.html

API Call:
https://congress.api.sunlightfoundation.com/bills?fields=bill_id,congress,number,official_title,summary



### Votes
Documentation:
https://sunlightlabs.github.io/congress/votes.html

API Calls:
https://congress.api.sunlightfoundation.com/votes?fields=bill_id,congress,vote_zipUri,year,question,result,voter_ids&vote_type=passage&voter_ids.${legislator.bioguide_id}__exists=true



## Additional Data Sources
https://github.com/unitedstates/
45 changes: 45 additions & 0 deletions models/legislator_model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class Legislator {
// Take the full results object and parse it into useful fields for the views
constructor(params) {
this.bioguide_id = params.bioguide_id,
this.name = this.name(params.first_name, params.last_name),
this.chamber = params.chamber,
this.party = this.partyConverter(params.party),
this.phone = params.phone,
this.website = params.website,
this.imageUrl = this.image(params.bioguide_id)
};

name(first_name, last_name){
return `${first_name} ${last_name}`
}

image(bioguide_id){
return `https://theunitedstates.io/images/congress/225x275/${bioguide_id}.jpg`
}

partyConverter(apiParty){
switch (apiParty) {
case 'D':
return 'Democrat'
break;
case 'R':
return 'Republican'
break;
case 'G':
return 'Green'
break;
case 'I':
return 'Independent'
break;
default:
return 'Party Unknown'
}
};
} // close Legislator


// return the class for use in other files
module.exports = {
Legislator
};
40 changes: 40 additions & 0 deletions models/vote_model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Vote {
// Take the full results object and parse it into useful fields for the views
constructor(params, bioguide_id) {
this.billId = params.bill_id,
this.result = this.resultConverter(params.result),
this.legislatorId = bioguide_id,
this.legislatorVote = this.voteParser(params.voter_ids, bioguide_id)
};

voteParser(voterIds, bioguide_id){
switch (voterIds[bioguide_id]) {
case 'Yea':
return 'Yes'
break;
case 'Nay':
return 'No'
break;
default:
return voterIds[bioguide_id];
}
};

resultConverter(apiResult){
apiResult = apiResult.toLowerCase();
if (apiResult.includes('pass') || apiResult.includes('agree')) {
return 'Passed'
} else if (apiResult.includes('fail')) {
return 'Failed'
} else {
return apiResult
}
};

} // close Vote


// return the class for use in other files
module.exports = {
Vote
};
Loading