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
66 changes: 66 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Node modules
./node_modules

# Notes and stuff
notes.txt
example.json

# .gitignore Template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# project_what_have_you_done
Build an application to help track the legislative activities of your local representatives.


https://github.com/unitedstates/congress-legislators
https://theunitedstates.io/congress-legislators/legislators-current.json
70 changes: 70 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
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");
var expressValidator = require('express-validator');
var exphbs = require('express-handlebars');
// var helpers = require('./helpers/helpers');

// Require each route
var index = require("./routes/index");

// Require keys
var keys = require("../../../Modules/Cles/items.js");

var app = express();

// view engine setup
app.engine('handlebars', exphbs({
defaultLayout: 'main',
helpers: {
reps: function(items, options) {
var out = "<ul>";

for(var i = 0; i <= (reps.length -1); i++) {
out = out + "<li>" + options.fn(items[i]) + "</li>";
}

return out + "</ul>";
},
foo: function(){
return 'foo';
}
}
}));
app.set("view engine", "handlebars");

// uncomment after placing your favicon in /public
//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")));
app.use(expressValidator());

// Set routes
app.use("/", index);
//app.use("/results", results);

// 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);
}
13 changes: 13 additions & 0 deletions helpers/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var helpers = {
reps: function(items, options) {
var out = "<ul>";

for(var i = 0; i <= (reps.length -1); i++) {
out = out + "<li>" + options.fn(items[i]) + "</li>";
}

return out + "</ul>";
}
};

module.exports = helpers;
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

100 changes: 100 additions & 0 deletions models/google.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
var request = require("request");
var keys = require("C:/Users/Jared/Modules/Cles/items");

// Retrieves basic information about
// Necessary because part of original API shut down
var executeGoogleRequest = (line1, city, state, zip, callback) => {

var address = `${line1} ${city} ${state} ${zip}`;
var officialArray = [];
var senateIndices = [];
var houseIndices = [];
var indexArray = [];

// Options object, which gets passed to request call
var options = {
method: 'GET',
url: 'https://www.googleapis.com/civicinfo/v2/representatives',
qs:
{ address: address,
includeOffices: 'true',
levels: 'country',
key: keys.google,
fields: 'offices(name,officialIndices),officials(name,party,urls,photoUrl,channels)' },
headers:
{ 'postman-token': keys.postmanToken,
'cache-control': 'no-cache',
authorization: 'Basic ' + keys.googleBasic } };

request(options, function(error, response, body) {
if (error) throw new Error(error);


var APIerr = null;
if (response.statusCode !== 200 ) {
APIerr = `Invalid API Response: ${body}`;
callback(error, APIerr, null);

} else {
// Parse response
var obj = JSON.parse(body);

// For each INDEX in obj.offices - unknown quantity
var i = 0;

while (i < (obj.offices.length)) {
// If the rep is in the Senate or House, add them to
// their respective arrays
if(obj['offices'][i]['name'] === "United States Senate") {
senateIndices = obj['offices'][i]['officialIndices'];
i++;

} else if (obj['offices'][i]['name'].substring(0, 19) === "United States House") {
houseIndices = obj['offices'][i]['officialIndices'];
i++;

} else {
i++;
}
}
indices = senateIndices.concat(houseIndices);

// For each index in indices, go to officials[index] and grab info
indices.forEach(function(index) {
var officialInfo = {
name: obj.officials[index].name,
party: obj.officials[index].party,
siteURL: obj.officials[index].urls,
photoURL: obj.officials[index].photoUrl,
channels: obj.officials[index].channels
}


// Parse social media elsewhere?
// Get Twitter info if available, otherwise get FB info
var i;
for(i = 0; i < officialInfo.channels.length; i++) {
if(officialInfo.channels[i].type === "Twitter") {
officialInfo.twitter = obj.officials[index].channels[i].id.toLowerCase();
} else if(officialInfo.channels[i].type === "Facebook") {
officialInfo.facebook = obj.officials[index].channels[i].id.toLowerCase();
} else if(officialInfo.channels[i].type === "YouTube") {
officialInfo.youtube = obj.officials[index].channels[i].id.toLowerCase();
}
}
// Delete channels property from officialInfo
// It's now unneccesary
delete officialInfo.channels;
// Push each official object into an array
officialArray.push(officialInfo);
});

callback(error, APIerr, officialArray);
}

});
};

module.exports = {
executeGoogleRequest
}
27 changes: 27 additions & 0 deletions models/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
var request = require("request");
var keys = require("C:/Users/Jared/Modules/Cles/items");
var line1 = "352 Woodford St.";
var city = "Portland";
var state = "ME";
var zip = "04103";
var address = `${line1} ${city} ${state} ${zip}`;

// Options object, which gets passed to request call
var options = {
method: 'GET',
url: 'https://www.googleapis.com/civicinfo/v2/representatives',
qs:
{ address: address,
includeOffices: 'true',
levels: 'country',
key: keys.google },
headers:
{ 'postman-token': keys.postmanToken,
'cache-control': 'no-cache',
authorization: 'Basic ' + keys.googleBasic } };

request(options, function (error, response, body) {
if (error) throw new Error(error);

console.log(body);
});
Loading