python-terminusgps 1.5.6__py3-none-any.whl → 1.5.7__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-terminusgps
3
- Version: 1.5.6
3
+ Version: 1.5.7
4
4
  Summary: Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more.
5
5
  Project-URL: Documentation, https://app.terminusgps.com/docs/apps/python-terminusgps/index.html
6
6
  Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
@@ -15,5 +15,5 @@ Requires-Python: >=3.12
15
15
  Requires-Dist: argparse>=1.4.0
16
16
  Requires-Dist: authorizenet>=1.1.5
17
17
  Requires-Dist: boto3>=1.34.144
18
- Requires-Dist: django>=5.1.4
18
+ Requires-Dist: django>=5.1.5
19
19
  Requires-Dist: python-wialon>=1.2.4
@@ -6,19 +6,19 @@ terminusgps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  terminusgps/aws/secrets.py,sha256=kgRA77rs0mD4berWRLkPtJLOe4Grf--o5f8NzwQqXCk,360
7
7
  terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  terminusgps/wialon/constants.py,sha256=dsQaNt3TIjIZbr_m94KmBGFdrqe6HER2r6lol3X8QpU,2802
9
- terminusgps/wialon/errors.py,sha256=RbHwHuhW8P9L7i3jaPzcMO8ZHxX3Z3V970ypEtqnavw,1236
9
+ terminusgps/wialon/errors.py,sha256=SV9pVwU6FZ_zGlGP6zJN6aLE2auF4TfHFISQLiPMKrI,1758
10
10
  terminusgps/wialon/flags.py,sha256=-OoH-eZM54yjRqxsAXL8VImdQu_7C0OAxCrFqaCEuko,13510
11
- terminusgps/wialon/session.py,sha256=yEoOxRqL3dLIAAFAAgYu9K866QZzFiCDApZBQ8f0LTI,8740
11
+ terminusgps/wialon/session.py,sha256=x5aXxqLcBe4e0Zj3enUvWd1_Ufmd_MxXInC_d_GMn3E,9446
12
12
  terminusgps/wialon/utils.py,sha256=J8V2F-QDMsLD5x2OhCYI2lnZZdgqKboMve5XJD7Qt30,1877
13
13
  terminusgps/wialon/items/__init__.py,sha256=3BVthghekMvhMQSzQgBMlD_phxmKSmp3Zvmo-z0O8Bs,211
14
14
  terminusgps/wialon/items/base.py,sha256=MN4FG6U1nWkYAjNfXQJRVrWJoiW4Y64tyqxUO0mhv_w,6593
15
15
  terminusgps/wialon/items/resource.py,sha256=ADjGsQaCqD6Y3_AaD8vLgYzGaMK69MpxCZojnylS4GE,815
16
- terminusgps/wialon/items/retranslator.py,sha256=HkL_asa_4VTRDvl7e6I9rtUhF0PBV3HRmecgesneHUM,839
16
+ terminusgps/wialon/items/retranslator.py,sha256=zsQXqOhH1zFe5_e8DROPu60z3v6xPWOEPyMCi2IqJAo,3861
17
17
  terminusgps/wialon/items/route.py,sha256=qOHPN_rejwiGqvwWzlwmUIAIyc3lKavCalf8ki66rx0,760
18
18
  terminusgps/wialon/items/unit.py,sha256=tLAWPfHUUS6_Feh1aYBMFPgyuGlSiAnfumJJmGt3bKw,4662
19
19
  terminusgps/wialon/items/unit_group.py,sha256=1yc7ldPIgGbtiTj0djRDWmt6Q9K_VT9sxOaioasbbLY,5212
20
20
  terminusgps/wialon/items/user.py,sha256=bkcMw_YiocaMuhP_pBfB7apjAZwnsOzGScnGkn8Ybbw,6107
21
- python_terminusgps-1.5.6.dist-info/METADATA,sha256=-ydcnkpNZo3XBwK4pe9MCouyUryZqstT0lJa76zuuvY,882
22
- python_terminusgps-1.5.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
- python_terminusgps-1.5.6.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
24
- python_terminusgps-1.5.6.dist-info/RECORD,,
21
+ python_terminusgps-1.5.7.dist-info/METADATA,sha256=nY0ZeyVuZ4mUV82NrlzNEXNbLQ-kpDUJW8Y1vvFAAOM,882
22
+ python_terminusgps-1.5.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
+ python_terminusgps-1.5.7.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
24
+ python_terminusgps-1.5.7.dist-info/RECORD,,
@@ -2,34 +2,52 @@ from wialon.api import WialonError
2
2
 
3
3
 
4
4
  class WialonBaseError(Exception):
5
- def __init__(self, message: str, wialon_err: WialonError | None = None) -> None:
5
+ def __init__(
6
+ self, message: str, wialon_err: WialonError | AssertionError | None = None
7
+ ) -> None:
6
8
  self.wialon_err = wialon_err
7
- super().__init__(message)
9
+ return super().__init__(message)
8
10
 
9
11
 
10
12
  class WialonLoginError(WialonBaseError):
11
13
  def __init__(
12
- self, token: str | None, wialon_err: WialonError | None = None
14
+ self, token: str | None, wialon_err: WialonError | AssertionError | None = None
13
15
  ) -> None:
14
16
  message = f"Failed to login to the Wialon API using token: '{token}'\n"
15
17
  if wialon_err:
16
18
  message += str(wialon_err)
17
- super().__init__(message, wialon_err)
19
+ return super().__init__(message, wialon_err)
18
20
 
19
21
 
20
22
  class WialonSessionDuplicationError(WialonBaseError):
21
23
  def __init__(
22
- self, session_id: str | None, wialon_err: WialonError | None = None
24
+ self,
25
+ session_id: str | None,
26
+ wialon_err: WialonError | AssertionError | None = None,
23
27
  ) -> None:
24
28
  message = f"Failed to duplicate the Wialon session: '#{session_id}'\n"
25
29
  if wialon_err:
26
30
  message += str(wialon_err)
27
- super().__init__(message, wialon_err)
31
+ return super().__init__(message, wialon_err)
28
32
 
29
33
 
30
34
  class WialonLogoutError(WialonBaseError):
31
- def __init__(self, session_id: str, wialon_err: WialonError | None = None) -> None:
35
+ def __init__(
36
+ self, session_id: str, wialon_err: WialonError | AssertionError | None = None
37
+ ) -> None:
32
38
  message = f"Failed to logout of the Wialon API session: '{session_id}'\n"
33
39
  if wialon_err:
34
40
  message += str(wialon_err)
35
- super().__init__(message, wialon_err)
41
+ return super().__init__(message, wialon_err)
42
+
43
+
44
+ class WialonSessionInvalidError(WialonBaseError):
45
+ def __init__(
46
+ self,
47
+ session_id: str | None,
48
+ wialon_err: WialonError | AssertionError | None = None,
49
+ ) -> None:
50
+ message = f"The session was invalid/expired: '{session_id}'\n"
51
+ if wialon_err:
52
+ message += str(wialon_err)
53
+ return super().__init__(message, wialon_err)
@@ -4,6 +4,21 @@ from terminusgps.wialon.items.base import WialonBase
4
4
 
5
5
  class WialonRetranslator(WialonBase):
6
6
  def create(self, **kwargs) -> int | None:
7
+ """
8
+ Creates a Wialon retranslator.
9
+
10
+ :param creator_id: A Wialon user that will create the retranslator.
11
+ :type creator_id: :py:obj:`str`
12
+ :param name: A name for the new retranslator.
13
+ :type name: :py:obj:`str`
14
+ :param config: A Wialon retranslator configuration object.
15
+ :type config: :py:obj:`dict`
16
+ :raises ValueError: If a required parameter was not provided.
17
+ :raises WialonError: If something went wrong with Wialon.
18
+ :returns: Nothing.
19
+ :rtype: :py:obj:`None`
20
+
21
+ """
7
22
  if not kwargs.get("creator_id"):
8
23
  raise ValueError("'creator_id' is required on creation.")
9
24
  if not kwargs.get("name"):
@@ -20,3 +35,83 @@ class WialonRetranslator(WialonBase):
20
35
  }
21
36
  )
22
37
  return response.get("item", {}).get("id")
38
+
39
+ def update_config(self, new_config: dict) -> None:
40
+ """
41
+ Updates the retranslator config to the new config.
42
+
43
+ :param new_config: A Wialon retranslator configuration.
44
+ :type units: :py:obj:`dict`
45
+ :raises WialonError: If something went wrong with Wialon.
46
+ :returns: Nothing.
47
+ :rtype: :py:obj:`None`
48
+
49
+ """
50
+ self.session.wialon_api.retranslator_update_config(
51
+ **{"itemId": self.id, "config": new_config}
52
+ )
53
+
54
+ def add_units(self, units: list[WialonBase]) -> None:
55
+ """
56
+ Adds a list of units to the Wialon retranslator.
57
+
58
+ :param units: A list of Wialon unit objects.
59
+ :type units: :py:obj:`list`
60
+ :raises WialonError: If something went wrong with Wialon.
61
+ :returns: Nothing.
62
+ :rtype: :py:obj:`None`
63
+
64
+ """
65
+ self.session.wialon_api.retranslator_update_units(
66
+ **{
67
+ "itemId": self.id,
68
+ "units": [{"a": unit.id, "i": unit.hw_type} for unit in units],
69
+ "callMode": "add",
70
+ }
71
+ )
72
+
73
+ def rm_units(self, units: list[WialonBase]) -> None:
74
+ """
75
+
76
+ Naively removes a list of units from the Wialon retranslator.
77
+
78
+ :param units: A list of Wialon unit objects.
79
+ :type units: :py:obj:`list`
80
+ :raises WialonError: If something went wrong with Wialon.
81
+ :returns: Nothing.
82
+ :rtype: :py:obj:`None`
83
+
84
+ """
85
+ self.session.wialon_api.retranslator_update_units(
86
+ **{
87
+ "itemId": self.id,
88
+ "units": [{"a": unit.id, "i": unit.hw_type} for unit in units],
89
+ "callMode": "remove",
90
+ }
91
+ )
92
+
93
+ def start(self, stop: int | None = None) -> None:
94
+ """
95
+ Starts the Wialon retranslator.
96
+
97
+ :raises WialonError: If something went wrong with Wialon.
98
+ :returns: Nothing.
99
+ :rtype: :py:obj:`None`
100
+
101
+ """
102
+ self.session.wialon_api.retranslator_update_operating(
103
+ **{"itemId": self.id, "operate": int(True), "stopTime": stop}
104
+ )
105
+
106
+ def stop(self) -> None:
107
+ """
108
+ Stops the Wialon retranslator.
109
+
110
+ :raises WialonError: If something went wrong with Wialon.
111
+ :returns: Nothing.
112
+ :rtype: :py:obj:`None`
113
+
114
+ """
115
+ self.session.wialon_api.retranslator_update_operating(
116
+ **{"itemId": self.id, "operate": int(False)}
117
+ )
@@ -2,7 +2,12 @@ from wialon.api import Wialon, WialonError
2
2
  from django.conf import settings
3
3
  from django.core.exceptions import ImproperlyConfigured
4
4
 
5
- from .errors import WialonLogoutError, WialonLoginError, WialonSessionDuplicationError
5
+ from .errors import (
6
+ WialonLogoutError,
7
+ WialonLoginError,
8
+ WialonSessionDuplicationError,
9
+ WialonSessionInvalidError,
10
+ )
6
11
 
7
12
 
8
13
  class WialonSession:
@@ -32,7 +37,6 @@ class WialonSession:
32
37
  raise ImproperlyConfigured("'WIALON_ADMIN_ID' setting is required.")
33
38
 
34
39
  self.wialon_api = Wialon(scheme=scheme, host=host, port=port, sid=sid)
35
- self.active = bool(sid)
36
40
  self.token = token
37
41
  self._username = None
38
42
  self._gis_sid = None
@@ -48,6 +52,24 @@ class WialonSession:
48
52
  def __exit__(self, *args, **kwargs) -> None:
49
53
  self.logout()
50
54
 
55
+ @property
56
+ def active(self) -> bool:
57
+ """
58
+ Whether or not the Wialon session is currently active.
59
+
60
+ :type: :py:obj:`bool`
61
+ :value: :py:obj:`False`
62
+ """
63
+ is_active = False
64
+
65
+ try:
66
+ response = self.wialon_api.core_duplicate(**{"restore": 1})
67
+ is_active = bool(response)
68
+ except WialonError as e:
69
+ raise WialonSessionInvalidError(self.id, e)
70
+ finally:
71
+ return is_active
72
+
51
73
  @property
52
74
  def gis_geocode(self) -> str | None:
53
75
  """
@@ -198,32 +220,31 @@ class WialonSession:
198
220
  def token(self, value: str | None = None) -> None:
199
221
  self._token = value if value else settings.WIALON_TOKEN
200
222
 
201
- def duplicate(
202
- self, user_id: str | None = None, continue_session: bool = False
203
- ) -> None:
223
+ def duplicate(self, username: str | None = None, continued: bool = False) -> str:
204
224
  """
205
225
  Duplicates the active Wialon API session.
206
226
 
207
- :param user_id: A Wialon user to operate as in the session.
208
- :type user_id: :py:obj:`str` | :py:obj:`None`
227
+ :param username: A Wialon user to operate as in the session.
228
+ :type username: :py:obj:`str` | :py:obj:`None`
209
229
  :param continue_session: Whether or not the original session id should be valid after duplication.
210
230
  :type continue_session: :py:obj:`bool`
211
231
  :raises WialonSessionDuplicationError: If the Wialon session was not duplicated.
212
- :returns: Nothing.
213
- :rtype: :py:obj:`None`
232
+ :raises AssertionError: If the session was already active.
233
+ :returns: The new session id.
234
+ :rtype: :py:obj:`str`
214
235
 
215
236
  """
216
237
  try:
217
- login_response = self.wialon_api.core_duplicate(
218
- **{"operateAs": user_id, "continueCurrentSession": continue_session}
238
+ assert self.active, "Cannot duplicate an inactive session."
239
+ response = self.wialon_api.core_duplicate(
240
+ **{"operateAs": username, "continueCurrentSession": continued}
219
241
  )
220
- except WialonError as e:
242
+ self._set_login_response(response)
243
+ return response.get("eid")
244
+ except (WialonError, AssertionError) as e:
221
245
  raise WialonSessionDuplicationError(self.id, e)
222
- else:
223
- self._set_login_response(login_response)
224
- self.active = True
225
246
 
226
- def login(self, token: str, flags: int = sum([0x1, 0x2, 0x20])) -> None:
247
+ def login(self, token: str, flags: int = sum([0x1, 0x2, 0x20])) -> str:
227
248
  """
228
249
  Logs into the Wialon API and starts a new session.
229
250
 
@@ -235,18 +256,17 @@ class WialonSession:
235
256
  :type flags: :py:obj:`int`
236
257
  :raises WialonLoginError: If the login fails.
237
258
  :raises AssertionError: If the session was already active.
238
- :returns: Nothing.
239
- :rtype: :py:obj:`None`
259
+ :returns: The new session id.
260
+ :rtype: :py:obj:`str`
240
261
 
241
262
  """
242
- assert not self.active, "Cannot login to an active session."
243
263
  try:
264
+ assert not self.active, "Cannot login to an active session."
244
265
  response = self.wialon_api.token_login(**{"token": token, "fl": flags})
245
- except WialonError as e:
246
- raise WialonLoginError(token, e)
247
- else:
248
266
  self._set_login_response(response)
249
- self.active = True
267
+ return response.get("eid")
268
+ except (WialonError, AssertionError) as e:
269
+ raise WialonLoginError(token, e)
250
270
 
251
271
  def logout(self) -> None:
252
272
  """
@@ -265,7 +285,7 @@ class WialonSession:
265
285
  """
266
286
  Sets the Wialon API session's attributes based on a login response.
267
287
 
268
- :param login_response: A Wialon API response to :py:meth:`login`.
288
+ :param login_response: A response returned from :py:meth:`login` or :py:meth:`duplicate`.
269
289
  :type login_response: :py:obj:`dict`
270
290
  :returns: Nothing.
271
291
  :rtype: :py:obj:`None`
@@ -289,8 +309,8 @@ class WialonSession:
289
309
 
290
310
  def main() -> None:
291
311
  session = WialonSession()
292
- session.login(settings.WIALON_TOKEN)
293
- session.duplicate(user_id="28944309")
312
+ session.login(token=settings.WIALON_TOKEN)
313
+ session.duplicate(username="chrissyron@gmail.com", continued=False)
294
314
  session.logout()
295
315
  return
296
316