Source code for terminusgps.wialon.utils

import secrets
import string
import typing

from terminusgps.wialon import flags, items
from terminusgps.wialon.items.base import WialonBase
from terminusgps.wialon.session import WialonSession


[docs] def get_hw_type_id(name: str, session: WialonSession) -> int | None: """ Takes a Wialon hardware type name and returns its id, if it exists. :param name: The name of a Wialon hardware type. :type name: :py:obj:`str` :param session: A valid Wialon API session. :type session: :py:obj:`~terminusgps.wialon.session.WialonSession` :raises WialonError: If something goes wrong during a Wialon API call. :returns: A Wialon hardware type id, if it was found. :rtype: :py:obj:`int` | :py:obj:`None` """ response = session.wialon_api.core_get_hw_types( **{ "filterType": "id", "filterValue": "name,id", "includeType": "true", "ignoreRename": "true", } ) hw_types = {item.get("name"): item.get("id") for item in response} return int(hw_types.get(name)) if name in hw_types.keys() else None
[docs] def get_id_from_imei(imei: str, session: WialonSession) -> str | None: """ Takes a Wialon unit's IMEI # and returns its unit id. :param imei: A Wialon unit's IMEI #. :type imei: :py:obj:`str` :param session: A valid Wialon API session. :type session: :py:obj:`~terminusgps.wialon.session.WialonSession` :raises ValueError: If ``imei`` contains non-digit characters. :raises WialonError: If something goes wrong during a Wialon API call. :returns: A Wialon object id, if it was found. :rtype: :py:obj:`str` | :py:obj:`None` """ if not imei.isdigit(): raise ValueError(f"'imei' must be a digit, got '{imei}'.") results: dict[str, typing.Any] | None = session.wialon_api.core_search_items( **{ "spec": { "itemsType": "avl_unit", "propName": "sys_unique_id", "propValueMask": f"*{imei}*", "sortType": "sys_unique_id", "propType": "property", "or_logic": 0, }, "force": 0, "flags": flags.DATAFLAG_UNIT_BASE, "from": 0, "to": 0, } ) if results and results.get("totalItemsCount", 0) == 1: return results["items"][0].get("id")
[docs] def get_id_from_iccid(iccid: str, session: WialonSession) -> str | None: """ DEPRECATED: Use :py:func:`~terminusgps.wialon.utils.get_id_from_imei`. Takes a Wialon unit's IMEI # and returns its unit id, if it exists. :param iccid: A unique id. :type iccid: :py:obj:`str` :param session: A valid Wialon API session. :type session: :py:obj:`~terminusgps.wialon.session.WialonSession` :raises WialonError: If something goes wrong during a Wialon API call. :returns: A Wialon object id, if it was found. :rtype: :py:obj:`str` | :py:obj:`None` """ return get_id_from_imei(imei=iccid, session=session)
[docs] def get_wialon_cls(items_type: str) -> typing.Type[WialonBase] | None: """ Returns a Wialon object class based on ``items_type``. Valid ``items_type`` are ``"user"``, ``"avl_unit"``, ``"avl_unit_group"`` and ``"avl_resource"``. :param items_type: A Wialon object type. :type items_type: :py:obj:`str` :returns: A subclass of :py:obj:`~terminusgps.wialon.items.base.WialonBase`. :rtype: :py:obj:`~terminusgps.wialon.items.base.WialonBase` | :py:obj:`None` """ items_map: dict[str, typing.Type[WialonBase]] = { "user": items.WialonUser, "avl_unit": items.WialonUnit, "avl_unit_group": items.WialonUnitGroup, "avl_resource": items.WialonResource, } return items_map.get(items_type)
[docs] def get_vin_info(vin_number: str, session: WialonSession) -> dict: """ Retrieves vehicle data from a VIN number. :param value: A vehicle's VIN number. :type value: :py:obj:`str` :param session: A valid Wialon API session. :type session: :py:obj:`~terminusgps.wialon.session.WialonSession` :returns: A dictionary of vehicle information, if any was found. :rtype: :py:obj:`dict` """ response: dict[str, typing.Any] | None = session.wialon_api.unit_get_vin_info( **{"vin": vin_number} ) if response is None or "error" in response.get("vin_lookup_result", {}).keys(): return {} return { field.get("n"): field.get("v") for field in response.get("vin_lookup_result", {}).get("pflds") }
[docs] def is_unique(value: str, session: WialonSession, items_type: str = "avl_unit") -> bool: """ Determines if the value is unique among Wialon objects of type 'items_type'. :param value: A Wialon object name. :type value: :py:obj:`str` :param session: A valid Wialon API session. :type session: :py:obj:`~terminusgps.wialon.session.WialonSession` :param items_type: Type of Wialon objects to validate the value against. Default is ``"avl_unit"``. :type items_type: :py:obj:`str` :raises WialonError: If something goes wrong during a Wialon API call. :returns: Whether or not the value is unique among 'items_type'. :rtype: :py:obj:`bool` """ response = session.wialon_api.core_check_unique( **{"type": items_type, "value": value.strip()} ) if not response: return False return bool(response.get("result"))
[docs] def generate_wialon_password(length: int = 32) -> str: """ Generates a Wialon compliant password between ``8`` and ``64`` characters. The generated password will contain: - At least one uppercase letter. - At least one lowercase letter. - At least one special symbol. - At least three digits. :param length: Length of the generated password. Default is ``32``. :type length: :py:obj:`int` :raises ValueError: If :py:length is less than ``8`` or greater than ``64``. :returns: A Wialon compliant password. :rtype: :py:obj:`str` """ min_length, max_length = 8, 64 if length > max_length: raise ValueError( f"Password cannot be greater than {max_length} characters in length. Got {length}." ) elif length < min_length: raise ValueError( f"Password cannot be less than {min_length} characters in length. Got {length}." ) s0 = list(string.ascii_uppercase) s1 = list(string.ascii_lowercase) s2 = list(string.digits) s3 = list("!@#$%^*()[]-_+") while True: password = "".join([secrets.choice(s0 + s1 + s2 + s3) for _ in range(length)]) if ( any(c.islower() for c in password) and any(c.isupper() for c in password) and sum(c.isdigit() for c in password) >= 3 and any(c in s3 for c in password) ): break return password