Skip to content

Commit 973ec71

Browse files
authored
✨ Provide tracked trackables with setting (#20)
* ✨ Provide tracked trackables with setting * Allow updating settings * ✨ Add last log information
1 parent b8a38a6 commit 973ec71

3 files changed

Lines changed: 68 additions & 14 deletions

File tree

geocachingapi/geocachingapi.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ async def _request(self, method, uri, **kwargs) -> ClientResponse:
138138

139139
async def update(self) -> GeocachingStatus:
140140
await self._update_user(None)
141-
if self._settings.fetch_trackables:
141+
if len(self._settings.trackable_codes) > 0:
142142
await self._update_trackables()
143143
_LOGGER.info(f'Status updated.')
144144
return self._status
@@ -172,9 +172,11 @@ async def _update_trackables(self, data: Dict[str, Any] = None) -> None:
172172
"milesTraveled",
173173
"currentGeocacheCode",
174174
"currentGeocacheName",
175-
"isMissing"
175+
"isMissing",
176+
"type"
176177
])
177-
data = await self._request("GET", f"/trackables?fields={fields}&type=3")
178+
trackable_parameters = ",".join(self._settings.trackable_codes)
179+
data = await self._request("GET", f"/trackables?referenceCodes={trackable_parameters}&fields={fields}&expand=trackablelogs:1")
178180
self._status.update_trackables_from_dict(data)
179181
if len(self._status.trackables) > 0:
180182
for trackable in self._status.trackables.values():
@@ -186,7 +188,10 @@ async def _update_trackables(self, data: Dict[str, Any] = None) -> None:
186188

187189
_LOGGER.debug(f'Trackables updated.')
188190

189-
191+
async def update_settings(self, settings: GeocachingSettings):
192+
"""Update the Geocaching settings"""
193+
self._settings = settings
194+
190195
async def close(self) -> None:
191196
"""Close open client session."""
192197
if self._session and self._close_session:

geocachingapi/models.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from __future__ import annotations
2+
from array import array
23
from enum import Enum
34
from typing import Any, Dict, Optional, TypedDict
45

@@ -20,12 +21,15 @@ class GeocachingApiEnvironment(Enum):
2021

2122
class GeocachingSettings:
2223
"""Class to hold the Geocaching Api settings"""
23-
fetch_trackables: bool
24+
trackable_codes: array(str)
2425
environment: GeocachingApiEnvironment
2526

26-
def __init__(self, fetch_trackables:bool = False, environment:GeocachingApiEnvironment = GeocachingApiEnvironment.Production ) -> None:
27+
def __init__(self, environment:GeocachingApiEnvironment = GeocachingApiEnvironment.Production, trackables:array(str) = [] ) -> None:
2728
"""Initialize settings"""
28-
self.fetch_trackables = fetch_trackables
29+
self.trackable_codes = trackables
30+
31+
def set_trackables(self, trackables:array(str)):
32+
self.trackable_codes = trackables
2933

3034
@dataclass
3135
class GeocachingUser:
@@ -37,6 +41,7 @@ class GeocachingUser:
3741
favorite_points: Optional[int] = None
3842
souvenir_count: Optional[int] = None
3943
awarded_favorite_points: Optional[int] = None
44+
membership_level_id: Optional[int] = None
4045

4146
def update_from_dict(self, data: Dict[str, Any]) -> None:
4247
"""Update user from the API result"""
@@ -47,6 +52,7 @@ def update_from_dict(self, data: Dict[str, Any]) -> None:
4752
self.favorite_points = try_get_from_dict(data, "favoritePoints", self.favorite_points)
4853
self.souvenir_count = try_get_from_dict(data, "souvenirCount", self.souvenir_count)
4954
self.awarded_favorite_points = try_get_from_dict(data, "awardedFavoritePoints", self.awarded_favorite_points)
55+
self.membership_level_id = try_get_from_dict(data, "membershipLevelId", self.membership_level_id)
5056

5157
@dataclass
5258
class GeocachingCoordinate:
@@ -73,6 +79,27 @@ def __init__(self, *, data: Dict[str, Any]) -> GeocachingTrackableJourney:
7379
self.coordinates = None
7480
self.logged_date = try_get_from_dict(data, "loggedDate", self.logged_date)
7581

82+
@dataclass
83+
class GeocachingTrackableLog:
84+
reference_code: Optional[str] = None
85+
owner: GeocachingUser = None
86+
text: Optional[str] = None
87+
log_type: Optional[str] = None
88+
logged_date: Optional[datetime] = None
89+
90+
def __init__(self, *, data: Dict[str, Any]) -> GeocachingTrackableLog:
91+
self.reference_code = try_get_from_dict(data, 'referenceCode',self.reference_code)
92+
if self.owner is None:
93+
self.owner = GeocachingUser()
94+
if 'owner' in data:
95+
self.owner.update_from_dict(data['owner'])
96+
else:
97+
self.owner = None
98+
self.log_type = try_get_from_dict(data['trackableLogType'], 'name',self.log_type)
99+
self.logged_date = try_get_from_dict(data, 'loggedDate',self.logged_date)
100+
self.text = try_get_from_dict(data, 'text',self.text)
101+
102+
76103
@dataclass
77104
class GeocachingTrackable:
78105
"""Class to hold the Geocaching trackable information"""
@@ -85,7 +112,10 @@ class GeocachingTrackable:
85112
current_geocache_code: Optional[str] = None
86113
current_geocache_name: Optional[str] = None
87114
latest_journey: GeocachingTrackableJourney = None
88-
is_missing: bool = False
115+
is_missing: bool = False,
116+
trackable_type: str = None,
117+
latest_log: GeocachingTrackableLog = None
118+
89119

90120
def update_from_dict(self, data: Dict[str, Any]) -> None:
91121
"""Update trackable from the API"""
@@ -104,6 +134,10 @@ def update_from_dict(self, data: Dict[str, Any]) -> None:
104134
self.current_geocache_code = try_get_from_dict(data, "currectGeocacheCode", self.current_geocache_code)
105135
self.current_geocache_name = try_get_from_dict(data, "currentGeocacheName", self.current_geocache_name)
106136
self.is_missing = try_get_from_dict(data, "isMissing", self.is_missing)
137+
self.trackable_type = try_get_from_dict(data, "type", self.trackable_type)
138+
if "trackableLogs" in data and len(data["trackableLogs"]) > 0:
139+
self.latest_log = GeocachingTrackableLog(data=data["trackableLogs"][0])
140+
107141

108142
class GeocachingStatus:
109143
"""Class to hold all account status information"""

tests/test.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,45 @@
11
"""Test for Geocaching Api integration."""
22
import asyncio
33
import logging
4-
from geocachingapi import GeocachingApi, GeocachingStatus
5-
from geocachingapi.models import GeocachingApiEnvironment, GeocachingSettings, GeocachingTrackable
4+
from geocachingapi import GeocachingApi
5+
from geocachingapi.models import GeocachingApiEnvironment, GeocachingSettings
66
from my_token import TOKEN
77
logging.basicConfig(level=logging.INFO)
88
mylogger = logging.getLogger()
99

1010
async def test():
1111
"""Function to test GeocachingAPI integration"""
12-
status:GeocachingStatus = None
13-
api = GeocachingApi(token=TOKEN, environment=GeocachingApiEnvironment.Staging, settings = GeocachingSettings(fetch_trackables=True))
12+
gc_settings = GeocachingSettings()
13+
api = GeocachingApi(token=TOKEN, environment=GeocachingApiEnvironment.Staging, settings=gc_settings)
14+
gc_settings.set_trackables(['TB87DTF'])
15+
await api.update_settings(gc_settings)
16+
await _update(api)
17+
await api.close()
18+
19+
20+
async def _update(api:GeocachingApi):
21+
"""Update and print"""
1422
status = await api.update()
1523
print(status.user.reference_code)
1624
for trackable in status.trackables.values():
1725
print('----------------------')
1826
print(f'Trackable code: {trackable.reference_code}')
1927
print(f'Trackable name: {trackable.name}')
28+
print(f'Trackable type: {trackable.trackable_type}')
2029
print(f'Kilometers traveled: {trackable.kilometers_traveled}km')
2130
print(f'Miles traveled: {trackable.miles_traveled}mi')
2231
print(f'Missing?: {trackable.is_missing}')
2332
if trackable.latest_journey:
24-
print(f'last log: {trackable.latest_journey.logged_date}')
33+
print(f'last journey: {trackable.latest_journey.logged_date}')
2534
print(f'latitude: {trackable.latest_journey.coordinates.latitude}')
2635
print(f'longitude: {trackable.latest_journey.coordinates.longitude}')
27-
await api.close()
36+
if trackable.latest_log:
37+
print(f'last log date: {trackable.latest_log.logged_date}')
38+
print(f'last log type: {trackable.latest_log.log_type}')
39+
print(f'last log username: {trackable.latest_log.owner.username}')
40+
print(f'last log text: {trackable.latest_log.text}')
41+
42+
2843
loop = asyncio.get_event_loop()
2944
loop.run_until_complete(test())
3045
loop.close()

0 commit comments

Comments
 (0)