M README.md => README.md +3 -2
@@ 8,10 8,11 @@ A python library and a GTK3 mobile/desktop application for tracking multiple shi
Supported carriers
------------------
-* UPS
+* DHL (needs api code)
+* InPost
* PostNL
* Russian Post
-* InPost
+* UPS
Installing
----------
M data/org.postmarketos.Shipments.appdata.xml => data/org.postmarketos.Shipments.appdata.xml +3 -2
@@ 11,10 11,11 @@
Application to track your shipments. Supported carriers:
</p>
<ul>
- <li>UPS</li>
+ <li>DHL (needs api code)</li>
+ <li>InPost</li>
<li>PostNL</li>
<li>Russian Post</li>
- <li>InPost</li>
+ <li>UPS</li>
</ul>
</description>
<launchable type="desktop-id">org.postmarketos.Shipments.desktop</launchable>
M shipments/carrier.py => shipments/carrier.py +68 -0
@@ 366,3 366,71 @@ class InPost(Carrier):
result.events.append(e)
return result
+
+
+class DHL(Carrier):
+ DISPLAYNAME = 'DHL'
+
+ def _addr(self, payload):
+ res = Address()
+ if 'countryCode' in payload['address']:
+ res.country = payload['address']['countryCode']
+ return res
+
+ def get_requirements(cls, code):
+ return [
+ ('apikey', 'DHL API key', 'text'),
+ ]
+
+ def get_info(self, code, extra):
+ url = 'https://api-eu.dhl.com/track/shipments'
+ headers = {
+ 'Accept': 'application/json',
+ 'DHL-API-Key': extra['apikey'],
+ }
+ payload = {
+ 'trackingNumber': code
+ }
+ response = requests.get(url, params=payload, headers=headers)
+ payload = response.json()
+ result = PackageInfo(code, 'DHL')
+ result.carrier_name = self.DISPLAYNAME
+ result.status_category = StatusCategory.ERROR
+ result.tracking_url = 'https://www.dhl.com/gb-en/home/tracking/tracking-parcel.html?submit=1&tracking-id=' + code
+
+ if len(payload['shipments']):
+ payload = payload['shipments'][0]
+ else:
+ result.status = payload['']
+ return result
+
+ result.status_category = StatusCategory.LABEL_CREATED
+ result.status = payload['status']['status']
+ if payload['status']['statusCode'] == 'pre-transit':
+ result.status_category = StatusCategory.LABEL_CREATED
+ elif payload['status']['statusCode'] == 'transit':
+ result.status_category = StatusCategory.IN_TRANSIT
+
+ if 'weight' in payload['details'] and payload['details']['weight'] is not None:
+ w = payload['details']['weight']
+ if w['unitText'] == 'kg':
+ result.weight = w['value'] * 1000
+ else:
+ print(f"Unknown unit '{w['unitText']}'")
+
+ for event in payload['events']:
+ stamp = datetime.fromisoformat(event['timestamp'])
+ location = ''
+ if 'location' in event:
+ if len(event['location']['address']) == 1 and 'addressLocality' in event['location']['address']:
+ location = event['location']['address']['addressLocality']
+ e = PackageEvent(stamp, location, event['status'])
+ result.events.append(e)
+
+ if 'address' in payload['origin']:
+ result.origin = self._addr(payload['origin'])
+
+ if 'address' in payload['destination']:
+ result.destination = self._addr(payload['destination'])
+
+ return result