Update version to 0.2.2, add DHL tracking provider, and improve config file generation and loading
- Change version in pyproject.toml to 0.2.2 - Add DHL tracking provider to README.md - Update README.md with instructions for generating a config file - Improve config file generation in __main__.py - Load config file in Tracker class - Update start and start_async methods in Tracker class to accept an optional config file path
This commit is contained in:
parent
44fe6a28a2
commit
751a7ad9e5
5 changed files with 59 additions and 17 deletions
|
@ -12,6 +12,7 @@ Status information is stored in a SQLite database.
|
|||
- [Austrian Post](https://www.post.at)
|
||||
- [GLS](https://gls-group.eu)
|
||||
- [FedEx](https://www.fedex.com) (requires an API key, see [FedEx Developer Resource Center](https://www.fedex.com/en-us/developer.html))
|
||||
- [DHL](https://www.dhl.com) (requires an API key, see [DHL Developer Portal](https://developer.dhl.com/))
|
||||
|
||||
More tracking providers can be added easily by subclassing `trackbert.trackers.base.BaseTracker`. This should be relatively self-explanatory if you look at the existing implementations. Pull requests are welcome!
|
||||
|
||||
|
@ -43,6 +44,10 @@ First, assure that the virtual environment is activated:
|
|||
source venv/bin/activate
|
||||
```
|
||||
|
||||
If you need to create a new config file, run `trackbert -g`. You need this if
|
||||
you want to provide API keys required for KeyDelivery or some of the other
|
||||
tracking providers.
|
||||
|
||||
To add a new shipment, run `trackbert --tracking-number <tracking-number> --carrier <carrier-id>`. Find the required carrier ID in the [KeyDelivery API management](https://app.kd100.com/api-management).
|
||||
|
||||
To run the main loop, run `trackbert`. This will check the status of all shipments every 5 minutes, and print the status to the console. If the status of a shipment changes, you will get a desktop notification.
|
||||
|
|
|
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||
|
||||
[project]
|
||||
name = "trackbert"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
authors = [
|
||||
{ name="Kumi Mitterer", email="trackbert@kumi.email" },
|
||||
]
|
||||
|
|
|
@ -6,13 +6,18 @@ import subprocess
|
|||
import argparse
|
||||
import logging
|
||||
import asyncio
|
||||
|
||||
from typing import Tuple, Never, Optional
|
||||
|
||||
from .classes.database import Database
|
||||
from .classes.tracker import Tracker
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
# Arguments related to the tracker
|
||||
|
||||
parser.add_argument("--tracking-number", "-n", type=str, required=False)
|
||||
parser.add_argument("--carrier", "-c", type=str, required=False)
|
||||
parser.add_argument("--description", "-d", type=str, required=False)
|
||||
|
@ -30,17 +35,37 @@ def main():
|
|||
required=False,
|
||||
help="Disable existing shipment",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--timeout",
|
||||
"-t",
|
||||
type=int,
|
||||
required=False,
|
||||
default=30,
|
||||
help="Notification timeout in seconds",
|
||||
)
|
||||
|
||||
# Arguments related to the config file
|
||||
|
||||
parser.add_argument("--generate-config", action="store_true", required=False)
|
||||
parser.add_argument("--config-file", "-C", type=str, required=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Generate config file if requested
|
||||
|
||||
config_file = Path(args.config_file or "config.ini")
|
||||
|
||||
if args.generate_config:
|
||||
if config_file.exists():
|
||||
print(f"Config file {config_file} already exists.")
|
||||
exit(1)
|
||||
|
||||
with Path(config_file).open("w") as config_file_obj:
|
||||
template = Path(__file__).parent / "config.dist.ini"
|
||||
config_file_obj.write(template.read_text())
|
||||
print(f"Generated config file {config_file}")
|
||||
exit(0)
|
||||
|
||||
# Load config file
|
||||
|
||||
if not config_file.exists():
|
||||
print(f"Config file {config_file} does not exist. Use -g to generate it.")
|
||||
exit(1)
|
||||
|
||||
|
||||
|
||||
db = Database("sqlite:///trackbert.db")
|
||||
|
||||
if args.tracking_number is not None and args.carrier is not None:
|
||||
|
@ -76,5 +101,6 @@ def main():
|
|||
tracker = Tracker()
|
||||
asyncio.run(tracker.start_async())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -3,8 +3,11 @@ import subprocess
|
|||
import time
|
||||
import importlib
|
||||
import asyncio
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Optional, Tuple, Never
|
||||
from os import PathLike
|
||||
from configparser import ConfigParser
|
||||
|
||||
from .database import Database
|
||||
from ..trackers.base import BaseTracker
|
||||
|
@ -46,7 +49,7 @@ class Tracker:
|
|||
for carrier, priority in carriers:
|
||||
self.apis.append((carrier, priority, api))
|
||||
except:
|
||||
logging.exception(f"Error loading tracker {name}")
|
||||
logging.exception(f"Error loading tracker {api.stem}")
|
||||
|
||||
def query_api(self, tracking_number: str, carrier: str) -> list:
|
||||
logging.debug(f"Querying API for {tracking_number} with carrier {carrier}")
|
||||
|
@ -173,12 +176,20 @@ class Tracker:
|
|||
|
||||
await asyncio.sleep(self.loop_interval)
|
||||
|
||||
def start(self):
|
||||
self.db = Database("sqlite:///trackbert.db")
|
||||
def _pre_start(self, config: Optional[PathLike] = None):
|
||||
parser = ConfigParser()
|
||||
parser.read(config or [])
|
||||
|
||||
self.database_uri = parser.get("Trackbert", "database", fallback="sqlite:///trackbert.db")
|
||||
self.db = Database(self.database_uri)
|
||||
|
||||
self.loop_interval = parser.getint("Trackbert", "interval", fallback=60)
|
||||
self.notify("Trackbert", "Starting up")
|
||||
|
||||
def start(self, config: Optional[PathLike] = None):
|
||||
self._pre_start(config)
|
||||
self.start_loop()
|
||||
|
||||
async def start_async(self):
|
||||
self.db = Database("sqlite:///trackbert.db")
|
||||
self.notify("Trackbert", "Starting up")
|
||||
await self.start_loop_async()
|
||||
async def start_async(self, config: Optional[PathLike] = None):
|
||||
self._pre_start(config)
|
||||
await self.start_loop_async()
|
Loading…
Reference in a new issue