python-terminusgps 1.5.2__py3-none-any.whl → 1.5.5__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.2
3
+ Version: 1.5.5
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
@@ -1,13 +1,14 @@
1
1
  terminusgps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ terminusgps/settings.py,sha256=CIWif9AJYXk5nE-9Mqmqkeoum6-ON5MTuh0WJilgv3E,185
2
3
  terminusgps/authorizenet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
4
  terminusgps/authorizenet/auth.py,sha256=zITSQMH8F-3vw-lDQRbuR2s9AVlGqbOyyFo0zqU00qU,870
4
5
  terminusgps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
6
  terminusgps/aws/secrets.py,sha256=kgRA77rs0mD4berWRLkPtJLOe4Grf--o5f8NzwQqXCk,360
6
7
  terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
8
  terminusgps/wialon/constants.py,sha256=dsQaNt3TIjIZbr_m94KmBGFdrqe6HER2r6lol3X8QpU,2802
8
- terminusgps/wialon/errors.py,sha256=AFnu6RHPFlJ6x3zAC-iKn4x_8PyUgheY2IOSEv02Sp4,880
9
+ terminusgps/wialon/errors.py,sha256=RbHwHuhW8P9L7i3jaPzcMO8ZHxX3Z3V970ypEtqnavw,1236
9
10
  terminusgps/wialon/flags.py,sha256=-OoH-eZM54yjRqxsAXL8VImdQu_7C0OAxCrFqaCEuko,13510
10
- terminusgps/wialon/session.py,sha256=d-ym6TVXqFOQK-G1EPHr8r9XUr0qg8vwx-m5KUIt9co,2570
11
+ terminusgps/wialon/session.py,sha256=TqUI6k1BOUqDU-KhqAkVmEN3-E03tbHjLRIEtR44UOM,8795
11
12
  terminusgps/wialon/utils.py,sha256=J8V2F-QDMsLD5x2OhCYI2lnZZdgqKboMve5XJD7Qt30,1877
12
13
  terminusgps/wialon/items/__init__.py,sha256=3BVthghekMvhMQSzQgBMlD_phxmKSmp3Zvmo-z0O8Bs,211
13
14
  terminusgps/wialon/items/base.py,sha256=MN4FG6U1nWkYAjNfXQJRVrWJoiW4Y64tyqxUO0mhv_w,6593
@@ -17,7 +18,7 @@ terminusgps/wialon/items/route.py,sha256=qOHPN_rejwiGqvwWzlwmUIAIyc3lKavCalf8ki6
17
18
  terminusgps/wialon/items/unit.py,sha256=tLAWPfHUUS6_Feh1aYBMFPgyuGlSiAnfumJJmGt3bKw,4662
18
19
  terminusgps/wialon/items/unit_group.py,sha256=1yc7ldPIgGbtiTj0djRDWmt6Q9K_VT9sxOaioasbbLY,5212
19
20
  terminusgps/wialon/items/user.py,sha256=bkcMw_YiocaMuhP_pBfB7apjAZwnsOzGScnGkn8Ybbw,6107
20
- python_terminusgps-1.5.2.dist-info/METADATA,sha256=R8eIQov81lvkL9CsAVgsCy36IHKtsfCVcMyji65qA9U,882
21
- python_terminusgps-1.5.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
22
- python_terminusgps-1.5.2.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
23
- python_terminusgps-1.5.2.dist-info/RECORD,,
21
+ python_terminusgps-1.5.5.dist-info/METADATA,sha256=R7GHQv_EnEXS0U6emZXYn73-lpVfsRmZf7QyHKN-_CU,882
22
+ python_terminusgps-1.5.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
+ python_terminusgps-1.5.5.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
24
+ python_terminusgps-1.5.5.dist-info/RECORD,,
@@ -0,0 +1,6 @@
1
+ from os import getenv
2
+
3
+ DEBUG = False
4
+ SECRET_KEY = "xem*6no%8d9%^qzt2f3x3ar-uq4_+7h9myc$t0!+4%bj5us6f)"
5
+ WIALON_ADMIN_ID = getenv("WIALON_ADMIN_ID")
6
+ WIALON_TOKEN = getenv("WIALON_TOKEN")
@@ -11,7 +11,17 @@ class WialonLoginError(WialonBaseError):
11
11
  def __init__(
12
12
  self, token: str | None, wialon_err: WialonError | None = None
13
13
  ) -> None:
14
- message = f"Failed to login to the Wialon API using token: '{token}'"
14
+ message = f"Failed to login to the Wialon API using token: '{token}'\n"
15
+ if wialon_err:
16
+ message += str(wialon_err)
17
+ super().__init__(message, wialon_err)
18
+
19
+
20
+ class WialonSessionDuplicationError(WialonBaseError):
21
+ def __init__(
22
+ self, session_id: str | None, wialon_err: WialonError | None = None
23
+ ) -> None:
24
+ message = f"Failed to duplicate the Wialon session: '#{session_id}'\n"
15
25
  if wialon_err:
16
26
  message += str(wialon_err)
17
27
  super().__init__(message, wialon_err)
@@ -19,7 +29,7 @@ class WialonLoginError(WialonBaseError):
19
29
 
20
30
  class WialonLogoutError(WialonBaseError):
21
31
  def __init__(self, session_id: str, wialon_err: WialonError | None = None) -> None:
22
- message = f"Failed to logout of the Wialon API session: '{session_id}'"
32
+ message = f"Failed to logout of the Wialon API session: '{session_id}'\n"
23
33
  if wialon_err:
24
34
  message += str(wialon_err)
25
35
  super().__init__(message, wialon_err)
@@ -1,69 +1,301 @@
1
1
  from wialon.api import Wialon, WialonError
2
+ from pprint import pprint
2
3
  from django.conf import settings
3
4
  from django.core.exceptions import ImproperlyConfigured
4
5
 
5
- from .errors import WialonLogoutError, WialonLoginError
6
+ from .errors import WialonLogoutError, WialonLoginError, WialonSessionDuplicationError
6
7
 
7
8
 
8
9
  class WialonSession:
9
- def __init__(self, token: str | None = None, sid: str | None = None) -> None:
10
+ def __init__(
11
+ self,
12
+ token: str | None = None,
13
+ sid: str | None = None,
14
+ scheme: str = "https",
15
+ host: str = "hst-api.wialon.com",
16
+ port: int = 443,
17
+ ) -> None:
18
+ """
19
+ Starts or continues a Wialon API session.
20
+
21
+ :param token: An optional Wialon API token. Default is :confval:`WIALON_TOKEN`.
22
+ :type token: :py:obj:`str` | :py:obj:`None`
23
+ :param sid: An optional Wialon API session id. If provided, the session is continued.
24
+ :type sid: :py:obj:`str` | :py:obj:`None`
25
+ :raises ImproperlyConfigured: If either :confval:`WIALON_TOKEN` or :confval:`WIALON_ADMIN_ID` is not set.
26
+ :returns: Nothing.
27
+ :rtype: :py:obj:`None`
28
+
29
+ """
10
30
  if not hasattr(settings, "WIALON_TOKEN"):
11
31
  raise ImproperlyConfigured("'WIALON_TOKEN' setting is required.")
32
+ if not hasattr(settings, "WIALON_ADMIN_ID"):
33
+ raise ImproperlyConfigured("'WIALON_ADMIN_ID' setting is required.")
12
34
 
35
+ self.wialon_api = Wialon(scheme=scheme, host=host, port=port, sid=sid)
36
+ self.active = bool(sid)
13
37
  self.token = token
14
- self.wialon_api = Wialon(
15
- scheme="https", host="hst-api.wialon.com", port=443, sid=sid
16
- )
38
+ self._username = None
39
+ self._gis_sid = None
40
+ self._hw_gp_ip = None
41
+ self._wsdk_version = None
42
+ self._uid = None
43
+
44
+ def __enter__(self) -> "WialonSession":
45
+ assert self.token, "Wialon API token was not set"
46
+ self.login(self.token)
47
+ return self
48
+
49
+ def __exit__(self, *args, **kwargs) -> None:
50
+ self.logout()
51
+
52
+ @property
53
+ def gis_geocode(self) -> str | None:
54
+ """
55
+ Gis geocode URL.
56
+
57
+ :type: :py:obj:`str` | :py:obj:`None`
58
+ :value: :py:obj:`None`
59
+
60
+ """
61
+ return self._gis_geocode
62
+
63
+ @property
64
+ def gis_render(self) -> str | None:
65
+ """
66
+ Gis rendering URL.
67
+
68
+ :type: :py:obj:`str` | :py:obj:`None`
69
+ :value: :py:obj:`None`
70
+
71
+ """
72
+ return self._gis_render
73
+
74
+ @property
75
+ def gis_routing(self) -> str | None:
76
+ """
77
+ Gis routing URL.
78
+
79
+ :type: :py:obj:`str` | :py:obj:`None`
80
+ :value: :py:obj:`None`
81
+
82
+ """
83
+ return self._gis_routing
84
+
85
+ @property
86
+ def gis_search(self) -> str | None:
87
+ """
88
+ Gis search URL.
89
+
90
+ :type: :py:obj:`str` | :py:obj:`None`
91
+ :value: :py:obj:`None`
92
+
93
+ """
94
+ return self._gis_search
95
+
96
+ @property
97
+ def gis_sid(self) -> str | None:
98
+ """
99
+ Gis session id.
100
+
101
+ :type: :py:obj:`str` | :py:obj:`None`
102
+ :value: :py:obj:`None`
103
+
104
+ """
105
+ return self._gis_sid
106
+
107
+ @property
108
+ def host(self) -> str | None:
109
+ """
110
+ IP of the client hosting the Wialon session.
111
+
112
+ :type: :py:obj:`str` | :py:obj:`None`
113
+ :value: :py:obj:`None`
114
+
115
+ """
116
+ return self._host
117
+
118
+ @property
119
+ def hw_gw_ip(self) -> str | None:
120
+ """
121
+ Hardware gateway IP.
122
+
123
+ :type: :py:obj:`str` | :py:obj:`None`
124
+ :value: :py:obj:`None`
125
+
126
+ """
127
+ return self._hw_gw_ip
128
+
129
+ @property
130
+ def hw_gw_dns(self) -> str | None:
131
+ """
132
+ Hardware gateway domain name, should evaluate to :py:attr:`hw_gw_ip` if present.
133
+
134
+ :type: :py:obj:`str` | :py:obj:`None`
135
+ :value: :py:obj:`None`
136
+
137
+ """
138
+ return self._hw_gw_dns
139
+
140
+ @property
141
+ def wsdk_version(self) -> str | None:
142
+ """
143
+ The Wialon Source Developer Kit (WSDK) version number of the session.
144
+
145
+ :type: :py:obj:`str` | :py:obj:`None`
146
+ :value: :py:obj:`None`
147
+
148
+ """
149
+ return self._wsdk_version
150
+
151
+ @property
152
+ def uid(self) -> str | None:
153
+ """
154
+ A Wialon user ID this session is operating as.
155
+
156
+ :type: :py:obj:`str` | :py:obj:`None`
157
+ :value: :py:obj:`None`
158
+ """
159
+ return self._uid
160
+
161
+ @property
162
+ def username(self) -> str | None:
163
+ """
164
+ A Wialon username the session is operating as.
165
+
166
+ :type: :py:obj:`str` | :py:obj:`None`
167
+ :value: :py:obj:`None`
168
+
169
+ """
170
+ return self._username
17
171
 
18
172
  @property
19
173
  def id(self) -> str | None:
174
+ """
175
+ Shortcut property for :py:attr:`WialonSession.wialon_api.sid`.
176
+
177
+ Returns :py:obj:`None` if the session wasn't logged in.
178
+
179
+ :type: :py:obj:`str` | :py:obj:`None`
180
+ :value: :py:obj:`None`
181
+
182
+ """
20
183
  return self.wialon_api.sid
21
184
 
22
185
  @property
23
- def token(self) -> str | None:
186
+ def token(self) -> str:
187
+ """
188
+ A Wialon API token set during :py:meth:`WialonSession.__init__`.
189
+
190
+ Default token value is :confval:`WIALON_TOKEN`.
191
+
192
+ :type: :py:obj:`str`
193
+ :value: :confval:`WIALON_TOKEN`
194
+
195
+ """
24
196
  return self._token
25
197
 
26
198
  @token.setter
27
199
  def token(self, value: str | None = None) -> None:
28
200
  self._token = value if value else settings.WIALON_TOKEN
29
201
 
30
- def __enter__(self) -> "WialonSession":
31
- if not self.wialon_api.sid:
32
- self.login(self.token)
33
- return self
202
+ def duplicate(
203
+ self, user_id: str | None = None, continue_session: bool = False
204
+ ) -> None:
205
+ """
206
+ Duplicates the active Wialon API session.
34
207
 
35
- def __exit__(self, exc_type, exc_value, exc_tb) -> None:
36
- self.logout()
37
- return
38
-
39
- def _deconstruct_login_response(self, login_response: dict) -> None:
40
- self.wialon_api.sid = login_response.get("eid", "")
41
- self.username = login_response.get("user", {}).get("nm")
42
- self.uid = login_response.get("user", {}).get("id")
43
- self.base_url = login_response.get("base_url", "")
44
- self.gis_sid = login_response.get("gis_sid", "")
45
- self.host = login_response.get("host", "")
46
- self.hw_gp_ip = login_response.get("hw_gw_ip", "")
47
- self.video_service_url = login_response.get("video_service_url", "")
48
- self.wsdk_version = login_response.get("wsdk_version", "")
49
- return
50
-
51
- def login(self, token: str | None = None) -> None:
52
- """Logs into the Wialon API and starts a new session."""
53
- if not token:
54
- raise ValueError("Must provide a Wialon API token to login with.")
208
+ :param user_id: A Wialon user to operate as in the session.
209
+ :type user_id: :py:obj:`str` | :py:obj:`None`
210
+ :param continue_session: Whether or not the original session id should be valid after duplication.
211
+ :type continue_session: :py:obj:`bool`
212
+ :raises WialonSessionDuplicationError: If the Wialon session was not duplicated.
213
+ :returns: Nothing.
214
+ :rtype: :py:obj:`None`
215
+
216
+ """
55
217
  try:
56
- login_response = self.wialon_api.token_login(
57
- **{"token": token, "fl": sum([0x1, 0x2, 0x20])}
218
+ login_response = self.wialon_api.core_duplicate(
219
+ **{"operateAs": user_id, "continueCurrentSession": continue_session}
58
220
  )
221
+ except WialonError as e:
222
+ raise WialonSessionDuplicationError(self.id, e)
223
+ else:
224
+ self._set_login_response(login_response)
225
+ self.active = True
226
+
227
+ def login(self, token: str, flags: int = sum([0x1, 0x2, 0x20])) -> None:
228
+ """
229
+ Logs into the Wialon API and starts a new session.
230
+
231
+ :param token: An active Wialon API token.
232
+ :type token: :py:obj:`str`
233
+ :param user_id: A user to operate as in the Wialon API session.
234
+ :type user_id: :py:obj:`str` | :py:obj:`None`
235
+ :param flags: A login response flag integer.
236
+ :type flags: :py:obj:`int`
237
+ :raises WialonLoginError: If the login fails.
238
+ :raises AssertionError: If the session was already active.
239
+ :returns: Nothing.
240
+ :rtype: :py:obj:`None`
241
+
242
+ """
243
+ assert not self.active, "Cannot login to an active session."
244
+ try:
245
+ response = self.wialon_api.token_login(**{"token": token, "fl": flags})
246
+ pprint(response)
59
247
  except WialonError as e:
60
248
  raise WialonLoginError(token, e)
61
249
  else:
62
- self._deconstruct_login_response(login_response)
250
+ self._set_login_response(response)
251
+ self.active = True
63
252
 
64
253
  def logout(self) -> None:
65
- """Logs out of the Wialon API and raises an error if the session was not destroyed."""
66
- sid: str = str(self.id)
67
- logout_response = self.wialon_api.core_logout({})
68
- if logout_response.get("error") != 0:
69
- raise WialonLogoutError(sid)
254
+ """
255
+ Logs out of the Wialon API session.
256
+
257
+ :raises WialonLogoutError: If the logout fails.
258
+ :returns: Nothing.
259
+ :rtype: :py:obj:`None`
260
+
261
+ """
262
+ response: dict = self.wialon_api.core_logout({})
263
+ if response.get("error") != 0:
264
+ raise WialonLogoutError(str(self.id))
265
+
266
+ def _set_login_response(self, login_response: dict) -> None:
267
+ """
268
+ Sets the Wialon API session's attributes based on a login response.
269
+
270
+ :param login_response: A Wialon API response to :py:meth:`login`.
271
+ :type login_response: :py:obj:`dict`
272
+ :returns: Nothing.
273
+ :rtype: :py:obj:`None`
274
+
275
+ """
276
+ self.wialon_api.sid = login_response.get("eid")
277
+ self._gis_geocode = login_response.get("gis_geocode")
278
+ self._gis_render = login_response.get("gis_render")
279
+ self._gis_routing = login_response.get("gis_routing")
280
+ self._gis_search = login_response.get("gis_search")
281
+ self._gis_sid = login_response.get("gis_sid")
282
+ self._host = login_response.get("host")
283
+ self._hw_gw_dns = login_response.get("hw_gw_dns")
284
+ self._hw_gw_ip = login_response.get("hw_gw_ip")
285
+ self._uid = login_response.get("user", {}).get("id")
286
+ self._nm = login_response.get("user", {}).get("nm")
287
+ self._username = login_response.get("au")
288
+ self._video_service_url = login_response.get("video_service_url")
289
+ self._wsdk_version = login_response.get("wsdk_version")
290
+
291
+
292
+ def main() -> None:
293
+ session = WialonSession()
294
+ session.login(settings.WIALON_TOKEN)
295
+ session.duplicate(user_id="28944309")
296
+ session.logout()
297
+ return
298
+
299
+
300
+ if __name__ == "__main__":
301
+ main()