PyTransportNSWv2 0.5.5__tar.gz → 0.6.0__tar.gz

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.5.5
3
+ Version: 0.6.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
@@ -24,7 +24,21 @@ Description: # TransportNSWv2
24
24
 
25
25
  ### Parameters
26
26
  ```python
27
- .get_trip(origin_stop_id, destination_stop_id, api_key, [trip_wait_time = 0], [transport_type = 0])
27
+ .get_trip(origin_stop_id, destination_stop_id, api_key, [trip_wait_time = 0], [transport_type = 0], [strict_transport_type = True|False], [raw_output = True|False], [journeys_to_return = 1] )
28
+ ```
29
+
30
+ Transport types:
31
+ ```
32
+ 1: Train
33
+ 2: Metro
34
+ 4: Light rail
35
+ 5: Bus
36
+ 7: Coach
37
+ 9: Ferry
38
+ 11: School bus
39
+ 99: Walk
40
+ 100: Walk
41
+ 107: Cycle
28
42
  ```
29
43
 
30
44
  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.
@@ -62,7 +76,7 @@ Description: # TransportNSWv2
62
76
  * latitude & longitude: The location of the vehicle, if available
63
77
 
64
78
  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.
65
- Also note that the 'transport_type' filter, if present, only makes sure that at least one leg of the journey includes that transport type.
79
+ Also note that the 'transport_type' filter, if present, only makes sure that at least one leg of the journey includes that transport type unless 'strict_transport_type' is True, in which case the first leg MUST be of the requested type to be returned.
66
80
 
67
81
  ## Thank you
68
82
  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!
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyTransportNSWv2
3
- Version: 0.5.5
3
+ Version: 0.6.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
@@ -24,7 +24,21 @@ Description: # TransportNSWv2
24
24
 
25
25
  ### Parameters
26
26
  ```python
27
- .get_trip(origin_stop_id, destination_stop_id, api_key, [trip_wait_time = 0], [transport_type = 0])
27
+ .get_trip(origin_stop_id, destination_stop_id, api_key, [trip_wait_time = 0], [transport_type = 0], [strict_transport_type = True|False], [raw_output = True|False], [journeys_to_return = 1] )
28
+ ```
29
+
30
+ Transport types:
31
+ ```
32
+ 1: Train
33
+ 2: Metro
34
+ 4: Light rail
35
+ 5: Bus
36
+ 7: Coach
37
+ 9: Ferry
38
+ 11: School bus
39
+ 99: Walk
40
+ 100: Walk
41
+ 107: Cycle
28
42
  ```
29
43
 
30
44
  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.
@@ -62,7 +76,7 @@ Description: # TransportNSWv2
62
76
  * latitude & longitude: The location of the vehicle, if available
63
77
 
64
78
  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.
65
- Also note that the 'transport_type' filter, if present, only makes sure that at least one leg of the journey includes that transport type.
79
+ Also note that the 'transport_type' filter, if present, only makes sure that at least one leg of the journey includes that transport type unless 'strict_transport_type' is True, in which case the first leg MUST be of the requested type to be returned.
66
80
 
67
81
  ## Thank you
68
82
  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!
@@ -17,7 +17,21 @@ The source API details can be found here: https://opendata.transport.nsw.gov.au/
17
17
 
18
18
  ### Parameters
19
19
  ```python
20
- .get_trip(origin_stop_id, destination_stop_id, api_key, [trip_wait_time = 0], [transport_type = 0])
20
+ .get_trip(origin_stop_id, destination_stop_id, api_key, [trip_wait_time = 0], [transport_type = 0], [strict_transport_type = True|False], [raw_output = True|False], [journeys_to_return = 1] )
21
+ ```
22
+
23
+ Transport types:
24
+ ```
25
+ 1: Train
26
+ 2: Metro
27
+ 4: Light rail
28
+ 5: Bus
29
+ 7: Coach
30
+ 9: Ferry
31
+ 11: School bus
32
+ 99: Walk
33
+ 100: Walk
34
+ 107: Cycle
21
35
  ```
22
36
 
23
37
  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.
@@ -55,7 +69,7 @@ Fun fact: TransportNSW's raw API output calls itself JSON, but it uses single q
55
69
  * latitude & longitude: The location of the vehicle, if available
56
70
 
57
71
  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.
58
- Also note that the 'transport_type' filter, if present, only makes sure that at least one leg of the journey includes that transport type.
72
+ Also note that the 'transport_type' filter, if present, only makes sure that at least one leg of the journey includes that transport type unless 'strict_transport_type' is True, in which case the first leg MUST be of the requested type to be returned.
59
73
 
60
74
  ## Thank you
61
75
  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!
@@ -154,7 +154,9 @@ class TransportNSWv2(object):
154
154
  else:
155
155
  legs = journey['legs']
156
156
  first_leg = self.find_first_leg(legs, transport_type, strict_transport_type)
157
- last_leg = self.find_last_leg(legs, transport_type, strict_transport_type)
157
+
158
+ #Executive decision - don't be strict on the last leg, there's often some walking (transport type 100) involved.
159
+ last_leg = self.find_last_leg(legs, transport_type, False)
158
160
  changes = self.find_changes(legs, transport_type)
159
161
 
160
162
  origin = first_leg['origin']
@@ -176,8 +178,8 @@ class TransportNSWv2(object):
176
178
  destination_arrival_time = destination['arrivalTimeEstimated']
177
179
 
178
180
  # Origin type info - train, bus, etc
179
- origin_mode_temp = transportation['product']['class']
180
- origin_mode = self.get_mode(origin_mode_temp)
181
+ #origin_mode_temp = transportation['product']['class']
182
+ origin_mode = self.get_mode(transportation['product']['class'])
181
183
  origin_mode_name = transportation['product']['name']
182
184
 
183
185
  # RealTimeTripID info so we can try and get the current location later
@@ -207,79 +209,75 @@ class TransportNSWv2(object):
207
209
  longitude = 'n/a'
208
210
 
209
211
  if realtimetripid != 'n/a':
210
- # Build the URL
211
- url = \
212
- 'https://api.transport.nsw.gov.au/v1/gtfs/vehiclepos' \
213
- + self.get_url(origin_mode)
214
- auth = 'apikey ' + self.api_key
215
- header = {'Authorization': auth}
216
-
217
- response = requests.get(url, headers=header, timeout=10)
218
- # Only try and process the results if we got a good return code
219
- if response.status_code == 200:
220
- # Search the feed and see if we can find the trip_id
221
- # If we do, capture the latitude and longitude
222
- feed = gtfs_realtime_pb2.FeedMessage()
223
- feed.ParseFromString(response.content)
224
-
225
- # Unfortunately we need to do some mucking about for train-based trip_ids
226
- # Define the appropriate regular expression to search for - usually just the full text
227
- bFindLocation = True
228
-
229
- if origin_mode == 'Train':
230
- triparray = realtimetripid.split('.')
231
- if len(triparray) == 7:
232
- trip_id_wild = triparray[0] + '.' + triparray[1] + '.' + triparray[2] + '.+.' + triparray[4] + '.' + triparray[5] + '.' + triparray[6]
233
- else:
234
- # Hmm, it's not the right length (this happens rarely) - give up
235
- bFindLocation = False
236
- else:
237
- trip_id_wild = realtimetripid
238
-
239
- if bFindLocation:
240
- reg = re.compile(trip_id_wild)
212
+ # Build the URL(s) - some modes have multiple GTFS sources, unforunately
213
+ url_path = self.get_url(origin_mode)
214
+ url_list = self.get_url_path(origin_mode)
215
+ bFoundTripID = False
216
+
217
+ for mode_url in url_list:
218
+ url = url_path + mode_url
219
+ auth = 'apikey ' + self.api_key
220
+ header = {'Authorization': auth}
221
+
222
+ response = requests.get(url, headers=header, timeout=10)
223
+
224
+ # Only try and process the results if we got a good return code
225
+ if response.status_code == 200:
226
+ # Search the feed and see if we can match realtimetripid to trip_id
227
+ # If we do, capture the latitude and longitude
228
+ feed = gtfs_realtime_pb2.FeedMessage()
229
+ feed.ParseFromString(response.content)
230
+
231
+ reg = re.compile(realtimetripid)
241
232
 
242
233
  for entity in feed.entity:
243
234
  if bool(re.match(reg, entity.vehicle.trip.trip_id)):
244
235
  latitude = entity.vehicle.position.latitude
245
236
  longitude = entity.vehicle.position.longitude
246
- # We found it, so break out
237
+
238
+ # We found it, so flag it and break out
239
+ bFoundTripID = True
247
240
  break
248
241
 
249
- self.info = {
250
- ATTR_DUE_IN: due,
251
- ATTR_ORIGIN_STOP_ID : origin_stop_id,
252
- ATTR_ORIGIN_NAME : origin_name,
253
- ATTR_DEPARTURE_TIME : origin_departure_time,
254
- ATTR_DESTINATION_STOP_ID : destination_stop_id,
255
- ATTR_DESTINATION_NAME : destination_name,
256
- ATTR_ARRIVAL_TIME : destination_arrival_time,
257
- ATTR_ORIGIN_TRANSPORT_TYPE : origin_mode,
258
- ATTR_ORIGIN_TRANSPORT_NAME: origin_mode_name,
259
- ATTR_ORIGIN_LINE_NAME : origin_line_name,
260
- ATTR_ORIGIN_LINE_NAME_SHORT : origin_line_name_short,
261
- ATTR_CHANGES: changes,
262
- ATTR_OCCUPANCY : occupancy,
263
- ATTR_REAL_TIME_TRIP_ID : realtimetripid,
264
- ATTR_LATITUDE : latitude,
265
- ATTR_LONGITUDE : longitude
266
- }
267
-
268
- found_journeys = found_journeys + 1
269
-
270
- # Add to the return array
271
- if (no_valid_journeys == True):
272
- break
273
-
274
- if (found_journeys >= 2):
275
- json_output = json_output + ',' + json.dumps(self.info)
276
- else:
277
- json_output = json_output + json.dumps(self.info)
278
-
279
- if (found_journeys == journeys_to_return):
280
- break
281
-
282
- current_journey_index = next_journey_index
242
+ if bFoundTripID == True:
243
+ # No need to look any further
244
+ break
245
+
246
+
247
+ self.info = {
248
+ ATTR_DUE_IN: due,
249
+ ATTR_ORIGIN_STOP_ID : origin_stop_id,
250
+ ATTR_ORIGIN_NAME : origin_name,
251
+ ATTR_DEPARTURE_TIME : origin_departure_time,
252
+ ATTR_DESTINATION_STOP_ID : destination_stop_id,
253
+ ATTR_DESTINATION_NAME : destination_name,
254
+ ATTR_ARRIVAL_TIME : destination_arrival_time,
255
+ ATTR_ORIGIN_TRANSPORT_TYPE : origin_mode,
256
+ ATTR_ORIGIN_TRANSPORT_NAME: origin_mode_name,
257
+ ATTR_ORIGIN_LINE_NAME : origin_line_name,
258
+ ATTR_ORIGIN_LINE_NAME_SHORT : origin_line_name_short,
259
+ ATTR_CHANGES: changes,
260
+ ATTR_OCCUPANCY : occupancy,
261
+ ATTR_REAL_TIME_TRIP_ID : realtimetripid,
262
+ ATTR_LATITUDE : latitude,
263
+ ATTR_LONGITUDE : longitude
264
+ }
265
+
266
+ found_journeys = found_journeys + 1
267
+
268
+ # Add to the return array
269
+ if (no_valid_journeys == True):
270
+ break
271
+
272
+ if (found_journeys >= 2):
273
+ json_output = json_output + ',' + json.dumps(self.info)
274
+ else:
275
+ json_output = json_output + json.dumps(self.info)
276
+
277
+ if (found_journeys == journeys_to_return):
278
+ break
279
+
280
+ current_journey_index = next_journey_index
283
281
 
284
282
  json_output='{"journeys_to_return": ' + str(self.journeys_to_return) + ', "journeys_with_data": ' + str(found_journeys) + ', "journeys": [' + json_output + ']}'
285
283
  return json_output
@@ -376,6 +374,7 @@ class TransportNSWv2(object):
376
374
  """Map the iconId to a full text string"""
377
375
  modes = {
378
376
  1: "Train",
377
+ 2: "Metro",
379
378
  4: "Light rail",
380
379
  5: "Bus",
381
380
  7: "Coach",
@@ -387,17 +386,35 @@ class TransportNSWv2(object):
387
386
  }
388
387
  return modes.get(iconId, None)
389
388
 
390
-
391
389
  def get_url(self, mode):
392
- """Map the journey mode to the proper real time location URL """
390
+ """Map the journey mode to the proper base real time location URL """
391
+ v1_url = "https://api.transport.nsw.gov.au/v1/gtfs/vehiclepos"
392
+ v2_url = "https://api.transport.nsw.gov.au/v2/gtfs/vehiclepos"
393
+
394
+ url_options = {
395
+ "Train": v2_url,
396
+ "Metro": v2_url,
397
+ "Light rail": v1_url,
398
+ "Bus": v1_url,
399
+ "Coach": v1_url,
400
+ "Ferry": v1_url,
401
+ "School bus": v1_url
402
+ }
403
+ return url_options.get(mode, None)
404
+
405
+
406
+ def get_url_path(self, mode):
407
+ """Map the journey mode to the proper modifier URL """
408
+ bus_list = ["/buses", "/regionbuses/centralwestandorana", "/regionbuses/centralwestandorana2", "/regionbuses/newenglandnorthwest", "/regionbuses/northcoast", "/regionbuses/northcoast2", "/regionbuses/northcoast3", "/regionbuses/riverinamurray", "/regionbuses/riverinamurray2", "/regionbuses/southeasttablelands", "/regionbuses/southeasttablelands2", "/regionbuses/sydneysurrounds", "/regionbuses/newcastlehunter", "/regionbuses/farwest"]
393
409
 
394
410
  url_options = {
395
- "Train" : "/sydneytrains",
396
- "Light rail" : "/lightrail/innerwest",
397
- "Bus" : "/buses",
398
- "Coach" : "/buses",
399
- "Ferry" : "/ferries/sydneyferries",
400
- "School bus" : "/buses"
411
+ "Train" : ["/sydneytrains"],
412
+ "Metro" : ["/metro"],
413
+ "Light rail" : ["/lightrail/innerwest", "/lightrail/cbdandsoutheast", "/lightrail/newcastle"],
414
+ "Bus" : bus_list,
415
+ "Coach" : bus_list,
416
+ "Ferry" : ["/ferries/sydneyferries"],
417
+ "School bus" : bus_list
401
418
  }
402
419
  return url_options.get(mode, None)
403
420
 
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="PyTransportNSWv2",
8
- version="0.5.5",
8
+ version="0.6.0",
9
9
  author="andystewart999",
10
10
  description="Get detailed per-trip transport information from TransportNSW",
11
11
  long_description=long_description,