PyTransportNSWv2 0.5.6__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.6
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.6
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!
@@ -178,8 +178,8 @@ class TransportNSWv2(object):
178
178
  destination_arrival_time = destination['arrivalTimeEstimated']
179
179
 
180
180
  # Origin type info - train, bus, etc
181
- origin_mode_temp = transportation['product']['class']
182
- origin_mode = self.get_mode(origin_mode_temp)
181
+ #origin_mode_temp = transportation['product']['class']
182
+ origin_mode = self.get_mode(transportation['product']['class'])
183
183
  origin_mode_name = transportation['product']['name']
184
184
 
185
185
  # RealTimeTripID info so we can try and get the current location later
@@ -209,79 +209,75 @@ class TransportNSWv2(object):
209
209
  longitude = 'n/a'
210
210
 
211
211
  if realtimetripid != 'n/a':
212
- # Build the URL
213
- url = \
214
- 'https://api.transport.nsw.gov.au/v1/gtfs/vehiclepos' \
215
- + self.get_url(origin_mode)
216
- auth = 'apikey ' + self.api_key
217
- header = {'Authorization': auth}
218
-
219
- response = requests.get(url, headers=header, timeout=10)
220
- # Only try and process the results if we got a good return code
221
- if response.status_code == 200:
222
- # Search the feed and see if we can find the trip_id
223
- # If we do, capture the latitude and longitude
224
- feed = gtfs_realtime_pb2.FeedMessage()
225
- feed.ParseFromString(response.content)
226
-
227
- # Unfortunately we need to do some mucking about for train-based trip_ids
228
- # Define the appropriate regular expression to search for - usually just the full text
229
- bFindLocation = True
230
-
231
- if origin_mode == 'Train':
232
- triparray = realtimetripid.split('.')
233
- if len(triparray) == 7:
234
- trip_id_wild = triparray[0] + '.' + triparray[1] + '.' + triparray[2] + '.+.' + triparray[4] + '.' + triparray[5] + '.' + triparray[6]
235
- else:
236
- # Hmm, it's not the right length (this happens rarely) - give up
237
- bFindLocation = False
238
- else:
239
- trip_id_wild = realtimetripid
240
-
241
- if bFindLocation:
242
- 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)
243
232
 
244
233
  for entity in feed.entity:
245
234
  if bool(re.match(reg, entity.vehicle.trip.trip_id)):
246
235
  latitude = entity.vehicle.position.latitude
247
236
  longitude = entity.vehicle.position.longitude
248
- # We found it, so break out
237
+
238
+ # We found it, so flag it and break out
239
+ bFoundTripID = True
249
240
  break
250
241
 
251
- self.info = {
252
- ATTR_DUE_IN: due,
253
- ATTR_ORIGIN_STOP_ID : origin_stop_id,
254
- ATTR_ORIGIN_NAME : origin_name,
255
- ATTR_DEPARTURE_TIME : origin_departure_time,
256
- ATTR_DESTINATION_STOP_ID : destination_stop_id,
257
- ATTR_DESTINATION_NAME : destination_name,
258
- ATTR_ARRIVAL_TIME : destination_arrival_time,
259
- ATTR_ORIGIN_TRANSPORT_TYPE : origin_mode,
260
- ATTR_ORIGIN_TRANSPORT_NAME: origin_mode_name,
261
- ATTR_ORIGIN_LINE_NAME : origin_line_name,
262
- ATTR_ORIGIN_LINE_NAME_SHORT : origin_line_name_short,
263
- ATTR_CHANGES: changes,
264
- ATTR_OCCUPANCY : occupancy,
265
- ATTR_REAL_TIME_TRIP_ID : realtimetripid,
266
- ATTR_LATITUDE : latitude,
267
- ATTR_LONGITUDE : longitude
268
- }
269
-
270
- found_journeys = found_journeys + 1
271
-
272
- # Add to the return array
273
- if (no_valid_journeys == True):
274
- break
275
-
276
- if (found_journeys >= 2):
277
- json_output = json_output + ',' + json.dumps(self.info)
278
- else:
279
- json_output = json_output + json.dumps(self.info)
280
-
281
- if (found_journeys == journeys_to_return):
282
- break
283
-
284
- 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
285
281
 
286
282
  json_output='{"journeys_to_return": ' + str(self.journeys_to_return) + ', "journeys_with_data": ' + str(found_journeys) + ', "journeys": [' + json_output + ']}'
287
283
  return json_output
@@ -378,6 +374,7 @@ class TransportNSWv2(object):
378
374
  """Map the iconId to a full text string"""
379
375
  modes = {
380
376
  1: "Train",
377
+ 2: "Metro",
381
378
  4: "Light rail",
382
379
  5: "Bus",
383
380
  7: "Coach",
@@ -389,17 +386,35 @@ class TransportNSWv2(object):
389
386
  }
390
387
  return modes.get(iconId, None)
391
388
 
392
-
393
389
  def get_url(self, mode):
394
- """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"]
395
409
 
396
410
  url_options = {
397
- "Train" : "/sydneytrains",
398
- "Light rail" : "/lightrail/innerwest",
399
- "Bus" : "/buses",
400
- "Coach" : "/buses",
401
- "Ferry" : "/ferries/sydneyferries",
402
- "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
403
418
  }
404
419
  return url_options.get(mode, None)
405
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.6",
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,