gtfs-to-html 2.10.0 → 2.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/index.js +65 -26
- package/dist/app/index.js.map +1 -1
- package/dist/bin/gtfs-to-html.js +200 -178
- package/dist/bin/gtfs-to-html.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.js +200 -178
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/bin/gtfs-to-html.js
CHANGED
|
@@ -103,6 +103,7 @@ import {
|
|
|
103
103
|
cloneDeep,
|
|
104
104
|
compact,
|
|
105
105
|
countBy,
|
|
106
|
+
difference,
|
|
106
107
|
entries,
|
|
107
108
|
every as every2,
|
|
108
109
|
find,
|
|
@@ -152,6 +153,163 @@ import { getShapesAsGeoJSON, getStopsAsGeoJSON } from "gtfs";
|
|
|
152
153
|
import { flatMap } from "lodash-es";
|
|
153
154
|
import simplify from "@turf/simplify";
|
|
154
155
|
import { featureCollection, round } from "@turf/helpers";
|
|
156
|
+
|
|
157
|
+
// src/lib/log-utils.ts
|
|
158
|
+
import { clearLine, cursorTo } from "node:readline";
|
|
159
|
+
import { noop } from "lodash-es";
|
|
160
|
+
import * as colors from "yoctocolors";
|
|
161
|
+
import { getFeedInfo } from "gtfs";
|
|
162
|
+
import Table from "cli-table";
|
|
163
|
+
function generateLogText(outputStats, config) {
|
|
164
|
+
const feedInfo = getFeedInfo();
|
|
165
|
+
const feedVersion = feedInfo.length > 0 && feedInfo[0].feed_version ? feedInfo[0].feed_version : "Unknown";
|
|
166
|
+
const logText = [
|
|
167
|
+
`Feed Version: ${feedVersion}`,
|
|
168
|
+
`GTFS-to-HTML Version: ${config.gtfsToHtmlVersion}`,
|
|
169
|
+
`Date Generated: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
170
|
+
`Timetable Page Count: ${outputStats.timetablePages}`,
|
|
171
|
+
`Timetable Count: ${outputStats.timetables}`,
|
|
172
|
+
`Calendar Service ID Count: ${outputStats.calendars}`,
|
|
173
|
+
`Route Count: ${outputStats.routes}`,
|
|
174
|
+
`Trip Count: ${outputStats.trips}`,
|
|
175
|
+
`Stop Count: ${outputStats.stops}`
|
|
176
|
+
];
|
|
177
|
+
for (const agency of config.agencies) {
|
|
178
|
+
if (agency.url) {
|
|
179
|
+
logText.push(`Source: ${agency.url}`);
|
|
180
|
+
} else if (agency.path) {
|
|
181
|
+
logText.push(`Source: ${agency.path}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (outputStats.warnings.length > 0) {
|
|
185
|
+
logText.push("", "Warnings:", ...outputStats.warnings);
|
|
186
|
+
}
|
|
187
|
+
return logText.join("\n");
|
|
188
|
+
}
|
|
189
|
+
function log(config) {
|
|
190
|
+
if (config.verbose === false) {
|
|
191
|
+
return noop;
|
|
192
|
+
}
|
|
193
|
+
if (config.logFunction) {
|
|
194
|
+
return config.logFunction;
|
|
195
|
+
}
|
|
196
|
+
return (text, overwrite) => {
|
|
197
|
+
if (overwrite === true && process.stdout.isTTY) {
|
|
198
|
+
clearLine(process.stdout, 0);
|
|
199
|
+
cursorTo(process.stdout, 0);
|
|
200
|
+
} else {
|
|
201
|
+
process.stdout.write("\n");
|
|
202
|
+
}
|
|
203
|
+
process.stdout.write(text);
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function logWarning(config) {
|
|
207
|
+
if (config.logFunction) {
|
|
208
|
+
return config.logFunction;
|
|
209
|
+
}
|
|
210
|
+
return (text) => {
|
|
211
|
+
process.stdout.write(`
|
|
212
|
+
${formatWarning(text)}
|
|
213
|
+
`);
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function logError(config) {
|
|
217
|
+
if (config.logFunction) {
|
|
218
|
+
return config.logFunction;
|
|
219
|
+
}
|
|
220
|
+
return (text) => {
|
|
221
|
+
process.stdout.write(`
|
|
222
|
+
${formatError(text)}
|
|
223
|
+
`);
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function formatWarning(text) {
|
|
227
|
+
const warningMessage = `${colors.underline("Warning")}: ${text}`;
|
|
228
|
+
return colors.yellow(warningMessage);
|
|
229
|
+
}
|
|
230
|
+
function formatError(error) {
|
|
231
|
+
const messageText = error instanceof Error ? error.message : error;
|
|
232
|
+
const errorMessage = `${colors.underline("Error")}: ${messageText.replace(
|
|
233
|
+
"Error: ",
|
|
234
|
+
""
|
|
235
|
+
)}`;
|
|
236
|
+
return colors.red(errorMessage);
|
|
237
|
+
}
|
|
238
|
+
function logStats(config) {
|
|
239
|
+
if (config.logFunction) {
|
|
240
|
+
return noop;
|
|
241
|
+
}
|
|
242
|
+
return (stats) => {
|
|
243
|
+
const table = new Table({
|
|
244
|
+
colWidths: [40, 20],
|
|
245
|
+
head: ["Item", "Count"]
|
|
246
|
+
});
|
|
247
|
+
table.push(
|
|
248
|
+
["\u{1F4C4} Timetable Pages", stats.timetablePages],
|
|
249
|
+
["\u{1F551} Timetables", stats.timetables],
|
|
250
|
+
["\u{1F4C5} Calendar Service IDs", stats.calendars],
|
|
251
|
+
["\u{1F504} Routes", stats.routes],
|
|
252
|
+
["\u{1F68D} Trips", stats.trips],
|
|
253
|
+
["\u{1F6D1} Stops", stats.stops],
|
|
254
|
+
["\u26D4\uFE0F Warnings", stats.warnings.length]
|
|
255
|
+
);
|
|
256
|
+
log(config)(table.toString());
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
var generateProgressBarString = (barTotal, barProgress, size2 = 40) => {
|
|
260
|
+
const line = "-";
|
|
261
|
+
const slider = "=";
|
|
262
|
+
if (!barTotal) {
|
|
263
|
+
throw new Error("Total value is either not provided or invalid");
|
|
264
|
+
}
|
|
265
|
+
if (!barProgress && barProgress !== 0) {
|
|
266
|
+
throw new Error("Current value is either not provided or invalid");
|
|
267
|
+
}
|
|
268
|
+
if (isNaN(barTotal)) {
|
|
269
|
+
throw new Error("Total value is not an integer");
|
|
270
|
+
}
|
|
271
|
+
if (isNaN(barProgress)) {
|
|
272
|
+
throw new Error("Current value is not an integer");
|
|
273
|
+
}
|
|
274
|
+
if (isNaN(size2)) {
|
|
275
|
+
throw new Error("Size is not an integer");
|
|
276
|
+
}
|
|
277
|
+
if (barProgress > barTotal) {
|
|
278
|
+
return slider.repeat(size2 + 2);
|
|
279
|
+
}
|
|
280
|
+
const percentage = barProgress / barTotal;
|
|
281
|
+
const progress = Math.round(size2 * percentage);
|
|
282
|
+
const emptyProgress = size2 - progress;
|
|
283
|
+
const progressText = slider.repeat(progress);
|
|
284
|
+
const emptyProgressText = line.repeat(emptyProgress);
|
|
285
|
+
return progressText + emptyProgressText;
|
|
286
|
+
};
|
|
287
|
+
function progressBar(formatString, barTotal, config) {
|
|
288
|
+
let barProgress = 0;
|
|
289
|
+
if (config.verbose === false) {
|
|
290
|
+
return {
|
|
291
|
+
increment: noop,
|
|
292
|
+
interrupt: noop
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
if (barTotal === 0) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
const renderProgressString = () => formatString.replace("{value}", barProgress).replace("{total}", barTotal).replace("{bar}", generateProgressBarString(barTotal, barProgress));
|
|
299
|
+
log(config)(renderProgressString(), true);
|
|
300
|
+
return {
|
|
301
|
+
interrupt(text) {
|
|
302
|
+
logWarning(config)(text);
|
|
303
|
+
log(config)("");
|
|
304
|
+
},
|
|
305
|
+
increment() {
|
|
306
|
+
barProgress += 1;
|
|
307
|
+
log(config)(renderProgressString(), true);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// src/lib/geojson-utils.ts
|
|
155
313
|
var mergeGeojson = (...geojsons) => featureCollection(flatMap(geojsons, (geojson) => geojson.features));
|
|
156
314
|
var truncateGeoJSONDecimals = (geojson, config) => {
|
|
157
315
|
for (const feature of geojson.features) {
|
|
@@ -179,18 +337,6 @@ var truncateGeoJSONDecimals = (geojson, config) => {
|
|
|
179
337
|
}
|
|
180
338
|
return geojson;
|
|
181
339
|
};
|
|
182
|
-
var simplifyGeoJSON = (geojson, config) => {
|
|
183
|
-
try {
|
|
184
|
-
const simplifiedGeojson = simplify(geojson, {
|
|
185
|
-
tolerance: 1 / 10 ** config.coordinatePrecision,
|
|
186
|
-
highQuality: true
|
|
187
|
-
});
|
|
188
|
-
return truncateGeoJSONDecimals(simplifiedGeojson, config);
|
|
189
|
-
} catch {
|
|
190
|
-
config.logWarning("Unable to simplify geojson");
|
|
191
|
-
return truncateGeoJSONDecimals(geojson, config);
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
340
|
function getTimetableGeoJSON(timetable, config) {
|
|
195
341
|
const shapesGeojsons = timetable.route_ids.map(
|
|
196
342
|
(routeId) => getShapesAsGeoJSON({
|
|
@@ -207,13 +353,35 @@ function getTimetableGeoJSON(timetable, config) {
|
|
|
207
353
|
})
|
|
208
354
|
);
|
|
209
355
|
const geojson = mergeGeojson(...shapesGeojsons, ...stopsGeojsons);
|
|
210
|
-
|
|
356
|
+
let simplifiedGeojson;
|
|
357
|
+
try {
|
|
358
|
+
simplifiedGeojson = simplify(geojson, {
|
|
359
|
+
tolerance: 1 / 10 ** config.coordinatePrecision,
|
|
360
|
+
highQuality: true
|
|
361
|
+
});
|
|
362
|
+
} catch {
|
|
363
|
+
timetable.warnings.push(
|
|
364
|
+
`Timetable ${timetable.timetable_id} - Unable to simplify geojson`
|
|
365
|
+
);
|
|
366
|
+
simplifiedGeojson = geojson;
|
|
367
|
+
}
|
|
368
|
+
return truncateGeoJSONDecimals(simplifiedGeojson, config);
|
|
211
369
|
}
|
|
212
370
|
function getAgencyGeoJSON(config) {
|
|
213
371
|
const shapesGeojsons = getShapesAsGeoJSON();
|
|
214
372
|
const stopsGeojsons = getStopsAsGeoJSON();
|
|
215
373
|
const geojson = mergeGeojson(shapesGeojsons, stopsGeojsons);
|
|
216
|
-
|
|
374
|
+
let simplifiedGeojson;
|
|
375
|
+
try {
|
|
376
|
+
simplifiedGeojson = simplify(geojson, {
|
|
377
|
+
tolerance: 1 / 10 ** config.coordinatePrecision,
|
|
378
|
+
highQuality: true
|
|
379
|
+
});
|
|
380
|
+
} catch {
|
|
381
|
+
logWarning(config)("Unable to simplify geojson");
|
|
382
|
+
simplifiedGeojson = geojson;
|
|
383
|
+
}
|
|
384
|
+
return truncateGeoJSONDecimals(simplifiedGeojson, config);
|
|
217
385
|
}
|
|
218
386
|
|
|
219
387
|
// src/lib/template-functions.ts
|
|
@@ -331,7 +499,7 @@ function formatTripNameForCSV(trip, timetable) {
|
|
|
331
499
|
}
|
|
332
500
|
|
|
333
501
|
// package.json
|
|
334
|
-
var version = "2.10.
|
|
502
|
+
var version = "2.10.1";
|
|
335
503
|
|
|
336
504
|
// src/lib/utils.ts
|
|
337
505
|
var isTimepoint = (stoptime) => {
|
|
@@ -561,7 +729,7 @@ var getTimetableNotesForTimetable = (timetable, config) => {
|
|
|
561
729
|
continue;
|
|
562
730
|
}
|
|
563
731
|
if (noteReference.stop_id === "" || noteReference.stop_id === null) {
|
|
564
|
-
|
|
732
|
+
timetable.warnings.push(
|
|
565
733
|
`Timetable Note Reference for note_id=${noteReference.note_id} has a \`stop_sequence\` but no \`stop_id\` - ignoring`
|
|
566
734
|
);
|
|
567
735
|
continue;
|
|
@@ -794,9 +962,19 @@ var getStopOrder = (timetable, config) => {
|
|
|
794
962
|
config
|
|
795
963
|
);
|
|
796
964
|
const stopIds = longestTripStoptimes.map((stoptime) => stoptime.stop_id);
|
|
797
|
-
|
|
798
|
-
|
|
965
|
+
const missingStopIds = difference(
|
|
966
|
+
uniq(
|
|
967
|
+
timetable.orderedTrips.flatMap(
|
|
968
|
+
(trip) => trip.stoptimes.map((stoptime) => stoptime.stop_id)
|
|
969
|
+
)
|
|
970
|
+
),
|
|
971
|
+
uniq(stopIds)
|
|
799
972
|
);
|
|
973
|
+
if (missingStopIds.length > 0) {
|
|
974
|
+
timetable.warnings.push(
|
|
975
|
+
`Timetable ${timetable.timetable_id} stops are unable to be topologically sorted and has no \`timetable_stop_order.txt\`. Falling back to using the using the stop order from trip with most stoptimes, but this does not include stop_ids ${new Intl.ListFormat("en", { style: "long", type: "conjunction" }).format(missingStopIds)}. Try manually specifying stops with \`timetable_stop_order.txt\`. Read more at https://gtfstohtml.com/docs/timetable-stop-order`
|
|
976
|
+
);
|
|
977
|
+
}
|
|
800
978
|
return duplicateStopsForDifferentArrivalDeparture(
|
|
801
979
|
stopIds,
|
|
802
980
|
timetable,
|
|
@@ -1996,159 +2174,6 @@ async function renderPdf(htmlPath) {
|
|
|
1996
2174
|
await browser.close();
|
|
1997
2175
|
}
|
|
1998
2176
|
|
|
1999
|
-
// src/lib/log-utils.ts
|
|
2000
|
-
import { clearLine, cursorTo } from "node:readline";
|
|
2001
|
-
import { noop } from "lodash-es";
|
|
2002
|
-
import * as colors from "yoctocolors";
|
|
2003
|
-
import { getFeedInfo } from "gtfs";
|
|
2004
|
-
import Table from "cli-table";
|
|
2005
|
-
function generateLogText(outputStats, config) {
|
|
2006
|
-
const feedInfo = getFeedInfo();
|
|
2007
|
-
const feedVersion = feedInfo.length > 0 && feedInfo[0].feed_version ? feedInfo[0].feed_version : "Unknown";
|
|
2008
|
-
const logText = [
|
|
2009
|
-
`Feed Version: ${feedVersion}`,
|
|
2010
|
-
`GTFS-to-HTML Version: ${config.gtfsToHtmlVersion}`,
|
|
2011
|
-
`Date Generated: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
2012
|
-
`Timetable Page Count: ${outputStats.timetablePages}`,
|
|
2013
|
-
`Timetable Count: ${outputStats.timetables}`,
|
|
2014
|
-
`Calendar Service ID Count: ${outputStats.calendars}`,
|
|
2015
|
-
`Route Count: ${outputStats.routes}`,
|
|
2016
|
-
`Trip Count: ${outputStats.trips}`,
|
|
2017
|
-
`Stop Count: ${outputStats.stops}`
|
|
2018
|
-
];
|
|
2019
|
-
for (const agency of config.agencies) {
|
|
2020
|
-
if (agency.url) {
|
|
2021
|
-
logText.push(`Source: ${agency.url}`);
|
|
2022
|
-
} else if (agency.path) {
|
|
2023
|
-
logText.push(`Source: ${agency.path}`);
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
if (outputStats.warnings.length > 0) {
|
|
2027
|
-
logText.push("", "Warnings:", ...outputStats.warnings);
|
|
2028
|
-
}
|
|
2029
|
-
return logText.join("\n");
|
|
2030
|
-
}
|
|
2031
|
-
function log(config) {
|
|
2032
|
-
if (config.verbose === false) {
|
|
2033
|
-
return noop;
|
|
2034
|
-
}
|
|
2035
|
-
if (config.logFunction) {
|
|
2036
|
-
return config.logFunction;
|
|
2037
|
-
}
|
|
2038
|
-
return (text, overwrite) => {
|
|
2039
|
-
if (overwrite === true && process.stdout.isTTY) {
|
|
2040
|
-
clearLine(process.stdout, 0);
|
|
2041
|
-
cursorTo(process.stdout, 0);
|
|
2042
|
-
} else {
|
|
2043
|
-
process.stdout.write("\n");
|
|
2044
|
-
}
|
|
2045
|
-
process.stdout.write(text);
|
|
2046
|
-
};
|
|
2047
|
-
}
|
|
2048
|
-
function logWarning(config) {
|
|
2049
|
-
if (config.logFunction) {
|
|
2050
|
-
return config.logFunction;
|
|
2051
|
-
}
|
|
2052
|
-
return (text) => {
|
|
2053
|
-
process.stdout.write(`
|
|
2054
|
-
${formatWarning(text)}
|
|
2055
|
-
`);
|
|
2056
|
-
};
|
|
2057
|
-
}
|
|
2058
|
-
function logError(config) {
|
|
2059
|
-
if (config.logFunction) {
|
|
2060
|
-
return config.logFunction;
|
|
2061
|
-
}
|
|
2062
|
-
return (text) => {
|
|
2063
|
-
process.stdout.write(`
|
|
2064
|
-
${formatError(text)}
|
|
2065
|
-
`);
|
|
2066
|
-
};
|
|
2067
|
-
}
|
|
2068
|
-
function formatWarning(text) {
|
|
2069
|
-
const warningMessage = `${colors.underline("Warning")}: ${text}`;
|
|
2070
|
-
return colors.yellow(warningMessage);
|
|
2071
|
-
}
|
|
2072
|
-
function formatError(error) {
|
|
2073
|
-
const messageText = error instanceof Error ? error.message : error;
|
|
2074
|
-
const errorMessage = `${colors.underline("Error")}: ${messageText.replace(
|
|
2075
|
-
"Error: ",
|
|
2076
|
-
""
|
|
2077
|
-
)}`;
|
|
2078
|
-
return colors.red(errorMessage);
|
|
2079
|
-
}
|
|
2080
|
-
function logStats(stats, config) {
|
|
2081
|
-
if (config.logFunction) {
|
|
2082
|
-
return;
|
|
2083
|
-
}
|
|
2084
|
-
const table = new Table({
|
|
2085
|
-
colWidths: [40, 20],
|
|
2086
|
-
head: ["Item", "Count"]
|
|
2087
|
-
});
|
|
2088
|
-
table.push(
|
|
2089
|
-
["\u{1F4C4} Timetable Pages", stats.timetablePages],
|
|
2090
|
-
["\u{1F551} Timetables", stats.timetables],
|
|
2091
|
-
["\u{1F4C5} Calendar Service IDs", stats.calendars],
|
|
2092
|
-
["\u{1F504} Routes", stats.routes],
|
|
2093
|
-
["\u{1F68D} Trips", stats.trips],
|
|
2094
|
-
["\u{1F6D1} Stops", stats.stops],
|
|
2095
|
-
["\u26D4\uFE0F Warnings", stats.warnings.length]
|
|
2096
|
-
);
|
|
2097
|
-
config.log(table.toString());
|
|
2098
|
-
}
|
|
2099
|
-
var generateProgressBarString = (barTotal, barProgress, size2 = 40) => {
|
|
2100
|
-
const line = "-";
|
|
2101
|
-
const slider = "=";
|
|
2102
|
-
if (!barTotal) {
|
|
2103
|
-
throw new Error("Total value is either not provided or invalid");
|
|
2104
|
-
}
|
|
2105
|
-
if (!barProgress && barProgress !== 0) {
|
|
2106
|
-
throw new Error("Current value is either not provided or invalid");
|
|
2107
|
-
}
|
|
2108
|
-
if (isNaN(barTotal)) {
|
|
2109
|
-
throw new Error("Total value is not an integer");
|
|
2110
|
-
}
|
|
2111
|
-
if (isNaN(barProgress)) {
|
|
2112
|
-
throw new Error("Current value is not an integer");
|
|
2113
|
-
}
|
|
2114
|
-
if (isNaN(size2)) {
|
|
2115
|
-
throw new Error("Size is not an integer");
|
|
2116
|
-
}
|
|
2117
|
-
if (barProgress > barTotal) {
|
|
2118
|
-
return slider.repeat(size2 + 2);
|
|
2119
|
-
}
|
|
2120
|
-
const percentage = barProgress / barTotal;
|
|
2121
|
-
const progress = Math.round(size2 * percentage);
|
|
2122
|
-
const emptyProgress = size2 - progress;
|
|
2123
|
-
const progressText = slider.repeat(progress);
|
|
2124
|
-
const emptyProgressText = line.repeat(emptyProgress);
|
|
2125
|
-
return progressText + emptyProgressText;
|
|
2126
|
-
};
|
|
2127
|
-
function progressBar(formatString, barTotal, config) {
|
|
2128
|
-
let barProgress = 0;
|
|
2129
|
-
if (config.verbose === false) {
|
|
2130
|
-
return {
|
|
2131
|
-
increment: noop,
|
|
2132
|
-
interrupt: noop
|
|
2133
|
-
};
|
|
2134
|
-
}
|
|
2135
|
-
if (barTotal === 0) {
|
|
2136
|
-
return null;
|
|
2137
|
-
}
|
|
2138
|
-
const renderProgressString = () => formatString.replace("{value}", barProgress).replace("{total}", barTotal).replace("{bar}", generateProgressBarString(barTotal, barProgress));
|
|
2139
|
-
config.log(renderProgressString(), true);
|
|
2140
|
-
return {
|
|
2141
|
-
interrupt(text) {
|
|
2142
|
-
config.logWarning(text);
|
|
2143
|
-
config.log("");
|
|
2144
|
-
},
|
|
2145
|
-
increment() {
|
|
2146
|
-
barProgress += 1;
|
|
2147
|
-
config.log(renderProgressString(), true);
|
|
2148
|
-
}
|
|
2149
|
-
};
|
|
2150
|
-
}
|
|
2151
|
-
|
|
2152
2177
|
// src/lib/gtfs-to-html.ts
|
|
2153
2178
|
import path from "node:path";
|
|
2154
2179
|
import { mkdir as mkdir2, writeFile } from "node:fs/promises";
|
|
@@ -2160,9 +2185,6 @@ import untildify2 from "untildify";
|
|
|
2160
2185
|
var gtfsToHtml = async (initialConfig) => {
|
|
2161
2186
|
const config = setDefaultConfig(initialConfig);
|
|
2162
2187
|
const timer = new Timer();
|
|
2163
|
-
config.log = log(config);
|
|
2164
|
-
config.logWarning = logWarning(config);
|
|
2165
|
-
config.logError = logError(config);
|
|
2166
2188
|
const agencyKey = config.agencies.map(
|
|
2167
2189
|
(agency) => agency.agencyKey ?? agency.agency_key ?? "unknown"
|
|
2168
2190
|
).join("-");
|
|
@@ -2173,7 +2195,7 @@ var gtfsToHtml = async (initialConfig) => {
|
|
|
2173
2195
|
openDb2(config);
|
|
2174
2196
|
} catch (error) {
|
|
2175
2197
|
if (error?.code === "SQLITE_CANTOPEN") {
|
|
2176
|
-
|
|
2198
|
+
logError(config)(
|
|
2177
2199
|
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json.`
|
|
2178
2200
|
);
|
|
2179
2201
|
}
|
|
@@ -2281,12 +2303,12 @@ var gtfsToHtml = async (initialConfig) => {
|
|
|
2281
2303
|
outputPath,
|
|
2282
2304
|
config.zipOutput ? "/timetables.zip" : ""
|
|
2283
2305
|
);
|
|
2284
|
-
|
|
2306
|
+
log(config)(
|
|
2285
2307
|
`${agencyKey}: ${config.outputFormat.toUpperCase()} timetables created at ${fullOutputPath}`
|
|
2286
2308
|
);
|
|
2287
|
-
logStats(
|
|
2309
|
+
logStats(config)(stats);
|
|
2288
2310
|
const seconds = Math.round(timer.time() / 1e3);
|
|
2289
|
-
|
|
2311
|
+
log(config)(
|
|
2290
2312
|
`${agencyKey}: ${config.outputFormat.toUpperCase()} timetable generation required ${seconds} seconds`
|
|
2291
2313
|
);
|
|
2292
2314
|
timer.stop();
|