python-terminusgps 31.0.0__py3-none-any.whl → 31.1.0__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.
- {python_terminusgps-31.0.0.dist-info → python_terminusgps-31.1.0.dist-info}/METADATA +13 -1
- {python_terminusgps-31.0.0.dist-info → python_terminusgps-31.1.0.dist-info}/RECORD +12 -12
- terminusgps/django/mixins.py +1 -0
- terminusgps/twilio/caller.py +64 -10
- terminusgps/twilio/validators.py +1 -1
- terminusgps/wialon/items/base.py +69 -1
- terminusgps/wialon/items/resource.py +1 -1
- terminusgps/wialon/items/unit.py +53 -1
- terminusgps/wialon/utils.py +3 -4
- terminusgps/wialon/validators.py +1 -1
- {python_terminusgps-31.0.0.dist-info → python_terminusgps-31.1.0.dist-info}/WHEEL +0 -0
- {python_terminusgps-31.0.0.dist-info → python_terminusgps-31.1.0.dist-info}/licenses/COPYING +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-terminusgps
|
|
3
|
-
Version: 31.
|
|
3
|
+
Version: 31.1.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://app.terminusgps.com/docs/apps/python-terminusgps/index.html
|
|
6
6
|
Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
|
|
@@ -22,3 +22,15 @@ Requires-Dist: pandas>=2.2.3
|
|
|
22
22
|
Requires-Dist: python-wialon>=1.2.4
|
|
23
23
|
Requires-Dist: pyzbar>=0.1.9
|
|
24
24
|
Requires-Dist: twilio>=9.4.5
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# python-terminusgps
|
|
28
|
+
|
|
29
|
+
[python-terminusgps](https://docs.terminusgps.com/) is a collection of Python libraries intended for use by Terminus GPS developers.
|
|
30
|
+
|
|
31
|
+
Currently, the following services are streamlined for web development:
|
|
32
|
+
|
|
33
|
+
* [AWS/boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)
|
|
34
|
+
* [Authorizenet API](https://developer.authorize.net/api/reference/index.html)
|
|
35
|
+
* [Twilio API](https://www.twilio.com/docs)
|
|
36
|
+
* [Wialon Remote API](https://sdk.wialon.com/wiki/en/sidebar/remoteapi/apiref/apiref)
|
|
@@ -13,28 +13,28 @@ terminusgps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
13
13
|
terminusgps/aws/connect.py,sha256=TWf2bVz6LqSNQfVD7FKRn3K71VuLOwBj05Gs-9BsROg,693
|
|
14
14
|
terminusgps/aws/secrets.py,sha256=MxQEmmBLpMUQ2tYAsHdCYf-7RZ84LiogdKcTsACX5dw,361
|
|
15
15
|
terminusgps/django/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
terminusgps/django/mixins.py,sha256=
|
|
16
|
+
terminusgps/django/mixins.py,sha256=Q9ZJuzpk3d9lDnlVA8ZTVvnZWxB13p08EQ8yVJcztn4,1034
|
|
17
17
|
terminusgps/django/settings.py,sha256=vY5yNjyMu-7Ya0bIPWUvrrSLERtxHGdkfeoY4Ul6cP0,613
|
|
18
18
|
terminusgps/django/utils.py,sha256=SYDQyHA5tTuVwdpZGsCtf0LpTTD0ilRKoxa8StfSTpQ,156
|
|
19
19
|
terminusgps/twilio/__init__.py,sha256=dYo41F2jft_eHDWSUtSpKGSRG1bewq_qClqilUJZkYM,33
|
|
20
|
-
terminusgps/twilio/caller.py,sha256=
|
|
21
|
-
terminusgps/twilio/validators.py,sha256=
|
|
20
|
+
terminusgps/twilio/caller.py,sha256=Q0wcJ5aaNDGvKfht7ARwPTFdqpFoB81DmZ_K2oZixyA,5077
|
|
21
|
+
terminusgps/twilio/validators.py,sha256=HWCpzgDXTedofty4Zhrm2OenbgtkzrDUC08B1l15gqc,1112
|
|
22
22
|
terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
23
|
terminusgps/wialon/constants.py,sha256=-fRrvtQuSAJ6hpBJzp_Xa4GDI4LuQbqZ1z1L_QFzZiE,5609
|
|
24
24
|
terminusgps/wialon/flags.py,sha256=M50EdhxQ8IMnJnU0mrHK7-h8Asc6tvNiTOOfd1dBW6A,12815
|
|
25
25
|
terminusgps/wialon/logger.py,sha256=nUBsaLMaffSaAHGHAM6mFXDzix9hbNecVtA3INVtii8,968
|
|
26
26
|
terminusgps/wialon/session.py,sha256=emB0XHJjFObtb6WbttsXZXTeRaPztcbjAV212B_Ssek,9781
|
|
27
|
-
terminusgps/wialon/utils.py,sha256=
|
|
28
|
-
terminusgps/wialon/validators.py,sha256=
|
|
27
|
+
terminusgps/wialon/utils.py,sha256=eRo-NHWEi8zq8mMWFnCs8__iDbkpPvSkCqcsdr13ltI,9953
|
|
28
|
+
terminusgps/wialon/validators.py,sha256=CVEpFsxqplEcpv4U2ipA6v9y5cSrMKFUXLvze-3vs4U,4223
|
|
29
29
|
terminusgps/wialon/items/__init__.py,sha256=3BVthghekMvhMQSzQgBMlD_phxmKSmp3Zvmo-z0O8Bs,211
|
|
30
|
-
terminusgps/wialon/items/base.py,sha256=
|
|
31
|
-
terminusgps/wialon/items/resource.py,sha256=
|
|
30
|
+
terminusgps/wialon/items/base.py,sha256=y0z3eW_Gz7dlusKHj3T3TH3_nPsx5yGUKuImEJSK10M,10215
|
|
31
|
+
terminusgps/wialon/items/resource.py,sha256=FmuY0thel8aIThSWKJXur72Sptful3MuwBfIn9bdeaY,14616
|
|
32
32
|
terminusgps/wialon/items/retranslator.py,sha256=sVEWrp8q1I-tO_rMTCH7TeQDDbZryIq8d9KVnhYyhH0,3795
|
|
33
33
|
terminusgps/wialon/items/route.py,sha256=amNPKZqgl8pEzKA_XJudnvBPzEsfHTmrC7uF15sZVI4,1216
|
|
34
|
-
terminusgps/wialon/items/unit.py,sha256=
|
|
34
|
+
terminusgps/wialon/items/unit.py,sha256=jq4S8EV_yukRTTE8rr2oXpu_9AdXDFYA6-GCjkR6shw,12282
|
|
35
35
|
terminusgps/wialon/items/unit_group.py,sha256=QV2ZZgICaN3n6W1pFIyMLyNKB6KYBsLyKG64i-qXoOg,4113
|
|
36
36
|
terminusgps/wialon/items/user.py,sha256=N30wdejdG7LXrgafdKZH74YArGkX3xpZfTucn3m3aqM,7155
|
|
37
|
-
python_terminusgps-31.
|
|
38
|
-
python_terminusgps-31.
|
|
39
|
-
python_terminusgps-31.
|
|
40
|
-
python_terminusgps-31.
|
|
37
|
+
python_terminusgps-31.1.0.dist-info/METADATA,sha256=MIfipx-9aKDFbozGWwy-i6MXtywcZMOk8O968CjS2TQ,1630
|
|
38
|
+
python_terminusgps-31.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
39
|
+
python_terminusgps-31.1.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
40
|
+
python_terminusgps-31.1.0.dist-info/RECORD,,
|
terminusgps/django/mixins.py
CHANGED
|
@@ -24,6 +24,7 @@ class HtmxTemplateResponseMixin(TemplateResponseMixin):
|
|
|
24
24
|
def render_to_response(
|
|
25
25
|
self, context: dict[str, typing.Any], **response_kwargs: typing.Any
|
|
26
26
|
) -> HttpResponse:
|
|
27
|
+
"""Sets :py:attr:`template_name` to :py:attr:`partial_template_name` if necessary."""
|
|
27
28
|
htmx_request = self.request.headers.get("HX-Request", False)
|
|
28
29
|
boosted = self.request.headers.get("HX-Boosted", False)
|
|
29
30
|
|
terminusgps/twilio/caller.py
CHANGED
|
@@ -17,30 +17,53 @@ if not hasattr(settings, "TWILIO_MESSAGING_SID"):
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class TwilioCaller:
|
|
20
|
-
def __init__(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
client_sid: str | None = None,
|
|
23
|
+
client_token: str | None = None,
|
|
24
|
+
from_number: str | None = None,
|
|
25
|
+
messaging_sid: str | None = None,
|
|
26
|
+
) -> None:
|
|
27
|
+
"""
|
|
28
|
+
Sets Twilio client session variables.
|
|
29
|
+
|
|
30
|
+
All parameters are optional, default values are pulled from a Django settings module.
|
|
31
|
+
|
|
32
|
+
:param client_sid: A Twilio client session id.
|
|
33
|
+
:type client_sid: :py:obj:`str` | :py:obj:`None`
|
|
34
|
+
:param client_token: A Twilio client API token.
|
|
35
|
+
:type client_token: :py:obj:`str` | :py:obj:`None`
|
|
36
|
+
:param from_number: Phone number used to send notifications.
|
|
37
|
+
:type from_number: :py:obj:`str` | :py:obj:`None`
|
|
38
|
+
:param messaging_sid: A Twilio client messaging service session id.
|
|
39
|
+
:type messaging_sid: :py:obj:`str` | :py:obj:`None`
|
|
40
|
+
:returns: Nothing.
|
|
41
|
+
:rtype: :py:obj:`None`
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
self._client_sid = client_sid or settings.TWILIO_SID
|
|
45
|
+
self._client_token = client_token or settings.TWILIO_TOKEN
|
|
46
|
+
self._from_number = from_number or settings.TWILIO_FROM_NUMBER
|
|
47
|
+
self._messaging_sid = messaging_sid or settings.TWILIO_MESSAGING_SID
|
|
26
48
|
|
|
27
49
|
def __enter__(self) -> "TwilioCaller":
|
|
28
|
-
"""
|
|
50
|
+
"""Opens a context manager and creates an asyncronous Twilio client."""
|
|
29
51
|
self.client = twilio.rest.Client(
|
|
30
|
-
self.client_sid, self.
|
|
52
|
+
self.client_sid, self._client_token, http_client=AsyncTwilioHttpClient()
|
|
31
53
|
)
|
|
32
54
|
return self
|
|
33
55
|
|
|
34
56
|
def __exit__(self, exc_type, exc_value, exc_tb) -> None:
|
|
57
|
+
"""Closes the context manager."""
|
|
35
58
|
return None
|
|
36
59
|
|
|
37
|
-
|
|
60
|
+
def create_notification(
|
|
38
61
|
self, to_number: str, message: str, method: str = "sms"
|
|
39
62
|
) -> asyncio.Task[Any]:
|
|
40
63
|
"""
|
|
41
64
|
Returns an awaitable notification task.
|
|
42
65
|
|
|
43
|
-
|
|
66
|
+
Valid methods are ``"sms"``, ``"call"`` and ``"phone"``.
|
|
44
67
|
|
|
45
68
|
:param to_number: A phone number to notify.
|
|
46
69
|
:type to_number: :py:obj:`str`
|
|
@@ -48,6 +71,7 @@ class TwilioCaller:
|
|
|
48
71
|
:type message: :py:obj:`str`
|
|
49
72
|
:param method: A notification method. Default is ``"sms"``.
|
|
50
73
|
:type method: :py:obj:`str`
|
|
74
|
+
:raises ValueError: If ``method`` is invalid.
|
|
51
75
|
:returns: An awaitable task.
|
|
52
76
|
:rtype: :py:obj:`~asyncio.Task`
|
|
53
77
|
|
|
@@ -100,3 +124,33 @@ class TwilioCaller:
|
|
|
100
124
|
body=message,
|
|
101
125
|
messaging_service_sid=self.messaging_sid,
|
|
102
126
|
)
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def client_sid(self) -> str:
|
|
130
|
+
"""
|
|
131
|
+
Client session id.
|
|
132
|
+
|
|
133
|
+
:type: :py:obj:`str`
|
|
134
|
+
|
|
135
|
+
"""
|
|
136
|
+
return self._client_sid
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def from_number(self) -> str:
|
|
140
|
+
"""
|
|
141
|
+
Origin phone number.
|
|
142
|
+
|
|
143
|
+
:type: :py:obj:`str`
|
|
144
|
+
|
|
145
|
+
"""
|
|
146
|
+
return self._from_number
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def messaging_sid(self) -> str:
|
|
150
|
+
"""
|
|
151
|
+
Messaging service session id.
|
|
152
|
+
|
|
153
|
+
:type: :py:obj:`str`
|
|
154
|
+
|
|
155
|
+
"""
|
|
156
|
+
return self._messaging_sid
|
terminusgps/twilio/validators.py
CHANGED
|
@@ -27,5 +27,5 @@ def validate_phone_number(value: str) -> None:
|
|
|
27
27
|
raise ValidationError(
|
|
28
28
|
_("Phone number cannot be greater than %(max)s characters, got %(len)s."),
|
|
29
29
|
code="invalid",
|
|
30
|
-
params={"max":
|
|
30
|
+
params={"max": max_length, "len": len(value)},
|
|
31
31
|
)
|
terminusgps/wialon/items/base.py
CHANGED
|
@@ -9,6 +9,20 @@ class WialonBase:
|
|
|
9
9
|
def __init__(
|
|
10
10
|
self, id: str | int | None, session: WialonSession, *args, **kwargs
|
|
11
11
|
) -> None:
|
|
12
|
+
"""
|
|
13
|
+
Sets the Wialon session and id for the Wialon object.
|
|
14
|
+
|
|
15
|
+
If no id was provided, :py:meth:`create` is executed to get one.
|
|
16
|
+
|
|
17
|
+
:param id: An optional Wialon object id.
|
|
18
|
+
:type id: :py:obj:`str` | :py:obj:`int` | :py:obj:`None`
|
|
19
|
+
:param session: A valid Wialon API session.
|
|
20
|
+
:type session: :py:obj:`~terminusgps.wialon.session.WialonSession`
|
|
21
|
+
:raises ValueError: If ``id`` was a string that contained non-digit values.
|
|
22
|
+
:returns: Nothing.
|
|
23
|
+
:rtype: :py:obj:`None`
|
|
24
|
+
|
|
25
|
+
"""
|
|
12
26
|
if isinstance(id, str) and not id.isdigit():
|
|
13
27
|
raise ValueError(f"'id' must be a digit. Got '{id}'.")
|
|
14
28
|
|
|
@@ -19,13 +33,23 @@ class WialonBase:
|
|
|
19
33
|
self._access_lvl = None
|
|
20
34
|
|
|
21
35
|
def __str__(self) -> str:
|
|
36
|
+
"""Returns the Wialon object id as a string."""
|
|
22
37
|
return str(self.id)
|
|
23
38
|
|
|
24
39
|
def __repr__(self) -> str:
|
|
40
|
+
"""Returns the Wialon object type and parameters used to initialize it."""
|
|
25
41
|
return f"{type(self).__name__}(id={self.id}, session={self.session.id})"
|
|
26
42
|
|
|
27
43
|
def populate(self) -> None:
|
|
28
|
-
"""
|
|
44
|
+
"""
|
|
45
|
+
Retrieves and saves the latest data for the item from Wialon.
|
|
46
|
+
|
|
47
|
+
:raises AssertionError: If :py:attr:`id` wasn't set.
|
|
48
|
+
:returns: Nothing.
|
|
49
|
+
:rtype: :py:obj:`None`
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
assert self.id, "No Wialon object id set."
|
|
29
53
|
response = self.session.wialon_api.core_search_item(
|
|
30
54
|
**{"id": str(self.id), "flags": flags.DataFlag.UNIT_BASE}
|
|
31
55
|
)
|
|
@@ -111,6 +135,50 @@ class WialonBase:
|
|
|
111
135
|
)
|
|
112
136
|
self._name = new_name
|
|
113
137
|
|
|
138
|
+
def get_cfield_id(self, key: str) -> int | None:
|
|
139
|
+
"""
|
|
140
|
+
Returns a custom field id by its key, if it exists.
|
|
141
|
+
|
|
142
|
+
:param key: A custom field key.
|
|
143
|
+
:type key: :py:obj:`str`
|
|
144
|
+
:returns: A custom field id, if any.
|
|
145
|
+
:rtype: :py:obj:`int` | :py:obj:`None`
|
|
146
|
+
|
|
147
|
+
"""
|
|
148
|
+
cfields = (
|
|
149
|
+
self.session.wialon_api.core_search_item(
|
|
150
|
+
**{"id": str(self.id), "flags": flags.DataFlag.UNIT_CUSTOM_FIELDS}
|
|
151
|
+
)
|
|
152
|
+
.get("item", {})
|
|
153
|
+
.get("flds", {})
|
|
154
|
+
.values()
|
|
155
|
+
)
|
|
156
|
+
for field in cfields:
|
|
157
|
+
if field["n"] == key:
|
|
158
|
+
return int(field["id"])
|
|
159
|
+
|
|
160
|
+
def get_afield_id(self, key: str) -> int | None:
|
|
161
|
+
"""
|
|
162
|
+
Returns an admin field id by its key, if it exists.
|
|
163
|
+
|
|
164
|
+
:param key: An admin field key.
|
|
165
|
+
:type key: :py:obj:`str`
|
|
166
|
+
:returns: An admin field id, if any.
|
|
167
|
+
:rtype: :py:obj:`int` | :py:obj:`None`
|
|
168
|
+
|
|
169
|
+
"""
|
|
170
|
+
afields = (
|
|
171
|
+
self.session.wialon_api.core_search_item(
|
|
172
|
+
**{"id": str(self.id), "flags": flags.DataFlag.UNIT_ADMIN_FIELDS}
|
|
173
|
+
)
|
|
174
|
+
.get("item", {})
|
|
175
|
+
.get("aflds", {})
|
|
176
|
+
.values()
|
|
177
|
+
)
|
|
178
|
+
for field in afields:
|
|
179
|
+
if field["n"] == key:
|
|
180
|
+
return int(field["id"])
|
|
181
|
+
|
|
114
182
|
def add_afield(self, key: str, value: str) -> None:
|
|
115
183
|
"""
|
|
116
184
|
Adds an admin field to the Wialon object.
|
terminusgps/wialon/items/unit.py
CHANGED
|
@@ -70,7 +70,7 @@ class WialonUnit(WialonBase):
|
|
|
70
70
|
|
|
71
71
|
def get_position(self) -> dict | None:
|
|
72
72
|
return self.session.wialon_api.core_search_item(
|
|
73
|
-
**{"id": self.id, "flags": flags.DataFlag.UNIT_POSITION
|
|
73
|
+
**{"id": self.id, "flags": flags.DataFlag.UNIT_POSITION}
|
|
74
74
|
)
|
|
75
75
|
|
|
76
76
|
@property
|
|
@@ -152,10 +152,62 @@ class WialonUnit(WialonBase):
|
|
|
152
152
|
|
|
153
153
|
@property
|
|
154
154
|
def image_url(self) -> str | None:
|
|
155
|
+
"""Returns an absolute url to the unit's icon in Wialon."""
|
|
155
156
|
if hasattr(settings, "WIALON_HOST"):
|
|
156
157
|
return urljoin(settings.WIALON_HOST, self._image_uri)
|
|
157
158
|
return urljoin("https://hst-api.wialon.com", self._image_uri)
|
|
158
159
|
|
|
160
|
+
def assign_to_number(self, value: str) -> None:
|
|
161
|
+
"""
|
|
162
|
+
Sets ``value`` to the unit's ``to_number`` custom field.
|
|
163
|
+
|
|
164
|
+
:param value: A new value for the unit's ``to_number`` custom field.
|
|
165
|
+
:type value: :py:obj:`str`
|
|
166
|
+
:returns: Nothing.
|
|
167
|
+
:rtype: :py:obj:`None`
|
|
168
|
+
|
|
169
|
+
"""
|
|
170
|
+
cfield_key: str = "to_number"
|
|
171
|
+
cfield_val: str = value
|
|
172
|
+
cfield_id: int | None = self.get_cfield_id(cfield_key)
|
|
173
|
+
|
|
174
|
+
if cfield_id:
|
|
175
|
+
self.update_cfield(cfield_id, cfield_key, cfield_val)
|
|
176
|
+
|
|
177
|
+
def assign_iccid(self, value: str) -> None:
|
|
178
|
+
"""
|
|
179
|
+
Sets ``value`` to the unit's ``iccid`` admin field.
|
|
180
|
+
|
|
181
|
+
:param value: A new value for the unit's ``iccid`` custom field.
|
|
182
|
+
:type value: :py:obj:`str`
|
|
183
|
+
:returns: Nothing.
|
|
184
|
+
:rtype: :py:obj:`None`
|
|
185
|
+
|
|
186
|
+
"""
|
|
187
|
+
afield_key: str = "iccid"
|
|
188
|
+
afield_val: str = value
|
|
189
|
+
afield_id: int | None = self.get_afield_id(afield_key)
|
|
190
|
+
|
|
191
|
+
if afield_id:
|
|
192
|
+
self.update_afield(afield_id, afield_key, afield_val)
|
|
193
|
+
|
|
194
|
+
def assign_carrier(self, value: str) -> None:
|
|
195
|
+
"""
|
|
196
|
+
Sets ``value`` to the unit's ``carrier`` admin field.
|
|
197
|
+
|
|
198
|
+
:param value: A new value for the unit's ``carrier`` custom field.
|
|
199
|
+
:type value: :py:obj:`str`
|
|
200
|
+
:returns: Nothing.
|
|
201
|
+
:rtype: :py:obj:`None`
|
|
202
|
+
|
|
203
|
+
"""
|
|
204
|
+
afield_key: str = "carrier"
|
|
205
|
+
afield_val: str = value
|
|
206
|
+
afield_id: int | None = self.get_afield_id(afield_key)
|
|
207
|
+
|
|
208
|
+
if afield_id:
|
|
209
|
+
self.update_afield(afield_id, afield_key, afield_val)
|
|
210
|
+
|
|
159
211
|
def execute_command(
|
|
160
212
|
self,
|
|
161
213
|
name: str,
|
terminusgps/wialon/utils.py
CHANGED
|
@@ -2,10 +2,9 @@ import secrets
|
|
|
2
2
|
import string
|
|
3
3
|
import typing
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from terminusgps.wialon.session import WialonSession
|
|
5
|
+
from . import constants, flags
|
|
6
|
+
from .items import WialonResource, WialonUnit
|
|
7
|
+
from .session import WialonSession
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def get_carrier_names(session: WialonSession) -> list[str]:
|
terminusgps/wialon/validators.py
CHANGED
|
@@ -4,7 +4,7 @@ from django.conf import settings
|
|
|
4
4
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
|
5
5
|
from django.utils.translation import gettext_lazy as _
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from .session import WialonSession
|
|
8
8
|
|
|
9
9
|
if not hasattr(settings, "WIALON_TOKEN"):
|
|
10
10
|
raise ImproperlyConfigured("'WIALON_TOKEN' setting is required.")
|
|
File without changes
|
{python_terminusgps-31.0.0.dist-info → python_terminusgps-31.1.0.dist-info}/licenses/COPYING
RENAMED
|
File without changes
|