Skip to content
This repository was archived by the owner on Dec 8, 2017. It is now read-only.
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
53 changes: 53 additions & 0 deletions api/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ var express = require('express')
, request = require('request')
, qs = require('querystring')
, solr = require('solr-client')
, icalendar = require('icalendar')
, uuid = require('node-uuid')
, url = require('url')
, moment = require('moment') // momentjs.com
, S = require('string') // stringjs.com
Expand Down Expand Up @@ -247,6 +249,57 @@ app.get('/v0/opps', function(req, res) {

});

// Create a calendar event from record id
app.get('/v0/cal/:id?', function(req, res) {
// Make sure we have a record id to retrieve
if (req.param('id') === undefined) {
return res.json(404, { error: 'Invalid record id supplied.' });
}

// start with base endpoint, then add query params
var solr_url = config.solr.base_url;

// Adding the fq here to get rid of a links record that was being returned
// unwantedly.
solr_url += '?q=id="' + req.param('id') + '"' +
'&fq=%2Bclose_dt%3A%5B*+TO+*%5D' +
'&fl=id,title,listing_url,close_dt,description' +
'&wt=json&indent=true';

// Search solor for our record
request(solr_url, function(err, resp, body) {

res.set('Access-Control-Allow-Origin', '*');
res.set('Content-Type', 'application/json;charset=utf-8');

if (!err && resp.statusCode == 200) {

var results_in = JSON.parse(body);
// Grab the first result, there should only be one if we're
// correctly using a uid
var result = results_in.response.docs[0];

// Got good results, create the calendar event
var ev = new icalendar.VEvent(uuid.v4());

Choose a reason for hiding this comment

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

If someone "subscribes" to the calendar (such as putting it in Google Calendar), having a different UUID every time the endpoint is hit will result in the calendar app thinking they are different calendar entries. An alternative would be to use the id, or hash the id.

Choose a reason for hiding this comment

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

This happens when someone accesses the .ics file through webcal:// rather than https://

ev.setSummary("FBOpen Deadline for " + result.title);

// We want the start date to be 1 hour before the closing time
var endDate = new Date(result.close_dt);
var startDate = new moment(result.close_dt);
startDate.subtract('hours', 1);
console.log(startDate.toDate(), endDate);
ev.setDate(startDate.toDate(), endDate);
ev.setDescription(result.description);
ev.addProperty('URL', result.listing_url);
res.setHeader('Content-Disposition', 'attachment; filename=fbopen.ics');
res.type('text/calendar');
res.end(ev.toString());
} else {
res.json(resp.statusCode, { error: err });
}
});
});

// translate solr facets into JSON
// Strangely, Solr returns facets as a flat list of code/count pairs: e.g., NAICS code, count, NAICS code, count, ... etc.
// This function creates a single JSON object, with a key for each code, where the value of that key is the count.
Expand Down
12 changes: 7 additions & 5 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
"express": "3.3.4",
"jade": "*",
"less-middleware": ">=0.2.1-beta",
"request": "*",
"solr-client": "*",
"moment": "*",
"string": "*",
"http-auth": "*"
"request": "*",
"solr-client": "*",
"moment": "*",
"string": "*",
"http-auth": "*",
"icalendar": "0.6.5",
"node-uuid": "1.4.x"
}
}
24 changes: 19 additions & 5 deletions sample-www/assets/js/fbopen.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@
var PAGESIZE = 10; // results per page -- fixed by the API, not customizable here

// always call current version of the API (currently v0)
var api_base;
if (location.protocol == 'https:' && fbopen_config.API_SERVER_SSL) {
api_base = fbopen_config.API_SERVER_SSL + '/v0';
} else {
api_base = fbopen_config.API_SERVER + '/v0';
}

$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
if (location.protocol == 'https:' && fbopen_config.API_SERVER_SSL) {
options.url = fbopen_config.API_SERVER_SSL + '/v0' + options.url;
} else {
options.url = fbopen_config.API_SERVER + '/v0' + options.url;
}
options.url = api_base + options.url;
});

// disable ajax caching in IE
Expand Down Expand Up @@ -196,6 +199,17 @@
, 'html': true
});

// Add handler for calendar event creation
$('.listing-dates').click(function () {
var id = $(this).parents(".result-item").attr("data-solr-id");

// Make sure the record has a valid id
if (!id) {
return;
}
window.open(api_base + '/cal/' + id, 'FBOpen Calendar Event');
});

});
},
// NOTE: this call to render_error will catch issues with accessing the API
Expand Down