2626from cryptography .hazmat .primitives .asymmetric import padding
2727from cryptography .hazmat .primitives .ciphers .aead import AESGCM
2828
29- from .helpers import b64_decode_padded , _pad_base64
30- from .exceptions import FmdApiException , AuthenticationError
31- from .models import PhotoResult , Location
29+ from .helpers import _pad_base64
30+ from .exceptions import FmdApiException
3231
3332# Constants copied from original module to ensure parity
3433CONTEXT_STRING_LOGIN = "context:loginAuthentication"
@@ -183,12 +182,18 @@ async def _make_api_request(self, method: str, endpoint: str, payload: Any,
183182 # Handle 401 -> re-authenticate once
184183 if resp .status == 401 and retry_auth and self ._fmd_id and self ._password :
185184 log .info ("Received 401 Unauthorized, re-authenticating..." )
186- await self .authenticate (self ._fmd_id , self ._password , self .session_duration )
185+ await self .authenticate (
186+ self ._fmd_id , self ._password , self .session_duration )
187187 payload ["IDT" ] = self .access_token
188- return await self ._make_api_request (method , endpoint , payload , stream , expect_json , retry_auth = False )
188+ return await self ._make_api_request (
189+ method , endpoint , payload , stream , expect_json ,
190+ retry_auth = False )
189191
190192 resp .raise_for_status ()
191- log .debug (f"{ endpoint } response - status: { resp .status } , content-type: { resp .content_type } , content-length: { resp .content_length } " )
193+ log .debug (
194+ f"{ endpoint } response - status: { resp .status } , "
195+ f"content-type: { resp .content_type } , "
196+ f"content-length: { resp .content_length } " )
192197
193198 if not stream :
194199 if expect_json :
@@ -223,13 +228,19 @@ async def _make_api_request(self, method: str, endpoint: str, payload: Any,
223228 # -------------------------
224229 # Location / picture access
225230 # -------------------------
226- async def get_locations (self , num_to_get : int = - 1 , skip_empty : bool = True , max_attempts : int = 10 ) -> List [str ]:
231+ async def get_locations (
232+ self , num_to_get : int = - 1 , skip_empty : bool = True ,
233+ max_attempts : int = 10 ) -> List [str ]:
227234 """
228235 Fetches all or the N most recent location blobs.
229236 Returns list of base64-encoded blobs (strings), same as original get_all_locations.
230237 """
231- log .debug (f"Getting locations, num_to_get={ num_to_get } , skip_empty={ skip_empty } " )
232- size_str = await self ._make_api_request ("PUT" , "/api/v1/locationDataSize" , {"IDT" : self .access_token , "Data" : "" })
238+ log .debug (
239+ f"Getting locations, num_to_get={ num_to_get } , "
240+ f"skip_empty={ skip_empty } " )
241+ size_str = await self ._make_api_request (
242+ "PUT" , "/api/v1/locationDataSize" ,
243+ {"IDT" : self .access_token , "Data" : "" })
233244 size = int (size_str )
234245 log .debug (f"Server reports { size } locations available" )
235246 if size == 0 :
@@ -242,7 +253,9 @@ async def get_locations(self, num_to_get: int = -1, skip_empty: bool = True, max
242253 indices = range (size )
243254 for i in indices :
244255 log .info (f" - Downloading location at index { i } ..." )
245- blob = await self ._make_api_request ("PUT" , "/api/v1/location" , {"IDT" : self .access_token , "Data" : str (i )})
256+ blob = await self ._make_api_request (
257+ "PUT" , "/api/v1/location" ,
258+ {"IDT" : self .access_token , "Data" : str (i )})
246259 locations .append (blob )
247260 return locations
248261 else :
@@ -251,8 +264,11 @@ async def get_locations(self, num_to_get: int = -1, skip_empty: bool = True, max
251264 start_index = size - 1
252265
253266 if skip_empty :
254- indices = range (start_index , max (- 1 , start_index - max_attempts ), - 1 )
255- log .info (f"Will search for { num_to_download } non-empty location(s) starting from index { start_index } " )
267+ indices = range (
268+ start_index , max (- 1 , start_index - max_attempts ), - 1 )
269+ log .info (
270+ f"Will search for { num_to_download } non-empty location(s) "
271+ f"starting from index { start_index } " )
256272 else :
257273 end_index = size - num_to_download
258274 indices = range (start_index , end_index - 1 , - 1 )
@@ -272,15 +288,19 @@ async def get_locations(self, num_to_get: int = -1, skip_empty: bool = True, max
272288 log .warning (f"Empty blob received for location index { i } , repr: { repr (blob [:50 ] if blob else blob )} " )
273289
274290 if not locations and num_to_get != - 1 :
275- log .warning (f"No valid locations found after checking { min (max_attempts , size )} indices" )
291+ log .warning (
292+ f"No valid locations found after checking "
293+ f"{ min (max_attempts , size )} indices" )
276294
277295 return locations
278296
279297 async def get_pictures (self , num_to_get : int = - 1 ) -> List [Any ]:
280298 """Fetches all or the N most recent picture metadata blobs (raw server response)."""
281299 try :
282300 await self ._ensure_session ()
283- async with self ._session .put (f"{ self .base_url } /api/v1/pictures" , json = {"IDT" : self .access_token , "Data" : "" }) as resp :
301+ async with self ._session .put (
302+ f"{ self .base_url } /api/v1/pictures" ,
303+ json = {"IDT" : self .access_token , "Data" : "" }) as resp :
284304 resp .raise_for_status ()
285305 json_data = await resp .json ()
286306 # Extract the Data field if it exists, otherwise use the response as-is
@@ -377,8 +397,6 @@ async def request_location(self, provider: str = "all") -> bool:
377397 log .info (f"Requesting location update with provider: { provider } (command: { command } )" )
378398 return await self .send_command (command )
379399
380-
381-
382400 async def set_bluetooth (self , enable : bool ) -> bool :
383401 """Set Bluetooth power explicitly: True = on, False = off."""
384402 command = "bluetooth on" if enable else "bluetooth off"
@@ -414,4 +432,4 @@ async def take_picture(self, camera: str = "back") -> bool:
414432 raise ValueError (f"Invalid camera '{ camera } '. Must be 'front' or 'back'" )
415433 command = "camera front" if camera == "front" else "camera back"
416434 log .info (f"Requesting picture from { camera } camera" )
417- return await self .send_command (command )
435+ return await self .send_command (command )
0 commit comments