~martijnbraam/shipments

5f675f3433ec7ade712bafa63681f4326e9bff54 — Martijn Braam 2 years ago 9fa9af3
carrier: Add DHL

DHL requires an API key to work, added as extra options for now
3 files changed, 74 insertions(+), 4 deletions(-)

M README.md
M data/org.postmarketos.Shipments.appdata.xml
M shipments/carrier.py
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