Ejemplo n.º 1
0
    def __call__(self, *, names: list = None):
        if self._item is doors_params_error:
            raise FireError('Parameters may be used only for single door')

        if names is None:
            names = self._readable_params
        elif isinstance(names, str):
            names = (names, )
        elif not isinstance(names, (list, tuple)):
            # Workaround of "Could not consume arg" message appearing
            # instead of exception message problem
            sys.stderr.write("ERROR: Names must be a name or list of parameters")
            raise FireError("Names must be a name or list of parameters")

        names = set(names)

        extra_names = names - set(self._readable_params)
        if extra_names:
            # Workaround of "Could not consume arg" message appearing
            # instead of exception message problem
            sys.stderr.write('ERROR: Unknown parameters were given: {}\n'.format(extra_names))
            raise FireError('Unknown parameters were given: {}'.format(extra_names))

        formatter = BaseFormatter.get_formatter(opt_io_format)(
            data_in, data_out, names
        )
        converter = TypedFieldConverter(formatter, self._prop_types)
        converter.write_records(
            [{name: getattr(self._item, name) for name in sorted(names)}]
        )
Ejemplo n.º 2
0
def parse_array_index(opt_indexes: Optional[Union[int, str]]) -> Union[int, slice]:
    """
    Parse index/range cli parameter and return appropriate int or slice

        >>> assert parse_array_index(None) == slice(None, None, None)
        >>> assert parse_array_index(1) == int(1)
        >>> assert parse_array_index('1-2') == slice(1, 2, None)

    Args:
        opt_indexes(Union[int, str], optional): index or range

    Returns:
        Union[int, slice]: int or slice suitable for sequences indexing
    """
    if opt_indexes is None:
        return slice(None, None)
    if isinstance(opt_indexes, str):
        if not re.match(r'^\d-\d$', opt_indexes):
            raise FireError("Select range must contain numbers divided by dash, for example 0-3")

        pieces = opt_indexes.split('-')
        start = int(pieces.pop(0)) if pieces else None
        stop = int(pieces.pop(0) or 1000) + 1 if pieces else None
        return slice(start, stop)
    if isinstance(opt_indexes, int):
        if opt_indexes < 0:
            raise FireError("Select index must be a positive number")

        return opt_indexes

    raise FireError("Numbers must be list or int")
Ejemplo n.º 3
0
    def validate_headers(self, input_headers: Union[set, KeysView]):
        headers = set(self._headers)
        extra = input_headers - headers
        if extra:
            raise FireError("Unknown fields in input: {}".format(extra))

        missed = headers - input_headers
        if missed:
            raise FireError("Missed fields in input: {}".format(extra))
Ejemplo n.º 4
0
    def write_raw(self, name: str):
        """Write raw data to a given table.

        ZKAccess device keeps table values as strings, many of these
        fields are encoded (some date fields, for instance). This
        command expects input data as it stores on a device, without
        applying any type convertions or decoding (like `table`
        command does).

        Args:
            name: table name. Possible values are:
                'User', 'UserAuthorize', 'Holiday', 'Timezone',
                'Transaction', 'FirstCard', 'MultiCard', 'InOutFun',
                'TemplateV10'
        """
        if name not in models_registry:
            raise FireError("Unknown table '{}', possible values are: {}".format(
                name, list(sorted(models_registry.keys()))
            ))
        table_cls = models_registry[name]
        formatter = BaseFormatter.get_formatter(opt_io_format)(
            data_in, data_out, table_cls.fields_mapping().values()
        )
        converter = TextConverter(formatter)

        gen = self._zk.sdk.set_device_data(table_cls.table_name)
        gen.send(None)
        for record in converter.read_records():
            gen.send(record)

        try:
            gen.send(None)
        except StopIteration:
            pass
Ejemplo n.º 5
0
    def read_raw(self, name: str, *, buffer_size=32768):
        """Return raw data from a given table.

        ZKAccess device keeps table values as strings, many of these
        fields are encoded (some date fields, for instance). This
        command returns data as it stores on a device, without
        applying any type convertions or decoding, like `table`
        command does.

        This command works on low level. So, it accepts buffer size
        for storing a result. If you are observed that results
        are cut, its makes sense to increase buffer size.

        Args:
            name: table name. Possible values are:
                'User', 'UserAuthorize', 'Holiday', 'Timezone',
                'Transaction', 'FirstCard', 'MultiCard', 'InOutFun',
                'TemplateV10'
            buffer_size: buffer size in bytes to store a result.
                Default is 32Kb
        """
        if name not in models_registry:
            raise FireError("Unknown table '{}', possible values are: {}".format(
                name, list(sorted(models_registry.keys()))
            ))
        table_cls = models_registry[name]
        formatter = BaseFormatter.get_formatter(opt_io_format)(
            data_in, data_out, table_cls.fields_mapping().values()
        )
        converter = TextConverter(formatter)
        converter.write_records(
            self._zk.sdk.get_device_data(table_cls.table_name, [], {}, buffer_size, False)
        )
Ejemplo n.º 6
0
 def _validate_field_names(self, fields: Union[Set[str], KeysView], item: Mapping[str, Any]):
     # Check if field names are all exist in the model
     extra_fields = item.keys() - fields
     if extra_fields:
         raise FireError("Unknown fields of {} found in the input data: {}".format(
             self._model_cls.__name__, list(sorted(extra_fields))
         ))
Ejemplo n.º 7
0
    def _set_from_args(self, args: dict, converter):
        extra_names = args.keys() - set(self._readable_params)
        if extra_names:
            raise FireError('Unknown parameters were given: {}'.format(extra_names))

        typed_items = converter.to_record_dict(args)
        for name, val in typed_items.items():
            setattr(self._item, name, val)
Ejemplo n.º 8
0
    def list(self):
        """List of all valid parameter names"""
        if self._item is doors_params_error:
            raise FireError('Parameters may be used only for single door')

        formatter = BaseFormatter.get_formatter(opt_io_format)(
            data_in, data_out, ['parameter_name']
        )
        converter = TextConverter(formatter)
        converter.write_records({'parameter_name': x} for x in sorted(self._readable_params))
Ejemplo n.º 9
0
    def set(self, **parameters):
        """Set given parameters

        Args:
            parameters: Flags are parameters with values to be set.
                For example, `... parameters set --param1=value1 --param2=value2 ...`
        """
        if self._item is doors_params_error:
            raise FireError('Parameters may be used only for single door')

        readonly_params = parameters.keys() & self._readonly_params
        if readonly_params:
            raise FireError('The following parameters are read-only: {}'.format(readonly_params))

        formatter = BaseFormatter.get_formatter(opt_io_format)(
            data_in, data_out, parameters.keys()
        )
        converter = TypedFieldConverter(formatter, self._prop_types)
        if parameters:
            self._set_from_args(parameters, converter)
        else:
            self._set_from_input(converter)
Ejemplo n.º 10
0
    def connect(self, ip: str, *, model: str = 'ZK400') -> ZKCommand:
        """
        Connect to a device with given ip.

        Args:
            ip (str): IP address of a device
            model (DeviceModels): device model. Possible values are:
            ZK100, ZK200, ZK400
        """
        model = device_models.get(model)
        if model is None:
            raise FireError(
                "Unknown device model '{}', possible values are: ZK100, ZK200, ZK400".format(model)
            )

        if not ip:
            raise FireError('IP argument is required')

        connstr = 'protocol=TCP,ipaddress={},port=4370,timeout=4000,passwd='.format(ip)

        zkcmd = ZKCommand(ZKAccess(connstr, device_model=model, dllpath=self._dllpath))

        return zkcmd
Ejemplo n.º 11
0
    def __call__(
            self, *, format: str = 'ascii_table', file: str = None, dllpath: str = 'plcommpro.dll'
    ):
        if format not in io_formats:
            # Workaround of "Could not consume arg" message appearing
            # instead of exception message problem
            sys.stderr.write("ERROR: Unknown format '{}', available are: {}\n".format(
                format, list(sorted(io_formats.keys()))
            ))
            raise FireError("Unknown format '{}', available are: {}".format(
                format, list(sorted(io_formats.keys()))
            ))

        global opt_io_format
        opt_io_format = format

        self._file = None
        if file:
            d = os.path.dirname(file)
            if not os.path.isdir(d):
                # Workaround of "Could not consume arg" message appearing
                # instead of exception message problem
                sys.stderr.write("ERROR: Directory '{}' does not exist\n".format(d))
                raise FireError("Directory {} does not exist".format(d))

            self._file = open(file, 'r+')
            self._file.seek(0)

            global data_in
            global data_out
            data_in = self._file
            data_out = WriteFile(self._file)

        self._dllpath = dllpath

        return self
Ejemplo n.º 12
0
    def _parse_value(self, field_name: str, value: str, field_datatype) -> Optional[Any]:
        if value == '':
            return None

        error_msg = ''
        try:
            if issubclass(field_datatype, Enum):
                error_msg = 'one of values: {}'.format(
                    ','.join(x for x in dir(field_datatype) if not x.startswith('_'))
                )
                return field_datatype[value]

            cast, error_msg = self._input_converters[field_datatype]
            return cast(value)
        except (ValueError, TypeError, KeyError):
            raise FireError(
                "Bad value of {}={} but must be: {}".format(field_name, value, error_msg)
            )
Ejemplo n.º 13
0
 def table(self, name: str) -> Query:
     """
     Make a query to a device table with given name
     
     Args:
         name: table name. Possible values are:
             'User', 'UserAuthorize', 'Holiday', 'Timezone',
             'Transaction', 'FirstCard', 'MultiCard', 'InOutFun',
             'TemplateV10'
     """
     if name not in models_registry:
         raise FireError("Unknown table '{}', possible values are: {}".format(
             name, list(sorted(models_registry.keys()))
         ))
     qs = self._zk.table(name)
     table_cls = qs._table_cls
     formatter = BaseFormatter.get_formatter(opt_io_format)(
         data_in, data_out, table_cls.fields_mapping().keys()
     )
     return Query(qs, ModelConverter(formatter, table_cls))
Ejemplo n.º 14
0
    def __init__(
        self,
        bg: str = "#EEE8D5",
        fg: str = "#484848",
        contrast_ratio: Optional[float] = None,
        saturation: float = 1,
        hues: Optional[Tuple[float, float, float, float, float, float]] = None,
        sample_rate: int = 256,
    ):
        try:
            # Cooking input.
            check_argument_types()
            bg = from_hex(bg)
            fg = from_hex(fg)
            if hues is None:
                hues = (0, 120, 60, 240, 300, 200)
            hues = (hue / 360 for hue in hues)
            if contrast_ratio is None:
                contrast_ratio = contrast(bg, fg)

            # Generating the palette.
            self.colors = [to_hex(*bg)] + [None] * 6 + [to_hex(*fg)]
            for hue, color in zip(hues, range(1, 7)):
                lightness_contrast = (
                    (lightness,
                     contrast(bg, hls_to_rgb(hue, lightness, saturation)))
                    for lightness in (x / (sample_rate - 1)
                                      for x in range(sample_rate)))
                # Filter out values of the opposite sign.
                lightness_contrast = filter(
                    lambda p: (p[1] > 0) == (contrast_ratio > 0),
                    lightness_contrast)
                best_lightness, best_contrast = min(
                    lightness_contrast,
                    key=lambda p: abs(p[1] - contrast_ratio))
                self.colors[color] = to_hex(
                    *hls_to_rgb(hue, best_lightness, saturation))
        except Exception as e:
            raise FireError(str(e))
Ejemplo n.º 15
0
 def get_formatter(io_format: str) -> 'Type[BaseFormatter]':
     if io_format not in io_formats:
         raise FireError("{} format(s) are only supported", sorted(io_formats.keys()))
     return io_formats[io_format]
Ejemplo n.º 16
0
 def get_reader(self) -> Iterable[Mapping[str, str]]:
     raise FireError(
         'You should to specify input data format, e.g. `pyzkaccess --format=csv ...`'
     )