42Cummer commited on
Commit
170a431
·
verified ·
1 Parent(s): 26991c8

Update app.py

Browse files

add vehicle destinations

Files changed (1) hide show
  1. app.py +62 -43
app.py CHANGED
@@ -19,21 +19,7 @@ reader = easyocr.Reader(
19
  user_network_directory='/tmp/.EasyOCR' # ✅ Also tell it where user models are
20
  )
21
 
22
- def get_trip_info(trip_id):
23
- try:
24
- with open('trips.txt', 'r') as f:
25
- for line in f:
26
- if trip_id in line:
27
- # Split the line by commas and get the route information
28
- parts = line.strip().split(',')
29
- if len(parts) >= 2:
30
- return parts[3].strip() # third part
31
- except Exception as e:
32
- print(f"Error reading trips.txt: {e}")
33
- return None
34
-
35
  def get_vehicle_locations_and_occupancy(vehicle_numbers):
36
- print("DEBUG: Called get_vehicle_locations_and_occupancy with vehicle_numbers:", vehicle_numbers)
37
  url = "https://bustime.ttc.ca/gtfsrt/vehicles?debug"
38
  headers = {
39
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
@@ -45,59 +31,82 @@ def get_vehicle_locations_and_occupancy(vehicle_numbers):
45
  'Upgrade-Insecure-Requests': '1'
46
  }
47
  try:
48
- print("DEBUG: Sending GET request to", url)
49
  response = requests.get(url, headers=headers, timeout=10)
50
- print("DEBUG: Response status code:", response.status_code)
51
  response.raise_for_status()
52
  except Exception as e:
53
- print("ERROR: Exception during requests.get:", e)
54
  return jsonify({"error": f"Failed to fetch vehicle data: {e}"}), 500
55
 
56
  text = response.text
57
- print("DEBUG: Length of response text:", len(text))
58
- if len(text) < 1000:
59
- print("DEBUG: Response text (first 500 chars):", text[:500])
60
-
61
  entities = text.split('entity {')[1:] # skip the header
62
- print("DEBUG: Number of entities found:", len(entities))
63
 
64
  # Ensure vehicle_numbers are strings for comparison
65
  vehicle_numbers = set(str(num) for num in vehicle_numbers)
66
- print("DEBUG: vehicle_numbers as strings:", vehicle_numbers)
67
 
68
  results = []
69
- for idx, entity in enumerate(entities):
70
  vehicle_id_matches = re.findall(r'vehicle\s*\{\s*id: "(\d+)"', entity)
71
  if not vehicle_id_matches:
72
- print(f"DEBUG: No vehicle id found in entity {idx}")
73
  continue
74
  vehicle_id = vehicle_id_matches[-1]
75
  if vehicle_id not in vehicle_numbers:
76
- print(f"DEBUG: vehicle_id {vehicle_id} not in requested vehicle_numbers")
77
  continue
78
 
79
  lat_match = re.search(r'latitude: (-?[\d\.]+)', entity)
80
  lon_match = re.search(r'longitude: (-?[\d\.]+)', entity)
81
  occ_match = re.search(r'occupancy_status: ([A-Z_]+)', entity)
82
- trip_id_match = re.search(r'trip_id: "(\d+)"', entity)
83
-
84
- print(f"DEBUG: vehicle_id={vehicle_id}, lat={lat_match.group(1) if lat_match else None}, lon={lon_match.group(1) if lon_match else None}, occ={occ_match.group(1) if occ_match else None}")
85
-
86
- trip_id = trip_id_match.group(1) if trip_id_match else None
87
- route_info = get_trip_info(trip_id) if trip_id else None
88
 
89
  results.append({
90
  'vehicle_id': vehicle_id,
91
  'latitude': float(lat_match.group(1)) if lat_match else None,
92
  'longitude': float(lon_match.group(1)) if lon_match else None,
93
- 'occupancy_status': occ_match.group(1) if occ_match else None,
94
- #'trip_id': trip_id, # not needed
95
- 'route_info': route_info
96
  })
97
-
98
- print("DEBUG: Final results to return:", results)
99
  return results
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  @app.route('/', methods=['GET'])
102
  def health_check():
103
  return 'Backend is running!', 200
@@ -235,14 +244,24 @@ def vehicle_status():
235
  vehicle_numbers = data.get('vehicle_numbers')
236
  if not vehicle_numbers or not isinstance(vehicle_numbers, list):
237
  return jsonify({'error': 'vehicle_numbers must be a list'}), 400
238
-
239
  info = get_vehicle_locations_and_occupancy(vehicle_numbers)
240
  return jsonify({'vehicles': info})
241
 
242
- #@app.route('/test_vehicle', methods=['GET'])
243
- #def test_vehicle():
244
- # info = get_vehicle_locations_and_occupancy(['3433', '1676'])
245
- # return info
 
 
 
 
 
 
 
 
 
 
 
246
 
247
  if __name__ == '__main__':
248
- app.run(debug=True, port=5000)
 
19
  user_network_directory='/tmp/.EasyOCR' # ✅ Also tell it where user models are
20
  )
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def get_vehicle_locations_and_occupancy(vehicle_numbers):
 
23
  url = "https://bustime.ttc.ca/gtfsrt/vehicles?debug"
24
  headers = {
25
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
 
31
  'Upgrade-Insecure-Requests': '1'
32
  }
33
  try:
 
34
  response = requests.get(url, headers=headers, timeout=10)
 
35
  response.raise_for_status()
36
  except Exception as e:
 
37
  return jsonify({"error": f"Failed to fetch vehicle data: {e}"}), 500
38
 
39
  text = response.text
 
 
 
 
40
  entities = text.split('entity {')[1:] # skip the header
 
41
 
42
  # Ensure vehicle_numbers are strings for comparison
43
  vehicle_numbers = set(str(num) for num in vehicle_numbers)
 
44
 
45
  results = []
46
+ for entity in entities:
47
  vehicle_id_matches = re.findall(r'vehicle\s*\{\s*id: "(\d+)"', entity)
48
  if not vehicle_id_matches:
 
49
  continue
50
  vehicle_id = vehicle_id_matches[-1]
51
  if vehicle_id not in vehicle_numbers:
 
52
  continue
53
 
54
  lat_match = re.search(r'latitude: (-?[\d\.]+)', entity)
55
  lon_match = re.search(r'longitude: (-?[\d\.]+)', entity)
56
  occ_match = re.search(r'occupancy_status: ([A-Z_]+)', entity)
 
 
 
 
 
 
57
 
58
  results.append({
59
  'vehicle_id': vehicle_id,
60
  'latitude': float(lat_match.group(1)) if lat_match else None,
61
  'longitude': float(lon_match.group(1)) if lon_match else None,
62
+ 'occupancy_status': occ_match.group(1) if occ_match else None
 
 
63
  })
 
 
64
  return results
65
 
66
+ def get_vehicle_destinations(vehicle_numbers):
67
+ # Join vehicle numbers with %2C (URL encoded comma)
68
+ vehicle_query = '%2C'.join(vehicle_numbers)
69
+ url = f"https://www.transsee.ca/fleetfind?a=ttc&findtrack=1&q={vehicle_query}&Go=Go"
70
+ headers = {
71
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
72
+ 'Referer': 'https://www.transsee.ca/',
73
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
74
+ 'Accept-Language': 'en-US,en;q=0.9',
75
+ 'DNT': '1', # Do Not Track
76
+ 'Connection': 'keep-alive',
77
+ 'Upgrade-Insecure-Requests': '1'
78
+ }
79
+ try:
80
+ response = requests.get(url, headers=headers, timeout=10)
81
+ response.raise_for_status()
82
+ except Exception as e:
83
+ return jsonify({"error": f"Failed to fetch vehicle data: {e}"}), 500
84
+
85
+ soup = BeautifulSoup(response.text, 'html.parser')
86
+ vehicle_info = {}
87
+ for vid in vehicle_numbers:
88
+ p_tag = soup.find('p', id=f'{vid}')
89
+ if p_tag:
90
+ # Remove the span with class 'tsfont'
91
+ for span in p_tag.find_all('span', class_='tsfont'):
92
+ span.decompose() # no arrows please
93
+ text = p_tag.get_text(" ", strip=True)
94
+ # Extract the destination string starting with 'going' up to
95
+ # ' at ', ' aprchg', ' past', or end of string
96
+ match = re.search(r'(going.*?)(?= at | aprchg| past|$)', text)
97
+ if match:
98
+ destination = match.group(1).strip()
99
+ # Remove direction words (case-insensitive, as whole words)
100
+ destination = re.sub(r'\b(going|North|South|East|West)\b', '', destination, flags=re.IGNORECASE)
101
+ # Remove any extra spaces left behind
102
+ destination = re.sub(r'\s+', ' ', destination).strip()
103
+ else:
104
+ destination = None
105
+ vehicle_info[vid] = destination
106
+
107
+ # Now vehicle_info is a dict mapping vehicle IDs to their info
108
+ return jsonify(vehicle_info)
109
+
110
  @app.route('/', methods=['GET'])
111
  def health_check():
112
  return 'Backend is running!', 200
 
244
  vehicle_numbers = data.get('vehicle_numbers')
245
  if not vehicle_numbers or not isinstance(vehicle_numbers, list):
246
  return jsonify({'error': 'vehicle_numbers must be a list'}), 400
 
247
  info = get_vehicle_locations_and_occupancy(vehicle_numbers)
248
  return jsonify({'vehicles': info})
249
 
250
+ @app.route('/destinations', methods=['POST'])
251
+ def destinations():
252
+ if not request.is_json:
253
+ return jsonify({'error': 'Request must be JSON'}), 400
254
+ data = request.get_json()
255
+ vehicle_numbers = data.get('vehicle_numbers')
256
+ if not vehicle_numbers or not isinstance(vehicle_numbers, list):
257
+ return jsonify({'error': 'vehicle_numbers must be a list'}), 400
258
+ info = get_vehicle_destinations(vehicle_numbers)
259
+ return jsonify({'vehicles': info})
260
+
261
+ #@app.route('/test_destinations')
262
+ #def test_destinations():
263
+ # return get_vehicle_destinations(['1220', '3640', '9051'])
264
+
265
 
266
  if __name__ == '__main__':
267
+ app.run(debug=True, port=5000)