transit-departures-widget 2.1.1 → 2.2.0

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/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.2.0] - 2024-03-07
9
+
10
+ ## Added
11
+
12
+ - startDate and endDate config params
13
+
14
+ ## Updated
15
+
16
+ - Dependency updates
17
+
8
18
  ## [2.1.1] - 2023-12-04
9
19
 
10
20
  ## Fixed
package/README.md CHANGED
@@ -93,11 +93,13 @@ Copy `config-sample.json` to `config.json` and then add your projects configurat
93
93
  | --------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- |
94
94
  | [`agency`](#agency) | object | Information about the GTFS and GTFS-RT to be used. |
95
95
  | [`beautify`](#beautify) | boolean | Whether or not to beautify the HTML output. |
96
+ | [`endDAte`](#enddate) | string | A date in YYYYMMDD format to use to filter calendar.txt service. Optional, defaults to using all service in specified GTFS. |
96
97
  | [`locale`](#locale) | string | The 2-letter code of the language to use for the interface. |
97
98
  | [`noHead`](#nohead) | boolean | Whether or not to skip the header and footer of the HTML document. |
98
99
  | [`refreshIntervalSeconds`](#refreshIntervalSeconds) | integer | How often the widget should refresh departure data in seconds. Optional, defaults to 20 seconds. |
99
100
  | [`skipImport`](#skipimport) | boolean | Whether or not to skip importing GTFS data into SQLite. |
100
101
  | [`sqlitePath`](#sqlitepath) | string | A path to an SQLite database. Optional, defaults to using an in-memory database. |
102
+ | [`startDate`](#startdate) | string | A date in YYYYMMDD format to use to filter calendar.txt service. Optional, defaults to using all service in specified GTFS. |
101
103
  | [`templatePath`](#templatepath) | string | Path to custom pug template for rendering widget. |
102
104
  | [`timeFormat`](#timeFormat) | string | The format (12hour or 24hour) for the "as of" display. |
103
105
 
@@ -157,6 +159,14 @@ Copy `config-sample.json` to `config.json` and then add your projects configurat
157
159
  "beautify": false
158
160
  ```
159
161
 
162
+ ### endDate
163
+
164
+ {Integer} A date in YYYYMMDD format to use to filter service_ids in calendar.txt. Useful in combination with `startDate` configuration option. Optional, if not specified, all services in GTFS will be used.
165
+
166
+ ```
167
+ "endDate": 20240401
168
+ ```
169
+
160
170
  ### locale
161
171
 
162
172
  {String} The 2-letter language code of the language to use for the interface. Current languages supported are Polish (`pl`) and English (`en`). Pull Requests welcome for translations to other languages. Defaults to `en` (English).
@@ -189,6 +199,14 @@ Copy `config-sample.json` to `config.json` and then add your projects configurat
189
199
  "skipImport": false
190
200
  ```
191
201
 
202
+ ### startDate
203
+
204
+ {Integer} A date in YYYYMMDD format to use to filter service_ids in calendar.txt. Useful in combination with `endDate` configuration option. Optional, if not specified, all services in GTFS will be used.
205
+
206
+ ```
207
+ "startDate": 20240301
208
+ ```
209
+
192
210
  ### sqlitePath
193
211
 
194
212
  {String} A path to an SQLite database. Optional, defaults to using an in-memory database.
package/lib/utils.js CHANGED
@@ -7,6 +7,29 @@ import sqlString from 'sqlstring-sqlite'
7
7
  import toposort from 'toposort'
8
8
  import i18n from 'i18n'
9
9
 
10
+ /*
11
+ * Get calendars for a specified date range
12
+ */
13
+ const getCalendarsForDateRange = (config) => {
14
+ const db = openDb(config)
15
+ let whereClause = ''
16
+ const whereClauses = []
17
+
18
+ if (config.endDate) {
19
+ whereClauses.push(`start_date <= ${sqlString.escape(config.endDate)}`)
20
+ }
21
+
22
+ if (config.startDate) {
23
+ whereClauses.push(`end_date >= ${sqlString.escape(config.startDate)}`)
24
+ }
25
+
26
+ if (whereClauses.length > 0) {
27
+ whereClause = `WHERE ${whereClauses.join(' AND ')}`
28
+ }
29
+
30
+ return db.prepare(`SELECT * FROM calendar ${whereClause}`).all()
31
+ }
32
+
10
33
  /*
11
34
  * Format a route name.
12
35
  */
@@ -40,11 +63,15 @@ function getDirectionsForRoute(route, config) {
40
63
  'direction',
41
64
  ])
42
65
 
66
+ const calendars = getCalendarsForDateRange(config)
67
+
43
68
  // Else use the most common headsigns as directions from trips.txt file
44
69
  if (directions.length === 0) {
45
70
  const headsigns = db
46
71
  .prepare(
47
- 'SELECT direction_id, trip_headsign, count(*) AS count FROM trips WHERE route_id = ? GROUP BY direction_id, trip_headsign',
72
+ `SELECT direction_id, trip_headsign, count(*) AS count FROM trips WHERE route_id = ? AND service_id IN (${calendars
73
+ .map((calendar) => `'${calendar.service_id}'`)
74
+ .join(', ')}) GROUP BY direction_id, trip_headsign`,
48
75
  )
49
76
  .all(route.route_id)
50
77
 
@@ -105,9 +132,11 @@ function sortStopIdsBySequence(stoptimes) {
105
132
  */
106
133
  function getStopsForDirection(route, direction, config) {
107
134
  const db = openDb(config)
135
+ const calendars = getCalendarsForDateRange(config)
108
136
  const whereClause = formatWhereClauses({
109
137
  direction_id: direction.direction_id,
110
138
  route_id: route.route_id,
139
+ service_id: calendars.map((calendar) => calendar.service_id),
111
140
  })
112
141
  const stoptimes = db
113
142
  .prepare(
@@ -155,6 +184,8 @@ export function generateTransitDeparturesWidgetHtml(config) {
155
184
  updateFiles: false,
156
185
  })
157
186
 
187
+ const calendars = getCalendarsForDateRange(config)
188
+
158
189
  for (const route of routes) {
159
190
  route.route_full_name = formatRouteName(route)
160
191
 
@@ -174,7 +205,11 @@ export function generateTransitDeparturesWidgetHtml(config) {
174
205
  direction.stopIds = directionStops.map((stop) => stop.stop_id)
175
206
 
176
207
  const trips = getTrips(
177
- { route_id: route.route_id, direction_id: direction.direction_id },
208
+ {
209
+ route_id: route.route_id,
210
+ direction_id: direction.direction_id,
211
+ service_id: calendars.map((calendar) => calendar.service_id),
212
+ },
178
213
  ['trip_id'],
179
214
  )
180
215
  direction.tripIds = trips.map((trip) => trip.trip_id)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "transit-departures-widget",
3
3
  "description": "Build a realtime transit departures tool from GTFS and GTFS-Realtime.",
4
- "version": "2.1.1",
4
+ "version": "2.2.0",
5
5
  "keywords": [
6
6
  "transit",
7
7
  "gtfs",
@@ -30,10 +30,10 @@
30
30
  "main": "index.js",
31
31
  "dependencies": {
32
32
  "copy-dir": "^1.3.0",
33
- "express": "^4.18.2",
34
- "gtfs": "^4.5.1",
33
+ "express": "^4.18.3",
34
+ "gtfs": "^4.7.2",
35
35
  "i18n": "^0.15.1",
36
- "js-beautify": "^1.14.11",
36
+ "js-beautify": "^1.15.1",
37
37
  "lodash-es": "^4.17.21",
38
38
  "morgan": "^1.10.0",
39
39
  "pretty-error": "^4.0.0",
@@ -44,12 +44,12 @@
44
44
  "toposort": "^2.0.2",
45
45
  "untildify": "^5.0.0",
46
46
  "yargs": "^17.7.2",
47
- "yoctocolors": "^1.0.0"
47
+ "yoctocolors": "^2.0.0"
48
48
  },
49
49
  "devDependencies": {
50
- "husky": "^8.0.3",
51
- "lint-staged": "^15.2.0",
52
- "prettier": "^3.1.0"
50
+ "husky": "^9.0.11",
51
+ "lint-staged": "^15.2.2",
52
+ "prettier": "^3.2.5"
53
53
  },
54
54
  "engines": {
55
55
  "node": ">= 14.15.4"