python-terminusgps 31.3.0__py3-none-any.whl → 31.5.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.
- {python_terminusgps-31.3.0.dist-info → python_terminusgps-31.5.0.dist-info}/METADATA +1 -1
- {python_terminusgps-31.3.0.dist-info → python_terminusgps-31.5.0.dist-info}/RECORD +12 -8
- terminusgps/aws/utils.py +5 -0
- terminusgps/wialon/constants.py +6 -0
- terminusgps/wialon/items/resource.py +68 -1
- terminusgps/wialon/items/unit.py +4 -4
- terminusgps/wialon/session.py +1 -0
- terminusgps/wialon/tests/test_items.py +37 -0
- terminusgps/wialon/tests/test_session.py +40 -0
- terminusgps/wialon/tests/test_utils.py +41 -0
- {python_terminusgps-31.3.0.dist-info → python_terminusgps-31.5.0.dist-info}/WHEEL +0 -0
- {python_terminusgps-31.3.0.dist-info → python_terminusgps-31.5.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.5.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
|
|
@@ -12,6 +12,7 @@ terminusgps/authorizenet/profiles/subscriptions.py,sha256=N4_0kbBBJ0FtKdIydN8FLn
|
|
|
12
12
|
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
|
+
terminusgps/aws/utils.py,sha256=68GWcllu4h41qzFiKdUkWOAA4LDsTPqRY446VRMxYsY,116
|
|
15
16
|
terminusgps/django/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
17
|
terminusgps/django/mixins.py,sha256=Q9ZJuzpk3d9lDnlVA8ZTVvnZWxB13p08EQ8yVJcztn4,1034
|
|
17
18
|
terminusgps/django/settings.py,sha256=cKUpFXH-uYWStvT6vzclczJAKwCGNx_2wY9-fqsbmIs,624
|
|
@@ -20,21 +21,24 @@ terminusgps/twilio/__init__.py,sha256=dYo41F2jft_eHDWSUtSpKGSRG1bewq_qClqilUJZkY
|
|
|
20
21
|
terminusgps/twilio/caller.py,sha256=Q0wcJ5aaNDGvKfht7ARwPTFdqpFoB81DmZ_K2oZixyA,5077
|
|
21
22
|
terminusgps/twilio/validators.py,sha256=HWCpzgDXTedofty4Zhrm2OenbgtkzrDUC08B1l15gqc,1112
|
|
22
23
|
terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
-
terminusgps/wialon/constants.py,sha256=
|
|
24
|
+
terminusgps/wialon/constants.py,sha256=pMWqXkZK7bbA_KOdBdJ8hs9MnUUEk-MMygJ3fLNA4pQ,5783
|
|
24
25
|
terminusgps/wialon/flags.py,sha256=M50EdhxQ8IMnJnU0mrHK7-h8Asc6tvNiTOOfd1dBW6A,12815
|
|
25
26
|
terminusgps/wialon/logger.py,sha256=nUBsaLMaffSaAHGHAM6mFXDzix9hbNecVtA3INVtii8,968
|
|
26
|
-
terminusgps/wialon/session.py,sha256=
|
|
27
|
+
terminusgps/wialon/session.py,sha256=SGiHH58h8d3n4dQqKrLjWKlZvNHjBqpWqK6GKofMCBo,10079
|
|
27
28
|
terminusgps/wialon/utils.py,sha256=JWHZ7VEeo8VNBH67gjOAQk5ITKuPllWDlJ4dVSQ5blA,11002
|
|
28
29
|
terminusgps/wialon/validators.py,sha256=CVEpFsxqplEcpv4U2ipA6v9y5cSrMKFUXLvze-3vs4U,4223
|
|
29
30
|
terminusgps/wialon/items/__init__.py,sha256=3BVthghekMvhMQSzQgBMlD_phxmKSmp3Zvmo-z0O8Bs,211
|
|
30
31
|
terminusgps/wialon/items/base.py,sha256=7J5B-EPj997GJV7TbZP7pAfjl2G4nTcKmP-RMxmuzoY,10959
|
|
31
|
-
terminusgps/wialon/items/resource.py,sha256=
|
|
32
|
+
terminusgps/wialon/items/resource.py,sha256=DDnyL_Y5P3DxiirUkQb9y4cokMXZVq3xnfn16Vx8sxk,16992
|
|
32
33
|
terminusgps/wialon/items/retranslator.py,sha256=sVEWrp8q1I-tO_rMTCH7TeQDDbZryIq8d9KVnhYyhH0,3795
|
|
33
34
|
terminusgps/wialon/items/route.py,sha256=amNPKZqgl8pEzKA_XJudnvBPzEsfHTmrC7uF15sZVI4,1216
|
|
34
|
-
terminusgps/wialon/items/unit.py,sha256=
|
|
35
|
+
terminusgps/wialon/items/unit.py,sha256=iwHM4AfUED2blKkP940RbUxFFPD_4pTDe4Dut853cfA,12302
|
|
35
36
|
terminusgps/wialon/items/unit_group.py,sha256=QV2ZZgICaN3n6W1pFIyMLyNKB6KYBsLyKG64i-qXoOg,4113
|
|
36
37
|
terminusgps/wialon/items/user.py,sha256=5LgwalGO8KS_7psmAVmAlnC0S6SPBDZMOuT5ZqPKRmo,7758
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
python_terminusgps-31.
|
|
38
|
+
terminusgps/wialon/tests/test_items.py,sha256=P2LmBYx_63-bfSmsrIdVegLUcet-OBIjjJo0kJAJ-lE,1300
|
|
39
|
+
terminusgps/wialon/tests/test_session.py,sha256=4H_TeIMrC4dyaDAy11a0o1GMn6PIZaRF8soPaoaowQg,1318
|
|
40
|
+
terminusgps/wialon/tests/test_utils.py,sha256=vYnOKCPPYqUWcQ2nTJTOu7NhNKMiTGNBkvX9H2APxL0,1670
|
|
41
|
+
python_terminusgps-31.5.0.dist-info/METADATA,sha256=Dcha0-mD7REBsNgTK-DTBoXBOTGZGUyfkjzicxVQ4ec,1648
|
|
42
|
+
python_terminusgps-31.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
43
|
+
python_terminusgps-31.5.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
44
|
+
python_terminusgps-31.5.0.dist-info/RECORD,,
|
terminusgps/aws/utils.py
ADDED
terminusgps/wialon/constants.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from urllib.parse import quote_plus
|
|
2
2
|
|
|
3
|
-
from terminusgps.wialon import flags
|
|
3
|
+
from terminusgps.wialon import constants, flags
|
|
4
4
|
from terminusgps.wialon.items.base import WialonBase
|
|
5
5
|
|
|
6
6
|
|
|
@@ -85,6 +85,73 @@ class WialonResource(WialonBase):
|
|
|
85
85
|
)
|
|
86
86
|
return int(response.get("item", {}).get("bact")) == self.id
|
|
87
87
|
|
|
88
|
+
def create_geofence(
|
|
89
|
+
self,
|
|
90
|
+
name: str,
|
|
91
|
+
x: float,
|
|
92
|
+
y: float,
|
|
93
|
+
_type: constants.WialonGeofenceType = constants.WialonGeofenceType.CIRCLE,
|
|
94
|
+
desc: str = "",
|
|
95
|
+
flags: int = 0x10,
|
|
96
|
+
color: int = int("6d0204", 16),
|
|
97
|
+
text_color: int = int("21130d", 16),
|
|
98
|
+
text_size: int = 12,
|
|
99
|
+
width: int = 100,
|
|
100
|
+
min_zoom: int = 4,
|
|
101
|
+
max_zoom: int = 19,
|
|
102
|
+
) -> None:
|
|
103
|
+
"""
|
|
104
|
+
Creates a geofence in Wialon for the resource.
|
|
105
|
+
|
|
106
|
+
:param name: Name of the geofence.
|
|
107
|
+
:type name: :py:obj:`str`
|
|
108
|
+
:param x: X-coordinate for the geofence.
|
|
109
|
+
:type x: :py:obj:`float`
|
|
110
|
+
:param y: Y-coordinate for the geofence.
|
|
111
|
+
:type y: :py:obj:`float`
|
|
112
|
+
:param _type: *Optional.* Type of Wialon geofence.
|
|
113
|
+
:type _type: :py:obj:`int`
|
|
114
|
+
:param desc: *Optional.* Description of the geofence.
|
|
115
|
+
:type desc: :py:obj:`str`
|
|
116
|
+
:param flags: *Optional.* Flags to use on the creation API call.
|
|
117
|
+
:type flags: :py:obj:`int`
|
|
118
|
+
:param color: *Optional.* Color of the geofence.
|
|
119
|
+
:type color: :py:obj:`int`
|
|
120
|
+
:param text_color: *Optional.* Text color of the geofence.
|
|
121
|
+
:type text_color: :py:obj:`int`
|
|
122
|
+
:param text_size: *Optional.* Text size of the geofence.
|
|
123
|
+
:type text_size: :py:obj:`int`
|
|
124
|
+
:param width: *Optional.* Width of the geofence.
|
|
125
|
+
:type width: :py:obj:`int`
|
|
126
|
+
:param min_zoom: *Optional.* Minimum zoom level the geofence will be visible at.
|
|
127
|
+
:type min_zoom: :py:obj:`int`
|
|
128
|
+
:param max_zoom: *Optional* Maximum zoom level the geofence will be visible at.
|
|
129
|
+
:type max_zoom: :py:obj:`int`
|
|
130
|
+
:returns: Nothing.
|
|
131
|
+
:rtype: :py:obj:`None`
|
|
132
|
+
|
|
133
|
+
"""
|
|
134
|
+
self.session.wialon_api.resource_update_zone(
|
|
135
|
+
**{
|
|
136
|
+
"itemId": self.id,
|
|
137
|
+
"id": 0,
|
|
138
|
+
"callMode": "create",
|
|
139
|
+
"n": name,
|
|
140
|
+
"d": desc,
|
|
141
|
+
"t": _type,
|
|
142
|
+
"w": width,
|
|
143
|
+
"f": flags,
|
|
144
|
+
"c": color,
|
|
145
|
+
"tc": text_color,
|
|
146
|
+
"ts": text_size,
|
|
147
|
+
"min": min_zoom,
|
|
148
|
+
"max": max_zoom,
|
|
149
|
+
"path": "",
|
|
150
|
+
"libId": 0,
|
|
151
|
+
"p": [{"x": x, "y": y, "r": width}],
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
|
|
88
155
|
def is_migrated(self, unit: WialonBase) -> bool:
|
|
89
156
|
"""
|
|
90
157
|
Checks if a unit is migrated into the account.
|
terminusgps/wialon/items/unit.py
CHANGED
|
@@ -38,10 +38,10 @@ class WialonUnit(WialonBase):
|
|
|
38
38
|
|
|
39
39
|
response = self.session.wialon_api.core_create_unit(
|
|
40
40
|
**{
|
|
41
|
-
"creatorId": creator_id,
|
|
42
|
-
"name": name,
|
|
43
|
-
"hwTypeId": hw_type_id,
|
|
44
|
-
"dataFlags": flags.DataFlag.UNIT_BASE,
|
|
41
|
+
"creatorId": str(creator_id),
|
|
42
|
+
"name": str(name),
|
|
43
|
+
"hwTypeId": str(hw_type_id),
|
|
44
|
+
"dataFlags": str(flags.DataFlag.UNIT_BASE),
|
|
45
45
|
}
|
|
46
46
|
)
|
|
47
47
|
return (
|
terminusgps/wialon/session.py
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
from django.conf import settings
|
|
5
|
+
|
|
6
|
+
from .. import items
|
|
7
|
+
from ..session import WialonSession
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class WialonResourceTestCase(unittest.TestCase):
|
|
11
|
+
def setUp(self) -> None:
|
|
12
|
+
if not hasattr(settings, "WIALON_TOKEN"):
|
|
13
|
+
self.fail("'WIALON_TOKEN' setting is required.")
|
|
14
|
+
if not hasattr(settings, "WIALON_ADMIN_ID"):
|
|
15
|
+
self.fail("'WIALON_ADMIN_ID' setting is required.")
|
|
16
|
+
|
|
17
|
+
self.session = WialonSession()
|
|
18
|
+
self.session.login(settings.WIALON_TOKEN)
|
|
19
|
+
self.test_timestamp = f"{datetime.now():%Y-%m-%d-%H:%M:%S}"
|
|
20
|
+
self.test_resource = items.WialonResource(
|
|
21
|
+
id=None,
|
|
22
|
+
creator_id=str(settings.WIALON_ADMIN_ID),
|
|
23
|
+
name=f"test_resource_{self.test_timestamp}",
|
|
24
|
+
skip_creator_check=True,
|
|
25
|
+
session=self.session,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def tearDown(self) -> None:
|
|
29
|
+
self.test_resource.delete()
|
|
30
|
+
|
|
31
|
+
def test_resource_is_not_account(self) -> None:
|
|
32
|
+
"""Tests whether or not a new resource is an account after creation."""
|
|
33
|
+
self.assertFalse(self.test_resource.is_account)
|
|
34
|
+
|
|
35
|
+
def test_resource_create_account(self) -> None:
|
|
36
|
+
self.test_resource.create_account("terminusgps_ext_hist")
|
|
37
|
+
self.assertTrue(self.test_resource.is_account)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from django.conf import settings
|
|
4
|
+
|
|
5
|
+
from ..session import WialonSession
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WialonSessionTestCase(unittest.TestCase):
|
|
9
|
+
def setUp(self) -> None:
|
|
10
|
+
if not hasattr(settings, "WIALON_TOKEN"):
|
|
11
|
+
self.fail("'WIALON_TOKEN' setting is required.")
|
|
12
|
+
|
|
13
|
+
self.token = settings.WIALON_TOKEN
|
|
14
|
+
self.session = WialonSession()
|
|
15
|
+
|
|
16
|
+
def test_session_init(self) -> None:
|
|
17
|
+
self.assertIsNone(self.session.id)
|
|
18
|
+
self.assertIsNone(self.session.username)
|
|
19
|
+
self.assertIsNone(self.session.uid)
|
|
20
|
+
|
|
21
|
+
def test_session_login(self) -> None:
|
|
22
|
+
sid: str = self.session.login(self.token)
|
|
23
|
+
self.assertEqual(self.session.id, sid)
|
|
24
|
+
|
|
25
|
+
def test_session_logout(self) -> None:
|
|
26
|
+
self.session.login(self.token)
|
|
27
|
+
self.session.logout()
|
|
28
|
+
self.assertEqual(self.session.id, None)
|
|
29
|
+
|
|
30
|
+
def test_session_bad_call(self) -> None:
|
|
31
|
+
self.session.login(self.token)
|
|
32
|
+
response = self.session.wialon_api.core_bad_call({})
|
|
33
|
+
self.assertEqual(response, None)
|
|
34
|
+
self.session.logout()
|
|
35
|
+
|
|
36
|
+
def test_session_valid_call_count(self) -> None:
|
|
37
|
+
self.session.login(self.token) # Login/logout does not count
|
|
38
|
+
self.session.wialon_api.avl_evts()
|
|
39
|
+
self.assertEqual(self.session.wialon_api.total_calls, 1)
|
|
40
|
+
self.session.logout()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import string
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from .. import utils
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WialonUtilsTestCase(unittest.TestCase):
|
|
9
|
+
def test_generate_wialon_password_min_length(self) -> None:
|
|
10
|
+
with self.assertRaises(ValueError) as context:
|
|
11
|
+
utils.generate_wialon_password(length=7)
|
|
12
|
+
self.assertTrue(
|
|
13
|
+
"Password cannot be less than 8 characters in length, got 7."
|
|
14
|
+
in str(context.exception)
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
def test_generate_wialon_password_max_length(self) -> None:
|
|
18
|
+
with self.assertRaises(ValueError) as context:
|
|
19
|
+
utils.generate_wialon_password(length=65)
|
|
20
|
+
self.assertTrue(
|
|
21
|
+
"Password cannot be greater than 64 characters in length, got 65."
|
|
22
|
+
in str(context.exception)
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def test_generate_wialon_password_valid(self) -> None:
|
|
26
|
+
password = utils.generate_wialon_password()
|
|
27
|
+
s0 = list(string.ascii_uppercase)
|
|
28
|
+
s1 = list(string.ascii_lowercase)
|
|
29
|
+
s2 = list(string.digits)
|
|
30
|
+
s3 = list("!@#$%^*()[]-_+")
|
|
31
|
+
|
|
32
|
+
if len(password) < 8 or len(password) > 64:
|
|
33
|
+
self.fail(f"Generated password was {len(password)} chars in length.")
|
|
34
|
+
if not any([c for c in password if c in s0]):
|
|
35
|
+
self.fail("Generated password did not contain an uppercase letter.")
|
|
36
|
+
if not any([c for c in password if c in s1]):
|
|
37
|
+
self.fail("Generated password did not contain a lowercase letter.")
|
|
38
|
+
if not any([c for c in password if c in s2]):
|
|
39
|
+
self.fail("Generated password did not contain a digit.")
|
|
40
|
+
if not any([c for c in password if c in s3]):
|
|
41
|
+
self.fail("Generated password did not contain a special symbol.")
|
|
File without changes
|
{python_terminusgps-31.3.0.dist-info → python_terminusgps-31.5.0.dist-info}/licenses/COPYING
RENAMED
|
File without changes
|