commit 3194493e64efdeaf08f04ab464f7c4f84340eeb5 Author: Kumi Date: Sat Mar 25 20:18:17 2023 +0000 Seems to work so far diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c8f647 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +venv/ +*.pyc +__pycache__/ +settings.ini \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..eba8a5a --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# TrackingMore API Tool + +This is a simple Python tool to use the TrackingMore API. + +## Dependencies + +This tool has no dependencies other than Python 3. It has been tested with Python 3.10.9, but should work with any Python >= 3.8. \ No newline at end of file diff --git a/classes/api.py b/classes/api.py new file mode 100644 index 0000000..0f36b77 --- /dev/null +++ b/classes/api.py @@ -0,0 +1,47 @@ +from typing import Optional +from json import dumps, loads + +import urllib.request + + +class TrackingMore: + def __init__(self, api_key: str): + self.api_key = api_key + + def request(self, endpoint: str, payload: Optional[dict | str] = None, method: Optional[str] = None): + url = f"https://api.trackingmore.com/v3/trackings/{endpoint}" + + headers = {"Tracking-Api-Key": self.api_key} + + if isinstance(payload, dict): + payload = dumps(payload) + + if payload: + headers["Content-Type"] = "application/json" + + if payload and not method: + method = "POST" + elif method: + method = method.upper() + else: + method = "GET" + + req = urllib.request.Request( + url, payload.encode() if payload else None, headers=headers, method=method) + + res = urllib.request.urlopen(req) + return loads(res.read()) + + def get_carriers(self): + return self.request("carriers").get("data", []) + + def detect_carrier(self, tracking_number: str): + return self.request("detect", {"tracking_number": tracking_number}).get("data", {}) + + def track_shipment(self, tracking_number: str, carrier_code: str): + payload = { + "tracking_number": tracking_number, + "courier_code": carrier_code or self.detect_carrier(tracking_number)[0]["courier_code"] + } + + return self.request("realtime", payload).get("data", {}) diff --git a/settings.dist.ini b/settings.dist.ini new file mode 100644 index 0000000..b2ba6bb --- /dev/null +++ b/settings.dist.ini @@ -0,0 +1,2 @@ +[TrackingMore] +APIKey = YourAPIKey \ No newline at end of file diff --git a/tracker.py b/tracker.py new file mode 100644 index 0000000..8a3132e --- /dev/null +++ b/tracker.py @@ -0,0 +1,38 @@ +from classes.api import TrackingMore + +from configparser import ConfigParser +from argparse import ArgumentParser + +if __name__ == "__main__": + config = ConfigParser() + config.read('settings.ini') + + parser = ArgumentParser() + + parser.add_argument('tracking_number', nargs="?", help='Tracking number to track') + parser.add_argument('--carrier', '-c', help='Carrier to track (carrier code – see --list-carriers/-l, auto-detected if not specified)') + parser.add_argument('--detect-carrier', '-d', action='store_true', help='Detect and output carrier from tracking number') + parser.add_argument('--list-carriers', '-l', action='store_true', help='List carriers') + parser.add_argument('--key', '-k', help='TrackingMore API Key (overrides config)') + + args = parser.parse_args() + + if (args.tracking_number or args.carrier) and args.list_carriers: + print("Cannot specify both tracking number and --list-carriers/-l") + exit(1) + + api_key = args.key or config['TrackingMore']['APIKey'] + + api = TrackingMore(api_key) + + if args.list_carriers: + for carrier in api.get_carriers(): + print(f"{carrier['courier_name']} ({carrier['courier_code']})") + + elif args.tracking_number: + if args.detect_carrier: + for carrier in api.detect_carrier(args.tracking_number): + print(f"{carrier['courier_name']} ({carrier['courier_code']})") + + else: + print(api.track_shipment(args.tracking_number, args.carrier))