1
0

Propogate error to interface
All checks were successful
Run Python tests (through Pytest) / Test (push) Successful in 25s
Verify Python project can be installed, loaded and have version checked / Test (push) Successful in 23s

This commit is contained in:
Jon Michael Aanes 2025-01-26 19:59:27 +01:00
parent fe0bd9f3f7
commit 3cb26194e8
2 changed files with 25 additions and 8 deletions

View File

@ -1,5 +1,6 @@
import bottle import bottle
import datetime
from . import database, parcelsapp from . import database, parcelsapp
PARCELSAPP_CLIENT: parcelsapp.ParcelsAppClient | None = None PARCELSAPP_CLIENT: parcelsapp.ParcelsAppClient | None = None
@ -57,6 +58,10 @@ a {
background: #AEABFB; background: #AEABFB;
} }
.tracking-item.unknown {
background: red;
}
h1 { h1 {
text-align: center; text-align: center;
} }
@ -98,13 +103,17 @@ footer {
<main> <main>
% if error_message is not None:
<div class="error-message">{{error_message}}</div>
% end
<div class="tracking-grid"> <div class="tracking-grid">
% for entry, tracking_data in tracking_results: % for entry, tracking_data in tracking_results:
<a target="_blank" href="{{tracking_data.tracking_url}}"> <a target="_blank" href="{{tracking_data.tracking_url if tracking_data else ''}}">
<div class="tracking-item {{tracking_data.status}}"> <div class="tracking-item {{tracking_data.status if tracking_data else 'unknown'}}">
<div class="tracking-name" title="{{entry.number}}"><span class="tracking-name-inner">{{ entry.name }}</span></div> <div class="tracking-name" title="{{entry.number}}"><span class="tracking-name-inner">{{ entry.name }}</span></div>
<div class="tracking-status">{{ tracking_data.latest_state().status }}</div> <div class="tracking-status">{{ tracking_data.latest_state().status if tracking_data else 'unknown' }}</div>
<div class="tracking-update-date">{{ tracking_data.latest_state().date.date() }}</div> <div class="tracking-update-date">{{ tracking_data.latest_state().date.date() if tracking_data else '???' }}</div>
</div> </div>
</a> </a>
% end % end
@ -131,21 +140,27 @@ footer {
</html> </html>
""" """
TODAY = datetime.datetime.now(tz=datetime.UTC).date()
def render_tracking(with_form: bool): def render_tracking(with_form: bool):
tracking_entries = database.get_tracking_numbers() tracking_entries = database.get_tracking_numbers()
tracking_numbers = [e.number for e in tracking_entries] tracking_numbers = [e.number for e in tracking_entries]
tracking_results = PARCELSAPP_CLIENT.get_tracking_status(tracking_numbers) try:
tracking_results = list(PARCELSAPP_CLIENT.get_tracking_status(tracking_numbers))
error_message = None
except parcelsapp.ParcelsApiError as ex:
tracking_results = []
error_message = str(ex)
tracking_results_by_id = { tracking_results_by_id = {
result.tracking_number: result for result in tracking_results result.tracking_number: result for result in tracking_results
} }
tracking_results_with_name = [(e, tracking_results_by_id.get(e.number)) for e in tracking_entries] tracking_results_with_name = [(e, tracking_results_by_id.get(e.number)) for e in tracking_entries]
tracking_results_with_name.sort(key=lambda x: x[1].latest_state().date, reverse=True) tracking_results_with_name.sort(key=lambda x: x[1].latest_state().date if x[1] else TODAY, reverse=True)
return bottle.template(TEMPLATE, tracking_results=tracking_results_with_name, with_form=with_form) return bottle.template(TEMPLATE, error_message=error_message, tracking_results=tracking_results_with_name, with_form=with_form)
@bottle.route('/') @bottle.route('/')
def index(): def index():

View File

@ -35,6 +35,8 @@ class ParcelInfo:
def latest_state(self) -> ParcelState: def latest_state(self) -> ParcelState:
return max(self.states, key=lambda state: state.date) return max(self.states, key=lambda state: state.date)
class ParcelsApiError(RuntimeError):
pass
class ParcelsAppClient: class ParcelsAppClient:
def __init__(self, api_key: str): def __init__(self, api_key: str):
@ -50,7 +52,7 @@ class ParcelsAppClient:
json_data = response.json() json_data = response.json()
if 'error' in json_data: if 'error' in json_data:
msg = 'Error from endpoint: {}'.format(json_data['error']) msg = 'Error from endpoint: {}'.format(json_data['error'])
raise RuntimeError(msg) raise ParcelsApiError(msg)
return json_data return json_data
def check_tracking_status(self, uuid: str) -> dict: def check_tracking_status(self, uuid: str) -> dict: