python-terminusgps 1.9.7__py3-none-any.whl → 1.9.9__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 python-terminusgps might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-terminusgps
3
- Version: 1.9.7
3
+ Version: 1.9.9
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
@@ -4,7 +4,7 @@ terminusgps/authorizenet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
4
4
  terminusgps/authorizenet/auth.py,sha256=kWsqRT9OVEAQuNxDzQNzY1x2SqmvJr-HAbLwgkILntk,997
5
5
  terminusgps/authorizenet/profiles/__init__.py,sha256=QKjMKcXpCSCEhv6LBCz0yGP8t0VxAyKyYRS4_HLYnxQ,114
6
6
  terminusgps/authorizenet/profiles/addresses.py,sha256=ffAi3LcEOB3Xsr9f4N_PfjSZcN3I9dTKNamoAmnLpo4,3838
7
- terminusgps/authorizenet/profiles/base.py,sha256=Uk_VwtEVOomyV92ljVn7vcRn8BfwWHu80Jnct0NNlmw,2491
7
+ terminusgps/authorizenet/profiles/base.py,sha256=IooSz_PTeq23IIgq6upx2CcpWEOXgK3mFNylADYlF3I,2553
8
8
  terminusgps/authorizenet/profiles/customers.py,sha256=iEuNFP6PHuGdFQftgxxKpQFYaGw8IWLjsOaugvEOA-g,4513
9
9
  terminusgps/authorizenet/profiles/payments.py,sha256=qOWp-gO6qBCADP98WjoNCHm-jtq7DY5-moiPsOnT5yI,5263
10
10
  terminusgps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -13,17 +13,17 @@ terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
13
13
  terminusgps/wialon/constants.py,sha256=aybYcNcHyar2lz_6BlQbMWpbcHW6eyJeq05QwuiqZQ0,3078
14
14
  terminusgps/wialon/errors.py,sha256=SV9pVwU6FZ_zGlGP6zJN6aLE2auF4TfHFISQLiPMKrI,1758
15
15
  terminusgps/wialon/flags.py,sha256=-OoH-eZM54yjRqxsAXL8VImdQu_7C0OAxCrFqaCEuko,13510
16
- terminusgps/wialon/session.py,sha256=segEjyt-K9AAlMq_OYLVtxFBp_jE5c3KL-AJQhOVa9U,9936
17
- terminusgps/wialon/utils.py,sha256=9xJq5eAWm-vu0nJVJ7eUcwhJhMCrGjS1p__4CIBXYm4,3407
16
+ terminusgps/wialon/session.py,sha256=AntMZQA7g5FAnEHzPCVopmfDgigP1JFp-zYv8_H7xEg,9792
17
+ terminusgps/wialon/utils.py,sha256=vo5-md05VzyFtM98AxG7_gI2TVgOecqY9K78tQErxDU,3429
18
18
  terminusgps/wialon/items/__init__.py,sha256=3BVthghekMvhMQSzQgBMlD_phxmKSmp3Zvmo-z0O8Bs,211
19
- terminusgps/wialon/items/base.py,sha256=Z6aGEC2_m5CPHYCa1rgAvkGtSegbrvZ68mifCqo-07A,6617
19
+ terminusgps/wialon/items/base.py,sha256=CuDctBbR0NwW9Fo--05iozSx7GkNysvAFXvdidggJjg,6693
20
20
  terminusgps/wialon/items/resource.py,sha256=xElMYSMyKA5y8rIP0EeF429MBV2hbLZcS6SokftvrOs,5641
21
21
  terminusgps/wialon/items/retranslator.py,sha256=zsQXqOhH1zFe5_e8DROPu60z3v6xPWOEPyMCi2IqJAo,3861
22
22
  terminusgps/wialon/items/route.py,sha256=qOHPN_rejwiGqvwWzlwmUIAIyc3lKavCalf8ki66rx0,760
23
- terminusgps/wialon/items/unit.py,sha256=wzcLa0adMTKX6rtO4Vz6ntaxgY50rLk2KK_VBXlW_lQ,4680
23
+ terminusgps/wialon/items/unit.py,sha256=mEYQRpICELQPR3dyDJVRzoKeIuFRnPgkqK-Oo6xuIP4,6306
24
24
  terminusgps/wialon/items/unit_group.py,sha256=1yc7ldPIgGbtiTj0djRDWmt6Q9K_VT9sxOaioasbbLY,5212
25
25
  terminusgps/wialon/items/user.py,sha256=bkcMw_YiocaMuhP_pBfB7apjAZwnsOzGScnGkn8Ybbw,6107
26
- python_terminusgps-1.9.7.dist-info/METADATA,sha256=AM9Wj1ho_7YrRdExekgsaiPG6zL8rrYRQfago0bpc6Q,882
27
- python_terminusgps-1.9.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
- python_terminusgps-1.9.7.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
29
- python_terminusgps-1.9.7.dist-info/RECORD,,
26
+ python_terminusgps-1.9.9.dist-info/METADATA,sha256=tbP74Vv0X3nKIuyECKlcHHKVsoQJ4mp4BHRsP1Rj7V4,882
27
+ python_terminusgps-1.9.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
+ python_terminusgps-1.9.9.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
29
+ python_terminusgps-1.9.9.dist-info/RECORD,,
@@ -7,9 +7,11 @@ from ..auth import get_merchant_auth, get_environment, get_validation_mode
7
7
 
8
8
 
9
9
  class AuthorizenetProfileBase:
10
- def __init__(self, merchant_id: int | str, id: int | str | None = None) -> None:
10
+ def __init__(
11
+ self, merchant_id: int | str, id: int | str | None = None, **kwargs
12
+ ) -> None:
11
13
  self._merchantCustomerId = merchant_id
12
- self._id = id
14
+ self._id = str(id) if id else self.create(**kwargs)
13
15
 
14
16
  def __str__(self) -> str:
15
17
  return f"#{self.id}"
@@ -1,17 +1,15 @@
1
- import terminusgps.wialon.flags as flags
1
+ from abc import abstractmethod
2
+ from terminusgps.wialon import flags
2
3
  from terminusgps.wialon.session import WialonSession
3
4
 
4
5
 
5
6
  class WialonBase:
6
- def __init__(
7
- self, *, id: str | None = None, session: WialonSession, **kwargs
8
- ) -> None:
9
- self._session = session
7
+ def __init__(self, id: str | int, session: WialonSession, **kwargs) -> None:
8
+ if isinstance(id, str) and not id.isdigit():
9
+ raise ValueError(f"'id' must be a digit. Got '{id}'.")
10
10
 
11
- if not id:
12
- self._id = self.create(**kwargs)
13
- else:
14
- self._id = id
11
+ self._session = session
12
+ self._id = str(id if id else self.create(**kwargs))
15
13
  self.populate()
16
14
 
17
15
  def __str__(self) -> str:
@@ -20,7 +18,7 @@ class WialonBase:
20
18
  def populate(self) -> None:
21
19
  response = self.session.wialon_api.core_search_item(
22
20
  **{"id": str(self.id), "flags": 0x1}
23
- )["item"]
21
+ ).get("item", {})
24
22
  self.name = response.get("nm")
25
23
  self.hw_type = response.get("cls")
26
24
  self.access_lvl = response.get("uacl")
@@ -59,8 +57,9 @@ class WialonBase:
59
57
  )
60
58
  return True if self.id in response.keys() else False
61
59
 
60
+ @abstractmethod
62
61
  def create(self) -> int | None:
63
- """Creates a Wialon object and returns the newly created Wialon object's id."""
62
+ """Creates a Wialon object and returns its id."""
64
63
  raise NotImplementedError("Subclasses must implement this method.")
65
64
 
66
65
  def rename(self, new_name: str) -> None:
@@ -133,11 +133,20 @@ class WialonUnit(WialonBase):
133
133
  **{"itemId": self.id, "phoneNumber": quote_plus(phone)}
134
134
  )
135
135
 
136
+ def clean_phone_numbers(self, phones: list[str]) -> list[str]:
137
+ cleaned_phones = []
138
+ for num in phones:
139
+ if "," in num:
140
+ cleaned_phones.extend(num.split(","))
141
+ else:
142
+ cleaned_phones.append(num)
143
+ return cleaned_phones
144
+
136
145
  def get_phone_numbers(self) -> list[str]:
137
146
  """
138
147
  Retrieves all phone numbers assigned to this Wialon unit.
139
148
 
140
- This includes the usually assigned phone number + custom/admin fields labeled ``to_number``.
149
+ This includes any attached drivers, custom fields, and normally assigned unit phone numbers.
141
150
 
142
151
  :raises WialonError: If something goes wrong with Wialon.
143
152
  :returns: A list of phone numbers.
@@ -145,8 +154,41 @@ class WialonUnit(WialonBase):
145
154
 
146
155
  """
147
156
 
148
- phones = []
149
- for field in self.cfields | self.afields:
150
- if field["n"] == "to_number":
151
- phones.append(field["v"])
152
- return phones
157
+ phone_numbers = []
158
+ phones_0 = self._get_driver_phone_numbers()
159
+ phones_1 = self._get_cfield_phone_numbers()
160
+
161
+ if phones_0:
162
+ phone_numbers.extend(phones_0)
163
+ if phones_1:
164
+ phone_numbers.extend(phones_1)
165
+ return list(dict.fromkeys(phone_numbers)) # Removes duplicate phone numbers
166
+
167
+ def _get_cfield_phone_numbers(self) -> list[str] | None:
168
+ """
169
+ Retrives any phone numbers saved in the unit's custom 'to_number' field.
170
+
171
+ :raises WialonError: If something goes wrong with Wialon.
172
+ :returns: A list of phone numbers, if the unit has custom phone number fields.
173
+ :rtype: :py:obj:`list` | :py:obj:`None`
174
+
175
+ """
176
+ for key, value in self.cfields.items():
177
+ if key == "to_number":
178
+ return self.clean_phone_numbers([value])
179
+
180
+ def _get_driver_phone_numbers(self) -> list[str] | None:
181
+ """
182
+ Retrieves any phone numbers assigned to drivers attached to the unit.
183
+
184
+ :raises WialonError: If something goes wrong with Wialon.
185
+ :returns: A list of phone numbers, if the unit has attached drivers with phone numbers.
186
+ :rtype: :py:obj:`list` | :py:obj:`None`
187
+
188
+ """
189
+ response = self.session.wialon_api.resource_get_unit_drivers(
190
+ **{"unitId": self.id}
191
+ )
192
+ if response:
193
+ dirty_phones = [driver[0].get("ph") for _, driver in response.items()]
194
+ return self.clean_phone_numbers(dirty_phones)
@@ -50,7 +50,7 @@ class WialonSession:
50
50
 
51
51
  def __enter__(self) -> "WialonSession":
52
52
  assert self.token, "Wialon API token was not set"
53
- self.login(self.token, self.login_id)
53
+ self.login(self.token)
54
54
  return self
55
55
 
56
56
  def __exit__(self, *args, **kwargs) -> None:
@@ -321,9 +321,6 @@ class WialonSessionManager:
321
321
  return cls._instance
322
322
 
323
323
  def get_session(self, sid: str | None = None) -> WialonSession:
324
- if not hasattr(settings, "WIALON_TOKEN"):
325
- raise ImproperlyConfigured("'WIALON_TOKEN' setting is required.")
326
-
327
324
  with self._lock:
328
325
  if not self._session or not self._session.active:
329
326
  self._session = WialonSession(sid=sid)
@@ -1,3 +1,4 @@
1
+ from enum import Enum
1
2
  import secrets
2
3
  import string
3
4