~martijnbraam/shipments

ba281dbe88c405761e68aba5f56f5109a1931dd1 — Martijn Braam 2 years ago 6566f27
carrier: Add 4PX
3 files changed, 61 insertions(+), 1 deletions(-)

M README.md
M data/org.postmarketos.Shipments.appdata.xml
M shipments/carrier.py
M README.md => README.md +1 -0
@@ 8,6 8,7 @@ A python library and a GTK3 mobile/desktop application for tracking multiple shi
Supported carriers
------------------

* 4PX
* DHL (needs api code)
* InPost
* PostNL

M data/org.postmarketos.Shipments.appdata.xml => data/org.postmarketos.Shipments.appdata.xml +1 -0
@@ 11,6 11,7 @@
      Application to track your shipments. Supported carriers:
    </p>
    <ul>
      <li>4PX</li>
      <li>DHL (needs api code)</li>
      <li>InPost</li>
      <li>PostNL</li>

M shipments/carrier.py => shipments/carrier.py +59 -1
@@ 1,4 1,4 @@
from datetime import datetime
from datetime import datetime, timezone, timedelta

import requests



@@ 434,3 434,61 @@ class DHL(Carrier):
            result.destination = self._addr(payload['destination'])

        return result


class Track4PX(Carrier):
    DISPLAYNAME = '4PX'

    @classmethod
    def identify(cls, code):
        if len(code) != 20:
            return False
        if not code.startswith('H'):
            return False
        if not code[1:].isnumeric():
            return False
        return True

    def get_info(self, code, extra):
        url = 'https://track.4px.com/track/v2/front/listTrack'
        data = {
            'serveCodes': [code],
            'language': 'en-us',
        }
        response = requests.post(url, json=data)
        payload = response.json()
        result = PackageInfo(code, 'Track4PX')
        result.carrier_name = self.DISPLAYNAME
        result.status_category = StatusCategory.ERROR
        result.tracking_url = 'https://track.4px.com/#/result/0/' + code

        if 'data' in payload and len(payload['data']):
            payload = payload['data'][0]
        else:
            result.status = payload['message']
            return result

        if payload['status'] == 0:
            result.status_category = StatusCategory.ERROR
            result.status = 'error'
        elif payload['status'] == 1:
            result.status_category = StatusCategory.IN_TRANSIT
            result.status = 'In transit'
        else:
            result.status_category = StatusCategory.DELIVERED
            result.status = 'Delivered'

        for event in payload['tracks']:
            _, tz = event['tkTimezone'].split('+')
            tz_hour, tz_min = tz.split(':')
            stamp = datetime.fromtimestamp(event['tkDate'] / 1000,
                                           tz=timezone(timedelta(hours=int(tz_hour, 10), minutes=int(tz_min, 10))))
            e = PackageEvent(stamp, event['tkLocation'], event['tkDesc'])
            result.events.append(e)

        result.origin = Address()
        result.origin.country = payload['ctStartName']
        result.destination = Address()
        result.destination.country = payload['ctEndName']

        return result