python-terminusgps 1.1.4__tar.gz → 1.2.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.
Files changed (28) hide show
  1. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/PKG-INFO +2 -2
  2. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/pyproject.toml +2 -2
  3. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/items/base.py +22 -8
  4. python_terminusgps-1.2.0/terminusgps/wialon/items/unit.py +90 -0
  5. python_terminusgps-1.2.0/terminusgps/wialon/items/unit_group.py +71 -0
  6. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/items/user.py +1 -3
  7. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/utils.py +9 -0
  8. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/uv.lock +1 -1
  9. python_terminusgps-1.1.4/terminusgps/wialon/items/unit.py +0 -22
  10. python_terminusgps-1.1.4/terminusgps/wialon/items/unit_group.py +0 -19
  11. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/.gitignore +0 -0
  12. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/COPYING +0 -0
  13. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/README.md +0 -0
  14. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/requirements.txt +0 -0
  15. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/__init__.py +0 -0
  16. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/authorizenet/__init__.py +0 -0
  17. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/authorizenet/auth.py +0 -0
  18. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/aws/__init__.py +0 -0
  19. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/aws/secrets.py +0 -0
  20. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/__init__.py +0 -0
  21. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/constants.py +0 -0
  22. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/errors.py +0 -0
  23. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/flags.py +0 -0
  24. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/items/__init__.py +0 -0
  25. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/items/resource.py +0 -0
  26. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/items/retranslator.py +0 -0
  27. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/items/route.py +0 -0
  28. {python_terminusgps-1.1.4 → python_terminusgps-1.2.0}/terminusgps/wialon/session.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: python-terminusgps
3
- Version: 1.1.4
3
+ Version: 1.2.0
4
4
  Summary: Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more.
5
- Project-URL: Documentation, https://app.terminusgps.com/docs/apps/python-terminusgps
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
7
7
  Author-email: Blake Nall <blake@terminusgps.com>
8
8
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-terminusgps"
3
- version = "1.1.4"
3
+ version = "1.2.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" } ]
@@ -21,7 +21,7 @@ dependencies = [
21
21
  ]
22
22
 
23
23
  [project.urls]
24
- Documentation = "https://app.terminusgps.com/docs/apps/python-terminusgps"
24
+ Documentation = "https://app.terminusgps.com/docs/apps/python-terminusgps/index.html"
25
25
  Repository = "https://github.com/terminusgps/python-terminusgps"
26
26
 
27
27
  [build-system]
@@ -2,9 +2,11 @@ from typing import Any
2
2
 
3
3
  import terminusgps.wialon.flags as flags
4
4
  from terminusgps.wialon.session import WialonSession
5
+ from terminusgps.wialon.utils import repopulate
5
6
 
6
7
 
7
8
  class WialonBase:
9
+ @repopulate
8
10
  def __init__(
9
11
  self, *, id: str | None = None, session: WialonSession, **kwargs
10
12
  ) -> None:
@@ -14,7 +16,6 @@ class WialonBase:
14
16
  self._id = self.create(**kwargs)
15
17
  else:
16
18
  self._id = id
17
- self.populate()
18
19
 
19
20
  def __str__(self) -> str:
20
21
  return f"{self.__class__}:{self.id}"
@@ -31,9 +32,7 @@ class WialonBase:
31
32
  response = self.session.wialon_api.core_check_accessors(
32
33
  **{"items": [other_item.id], "flags": False}
33
34
  )
34
- if self.id in response.keys():
35
- return True
36
- return False
35
+ return True if self.id in response.keys() else False
37
36
 
38
37
  def create(self) -> int | None:
39
38
  """Creates a Wialon object and returns the newly created Wialon object's id."""
@@ -48,11 +47,11 @@ class WialonBase:
48
47
  self.name = item.get("nm", None)
49
48
  self.uid = item.get("uid", None)
50
49
 
50
+ @repopulate
51
51
  def rename(self, new_name: str) -> None:
52
52
  self.session.wialon_api.item_update_name(
53
53
  **{"itemId": self.id, "name": new_name}
54
54
  )
55
- self.populate()
56
55
 
57
56
  def add_afield(self, field: tuple[str, str]) -> None:
58
57
  self.session.wialon_api.item_update_admin_field(
@@ -111,9 +110,24 @@ class WialonBase:
111
110
  def delete(self) -> None:
112
111
  self.session.wialon_api.item_delete_item(**{"itemId": self.id})
113
112
 
114
- @property
115
- def cfields(self) -> dict[str, Any]:
113
+ def _get_cfields(self) -> dict:
116
114
  response = self.session.wialon_api.core_search_item(
117
115
  **{"id": self.id, "flags": flags.DATAFLAG_UNIT_CUSTOM_FIELDS}
118
116
  )
119
- return response.get("item", {}).get("flds")
117
+ return response["item"]["flds"]
118
+
119
+ def _get_afields(self) -> dict:
120
+ response = self.session.wialon_api.core_search_item(
121
+ **{"id": self.id, "flags": flags.DATAFLAG_UNIT_ADMIN_FIELDS}
122
+ )
123
+ return response["item"]["aflds"]
124
+
125
+ @property
126
+ def cfields(self) -> dict:
127
+ fields = self._get_cfields()
128
+ return {field["n"]: field["v"] for _, field in fields.items()}
129
+
130
+ @property
131
+ def afields(self) -> dict:
132
+ fields = self._get_afields()
133
+ return {field["n"]: field["v"] for _, field in fields.items()}
@@ -0,0 +1,90 @@
1
+ from urllib.parse import quote_plus
2
+
3
+ from terminusgps.wialon import flags
4
+ from terminusgps.wialon.items.base import WialonBase, repopulate
5
+
6
+
7
+ class WialonUnit(WialonBase):
8
+ def create(self, **kwargs) -> int | None:
9
+ if not kwargs.get("owner_id"):
10
+ raise ValueError("'owner_id' is required on creation.")
11
+ if not kwargs.get("name"):
12
+ raise ValueError("'name' is required on creation.")
13
+ if not kwargs.get("hw_type"):
14
+ raise ValueError("'hw_type' is required on creation.")
15
+
16
+ response = self.session.wialon_api.core_create_unit(
17
+ **{
18
+ "creatorId": kwargs["owner_id"],
19
+ "name": kwargs["name"],
20
+ "hwTypeId": kwargs["hw_type"],
21
+ "dataFlags": flags.DATAFLAG_UNIT_BASE,
22
+ }
23
+ )
24
+ return response.get("item", {}).get("id")
25
+
26
+ def populate(self) -> None:
27
+ super().populate()
28
+ unit_data = self.session.wialon_api.core_search_item(
29
+ **{"id": self.id, "flags": flags.DATAFLAG_UNIT_ADVANCED_PROPERTIES}
30
+ )
31
+ self.uid = unit_data.get("uid", "")
32
+ self.phone = unit_data.get("ph", "")
33
+ self.is_active = bool(unit_data.get("act", 0))
34
+
35
+ def execute_command(
36
+ self,
37
+ name: str,
38
+ link_type: str,
39
+ timeout: int = 5,
40
+ flags: int = 0,
41
+ param: dict | None = None,
42
+ ) -> None:
43
+ self.session.wialon_api.unit_exec_cmd(
44
+ **{
45
+ "itemId": self.id,
46
+ "commandName": name,
47
+ "linkType": link_type,
48
+ "timeout": timeout,
49
+ "flags": flags,
50
+ "param": param if param else {},
51
+ }
52
+ )
53
+
54
+ def set_access_password(self, password: str) -> None:
55
+ self.session.wialon_api.unit_update_access_password(
56
+ **{"itemId": self.id, "accessPassword": password}
57
+ )
58
+
59
+ @repopulate
60
+ def activate(self) -> None:
61
+ if self.is_active:
62
+ return
63
+
64
+ self.session.wialon_api.unit_set_active(
65
+ **{"itemId": self.id, "active": int(True)}
66
+ )
67
+
68
+ @repopulate
69
+ def deactivate(self) -> None:
70
+ if not self.is_active:
71
+ return
72
+
73
+ self.session.wialon_api.unit_set_active(
74
+ **{"itemId": self.id, "active": int(False)}
75
+ )
76
+
77
+ @repopulate
78
+ def assign_phone(self, phone: str) -> None:
79
+ self.session.wialon_api.unit_update_phone(
80
+ **{"itemId": self.id, "phoneNumber": quote_plus(phone)}
81
+ )
82
+
83
+ def get_phone_numbers(self) -> list[str]:
84
+ phones = []
85
+ if self.phone:
86
+ phones.append(self.phone)
87
+ for field in self.cfields | self.afields:
88
+ if field["n"] == "to_number":
89
+ phones.append(field["v"])
90
+ return phones
@@ -0,0 +1,71 @@
1
+ from terminusgps.wialon import constants, flags
2
+ from terminusgps.wialon.items.base import WialonBase
3
+
4
+
5
+ class WialonUnitGroup(WialonBase):
6
+ def _update_items(self, new_items: list[str]) -> None:
7
+ self.session.wialon_api.unit_group_update_units(
8
+ **{"itemId": self.id, "units": new_items}
9
+ )
10
+
11
+ def create(self, **kwargs) -> int | None:
12
+ if not kwargs.get("owner_id"):
13
+ raise ValueError("'owner_id' is required on creation.")
14
+ if not kwargs.get("name"):
15
+ raise ValueError("'name' is required on creation.")
16
+
17
+ response = self.session.wialon_api.core_create_unit_group(
18
+ **{
19
+ "creatorId": kwargs["owner_id"],
20
+ "name": kwargs["name"],
21
+ "dataFlags": flags.DATAFLAG_UNIT_BASE,
22
+ }
23
+ )
24
+ return response.get("item", {}).get("id")
25
+
26
+ def is_member(self, item: WialonBase) -> bool:
27
+ return True if str(item.id) in self.items else False
28
+
29
+ def grant_access(self, item: WialonBase, access_mask: int | None = None) -> None:
30
+ if not access_mask:
31
+ access_mask = constants.ACCESSMASK_UNIT_BASIC
32
+
33
+ self.session.wialon_api.user_update_item_access(
34
+ **{"userId": item.id, "itemId": self.id, "accessMask": access_mask}
35
+ )
36
+
37
+ def revoke_access(self, item: WialonBase) -> None:
38
+ self.session.wialon_api.user_update_item_access(
39
+ **{"userId": item.id, "itemId": self.id, "accessMask": 0}
40
+ )
41
+
42
+ def add_item(self, item: WialonBase) -> None:
43
+ new_items: list[str] = self.items + [str(item.id)]
44
+ self._update_items(new_items)
45
+
46
+ def rm_item(self, item: WialonBase) -> None:
47
+ assert self.is_member(item), "Cannot remove item, it's not in the group"
48
+ new_items: list[str] = self.items
49
+ new_items.remove(str(item.id))
50
+ self._update_items(new_items)
51
+
52
+ @property
53
+ def items(self) -> list[str]:
54
+ """Calls the Wialon API and returns a list of group member IDs."""
55
+ response = self.session.wialon_api.core_search_items(
56
+ **{
57
+ "spec": {
58
+ "itemsType": "avl_unit_group",
59
+ "propName": "sys_id",
60
+ "propValueMask": str(self.id),
61
+ "sortType": "sys_id",
62
+ "propType": "property",
63
+ "or_logic": 0,
64
+ },
65
+ "force": 1,
66
+ "flags": flags.DATAFLAG_UNIT_BASE,
67
+ "from": 0,
68
+ "to": 0,
69
+ }
70
+ )
71
+ return [str(unit_id) for unit_id in response.get("items")[0].get("u", [])]
@@ -47,9 +47,7 @@ class WialonUser(WialonBase):
47
47
  def has_access(self, other_item: WialonBase) -> bool:
48
48
  response = self._get_access_response(hw_type=other_item.hw_type)
49
49
  items = [key for key in response.keys()]
50
- if str(other_item.id) in items:
51
- return True
52
- return False
50
+ return True if str(other_item.id) in items else False
53
51
 
54
52
  def assign_phone(self, phone: str) -> None:
55
53
  self.add_cproperty(("phone", quote_plus(phone)))
@@ -5,6 +5,15 @@ from .session import WialonSession
5
5
  from .flags import DATAFLAG_UNIT_BASE
6
6
 
7
7
 
8
+ def repopulate(func):
9
+ def wrapper(self, *args, **kwargs):
10
+ result = func(self, *args, **kwargs)
11
+ self.populate()
12
+ return result
13
+
14
+ return wrapper
15
+
16
+
8
17
  def is_unique(value: str, session: WialonSession, items_type: str = "avl_unit") -> bool:
9
18
  """Determines if the value is unique among Wialon objects of type 'items_type'."""
10
19
  result = session.wialon_api.core_check_unique(
@@ -176,7 +176,7 @@ wheels = [
176
176
 
177
177
  [[package]]
178
178
  name = "python-terminusgps"
179
- version = "1.1.1"
179
+ version = "1.2.0"
180
180
  source = { editable = "." }
181
181
  dependencies = [
182
182
  { name = "argparse" },
@@ -1,22 +0,0 @@
1
- from terminusgps.wialon import flags
2
- from terminusgps.wialon.items.base import WialonBase
3
-
4
-
5
- class WialonUnit(WialonBase):
6
- def create(self, **kwargs) -> int | None:
7
- if not kwargs.get("owner_id"):
8
- raise ValueError("'owner_id' is required on creation.")
9
- if not kwargs.get("name"):
10
- raise ValueError("'name' is required on creation.")
11
- if not kwargs.get("hw_type"):
12
- raise ValueError("'hw_type' is required on creation.")
13
-
14
- response = self.session.wialon_api.core_create_unit(
15
- **{
16
- "creatorId": kwargs["owner_id"],
17
- "name": kwargs["name"],
18
- "hwTypeId": kwargs["hw_type"],
19
- "dataFlags": flags.DATAFLAG_UNIT_BASE,
20
- }
21
- )
22
- return response.get("item", {}).get("id")
@@ -1,19 +0,0 @@
1
- from terminusgps.wialon import flags
2
- from terminusgps.wialon.items.base import WialonBase
3
-
4
-
5
- class WialonUnitGroup(WialonBase):
6
- def create(self, **kwargs) -> int | None:
7
- if not kwargs.get("owner_id"):
8
- raise ValueError("'owner_id' is required on creation.")
9
- if not kwargs.get("name"):
10
- raise ValueError("'name' is required on creation.")
11
-
12
- response = self.session.wialon_api.core_create_unit_group(
13
- **{
14
- "creatorId": kwargs["owner_id"],
15
- "name": kwargs["name"],
16
- "dataFlags": flags.DATAFLAG_UNIT_BASE,
17
- }
18
- )
19
- return response.get("item", {}).get("id")