python-terminusgps 49.2.0__tar.gz → 50.0.0__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.
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/PKG-INFO +1 -1
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/conf.py +1 -1
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/pyproject.toml +1 -1
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/constants.py +18 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/wialon/session.py +1 -2
- python_terminusgps-50.0.0/terminusgps/wialon/utils.py +180 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/uv.lock +25 -25
- python_terminusgps-49.2.0/terminusgps/tests/authorizenet/__init__.py +0 -0
- python_terminusgps-49.2.0/terminusgps/tests/wialon/__init__.py +0 -0
- python_terminusgps-49.2.0/terminusgps/wialon/__init__.py +0 -0
- python_terminusgps-49.2.0/terminusgps/wialon/items/__init__.py +0 -1
- python_terminusgps-49.2.0/terminusgps/wialon/items/account.py +0 -217
- python_terminusgps-49.2.0/terminusgps/wialon/items/base.py +0 -272
- python_terminusgps-49.2.0/terminusgps/wialon/items/factory.py +0 -126
- python_terminusgps-49.2.0/terminusgps/wialon/items/resource.py +0 -126
- python_terminusgps-49.2.0/terminusgps/wialon/items/retranslator.py +0 -39
- python_terminusgps-49.2.0/terminusgps/wialon/items/route.py +0 -35
- python_terminusgps-49.2.0/terminusgps/wialon/items/unit.py +0 -152
- python_terminusgps-49.2.0/terminusgps/wialon/items/unit_group.py +0 -55
- python_terminusgps-49.2.0/terminusgps/wialon/items/user.py +0 -135
- python_terminusgps-49.2.0/terminusgps/wialon/utils.py +0 -417
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/.github/workflows/sphinx.yml +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/.gitignore +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/.python-version +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/COPYING +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/README.md +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/Makefile +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/make.bat +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/requirements.txt +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/authorizenet/api.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/authorizenet/constants.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/authorizenet/index.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/authorizenet/service.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/index.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/mixins.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/validators.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/wialon/constants.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/wialon/exceptions.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/wialon/index.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/wialon/items.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/wialon/session.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/wialon/usage.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/docs/source/wialon/utils.rst +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/__init__.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/__init__.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/api/__init__.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/api/address_profiles.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/api/customer_profiles.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/api/payment_profiles.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/api/subscriptions.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/api/transactions.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/service.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/default_settings.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/mixins.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/validators.py +0 -0
- {python_terminusgps-49.2.0/terminusgps/tests → python_terminusgps-50.0.0/terminusgps/wialon}/__init__.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/wialon/constants.py +0 -0
- {python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/wialon/flags.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-terminusgps
|
|
3
|
-
Version:
|
|
3
|
+
Version: 50.0.0
|
|
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 = "
|
|
15
|
+
release = "50.0.0"
|
|
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 = "
|
|
3
|
+
version = "50.0.0"
|
|
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" } ]
|
{python_terminusgps-49.2.0 → python_terminusgps-50.0.0}/terminusgps/authorizenet/constants.py
RENAMED
|
@@ -4,6 +4,24 @@ from django.db import models
|
|
|
4
4
|
from django.utils.translation import gettext_lazy as _
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
class BankAccountType(models.TextChoices):
|
|
8
|
+
CHECKING = "checking", _("Checking account")
|
|
9
|
+
"""Checking account."""
|
|
10
|
+
SAVINGS = "savings", _("Savings account")
|
|
11
|
+
"""Savings account."""
|
|
12
|
+
BUSINESS_CHECKING = "businessChecking", _("Business checking account")
|
|
13
|
+
"""Business checking account."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ECheckType(models.TextChoices):
|
|
17
|
+
PPD = "PPD", _("Prearranged Payment and Deposit Entry")
|
|
18
|
+
"""Prearranged Payment and Deposit Entry."""
|
|
19
|
+
TEL = "TEL", _("Telephone-Initiated Entry")
|
|
20
|
+
"""Telephone-Initiated Entry."""
|
|
21
|
+
WEB = "WEB", _("Web-Initiated Entry")
|
|
22
|
+
"""Web-Initiated Entry."""
|
|
23
|
+
|
|
24
|
+
|
|
7
25
|
class CreditCardType(models.TextChoices):
|
|
8
26
|
AMEX = apicontractsv1.cardTypeEnum.AmericanExpress, _("American Express")
|
|
9
27
|
"""American express card."""
|
|
@@ -15,8 +15,7 @@ class WialonAPIError(Exception):
|
|
|
15
15
|
try:
|
|
16
16
|
self._code = int(message._code)
|
|
17
17
|
except ValueError:
|
|
18
|
-
|
|
19
|
-
self._code = 6
|
|
18
|
+
self._code = 6 # 'Unknown Error' according to Wialon
|
|
20
19
|
return super().__init__(message, *args, **kwargs)
|
|
21
20
|
|
|
22
21
|
@property
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import secrets
|
|
2
|
+
import string
|
|
3
|
+
|
|
4
|
+
from terminusgps.wialon.session import WialonSession
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_id_from_iccid(
|
|
8
|
+
iccid: str,
|
|
9
|
+
session: WialonSession,
|
|
10
|
+
*,
|
|
11
|
+
use_cache: bool = True,
|
|
12
|
+
afield_key: str = "iccid",
|
|
13
|
+
) -> int | None:
|
|
14
|
+
"""
|
|
15
|
+
Returns a Wialon unit ID from a telecom iccid.
|
|
16
|
+
|
|
17
|
+
:param iccid: A telecom iccid number.
|
|
18
|
+
:type iccid: str
|
|
19
|
+
:param session: A valid Wialon API session.
|
|
20
|
+
:type session: ~terminusgps.wialon.session.WialonSession
|
|
21
|
+
:param use_cache: Whether to use a cached Wialon API response or force a Wialon API call. Default is :py:obj:`True`.
|
|
22
|
+
:type use_cache: bool
|
|
23
|
+
:param afield_key: Admin field key to search against. Default is ``"iccid"``.
|
|
24
|
+
:type afield_key: str
|
|
25
|
+
:raises ValueError: If multiple units were found with the provided iccid.
|
|
26
|
+
:raises ValueError: If zero units were found with the provided iccid.
|
|
27
|
+
:returns: A Wialon unit ID, if found.
|
|
28
|
+
:rtype: int | None
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
response = session.wialon_api.core_search_items(
|
|
32
|
+
**{
|
|
33
|
+
"spec": {
|
|
34
|
+
"itemsType": "avl_unit",
|
|
35
|
+
"propName": "rel_adminfield_name,rel_adminfield_value",
|
|
36
|
+
"propValueMask": f"{afield_key},{iccid}",
|
|
37
|
+
"sortType": "sys_name",
|
|
38
|
+
"propType": "admin_fields,admin_fields",
|
|
39
|
+
},
|
|
40
|
+
"force": int(not use_cache),
|
|
41
|
+
"flags": 1,
|
|
42
|
+
"from": 0,
|
|
43
|
+
"to": 0,
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
if int(response["totalItemsCount"]) > 1:
|
|
47
|
+
raise ValueError(f"Multiple units found for iccid #{iccid}.")
|
|
48
|
+
elif int(response["totalItemsCount"]) == 0:
|
|
49
|
+
raise ValueError(f"No units found for iccid #{iccid}.")
|
|
50
|
+
return int(response["items"][0]["id"])
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_id_from_imei(
|
|
54
|
+
imei: str, session: WialonSession, *, use_cache: bool = True
|
|
55
|
+
) -> int | None:
|
|
56
|
+
"""
|
|
57
|
+
Returns a Wialon unit ID from an IMEI (sys_unique_id) number.
|
|
58
|
+
|
|
59
|
+
:param imei: An IMEI number.
|
|
60
|
+
:type imei: str
|
|
61
|
+
:param session: A valid Wialon API session.
|
|
62
|
+
:type session: ~terminusgps.wialon.session.WialonSession
|
|
63
|
+
:param use_cache: Whether to use a cached Wialon API response or force a Wialon API call. Default is :py:obj:`True`.
|
|
64
|
+
:type use_cache: bool
|
|
65
|
+
:raises ValueError: If multiple units were found with the provided IMEI number.
|
|
66
|
+
:raises ValueError: If zero units were found with the provided IMEI number.
|
|
67
|
+
:returns: A Wialon unit ID, if found.
|
|
68
|
+
:rtype: int | None
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
response = session.wialon_api.core_search_items(
|
|
72
|
+
**{
|
|
73
|
+
"spec": {
|
|
74
|
+
"itemsType": "avl_unit",
|
|
75
|
+
"propName": "sys_unique_id",
|
|
76
|
+
"propValueMask": imei,
|
|
77
|
+
"sortType": "sys_name",
|
|
78
|
+
"propType": "property",
|
|
79
|
+
},
|
|
80
|
+
"force": int(not use_cache),
|
|
81
|
+
"flags": 1,
|
|
82
|
+
"from": 0,
|
|
83
|
+
"to": 0,
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
if int(response["totalItemsCount"]) > 1:
|
|
87
|
+
raise ValueError(f"Multiple units found for IMEI #{imei}.")
|
|
88
|
+
elif int(response["totalItemsCount"]) == 0:
|
|
89
|
+
raise ValueError(f"No units found for IMEI #{imei}.")
|
|
90
|
+
return int(response["items"][0]["id"])
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def get_ids_from_carrier(
|
|
94
|
+
carrier: str,
|
|
95
|
+
session: WialonSession,
|
|
96
|
+
*,
|
|
97
|
+
use_cache: bool = True,
|
|
98
|
+
afield_key: str = "carrier",
|
|
99
|
+
) -> list[int]:
|
|
100
|
+
"""
|
|
101
|
+
Returns a list of Wialon unit IDs by telecom carrier name.
|
|
102
|
+
|
|
103
|
+
The list may be empty if no units were found.
|
|
104
|
+
|
|
105
|
+
:param carrier: A telecom carrier name.
|
|
106
|
+
:type carrier: str
|
|
107
|
+
:param session: A valid Wialon API session.
|
|
108
|
+
:type session: ~terminusgps.wialon.session.WialonSession
|
|
109
|
+
:param use_cache: Whether to use a cached Wialon API response or force a Wialon API call. Default is :py:obj:`True`.
|
|
110
|
+
:type use_cache: bool
|
|
111
|
+
:param afield_key: Admin field key to search against. Default is ``"carrier"``.
|
|
112
|
+
:type afield_key: str
|
|
113
|
+
:returns: A list of Wialon unit IDs, if any were found.
|
|
114
|
+
:rtype: list[int]
|
|
115
|
+
|
|
116
|
+
"""
|
|
117
|
+
response = session.wialon_api.core_search_items(
|
|
118
|
+
**{
|
|
119
|
+
"spec": {
|
|
120
|
+
"itemsType": "avl_unit",
|
|
121
|
+
"propName": "rel_adminfield_name,rel_adminfield_value",
|
|
122
|
+
"propValueMask": f"{afield_key},{carrier}",
|
|
123
|
+
"sortType": "sys_name",
|
|
124
|
+
"propType": "admin_fields,admin_fields",
|
|
125
|
+
},
|
|
126
|
+
"force": int(not use_cache),
|
|
127
|
+
"flags": 1,
|
|
128
|
+
"from": 0,
|
|
129
|
+
"to": 0,
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
if int(response["totalItemsCount"]) == 0:
|
|
133
|
+
return []
|
|
134
|
+
return [int(unit["id"]) for unit in response["items"]]
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def generate_wialon_password(length: int = 32) -> str:
|
|
138
|
+
"""
|
|
139
|
+
Generates a Wialon compliant password between ``8`` and ``64`` characters.
|
|
140
|
+
|
|
141
|
+
The generated password will contain:
|
|
142
|
+
|
|
143
|
+
- At least one uppercase letter.
|
|
144
|
+
- At least one lowercase letter.
|
|
145
|
+
- At least one special symbol.
|
|
146
|
+
- At least three digits.
|
|
147
|
+
|
|
148
|
+
:param length: Length of the generated password. Default is ``32``.
|
|
149
|
+
:type length: int
|
|
150
|
+
:raises ValueError: If ``length`` was less than ``8`` or greater than ``64``.
|
|
151
|
+
:returns: A Wialon compliant password.
|
|
152
|
+
:rtype: str
|
|
153
|
+
|
|
154
|
+
"""
|
|
155
|
+
if length > 64:
|
|
156
|
+
raise ValueError(
|
|
157
|
+
f"Password cannot be greater than 64 characters in length, got {length}."
|
|
158
|
+
)
|
|
159
|
+
elif length < 8:
|
|
160
|
+
raise ValueError(
|
|
161
|
+
f"Password cannot be less than 8 characters in length, got {length}."
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
s0 = list(string.ascii_uppercase)
|
|
165
|
+
s1 = list(string.ascii_lowercase)
|
|
166
|
+
s2 = list(string.digits)
|
|
167
|
+
s3 = list("!@#$%^*()[]-_+")
|
|
168
|
+
|
|
169
|
+
while True:
|
|
170
|
+
password = "".join(
|
|
171
|
+
[secrets.choice(s0 + s1 + s2 + s3) for _ in range(length)]
|
|
172
|
+
)
|
|
173
|
+
if (
|
|
174
|
+
any(c.islower() for c in password)
|
|
175
|
+
and any(c.isupper() for c in password)
|
|
176
|
+
and sum(c.isdigit() for c in password) >= 3
|
|
177
|
+
and any(c in s3 for c in password)
|
|
178
|
+
):
|
|
179
|
+
break
|
|
180
|
+
return password
|
|
@@ -128,11 +128,11 @@ wheels = [
|
|
|
128
128
|
|
|
129
129
|
[[package]]
|
|
130
130
|
name = "asgiref"
|
|
131
|
-
version = "3.
|
|
131
|
+
version = "3.11.0"
|
|
132
132
|
source = { registry = "https://pypi.org/simple" }
|
|
133
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
133
|
+
sdist = { url = "https://files.pythonhosted.org/packages/76/b9/4db2509eabd14b4a8c71d1b24c8d5734c52b8560a7b1e1a8b56c8d25568b/asgiref-3.11.0.tar.gz", hash = "sha256:13acff32519542a1736223fb79a715acdebe24286d98e8b164a73085f40da2c4", size = 37969 }
|
|
134
134
|
wheels = [
|
|
135
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
135
|
+
{ url = "https://files.pythonhosted.org/packages/91/be/317c2c55b8bbec407257d45f5c8d1b6867abc76d12043f2d3d58c538a4ea/asgiref-3.11.0-py3-none-any.whl", hash = "sha256:1db9021efadb0d9512ce8ffaf72fcef601c7b73a8807a1bb2ef143dc6b14846d", size = 24096 },
|
|
136
136
|
]
|
|
137
137
|
|
|
138
138
|
[[package]]
|
|
@@ -180,15 +180,15 @@ wheels = [
|
|
|
180
180
|
|
|
181
181
|
[[package]]
|
|
182
182
|
name = "beautifulsoup4"
|
|
183
|
-
version = "4.14.
|
|
183
|
+
version = "4.14.3"
|
|
184
184
|
source = { registry = "https://pypi.org/simple" }
|
|
185
185
|
dependencies = [
|
|
186
186
|
{ name = "soupsieve" },
|
|
187
187
|
{ name = "typing-extensions" },
|
|
188
188
|
]
|
|
189
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
189
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737 }
|
|
190
190
|
wheels = [
|
|
191
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
191
|
+
{ url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721 },
|
|
192
192
|
]
|
|
193
193
|
|
|
194
194
|
[[package]]
|
|
@@ -268,21 +268,21 @@ wheels = [
|
|
|
268
268
|
|
|
269
269
|
[[package]]
|
|
270
270
|
name = "django"
|
|
271
|
-
version = "
|
|
271
|
+
version = "6.0"
|
|
272
272
|
source = { registry = "https://pypi.org/simple" }
|
|
273
273
|
dependencies = [
|
|
274
274
|
{ name = "asgiref" },
|
|
275
275
|
{ name = "sqlparse" },
|
|
276
276
|
{ name = "tzdata", marker = "sys_platform == 'win32'" },
|
|
277
277
|
]
|
|
278
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
278
|
+
sdist = { url = "https://files.pythonhosted.org/packages/15/75/19762bfc4ea556c303d9af8e36f0cd910ab17dff6c8774644314427a2120/django-6.0.tar.gz", hash = "sha256:7b0c1f50c0759bbe6331c6a39c89ae022a84672674aeda908784617ef47d8e26", size = 10932418 }
|
|
279
279
|
wheels = [
|
|
280
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
280
|
+
{ url = "https://files.pythonhosted.org/packages/d7/ae/f19e24789a5ad852670d6885f5480f5e5895576945fcc01817dfd9bc002a/django-6.0-py3-none-any.whl", hash = "sha256:1cc2c7344303bbfb7ba5070487c17f7fc0b7174bbb0a38cebf03c675f5f19b6d", size = 8339181 },
|
|
281
281
|
]
|
|
282
282
|
|
|
283
283
|
[[package]]
|
|
284
284
|
name = "django-stubs"
|
|
285
|
-
version = "5.2.
|
|
285
|
+
version = "5.2.8"
|
|
286
286
|
source = { registry = "https://pypi.org/simple" }
|
|
287
287
|
dependencies = [
|
|
288
288
|
{ name = "django" },
|
|
@@ -290,22 +290,22 @@ dependencies = [
|
|
|
290
290
|
{ name = "types-pyyaml" },
|
|
291
291
|
{ name = "typing-extensions" },
|
|
292
292
|
]
|
|
293
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
293
|
+
sdist = { url = "https://files.pythonhosted.org/packages/6c/75/97626224fd8f1787bb6f7f06944efcfddd5da7764bf741cf7f59d102f4a0/django_stubs-5.2.8.tar.gz", hash = "sha256:9bba597c9a8ed8c025cae4696803d5c8be1cf55bfc7648a084cbf864187e2f8b", size = 257709 }
|
|
294
294
|
wheels = [
|
|
295
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
295
|
+
{ url = "https://files.pythonhosted.org/packages/7d/3f/7c9543ad5ade5ce1d33d187a3abd82164570314ebee72c6206ab5c044ebf/django_stubs-5.2.8-py3-none-any.whl", hash = "sha256:a3c63119fd7062ac63d58869698d07c9e5ec0561295c4e700317c54e8d26716c", size = 508136 },
|
|
296
296
|
]
|
|
297
297
|
|
|
298
298
|
[[package]]
|
|
299
299
|
name = "django-stubs-ext"
|
|
300
|
-
version = "5.2.
|
|
300
|
+
version = "5.2.8"
|
|
301
301
|
source = { registry = "https://pypi.org/simple" }
|
|
302
302
|
dependencies = [
|
|
303
303
|
{ name = "django" },
|
|
304
304
|
{ name = "typing-extensions" },
|
|
305
305
|
]
|
|
306
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
306
|
+
sdist = { url = "https://files.pythonhosted.org/packages/14/a2/d67f4a5200ff7626b104eddceaf529761cba4ed318a73ffdb0677551be73/django_stubs_ext-5.2.8.tar.gz", hash = "sha256:b39938c46d7a547cd84e4a6378dbe51a3dd64d70300459087229e5fee27e5c6b", size = 6487 }
|
|
307
307
|
wheels = [
|
|
308
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
308
|
+
{ url = "https://files.pythonhosted.org/packages/da/2d/cb0151b780c3730cf0f2c0fcb1b065a5e88f877cf7a9217483c375353af1/django_stubs_ext-5.2.8-py3-none-any.whl", hash = "sha256:1dd5470c9675591362c78a157a3cf8aec45d0e7a7f0cf32f227a1363e54e0652", size = 9949 },
|
|
309
309
|
]
|
|
310
310
|
|
|
311
311
|
[[package]]
|
|
@@ -748,7 +748,7 @@ wheels = [
|
|
|
748
748
|
|
|
749
749
|
[[package]]
|
|
750
750
|
name = "python-terminusgps"
|
|
751
|
-
version = "
|
|
751
|
+
version = "50.0.0"
|
|
752
752
|
source = { editable = "." }
|
|
753
753
|
dependencies = [
|
|
754
754
|
{ name = "authorizenet" },
|
|
@@ -979,11 +979,11 @@ wheels = [
|
|
|
979
979
|
|
|
980
980
|
[[package]]
|
|
981
981
|
name = "sqlparse"
|
|
982
|
-
version = "0.5.
|
|
982
|
+
version = "0.5.4"
|
|
983
983
|
source = { registry = "https://pypi.org/simple" }
|
|
984
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
984
|
+
sdist = { url = "https://files.pythonhosted.org/packages/18/67/701f86b28d63b2086de47c942eccf8ca2208b3be69715a1119a4e384415a/sqlparse-0.5.4.tar.gz", hash = "sha256:4396a7d3cf1cd679c1be976cf3dc6e0a51d0111e87787e7a8d780e7d5a998f9e", size = 120112 }
|
|
985
985
|
wheels = [
|
|
986
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
986
|
+
{ url = "https://files.pythonhosted.org/packages/25/70/001ee337f7aa888fb2e3f5fd7592a6afc5283adb1ed44ce8df5764070f22/sqlparse-0.5.4-py3-none-any.whl", hash = "sha256:99a9f0314977b76d776a0fcb8554de91b9bb8a18560631d6bc48721d07023dcb", size = 45933 },
|
|
987
987
|
]
|
|
988
988
|
|
|
989
989
|
[[package]]
|
|
@@ -1006,20 +1006,20 @@ wheels = [
|
|
|
1006
1006
|
|
|
1007
1007
|
[[package]]
|
|
1008
1008
|
name = "tzdata"
|
|
1009
|
-
version = "2025.
|
|
1009
|
+
version = "2025.3"
|
|
1010
1010
|
source = { registry = "https://pypi.org/simple" }
|
|
1011
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1011
|
+
sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772 }
|
|
1012
1012
|
wheels = [
|
|
1013
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1013
|
+
{ url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521 },
|
|
1014
1014
|
]
|
|
1015
1015
|
|
|
1016
1016
|
[[package]]
|
|
1017
1017
|
name = "urllib3"
|
|
1018
|
-
version = "2.
|
|
1018
|
+
version = "2.6.2"
|
|
1019
1019
|
source = { registry = "https://pypi.org/simple" }
|
|
1020
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1020
|
+
sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930 }
|
|
1021
1021
|
wheels = [
|
|
1022
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1022
|
+
{ url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182 },
|
|
1023
1023
|
]
|
|
1024
1024
|
|
|
1025
1025
|
[[package]]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .factory import WialonObjectFactory
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import collections.abc
|
|
2
|
-
import decimal
|
|
3
|
-
import typing
|
|
4
|
-
|
|
5
|
-
from terminusgps.wialon.items.base import WialonObject, requires_id
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class WialonAccount(WialonObject):
|
|
9
|
-
"""A Wialon `account <https://help.wialon.com/en/wialon-hosting/user-guide/management-system/accounts-and-resources>`_."""
|
|
10
|
-
|
|
11
|
-
def create(
|
|
12
|
-
self, resource_id: int | str, billing_plan: str
|
|
13
|
-
) -> dict[str, str]:
|
|
14
|
-
"""
|
|
15
|
-
Creates the account in Wialon and sets its id.
|
|
16
|
-
|
|
17
|
-
:param resource_id: A Wialon resource id.
|
|
18
|
-
:type creator_id: int | str
|
|
19
|
-
:param billing_plan: A Wialon account billing plan.
|
|
20
|
-
:type billing_plan: str
|
|
21
|
-
:raises ValueError: If ``resource_id`` wasn't a digit.
|
|
22
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
23
|
-
:returns: A Wialon object dictionary.
|
|
24
|
-
:rtype: dict[str, str]
|
|
25
|
-
|
|
26
|
-
"""
|
|
27
|
-
if isinstance(resource_id, str) and not resource_id.isdigit():
|
|
28
|
-
raise ValueError(
|
|
29
|
-
f"'resource_id' must be a digit, got '{resource_id}'."
|
|
30
|
-
)
|
|
31
|
-
response = self.session.wialon_api.account_create_account(
|
|
32
|
-
**{"itemId": resource_id, "plan": billing_plan}
|
|
33
|
-
)
|
|
34
|
-
self.id = resource_id
|
|
35
|
-
return response
|
|
36
|
-
|
|
37
|
-
@typing.override
|
|
38
|
-
@requires_id
|
|
39
|
-
def delete(
|
|
40
|
-
self, reasons: collections.abc.Collection[str] | None = None
|
|
41
|
-
) -> dict[str, str]:
|
|
42
|
-
"""
|
|
43
|
-
Deletes the account in Wialon.
|
|
44
|
-
|
|
45
|
-
:param reasons: An optional collection of reason strings. Default is :py:obj:`None`.
|
|
46
|
-
:type reasons: ~collections.abc.Collection[str] | None
|
|
47
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
48
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
49
|
-
:returns: An empty dictionary.
|
|
50
|
-
:rtype: dict[str, str]
|
|
51
|
-
|
|
52
|
-
"""
|
|
53
|
-
return self.session.wialon_api.account_delete_account(
|
|
54
|
-
**{"itemId": self.id, "reasons": reasons}
|
|
55
|
-
if reasons is not None
|
|
56
|
-
else {"itemId": self.id}
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
@requires_id
|
|
60
|
-
def activate(self) -> dict[str, str]:
|
|
61
|
-
"""
|
|
62
|
-
Enables the account in Wialon.
|
|
63
|
-
|
|
64
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
65
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
66
|
-
:returns: An empty dictionary.
|
|
67
|
-
:rtype: dict[str, str]
|
|
68
|
-
|
|
69
|
-
"""
|
|
70
|
-
return self.session.wialon_api.account_enable_account(
|
|
71
|
-
**{"itemId": self.id, "enable": 1}
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
@requires_id
|
|
75
|
-
def deactivate(self) -> dict[str, str]:
|
|
76
|
-
"""
|
|
77
|
-
Disables the account in Wialon.
|
|
78
|
-
|
|
79
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
80
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
81
|
-
:returns: An empty dictionary.
|
|
82
|
-
:rtype: dict[str, str]
|
|
83
|
-
|
|
84
|
-
"""
|
|
85
|
-
return self.session.wialon_api.account_enable_account(
|
|
86
|
-
**{"itemId": self.id, "enable": 0}
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
@requires_id
|
|
90
|
-
def do_payment(
|
|
91
|
-
self,
|
|
92
|
-
balance_update: decimal.Decimal,
|
|
93
|
-
days_update: int,
|
|
94
|
-
description: str,
|
|
95
|
-
) -> dict[str, str]:
|
|
96
|
-
"""
|
|
97
|
-
Makes an account payment in Wialon.
|
|
98
|
-
|
|
99
|
-
:param balance_update: Amount to update the account balance by. Can be negative.
|
|
100
|
-
:type balance_update: ~decimal.Decimal
|
|
101
|
-
:param days_update: Amount of days to add to the account.
|
|
102
|
-
:type days_update: str
|
|
103
|
-
:param description: A description for the payment.
|
|
104
|
-
:type description: str
|
|
105
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
106
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
107
|
-
:returns: An empty dictionary.
|
|
108
|
-
:rtype: dict[str, str]
|
|
109
|
-
|
|
110
|
-
"""
|
|
111
|
-
return self.session.wialon_api.account_do_payment(
|
|
112
|
-
**{
|
|
113
|
-
"itemId": self.id,
|
|
114
|
-
"balanceUpdate": str(balance_update),
|
|
115
|
-
"daysUpdate": days_update,
|
|
116
|
-
"description": description,
|
|
117
|
-
}
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
@requires_id
|
|
121
|
-
def set_dealer_rights(self, enabled: bool) -> dict[str, str]:
|
|
122
|
-
"""
|
|
123
|
-
Enables or disables the account's dealer rights in Wialon.
|
|
124
|
-
|
|
125
|
-
:param enabled: Whether to set the account as a dealer or not.
|
|
126
|
-
:type enabled: bool
|
|
127
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
128
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
129
|
-
:returns: An empty dictionary.
|
|
130
|
-
:rtype: dict[str, str]
|
|
131
|
-
|
|
132
|
-
"""
|
|
133
|
-
return self.session.wialon_api.account_update_dealer_rights(
|
|
134
|
-
**{"itemId": self.id, "enable": int(enabled)}
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
@requires_id
|
|
138
|
-
def set_flags(
|
|
139
|
-
self,
|
|
140
|
-
flags: int,
|
|
141
|
-
block_balance: decimal.Decimal = decimal.Decimal("0.00"),
|
|
142
|
-
deny_balance: decimal.Decimal = decimal.Decimal("0.00"),
|
|
143
|
-
) -> dict[str, str]:
|
|
144
|
-
"""
|
|
145
|
-
Sets settings flags for the account in Wialon.
|
|
146
|
-
|
|
147
|
-
:param flags: A Wialon account settings flag integer.
|
|
148
|
-
:type flags: int
|
|
149
|
-
:param block_balance: Balance required for account blocking. Default is ``0.00``.
|
|
150
|
-
:type block_balance: ~decimal.Decimal
|
|
151
|
-
:param deny_balance: Balance required for service denial. Default is ``0.00``.
|
|
152
|
-
:type deny_balance: ~decimal.Decimal
|
|
153
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
154
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
155
|
-
:returns: An empty dictionary.
|
|
156
|
-
:rtype: dict[str, str]
|
|
157
|
-
|
|
158
|
-
"""
|
|
159
|
-
return self.session.wialon_api.account_update_flags(
|
|
160
|
-
**{
|
|
161
|
-
"itemId": self.id,
|
|
162
|
-
"flags": flags,
|
|
163
|
-
"blockBalance": block_balance,
|
|
164
|
-
"denyBalance": deny_balance,
|
|
165
|
-
}
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
@requires_id
|
|
169
|
-
def set_plan(self, name: str) -> dict[str, str]:
|
|
170
|
-
"""
|
|
171
|
-
Sets the account's billing plan to ``name``.
|
|
172
|
-
|
|
173
|
-
:param name: A Wialon billing plan name.
|
|
174
|
-
:type name: str
|
|
175
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
176
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
177
|
-
:returns: An empty dictionary.
|
|
178
|
-
:rtype: dict[str, str]
|
|
179
|
-
|
|
180
|
-
"""
|
|
181
|
-
return self.session.wialon_api.account_update_plan(
|
|
182
|
-
**{"itemId": self.id, "plan": name}
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
@requires_id
|
|
186
|
-
def set_minimum_days(self, days: int) -> dict[str, str]:
|
|
187
|
-
"""
|
|
188
|
-
Sets the account's minimum days to ``days`` in Wialon.
|
|
189
|
-
|
|
190
|
-
:param days: Minimum number of days as an integer.
|
|
191
|
-
:type days: int
|
|
192
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
193
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
194
|
-
:returns: An empty dictionary.
|
|
195
|
-
:rtype: dict[str, str]
|
|
196
|
-
|
|
197
|
-
"""
|
|
198
|
-
return self.session.wialon_api.account_update_min_days(
|
|
199
|
-
**{"itemId": self.id, "minDays": days}
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
@requires_id
|
|
203
|
-
def get_data(self, response_type: int = 1) -> dict[str, str]:
|
|
204
|
-
"""
|
|
205
|
-
Returns account data from Wialon.
|
|
206
|
-
|
|
207
|
-
:param response_type: A response flag integer. Default is ``1``.
|
|
208
|
-
:type response_type: int
|
|
209
|
-
:raises AssertionError: If the Wialon account id wasn't set.
|
|
210
|
-
:raises ~terminusgps.wialon.session.WialonAPIError: If something went wrong calling the Wialon API.
|
|
211
|
-
:returns: A dictionary containing the account's data from Wialon.
|
|
212
|
-
:rtype: dict[str, str]
|
|
213
|
-
|
|
214
|
-
"""
|
|
215
|
-
return self.session.wialon_api.account_get_account_data(
|
|
216
|
-
**{"itemId": self.id, "type": response_type}
|
|
217
|
-
)
|