From 3adb516663adbad535f3c462ad84fa742cb19626 Mon Sep 17 00:00:00 2001 From: loboda4450 Date: Fri, 12 May 2023 15:14:50 +0200 Subject: [PATCH 1/8] air sensor in parcel machines implemented --- inpost/static/parcels.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/inpost/static/parcels.py b/inpost/static/parcels.py index 687ca79..f3b15e3 100644 --- a/inpost/static/parcels.py +++ b/inpost/static/parcels.py @@ -33,7 +33,6 @@ class Parcel(BaseParcel): def __init__(self, parcel_data: dict, logger: logging.Logger): """Constructor method""" super().__init__(parcel_data, logger) - # self.shipment_number: str = parcel_data['shipmentNumber'] self._log: logging.Logger = logger.getChild(f'{__class__.__name__}.{self.shipment_number}') self.shipment_type: ParcelShipmentType = ParcelShipmentType[parcel_data['shipmentType']] self._open_code: str | None = parcel_data['openCode'] if 'openCode' in parcel_data else None @@ -41,7 +40,6 @@ def __init__(self, parcel_data: dict, logger: logging.Logger): if 'qrCode' in parcel_data else None self.stored_date: arrow | None = get(parcel_data['storedDate']) if 'storedDate' in parcel_data else None self.pickup_date: arrow | None = get(parcel_data['pickUpDate']) if 'pickUpDate' in parcel_data else None - # self.expiry_date: arrow | None = get(parcel_data['expiryDate']) if 'expiryDate' in parcel_data else None self.parcel_size: ParcelLockerSize | ParcelCarrierSize = ParcelLockerSize[parcel_data['parcelSize']] \ if self.shipment_type == ParcelShipmentType.parcel else ParcelCarrierSize[parcel_data['parcelSize']] self.receiver: Receiver = Receiver(receiver_data=parcel_data['receiver'], logger=self._log) @@ -51,10 +49,7 @@ def __init__(self, parcel_data: dict, logger: logging.Logger): self.multi_compartment: MultiCompartment | None = MultiCompartment( parcel_data['multiCompartment'], logger=self._log) if 'multiCompartment' in parcel_data else None self.is_end_off_week_collection: bool = parcel_data['endOfWeekCollection'] - # self.operations: Operations = Operations(operations_data=parcel_data['operations'], logger=self._log) self.status: ParcelStatus = ParcelStatus[parcel_data['status']] - # self.event_log: List[EventLog] = [EventLog(eventlog_data=event, logger=self._log) - # for event in parcel_data['eventLog']] self.avizo_transaction_status: str = parcel_data['avizoTransactionStatus'] self.shared_to: List[SharedTo] = [SharedTo(sharedto_data=person, logger=self._log) for person in parcel_data['sharedTo']] @@ -338,6 +333,7 @@ def __init__(self, pickuppoint_data: dict, logger: logging.Logger): self.image_url: str = pickuppoint_data['imageUrl'] self.easy_access_zone: bool = pickuppoint_data['easyAccessZone'] self.air_sensor: bool = pickuppoint_data['airSensor'] + self.air_sensor_data: AirSensorData | None = AirSensorData(pickuppoint_data['airSensorData']) if 'airSensorData' in pickuppoint_data else None self._log: logging.Logger = logger.getChild(__class__.__name__) self._log.debug('created') @@ -604,3 +600,25 @@ def status(self, status_data: str | CompartmentActualStatus): if self._status == CompartmentActualStatus.UNKNOWN and isinstance(status_data, str): self._log.debug(f'unexpected compartment actual status: {status_data}') + + +class AirSensorData: + """Object representation of :class:`Parcel` air sensor data + + :param airsensor_data: :class:`dict` containing air sensor data for :class:`Parcel` + :type airsensor_data: dict + :param logger: :class:`logging.Logger` parent instance + :type logger: logging.Logger""" + def __init__(self, airsensor_data: dict, logger: logging.Logger): + self.updated_until: arrow = airsensor_data['updatedUntil'] + self.air_quality: str = airsensor_data['airQuality'] + self.temperature: float = airsensor_data['temperature'] + self.humidity: float = airsensor_data['humidity'] + self.pressure: float = airsensor_data['pressure'] + self.pm25_value: float = airsensor_data['pollutants']['pm25']['value'] + self.pm25_percent: float = airsensor_data['pollutants']['pm25']['percent'] + self.pm10_value: float = airsensor_data['pollutants']['pm10']['value'] + self.pm10_percent: float = airsensor_data['pollutants']['pm10']['percent'] + + self._log: logging.Logger = logger.getChild(__class__.__name__) + self._log.debug('created') From f0cabb0ae1f7182cb9a0c2884aab751c4731c2e8 Mon Sep 17 00:00:00 2001 From: loboda4450 Date: Sun, 14 May 2023 10:53:40 +0200 Subject: [PATCH 2/8] reopen parcel machine, http method fix in parcel machine open, closes #7 --- inpost/api.py | 29 ++++++++++++++++++++++++++++- inpost/static/endpoints.py | 1 + pyproject.toml | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/inpost/api.py b/inpost/api.py index 0aac53a..5863e2d 100644 --- a/inpost/api.py +++ b/inpost/api.py @@ -502,7 +502,7 @@ async def open_compartment(self) -> bool: self._log.debug(f'authorization token missing') raise NotAuthenticatedError(reason='Not logged in') - resp = await self.request(method='get', + resp = await self.request(method='post', action=f"open compartment for {self.parcel.shipment_number}", url=compartment_open, auth=True, @@ -634,6 +634,33 @@ async def close_compartment(self) -> bool: return False + async def reopen_compartment(self) -> bool: + """Reopens compartment for `Inpost.parcel` object + + :return: True if compartment gets reopened + :rtype: bool + :raises NotAuthenticatedError: User not authenticated in inpost service + :raises UnauthorizedError: Unauthorized access to inpost services, + :raises NotFoundError: Phone number not found + :raises UnidentifiedAPIError: Unexpected thing happened""" + self._log.info(f'reopening compartment for {self.parcel.shipment_number}') + + if not self.auth_token: + self._log.debug(f'authorization token missing') + raise NotAuthenticatedError(reason='Not logged in') + + resp = await self.request(method='post', + action=f"reopen compartment for {self.parcel.shipment_number}", + url=compartment_open, + auth=True, + headers=None, + data={'sessionUuid': self.parcel.compartment_properties.session_uuid}, + autorefresh=True) + + if resp.status == 200: + self._log.debug(f'opened compartment for {self.parcel.shipment_number}') + return True + async def get_prices(self) -> dict: """Fetches prices for inpost services diff --git a/inpost/static/endpoints.py b/inpost/static/endpoints.py index c2e946b..d47f0cc 100644 --- a/inpost/static/endpoints.py +++ b/inpost/static/endpoints.py @@ -9,6 +9,7 @@ parcel: str = 'https://api-inmobile-pl.easypack24.net/v3/parcels/tracked/' # get multi: str = 'https://api-inmobile-pl.easypack24.net/v3/parcels/multi/' # get collect: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/validate' # post +reopen: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/compartment/reopen' # post compartment_open: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/compartment/open' # post compartment_status: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/compartment/status' # post terminate_collect_session: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/terminate' # post diff --git a/pyproject.toml b/pyproject.toml index 605d51f..d7a7bcb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "inpost" -version = "0.0.10" +version = "0.0.11" description = "Asynchronous InPost package allowing you to manage existing incoming parcels without mobile app" authors = ["loboda4450 ", "MrKazik99 "] maintainers = ["loboda4450 "] From 07282c778d93c14c88ee66070e2e268236598315 Mon Sep 17 00:00:00 2001 From: loboda4450 Date: Tue, 16 May 2023 19:51:57 +0200 Subject: [PATCH 3/8] initialize Inpost object from dict --- inpost/api.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/inpost/api.py b/inpost/api.py index 5863e2d..e5b6772 100644 --- a/inpost/api.py +++ b/inpost/api.py @@ -107,6 +107,17 @@ async def from_phone_number(cls, phone_number: str | int): inp._log.info(f'initialized by from_phone_number') return inp + @classmethod + async def from_dict(cls, data: dict): + inp = cls() + await inp.set_phone_number(data['phone_number']) + inp.sms_code = data['sms_code'] + inp.auth_token = data['auth_token'] + inp.refr_token = data['refr_token'] + + inp._log.info(f'initialized by from_dict') + return inp + async def set_phone_number(self, phone_number: str | int) -> bool: """Set :class:`Inpost` phone number required for verification From 08141777ac9a0df381474debb15ffd65fdedfe3e Mon Sep 17 00:00:00 2001 From: loboda4450 Date: Wed, 17 May 2023 20:25:09 +0200 Subject: [PATCH 4/8] cleanup, moved from 0.0.x to 0.1.0 --- inpost/static/parcels.py | 2 -- pyproject.toml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/inpost/static/parcels.py b/inpost/static/parcels.py index f3b15e3..21534ae 100644 --- a/inpost/static/parcels.py +++ b/inpost/static/parcels.py @@ -14,8 +14,6 @@ def __init__(self, parcel_data: dict, logger: logging.Logger): self.shipment_number: str = parcel_data['shipmentNumber'] self._log: logging.Logger = logger.getChild(f'{__class__.__name__}.{self.shipment_number}') self.status: ParcelStatus = ParcelStatus[parcel_data['status']] - # self.parcel_size: ParcelLockerSize | ParcelCarrierSize = ParcelLockerSize[parcel_data['parcelSize']] \ - # if self.shipment_type == ParcelShipmentType.parcel else ParcelCarrierSize[parcel_data['parcelSize']] self.expiry_date: arrow | None = get(parcel_data['expiryDate']) if 'expiryDate' in parcel_data else None self.operations: Operations = Operations(operations_data=parcel_data['operations'], logger=self._log) self.event_log: List[EventLog] = [EventLog(eventlog_data=event, logger=self._log) diff --git a/pyproject.toml b/pyproject.toml index d7a7bcb..85628f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "inpost" -version = "0.0.11" +version = "0.1.0" description = "Asynchronous InPost package allowing you to manage existing incoming parcels without mobile app" authors = ["loboda4450 ", "MrKazik99 "] maintainers = ["loboda4450 "] From 36c4617a111aeff4b8f820d2125abe076b3f502f Mon Sep 17 00:00:00 2001 From: loboda4450 Date: Tue, 30 May 2023 16:34:29 +0200 Subject: [PATCH 5/8] python 3.11 support --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 85628f6..770d4e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ packages = [ ] classifiers = [ "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Framework :: aiohttp", "Intended Audience :: Developers", "Operating System :: Microsoft :: Windows", From 5d1d93f80b3ef31a820ab4953c09459648ef0403 Mon Sep 17 00:00:00 2001 From: loboda4450 Date: Tue, 30 May 2023 16:36:05 +0200 Subject: [PATCH 6/8] using .get on optional dict keys and added new ones --- inpost/static/parcels.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/inpost/static/parcels.py b/inpost/static/parcels.py index 21534ae..b4a6f4b 100644 --- a/inpost/static/parcels.py +++ b/inpost/static/parcels.py @@ -11,7 +11,7 @@ class BaseParcel: def __init__(self, parcel_data: dict, logger: logging.Logger): - self.shipment_number: str = parcel_data['shipmentNumber'] + self.shipment_number: str = parcel_data.get('shipmentNumber') self._log: logging.Logger = logger.getChild(f'{__class__.__name__}.{self.shipment_number}') self.status: ParcelStatus = ParcelStatus[parcel_data['status']] self.expiry_date: arrow | None = get(parcel_data['expiryDate']) if 'expiryDate' in parcel_data else None @@ -33,25 +33,26 @@ def __init__(self, parcel_data: dict, logger: logging.Logger): super().__init__(parcel_data, logger) self._log: logging.Logger = logger.getChild(f'{__class__.__name__}.{self.shipment_number}') self.shipment_type: ParcelShipmentType = ParcelShipmentType[parcel_data['shipmentType']] - self._open_code: str | None = parcel_data['openCode'] if 'openCode' in parcel_data else None + self._open_code: str | None = parcel_data.get('openCode', None) self._qr_code: QRCode | None = QRCode(qrcode_data=parcel_data['qrCode'], logger=self._log) \ if 'qrCode' in parcel_data else None self.stored_date: arrow | None = get(parcel_data['storedDate']) if 'storedDate' in parcel_data else None self.pickup_date: arrow | None = get(parcel_data['pickUpDate']) if 'pickUpDate' in parcel_data else None self.parcel_size: ParcelLockerSize | ParcelCarrierSize = ParcelLockerSize[parcel_data['parcelSize']] \ if self.shipment_type == ParcelShipmentType.parcel else ParcelCarrierSize[parcel_data['parcelSize']] - self.receiver: Receiver = Receiver(receiver_data=parcel_data['receiver'], logger=self._log) - self.sender: Sender = Sender(sender_data=parcel_data['sender'], logger=self._log) + self.receiver: Receiver = Receiver(receiver_data=parcel_data['receiver'], logger=self._log) if 'reveiver' in parcel_data else None + self.sender: Sender = Sender(sender_data=parcel_data['sender'], logger=self._log) if 'sender' in parcel_data else None self.pickup_point: PickupPoint = PickupPoint(pickuppoint_data=parcel_data['pickUpPoint'], logger=self._log) \ if 'pickUpPoint' in parcel_data else None self.multi_compartment: MultiCompartment | None = MultiCompartment( parcel_data['multiCompartment'], logger=self._log) if 'multiCompartment' in parcel_data else None - self.is_end_off_week_collection: bool = parcel_data['endOfWeekCollection'] - self.status: ParcelStatus = ParcelStatus[parcel_data['status']] - self.avizo_transaction_status: str = parcel_data['avizoTransactionStatus'] + self.is_end_off_week_collection: bool | None = parcel_data.get('endOfWeekCollection', None) + self.status: ParcelStatus = ParcelStatus[parcel_data['status']] if 'status' in parcel_data else None + self.avizo_transaction_status: str | None = parcel_data.get('avizoTransactionStatus', None) self.shared_to: List[SharedTo] = [SharedTo(sharedto_data=person, logger=self._log) - for person in parcel_data['sharedTo']] - self.ownership_status: ParcelOwnership = ParcelOwnership[parcel_data['ownershipStatus']] + for person in parcel_data['sharedTo']] if 'sharedTo' in parcel_data else None + self.ownership_status: ParcelOwnership = ParcelOwnership[parcel_data['ownershipStatus']] if 'ownershipStatus' in parcel_data else None + self.economy_parcel: bool | None = parcel_data.get('economyParcel', None) self._compartment_properties: CompartmentProperties | None = None self._log.debug(f'created parcel with shipment number {self.shipment_number}') From 7effc568e75153ecb0321c498e4c882b16c7105c Mon Sep 17 00:00:00 2001 From: loboda4450 Date: Tue, 30 May 2023 16:37:21 +0200 Subject: [PATCH 7/8] fixed autorefresh bug --- inpost/api.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/inpost/api.py b/inpost/api.py index e5b6772..f0d3e7a 100644 --- a/inpost/api.py +++ b/inpost/api.py @@ -1,8 +1,9 @@ +import logging +from typing import List + from aiohttp import ClientSession, ClientResponse from aiohttp.typedefs import StrOrURL -from typing import List -import logging -from arrow import utcnow + from inpost.static import * @@ -77,6 +78,9 @@ async def request( if autorefresh and resp.status == 401: await self.refresh_token() + headers_.update( + {'Authorization': self.auth_token} + ) resp = await self.sess.request(method, url, headers=headers_, json=data, **kwargs) match resp.status: From e19a6ea0046cb41f3d05f703219df01f444285a8 Mon Sep 17 00:00:00 2001 From: loboda4450 Date: Tue, 6 Jun 2023 21:29:24 +0200 Subject: [PATCH 8/8] fixed typo that crashed opening parcel machine --- inpost/static/parcels.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inpost/static/parcels.py b/inpost/static/parcels.py index b4a6f4b..a396766 100644 --- a/inpost/static/parcels.py +++ b/inpost/static/parcels.py @@ -40,7 +40,7 @@ def __init__(self, parcel_data: dict, logger: logging.Logger): self.pickup_date: arrow | None = get(parcel_data['pickUpDate']) if 'pickUpDate' in parcel_data else None self.parcel_size: ParcelLockerSize | ParcelCarrierSize = ParcelLockerSize[parcel_data['parcelSize']] \ if self.shipment_type == ParcelShipmentType.parcel else ParcelCarrierSize[parcel_data['parcelSize']] - self.receiver: Receiver = Receiver(receiver_data=parcel_data['receiver'], logger=self._log) if 'reveiver' in parcel_data else None + self.receiver: Receiver = Receiver(receiver_data=parcel_data['receiver'], logger=self._log) if 'receiver' in parcel_data else None self.sender: Sender = Sender(sender_data=parcel_data['sender'], logger=self._log) if 'sender' in parcel_data else None self.pickup_point: PickupPoint = PickupPoint(pickuppoint_data=parcel_data['pickUpPoint'], logger=self._log) \ if 'pickUpPoint' in parcel_data else None diff --git a/pyproject.toml b/pyproject.toml index 770d4e5..55d577e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "inpost" -version = "0.1.0" +version = "0.1.2" description = "Asynchronous InPost package allowing you to manage existing incoming parcels without mobile app" authors = ["loboda4450 ", "MrKazik99 "] maintainers = ["loboda4450 "]