From fb7eb570cf1529122bfb58923449ef8e5b20d3b5 Mon Sep 17 00:00:00 2001 From: Joseph Flasher Date: Sun, 30 Mar 2014 16:20:46 -0400 Subject: [PATCH] Most of the way towards a cal implementation for #11 Using icalendar node lib to generate ics files server side. The major outstanding issue here is that solr is not returning the results I'd expect. I search for id="some_id" and it returns many results which don't contain the id. I think I am just missing something (hopefully) obvious. --- api/app.js | 53 ++++++++++++++++++++++++++++++++++ api/package.json | 12 ++++---- sample-www/assets/js/fbopen.js | 24 +++++++++++---- 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/api/app.js b/api/app.js index d1cfe27..d3ae1c6 100644 --- a/api/app.js +++ b/api/app.js @@ -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 @@ -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()); + 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. diff --git a/api/package.json b/api/package.json index 0ff6515..0cab6d7 100644 --- a/api/package.json +++ b/api/package.json @@ -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" } } diff --git a/sample-www/assets/js/fbopen.js b/sample-www/assets/js/fbopen.js index e298821..30f452b 100644 --- a/sample-www/assets/js/fbopen.js +++ b/sample-www/assets/js/fbopen.js @@ -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 @@ -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