Skip to content
This repository has been archived by the owner on Dec 23, 2017. It is now read-only.

Feature/handle proxy #756

Merged
merged 9 commits into from
Sep 25, 2015
Merged
Show file tree
Hide file tree
Changes from 5 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
62 changes: 37 additions & 25 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@ def get_election_url(candidate, cycle, district=None):
)


try:
assets = json.load(open('./rev-manifest.json'))
except OSError:
logger.error(
'Manifest "rev-manifest.json" not found. Did you remember to run '
'"npm run build"?'
)
raise

assets = {
key: value.replace('dist', '')
for key, value in assets.items()
}

def asset_for(path):
return url_for('static', filename=assets[path].lstrip('/'))


def get_base_path():
return request.headers.get('X-Script-Name', '/')


app.jinja_env.globals.update({
'min': min,
'max': max,
Expand All @@ -116,25 +138,12 @@ def get_election_url(candidate, cycle, district=None):
'election_url': get_election_url,
'constants': constants,
'cycles': get_cycles(),
'assets': assets,
'asset_for': asset_for,
'base_path': get_base_path,
})


try:
assets = json.load(open('./rev-manifest.json'))
except OSError:
logger.error(
'Manifest "rev-manifest.json" not found. Did you remember to run '
'"npm run build"?'
)
raise
# Hack: Rename paths from "dist" to "static"
# TODO(jmcarp) Find a better solution
app.jinja_env.globals['assets'] = {
key: value.replace('dist', 'static')
for key, value in assets.items()
}


@app.route('/')
def search():
query = request.args.get('search')
Expand All @@ -146,15 +155,15 @@ def search():
return render_template('search.html', page='home', dates=utils.date_ranges())


@app.route('/api')
@app.route('/api/')
def api():
"""Redirect to API as described at
https://18f.github.io/API-All-the-X/pages/developer_hub_kit.
"""
return redirect(config.api_location, http.client.MOVED_PERMANENTLY)


@app.route('/developers')
@app.route('/developers/')
def developers():
"""Redirect to developer portal as described at
https://18f.github.io/API-All-the-X/pages/developer_hub_kit.
Expand All @@ -164,7 +173,7 @@ def developers():
return redirect(url.url, http.client.MOVED_PERMANENTLY)


@app.route('/candidate/<c_id>')
@app.route('/candidate/<c_id>/')
@use_kwargs({
'cycle': Arg(int),
})
Expand All @@ -177,7 +186,7 @@ def candidate_page(c_id, cycle=None):
return render_candidate(candidate, committees, cycle)


@app.route('/committee/<c_id>')
@app.route('/committee/<c_id>/')
@use_kwargs({
'cycle': Arg(int),
})
Expand All @@ -190,12 +199,12 @@ def committee_page(c_id, cycle=None):
return render_committee(committee, candidates, cycle)


@app.route('/candidates')
@app.route('/candidates/')
def candidates():
return render_template('candidates.html', result_type='candidates')


@app.route('/committees')
@app.route('/committees/')
def committees():
return render_template(
'committees.html',
Expand All @@ -204,17 +213,17 @@ def committees():
)


@app.route('/receipts')
@app.route('/receipts/')
def receipts():
return render_template('receipts.html', dates=utils.date_ranges())


@app.route('/disbursements')
@app.route('/disbursements/')
def disbursements():
return render_template('disbursements.html', dates=utils.date_ranges())


@app.route('/filings')
@app.route('/filings/')
def filings():
return render_template(
'filings.html',
Expand Down Expand Up @@ -364,6 +373,9 @@ def fmt_state_full(value):
basic_auth = BasicAuth(app)


app.wsgi_app = utils.ReverseProxied(app.wsgi_app)


if __name__ == '__main__':
files = ['./rev-manifest.json']
app.run(host=config.host, port=int(config.port), debug=config.debug, extra_files=files)
36 changes: 36 additions & 0 deletions openfecwebapp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,42 @@ def delete(self, key):
self.data.clear()


class ReverseProxied(object):
"""Wrap the application in this middleware and configure the
front-end server to add these headers, to let you quietly bind
this to a URL other than / and to an HTTP scheme that is
different than what is used locally.
From http://flask.pocoo.org/snippets/35/.
In nginx:
location /myprefix {
proxy_pass http://192.168.0.1:5001;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Script-Name /myprefix;
}
:param app: the WSGI application
"""
def __init__(self, app):
self.app = app

def __call__(self, environ, start_response):
script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
if script_name:
environ['SCRIPT_NAME'] = script_name
path_info = environ['PATH_INFO']
if path_info.startswith(script_name):
environ['PATH_INFO'] = path_info[len(script_name):]

scheme = environ.get('HTTP_X_SCHEME', '')
if scheme:
environ['wsgi.url_scheme'] = scheme
return self.app(environ, start_response)


def date_ranges():
"""Build date ranges for current day, month, quarter, and year.
"""
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"gulp-minify-css": "1.1.5",
"gulp-rename": "1.2.2",
"gulp-rev": "3.0.1",
"gulp-sass": "2.0.0",
"gulp-sass": "2.0.4",
"gulp-sourcemaps": "^1.5.2",
"gulp-uglify": "1.2.0",
"gulp-util": "^3.0.6",
Expand Down
15 changes: 12 additions & 3 deletions static/js/modules/columns.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
var _ = require('underscore');

var tables = require('./tables');
var helpers = require('./helpers');
var decoders = require('./decoders');

var sizeInfo = {
Expand Down Expand Up @@ -42,11 +43,19 @@ var filings = {
className: 'all',
orderable: false,
render: function(data, type, row, meta) {
var cycle = tables.buildCycle(row);
var cycle = tables.getCycle(row);
if (row.candidate_name) {
return tables.buildEntityLink(row.candidate_name, '/candidate/' + row.candidate_id + cycle, 'candidate');
return tables.buildEntityLink(
row.candidate_name,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier 'candidate_name' is not in camel case.

helpers.buildAppUrl(['candidate', row.candidate_id], cycle),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier 'candidate_id' is not in camel case.

'candidate'
);
} else if (row.committee_name) {
return tables.buildEntityLink(row.committee_name, '/committee/' + row.committee_id + cycle, 'committee');
return tables.buildEntityLink(
row.committee_name,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier 'committee_name' is not in camel case.

helpers.buildAppUrl(['committee', row.committee_id], cycle),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier 'committee_id' is not in camel case.

'committee'
);
} else {
return '';
}
Expand Down
2 changes: 1 addition & 1 deletion static/js/modules/election-lookup.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ function formatUrl(result) {
path = path.concat(result.district);
}
path = path.concat(result.cycle);
return URI(path.join('/')).toString();
return helpers.buildAppUrl(path);
}

function formatColor(result, lookup) {
Expand Down
12 changes: 11 additions & 1 deletion static/js/modules/helpers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

/* global require, module, Intl, API_LOCATION, API_VERSION, API_KEY */
/* global require, module, Intl, BASE_PATH, API_LOCATION, API_VERSION, API_KEY */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long.


var URI = require('URIjs');
var _ = require('underscore');
Expand All @@ -26,6 +26,8 @@ function datetime(value) {
}
Handlebars.registerHelper('datetime', datetime);

Handlebars.registerHelper('basePath', BASE_PATH);

function cycleDates(year) {
return {
min: '01-01-' + (year - 1),
Expand All @@ -43,6 +45,13 @@ function filterNull(params) {
.value();
}

function buildAppUrl(path, query) {
return URI(BASE_PATH)
.path(Array.prototype.concat('', path, '').join('/'))
.addQuery(query)
.toString();
}

function buildUrl(path, query) {
return URI(API_LOCATION)
.path(Array.prototype.concat(API_VERSION, path, '').join('/'))
Expand All @@ -56,5 +65,6 @@ module.exports = {
datetime: datetime,
cycleDates: cycleDates,
filterNull: filterNull,
buildAppUrl: buildAppUrl,
buildUrl: buildUrl
};
12 changes: 6 additions & 6 deletions static/js/modules/tables.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ function mapFilters(filters) {

var parsedFilters;

function buildCycle(datum) {
function getCycle(datum) {
if (parsedFilters && parsedFilters.cycle) {
var cycles = _.intersection(
_.map(parsedFilters.cycle, function(cycle) {return parseInt(cycle);}),
datum.cycles
);
return '?cycle=' + _.max(cycles);
return {cycle: _.max(cycles)};
} else {
return '';
return {};
}
}

Expand Down Expand Up @@ -172,15 +172,15 @@ var barCurrencyColumn = barColumn(helpers.currency);

var candidateColumn = formattedColumn(function(data) {
if (data) {
return buildEntityLink(data.name, '/candidate/' + data.candidate_id, 'candidate');
return buildEntityLink(data.name, helpers.buildAppUrl(['candidate', data.candidate_id]), 'candidate');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long.
Identifier 'candidate_id' is not in camel case.

} else {
return '';
}
});

var committeeColumn = formattedColumn(function(data) {
if (data) {
return buildEntityLink(data.name, '/committee/' + data.committee_id, 'committee');
return buildEntityLink(data.name, helpers.buildAppUrl(['committee', data.committee_id]), 'committee');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long.
Identifier 'committee_id' is not in camel case.

} else {
return '';
}
Expand Down Expand Up @@ -497,7 +497,7 @@ var seekCallbacks = {
module.exports = {
simpleDOM: simpleDOM,
yearRange: yearRange,
buildCycle: buildCycle,
getCycle: getCycle,
buildAggregateUrl: buildAggregateUrl,
buildTotalLink: buildTotalLink,
buildEntityLink: buildEntityLink,
Expand Down
3 changes: 2 additions & 1 deletion static/js/pages/candidates.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var $ = require('jquery');
var _ = require('underscore');

var tables = require('../modules/tables');
var helpers = require('../modules/helpers');
var candidatesTemplate = require('../../templates/candidates.hbs');

var columns = [
Expand All @@ -16,7 +17,7 @@ var columns = [
render: function(data, type, row, meta) {
return tables.buildEntityLink(
data,
'/candidate/' + row.candidate_id + tables.buildCycle(row),
helpers.buildAppUrl(['candidate', row.candidate_id], tables.getCycle(row)),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long.
Identifier 'candidate_id' is not in camel case.

'candidate'
);
}
Expand Down
7 changes: 6 additions & 1 deletion static/js/pages/committees.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var $ = require('jquery');
var _ = require('underscore');

var tables = require('../modules/tables');
var helpers = require('../modules/helpers');
var committeesTemplate = require('../../templates/committees.hbs');

var columns = [
Expand All @@ -14,7 +15,11 @@ var columns = [
className: 'all',
width: '280px',
render: function(data, type, row, meta) {
return tables.buildEntityLink(data, '/committee/' + row.committee_id + tables.buildCycle(row), 'committee');
return tables.buildEntityLink(
data,
helpers.buildAppUrl(['committee', row.committee_id], tables.getCycle(row)),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long.
Identifier 'committee_id' is not in camel case.

'committee'
);
}
},
{data: 'treasurer_name', className: 'min-desktop hide-panel'},
Expand Down
2 changes: 1 addition & 1 deletion static/templates/candidates.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="panel__row">
<div class="panel__heading">
<h4 class="panel__title"><a href="/candidate/{{candidate_id}}">{{name}}</a></h4>
<h4 class="panel__title"><a href="{{basePath}}candidate/{{candidate_id}}">{{name}}</a></h4>
</div>
<table>
<tr>
Expand Down
12 changes: 6 additions & 6 deletions static/templates/committees.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="panel__row">
<div class="panel__heading">
<h4 class="panel__title"><a href="/committee/{{committee_id}}">{{name}}</a></h4>
<h4 class="panel__title"><a href="{{basePath}}committee/{{committee_id}}">{{name}}</a></h4>
</div>
<table>
<tr>
Expand All @@ -14,20 +14,20 @@
<tr>
<td class="panel__term">Political Party</td>
<td>{{party_full}}</td>
</tr>
</tr>
{{#if organization_type_full}}
<tr>
<td class="panel__term">Organization Type</td>
<td>{{organization_type_full}}</td>
</tr>
</tr>
{{/if}}
<tr>
<td class="panel__term">Treasurer</td>
<td>{{treasurer_name}}</td>
</tr>
</tr>
<tr>
<td class="panel__term">State</td>
<td>{{state}}</td>
</tr>
</tr>
</table>
</div>
</div>
Loading