python-terminusgps 47.0.0__tar.gz → 47.1.1__tar.gz

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.
Files changed (54) hide show
  1. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/PKG-INFO +1 -1
  2. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/conf.py +1 -1
  3. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/pyproject.toml +1 -1
  4. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/default_settings.py +1 -0
  5. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/session.py +4 -4
  6. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/utils.py +23 -10
  7. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/uv.lock +1 -1
  8. python_terminusgps-47.0.0/terminusgps/wialon/validators.py +0 -114
  9. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/.github/workflows/sphinx.yml +0 -0
  10. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/.gitignore +0 -0
  11. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/.python-version +0 -0
  12. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/COPYING +0 -0
  13. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/README.md +0 -0
  14. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/Makefile +0 -0
  15. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/make.bat +0 -0
  16. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/requirements.txt +0 -0
  17. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/authorizenet/api.rst +0 -0
  18. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/authorizenet/constants.rst +0 -0
  19. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/authorizenet/index.rst +0 -0
  20. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/authorizenet/service.rst +0 -0
  21. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/index.rst +0 -0
  22. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/mixins.rst +0 -0
  23. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/validators.rst +0 -0
  24. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/wialon/constants.rst +0 -0
  25. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/wialon/exceptions.rst +0 -0
  26. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/wialon/index.rst +0 -0
  27. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/wialon/items.rst +0 -0
  28. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/wialon/session.rst +0 -0
  29. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/docs/source/wialon/usage.rst +0 -0
  30. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/__init__.py +0 -0
  31. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/__init__.py +0 -0
  32. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/api/__init__.py +0 -0
  33. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/api/address_profiles.py +0 -0
  34. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/api/customer_profiles.py +0 -0
  35. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/api/payment_profiles.py +0 -0
  36. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/api/subscriptions.py +0 -0
  37. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/api/transactions.py +0 -0
  38. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/constants.py +0 -0
  39. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/authorizenet/service.py +0 -0
  40. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/mixins.py +0 -0
  41. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/validators.py +0 -0
  42. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/__init__.py +0 -0
  43. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/constants.py +0 -0
  44. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/flags.py +0 -0
  45. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/__init__.py +0 -0
  46. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/account.py +0 -0
  47. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/base.py +0 -0
  48. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/factory.py +0 -0
  49. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/resource.py +0 -0
  50. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/retranslator.py +0 -0
  51. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/route.py +0 -0
  52. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/unit.py +0 -0
  53. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/unit_group.py +0 -0
  54. {python_terminusgps-47.0.0 → python_terminusgps-47.1.1}/terminusgps/wialon/items/user.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-terminusgps
3
- Version: 47.0.0
3
+ Version: 47.1.1
4
4
  Summary: Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more.
5
5
  Project-URL: Documentation, https://terminusgps.github.io/python-terminusgps
6
6
  Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
@@ -12,7 +12,7 @@ sys.path.insert(0, os.path.abspath("../../"))
12
12
  project = "python-terminusgps"
13
13
  copyright = "2025, Terminus GPS, LLC"
14
14
  author = "Terminus GPS, LLC"
15
- release = "46.1.0"
15
+ release = "47.1.1"
16
16
 
17
17
  # -- General configuration ---------------------------------------------------
18
18
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-terminusgps"
3
- version = "47.0.0"
3
+ version = "47.1.1"
4
4
  description = "Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more."
5
5
  readme = "README.md"
6
6
  authors = [ {name = "Blake Nall", email = "blake@terminusgps.com" } ]
@@ -16,3 +16,4 @@ MERCHANT_AUTH_VALIDATION_MODE = ValidationMode.TEST
16
16
  MERCHANT_AUTH_LOGIN_ID = os.getenv("MERCHANT_AUTH_LOGIN_ID")
17
17
  MERCHANT_AUTH_TRANSACTION_KEY = os.getenv("MERCHANT_AUTH_TRANSACTION_KEY")
18
18
  WIALON_TOKEN = os.getenv("WIALON_TOKEN")
19
+ WIALON_USERNAME = os.getenv("WIALON_USERNAME")
@@ -53,11 +53,11 @@ class WialonSession:
53
53
  :type port: int
54
54
  :param sid: A Wialon API session id. Default is :py:obj:`None`.
55
55
  :type sid: str | None
56
- :param token: A Wialon API token. Default is :py:obj:`None`.
56
+ :param token: A Wialon API token. Default is environment variable ``"WIALON_TOKEN"``.
57
57
  :type token: str | None
58
- :param auth_hash: A Wialon API authentication hash. Default is environment variable ``"WIALON_TOKEN"``.
58
+ :param auth_hash: A Wialon API authentication hash. Default is :py:obj:`None`.
59
59
  :type auth_hash: str | None
60
- :param username: A Wialon user id to operate as during the session. Default is :py:obj:`None`.
60
+ :param username: A Wialon user to operate as during the session. Default is environment variable ``"WIALON_USERNAME"``.
61
61
  :type username: str | None
62
62
  :param check_service: A Wialon service name to check before calling the Wialon API. Default is :py:obj:`None`.
63
63
  :type check_service: str | None
@@ -69,7 +69,7 @@ class WialonSession:
69
69
  self._wialon_api = Wialon(scheme=scheme, host=host, port=port, sid=sid)
70
70
 
71
71
  self._token = token if token else os.getenv("WIALON_TOKEN")
72
- self._username = username
72
+ self._username = username if username else os.getenv("WIALON_USERNAME")
73
73
  self._auth_hash = auth_hash
74
74
  self._check_service = check_service
75
75
 
@@ -64,9 +64,9 @@ def get_user_by_name(name: str, session: WialonSession) -> WialonUser:
64
64
  raise ValueError(f"Multiple users returned for '{name}'.")
65
65
  elif num_items <= 0:
66
66
  raise ValueError(f"Couldn't find a Wialon user named '{name}'.")
67
-
68
67
  factory = WialonObjectFactory(session)
69
- return factory.get("user", id=int(response.get("items")[0].get("id")))
68
+ user_id = response.get("items")[0].get("id")
69
+ return factory.get("user", id=int(user_id))
70
70
 
71
71
 
72
72
  def get_carrier_names(session: WialonSession) -> list[str]:
@@ -89,7 +89,8 @@ def get_carrier_names(session: WialonSession) -> list[str]:
89
89
  "propType": "propitemname",
90
90
  },
91
91
  "force": 0,
92
- "flags": flags.DataFlag.UNIT_BASE | flags.DataFlag.UNIT_ADMIN_FIELDS,
92
+ "flags": flags.DataFlag.UNIT_BASE
93
+ | flags.DataFlag.UNIT_ADMIN_FIELDS,
93
94
  "from": 0,
94
95
  "to": 0,
95
96
  }
@@ -103,7 +104,9 @@ def get_carrier_names(session: WialonSession) -> list[str]:
103
104
  return sorted(list(frozenset(carrier_names)))
104
105
 
105
106
 
106
- def get_units_by_carrier(carrier_name: str, session: WialonSession) -> list[WialonUnit]:
107
+ def get_units_by_carrier(
108
+ carrier_name: str, session: WialonSession
109
+ ) -> list[WialonUnit]:
107
110
  """
108
111
  Returns a list of all units by telecommunications carrier company name.
109
112
 
@@ -125,14 +128,17 @@ def get_units_by_carrier(carrier_name: str, session: WialonSession) -> list[Wial
125
128
  "propType": "propitemname",
126
129
  },
127
130
  "force": 0,
128
- "flags": flags.DataFlag.UNIT_BASE | flags.DataFlag.UNIT_ADMIN_FIELDS,
131
+ "flags": flags.DataFlag.UNIT_BASE
132
+ | flags.DataFlag.UNIT_ADMIN_FIELDS,
129
133
  "from": 0,
130
134
  "to": 0,
131
135
  }
132
136
  )
133
137
  num_items: int = int(response.get("totalItemsCount"))
134
138
  if num_items <= 0:
135
- raise ValueError(f"Couldn't find any units by carrier '{carrier_name}'.")
139
+ raise ValueError(
140
+ f"Couldn't find any units by carrier '{carrier_name}'."
141
+ )
136
142
 
137
143
  factory = WialonObjectFactory(session)
138
144
  unit_ids = [int(unit.get("id")) for unit in response.get("items")]
@@ -161,7 +167,8 @@ def get_unit_by_iccid(iccid: str, session: WialonSession) -> WialonUnit:
161
167
  "propType": "propitemname",
162
168
  },
163
169
  "force": 0,
164
- "flags": flags.DataFlag.UNIT_BASE | flags.DataFlag.UNIT_ADMIN_FIELDS,
170
+ "flags": flags.DataFlag.UNIT_BASE
171
+ | flags.DataFlag.UNIT_ADMIN_FIELDS,
165
172
  "from": 0,
166
173
  "to": 0,
167
174
  }
@@ -177,7 +184,9 @@ def get_unit_by_iccid(iccid: str, session: WialonSession) -> WialonUnit:
177
184
  return factory.get("avl_unit", id=int(response.get("items")[0].get("id")))
178
185
 
179
186
 
180
- def get_unit_by_imei(imei: int | str, session: WialonSession) -> WialonUnit | None:
187
+ def get_unit_by_imei(
188
+ imei: int | str, session: WialonSession
189
+ ) -> WialonUnit | None:
181
190
  """
182
191
  Takes a Wialon unit's IMEI # and returns its unit id.
183
192
 
@@ -218,7 +227,9 @@ def get_unit_by_imei(imei: int | str, session: WialonSession) -> WialonUnit | No
218
227
  return factory.get("avl_unit", id=int(response.get("items")[0].get("id")))
219
228
 
220
229
 
221
- def get_vin_info(vin_number: str, session: WialonSession) -> dict[str, typing.Any]:
230
+ def get_vin_info(
231
+ vin_number: str, session: WialonSession
232
+ ) -> dict[str, typing.Any]:
222
233
  """
223
234
  Retrieves vehicle data from a VIN number.
224
235
 
@@ -279,7 +290,9 @@ def generate_wialon_password(length: int = 32) -> str:
279
290
  s3 = list("!@#$%^*()[]-_+")
280
291
 
281
292
  while True:
282
- password = "".join([secrets.choice(s0 + s1 + s2 + s3) for _ in range(length)])
293
+ password = "".join(
294
+ [secrets.choice(s0 + s1 + s2 + s3) for _ in range(length)]
295
+ )
283
296
  if (
284
297
  any(c.islower() for c in password)
285
298
  and any(c.isupper() for c in password)
@@ -323,7 +323,7 @@ wheels = [
323
323
 
324
324
  [[package]]
325
325
  name = "python-terminusgps"
326
- version = "47.0.0"
326
+ version = "47.1.1"
327
327
  source = { editable = "." }
328
328
  dependencies = [
329
329
  { name = "authorizenet" },
@@ -1,114 +0,0 @@
1
- import string
2
-
3
- from django.conf import settings
4
- from django.core.exceptions import ImproperlyConfigured, ValidationError
5
- from django.utils.translation import gettext_lazy as _
6
-
7
- from .session import WialonSession
8
-
9
- if settings.configured and not hasattr(settings, "WIALON_TOKEN"):
10
- raise ImproperlyConfigured("'WIALON_TOKEN' setting is required.")
11
-
12
-
13
- class WialonValidatorBase:
14
- def __init__(self) -> None:
15
- self.session = WialonSession()
16
- self.session.login(self.session.token)
17
-
18
- def __call__(self, value: str) -> None:
19
- raise NotImplementedError("Subclasses must implement this method.")
20
-
21
-
22
- class WialonVinNumberValidator(WialonValidatorBase):
23
- def __call__(self, value: str) -> None:
24
- response = self.session.wialon_api.unit_get_vin_info(vin=value)
25
- if "error" in response["vin_lookup_result"].keys():
26
- raise ValidationError(
27
- _("Failed to get info for VIN # '%(value)s': '%(message)s'"),
28
- code="invalid",
29
- params={
30
- "value": value,
31
- "message": response["vin_lookup_result"].get("message", ""),
32
- },
33
- )
34
-
35
-
36
- class WialonImeiNumberValidator(WialonValidatorBase):
37
- def __call__(self, value: str) -> None:
38
- response = self.session.wialon_api.core_search_items(
39
- **{
40
- "spec": {
41
- "itemsType": "avl_unit",
42
- "propName": "sys_id,sys_unique_id",
43
- "propValueMask": f"*,*{value}*",
44
- "sortType": "sys_id,sys_unique_id",
45
- },
46
- "force": 0,
47
- "flags": 1,
48
- "from": 0,
49
- "to": 0,
50
- }
51
- )
52
- if response is None or not response.get("items"):
53
- raise ValidationError(
54
- _("IMEI # '%(value)s' wasn't found in Wialon."),
55
- code="invalid",
56
- params={"value": value},
57
- )
58
-
59
-
60
- def validate_imei_number(value: str) -> None:
61
- """Raises :py:exec:`ValidationError` if the value is an invalid IMEI number."""
62
- WialonImeiNumberValidator()(value)
63
-
64
-
65
- def validate_vin_number(value: str) -> None:
66
- """Raises :py:exec:`ValidationError` if the value is an invalid VIN number."""
67
- if len(value) != 17:
68
- raise ValidationError(
69
- _("Whoops! VIN # must be exactly 17 characters in length, got %(length)s."),
70
- code="invalid",
71
- params={"length": len(value)},
72
- )
73
- WialonVinNumberValidator()(value)
74
-
75
-
76
- def validate_wialon_password(value: str) -> None:
77
- """Raises :py:exec:`ValidationError` if the value represents an invalid Wialon password."""
78
- special_symbols_0: list[str] = ["!", "@", "#", "$", "%", "^", "*"]
79
- special_symbols_1: list[str] = ["(", ")", "[", "]", "-", "_", "+"]
80
- forbidden_symbols: list[str] = [",", ":", "&", "<", ">", "'"]
81
-
82
- if len(value) < 4:
83
- raise ValidationError(
84
- _("Password cannot be less than 4 characters in length, got %(len)s."),
85
- code="invalid",
86
- params={"len": len(value)},
87
- )
88
- if len(value) > 64:
89
- raise ValidationError(
90
- _("Password cannot be greater than 64 characters in length, got %(len)s."),
91
- code="invalid",
92
- params={"len": len(value)},
93
- )
94
- if not any([char for char in value if char in string.ascii_uppercase]):
95
- raise ValidationError(
96
- _("Password must contain at least one uppercase letter."), code="invalid"
97
- )
98
- if not any([char for char in value if char in string.ascii_lowercase]):
99
- raise ValidationError(
100
- _("Password must contain at least one lowercase letter."), code="invalid"
101
- )
102
- if not any(
103
- [char for char in value if char in special_symbols_0 + special_symbols_1]
104
- ):
105
- raise ValidationError(
106
- _("Password must contain at least one special symbol."), code="invalid"
107
- )
108
- for char in value:
109
- if char in forbidden_symbols:
110
- raise ValidationError(
111
- _("Password cannot contain forbidden character '%(char)s'."),
112
- code="invalid",
113
- params={"char": char},
114
- )