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.
- {PyTransportNSWv2-0.3.4.dist-info → PyTransportNSWv2-0.4.0.dist-info}/METADATA +34 -6
- PyTransportNSWv2-0.4.0.dist-info/RECORD +7 -0
- TransportNSW/TransportNSW.py +238 -167
- PyTransportNSWv2-0.3.4.dist-info/RECORD +0 -7
- {PyTransportNSWv2-0.3.4.dist-info → PyTransportNSWv2-0.4.0.dist-info}/LICENSE +0 -0
- {PyTransportNSWv2-0.3.4.dist-info → PyTransportNSWv2-0.4.0.dist-info}/WHEEL +0 -0
- {PyTransportNSWv2-0.3.4.dist-info → PyTransportNSWv2-0.4.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: PyTransportNSWv2
|
3
|
-
Version: 0.
|
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, [
|
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
|
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
|
-
|
66
|
-
|
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,,
|
TransportNSW/TransportNSW.py
CHANGED
@@ -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.
|
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,
|
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.
|
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 '
|
81
|
-
now_plus_wait = datetime.now() + timedelta(minutes =
|
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
|
86
|
-
|
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=' +
|
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
|
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
|
129
|
-
# Just
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
'
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
if
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
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
|
-
|
242
|
-
|
243
|
-
|
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
|
-
|
262
|
-
|
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
|
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
|
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
|
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
|
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,,
|
File without changes
|
File without changes
|
File without changes
|