forked from codeforamerica/node-gtfs-zip-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
137 lines (115 loc) · 3.5 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
var http = require('http')
var gtfsFiles = require('./gtfsPackage')
var github = require('vinyl-github')
var zip = require('gulp-zip')
var buffer = require('gulp-buffer')
var fs = require('fs')
var filter = require('gulp-filter')
var csv = require('binary-csv')
var through = require('through2')
var File = require('vinyl')
var trailer = require('gulp-trailer')
http.createServer(function (req, res) {
res.setHeader('content-type', 'application/zip')
res.setHeader('Content-Disposition','attachment; filename=gtfs.zip')
getGtfsFeed(process.env.REPO)
.on('data', function (file) {
res.setHeader('content-length', file.contents.length)
res.write(file.contents)
res.end()
})
}).listen(process.env.PORT)
function getGtfsFeed(repo) {
var info = {
feed_publisher_name: 'unknown',
feed_publisher_url: 'http://unknown',
feed_lang: 'en',
feed_start_date: 0,
feed_end_date: 0,
feed_version: 'version'
}
var rev = '-'
return github.src(repo)
.pipe(buffer())
.pipe(filter(function (file) {
return gtfsFiles.isValid(file.path)
}))
.on('data', function (file) {
info.feed_version = file.ref
if (file.path === '/calendar.txt') {
parseCalendar(file.contents, info)
}
if (file.path === '/agency.txt') {
parseAgency(file.contents, info)
}
if (file.path === '/feed_info.txt') {
parseInfo(file.contents, info)
}
})
.on('data', function (x) {
console.log(x.path)
})
.pipe(zip('gtfs.zip'))
}
// get the earliest and latest calendar dates covered by this feed
function parseCalendar(file, info) {
var parser = csv()
var table = file.toString().split('\n').map(function (row) {
return row.split(',')
})
var headers = table.splice(0,1)[0]
var cols = table[0].length
var startCol = headers.indexOf('start_date')
var endCol = headers.indexOf('end_date')
info.feed_start_date = table.reduce(function (start, row) {
var rowStart = parseInt(row[startCol])
return rowStart ? Math.min(start, rowStart) : start
}, now())
info.feed_end_date = table.reduce(function (end, row) {
var rowEnd = parseInt(row[endCol])
return rowEnd ? Math.max(end, rowEnd) : end
}, now() + 1)
}
function now() {
var t = new Date()
var y = t.getFullYear()
var m = t.getMonth() + 1
m = m < 10 ? '0' + m : m
var d = t.getDate()
d = d < 10 ? '0' + d : d
return parseInt('' + y + m + d)
}
function parseAgency(file, info) {
var table = parsePairs(file)
info.feed_publisher_name = table.agency_name
info.feed_publisher_url = table.agency_url
// [ISO639-1] recommends that language codes be written in lowercase
// however, google's feed validator insists that it be identical to agency.txt
// info.feed_lang = table.agency_lang.toLowerCase()
// todo: lowercase the value in agency.txt
info.feed_lang = table.agency_lang
info.feed_id = table.agency_name
}
function parsePairs(buffer) {
var parser = csv()
var table = buffer.toString().split('\n').map(function (row) {
return row.split(',')
})
var headers = table[0]
return headers.reduce(function (o, key, i) {
o[key] = table[1][headers.indexOf(key)]
return o
}, {})
}
function writePairs(obj) {
var headers = []
var cells = []
Object.keys(obj).forEach(function (key) {
headers.push(key)
cells.push(obj[key])
})
return new Buffer(headers.join(',') + '\n' + cells.join(','))
}
function parseInfo(file, info) {
// todo: if a feed already has a feed_info.txt file specified, use it
}