flet-geolocator 0.1.0.dev1__py3-none-any.whl → 0.2.0.dev30__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of flet-geolocator might be problematic. Click here for more details.

@@ -1,12 +1,13 @@
1
- from flet_geolocator.geolocator import (
2
- Geolocator,
3
- GeolocatorActivityType,
4
- GeolocatorAndroidSettings,
5
- GeolocatorAppleSettings,
1
+ from .geolocator import Geolocator
2
+ from .types import (
3
+ ForegroundNotificationConfiguration,
4
+ GeolocatorAndroidConfiguration,
5
+ GeolocatorConfiguration,
6
+ GeolocatorIosActivityType,
7
+ GeolocatorIosConfiguration,
6
8
  GeolocatorPermissionStatus,
7
9
  GeolocatorPosition,
8
10
  GeolocatorPositionAccuracy,
9
11
  GeolocatorPositionChangeEvent,
10
- GeolocatorSettings,
11
- GeolocatorWebSettings,
12
+ GeolocatorWebConfiguration,
12
13
  )
@@ -1,340 +1,238 @@
1
- import json
2
- from dataclasses import dataclass
3
- from enum import Enum
4
- from typing import Any, Optional
5
-
6
- from flet.core.control import Control
7
- from flet.core.control_event import ControlEvent
8
- from flet.core.event_handler import EventHandler
9
- from flet.core.ref import Ref
10
- from flet.core.types import (
11
- ColorValue,
12
- DurationValue,
13
- OptionalControlEventCallable,
14
- OptionalEventCallable,
15
- OptionalNumber,
1
+ import asyncio
2
+ from dataclasses import field
3
+ from typing import Optional
4
+
5
+ import flet as ft
6
+
7
+ from .types import (
8
+ GeolocatorConfiguration,
9
+ GeolocatorPermissionStatus,
10
+ GeolocatorPosition,
11
+ GeolocatorPositionChangeEvent,
16
12
  )
17
13
 
14
+ __all__ = ["Geolocator"]
18
15
 
19
- class GeolocatorPositionAccuracy(Enum):
20
- LOWEST = "lowest"
21
- LOW = "low"
22
- MEDIUM = "medium"
23
- HIGH = "high"
24
- BEST = "best"
25
- BEST_FOR_NAVIGATION = "bestForNavigation"
26
- REDUCED = "reduced"
27
-
28
-
29
- class GeolocatorPermissionStatus(Enum):
30
- DENIED = "denied"
31
- DENIED_FOREVER = "deniedForever"
32
- WHILE_IN_USE = "whileInUse"
33
- ALWAYS = "always"
34
- UNABLE_TO_DETERMINE = "unableToDetermine"
35
-
36
-
37
- class GeolocatorActivityType(Enum):
38
- AUTOMOTIVE_NAVIGATION = "automotiveNavigation"
39
- FITNESS = "fitness"
40
- OTHER_NAVIGATION = "otherNavigation"
41
- AIRBORNE = "airborne"
42
- OTHER = "other"
43
-
44
-
45
- @dataclass
46
- class GeolocatorPosition:
47
- latitude: OptionalNumber = None
48
- longitude: OptionalNumber = None
49
- speed: OptionalNumber = None
50
- altitude: OptionalNumber = None
51
- timestamp: OptionalNumber = None
52
- accuracy: OptionalNumber = None
53
- altitude_accuracy: OptionalNumber = None
54
- heading: OptionalNumber = None
55
- heading_accuracy: OptionalNumber = None
56
- speed_accuracy: OptionalNumber = None
57
- floor: Optional[int] = None
58
- is_mocked: Optional[bool] = None
59
-
60
-
61
- @dataclass
62
- class GeolocatorSettings:
63
- accuracy: Optional[GeolocatorPositionAccuracy] = None
64
- distance_filter: Optional[int] = None
65
- time_limit: DurationValue = None
66
-
67
-
68
- @dataclass
69
- class GeolocatorWebSettings(GeolocatorSettings):
70
- maximum_age: DurationValue = None
71
-
72
-
73
- @dataclass
74
- class GeolocatorAppleSettings(GeolocatorSettings):
75
- activity_type: Optional[GeolocatorActivityType] = None
76
- pause_location_updates_automatically: Optional[bool] = False
77
- show_background_location_indicator: Optional[bool] = False
78
- allow_background_location_updates: Optional[bool] = True
79
-
80
-
81
- @dataclass
82
- class GeolocatorAndroidSettings(GeolocatorSettings):
83
- force_location_manager: Optional[bool] = False
84
- interval_duration: DurationValue = False
85
- foreground_notification_text: Optional[str] = None
86
- foreground_notification_title: Optional[str] = None
87
- foreground_notification_channel_name: Optional[str] = "Background Location"
88
- foreground_notification_enable_wake_lock: Optional[bool] = False
89
- foreground_notification_enable_wifi_lock: Optional[bool] = False
90
- foreground_notification_set_ongoing: Optional[bool] = False
91
- foreground_notification_color: Optional[ColorValue] = None
92
-
93
-
94
- class GeolocatorPositionChangeEvent(ControlEvent):
95
- def __init__(self, e: ControlEvent):
96
- super().__init__(e.target, e.name, e.data, e.control, e.page)
97
- d = json.loads(e.data)
98
- self.latitude: float = d.get("lat")
99
- self.longitude: float = d.get("long")
100
-
101
-
102
- class Geolocator(Control):
16
+
17
+ @ft.control("Geolocator")
18
+ class Geolocator(ft.Service):
103
19
  """
104
20
  A control that allows you to fetch GPS data from your device.
21
+
105
22
  This control is non-visual and should be added to `page.overlay` list.
23
+ """
106
24
 
107
- -----
25
+ configuration: Optional[GeolocatorConfiguration] = None
26
+ """
27
+ Some additional configuration.
28
+ """
108
29
 
109
- Online docs: https://flet.dev/docs/controls/geolocator
30
+ on_position_change: ft.OptionalEventHandler[
31
+ GeolocatorPositionChangeEvent["Geolocator"]
32
+ ] = None
110
33
  """
34
+ Fires when the position of the device changes.
111
35
 
112
- def __init__(
113
- self,
114
- # Control
115
- #
116
- ref: Optional[Ref] = None,
117
- data: Any = None,
118
- location_settings: Optional[GeolocatorSettings] = None,
119
- on_position_change: OptionalEventCallable[GeolocatorPositionChangeEvent] = None,
120
- on_error: OptionalControlEventCallable = None,
121
- ):
122
- Control.__init__(
123
- self,
124
- ref=ref,
125
- data=data,
126
- )
127
- self.__on_position_change = EventHandler(
128
- lambda e: GeolocatorPositionChangeEvent(e)
129
- )
130
- self._add_event_handler(
131
- "positionChange", self.__on_position_change.get_handler()
132
- )
133
- self.on_position_change = on_position_change
134
- self.on_error = on_error
135
- self.location_settings = location_settings
36
+ Event handler argument is of type [`GeolocatorPositionChangeEvent`][(p).].
37
+ """
136
38
 
137
- def _get_control_name(self):
138
- return "geolocator"
39
+ on_error: ft.OptionalControlEventHandler["Geolocator"] = None
40
+ """
41
+ Fires when an error occurs.
42
+
43
+ The `data` property of the event handler argument contains information on the error.
44
+ """
139
45
 
140
- def before_update(self):
141
- self._set_attr_json("locationSettings", self.location_settings)
46
+ position: Optional[GeolocatorPosition] = field(default=None, init=False) # todo: make this property readonly
47
+ """
48
+ The current position of the device. (read-only)
142
49
 
143
- def get_current_position(
144
- self,
145
- accuracy: Optional[
146
- GeolocatorPositionAccuracy
147
- ] = GeolocatorPositionAccuracy.BEST,
148
- location_settings: Optional[GeolocatorSettings] = None,
149
- wait_timeout: Optional[float] = 25,
150
- ) -> GeolocatorPosition:
151
- ls = (
152
- location_settings
153
- or self.location_settings
154
- or GeolocatorSettings(accuracy=accuracy)
155
- )
156
- output = self.invoke_method(
157
- "get_current_position",
158
- {"location_settings": self._convert_attr_json(ls)},
159
- wait_for_result=True,
160
- wait_timeout=wait_timeout,
161
- )
162
- return (
163
- GeolocatorPosition(**json.loads(output))
164
- if output is not None
165
- else GeolocatorPosition()
166
- )
50
+ Starts as `None` and will be updated when the position changes.
51
+ """
167
52
 
168
53
  async def get_current_position_async(
169
54
  self,
170
- accuracy: Optional[
171
- GeolocatorPositionAccuracy
172
- ] = GeolocatorPositionAccuracy.BEST,
173
- location_settings: Optional[GeolocatorSettings] = None,
174
- wait_timeout: Optional[float] = 25,
55
+ configuration: Optional[GeolocatorConfiguration] = None,
56
+ timeout: float = 30,
175
57
  ) -> GeolocatorPosition:
176
- ls = (
177
- location_settings
178
- or self.location_settings
179
- or GeolocatorSettings(accuracy=accuracy)
180
- )
181
- output = await self.invoke_method_async(
182
- "get_current_position",
183
- {"location_settings": self._convert_attr_json(ls)},
184
- wait_for_result=True,
185
- wait_timeout=wait_timeout,
186
- )
187
- return (
188
- GeolocatorPosition(**json.loads(output))
189
- if output is not None
190
- else GeolocatorPosition()
191
- )
192
-
193
- def get_last_known_position(
194
- self,
195
- wait_timeout: Optional[float] = 25,
196
- ) -> GeolocatorPosition:
197
- assert not self.page.web, "get_last_known_position is not supported on web"
198
- output = self.invoke_method(
199
- "get_last_known_position",
200
- wait_for_result=True,
201
- wait_timeout=wait_timeout,
202
- )
203
- return (
204
- GeolocatorPosition(**json.loads(output))
205
- if output is not None
206
- else GeolocatorPosition()
207
- )
58
+ """
59
+ Gets the current position of the device with the desired accuracy and settings.
60
+
61
+ Args:
62
+ configuration: Additional configuration for the location request.
63
+ If not specified, then the [`Geolocator.configuration`][(p).] property is used.
64
+ timeout: The maximum amount of time (in seconds) to wait for a response.
65
+ Returns:
66
+ The current position of the device as a [`GeolocatorPosition`][(p).].
67
+ Raises:
68
+ TimeoutError: If the request times out.
69
+
70
+ Note:
71
+ Depending on the availability of different location services, this can take several seconds.
72
+ It is recommended to call the [`get_last_known_position`][..] method first to receive a
73
+ known/cached position and update it with the result of the [`get_current_position`][..] method.
74
+ """
75
+ r = await self._invoke_method_async(
76
+ method_name="get_current_position",
77
+ arguments={"configuration": configuration or self.configuration},
78
+ timeout=timeout,
79
+ )
80
+ return GeolocatorPosition(**r)
208
81
 
209
82
  async def get_last_known_position_async(
210
- self,
211
- wait_timeout: Optional[float] = 25,
83
+ self, timeout: float = 10
212
84
  ) -> GeolocatorPosition:
85
+ """
86
+ Gets the last known position stored on the user's device.
87
+ The accuracy can be defined using the [`Geolocator.configuration`][(p).] property.
88
+
89
+ Note:
90
+ This method is not supported on web plaform.
91
+
92
+ Args:
93
+ timeout: The maximum amount of time (in seconds) to wait for a response.
94
+ Returns:
95
+ `True` if the app's settings were opened successfully, `False` otherwise.
96
+ Raises:
97
+ AssertionError: If invoked on a web platform.
98
+ TimeoutError: If the request times out.
99
+ """
213
100
  assert not self.page.web, "get_last_known_position is not supported on web"
214
- output = await self.invoke_method_async(
215
- "get_last_known_position",
216
- wait_for_result=True,
217
- wait_timeout=wait_timeout,
218
- )
219
- return (
220
- GeolocatorPosition(**json.loads(output))
221
- if output is not None
222
- else GeolocatorPosition()
223
- )
224
-
225
- def get_permission_status(
226
- self, wait_timeout: Optional[float] = 25
227
- ) -> GeolocatorPermissionStatus:
228
- p = self.invoke_method(
229
- "get_permission_status",
230
- wait_for_result=True,
231
- wait_timeout=wait_timeout,
232
- )
233
- return GeolocatorPermissionStatus(p)
101
+ r = await self._invoke_method_async("get_last_known_position", timeout=timeout)
102
+ return GeolocatorPosition(**r)
234
103
 
235
104
  async def get_permission_status_async(
236
- self, wait_timeout: Optional[float] = 25
105
+ self, timeout: float = 10
237
106
  ) -> GeolocatorPermissionStatus:
238
- p = await self.invoke_method_async(
239
- "get_permission_status",
240
- wait_for_result=True,
241
- wait_timeout=wait_timeout,
242
- )
243
- return GeolocatorPermissionStatus(p)
244
-
245
- def request_permission(
246
- self, wait_timeout: Optional[float] = 25
247
- ) -> GeolocatorPermissionStatus:
248
- p = self.invoke_method(
249
- "request_permission",
250
- wait_for_result=True,
251
- wait_timeout=wait_timeout,
252
- )
253
- return GeolocatorPermissionStatus(p)
107
+ """
108
+ Gets which permission the app has been granted to access the device's location.
109
+
110
+ Args:
111
+ timeout: The maximum amount of time (in seconds) to wait for a response.
112
+ Returns:
113
+ The status of the permission.
114
+ Raises:
115
+ TimeoutError: If the request times out.
116
+ """
117
+ r = await self._invoke_method_async("get_permission_status", timeout=timeout)
118
+ return GeolocatorPermissionStatus(r)
254
119
 
255
120
  async def request_permission_async(
256
- self, wait_timeout: Optional[float] = 25
121
+ self, timeout: int = 60
257
122
  ) -> GeolocatorPermissionStatus:
258
- p = await self.invoke_method_async(
259
- "request_permission",
260
- wait_for_result=True,
261
- wait_timeout=wait_timeout,
262
- )
263
- return GeolocatorPermissionStatus(p)
264
-
265
- def is_location_service_enabled(self, wait_timeout: Optional[float] = 10) -> bool:
266
- enabled = self.invoke_method(
267
- "is_location_service_enabled",
268
- wait_for_result=True,
269
- wait_timeout=wait_timeout,
270
- )
271
- return enabled == "true"
272
-
273
- async def is_location_service_enabled_async(
274
- self, wait_timeout: Optional[float] = 10
275
- ) -> bool:
276
- enabled = await self.invoke_method_async(
277
- "is_location_service_enabled",
278
- wait_for_result=True,
279
- wait_timeout=wait_timeout,
280
- )
281
- return enabled == "true"
282
-
283
- def open_app_settings(self, wait_timeout: Optional[float] = 10) -> bool:
284
- assert not self.page.web, "open_app_settings is not supported on web"
285
- opened = self.invoke_method(
286
- "open_app_settings",
287
- wait_for_result=True,
288
- wait_timeout=wait_timeout,
289
- )
290
- return opened == "true"
291
-
292
- async def open_app_settings_async(self, wait_timeout: Optional[float] = 10) -> bool:
123
+ """
124
+ Requests the device for access to the device's location.
125
+
126
+ Args:
127
+ timeout: The maximum amount of time (in seconds) to wait for a response.
128
+ Returns:
129
+ The status of the permission request.
130
+ Raises:
131
+ TimeoutError: If the request times out.
132
+ """
133
+ r = await self._invoke_method_async("request_permission", timeout=timeout)
134
+ return GeolocatorPermissionStatus(r)
135
+
136
+ async def is_location_service_enabled_async(self, timeout: float = 10) -> bool:
137
+ """
138
+ Checks if location service is enabled.
139
+
140
+ Args:
141
+ timeout: The maximum amount of time (in seconds) to wait for a response.
142
+ Returns:
143
+ `True` if location service is enabled, `False` otherwise.
144
+ Raises:
145
+ TimeoutError: If the request times out.
146
+ """
147
+ return await self._invoke_method_async(
148
+ "is_location_service_enabled", timeout=timeout
149
+ )
150
+
151
+ async def open_app_settings_async(self, timeout: float = 10) -> bool:
152
+ """
153
+ Attempts to open the app's settings.
154
+
155
+ Note:
156
+ This method is not supported on web plaform.
157
+
158
+ Args:
159
+ timeout: The maximum amount of time (in seconds) to wait for a response.
160
+ Returns:
161
+ `True` if the app's settings were opened successfully, `False` otherwise.
162
+ Raises:
163
+ AssertionError: If invoked on a web platform.
164
+ TimeoutError: If the request times out.
165
+ """
293
166
  assert not self.page.web, "open_app_settings is not supported on web"
294
- opened = await self.invoke_method_async(
295
- "open_app_settings",
296
- wait_for_result=True,
297
- wait_timeout=wait_timeout,
298
- )
299
- return opened == "true"
300
-
301
- def open_location_settings(self, wait_timeout: Optional[float] = 10) -> bool:
302
- assert not self.page.web, "open_location_settings is not supported on web"
303
- opened = self.invoke_method(
304
- "open_location_settings",
305
- wait_for_result=True,
306
- wait_timeout=wait_timeout,
307
- )
308
- return opened == "true"
309
-
310
- async def open_location_settings_async(
311
- self, wait_timeout: Optional[float] = 10
312
- ) -> bool:
167
+ return await self._invoke_method_async("open_app_settings", timeout=timeout)
168
+
169
+ def open_location_settings(self, timeout: float = 10):
170
+ """
171
+ Attempts to open the device's location settings.
172
+
173
+ Note:
174
+ This method is not supported on web plaform.
175
+
176
+ Args:
177
+ timeout: The maximum amount of time (in seconds) to wait for a response.
178
+ Returns:
179
+ `True` if the device's settings were opened successfully, `False` otherwise.
180
+ Raises:
181
+ AssertionError: If invoked on a web platform.
182
+ TimeoutError: If the request times out.
183
+ """
184
+ asyncio.create_task(self.open_location_settings_async(timeout=timeout))
185
+
186
+ async def open_location_settings_async(self, timeout: float = 10):
187
+ """
188
+ Attempts to open the device's location settings.
189
+
190
+ Note:
191
+ This method is not supported on web plaform.
192
+
193
+ Args:
194
+ timeout: The maximum amount of time (in seconds) to wait for a response.
195
+ Returns:
196
+ `True` if the device's settings were opened successfully, `False` otherwise.
197
+ Raises:
198
+ AssertionError: If invoked on a web platform.
199
+ TimeoutError: If the request times out.
200
+ """
313
201
  assert not self.page.web, "open_location_settings is not supported on web"
314
- opened = await self.invoke_method_async(
315
- "open_location_settings",
316
- wait_for_result=True,
317
- wait_timeout=wait_timeout,
318
- )
319
- return opened == "true"
202
+ await self._invoke_method_async("open_location_settings", timeout=timeout)
320
203
 
321
- @property
322
- def on_position_change(
204
+ async def distance_between_async(
323
205
  self,
324
- ) -> OptionalEventCallable[GeolocatorPositionChangeEvent]:
325
- return self.__on_position_change.handler
326
-
327
- @on_position_change.setter
328
- def on_position_change(
329
- self, handler: OptionalEventCallable[GeolocatorPositionChangeEvent]
206
+ start_latitude: ft.Number,
207
+ start_longitude: ft.Number,
208
+ end_latitude: ft.Number,
209
+ end_longitude: ft.Number,
210
+ timeout: float = 10,
330
211
  ):
331
- self.__on_position_change.handler = handler
332
- self._set_attr("onPositionChange", True if handler is not None else None)
333
-
334
- @property
335
- def on_error(self) -> OptionalControlEventCallable:
336
- return self._get_attr("error")
337
-
338
- @on_error.setter
339
- def on_error(self, handler: OptionalControlEventCallable):
340
- self._add_event_handler("error", handler)
212
+ """
213
+ Calculates the distance between the supplied coordinates in meters.
214
+
215
+ The distance between the coordinates is calculated using the
216
+ Haversine formula (see https://en.wikipedia.org/wiki/Haversine_formula).
217
+
218
+ Args:
219
+ start_latitude: The latitude of the starting point, in degrees.
220
+ start_longitude: The longitude of the starting point, in degrees.
221
+ end_latitude: The latitude of the ending point, in degrees.
222
+ end_longitude: The longitude of the ending point, in degrees.
223
+ timeout: The maximum amount of time (in seconds) to wait for a response.
224
+ Returns:
225
+ The distance between the coordinates in meters.
226
+ Raises:
227
+ TimeoutError: If the request times out.
228
+ """
229
+ await self._invoke_method_async(
230
+ method_name="distance_between",
231
+ arguments={
232
+ "start_latitude": start_latitude,
233
+ "start_longitude": start_longitude,
234
+ "end_latitude": end_latitude,
235
+ "end_longitude": end_longitude,
236
+ },
237
+ timeout=timeout,
238
+ )