PyTransportNSWv2 0.3.4__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyTransportNSWv2
3
- Version: 0.3.4
3
+ Version: 0.4.0
4
4
  Summary: Get detailed per-trip transport information from TransportNSW
5
5
  Home-page: https://github.com/andystewart999/TransportNSW
6
6
  Author: andystewart999
@@ -33,7 +33,7 @@ The source API details can be found here: https://opendata.transport.nsw.gov.au/
33
33
 
34
34
  ### Parameters
35
35
  ```python
36
- .get_trip(origin_stop_id, destination_stop_id, api_key, [trip_wait_time = 0], [transport_type = 0])
36
+ .get_trip(origin_stop_id, destination_stop_id, api_key, [journey_wait_time = 0], [transport_type = 0], [strict_transport_type = False], [raw_output = False], [journeys_to_return = 1])
37
37
  ```
38
38
  TransportNSW's trip planner can work better if you use the general location IDs (eg Central Station) rather than a specific Stop ID (eg Central Station, Platform 19) for the destination, depending on the transport type. Forcing a specific end destination sometimes results in much more complicated trips. Also note that the API expects (and returns) the Stop IDs as strings, although so far they all appear to be numeric.
39
39
 
@@ -49,10 +49,13 @@ TransportNSW's trip planner can work better if you use the general location IDs
49
49
  100: Walk
50
50
  107: Cycle
51
51
  ```
52
+ If you call the function with a `transport_type` filter and set `strict_transport_type` to `True`, only journeys whose **first** leg matches the desired filter will be considered. Otherwise the filter includes a journey if **any** of the legs includes the desired travel type.
53
+
54
+ `raw_output` simply returns the entire API response string as JSON, without making any changes to it.
52
55
 
53
56
  ### Sample Code
54
57
 
55
- The following example will return the next trip that starts from a bus stop in St. Ives (207537) five minutes from now, to Central Station's general stop ID (10101100):
58
+ The following example will return the next trip that starts from Pymble Station (207310) five minutes from now, to Gordon Station (207210). Note that specific platforms, such as Gordon Station, Platform 3 (207263) haven't been specified so any platform combination will be accepted:
56
59
 
57
60
  **Code:**
58
61
  ```python
@@ -62,8 +65,34 @@ journey = tnsw.get_trip('207537', '10101100', 'YOUR_API_KEY', 5)
62
65
  print(journey)
63
66
  ```
64
67
  **Result:**
65
- ```python
66
- {"due": 3, "origin_stop_id": "207537", "origin_name": "Mona Vale Rd at Shinfield Ave, St Ives", "departure_time": "2024-05-20T21:59:48Z", "destination_stop_id": "2000338", "destination_name": "Central Station, Platform 18, Sydney", "arrival_time": "2024-05-20T22:47:36Z", "origin_transport_type": "Bus", "origin_transport_name": "Sydney Buses Network", "origin_line_name": "195", "origin_line_name_short": "195", "changes": 1, "occupancy": "MANY_SEATS", "real_time_trip_id": "2096551", "latitude": -33.72665786743164, "longitude": 151.16305541992188}
68
+
69
+ Unless `raw_output` is `True`, the return output always returns an array of journeys, even if `journeys_to_return` is 1. The journey array is preceded by how many journeys were requested, and how many were actually returned that contained usable data:
70
+
71
+ ```json
72
+ {
73
+ "journeys_to_return": 1,
74
+ "journeys_with_data": 1,
75
+ "journeys": [
76
+ {
77
+ "due": 6,
78
+ "origin_stop_id": "2073161",
79
+ "origin_name": "Pymble Station, Platform 1, Pymble",
80
+ "departure_time": "2024-05-28T22:40:24Z",
81
+ "destination_stop_id": "207261",
82
+ "destination_name": "Gordon Station, Platform 1, Gordon",
83
+ "arrival_time": "2024-05-28T22:42:30Z",
84
+ "origin_transport_type": "Train",
85
+ "origin_transport_name": "Sydney Trains Network",
86
+ "origin_line_name": "T1 North Shore & Western Line",
87
+ "origin_line_name_short": "T1",
88
+ "changes": 0,
89
+ "occupancy": "UNKNOWN",
90
+ "real_time_trip_id": "161E.1378.133.60.A.8.80758268",
91
+ "latitude": "n/a",
92
+ "longitude": "n/a"
93
+ }
94
+ ]
95
+ }
67
96
  ```
68
97
  Fun fact: TransportNSW's raw API output calls itself JSON, but it uses single quotes for strings in defiance of the JSON standards. When using this wrapper the output is formatted such that `jq`, for example, is happy with it.
69
98
 
@@ -83,7 +112,6 @@ Fun fact: TransportNSW's raw API output calls itself JSON, but it uses single q
83
112
  * latitude & longitude: The location of the vehicle, if available
84
113
 
85
114
  Please note that the origin and destination detail is just that - information about the first and last stops on the journey at the time the request was made. We don't return any intermediate steps, transport change types etc other than the total number of changes - the assumption is that you'll know the details of your specified trip, you just want to know when the next departure is. If you need much more detailed information then I recommend that you use the full Transport NSW trip planner website or application.
86
- Also note that the 'transport_type' filter, if present, only makes sure that at least one leg of the journey includes that transport type.
87
115
 
88
116
  ## Thank you
89
117
  Thank you Dav0815 for your TransportNSW library that the vast majority of this fork is based on. I couldn't have done it without you!
@@ -0,0 +1,7 @@
1
+ TransportNSW/TransportNSW.py,sha256=FRXqREdCtjzn5D_PR01JloecUahRUT8uAHl1jarMv5s,18043
2
+ TransportNSW/__init__.py,sha256=O3iuSkUGkkDz4C7IlqvOXJHPJTxYz0q_48-94ESlkdg,86
3
+ PyTransportNSWv2-0.4.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
4
+ PyTransportNSWv2-0.4.0.dist-info/METADATA,sha256=cZwmoYVk2-wYPyclEO9weGmzQWZNRMqyIYOtpsbsQXc,6373
5
+ PyTransportNSWv2-0.4.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
+ PyTransportNSWv2-0.4.0.dist-info/top_level.txt,sha256=C4LQEkr85VJtG9cklBu9IFpSKRaNSADPBTSPeXIYnOw,13
7
+ PyTransportNSWv2-0.4.0.dist-info/RECORD,,
@@ -46,8 +46,11 @@ class TransportNSW(object):
46
46
  self.origin_id = None
47
47
  self.destination_id = None
48
48
  self.api_key = None
49
- self.trip_wait_time = None
49
+ self.journey_wait_time = None
50
50
  self.transport_type = None
51
+ self.strict_transport_type = None
52
+ self.raw_output = None
53
+ self.journeys_to_return = None
51
54
  self.info = {
52
55
  ATTR_DUE_IN : 'n/a',
53
56
  ATTR_ORIGIN_STOP_ID : 'n/a',
@@ -67,37 +70,38 @@ class TransportNSW(object):
67
70
  ATTR_LONGITUDE : 'n/a'
68
71
  }
69
72
 
70
- def get_trip(self, name_origin, name_destination , api_key, trip_wait_time = 0, transport_type = 0):
73
+ def get_trip(self, name_origin, name_destination , api_key, journey_wait_time = 0, transport_type = 0, \
74
+ strict_transport_type = False, raw_output = False, journeys_to_return = 1):
71
75
  """Get the latest data from Transport NSW."""
72
76
  fmt = '%Y-%m-%dT%H:%M:%SZ'
73
77
 
74
78
  self.name_origin = name_origin
75
79
  self.destination = name_destination
76
80
  self.api_key = api_key
77
- self.trip_wait_time = trip_wait_time
81
+ self.journey_wait_time = journey_wait_time
78
82
  self.transport_type = transport_type
83
+ self.strict_transport_type = strict_transport_type
84
+ self.raw_output = raw_output
85
+ self.journeys_to_return = journeys_to_return
79
86
 
80
- # This query always uses the current date and time - but add in any 'trip_wait_time' minutes
81
- now_plus_wait = datetime.now() + timedelta(minutes = trip_wait_time)
87
+ # This query always uses the current date and time - but add in any 'journey_wait_time' minutes
88
+ now_plus_wait = datetime.now() + timedelta(minutes = journey_wait_time)
82
89
  itdDate = now_plus_wait.strftime('%Y%m%d')
83
90
  itdTime = now_plus_wait.strftime('%H%M')
84
91
 
85
- if transport_type == 0:
86
- # We only need to retrieve one trip - a transport type filter hasn't been applied
87
- numberOfTrips = 1
88
- else:
89
- # 5 trips seems like a safe number
90
- numberOfTrips = 5
92
+ # We don't control how many journeys are returned any more, so need to be careful of running out of valid journeys if there is a filter in place, particularly a strict filter
93
+ # It would be more efficient to return one journey, check if the filter is met and then retrieve the next one via a new query if not, but for now we'll only be making use of the journeys we've been given
91
94
 
92
95
  # Build the entire URL
93
96
  url = \
94
97
  'https://api.transport.nsw.gov.au/v1/tp/trip?' \
95
98
  'outputFormat=rapidJSON&coordOutputFormat=EPSG%3A4326' \
96
99
  '&depArrMacro=dep&itdDate=' + itdDate + '&itdTime=' + itdTime + \
97
- '&type_origin=any&name_origin=' + name_origin + \
98
- '&type_destination=any&name_destination=' + name_destination + \
99
- '&calcNumberOfTrips=' + str(numberOfTrips) + \
100
+ '&type_origin=any&name_origin=' + self.name_origin + \
101
+ '&type_destination=any&name_destination=' + self.destination + \
100
102
  '&TfNSWTR=true'
103
+ # '&calcNumberOfTrips=' + str(journeys_to_retrieve) + \
104
+
101
105
 
102
106
  auth = 'apikey ' + self.api_key
103
107
  header = {'Accept': 'application/json', 'Authorization': auth}
@@ -108,13 +112,12 @@ class TransportNSW(object):
108
112
  response = requests.get(url, headers=header, timeout=10)
109
113
  except:
110
114
  logger.warning("Network or Timeout error")
111
- return self.info
115
+ return error_return(self.info, raw_output)
112
116
 
113
- # If there is no valid request (e.g. http code isn't 200)
114
- # log error and return empty object
117
+ # If we get bad status code, log error and return with n/a or an empty string
115
118
  if response.status_code != 200:
116
119
  logger.warning("Error with the request sent; check api key")
117
- return self.info
120
+ return error_return(self.info, raw_output)
118
121
 
119
122
  # Parse the result as a JSON object
120
123
  result = response.json()
@@ -125,186 +128,254 @@ class TransportNSW(object):
125
128
  # The assumption is that the travelee will know HOW to make the defined journey, they're just asking WHEN it's happening next
126
129
  # All we potentially have to do is find the first trip that matches the transport_type filter
127
130
 
128
- if transport_type == 0:
129
- # Just grab the first (and only) trip
130
- journey = result['journeys'][0]
131
- else:
132
- # Look for a trip with a matching class filter in at least one of its legs. Could possibly be more stringent here, if ANY part of the journey fits the filter, it will be returned.
133
- journey = self.find_first_journey(result['journeys'], transport_type)
134
-
135
- if journey is None:
136
- logger.warning("No journey information returned")
137
- return self.info
138
-
139
- if journey['legs'] is None:
140
- logger.warning("No journey information returned")
141
- return self.info
142
-
143
- legs = journey['legs']
144
- first_leg = self.find_first_leg(legs, transport_type)
145
- last_leg = self.find_last_leg(legs, transport_type)
146
- changes = self.find_changes(legs, transport_type)
147
-
148
- origin = result['journeys'][0]['legs'][first_leg]['origin']
149
- # probably tidy this up when we start to get occupancy data back
150
- first_stop = result['journeys'][0]['legs'][first_leg]['destination']
151
- destination = result['journeys'][0]['legs'][last_leg]['destination']
152
- transportation = result['journeys'][0]['legs'][first_leg]['transportation']
153
-
154
-
155
- # Origin info
156
- origin_stop_id = origin['id']
157
- origin_name = origin['name']
158
- origin_departure_time = origin['departureTimeEstimated']
159
-
160
- # How long until it leaves?
161
- due = self.get_due(datetime.strptime(origin_departure_time, fmt))
162
-
163
- # Destination info
164
- destination_stop_id = destination['id']
165
- destination_name = destination['name']
166
- destination_arrival_time = destination['arrivalTimeEstimated']
167
-
168
- # Origin type info - train, bus, etc
169
- origin_mode_temp = transportation['product']['class']
170
- origin_mode = self.get_mode(origin_mode_temp)
171
- origin_mode_name = transportation['product']['name']
172
-
173
- # RealTimeTripID info so we can try and get the current location later
174
- realtimetripid = 'n/a'
175
- if 'properties' in transportation:
176
- if 'RealtimeTripId' in transportation['properties']:
177
- realtimetripid = transportation['properties']['RealtimeTripId']
178
-
179
- # Line info
180
- origin_line_name_short = "unknown"
181
- if 'disassembledName' in transportation:
182
- origin_line_name_short = transportation['disassembledName']
183
-
184
- origin_line_name = "unknown"
185
- if 'number' in transportation:
186
- origin_line_name = transportation['number']
187
-
188
- # Occupancy info, if it's there
189
- occupancy = 'UNKNOWN'
190
- if 'properties' in first_stop:
191
- if 'occupancy' in first_stop['properties']:
192
- occupancy = first_stop['properties']['occupancy']
193
-
194
- # Now might be a good time to see if we can also find the latitude and longitude
195
- # Using the Realtime Vehicle Positions API
196
- latitude = 'n/a'
197
- longitude = 'n/a'
198
-
199
- if realtimetripid != 'n/a':
200
- # Build the URL
201
- url = \
202
- 'https://api.transport.nsw.gov.au/v1/gtfs/vehiclepos' \
203
- + self.get_url(origin_mode)
204
- auth = 'apikey ' + self.api_key
205
- header = {'Authorization': auth}
206
-
207
- response = requests.get(url, headers=header, timeout=10)
208
-
209
- # Only try and process the results if we got a good return code
210
- if response.status_code == 200:
211
- # Search the feed and see if we can find the trip_id
212
- # If we do, capture the latitude and longitude
213
-
214
- feed = gtfs_realtime_pb2.FeedMessage()
215
- feed.ParseFromString(response.content)
216
-
217
- # Unfortunately we need to do some mucking about for train-based trip_ids
218
- # Define the appropriate regular expression to search for - usually just the full text
219
- bFindLocation = True
220
-
221
- if origin_mode == 'Train':
222
- triparray = realtimetripid.split('.')
223
- if len(triparray) == 7:
224
- trip_id_wild = triparray[0] + '.' + triparray[1] + '.' + triparray[2] + '.+.' + triparray[4] + '.' + triparray[5] + '.' + triparray[6]
225
- else:
226
- # Hmm, it's not the right length (this happens rarely) - give up
227
- bFindLocation = False
228
- else:
229
- trip_id_wild = realtimetripid
230
-
231
- if bFindLocation:
232
- reg = re.compile(trip_id_wild)
233
-
234
- for entity in feed.entity:
235
- if bool(re.match(reg, entity.vehicle.trip.trip_id)):
236
- latitude = entity.vehicle.position.latitude
237
- longitude = entity.vehicle.position.longitude
238
- # We found it, so break out
239
- break
131
+ if raw_output == True:
132
+ # Just return the raw output
133
+ return json.dumps(result)
134
+ exit
135
+
136
+ retrieved_journeys = len(result['journeys'])
137
+
138
+ # Loop through the results applying filters where required, and generate the appropriate JSON output including an array of in-scope trips
139
+ json_output=''
140
+ found_journeys = 0
141
+ no_valid_journeys = False
142
+
143
+ for current_journey in range (0, retrieved_journeys, 1):
144
+ if transport_type == 0:
145
+ # Just grab the next trip
146
+ journey = result['journeys'][current_journey]
147
+ next_journey = current_journey + 1
148
+ else:
149
+ # Look for a trip with a matching class filter in at least one of its legs. Either ANY, or the first leg, depending on how strict we're being
150
+ journey, next_journey = self.find_next_journey(result['journeys'], current_journey, transport_type, strict_transport_type)
151
+
152
+ if (journey is None) or (journey['legs']) is None:
153
+ #We've reached the end
154
+ no_valid_journeys = True
155
+ self.info = {
156
+ ATTR_DUE_IN : 'n/a',
157
+ ATTR_ORIGIN_STOP_ID : 'n/a',
158
+ ATTR_ORIGIN_NAME : 'n/a',
159
+ ATTR_DEPARTURE_TIME : 'n/a',
160
+ ATTR_DESTINATION_STOP_ID : 'n/a',
161
+ ATTR_DESTINATION_NAME : 'n/a',
162
+ ATTR_ARRIVAL_TIME : 'n/a',
163
+ ATTR_ORIGIN_TRANSPORT_TYPE : 'n/a',
164
+ ATTR_ORIGIN_TRANSPORT_NAME : 'n/a',
165
+ ATTR_ORIGIN_LINE_NAME : 'n/a',
166
+ ATTR_ORIGIN_LINE_NAME_SHORT : 'n/a',
167
+ ATTR_CHANGES : 'n/a',
168
+ ATTR_OCCUPANCY : 'n/a',
169
+ ATTR_REAL_TIME_TRIP_ID : 'n/a',
170
+ ATTR_LATITUDE : 'n/a',
171
+ ATTR_LONGITUDE : 'n/a'
172
+ }
173
+ else:
174
+ legs = journey['legs']
175
+ first_leg = self.find_first_leg(legs, transport_type, strict_transport_type)
176
+ last_leg = self.find_last_leg(legs, transport_type, strict_transport_type)
177
+ changes = self.find_changes(legs, transport_type)
178
+
179
+ origin = first_leg['origin']
180
+ first_stop = first_leg['destination']
181
+ destination = last_leg['destination']
182
+ transportation = first_leg['transportation']
183
+
184
+
185
+ # Origin info
186
+ origin_stop_id = origin['id']
187
+ origin_name = origin['name']
188
+ origin_departure_time = origin['departureTimeEstimated']
189
+
190
+ # How long until it leaves?
191
+ due = self.get_due(datetime.strptime(origin_departure_time, fmt))
192
+
193
+ # Destination info
194
+ destination_stop_id = destination['id']
195
+ destination_name = destination['name']
196
+ destination_arrival_time = destination['arrivalTimeEstimated']
197
+
198
+ # Origin type info - train, bus, etc
199
+ origin_mode_temp = transportation['product']['class']
200
+ origin_mode = self.get_mode(origin_mode_temp)
201
+ origin_mode_name = transportation['product']['name']
202
+
203
+ # RealTimeTripID info so we can try and get the current location later
204
+ realtimetripid = 'n/a'
205
+ if 'properties' in transportation:
206
+ if 'RealtimeTripId' in transportation['properties']:
207
+ realtimetripid = transportation['properties']['RealtimeTripId']
208
+
209
+ # Line info
210
+ origin_line_name_short = "unknown"
211
+ if 'disassembledName' in transportation:
212
+ origin_line_name_short = transportation['disassembledName']
213
+
214
+ origin_line_name = "unknown"
215
+ if 'number' in transportation:
216
+ origin_line_name = transportation['number']
217
+
218
+ # Occupancy info, if it's there
219
+ occupancy = 'UNKNOWN'
220
+ if 'properties' in first_stop:
221
+ if 'occupancy' in first_stop['properties']:
222
+ occupancy = first_stop['properties']['occupancy']
223
+
224
+ # Now might be a good time to see if we can also find the latitude and longitude
225
+ # Using the Realtime Vehicle Positions API
226
+ latitude = 'n/a'
227
+ longitude = 'n/a'
228
+
229
+ if realtimetripid != 'n/a':
230
+ # Build the URL
231
+ url = \
232
+ 'https://api.transport.nsw.gov.au/v1/gtfs/vehiclepos' \
233
+ + self.get_url(origin_mode)
234
+ auth = 'apikey ' + self.api_key
235
+ header = {'Authorization': auth}
236
+
237
+ response = requests.get(url, headers=header, timeout=10)
238
+
239
+ # Only try and process the results if we got a good return code
240
+ if response.status_code == 200:
241
+ # Search the feed and see if we can find the trip_id
242
+ # If we do, capture the latitude and longitude
243
+
244
+ feed = gtfs_realtime_pb2.FeedMessage()
245
+ feed.ParseFromString(response.content)
246
+
247
+ # Unfortunately we need to do some mucking about for train-based trip_ids
248
+ # Define the appropriate regular expression to search for - usually just the full text
249
+ bFindLocation = True
250
+
251
+ if origin_mode == 'Train':
252
+ triparray = realtimetripid.split('.')
253
+ if len(triparray) == 7:
254
+ trip_id_wild = triparray[0] + '.' + triparray[1] + '.' + triparray[2] + '.+.' + triparray[4] + '.' + triparray[5] + '.' + triparray[6]
255
+ else:
256
+ # Hmm, it's not the right length (this happens rarely) - give up
257
+ bFindLocation = False
258
+ else:
259
+ trip_id_wild = realtimetripid
260
+
261
+ if bFindLocation:
262
+ reg = re.compile(trip_id_wild)
263
+
264
+ for entity in feed.entity:
265
+ if bool(re.match(reg, entity.vehicle.trip.trip_id)):
266
+ latitude = entity.vehicle.position.latitude
267
+ longitude = entity.vehicle.position.longitude
268
+ # We found it, so break out
269
+ break
270
+
271
+ self.info = {
272
+ ATTR_DUE_IN: due,
273
+ ATTR_ORIGIN_STOP_ID : origin_stop_id,
274
+ ATTR_ORIGIN_NAME : origin_name,
275
+ ATTR_DEPARTURE_TIME : origin_departure_time,
276
+ ATTR_DESTINATION_STOP_ID : destination_stop_id,
277
+ ATTR_DESTINATION_NAME : destination_name,
278
+ ATTR_ARRIVAL_TIME : destination_arrival_time,
279
+ ATTR_ORIGIN_TRANSPORT_TYPE : origin_mode,
280
+ ATTR_ORIGIN_TRANSPORT_NAME: origin_mode_name,
281
+ ATTR_ORIGIN_LINE_NAME : origin_line_name,
282
+ ATTR_ORIGIN_LINE_NAME_SHORT : origin_line_name_short,
283
+ ATTR_CHANGES: changes,
284
+ ATTR_OCCUPANCY : occupancy,
285
+ ATTR_REAL_TIME_TRIP_ID : realtimetripid,
286
+ ATTR_LATITUDE : latitude,
287
+ ATTR_LONGITUDE : longitude
288
+ }
289
+
290
+ found_journeys = found_journeys + 1
291
+
292
+ # Add to the return array
293
+ if (found_journeys == journeys_to_return) or (no_valid_journeys == True):
294
+ json_output = json_output + json.dumps(self.info) + ']}'
295
+ json_output='{"journeys_to_return": ' + str(self.journeys_to_return) + ', "journeys_with_data": ' + str(found_journeys) + ', "journeys": [' + json_output
296
+ break
297
+ else:
298
+ json_output = json_output + json.dumps(self.info) + ', '
299
+ current_journey = next_journey
300
+
301
+ return json_output
302
+
303
+
304
+ # def find_first_journey(self, journeys, journeytype, strictness):
305
+ # # Find the first journey that has a leg is of the requested type
306
+ # journey_count = len(journeys)
307
+ # for journey in range (0, journey_count, 1):
308
+ # leg = self.find_first_leg(journeys[journey]['legs'], journeytype, strictness)
309
+ # if leg is not None:
310
+ # return journeys[journey]
311
+ #
312
+ # # Hmm, we didn't find one
313
+ # return None
314
+
315
+
316
+ def find_next_journey(self, journeys, start_journey, journeytype, strict):
317
+ # Find the next journey that has a leg of the requested type
318
+ journey_count = len(journeys)
240
319
 
241
- self.info = {
242
- ATTR_DUE_IN: due,
243
- ATTR_ORIGIN_STOP_ID : origin_stop_id,
244
- ATTR_ORIGIN_NAME : origin_name,
245
- ATTR_DEPARTURE_TIME : origin_departure_time,
246
- ATTR_DESTINATION_STOP_ID : destination_stop_id,
247
- ATTR_DESTINATION_NAME : destination_name,
248
- ATTR_ARRIVAL_TIME : destination_arrival_time,
249
- ATTR_ORIGIN_TRANSPORT_TYPE : origin_mode,
250
- ATTR_ORIGIN_TRANSPORT_NAME: origin_mode_name,
251
- ATTR_ORIGIN_LINE_NAME : origin_line_name,
252
- ATTR_ORIGIN_LINE_NAME_SHORT : origin_line_name_short,
253
- ATTR_CHANGES: changes,
254
- ATTR_OCCUPANCY : occupancy,
255
- ATTR_REAL_TIME_TRIP_ID : realtimetripid,
256
- ATTR_LATITUDE : latitude,
257
- ATTR_LONGITUDE : longitude
258
- }
259
- return json.dumps(self.info)
320
+ # Some basic error checking
321
+ if start_journey > journey_count:
322
+ return None, None
260
323
 
261
- def find_first_journey(self, journeys, journeytype):
262
- # Find the first journey whose first leg is of the requested type
263
- journey_count = len(journeys)
264
- for journey in range (0, journey_count, 1):
265
- leg = self.find_first_leg(journeys[journey]['legs'], journeytype)
324
+ for journey in range (start_journey, journey_count, 1):
325
+ leg = self.find_first_leg(journeys[journey]['legs'], journeytype, strict)
266
326
  if leg is not None:
267
- return journeys[journey]
327
+ return journeys[journey], journey + 1
328
+ else:
329
+ return None, None
268
330
 
269
331
  # Hmm, we didn't find one
270
332
  return None
271
333
 
272
334
 
273
- def find_first_leg(self, legs, legtype):
335
+ def find_first_leg(self, legs, legtype, strict):
274
336
  # Find the first leg of the requested type
275
337
  leg_count = len(legs)
276
338
  for leg in range (0, leg_count, 1):
277
339
  leg_class = legs[leg]['transportation']['product']['class']
278
340
 
279
- # We've got a filter, and the leg type matches it, so return it
341
+ # We've got a filter, and the leg type matches it, so return that leg
280
342
  if legtype != 0 and leg_class == legtype:
281
- return leg
282
-
283
- # We don't have a filter, and this is the first non-walk/cycle leg so return it
343
+ return legs[leg]
344
+
345
+ # We don't have a filter, and this is the first non-walk/cycle leg so return that leg
284
346
  if legtype == 0 and leg_class < 99:
285
- return leg
347
+ return legs[leg]
348
+
349
+ # Exit if we're doing strict filtering and we haven't found that type in the first leg
350
+ if legtype != 0 and strict == True:
351
+ return None
286
352
 
287
353
  # Hmm, we didn't find one
288
354
  return None
289
355
 
290
356
 
291
- def find_last_leg(self, legs, legtype):
357
+ def find_last_leg(self, legs, legtype, strict):
292
358
  # Find the last leg of the requested type
293
359
  leg_count = len(legs)
294
360
  for leg in range (leg_count - 1, -1, -1):
295
361
  leg_class = legs[leg]['transportation']['product']['class']
296
362
 
297
- # We've got a filter, and the leg type matches it, so return it
363
+ # We've got a filter, and the leg type matches it, so return that leg
298
364
  if legtype != 0 and leg_class == legtype:
299
- return leg
300
-
301
- # We don't have a filter, and this is the first non-walk/cycle leg so return it
365
+ return legs[leg]
366
+
367
+ # We don't have a filter, and this is the first non-walk/cycle leg so return that leg
302
368
  if legtype == 0 and leg_class < 99:
303
- return leg
369
+ return legs[leg]
370
+
371
+ # Exit if we're doing strict filtering and we haven't found that type in the first leg
372
+ if legtype != 0 and strict == True:
373
+ return None
304
374
 
305
375
  # Hmm, we didn't find one
306
376
  return None
307
377
 
378
+
308
379
  def find_changes(self, legs, legtype):
309
380
  # Find out how often we have to change
310
381
  changes = 0
@@ -1,7 +0,0 @@
1
- TransportNSW/TransportNSW.py,sha256=AbgpP6PgHqVjB7LhNI9cT3q7O9ySUMnI057k7mmYLyQ,13926
2
- TransportNSW/__init__.py,sha256=O3iuSkUGkkDz4C7IlqvOXJHPJTxYz0q_48-94ESlkdg,86
3
- PyTransportNSWv2-0.3.4.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
4
- PyTransportNSWv2-0.3.4.dist-info/METADATA,sha256=vN1ZaUheTpFBEe_mj1aERCNP3ecrGmPGFCOsn0VizYU,5481
5
- PyTransportNSWv2-0.3.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- PyTransportNSWv2-0.3.4.dist-info/top_level.txt,sha256=C4LQEkr85VJtG9cklBu9IFpSKRaNSADPBTSPeXIYnOw,13
7
- PyTransportNSWv2-0.3.4.dist-info/RECORD,,