Browse files

First commit

  • Loading branch information...
0 parents commit e6d8f2084561cecfeb8c3d0b69278bc1001a9b90 @jfhbrook committed Sep 16, 2012
Showing with 263 additions and 0 deletions.
  1. +76 −0 README.md
  2. +47 −0 example/sfia-pitt.js
  3. +111 −0 index.js
  4. +29 −0 package.json
76 README.md
@@ -0,0 +1,76 @@
+# bart-api
+
+THIS IS A SYSTEM-WIDE BART ADVISORY. ALL ELEVATORS ARE WORKING. THAT IS ALL.
+
+## Install:
+
+ npm install bart-api
+
+## Start it up:
+
+```js
+var Bart = require('bart-api');
+
+// You can get yourself one of these at http://api.bart.gov/api/register.aspx
+var key = require('./config.json').key;
+
+var bart = new Bart(key);
+```
+
+## Make an API request, receive xml
+
+```js
+ // Get arrival schedule information
+ bart.sched.arrive({
+ orig: 'SFIA',
+ dest: 'PITT'
+ }, function (err, xml, body) {
+ if (err) {
+ throw err;
+ }
+
+ // xml is a parser instance from https://github.com/polotek/libxmljs
+ // it supports xpath and more!
+ var trips = [];
+
+ xml.find('/root/schedule/request/trip').forEach(function (trip) {
+ trips.push({
+ orig: trip.attr('origin').value(),
+ dest: trip.attr('destination').value(),
+ times: {
+ orig: trip.attr('origTimeMin').value(),
+ dest: trip.attr('destTimeMin').value()
+ },
+ legs: trip.find('leg').map(function (leg) {
+ return {
+ orig: leg.attr('origin').value(),
+ dest: leg.attr('destination').value(),
+ line: leg.attr('line').value(),
+ head: leg.attr('trainHeadStation').value(),
+ times: {
+ orig: leg.attr('origTimeMin').value(),
+ dest: leg.attr('destTimeMin').value()
+ }
+ };
+ })
+ })
+ });
+
+ // If you hate libxmljs, you can access the raw buffered body too!
+ //
+ // console.log(body);
+ //
+ // bart.sched.arrive() will also return the request instance, if you
+ // would rather parse the output using a streaming parser such as
+ // sax-js.
+ });
+```
+
+## More Reading:
+
+* API docs: <http://api.bart.gov/docs/overview/index.aspx>
+* libxmljs docs: <https://github.com/polotek/libxmljs/wiki>
+
+## License:
+
+MIT/X11.
47 example/sfia-pitt.js
@@ -0,0 +1,47 @@
+var read = require('read'),
+ Bart = require('../index');
+
+console.log('PITT line arrival schedule for SFIA:');
+read({ prompt: 'api key?' }, function (err, key) {
+ if (err) {
+ throw err;
+ }
+ var bart = new Bart(key);
+
+ // Get arrival schedule information
+ bart.sched.arrive({
+ orig: 'SFIA',
+ dest: 'PITT'
+ }, function (err, xml, body) {
+ if (err) {
+ throw err;
+ }
+
+ var trips = [];
+
+ xml.find('/root/schedule/request/trip').forEach(function (trip) {
+ trips.push({
+ orig: trip.attr('origin').value(),
+ dest: trip.attr('destination').value(),
+ times: {
+ orig: trip.attr('origTimeMin').value(),
+ dest: trip.attr('destTimeMin').value()
+ },
+ legs: trip.find('leg').map(function (leg) {
+ return {
+ orig: leg.attr('origin').value(),
+ dest: leg.attr('destination').value(),
+ line: leg.attr('line').value(),
+ head: leg.attr('trainHeadStation').value(),
+ times: {
+ orig: leg.attr('origTimeMin').value(),
+ dest: leg.attr('destTimeMin').value()
+ }
+ };
+ })
+ })
+ });
+
+ console.log(JSON.stringify(trips, true, 2));
+ });
+});
111 index.js
@@ -0,0 +1,111 @@
+var util = require('util');
+
+var request = require('request'),
+ libxmljs = require("libxmljs"),
+ qs = require('querystring');
+
+var Client = module.exports = function (key) {
+ if (!(this instanceof Client)) {
+ return new Client(key);
+ }
+ this.base = 'http://api.bart.gov/api/';
+ this.key = key;
+ addResources(this);
+};
+
+// Basic request action.
+Client.prototype.request = function (rsc, cmd, opts, cb) {
+ if (!cb) {
+ cb = opts;
+ opts = {};
+ }
+
+ opts.key = opts.key || this.key;
+
+ try {
+ var uri = (
+ this.base +
+ this._resource(rsc) +
+ '?' + this._command(cmd, opts)
+ );
+
+ // API is 100% GETs
+ var req = request.get({
+ uri: uri
+ }, !cb ? null : function (err, res, body) {
+ if (err) {
+ return cb(err);
+ }
+
+ if (res.statusCode !== 200) {
+ return cb(new Error(
+ '`' + url +'` expected: 200; actual: ' + res.statusCode
+ ));
+ }
+
+ cb(null, libxmljs.parseXml(body.toString()), body);
+ })
+ }
+ catch (err) {
+ cb(err);
+ }
+ // You can get a stream for passing into a sax parser too if you really
+ // want that
+ return req;
+};
+
+// Used to generate the uri.
+Client.prototype._resource = function (rsc) {
+ return rsc + '.aspx';
+};
+
+Client.prototype._command = function (cmd, opts) {
+ var command = {
+ cmd: cmd
+ };
+
+ Object.keys(opts).forEach(function (k) {
+ command[k] = opts[k];
+ });
+
+ return qs.stringify(command);
+};
+
+function addResources(client) {
+
+ var resources = {
+ bsa: [
+ 'bsa', 'count', 'elev', 'help', 'ver'
+ ],
+ etd: [
+ 'etd', 'help', 'ver'
+ ],
+ route: [
+ 'routeinfo', 'routes', 'help', 'ver'
+ ],
+ sched: [
+ 'arrive', 'depart', 'fare', 'help', 'holiday', 'routesched', 'scheds',
+ 'special', 'stnsched', 'ver'
+ ],
+ stn: [
+ 'help', 'stninfo', 'stnaccess', 'stns', 'ver'
+ ]
+ };
+
+ // Create methods for each resource
+ Object.keys(resources).forEach(function (rsc) {
+ var cmds = resources[rsc];
+
+ client[rsc] = function (cmd, opts, cb) {
+ client.request(rsc, cmd, opts, cb);
+ return client;
+ };
+
+ cmds.forEach(function (cmd) {
+ client[rsc][cmd] = function (opts, cb) {
+ client.request(rsc, cmd, opts, cb);
+ return client;
+ };
+ });
+ });
+}
29 package.json
@@ -0,0 +1,29 @@
+{
+ "name": "bart-api",
+ "version": "0.0.0",
+ "description": "Api client for api.bart.gov",
+ "main": "index.js",
+ "scripts": {
+ "test": "tests-of-the-sierra-madre && exit 1"
+ },
+ "keywords": [
+ "bart",
+ "bay",
+ "area",
+ "rapid",
+ "transit",
+ "train",
+ "api"
+ ],
+ "author": "Joshua Holbrook",
+ "license": "MIT/X11",
+ "dependencies": {
+ "request": "~2.11.1",
+ "querystring": "~0.1.0",
+ "libxmljs": "~0.6.1"
+ },
+ "devDependencies": {
+ "read": "*",
+ "tests-of-the-sierra-madre": "*"
+ }
+}

0 comments on commit e6d8f20

Please sign in to comment.