Jacobmadwed commited on
Commit
35bea37
·
verified ·
1 Parent(s): f4d4c5e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +100 -116
app.py CHANGED
@@ -1,48 +1,43 @@
1
- from flask import Flask, jsonify, request
2
- from flask_cors import CORS
3
  import logging
4
  import json
5
  import base64
6
  import uuid
7
  import os
8
  from datetime import datetime
 
9
  from threading import Thread
10
  import time
 
11
 
12
  app = Flask(__name__)
13
  CORS(app) # This will enable CORS for all routes
14
 
 
 
 
15
 
 
 
 
 
16
 
17
- TRACKING_FILE = 'trackings.json'
18
-
19
  def initialize_tracking_file():
20
  if not os.path.exists(TRACKING_FILE):
21
  with open(TRACKING_FILE, 'w') as f:
22
  json.dump({}, f)
23
 
24
- # Call this function when your app starts
25
  initialize_tracking_file()
26
 
27
  # Configure logging
28
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
29
  logger = logging.getLogger(__name__)
30
 
31
- app = Flask(__name__)
32
-
33
- UPS_CLIENT_ID = 'LKrZBgcSZ2v7vtAn3VAmEEBXqpkXD8zIEcZum97Eb8sSl7Fx'
34
- UPS_CLIENT_SECRET = 'DBAV77mzTWgI5oqWwXlA12hi62hgyUkesoGsREZsmjd1WHMSugpDUuBGTjyUiteT'
35
- FEDEX_API_KEY = 'l705da56bf34254c3495f351772a6ea2d3'
36
- FEDEX_SECRET_KEY = 'ae27688af74341f094228fc67a36a8cc'
37
-
38
- TRACKING_FILE = 'trackings.json'
39
- UPDATE_INTERVAL = 60 * 10 # 10 minute
40
-
41
  def get_fedex_access_token():
42
  url = "https://apis.fedex.com/oauth/token"
43
- headers = {
44
- 'Content-Type': "application/x-www-form-urlencoded"
45
- }
46
  payload = {
47
  'grant_type': 'client_credentials',
48
  'client_id': FEDEX_API_KEY,
@@ -76,9 +71,7 @@ def get_ups_access_token():
76
  credentials = base64.b64encode(f"{UPS_CLIENT_ID}:{UPS_CLIENT_SECRET}".encode()).decode()
77
  headers['Authorization'] = f'Basic {credentials}'
78
 
79
- data = {
80
- 'grant_type': 'client_credentials'
81
- }
82
 
83
  try:
84
  logger.info("Requesting UPS token")
@@ -92,73 +85,7 @@ def get_ups_access_token():
92
  logger.error(f"Response content: {e.response.text}")
93
  raise
94
 
95
- def fetch_ups_tracking_info(tracking_number):
96
- access_token = get_ups_access_token()
97
- url = f"https://onlinetools.ups.com/api/track/v1/details/{tracking_number}"
98
- headers = {
99
- 'Authorization': f'Bearer {access_token}',
100
- 'Content-Type': 'application/json',
101
- 'Accept': 'application/json',
102
- 'User-Agent': 'OCMTrackingApp/1.0',
103
- 'transId': str(uuid.uuid4()),
104
- 'transactionSrc': 'OCMTrackingApp'
105
- }
106
- params = {
107
- "locale": "en_US",
108
- "returnSignature": "false",
109
- "returnMilestones": "false",
110
- "returnPOD": "false"
111
- }
112
- try:
113
- logger.info(f"Requesting UPS tracking info for {tracking_number}")
114
- response = requests.get(url, headers=headers, params=params)
115
- response.raise_for_status()
116
- data = response.json()
117
-
118
- shipment = data['trackResponse']['shipment'][0]
119
- package = shipment['package'][0]
120
- events = package.get('activity', [])
121
-
122
- if events:
123
- sorted_events = sorted(events, key=lambda x: x['date'] + x['time'], reverse=True)
124
- latest_event = sorted_events[0]
125
- else:
126
- latest_event = None
127
-
128
- def format_date(date_str, time_str):
129
- if not date_str or not time_str or date_str == 'N/A' or time_str == 'N/A':
130
- return 'N/A'
131
- try:
132
- date = datetime.strptime(date_str + time_str, '%Y%m%d%H%M%S')
133
- return date.strftime('%m/%d/%Y %I:%M %p')
134
- except ValueError:
135
- logger.warning(f"Unable to parse date: {date_str} or time: {time_str}")
136
- return 'N/A'
137
-
138
- delivery_date = 'N/A'
139
- delivery_time = 'N/A'
140
- if 'deliveryDate' in package:
141
- if isinstance(package['deliveryDate'], list) and package['deliveryDate']:
142
- delivery_date = package['deliveryDate'][0].get('date', 'N/A')
143
- elif isinstance(package['deliveryDate'], dict):
144
- delivery_date = package['deliveryDate'].get('date', 'N/A')
145
- if 'deliveryTime' in package:
146
- delivery_time = package['deliveryTime'].get('endTime', 'N/A')
147
-
148
- return {
149
- 'status': latest_event['status']['type'] if latest_event else 'N/A',
150
- 'courier': 'UPS',
151
- 'estimatedDelivery': format_date(delivery_date, delivery_time),
152
- 'latestLocation': latest_event['location']['address'].get('city', 'N/A') if latest_event else 'N/A',
153
- 'latestCheckpoint': latest_event['status']['description'] if latest_event else 'N/A',
154
- 'lastUpdateDateTime': format_date(latest_event['date'], latest_event['time']) if latest_event else 'N/A',
155
- }
156
- except requests.exceptions.RequestException as e:
157
- logger.error(f"Error fetching UPS tracking info: {e}")
158
- if hasattr(e, 'response'):
159
- logger.error(f"Response content: {e.response.text}")
160
- raise
161
-
162
  def fetch_fedex_tracking_info(tracking_number):
163
  access_token = get_fedex_access_token()
164
  url = "https://apis.fedex.com/track/v1/trackingnumbers"
@@ -169,11 +96,7 @@ def fetch_fedex_tracking_info(tracking_number):
169
  }
170
  payload = {
171
  "trackingInfo": [
172
- {
173
- "trackingNumberInfo": {
174
- "trackingNumber": tracking_number
175
- }
176
- }
177
  ],
178
  "includeDetailedScans": True
179
  }
@@ -209,12 +132,10 @@ def fetch_fedex_tracking_info(tracking_number):
209
  else:
210
  location = 'N/A'
211
 
212
- # Get the latest event time
213
  latest_event_time = format_date(latest_status.get('scanDateTime'))
214
  if latest_event_time == 'N/A' and scan_events:
215
  latest_event_time = format_date(scan_events[0].get('date'))
216
 
217
- # Get delivery time if the package is delivered
218
  delivery_time = 'N/A'
219
  if latest_status.get('statusByLocale') == 'Delivered':
220
  for date_time in track_results.get('dateAndTimes', []):
@@ -222,14 +143,12 @@ def fetch_fedex_tracking_info(tracking_number):
222
  delivery_time = format_date(date_time.get('dateTime'))
223
  break
224
 
225
- # Append reasonDescription to latestCheckpoint if there's a shipment exception
226
  latest_checkpoint = latest_status.get('description', 'N/A')
227
  if latest_status.get('code') == 'SE':
228
  reason_description = latest_status.get('ancillaryDetails', [{}])[0].get('reasonDescription', '')
229
  if reason_description:
230
  latest_checkpoint += f" ({reason_description})"
231
 
232
- # Return the delivery time if available, otherwise return the latest event time
233
  last_update_date_time = delivery_time if delivery_time != 'N/A' else latest_event_time
234
 
235
  return {
@@ -253,6 +172,73 @@ def fetch_fedex_tracking_info(tracking_number):
253
  logger.error(f"Response content: {data}")
254
  raise
255
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  def load_trackings():
257
  try:
258
  if os.path.exists(TRACKING_FILE):
@@ -260,32 +246,30 @@ def load_trackings():
260
  content = file.read().strip()
261
  if content:
262
  trackings = json.loads(content)
263
- print(f"Loaded {len(trackings)} trackings from file")
264
  return trackings
265
  else:
266
- print("Tracking file is empty")
267
  return {}
268
  else:
269
- print(f"Tracking file {TRACKING_FILE} not found")
270
  return {}
271
  except json.JSONDecodeError:
272
- print("Error decoding JSON, file might be corrupted")
273
  return {}
274
  except Exception as e:
275
- print(f"Error loading trackings: {str(e)}")
276
- import traceback
277
- print(traceback.format_exc())
278
  return {}
279
 
280
  def save_trackings(trackings):
281
  try:
282
  with open(TRACKING_FILE, 'w') as file:
283
  json.dump(trackings, file, indent=4)
284
- print(f"Saved {len(trackings)} trackings to file")
285
  except Exception as e:
286
- print(f"Error saving trackings to {TRACKING_FILE}: {str(e)}")
287
- import traceback
288
- print(traceback.format_exc())
289
  raise
290
 
291
  def update_tracking_info():
@@ -329,6 +313,7 @@ def get_ups_tracking():
329
  tracking_info = fetch_ups_tracking_info(tracking_number)
330
  return jsonify(tracking_info), 200
331
  except Exception as e:
 
332
  return jsonify({"status": "error", "message": str(e)}), 500
333
 
334
  @app.route('/fedex', methods=['POST'])
@@ -341,6 +326,7 @@ def get_fedex_tracking():
341
  tracking_info = fetch_fedex_tracking_info(tracking_number)
342
  return jsonify(tracking_info), 200
343
  except Exception as e:
 
344
  return jsonify({"status": "error", "message": str(e)}), 500
345
 
346
  @app.route('/save_tracking', methods=['POST'])
@@ -350,7 +336,7 @@ def save_tracking():
350
  if not tracking_info:
351
  return jsonify({"status": "error", "message": "No data received"}), 400
352
 
353
- print("Received tracking info:", tracking_info) # Debug print
354
 
355
  trackings = load_trackings()
356
  tracking_number = tracking_info['tracking']
@@ -362,22 +348,20 @@ def save_tracking():
362
  trackings[tracking_number] = tracking_info
363
 
364
  save_trackings(trackings)
365
- print(f"Saved tracking: {tracking_number}")
366
  return jsonify({"status": "success", "message": "Tracking saved successfully"}), 200
367
  except Exception as e:
368
- print(f"Error saving tracking: {str(e)}")
369
- import traceback
370
- print(traceback.format_exc())
371
  return jsonify({"status": "error", "message": str(e)}), 500
372
 
373
  @app.route('/load_trackings', methods=['GET'])
374
  def get_trackings():
375
  try:
376
  trackings = load_trackings()
377
- print("Loaded trackings:", trackings)
378
  return jsonify(trackings), 200
379
  except Exception as e:
380
- print(f"Error in get_trackings: {str(e)}")
381
  return jsonify({"status": "error", "message": str(e)}), 500
382
 
383
  if __name__ == '__main__':
@@ -385,4 +369,4 @@ if __name__ == '__main__':
385
  update_thread = Thread(target=update_tracking_info, daemon=True)
386
  update_thread.start()
387
 
388
- app.run(host='0.0.0.0', port=7860)
 
1
+ import requests
 
2
  import logging
3
  import json
4
  import base64
5
  import uuid
6
  import os
7
  from datetime import datetime
8
+ from flask import Flask, jsonify, request
9
  from threading import Thread
10
  import time
11
+ from flask_cors import CORS
12
 
13
  app = Flask(__name__)
14
  CORS(app) # This will enable CORS for all routes
15
 
16
+ # Constants
17
+ TRACKING_FILE = 'https://capitolphotobooths.com/monday/trackings.json' # Update this path to your specific file location
18
+ UPDATE_INTERVAL = 60 * 10 # 10 minutes
19
 
20
+ UPS_CLIENT_ID = 'LKrZBgcSZ2v7vtAn3VAmEEBXqpkXD8zIEcZum97Eb8sSl7Fx'
21
+ UPS_CLIENT_SECRET = 'DBAV77mzTWgI5oqWwXlA12hi62hgyUkesoGsREZsmjd1WHMSugpDUuBGTjyUiteT'
22
+ FEDEX_API_KEY = 'l705da56bf34254c3495f351772a6ea2d3'
23
+ FEDEX_SECRET_KEY = 'ae27688af74341f094228fc67a36a8cc'
24
 
25
+ # Initialize tracking file
 
26
  def initialize_tracking_file():
27
  if not os.path.exists(TRACKING_FILE):
28
  with open(TRACKING_FILE, 'w') as f:
29
  json.dump({}, f)
30
 
 
31
  initialize_tracking_file()
32
 
33
  # Configure logging
34
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
35
  logger = logging.getLogger(__name__)
36
 
37
+ # Functions to get access tokens
 
 
 
 
 
 
 
 
 
38
  def get_fedex_access_token():
39
  url = "https://apis.fedex.com/oauth/token"
40
+ headers = {'Content-Type': "application/x-www-form-urlencoded"}
 
 
41
  payload = {
42
  'grant_type': 'client_credentials',
43
  'client_id': FEDEX_API_KEY,
 
71
  credentials = base64.b64encode(f"{UPS_CLIENT_ID}:{UPS_CLIENT_SECRET}".encode()).decode()
72
  headers['Authorization'] = f'Basic {credentials}'
73
 
74
+ data = {'grant_type': 'client_credentials'}
 
 
75
 
76
  try:
77
  logger.info("Requesting UPS token")
 
85
  logger.error(f"Response content: {e.response.text}")
86
  raise
87
 
88
+ # Functions to fetch tracking info
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  def fetch_fedex_tracking_info(tracking_number):
90
  access_token = get_fedex_access_token()
91
  url = "https://apis.fedex.com/track/v1/trackingnumbers"
 
96
  }
97
  payload = {
98
  "trackingInfo": [
99
+ {"trackingNumberInfo": {"trackingNumber": tracking_number}}
 
 
 
 
100
  ],
101
  "includeDetailedScans": True
102
  }
 
132
  else:
133
  location = 'N/A'
134
 
 
135
  latest_event_time = format_date(latest_status.get('scanDateTime'))
136
  if latest_event_time == 'N/A' and scan_events:
137
  latest_event_time = format_date(scan_events[0].get('date'))
138
 
 
139
  delivery_time = 'N/A'
140
  if latest_status.get('statusByLocale') == 'Delivered':
141
  for date_time in track_results.get('dateAndTimes', []):
 
143
  delivery_time = format_date(date_time.get('dateTime'))
144
  break
145
 
 
146
  latest_checkpoint = latest_status.get('description', 'N/A')
147
  if latest_status.get('code') == 'SE':
148
  reason_description = latest_status.get('ancillaryDetails', [{}])[0].get('reasonDescription', '')
149
  if reason_description:
150
  latest_checkpoint += f" ({reason_description})"
151
 
 
152
  last_update_date_time = delivery_time if delivery_time != 'N/A' else latest_event_time
153
 
154
  return {
 
172
  logger.error(f"Response content: {data}")
173
  raise
174
 
175
+ def fetch_ups_tracking_info(tracking_number):
176
+ access_token = get_ups_access_token()
177
+ url = f"https://onlinetools.ups.com/api/track/v1/details/{tracking_number}"
178
+ headers = {
179
+ 'Authorization': f'Bearer {access_token}',
180
+ 'Content-Type': 'application/json',
181
+ 'Accept': 'application/json',
182
+ 'User-Agent': 'OCMTrackingApp/1.0',
183
+ 'transId': str(uuid.uuid4()),
184
+ 'transactionSrc': 'OCMTrackingApp'
185
+ }
186
+ params = {
187
+ "locale": "en_US",
188
+ "returnSignature": "false",
189
+ "returnMilestones": "false",
190
+ "returnPOD": "false"
191
+ }
192
+ try:
193
+ logger.info(f"Requesting UPS tracking info for {tracking_number}")
194
+ response = requests.get(url, headers=headers, params=params)
195
+ response.raise_for_status()
196
+ data = response.json()
197
+
198
+ shipment = data['trackResponse']['shipment'][0]
199
+ package = shipment['package'][0]
200
+ events = package.get('activity', [])
201
+
202
+ if events:
203
+ sorted_events = sorted(events, key=lambda x: x['date'] + x['time'], reverse=True)
204
+ latest_event = sorted_events[0]
205
+ else:
206
+ latest_event = None
207
+
208
+ def format_date(date_str, time_str):
209
+ if not date_str or not time_str or date_str == 'N/A' or time_str == 'N/A':
210
+ return 'N/A'
211
+ try:
212
+ date = datetime.strptime(date_str + time_str, '%Y%m%d%H%M%S')
213
+ return date.strftime('%m/%d/%Y %I:%M %p')
214
+ except ValueError:
215
+ logger.warning(f"Unable to parse date: {date_str} or time: {time_str}")
216
+ return 'N/A'
217
+
218
+ delivery_date = 'N/A'
219
+ delivery_time = 'N/A'
220
+ if 'deliveryDate' in package:
221
+ if isinstance(package['deliveryDate'], list) and package['deliveryDate']:
222
+ delivery_date = package['deliveryDate'][0].get('date', 'N/A')
223
+ elif isinstance(package['deliveryDate'], dict):
224
+ delivery_date = package['deliveryDate'].get('date', 'N/A')
225
+ if 'deliveryTime' in package:
226
+ delivery_time = package['deliveryTime'].get('endTime', 'N/A')
227
+
228
+ return {
229
+ 'status': latest_event['status']['type'] if latest_event else 'N/A',
230
+ 'courier': 'UPS',
231
+ 'estimatedDelivery': format_date(delivery_date, delivery_time),
232
+ 'latestLocation': latest_event['location']['address'].get('city', 'N/A') if latest_event else 'N/A',
233
+ 'latestCheckpoint': latest_event['status']['description'] if latest_event else 'N/A',
234
+ 'lastUpdateDateTime': format_date(latest_event['date'], latest_event['time']) if latest_event else 'N/A',
235
+ }
236
+ except requests.exceptions.RequestException as e:
237
+ logger.error(f"Error fetching UPS tracking info: {e}")
238
+ if hasattr(e, 'response'):
239
+ logger.error(f"Response content: {e.response.text}")
240
+ raise
241
+
242
  def load_trackings():
243
  try:
244
  if os.path.exists(TRACKING_FILE):
 
246
  content = file.read().strip()
247
  if content:
248
  trackings = json.loads(content)
249
+ logger.info(f"Loaded {len(trackings)} trackings from file")
250
  return trackings
251
  else:
252
+ logger.info("Tracking file is empty")
253
  return {}
254
  else:
255
+ logger.info(f"Tracking file {TRACKING_FILE} not found")
256
  return {}
257
  except json.JSONDecodeError:
258
+ logger.error("Error decoding JSON, file might be corrupted")
259
  return {}
260
  except Exception as e:
261
+ logger.error(f"Error loading trackings: {str(e)}")
262
+ logger.error(f"Traceback: {traceback.format_exc()}")
 
263
  return {}
264
 
265
  def save_trackings(trackings):
266
  try:
267
  with open(TRACKING_FILE, 'w') as file:
268
  json.dump(trackings, file, indent=4)
269
+ logger.info(f"Saved {len(trackings)} trackings to file")
270
  except Exception as e:
271
+ logger.error(f"Error saving trackings to {TRACKING_FILE}: {str(e)}")
272
+ logger.error(f"Traceback: {traceback.format_exc()}")
 
273
  raise
274
 
275
  def update_tracking_info():
 
313
  tracking_info = fetch_ups_tracking_info(tracking_number)
314
  return jsonify(tracking_info), 200
315
  except Exception as e:
316
+ logger.error(f"Error in get_ups_tracking: {e}")
317
  return jsonify({"status": "error", "message": str(e)}), 500
318
 
319
  @app.route('/fedex', methods=['POST'])
 
326
  tracking_info = fetch_fedex_tracking_info(tracking_number)
327
  return jsonify(tracking_info), 200
328
  except Exception as e:
329
+ logger.error(f"Error in get_fedex_tracking: {e}")
330
  return jsonify({"status": "error", "message": str(e)}), 500
331
 
332
  @app.route('/save_tracking', methods=['POST'])
 
336
  if not tracking_info:
337
  return jsonify({"status": "error", "message": "No data received"}), 400
338
 
339
+ logger.info("Received tracking info: %s", tracking_info) # Debug print
340
 
341
  trackings = load_trackings()
342
  tracking_number = tracking_info['tracking']
 
348
  trackings[tracking_number] = tracking_info
349
 
350
  save_trackings(trackings)
351
+ logger.info(f"Saved tracking: {tracking_number}")
352
  return jsonify({"status": "success", "message": "Tracking saved successfully"}), 200
353
  except Exception as e:
354
+ logger.error(f"Error saving tracking: {str(e)}")
 
 
355
  return jsonify({"status": "error", "message": str(e)}), 500
356
 
357
  @app.route('/load_trackings', methods=['GET'])
358
  def get_trackings():
359
  try:
360
  trackings = load_trackings()
361
+ logger.info("Loaded trackings: %s", trackings)
362
  return jsonify(trackings), 200
363
  except Exception as e:
364
+ logger.error(f"Error in get_trackings: {str(e)}")
365
  return jsonify({"status": "error", "message": str(e)}), 500
366
 
367
  if __name__ == '__main__':
 
369
  update_thread = Thread(target=update_tracking_info, daemon=True)
370
  update_thread.start()
371
 
372
+ app.run(host='0.0.0.0', port=7860)